Skip to content

Commit

Permalink
Refactor test code v2, fix restart assertion
Browse files Browse the repository at this point in the history
  • Loading branch information
mszostok committed Jan 29, 2024
1 parent 316a195 commit 725a88e
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 86 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/branch-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Branch build
on:
push:
branches:
- main
# - main
- "teams/integration-tests"
repository_dispatch:
types: [ trigger-e2e-tests ]
Expand Down Expand Up @@ -199,9 +199,6 @@ jobs:
run: |
KUBECONFIG=$(k3d kubeconfig write ${{ matrix.integration }}-test-cluster) \
make test-integration-${{ matrix.integration }}
- name: Dump cluster state
if: ${{ failure() }}
uses: ./.github/actions/dump-cluster
# cli-migration-e2e:
# name: CLI Migration E2E tests
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ env:
HELM_VERSION: v3.9.0
GOLANGCI_LINT_VERSION: v1.54.2
GOLANGCI_LINT_TIMEOUT: 10m
GIT_USER: botkube-dev

concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || 'branch' }} # scope to for the current workflow
Expand All @@ -27,6 +28,11 @@ jobs:
- name: Verify Go modules
run: go mod verify
if: always()
- name: Setup Go modules
uses: ./.github/actions/go-private
with:
access_token: ${{ secrets.E2E_TEST_GH_DEV_ACCOUNT_PAT }}
username: ${{ env.GIT_USER }}
- name: Run Go import formatting
run: make go-import-fmt
if: always()
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/pr-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ on:
types: [ opened, synchronize, reopened ]
branches:
- "main"
- "teams/integration-tests"
paths-ignore:
- 'branding/**'
- 'design/**'
Expand Down Expand Up @@ -235,7 +234,7 @@ jobs:
run: "k3d cluster create ${{ matrix.integration }}-test-cluster --wait --timeout=5m"

- name: Install Botkube to test ${{ matrix.integration }}
# if: matrix.integration == 'discord'
if: matrix.integration == 'discord'
env:
DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
DISCORD_BOT_ID: ${{ secrets.DISCORD_BOT_ID }}
Expand Down
5 changes: 3 additions & 2 deletions pkg/bot/teams_cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"golang.org/x/exp/maps"

Check failure on line 7 in pkg/bot/teams_cloud.go

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not `goimports`-ed (goimports)

Check failure on line 7 in pkg/bot/teams_cloud.go

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not `goimports`-ed (goimports)
"regexp"
"strings"
"sync"
Expand Down Expand Up @@ -118,9 +119,9 @@ func (b *CloudTeams) Start(ctx context.Context) error {
})
}

// SendMessageToAll sends the message to MS CloudTeams to all conversations.
// SendMessageToAll sends the message to MS CloudTeams to all conversations even if notifications are disabled.
func (b *CloudTeams) SendMessageToAll(ctx context.Context, msg interactive.CoreMessage) error {
return b.sendAgentActivity(ctx, msg, b.getChannelsToNotify(nil))
return b.sendAgentActivity(ctx, msg, maps.Values(b.getChannels()))

Check failure on line 124 in pkg/bot/teams_cloud.go

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not `gofmt`-ed with `-s` (gofmt)

Check failure on line 124 in pkg/bot/teams_cloud.go

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not `gofmt`-ed with `-s` (gofmt)
}

// SendMessage sends the message to MS CloudTeams to selected conversations.
Expand Down
7 changes: 0 additions & 7 deletions test/commplatform/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,6 @@ func (d DriverType) IsCloud() bool {
}
}

//// AssertContains checks if message contains expected message
//func (d DriverType) AssertContains(expectedMessage string) MessageAssertion {
// return func(msg string) (bool, int, string) {
// return strings.Contains(msg, expectedMessage), 0, ""
// }
//}

