Skip to content

Commit

Permalink
chore: Parallelize EnsureCleanState for e2e tests, adding timing info…
Browse files Browse the repository at this point in the history
…rmation (#20998)

* chore: Parallelize EnsureCleanState for e2e tests, adding timing information

Closes #20968
Closes #20967

A number of cleanup and create steps can be done in parallel, reducing the total runtime. Gather timing information as well and log it.

Signed-off-by: Andrii Korotkov <[email protected]>

* Add underscores to function map keys

Signed-off-by: Andrii Korotkov <[email protected]>

* Have separate log statements for timing fields, since everything doesn't fit in Github logs and gets truncated

Signed-off-by: Andrii Korotkov <[email protected]>

* Re-run tests

Signed-off-by: Andrii Korotkov <[email protected]>

* Fix duplicate removal attempts, cleanup things in namespaces before removing namespaces

Signed-off-by: Andrii Korotkov <[email protected]>

* Combine config map cleanups, since they seem to have some kind of locking based on timings

Signed-off-by: Andrii Korotkov <[email protected]>

* Re-order some cleanups to not wait if something is already covered by no wait commands

Signed-off-by: Andrii Korotkov <[email protected]>

* Move rm temp dir to be together with re-creation, since otherwise repo server watcher seems to fail

Signed-off-by: Andrii Korotkov <[email protected]>

* Only update config maps and login as admin if there were any changes

Signed-off-by: Andrii Korotkov <[email protected]>

* Also check for user being logged in

Signed-off-by: Andrii Korotkov <[email protected]>

* Improve config maps equivalency check

Signed-off-by: Andrii Korotkov <[email protected]>

* Remove timing information

Signed-off-by: Andrii Korotkov <[email protected]>

* Improve loops with sleep

Signed-off-by: Andrii Korotkov <[email protected]>

* Properly propagate and handle errors for parallel functions

Signed-off-by: Andrii Korotkov <[email protected]>

* Add missing CheckError

Signed-off-by: Andrii Korotkov <[email protected]>

* Fix import

Signed-off-by: Andrii Korotkov <[email protected]>

* Fix imports linter error (try 2)

Signed-off-by: Andrii Korotkov <[email protected]>

* Parallelize EnsureCleanState for application sets

Signed-off-by: Andrii Korotkov <[email protected]>

* Fix errors.IsNotFound

Signed-off-by: Andrii Korotkov <[email protected]>

* Use errgroup to run functions in parallel

Signed-off-by: Andrii Korotkov <[email protected]>

* Remove name keys for functions as unused

Signed-off-by: Andrii Korotkov <[email protected]>

* Use apierr directly

Signed-off-by: Andrii Korotkov <[email protected]>

---------

Signed-off-by: Andrii Korotkov <[email protected]>
  • Loading branch information
andrii-korotkov-verkada authored Dec 2, 2024
1 parent 5fc306e commit bd5d76f
Show file tree
Hide file tree
Showing 20 changed files with 559 additions and 324 deletions.
4 changes: 2 additions & 2 deletions test/e2e/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ func TestCreateAndUseAccountCLI(t *testing.T) {
assert.Equal(t, `NAME ENABLED CAPABILITIES
admin true login`, output)

SetAccounts(map[string][]string{
errors.CheckError(SetAccounts(map[string][]string{
"test": {"login", "apiKey"},
})
}))

output, err = RunCli("account", "list")
errors.CheckError(err)
Expand Down
5 changes: 3 additions & 2 deletions test/e2e/app_deletion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ import (
. "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
. "github.com/argoproj/argo-cd/v2/test/e2e/fixture"
. "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app"
"github.com/argoproj/argo-cd/v2/util/errors"
)

// when a app gets stuck in sync, and we try to delete it, it won't delete, instead we must then terminate it
// and deletion will then just happen
func TestDeletingAppStuckInSync(t *testing.T) {
Given(t).
And(func() {
SetResourceOverrides(map[string]ResourceOverride{
errors.CheckError(SetResourceOverrides(map[string]ResourceOverride{
"ConfigMap": {
HealthLua: `return { status = obj.annotations and obj.annotations['health'] or 'Progressing' }`,
},
})
}))
}).
Async(true).
Path("hook-custom-health").
Expand Down
16 changes: 8 additions & 8 deletions test/e2e/app_management_ns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -852,14 +852,14 @@ func TestNamespacedKnownTypesInCRDDiffing(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
When().
And(func() {
SetResourceOverrides(map[string]ResourceOverride{
CheckError(SetResourceOverrides(map[string]ResourceOverride{
"argoproj.io/Dummy": {
KnownTypeFields: []KnownTypeField{{
Field: "spec",
Type: "core/v1/ResourceList",
}},
},
})
}))
}).
Refresh(RefreshTypeNormal).
Then().
Expand Down Expand Up @@ -2232,14 +2232,14 @@ definitions:
SetTrackingMethod("annotation").
Path("crd-subresource").
And(func() {
SetResourceOverrides(map[string]ResourceOverride{
CheckError(SetResourceOverrides(map[string]ResourceOverride{
"argoproj.io/StatusSubResource": {
Actions: actions,
},
"argoproj.io/NonStatusSubResource": {
Actions: actions,
},
})
}))
}).
When().CreateApp().Sync().Then().
Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expand Down Expand Up @@ -2320,14 +2320,14 @@ func TestNamespacedAppWaitOperationInProgress(t *testing.T) {
SetAppNamespace(AppNamespace()).
SetTrackingMethod("annotation").
And(func() {
SetResourceOverrides(map[string]ResourceOverride{
CheckError(SetResourceOverrides(map[string]ResourceOverride{
"batch/Job": {
HealthLua: `return { status = 'Running' }`,
},
"apps/Deployment": {
HealthLua: `return { status = 'Suspended' }`,
},
})
}))
}).
Async(true).
Path("hook-and-deployment").
Expand Down Expand Up @@ -2438,9 +2438,9 @@ func TestNamespacedDisableManifestGeneration(t *testing.T) {
}).
When().
And(func() {
SetEnableManifestGeneration(map[ApplicationSourceType]bool{
CheckError(SetEnableManifestGeneration(map[ApplicationSourceType]bool{
ApplicationSourceTypeKustomize: false,
})
}))
}).
Refresh(RefreshTypeHard).
Then().
Expand Down
18 changes: 9 additions & 9 deletions test/e2e/app_management_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -998,14 +998,14 @@ func TestKnownTypesInCRDDiffing(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
When().
And(func() {
SetResourceOverrides(map[string]ResourceOverride{
CheckError(SetResourceOverrides(map[string]ResourceOverride{
"argoproj.io/Dummy": {
KnownTypeFields: []KnownTypeField{{
Field: "spec",
Type: "core/v1/ResourceList",
}},
},
})
}))
}).
Refresh(RefreshTypeNormal).
Then().
Expand Down Expand Up @@ -2360,14 +2360,14 @@ definitions:
Given(t).
Path("crd-subresource").
And(func() {
SetResourceOverrides(map[string]ResourceOverride{
CheckError(SetResourceOverrides(map[string]ResourceOverride{
"argoproj.io/StatusSubResource": {
Actions: actions,
},
"argoproj.io/NonStatusSubResource": {
Actions: actions,
},
})
}))
}).
When().CreateApp().Sync().Then().
Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expand Down Expand Up @@ -2445,14 +2445,14 @@ func TestAppWaitOperationInProgress(t *testing.T) {
ctx := Given(t)
ctx.
And(func() {
SetResourceOverrides(map[string]ResourceOverride{
CheckError(SetResourceOverrides(map[string]ResourceOverride{
"batch/Job": {
HealthLua: `return { status = 'Running' }`,
},
"apps/Deployment": {
HealthLua: `return { status = 'Suspended' }`,
},
})
}))
}).
Async(true).
Path("hook-and-deployment").
Expand Down Expand Up @@ -2554,9 +2554,9 @@ func TestDisableManifestGeneration(t *testing.T) {
}).
When().
And(func() {
SetEnableManifestGeneration(map[ApplicationSourceType]bool{
CheckError(SetEnableManifestGeneration(map[ApplicationSourceType]bool{
ApplicationSourceTypeKustomize: false,
})
}))
}).
Refresh(RefreshTypeHard).
Then().
Expand Down Expand Up @@ -2758,7 +2758,7 @@ func TestSwitchTrackingLabel(t *testing.T) {
func TestAnnotationTrackingExtraResources(t *testing.T) {
ctx := Given(t)

SetTrackingMethod(string(argo.TrackingMethodAnnotation))
CheckError(SetTrackingMethod(string(argo.TrackingMethodAnnotation)))
ctx.
Path("deployment").
When().
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/app_namespaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ func TestForbiddenNamespace(t *testing.T) {
func TestDeletingNamespacedAppStuckInSync(t *testing.T) {
ctx := Given(t)
ctx.And(func() {
SetResourceOverrides(map[string]ResourceOverride{
CheckError(SetResourceOverrides(map[string]ResourceOverride{
"ConfigMap": {
HealthLua: `return { status = obj.annotations and obj.annotations['health'] or 'Progressing' }`,
},
})
}))
}).
Async(true).
SetAppNamespace(AppNamespace()).
Expand Down
5 changes: 3 additions & 2 deletions test/e2e/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/clusterauth"
"github.com/argoproj/argo-cd/v2/util/errors"

"github.com/argoproj/gitops-engine/pkg/health"
. "github.com/argoproj/gitops-engine/pkg/sync/common"
Expand Down Expand Up @@ -52,7 +53,7 @@ func TestDeployment(t *testing.T) {
func TestDeploymentWithAnnotationTrackingMode(t *testing.T) {
ctx := Given(t)

SetTrackingMethod(string(argo.TrackingMethodAnnotation))
errors.CheckError(SetTrackingMethod(string(argo.TrackingMethodAnnotation)))
ctx.
Path("deployment").
When().
Expand All @@ -75,7 +76,7 @@ func TestDeploymentWithAnnotationTrackingMode(t *testing.T) {

func TestDeploymentWithLabelTrackingMode(t *testing.T) {
ctx := Given(t)
SetTrackingMethod(string(argo.TrackingMethodLabel))
errors.CheckError(SetTrackingMethod(string(argo.TrackingMethodLabel)))
ctx.
Path("deployment").
When().
Expand Down
11 changes: 6 additions & 5 deletions test/e2e/fixture/account/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package project

import (
"github.com/argoproj/argo-cd/v2/test/e2e/fixture"
"github.com/argoproj/argo-cd/v2/util/errors"
)

// this implements the "when" part of given/when/then
Expand Down Expand Up @@ -46,25 +47,25 @@ func (a *Actions) prepareSetPasswordArgs(account string) []string {
}

func (a *Actions) Create() *Actions {
fixture.SetAccounts(map[string][]string{
errors.CheckError(fixture.SetAccounts(map[string][]string{
a.context.name: {"login"},
})
}))
_, _ = fixture.RunCli(a.prepareSetPasswordArgs(a.context.name)...)
return a
}

func (a *Actions) SetPermissions(permissions []fixture.ACL, roleName string) *Actions {
fixture.SetPermissions(permissions, a.context.name, roleName)
errors.CheckError(fixture.SetPermissions(permissions, a.context.name, roleName))
return a
}

func (a *Actions) SetParamInSettingConfigMap(key, value string) *Actions {
fixture.SetParamInSettingConfigMap(key, value)
errors.CheckError(fixture.SetParamInSettingConfigMap(key, value))
return a
}

func (a *Actions) Login() *Actions {
fixture.LoginAs(a.context.name)
errors.CheckError(fixture.LoginAs(a.context.name))
return a
}

Expand Down
8 changes: 4 additions & 4 deletions test/e2e/fixture/app/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ func (a *Actions) Wait(args ...string) *Actions {
}

func (a *Actions) SetParamInSettingConfigMap(key, value string) *Actions {
fixture.SetParamInSettingConfigMap(key, value)
errors.CheckError(fixture.SetParamInSettingConfigMap(key, value))
return a
}

Expand Down Expand Up @@ -477,16 +477,16 @@ func (a *Actions) verifyAction() {
}

func (a *Actions) SetTrackingMethod(trackingMethod string) *Actions {
fixture.SetTrackingMethod(trackingMethod)
errors.CheckError(fixture.SetTrackingMethod(trackingMethod))
return a
}

func (a *Actions) SetInstallationID(installationID string) *Actions {
fixture.SetInstallationID(installationID)
errors.CheckError(fixture.SetInstallationID(installationID))
return a
}

func (a *Actions) SetTrackingLabel(trackingLabel string) *Actions {
fixture.SetTrackingLabel(trackingLabel)
errors.CheckError(fixture.SetTrackingLabel(trackingLabel))
return a
}
6 changes: 3 additions & 3 deletions test/e2e/fixture/app/consequences.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ func (c *Consequences) Expect(e Expectation) *Consequences {
sleepIntervalsIdx := -1
timeout := time.Duration(c.timeout) * time.Second
for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepIntervals[sleepIntervalsIdx]) {
if sleepIntervalsIdx < len(sleepIntervals)-1 {
sleepIntervalsIdx++
}
state, message = e(c)
switch state {
case succeeded:
Expand All @@ -48,9 +51,6 @@ func (c *Consequences) Expect(e Expectation) *Consequences {
return c
}
log.Infof("pending: %s", message)
if sleepIntervalsIdx < len(sleepIntervals)-1 {
sleepIntervalsIdx++
}
}
c.context.t.Fatal("timeout waiting for: " + message)
return c
Expand Down
13 changes: 7 additions & 6 deletions test/e2e/fixture/app/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/env"
"github.com/argoproj/argo-cd/v2/util/errors"
"github.com/argoproj/argo-cd/v2/util/settings"
)

Expand Down Expand Up @@ -104,7 +105,7 @@ func (c *Context) AppNamespace() string {

func (c *Context) SetAppNamespace(namespace string) *Context {
c.appNamespace = namespace
// fixture.SetParamInSettingConfigMap("application.resourceTrackingMethod", "annotation")
// errors.CheckError(fixture.SetParamInSettingConfigMap("application.resourceTrackingMethod", "annotation"))
return c
}

Expand Down Expand Up @@ -211,7 +212,7 @@ func (c *Context) SSHCredentialsAdded() *Context {
}

func (c *Context) ProjectSpec(spec v1alpha1.AppProjectSpec) *Context {
fixture.SetProjectSpec(c.project, spec)
errors.CheckError(fixture.SetProjectSpec(c.project, spec))
return c
}

Expand Down Expand Up @@ -296,12 +297,12 @@ func (c *Context) NameSuffix(nameSuffix string) *Context {
}

func (c *Context) ResourceOverrides(overrides map[string]v1alpha1.ResourceOverride) *Context {
fixture.SetResourceOverrides(overrides)
errors.CheckError(fixture.SetResourceOverrides(overrides))
return c
}

func (c *Context) ResourceFilter(filter settings.ResourcesFilter) *Context {
fixture.SetResourceFilter(filter)
errors.CheckError(fixture.SetResourceFilter(filter))
return c
}

Expand Down Expand Up @@ -365,12 +366,12 @@ func (c *Context) HelmSkipTests() *Context {
}

func (c *Context) SetTrackingMethod(trackingMethod string) *Context {
fixture.SetTrackingMethod(trackingMethod)
errors.CheckError(fixture.SetTrackingMethod(trackingMethod))
return c
}

func (c *Context) SetInstallationID(installationID string) *Context {
fixture.SetTrackingMethod(installationID)
errors.CheckError(fixture.SetInstallationID(installationID))
return c
}

Expand Down
16 changes: 15 additions & 1 deletion test/e2e/fixture/applicationsets/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,21 @@ func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions {

var mostRecentError error

for start := time.Now(); time.Since(start) < timeout; time.Sleep(3 * time.Second) {
sleepIntervals := []time.Duration{
10 * time.Millisecond,
20 * time.Millisecond,
50 * time.Millisecond,
100 * time.Millisecond,
200 * time.Millisecond,
300 * time.Millisecond,
500 * time.Millisecond,
1 * time.Second,
}
sleepIntervalsIdx := -1
for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepIntervals[sleepIntervalsIdx]) {
if sleepIntervalsIdx < len(sleepIntervals)-1 {
sleepIntervalsIdx++
}
appSet, err := a.get()
mostRecentError = err
if err == nil {
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/fixture/applicationsets/consequences.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ func (c *Consequences) ExpectWithDuration(e Expectation, timeout time.Duration)
}
sleepIntervalsIdx := -1
for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepIntervals[sleepIntervalsIdx]) {
if sleepIntervalsIdx < len(sleepIntervals)-1 {
sleepIntervalsIdx++
}
state, message = e(c)
switch state {
case succeeded:
Expand All @@ -53,9 +56,6 @@ func (c *Consequences) ExpectWithDuration(e Expectation, timeout time.Duration)
return c
}
log.Infof("expectation pending: %s", message)
if sleepIntervalsIdx < len(sleepIntervals)-1 {
sleepIntervalsIdx++
}
}
c.context.t.Fatal("timeout waiting for: " + message)
return c
Expand Down
Loading

0 comments on commit bd5d76f

Please sign in to comment.