// AssertEquals checks if message is equal to expected message
func (d DriverType) AssertEquals(expectedMessage string) MessageAssertion {
return func(msg string) (bool, int, string) {
Expand Down
26 changes: 13 additions & 13 deletions test/commplatform/teams_tester.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,12 @@ func (s *TeamsTester) InitUsers(t *testing.T) {
func (s *TeamsTester) InitChannels(t *testing.T) []func() {
t.Helper()

//channels, err := s.cli.GetChannels(context.Background(), s.cfg.OrganizationTeamID)
//assert.NoError(t, err)
//for _, i := range channels {
// err := s.cli.DeleteChannel(context.Background(), s.cfg.OrganizationTeamID, i)
// assert.NoError(t, err)
//}
channels, err := s.cli.GetChannels(context.Background(), s.cfg.OrganizationTeamID)
assert.NoError(t, err)
for _, i := range channels {
err := s.cli.DeleteChannel(context.Background(), s.cfg.OrganizationTeamID, i)
assert.NoError(t, err)
}

firstChannel, cleanupFirstChannelFn := s.CreateChannel(t, "first")
s.firstChannel = firstChannel
Expand All @@ -170,7 +170,7 @@ func (s *TeamsTester) Type() DriverType {
}

func (s *TeamsTester) BotName() string {
return fmt.Sprintf("<@%s>", s.cfg.BotDevName)
return fmt.Sprintf("<at>%s</at>", s.cfg.BotDevName)
}

func (s *TeamsTester) BotUserID() string {
Expand Down Expand Up @@ -389,12 +389,12 @@ func (s *TeamsTester) CreateChannel(t *testing.T, prefix string) (Channel, func(

// AssertEquals checks if message is equal to expected message.
func (s *TeamsTester) AssertEquals(expectedMsg string) MessageAssertion {
return func(msg string) (bool, int, string) {
msg, expectedMsg = NormalizeTeamsWhitespacesInMessages(msg, expectedMsg)

if !strings.EqualFold(expectedMsg, msg) {
count := diff.CountMatchBlock(expectedMsg, msg)
msgDiff := diff.Diff(expectedMsg, msg)
return func(gotMsg string) (bool, int, string) {
gotMsg, expectedMsg = NormalizeTeamsWhitespacesInMessages(gotMsg, expectedMsg)
expectedMsg = teamsx.ReplaceEmojiTagsWithActualOne(expectedMsg)
if !strings.EqualFold(expectedMsg, gotMsg) {
count := diff.CountMatchBlock(expectedMsg, gotMsg)
msgDiff := diff.Diff(expectedMsg, gotMsg)
return false, count, msgDiff
}
return true, 0, ""
Expand Down
81 changes: 31 additions & 50 deletions test/e2e/bots_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"bytes"
"context"
"fmt"
gqlModel "github.com/kubeshop/botkube-cloud/botkube-cloud-backend/pkg/graphql"
"net/http"
"regexp"
"strconv"
Expand Down Expand Up @@ -251,54 +252,11 @@ func runBotTest(t *testing.T,
t.Log("Waiting for Deployment")
err = waitForDeploymentReady(deployNsCli, appCfg.Deployment.Name, appCfg.Deployment.WaitTimeout)
require.NoError(t, err)
case commplatform.SlackBot:
t.Log("Creating Botkube Cloud instance...")
gqlCli := NewClientForAPIKey(appCfg.ConfigProvider.Endpoint, appCfg.ConfigProvider.ApiKey)
appCfg.ClusterName = botDriver.FirstChannel().Name()
deployment := gqlCli.MustCreateBasicDeploymentWithCloudSlack(t, appCfg.ClusterName, appCfg.ConfigProvider.SlackWorkspaceTeamID, botDriver.FirstChannel().Name(), botDriver.SecondChannel().Name(), botDriver.ThirdChannel().Name())
for _, alias := range aliases {
gqlCli.MustCreateAlias(t, alias[0], alias[1], alias[2], deployment.ID)
}
t.Cleanup(func() {
// We have a glitch on backend side and the logic below is a workaround for that.
// Tl;dr uninstalling Helm chart reports "DISCONNECTED" status, and deployment deletion reports "DELETED" status.
// If we do these two things too quickly, we'll run into resource version mismatch in repository logic.
// Read more here: https://github.com/kubeshop/botkube-cloud/pull/486#issuecomment-1604333794
for !botkubeDeploymentUninstalled {
t.Log("Waiting for Helm chart uninstallation, in order to proceed with deleting Botkube Cloud instance...")
time.Sleep(1 * time.Second)
}

t.Log("Helm chart uninstalled. Waiting a bit...")
time.Sleep(3 * time.Second) // ugly, but at least we will be pretty sure we won't run into the resource version mismatch

t.Log("Deleting Botkube Cloud instance...")
gqlCli.MustDeleteDeployment(t, graphql.ID(deployment.ID))
})

err = botkubex.Install(t, botkubex.InstallParams{
BinaryPath: appCfg.ConfigProvider.BotkubeCliBinaryPath,
HelmRepoDirectory: appCfg.ConfigProvider.HelmRepoDirectory,
ConfigProviderEndpoint: appCfg.ConfigProvider.Endpoint,
ConfigProviderIdentifier: deployment.ID,
ConfigProviderAPIKey: deployment.APIKey.Value,
ImageTag: appCfg.ConfigProvider.ImageTag,
ImageRegistry: appCfg.ConfigProvider.ImageRegistry,
ImageRepository: appCfg.ConfigProvider.ImageRepository,
PluginRestartPolicyThreshold: 1,
PluginRestartHealthCheckIntervalSeconds: 2,
})
require.NoError(t, err)
t.Cleanup(func() {
t.Log("Uninstalling Helm chart...")
botkubex.Uninstall(t, appCfg.ConfigProvider.BotkubeCliBinaryPath)
botkubeDeploymentUninstalled = true
})
case commplatform.TeamsBot:
case commplatform.SlackBot, commplatform.TeamsBot:
t.Log("Creating Botkube Cloud instance...")
gqlCli := NewClientForAPIKey(appCfg.ConfigProvider.Endpoint, appCfg.ConfigProvider.ApiKey)
appCfg.ClusterName = botDriver.FirstChannel().Name()
deployment := gqlCli.MustCreateBasicDeploymentWithCloudTeams(t, appCfg.ClusterName, appCfg.Teams.OrganizationTeamID, botDriver.FirstChannel().ID(), botDriver.SecondChannel().ID(), botDriver.ThirdChannel().ID())
deployment := createCloudDeployment(t, gqlCli, botDriver, appCfg)
for _, alias := range aliases {
gqlCli.MustCreateAlias(t, alias[0], alias[1], alias[2], deployment.ID)
}
Expand Down Expand Up @@ -332,7 +290,6 @@ func runBotTest(t *testing.T,
PluginRestartHealthCheckIntervalSeconds: 2,
})
require.NoError(t, err)

t.Cleanup(func() {
t.Log("Uninstalling Helm chart...")
botkubex.Uninstall(t, appCfg.ConfigProvider.BotkubeCliBinaryPath)
Expand Down Expand Up @@ -386,6 +343,7 @@ func runBotTest(t *testing.T,
})

t.Run("Botkube PluginManagement", func(t *testing.T) {
t.Skip()
t.Run("Echo Executor success", func(t *testing.T) {
command := "echo test"
expectedBody := codeBlock(strings.ToUpper(command))
Expand Down Expand Up @@ -575,6 +533,7 @@ func runBotTest(t *testing.T,
})

t.Run("Show config", func(t *testing.T) {
t.Skip()
t.Run("With custom cluster name and filter", func(t *testing.T) {
command := fmt.Sprintf("show config --filter=cacheDir --cluster-name %s", appCfg.ClusterName)
expectedFilteredBody := codeBlock(heredoc.Doc(`cacheDir: /tmp`))
Expand Down Expand Up @@ -616,6 +575,7 @@ func runBotTest(t *testing.T,
})

t.Run("Executor", func(t *testing.T) {
t.Skip()
hasValidHeader := func(cmd, msg string) bool {
if botDriver.Type() == commplatform.TeamsBot {
// Teams uses AdaptiveCard and the built-in table format, that's the reason why we can't
Expand Down Expand Up @@ -1733,12 +1693,23 @@ func waitForRestart(t *testing.T, tester commplatform.BotDriver, userID, channel
t.Log("Waiting for restart...")
originalTimeout := tester.Timeout()
tester.SetTimeout(90 * time.Second)
if tester.Type() == commplatform.TeamsBot {
tester.SetTimeout(120 * time.Second)
}
// 2, since time to time latest message becomes upgrade message right after begin message
err := tester.WaitForMessagePosted(userID, channel, 2, func(content string) (bool, int, string) {
return content == fmt.Sprintf("My watch begins for cluster '%s'! :crossed_swords:", clusterName), 0, ""
})
expMsg := fmt.Sprintf("My watch begins for cluster '%s'! :crossed_swords:", clusterName)

assertFn := tester.AssertEquals(expMsg)
if tester.Type() == commplatform.TeamsBot { // teams sends AdaptiveCard not a plaintext message
expMsg = fmt.Sprintf("My watch begins for cluster '%s'!", clusterName)
assertFn = func(msg string) (bool, int, string) {
return strings.Contains(msg, expMsg), 0, ""
}
}

err := tester.WaitForMessagePosted(userID, channel, 2, assertFn)
assert.NoError(t, err)
tester.SetTimeout(originalTimeout)
require.NoError(t, err)
}

func hasAllColumns(msg string, headerColumnNames ...string) bool {
Expand Down Expand Up @@ -1812,3 +1783,13 @@ func waitForLastMessageWithHeaderEqual(cfg Config, driver commplatform.BotDriver
return driver.WaitForLastMessageEqual(driver.BotUserID(), driver.FirstChannel().ID(), expectedMessage)
}
}

func createCloudDeployment(t *testing.T, gqlCli *Client, driver commplatform.BotDriver, appCfg Config) *gqlModel.Deployment {
switch driver.Type() {
case commplatform.TeamsBot:
return gqlCli.MustCreateBasicDeploymentWithCloudTeams(t, appCfg.ClusterName, appCfg.Teams.OrganizationTeamID, driver.FirstChannel().ID(), driver.SecondChannel().ID(), driver.ThirdChannel().ID())
case commplatform.SlackBot:
return gqlCli.MustCreateBasicDeploymentWithCloudSlack(t, appCfg.ClusterName, appCfg.ConfigProvider.SlackWorkspaceTeamID, driver.FirstChannel().Name(), driver.SecondChannel().Name(), driver.ThirdChannel().Name())
}
return nil
}
10 changes: 5 additions & 5 deletions test/e2e/gql_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (c *Client) CreateBasicDeploymentWithCloudSlack(t *testing.T, clusterName,
Groups: []*gqlModel.PluginConfigurationGroupInput{
{
Name: "botkube/kubernetes",
DisplayName: "K8s recommendations", // Add commands: null
DisplayName: "K8s recommendations",
Type: gqlModel.PluginTypeSource,
Configurations: []*gqlModel.PluginConfigurationInput{
{
Expand Down Expand Up @@ -103,7 +103,7 @@ func (c *Client) CreateBasicDeploymentWithCloudSlack(t *testing.T, clusterName,
},
{
Name: "botkube/kubernetes",
DisplayName: "K8s ConfigMaps updates", // Add commands: null
DisplayName: "K8s ConfigMaps updates",
Type: gqlModel.PluginTypeSource,
Configurations: []*gqlModel.PluginConfigurationInput{
{
Expand All @@ -116,7 +116,7 @@ func (c *Client) CreateBasicDeploymentWithCloudSlack(t *testing.T, clusterName,
},
{
Name: "botkube/kubernetes",
DisplayName: "K8s ConfigMaps updates", // Add commands: null
DisplayName: "K8s ConfigMaps updates",
Type: gqlModel.PluginTypeSource,
Configurations: []*gqlModel.PluginConfigurationInput{
{
Expand Down Expand Up @@ -451,8 +451,8 @@ func (c *Client) CreateBasicDeploymentWithCloudTeams(t *testing.T, clusterName,
{
Name: "botkube/kubernetes",
DisplayName: "K8s recommendations",
Type: gqlModel.PluginTypeSource,
Enabled: true,
Type: gqlModel.PluginTypeSource,
Configurations: []*gqlModel.PluginConfigurationUpdateInput{
{
Name: "k8s-events",
Expand Down Expand Up @@ -623,7 +623,7 @@ func (c *Client) CreateBasicDeploymentWithCloudTeams(t *testing.T, clusterName,
},
{
Name: "botkube/kubectl",
DisplayName: "Not bounded",
DisplayName: "Not bound",
Enabled: true,
Type: gqlModel.PluginTypeExecutor,
Configurations: []*gqlModel.PluginConfigurationUpdateInput{
Expand Down
2 changes: 1 addition & 1 deletion test/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -235,5 +235,5 @@ require (
replace (
github.com/DanielTitkov/go-adaptive-cards => github.com/kubeshop/go-adaptive-cards v0.0.0-20231114223529-d6d8b980f0c8
github.com/kubeshop/botkube => ./..
github.com/kubeshop/botkube-cloud/botkube-cloud-backend => github.com/kubeshop/botkube-cloud/botkube-cloud-backend v0.0.0-20240129114748-2df001dcc99c
github.com/kubeshop/botkube-cloud/botkube-cloud-backend => github.com/kubeshop/botkube-cloud/botkube-cloud-backend v0.0.0-20240129135238-fd2ca2a74e57
)
4 changes: 2 additions & 2 deletions test/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -845,8 +845,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubeshop/botkube-cloud/botkube-cloud-backend v0.0.0-20240129114748-2df001dcc99c h1:eDVrc/2/WfLNyLksOkLd4NwpO5Zz2hWwX3aanAlKdbE=
github.com/kubeshop/botkube-cloud/botkube-cloud-backend v0.0.0-20240129114748-2df001dcc99c/go.mod h1:SD2/+mnfjuLdtDTY32UjpIx9zzq4c8z6bgb/K9T1fGY=
github.com/kubeshop/botkube-cloud/botkube-cloud-backend v0.0.0-20240129135238-fd2ca2a74e57 h1:su5cRQoejr2TxvVBUQRwCSBtegP5Rgp5BpsMJWbjiCs=
github.com/kubeshop/botkube-cloud/botkube-cloud-backend v0.0.0-20240129135238-fd2ca2a74e57/go.mod h1:SD2/+mnfjuLdtDTY32UjpIx9zzq4c8z6bgb/K9T1fGY=
github.com/kubeshop/go-adaptive-cards v0.0.0-20231114223529-d6d8b980f0c8 h1:uTChAaS5OdD9gGXnafXMUhMo1gyyX2loCjoCyQr5mlg=
github.com/kubeshop/go-adaptive-cards v0.0.0-20231114223529-d6d8b980f0c8/go.mod h1:RtCzt65p/zEos6+zhiCFQmiaHmro6M63l9NP7xXx/Lg=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
Expand Down

0 comments on commit 725a88e

Please sign in to comment.