test(e2e): add isolation by ensuring unique name (#25724)

Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
This commit is contained in:
Alexandre Gaudreault
2026-01-09 12:15:08 -05:00
committed by GitHub
parent 79b0981b05
commit dab6f3bfae
62 changed files with 1279 additions and 1325 deletions

View File

@@ -19,7 +19,7 @@ func TestBackupExportImport(t *testing.T) {
var exportRawOutput string
ctx := Given(t)
// Create application in argocd namespace
appctx := appfixture.GivenWithSameState(t)
appctx := appfixture.GivenWithSameState(ctx)
var appTestNamespace Application
var appOtherNamespace Application

View File

@@ -15,8 +15,8 @@ import (
)
func TestNSAutoSyncSelfHealDisabled(t *testing.T) {
Given(t).
SetTrackingMethod("annotation").
ctx := Given(t)
ctx.SetTrackingMethod("annotation").
Path(guestbookPath).
SetAppNamespace(fixture.AppNamespace()).
// TODO: There is a bug with annotation tracking method that prevents
@@ -37,7 +37,7 @@ func TestNSAutoSyncSelfHealDisabled(t *testing.T) {
// app should not be auto-synced if k8s change detected
When().
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), metav1.PatchOptions{}))
}).
Then().
@@ -45,8 +45,8 @@ func TestNSAutoSyncSelfHealDisabled(t *testing.T) {
}
func TestNSAutoSyncSelfHealEnabled(t *testing.T) {
Given(t).
SetTrackingMethod("annotation").
ctx := Given(t)
ctx.SetTrackingMethod("annotation").
Path(guestbookPath).
SetAppNamespace(fixture.AppNamespace()).
When().
@@ -63,7 +63,7 @@ func TestNSAutoSyncSelfHealEnabled(t *testing.T) {
When().
// app should be auto-synced once k8s change detected
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), metav1.PatchOptions{}))
}).
Refresh(RefreshTypeNormal).

View File

@@ -18,8 +18,8 @@ import (
)
func TestAutoSyncSelfHealDisabled(t *testing.T) {
Given(t).
Path(guestbookPath).
ctx := Given(t)
ctx.Path(guestbookPath).
When().
// app should be auto-synced once created
CreateFromFile(func(app *Application) {
@@ -36,7 +36,7 @@ func TestAutoSyncSelfHealDisabled(t *testing.T) {
// app should not be auto-synced if k8s change detected
When().
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), metav1.PatchOptions{}))
}).
Refresh(RefreshTypeNormal).
@@ -45,8 +45,8 @@ func TestAutoSyncSelfHealDisabled(t *testing.T) {
}
func TestAutoSyncSelfHealEnabled(t *testing.T) {
Given(t).
Path(guestbookPath).
ctx := Given(t)
ctx.Path(guestbookPath).
When().
// app should be auto-synced once created
CreateFromFile(func(app *Application) {
@@ -61,7 +61,7 @@ func TestAutoSyncSelfHealEnabled(t *testing.T) {
When().
// app should be auto-synced once k8s change detected
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 0}}`), metav1.PatchOptions{}))
}).
Refresh(RefreshTypeNormal).

View File

@@ -48,8 +48,8 @@ func TestNamespacedGetLogsAllow(_ *testing.T) {
func TestNamespacedGetLogsDeny(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
accountFixture.Given(t).
Name("test").
accountCtx := accountFixture.Given(t)
accountCtx.Name("test").
When().
Create().
Login().
@@ -76,7 +76,7 @@ func TestNamespacedGetLogsDeny(t *testing.T) {
},
}, "app-creator")
ctx := GivenWithSameState(t)
ctx := GivenWithSameState(accountCtx)
ctx.SetAppNamespace(fixture.ArgoCDAppNamespace)
ctx.
Path("guestbook-logs").
@@ -95,8 +95,8 @@ func TestNamespacedGetLogsDeny(t *testing.T) {
func TestNamespacedGetLogsAllowNS(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
accountFixture.Given(t).
Name("test").
accountCtx := accountFixture.Given(t)
accountCtx.Name("test").
When().
Create().
Login().
@@ -128,7 +128,7 @@ func TestNamespacedGetLogsAllowNS(t *testing.T) {
},
}, "app-creator")
ctx := GivenWithSameState(t)
ctx := GivenWithSameState(accountCtx)
ctx.SetAppNamespace(fixture.AppNamespace())
ctx.
Path("guestbook-logs").
@@ -220,11 +220,11 @@ func TestNamespacedAppCreation(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
And(func(app *Application) {
assert.Equal(t, fixture.Name(), app.Name)
assert.Equal(t, ctx.GetName(), app.Name)
assert.Equal(t, fixture.AppNamespace(), app.Namespace)
assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL)
assert.Equal(t, guestbookPath, app.Spec.GetSource().Path)
assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(NamespacedEvent(fixture.AppNamespace(), EventReasonResourceCreated, "create")).
@@ -272,7 +272,7 @@ func TestNamespacedAppCreationWithoutForceUpdate(t *testing.T) {
assert.Equal(t, fixture.AppNamespace(), app.Namespace)
assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL)
assert.Equal(t, guestbookPath, app.Spec.GetSource().Path)
assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, "in-cluster", app.Spec.Destination.Name)
}).
Expect(NamespacedEvent(fixture.AppNamespace(), EventReasonResourceCreated, "create")).
@@ -314,7 +314,8 @@ func TestNamespacedDeleteAppResource(t *testing.T) {
// demonstrate that we cannot use a standard sync when an immutable field is changed, we must use "force"
func TestNamespacedImmutableChange(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
Given(t).
ctx := Given(t)
ctx.
Path("secrets").
SetTrackingMethod("annotation").
SetAppNamespace(fixture.AppNamespace()).
@@ -338,7 +339,7 @@ func TestNamespacedImmutableChange(t *testing.T) {
Expect(ResourceResultMatches(ResourceResult{
Kind: "Secret",
Version: "v1",
Namespace: fixture.DeploymentNamespace(),
Namespace: ctx.DeploymentNamespace(),
Name: "test-secret",
SyncPhase: "Sync",
Status: "SyncFailed",
@@ -394,16 +395,17 @@ func TestNamespacedAppDeletion(t *testing.T) {
func TestNamespacedAppLabels(t *testing.T) {
ctx := Given(t)
label := "id=" + ctx.ShortID()
ctx.
Path("config-map").
SetTrackingMethod("annotation").
SetAppNamespace(fixture.AppNamespace()).
When().
CreateApp("-l", "foo=bar").
CreateApp("-l", label).
Then().
And(func(_ *Application) {
assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list")), ctx.AppQualifiedName())
assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "foo=bar")), ctx.AppQualifiedName())
assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", label)), ctx.AppQualifiedName())
assert.NotContains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "foo=rubbish")), ctx.AppQualifiedName())
}).
Given().
@@ -418,11 +420,12 @@ func TestNamespacedAppLabels(t *testing.T) {
// check we can update the app and it is then sync'd
Given().
When().
Sync("-l", "foo=bar")
Sync("-l", label)
}
func TestNamespacedTrackAppStateAndSyncApp(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path(guestbookPath).
SetTrackingMethod("annotation").
SetAppNamespace(fixture.AppNamespace()).
@@ -433,8 +436,8 @@ func TestNamespacedTrackAppStateAndSyncApp(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced ", fixture.DeploymentNamespace()))).
Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced", fixture.DeploymentNamespace()))).
Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced ", ctx.DeploymentNamespace()))).
Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced", ctx.DeploymentNamespace()))).
Expect(NamespacedEvent(fixture.AppNamespace(), EventReasonResourceUpdated, "sync")).
And(func(app *Application) {
assert.NotNil(t, app.Status.OperationState.SyncResult)
@@ -604,12 +607,12 @@ func TestNamespacedAppWithSecrets(t *testing.T) {
_, err = fixture.RunCli("app", "patch-resource", ctx.AppQualifiedName(), "--resource-name", "test-secret",
"--kind", "Secret", "--patch", `{"op": "add", "path": "/data", "value": "hello"}'`,
"--patch-type", "application/json-patch+json")
require.ErrorContains(t, err, fmt.Sprintf("failed to patch Secret %s/test-secret", fixture.DeploymentNamespace()))
require.ErrorContains(t, err, fmt.Sprintf("failed to patch Secret %s/test-secret", ctx.DeploymentNamespace()))
assert.NotContains(t, err.Error(), "username")
assert.NotContains(t, err.Error(), "password")
// patch secret and make sure app is out of sync and diff detects the change
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Secrets(fixture.DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Secrets(ctx.DeploymentNamespace()).Patch(t.Context(),
"test-secret", types.JSONPatchType, []byte(`[
{"op": "remove", "path": "/data/username"},
{"op": "add", "path": "/stringData", "value": {"password": "foo"}}
@@ -673,7 +676,7 @@ func TestNamespacedResourceDiffing(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
// Patch deployment
_, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
_, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "test" }]`), metav1.PatchOptions{})
require.NoError(t, err)
}).
@@ -684,7 +687,7 @@ func TestNamespacedResourceDiffing(t *testing.T) {
And(func(_ *Application) {
diffOutput, err := fixture.RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", "testdata/guestbook")
require.Error(t, err)
assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", fixture.DeploymentNamespace()))
assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", ctx.DeploymentNamespace()))
}).
Given().
ResourceOverrides(map[string]ResourceOverride{"apps/Deployment": {
@@ -713,7 +716,7 @@ func TestNamespacedResourceDiffing(t *testing.T) {
}]`).
Sync().
And(func() {
output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", fixture.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", ctx.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
require.NoError(t, err)
assert.Contains(t, output, "serverside-applied")
}).
@@ -740,12 +743,12 @@ func TestNamespacedResourceDiffing(t *testing.T) {
"value": { "syncOptions": ["RespectIgnoreDifferences=true"] }
}]`).
And(func() {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(3), *deployment.Spec.RevisionHistoryLimit)
}).
And(func() {
output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", fixture.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", ctx.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
require.NoError(t, err)
assert.Contains(t, output, "serverside-applied")
}).
@@ -754,13 +757,13 @@ func TestNamespacedResourceDiffing(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(1), *deployment.Spec.RevisionHistoryLimit)
}).
When().Sync().Then().Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(1), *deployment.Spec.RevisionHistoryLimit)
})
@@ -782,7 +785,7 @@ func TestNamespacedKnownTypesInCRDDiffing(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeSynced)).
When().
And(func() {
dummyResIf := fixture.DynamicClientset.Resource(dummiesGVR).Namespace(fixture.DeploymentNamespace())
dummyResIf := fixture.DynamicClientset.Resource(dummiesGVR).Namespace(ctx.DeploymentNamespace())
patchData := []byte(`{"spec":{"cpu": "2"}}`)
errors.NewHandler(t).FailOnErr(dummyResIf.Patch(t.Context(), "dummy-crd-instance", types.MergePatchType, patchData, metav1.PatchOptions{}))
}).Refresh(RefreshTypeNormal).
@@ -869,7 +872,7 @@ func TestNamespacedResourceAction(t *testing.T) {
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
Version: ptr.To("v1"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(ctx.DeploymentNamespace()),
ResourceName: ptr.To("guestbook-ui"),
})
require.NoError(t, err)
@@ -880,14 +883,14 @@ func TestNamespacedResourceAction(t *testing.T) {
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
Version: ptr.To("v1"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(ctx.DeploymentNamespace()),
ResourceName: ptr.To("guestbook-ui"),
Action: ptr.To("sample"),
AppNamespace: ptr.To(fixture.AppNamespace()),
})
require.NoError(t, err)
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "test", deployment.Labels["sample"])
@@ -1023,7 +1026,7 @@ func TestNamespacedSyncAsync(t *testing.T) {
}
// assertResourceActions verifies if view/modify resource actions are successful/failing for given application
func assertNSResourceActions(t *testing.T, appName string, successful bool) {
func assertNSResourceActions(t *testing.T, appName string, deploymentNamespace string, successful bool) {
t.Helper()
assertError := func(err error, message string) {
if successful {
@@ -1036,7 +1039,7 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) {
closer, cdClient := fixture.ArgoCDClientset.NewApplicationClientOrDie()
defer utilio.Close(closer)
deploymentResource, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deploymentResource, err := fixture.KubeClientset.AppsV1().Deployments(deploymentNamespace).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
logs, err := cdClient.PodLogs(t.Context(), &applicationpkg.ApplicationPodLogsQuery{
@@ -1044,7 +1047,7 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) {
Kind: ptr.To("Deployment"),
Name: &appName,
AppNamespace: ptr.To(fixture.AppNamespace()),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(deploymentNamespace),
Container: ptr.To(""),
SinceSeconds: ptr.To(int64(0)),
TailLines: ptr.To(int64(0)),
@@ -1060,7 +1063,7 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) {
Name: &appName,
AppNamespace: ptr.To(fixture.AppNamespace()),
ResourceName: ptr.To("guestbook-ui"),
ResourceNamespace: ptr.To(fixture.DeploymentNamespace()),
ResourceNamespace: ptr.To(deploymentNamespace),
ResourceUID: ptr.To(string(deploymentResource.UID)),
})
assertError(err, fmt.Sprintf("%s not found as part of application %s", "guestbook-ui", appName))
@@ -1069,7 +1072,7 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) {
Name: &appName,
AppNamespace: ptr.To(fixture.AppNamespace()),
ResourceName: ptr.To("guestbook-ui"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(deploymentNamespace),
Version: ptr.To("v1"),
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
@@ -1080,7 +1083,7 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) {
Name: &appName,
AppNamespace: ptr.To(fixture.AppNamespace()),
ResourceName: ptr.To("guestbook-ui"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(deploymentNamespace),
Version: ptr.To("v1"),
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
@@ -1092,7 +1095,7 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) {
Name: &appName,
AppNamespace: ptr.To(fixture.AppNamespace()),
ResourceName: ptr.To("guestbook-ui"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(deploymentNamespace),
Version: ptr.To("v1"),
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
@@ -1102,22 +1105,20 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) {
func TestNamespacedPermissions(t *testing.T) {
appCtx := Given(t)
projName := "argo-project"
projActions := projectFixture.
Given(t).
Name(projName).
projCtx := projectFixture.GivenWithSameState(appCtx)
projActions := projCtx.
SourceNamespaces([]string{fixture.AppNamespace()}).
When().
Create()
sourceError := fmt.Sprintf("application repo %s is not permitted in project 'argo-project'", fixture.RepoURL(fixture.RepoURLTypeFile))
destinationError := fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project 'argo-project'", KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace())
sourceError := fmt.Sprintf("application repo %s is not permitted in project '%s'", fixture.RepoURL(fixture.RepoURLTypeFile), projCtx.GetName())
destinationError := fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project '%s'", KubernetesInternalAPIServerAddr, appCtx.DeploymentNamespace(), projCtx.GetName())
appCtx.
Path("guestbook-logs").
SetTrackingMethod("annotation").
SetAppNamespace(fixture.AppNamespace()).
Project(projName).
Project(projCtx.GetName()).
When().
IgnoreErrors().
// ensure app is not created if project permissions are missing
@@ -1138,7 +1139,7 @@ func TestNamespacedPermissions(t *testing.T) {
Then().
// make sure application resource actions are successful
And(func(app *Application) {
assertNSResourceActions(t, app.Name, true)
assertNSResourceActions(t, app.Name, appCtx.DeploymentNamespace(), true)
}).
When().
// remove projet permissions and "refresh" app
@@ -1175,29 +1176,27 @@ func TestNamespacedPermissions(t *testing.T) {
Then().
// make sure application resource actions are failing
And(func(app *Application) {
assertNSResourceActions(t, app.Name, false)
assertNSResourceActions(t, app.Name, appCtx.DeploymentNamespace(), false)
})
}
func TestNamespacedPermissionWithScopedRepo(t *testing.T) {
projName := "argo-project"
fixture.EnsureCleanState(t)
projectFixture.
Given(t).
Name(projName).
ctx := Given(t)
projCtx := projectFixture.GivenWithSameState(ctx)
projCtx.
SourceNamespaces([]string{fixture.AppNamespace()}).
Destination("*,*").
When().
Create()
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(fixture.RepoURL(fixture.RepoURLTypeFile)).
Project(projName).
Project(projCtx.GetName()).
Create()
GivenWithSameState(t).
Project(projName).
GivenWithSameState(ctx).
Project(projCtx.GetName()).
RepoURLType(fixture.RepoURLTypeFile).
Path("two-nice-pods").
SetTrackingMethod("annotation").
@@ -1221,22 +1220,19 @@ func TestNamespacedPermissionWithScopedRepo(t *testing.T) {
}
func TestNamespacedPermissionDeniedWithScopedRepo(t *testing.T) {
projName := "argo-project"
projectFixture.
Given(t).
Name(projName).
Destination("*,*").
ctx := projectFixture.Given(t)
ctx.Destination("*,*").
SourceNamespaces([]string{fixture.AppNamespace()}).
When().
Create()
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(fixture.RepoURL(fixture.RepoURLTypeFile)).
Create()
GivenWithSameState(t).
Project(projName).
GivenWithSameState(ctx).
Project(ctx.GetName()).
RepoURLType(fixture.RepoURLTypeFile).
SetTrackingMethod("annotation").
SetAppNamespace(fixture.AppNamespace()).
@@ -1409,7 +1405,8 @@ func TestNamespacedRevisionHistoryLimit(t *testing.T) {
func TestNamespacedOrphanedResource(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
Given(t).
ctx := Given(t)
ctx.
ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}},
@@ -1427,7 +1424,7 @@ func TestNamespacedOrphanedResource(t *testing.T) {
Expect(NoConditions()).
When().
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "orphaned-configmap",
},
@@ -1513,7 +1510,7 @@ func TestNamespacedNotPermittedResources(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "sample-ingress",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s_%s:networking/Ingress:%s/sample-ingress", fixture.AppNamespace(), ctx.AppName(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s_%s:networking/Ingress:%s/sample-ingress", fixture.AppNamespace(), ctx.AppName(), ctx.DeploymentNamespace()),
},
},
Spec: networkingv1.IngressSpec{
@@ -1544,7 +1541,7 @@ func TestNamespacedNotPermittedResources(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "guestbook-ui",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s_%s:Service:%s/guesbook-ui", fixture.TestNamespace(), ctx.AppQualifiedName(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s_%s:Service:%s/guesbook-ui", fixture.TestNamespace(), ctx.AppQualifiedName(), ctx.DeploymentNamespace()),
},
},
Spec: corev1.ServiceSpec{
@@ -1560,7 +1557,7 @@ func TestNamespacedNotPermittedResources(t *testing.T) {
ctx.ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []ApplicationDestination{{Namespace: fixture.DeploymentNamespace(), Server: "*"}},
Destinations: []ApplicationDestination{{Namespace: ctx.DeploymentNamespace(), Server: "*"}},
SourceNamespaces: []string{fixture.AppNamespace()},
NamespaceResourceBlacklist: []metav1.GroupKind{
{Group: "", Kind: "Service"},
@@ -1568,7 +1565,7 @@ func TestNamespacedNotPermittedResources(t *testing.T) {
}).
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Create(t.Context(), ingress, metav1.CreateOptions{}))
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Create(t.Context(), svc, metav1.CreateOptions{}))
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(ctx.DeploymentNamespace()).Create(t.Context(), svc, metav1.CreateOptions{}))
}).
Path(guestbookPath).
When().
@@ -1594,7 +1591,7 @@ func TestNamespacedNotPermittedResources(t *testing.T) {
// Make sure prohibited resources are not deleted during application deletion
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Get(t.Context(), "sample-ingress", metav1.GetOptions{}))
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}))
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}))
}
func TestNamespacedSyncWithInfos(t *testing.T) {
@@ -1694,7 +1691,8 @@ func TestNamespacedCreateAppWithNoNameSpaceWhenRequired2(t *testing.T) {
func TestNamespacedListResource(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
Given(t).
ctx := Given(t)
ctx.
SetAppNamespace(fixture.AppNamespace()).
SetTrackingMethod("annotation").
ProjectSpec(AppProjectSpec{
@@ -1712,7 +1710,7 @@ func TestNamespacedListResource(t *testing.T) {
Expect(NoConditions()).
When().
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "orphaned-configmap",
},
@@ -1970,7 +1968,7 @@ metadata:
labels:
test: "true"
annotations:
something: "whatevs"
something: "whatevs"
`
s := fmt.Sprintf(existingNs, updatedNamespace)
@@ -2087,7 +2085,8 @@ func TestNamespacedFailedSyncWithRetry(t *testing.T) {
}
func TestNamespacedCreateDisableValidation(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
SetAppNamespace(fixture.AppNamespace()).
SetTrackingMethod("annotation").
Path("baddir").
@@ -2096,7 +2095,7 @@ func TestNamespacedCreateDisableValidation(t *testing.T) {
Then().
And(func(app *Application) {
_, err := fixture.RunCli("app", "create", app.QualifiedName(), "--upsert", "--validate=false", "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
"--path", "baddir2", "--project", app.Spec.Project, "--dest-server", KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace())
"--path", "baddir2", "--project", app.Spec.Project, "--dest-server", KubernetesInternalAPIServerAddr, "--dest-namespace", ctx.DeploymentNamespace())
require.NoError(t, err)
}).
When().

View File

@@ -59,8 +59,8 @@ func TestGetLogsAllowNoSwitch(_ *testing.T) {
func TestGetLogsDeny(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login().
@@ -87,7 +87,7 @@ func TestGetLogsDeny(t *testing.T) {
},
}, "app-creator")
GivenWithSameState(t).
GivenWithSameState(ctx).
Path("guestbook-logs").
When().
CreateApp().
@@ -103,8 +103,8 @@ func TestGetLogsDeny(t *testing.T) {
func TestGetLogsAllow(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login().
@@ -136,7 +136,7 @@ func TestGetLogsAllow(t *testing.T) {
},
}, "app-creator")
GivenWithSameState(t).
GivenWithSameState(ctx).
Path("guestbook-logs").
When().
CreateApp().
@@ -329,10 +329,10 @@ func TestAppCreation(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
And(func(app *Application) {
assert.Equal(t, fixture.Name(), app.Name)
assert.Equal(t, ctx.GetName(), app.Name)
assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL)
assert.Equal(t, guestbookPath, app.Spec.GetSource().Path)
assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(Event(argo.EventReasonResourceCreated, "create")).
@@ -340,7 +340,7 @@ func TestAppCreation(t *testing.T) {
// app should be listed
output, err := fixture.RunCli("app", "list")
require.NoError(t, err)
assert.Contains(t, output, fixture.Name())
assert.Contains(t, output, ctx.GetName())
}).
When().
// ensure that create is idempotent
@@ -377,7 +377,7 @@ func TestAppCreationWithoutForceUpdate(t *testing.T) {
assert.Equal(t, ctx.AppName(), app.Name)
assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL)
assert.Equal(t, guestbookPath, app.Spec.GetSource().Path)
assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, "in-cluster", app.Spec.Destination.Name)
}).
Expect(Event(argo.EventReasonResourceCreated, "create")).
@@ -385,7 +385,7 @@ func TestAppCreationWithoutForceUpdate(t *testing.T) {
// app should be listed
output, err := fixture.RunCli("app", "list")
require.NoError(t, err)
assert.Contains(t, output, fixture.Name())
assert.Contains(t, output, ctx.GetName())
}).
When().
IgnoreErrors().
@@ -444,27 +444,27 @@ func TestGetAppResource(t *testing.T) {
Then().
Expect(HealthIs(health.HealthStatusHealthy)).
And(func(_ *Application) {
out, err := fixture.RunCli("app", "get-resource", fixture.Name(), "--kind", "Service", "--resource-name", "guestbook-ui")
out, err := fixture.RunCli("app", "get-resource", ctx.GetName(), "--kind", "Service", "--resource-name", "guestbook-ui")
require.NoError(t, err)
assert.Contains(t, out, "guestbook-ui")
}).
And(func(_ *Application) {
out, err := fixture.RunCli("app", "get-resource", fixture.Name(), "--kind", "Service", "--group", "", "--resource-name", "guestbook-ui")
out, err := fixture.RunCli("app", "get-resource", ctx.GetName(), "--kind", "Service", "--group", "", "--resource-name", "guestbook-ui")
require.NoError(t, err)
assert.Contains(t, out, "guestbook-ui")
}).
And(func(_ *Application) {
out, err := fixture.RunCli("app", "get-resource", fixture.Name(), "--kind", "Service", "--resource-name", "bad-guestbook-ui")
out, err := fixture.RunCli("app", "get-resource", ctx.GetName(), "--kind", "Service", "--resource-name", "bad-guestbook-ui")
require.NoError(t, err)
assert.NotContains(t, out, "guestbook-ui")
}).
And(func(_ *Application) {
out, err := fixture.RunCli("app", "get-resource", fixture.Name(), "--kind", "Service", "--group", "badgroup", "--resource-name", "guestbook-ui")
out, err := fixture.RunCli("app", "get-resource", ctx.GetName(), "--kind", "Service", "--group", "badgroup", "--resource-name", "guestbook-ui")
require.NoError(t, err)
assert.NotContains(t, out, "guestbook-ui")
}).
And(func(_ *Application) {
out, err := fixture.RunCli("app", "get-resource", fixture.Name(), "--kind", "Deployment", "--group", "apps", "--resource-name", "guestbook-ui")
out, err := fixture.RunCli("app", "get-resource", ctx.GetName(), "--kind", "Deployment", "--group", "apps", "--resource-name", "guestbook-ui")
require.NoError(t, err)
assert.Contains(t, out, "guestbook-ui")
})
@@ -482,7 +482,7 @@ func TestDeleteAppResource(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
// app should be listed
if _, err := fixture.RunCli("app", "delete-resource", fixture.Name(), "--kind", "Service", "--resource-name", "guestbook-ui"); err != nil {
if _, err := fixture.RunCli("app", "delete-resource", ctx.GetName(), "--kind", "Service", "--resource-name", "guestbook-ui"); err != nil {
require.NoError(t, err)
}
}).
@@ -510,8 +510,8 @@ func TestPatchHttp(t *testing.T) {
// demonstrate that we cannot use a standard sync when an immutable field is changed, we must use "force"
func TestImmutableChange(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
Given(t).
Path("secrets").
ctx := Given(t)
ctx.Path("secrets").
When().
CreateApp().
PatchFile("secrets.yaml", `[{"op": "add", "path": "/data/new-field", "value": "dGVzdA=="}, {"op": "add", "path": "/immutable", "value": true}]`).
@@ -532,7 +532,7 @@ func TestImmutableChange(t *testing.T) {
Expect(ResourceResultMatches(ResourceResult{
Kind: "Secret",
Version: "v1",
Namespace: fixture.DeploymentNamespace(),
Namespace: ctx.DeploymentNamespace(),
Name: "test-secret",
SyncPhase: "Sync",
Status: "SyncFailed",
@@ -564,7 +564,8 @@ func TestInvalidAppProject(t *testing.T) {
}
func TestAppDeletion(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path(guestbookPath).
When().
CreateApp().
@@ -578,38 +579,40 @@ func TestAppDeletion(t *testing.T) {
output, err := fixture.RunCli("app", "list")
require.NoError(t, err)
assert.NotContains(t, output, fixture.Name())
assert.NotContains(t, output, ctx.GetName())
}
func TestAppLabels(t *testing.T) {
Given(t).
ctx := Given(t)
label := "id=" + ctx.ShortID()
ctx.
Path("config-map").
When().
CreateApp("-l", "foo=bar").
CreateApp("-l", label).
Then().
And(func(_ *Application) {
assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list")), fixture.Name())
assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "foo=bar")), fixture.Name())
assert.NotContains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "foo=rubbish")), fixture.Name())
assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list")), ctx.GetName())
assert.Contains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", label)), ctx.GetName())
assert.NotContains(t, errors.NewHandler(t).FailOnErr(fixture.RunCli("app", "list", "-l", "id=rubbish")), ctx.GetName())
}).
Given().
// remove both name and replace labels means nothing will sync
Name("").
When().
IgnoreErrors().
Sync("-l", "foo=rubbish").
Sync("-l", "id=rubbish").
DoNotIgnoreErrors().
Then().
Expect(Error("", "No matching apps found for filter: selector foo=rubbish")).
Expect(Error("", "No matching apps found for filter: selector id=rubbish")).
// check we can update the app and it is then sync'd
Given().
When().
Sync("-l", "foo=bar")
Sync("-l", label)
}
func TestTrackAppStateAndSyncApp(t *testing.T) {
Given(t).
Path(guestbookPath).
ctx := Given(t)
ctx.Path(guestbookPath).
When().
CreateApp().
Sync().
@@ -618,8 +621,8 @@ func TestTrackAppStateAndSyncApp(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced ", fixture.DeploymentNamespace()))).
Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced", fixture.DeploymentNamespace()))).
Expect(Success(fmt.Sprintf("Service %s guestbook-ui Synced ", ctx.DeploymentNamespace()))).
Expect(Success(fmt.Sprintf("apps Deployment %s guestbook-ui Synced", ctx.DeploymentNamespace()))).
Expect(Event(argo.EventReasonResourceUpdated, "sync")).
And(func(app *Application) {
assert.NotNil(t, app.Status.OperationState.SyncResult)
@@ -682,13 +685,13 @@ func TestComparisonFailsIfClusterNotAdded(t *testing.T) {
}
func TestComparisonFailsIfDestinationClusterIsInvalid(t *testing.T) {
clusterActions := clusterFixture.Given(t).
Name("temp-cluster").
ctx := clusterFixture.Given(t)
clusterActions := ctx.Name("temp-cluster").
Server(KubernetesInternalAPIServerAddr).
When().
Create()
GivenWithSameState(t).
GivenWithSameState(ctx).
Path(guestbookPath).
DestName("temp-cluster").
When().
@@ -816,8 +819,8 @@ func TestAppWithSecrets(t *testing.T) {
require.NoError(t, err)
defer utilio.Close(closer)
Given(t).
Path("secrets").
ctx := Given(t)
ctx.Path("secrets").
When().
CreateApp().
Sync().
@@ -848,12 +851,12 @@ func TestAppWithSecrets(t *testing.T) {
_, err = fixture.RunCli("app", "patch-resource", app.GetName(), "--resource-name", "test-secret",
"--kind", "Secret", "--patch", `{"op": "add", "path": "/data", "value": "hello"}'`,
"--patch-type", "application/json-patch+json")
require.ErrorContains(t, err, fmt.Sprintf("failed to patch Secret %s/test-secret", fixture.DeploymentNamespace()))
require.ErrorContains(t, err, fmt.Sprintf("failed to patch Secret %s/test-secret", ctx.DeploymentNamespace()))
assert.NotContains(t, err.Error(), "username")
assert.NotContains(t, err.Error(), "password")
// patch secret and make sure app is out of sync and diff detects the change
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Secrets(fixture.DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Secrets(ctx.DeploymentNamespace()).Patch(t.Context(),
"test-secret", types.JSONPatchType, []byte(`[
{"op": "remove", "path": "/data/username"},
{"op": "add", "path": "/stringData", "value": {"password": "foo"}}
@@ -905,8 +908,8 @@ stringData:
}
func TestResourceDiffing(t *testing.T) {
Given(t).
Path(guestbookPath).
ctx := Given(t)
ctx.Path(guestbookPath).
When().
CreateApp().
Sync().
@@ -914,7 +917,7 @@ func TestResourceDiffing(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
// Patch deployment
_, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
_, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "test" }]`), metav1.PatchOptions{})
require.NoError(t, err)
}).
@@ -925,7 +928,7 @@ func TestResourceDiffing(t *testing.T) {
And(func(app *Application) {
diffOutput, err := fixture.RunCli("app", "diff", app.Name, "--local", "testdata", "--server-side-generate")
require.Error(t, err)
assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", fixture.DeploymentNamespace()))
assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", ctx.DeploymentNamespace()))
}).
Given().
ResourceOverrides(map[string]ResourceOverride{"apps/Deployment": {
@@ -954,7 +957,7 @@ func TestResourceDiffing(t *testing.T) {
}]`).
Sync().
And(func() {
output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", fixture.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", ctx.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
require.NoError(t, err)
assert.Contains(t, output, "serverside-applied")
}).
@@ -981,12 +984,12 @@ func TestResourceDiffing(t *testing.T) {
"value": { "syncOptions": ["RespectIgnoreDifferences=true"] }
}]`).
And(func() {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(3), *deployment.Spec.RevisionHistoryLimit)
}).
And(func() {
output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", fixture.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
output, err := fixture.RunWithStdin(testdata.SSARevisionHistoryDeployment, "", "kubectl", "apply", "-n", ctx.DeploymentNamespace(), "--server-side=true", "--field-manager=revision-history-manager", "--validate=false", "--force-conflicts", "-f", "-")
require.NoError(t, err)
assert.Contains(t, output, "serverside-applied")
}).
@@ -995,13 +998,13 @@ func TestResourceDiffing(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(1), *deployment.Spec.RevisionHistoryLimit)
}).
When().Sync().Then().Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(1), *deployment.Spec.RevisionHistoryLimit)
})
@@ -1014,13 +1017,13 @@ func TestCRDs(t *testing.T) {
func TestKnownTypesInCRDDiffing(t *testing.T) {
dummiesGVR := schema.GroupVersionResource{Group: application.Group, Version: "v1alpha1", Resource: "dummies"}
Given(t).
Path("crd-creation").
ctx := Given(t)
ctx.Path("crd-creation").
When().CreateApp().Sync().Then().
Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeSynced)).
When().
And(func() {
dummyResIf := fixture.DynamicClientset.Resource(dummiesGVR).Namespace(fixture.DeploymentNamespace())
dummyResIf := fixture.DynamicClientset.Resource(dummiesGVR).Namespace(ctx.DeploymentNamespace())
patchData := []byte(`{"spec":{"cpu": "2"}}`)
errors.NewHandler(t).FailOnErr(dummyResIf.Patch(t.Context(), "dummy-crd-instance", types.MergePatchType, patchData, metav1.PatchOptions{}))
}).Refresh(RefreshTypeNormal).
@@ -1101,8 +1104,8 @@ definitions:
return obj`
func TestOldStyleResourceAction(t *testing.T) {
Given(t).
Path(guestbookPath).
ctx := Given(t)
ctx.Path(guestbookPath).
ResourceOverrides(map[string]ResourceOverride{"apps/Deployment": {Actions: actionsConfig}}).
When().
CreateApp().
@@ -1118,7 +1121,7 @@ func TestOldStyleResourceAction(t *testing.T) {
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
Version: ptr.To("v1"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(ctx.DeploymentNamespace()),
ResourceName: ptr.To("guestbook-ui"),
})
require.NoError(t, err)
@@ -1129,13 +1132,13 @@ func TestOldStyleResourceAction(t *testing.T) {
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
Version: ptr.To("v1"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(ctx.DeploymentNamespace()),
ResourceName: ptr.To("guestbook-ui"),
Action: ptr.To("sample"),
})
require.NoError(t, err)
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "test", deployment.Labels["sample"])
@@ -1199,8 +1202,8 @@ definitions:
return result`
func TestNewStyleResourceActionPermitted(t *testing.T) {
Given(t).
Path(resourceActions).
ctx := Given(t)
ctx.Path(resourceActions).
ResourceOverrides(map[string]ResourceOverride{"batch/CronJob": {Actions: newStyleActionsConfig}}).
ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
@@ -1225,7 +1228,7 @@ func TestNewStyleResourceActionPermitted(t *testing.T) {
Group: ptr.To("batch"),
Kind: ptr.To("CronJob"),
Version: ptr.To("v1"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(ctx.DeploymentNamespace()),
ResourceName: ptr.To("hello"),
})
require.NoError(t, err)
@@ -1236,13 +1239,13 @@ func TestNewStyleResourceActionPermitted(t *testing.T) {
Group: ptr.To("batch"),
Kind: ptr.To("CronJob"),
Version: ptr.To("v1"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(ctx.DeploymentNamespace()),
ResourceName: ptr.To("hello"),
Action: ptr.To("sample"),
})
require.NoError(t, err)
_, err = fixture.KubeClientset.BatchV1().Jobs(fixture.DeploymentNamespace()).Get(t.Context(), "hello-123", metav1.GetOptions{})
_, err = fixture.KubeClientset.BatchV1().Jobs(ctx.DeploymentNamespace()).Get(t.Context(), "hello-123", metav1.GetOptions{})
require.NoError(t, err)
})
}
@@ -1312,8 +1315,8 @@ definitions:
return result`
func TestNewStyleResourceActionMixedOk(t *testing.T) {
Given(t).
Path(resourceActions).
ctx := Given(t)
ctx.Path(resourceActions).
ResourceOverrides(map[string]ResourceOverride{"batch/CronJob": {Actions: newStyleActionsConfigMixedOk}}).
ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
@@ -1338,7 +1341,7 @@ func TestNewStyleResourceActionMixedOk(t *testing.T) {
Group: ptr.To("batch"),
Kind: ptr.To("CronJob"),
Version: ptr.To("v1"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(ctx.DeploymentNamespace()),
ResourceName: ptr.To("hello"),
})
require.NoError(t, err)
@@ -1349,17 +1352,17 @@ func TestNewStyleResourceActionMixedOk(t *testing.T) {
Group: ptr.To("batch"),
Kind: ptr.To("CronJob"),
Version: ptr.To("v1"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(ctx.DeploymentNamespace()),
ResourceName: ptr.To("hello"),
Action: ptr.To("sample"),
})
require.NoError(t, err)
// Assert new Job was created
_, err = fixture.KubeClientset.BatchV1().Jobs(fixture.DeploymentNamespace()).Get(t.Context(), "hello-123", metav1.GetOptions{})
_, err = fixture.KubeClientset.BatchV1().Jobs(ctx.DeploymentNamespace()).Get(t.Context(), "hello-123", metav1.GetOptions{})
require.NoError(t, err)
// Assert the original CronJob was patched
cronJob, err := fixture.KubeClientset.BatchV1().CronJobs(fixture.DeploymentNamespace()).Get(t.Context(), "hello", metav1.GetOptions{})
cronJob, err := fixture.KubeClientset.BatchV1().CronJobs(ctx.DeploymentNamespace()).Get(t.Context(), "hello", metav1.GetOptions{})
assert.Equal(t, "aValue", cronJob.Labels["aKey"])
require.NoError(t, err)
})
@@ -1497,7 +1500,7 @@ func TestSyncAsync(t *testing.T) {
}
// assertResourceActions verifies if view/modify resource actions are successful/failing for given application
func assertResourceActions(t *testing.T, appName string, successful bool) {
func assertResourceActions(t *testing.T, appName string, successful bool, deploymentNamespace string) {
t.Helper()
assertError := func(err error, message string) {
if successful {
@@ -1510,14 +1513,14 @@ func assertResourceActions(t *testing.T, appName string, successful bool) {
closer, cdClient := fixture.ArgoCDClientset.NewApplicationClientOrDie()
defer utilio.Close(closer)
deploymentResource, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deploymentResource, err := fixture.KubeClientset.AppsV1().Deployments(deploymentNamespace).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
logs, err := cdClient.PodLogs(t.Context(), &applicationpkg.ApplicationPodLogsQuery{
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
Name: &appName,
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(deploymentNamespace),
Container: ptr.To(""),
SinceSeconds: ptr.To(int64(0)),
TailLines: ptr.To(int64(0)),
@@ -1532,7 +1535,7 @@ func assertResourceActions(t *testing.T, appName string, successful bool) {
_, err = cdClient.ListResourceEvents(t.Context(), &applicationpkg.ApplicationResourceEventsQuery{
Name: &appName,
ResourceName: ptr.To("guestbook-ui"),
ResourceNamespace: ptr.To(fixture.DeploymentNamespace()),
ResourceNamespace: ptr.To(deploymentNamespace),
ResourceUID: ptr.To(string(deploymentResource.UID)),
})
assertError(err, fmt.Sprintf("%s not found as part of application %s", "guestbook-ui", appName))
@@ -1540,7 +1543,7 @@ func assertResourceActions(t *testing.T, appName string, successful bool) {
_, err = cdClient.GetResource(t.Context(), &applicationpkg.ApplicationResourceRequest{
Name: &appName,
ResourceName: ptr.To("guestbook-ui"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(deploymentNamespace),
Version: ptr.To("v1"),
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
@@ -1550,7 +1553,7 @@ func assertResourceActions(t *testing.T, appName string, successful bool) {
_, err = cdClient.RunResourceActionV2(t.Context(), &applicationpkg.ResourceActionRunRequestV2{
Name: &appName,
ResourceName: ptr.To("guestbook-ui"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(deploymentNamespace),
Version: ptr.To("v1"),
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
@@ -1561,7 +1564,7 @@ func assertResourceActions(t *testing.T, appName string, successful bool) {
_, err = cdClient.DeleteResource(t.Context(), &applicationpkg.ApplicationResourceDeleteRequest{
Name: &appName,
ResourceName: ptr.To("guestbook-ui"),
Namespace: ptr.To(fixture.DeploymentNamespace()),
Namespace: ptr.To(deploymentNamespace),
Version: ptr.To("v1"),
Group: ptr.To("apps"),
Kind: ptr.To("Deployment"),
@@ -1571,14 +1574,13 @@ func assertResourceActions(t *testing.T, appName string, successful bool) {
func TestPermissions(t *testing.T) {
appCtx := Given(t)
projCtx := projectFixture.GivenWithSameState(t)
projCtx := projectFixture.GivenWithSameState(appCtx)
projActions := projCtx.
Name("argo-project").
When().
Create()
sourceError := fmt.Sprintf("application repo %s is not permitted in project 'argo-project'", fixture.RepoURL(fixture.RepoURLTypeFile))
destinationError := fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project 'argo-project'", KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace())
sourceError := fmt.Sprintf("application repo %s is not permitted in project '%s'", fixture.RepoURL(fixture.RepoURLTypeFile), projCtx.GetName())
destinationError := fmt.Sprintf("application destination server '%s' and namespace '%s' do not match any of the allowed destinations in project '%s'", KubernetesInternalAPIServerAddr, appCtx.DeploymentNamespace(), projCtx.GetName())
appCtx.
Path("guestbook-logs").
@@ -1602,7 +1604,7 @@ func TestPermissions(t *testing.T) {
Then().
// make sure application resource actions are successful
And(func(app *Application) {
assertResourceActions(t, app.Name, true)
assertResourceActions(t, app.Name, true, appCtx.DeploymentNamespace())
}).
When().
// remove projet permissions and "refresh" app
@@ -1641,29 +1643,26 @@ func TestPermissions(t *testing.T) {
Then().
// make sure application resource actions are failing
And(func(a *Application) {
assertResourceActions(t, a.GetName(), false)
assertResourceActions(t, a.GetName(), false, appCtx.DeploymentNamespace())
})
}
func TestPermissionWithScopedRepo(t *testing.T) {
projName := "argo-project"
fixture.EnsureCleanState(t)
projectFixture.
Given(t).
Name(projName).
ctx := projectFixture.Given(t)
ctx.
Destination("*,*").
When().
Create().
AddSource("*")
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(fixture.RepoURL(fixture.RepoURLTypeFile)).
Project(projName).
Project(ctx.GetName()).
Create()
GivenWithSameState(t).
Project(projName).
GivenWithSameState(ctx).
Project(ctx.GetName()).
RepoURLType(fixture.RepoURLTypeFile).
Path("two-nice-pods").
When().
@@ -1685,21 +1684,18 @@ func TestPermissionWithScopedRepo(t *testing.T) {
}
func TestPermissionDeniedWithScopedRepo(t *testing.T) {
projName := "argo-project"
projectFixture.
Given(t).
Name(projName).
Destination("*,*").
ctx := projectFixture.Given(t)
ctx.Destination("*,*").
When().
Create()
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(fixture.RepoURL(fixture.RepoURLTypeFile)).
Create()
GivenWithSameState(t).
Project(projName).
GivenWithSameState(ctx).
Project(ctx.GetName()).
RepoURLType(fixture.RepoURLTypeFile).
Path("two-nice-pods").
When().
@@ -1711,22 +1707,19 @@ func TestPermissionDeniedWithScopedRepo(t *testing.T) {
}
func TestPermissionDeniedWithNegatedNamespace(t *testing.T) {
projName := "argo-project"
projectFixture.
Given(t).
Name(projName).
Destination("*,!*test-permission-denied-with-negated-namespace*").
ctx := projectFixture.Given(t)
ctx.Destination("*,!*test-permission-denied-with-negated-namespace*").
When().
Create()
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(fixture.RepoURL(fixture.RepoURLTypeFile)).
Project(projName).
Project(ctx.GetName()).
Create()
GivenWithSameState(t).
Project(projName).
GivenWithSameState(ctx).
Project(ctx.GetName()).
RepoURLType(fixture.RepoURLTypeFile).
Path("two-nice-pods").
When().
@@ -1738,22 +1731,19 @@ func TestPermissionDeniedWithNegatedNamespace(t *testing.T) {
}
func TestPermissionDeniedWithNegatedServer(t *testing.T) {
projName := "argo-project"
projectFixture.
Given(t).
Name(projName).
Destination("!https://kubernetes.default.svc,*").
ctx := projectFixture.Given(t)
ctx.Destination("!https://kubernetes.default.svc,*").
When().
Create()
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(fixture.RepoURL(fixture.RepoURLTypeFile)).
Project(projName).
Project(ctx.GetName()).
Create()
GivenWithSameState(t).
Project(projName).
GivenWithSameState(ctx).
Project(ctx.GetName()).
RepoURLType(fixture.RepoURLTypeFile).
Path("two-nice-pods").
When().
@@ -1842,11 +1832,11 @@ func TestCompareOptionIgnoreExtraneous(t *testing.T) {
}
func TestSourceNamespaceCanBeMigratedToManagedNamespaceWithoutBeingPrunedOrOutOfSync(t *testing.T) {
Given(t).
Prune(true).
ctx := Given(t)
ctx.Prune(true).
Path("guestbook-with-plain-namespace-manifest").
When().
PatchFile("guestbook-ui-namespace.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/metadata/name", "value": %q}]`, fixture.DeploymentNamespace())).
PatchFile("guestbook-ui-namespace.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/metadata/name", "value": %q}]`, ctx.DeploymentNamespace())).
CreateApp().
Sync().
Then().
@@ -1946,12 +1936,12 @@ func TestRevisionHistoryLimit(t *testing.T) {
func TestOrphanedResource(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
Given(t).
ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}},
OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true)},
}).
ctx := Given(t)
ctx.ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}},
OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true)},
}).
Path(guestbookPath).
When().
CreateApp().
@@ -1961,7 +1951,7 @@ func TestOrphanedResource(t *testing.T) {
Expect(NoConditions()).
When().
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "orphaned-configmap",
},
@@ -2090,14 +2080,14 @@ func TestNotPermittedResources(t *testing.T) {
ctx.ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []ApplicationDestination{{Namespace: fixture.DeploymentNamespace(), Server: "*"}},
Destinations: []ApplicationDestination{{Namespace: ctx.DeploymentNamespace(), Server: "*"}},
NamespaceResourceBlacklist: []metav1.GroupKind{
{Group: "", Kind: "Service"},
},
}).
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Create(t.Context(), ingress, metav1.CreateOptions{}))
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Create(t.Context(), svc, metav1.CreateOptions{}))
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(ctx.DeploymentNamespace()).Create(t.Context(), svc, metav1.CreateOptions{}))
}).
Path(guestbookPath).
When().
@@ -2123,7 +2113,7 @@ func TestNotPermittedResources(t *testing.T) {
// Make sure prohibited resources are not deleted during application deletion
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.NetworkingV1().Ingresses(fixture.TestNamespace()).Get(t.Context(), "sample-ingress", metav1.GetOptions{}))
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}))
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().Services(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{}))
}
func TestSyncWithInfos(t *testing.T) {
@@ -2282,12 +2272,12 @@ func TestCreateAppWithInClusterDisabled(t *testing.T) {
func TestListResource(t *testing.T) {
fixture.SkipOnEnv(t, "OPENSHIFT")
Given(t).
ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}},
OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true)},
}).
ctx := Given(t)
ctx.ProjectSpec(AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []ApplicationDestination{{Namespace: "*", Server: "*"}},
OrphanedResources: &OrphanedResourcesMonitorSettings{Warn: ptr.To(true)},
}).
Path(guestbookPath).
When().
CreateApp().
@@ -2297,7 +2287,7 @@ func TestListResource(t *testing.T) {
Expect(NoConditions()).
When().
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "orphaned-configmap",
},
@@ -2402,14 +2392,14 @@ func TestFailedSyncWithRetry(t *testing.T) {
}
func TestCreateDisableValidation(t *testing.T) {
Given(t).
Path("baddir").
ctx := Given(t)
ctx.Path("baddir").
When().
CreateApp("--validate=false").
Then().
And(func(app *Application) {
_, err := fixture.RunCli("app", "create", app.Name, "--upsert", "--validate=false", "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
"--path", "baddir2", "--project", app.Spec.Project, "--dest-server", KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace())
"--path", "baddir2", "--project", app.Spec.Project, "--dest-server", KubernetesInternalAPIServerAddr, "--dest-namespace", ctx.DeploymentNamespace())
require.NoError(t, err)
}).
When().
@@ -2707,11 +2697,11 @@ func TestSwitchTrackingMethod(t *testing.T) {
And(func() {
// Add resource with tracking annotation. This should put the
// application OutOfSync.
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "other-configmap",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", fixture.Name(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", ctx.GetName(), ctx.DeploymentNamespace()),
},
},
}, metav1.CreateOptions{}))
@@ -2723,7 +2713,7 @@ func TestSwitchTrackingMethod(t *testing.T) {
When().
And(func() {
// Delete resource to bring application back in sync
errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{}))
errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{}))
}).
Then().
Expect(OperationPhaseIs(OperationSucceeded)).
@@ -2741,11 +2731,11 @@ func TestSwitchTrackingMethod(t *testing.T) {
// Add a resource with a tracking annotation. This should not
// affect the application, because we now use the tracking method
// "label".
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "other-configmap",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", fixture.Name(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", ctx.GetName(), ctx.DeploymentNamespace()),
},
},
}, metav1.CreateOptions{}))
@@ -2758,11 +2748,11 @@ func TestSwitchTrackingMethod(t *testing.T) {
And(func() {
// Add a resource with the tracking label. The app should become
// OutOfSync.
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "extra-configmap",
Labels: map[string]string{
common.LabelKeyAppInstance: fixture.Name(),
common.LabelKeyAppInstance: ctx.GetName(),
},
},
}, metav1.CreateOptions{}))
@@ -2774,7 +2764,7 @@ func TestSwitchTrackingMethod(t *testing.T) {
When().
And(func() {
// Delete resource to bring application back in sync
errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Delete(t.Context(), "extra-configmap", metav1.DeleteOptions{}))
errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Delete(t.Context(), "extra-configmap", metav1.DeleteOptions{}))
}).
Then().
Expect(OperationPhaseIs(OperationSucceeded)).
@@ -2800,11 +2790,11 @@ func TestSwitchTrackingLabel(t *testing.T) {
And(func() {
// Add extra resource that carries the default tracking label
// We expect the app to go out of sync.
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "other-configmap",
Labels: map[string]string{
common.LabelKeyAppInstance: fixture.Name(),
common.LabelKeyAppInstance: ctx.GetName(),
},
},
}, metav1.CreateOptions{}))
@@ -2816,7 +2806,7 @@ func TestSwitchTrackingLabel(t *testing.T) {
When().
And(func() {
// Delete resource to bring application back in sync
errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{}))
errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{}))
}).
Then().
Expect(OperationPhaseIs(OperationSucceeded)).
@@ -2834,11 +2824,11 @@ func TestSwitchTrackingLabel(t *testing.T) {
And(func() {
// Create resource with the new tracking label, the application
// is expected to go out of sync
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "other-configmap",
Labels: map[string]string{
"argocd.tracking": fixture.Name(),
"argocd.tracking": ctx.GetName(),
},
},
}, metav1.CreateOptions{}))
@@ -2850,7 +2840,7 @@ func TestSwitchTrackingLabel(t *testing.T) {
When().
And(func() {
// Delete resource to bring application back in sync
errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{}))
errors.NewHandler(t).FailOnErr(nil, fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Delete(t.Context(), "other-configmap", metav1.DeleteOptions{}))
}).
Then().
Expect(OperationPhaseIs(OperationSucceeded)).
@@ -2861,11 +2851,11 @@ func TestSwitchTrackingLabel(t *testing.T) {
// Add extra resource that carries the default tracking label
// We expect the app to stay in sync, because the configured
// label is different.
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "other-configmap",
Labels: map[string]string{
common.LabelKeyAppInstance: fixture.Name(),
common.LabelKeyAppInstance: ctx.GetName(),
},
},
}, metav1.CreateOptions{}))
@@ -2894,11 +2884,11 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
And(func() {
// Add a resource with an annotation that is not referencing the
// resource.
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "extra-configmap",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:apps/Deployment:%s/guestbook-cm", fixture.Name(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:apps/Deployment:%s/guestbook-cm", ctx.GetName(), ctx.DeploymentNamespace()),
},
},
}, metav1.CreateOptions{}))
@@ -2912,18 +2902,18 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
Sync("--prune").
And(func() {
// The extra configmap must not be pruned, because it's not tracked
cm, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Get(t.Context(), "extra-configmap", metav1.GetOptions{})
cm, err := fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Get(t.Context(), "extra-configmap", metav1.GetOptions{})
require.NoError(t, err)
require.Equal(t, "extra-configmap", cm.Name)
}).
And(func() {
// Add a resource with an annotation that is self-referencing the
// resource.
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "other-configmap",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", fixture.Name(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/other-configmap", ctx.GetName(), ctx.DeploymentNamespace()),
},
},
}, metav1.CreateOptions{}))
@@ -2937,7 +2927,7 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
Sync("--prune").
And(func() {
// The extra configmap must be pruned now, because it's tracked
cm, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Get(t.Context(), "other-configmap", metav1.GetOptions{})
cm, err := fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Get(t.Context(), "other-configmap", metav1.GetOptions{})
require.Error(t, err)
require.Empty(t, cm.Name)
}).
@@ -2952,7 +2942,7 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-test-clusterrole",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", fixture.Name(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", ctx.GetName(), ctx.DeploymentNamespace()),
},
Labels: map[string]string{
fixture.TestingLabel: "true",
@@ -2972,7 +2962,7 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-other-clusterrole",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", fixture.Name(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:rbac.authorization.k8s.io/ClusterRole:%s/e2e-other-clusterrole", ctx.GetName(), ctx.DeploymentNamespace()),
},
Labels: map[string]string{
fixture.TestingLabel: "true",
@@ -3000,7 +2990,8 @@ func TestAnnotationTrackingExtraResources(t *testing.T) {
}
func TestCreateConfigMapsAndWaitForUpdate(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path("config-map").
When().
CreateApp().
@@ -3036,10 +3027,10 @@ data:
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
Expect(ResourceHealthWithNamespaceIs("ConfigMap", "other-map", fixture.DeploymentNamespace(), health.HealthStatusHealthy)).
Expect(ResourceSyncStatusWithNamespaceIs("ConfigMap", "other-map", fixture.DeploymentNamespace(), SyncStatusCodeSynced)).
Expect(ResourceHealthWithNamespaceIs("ConfigMap", "yet-another-map", fixture.DeploymentNamespace(), health.HealthStatusHealthy)).
Expect(ResourceSyncStatusWithNamespaceIs("ConfigMap", "yet-another-map", fixture.DeploymentNamespace(), SyncStatusCodeSynced))
Expect(ResourceHealthWithNamespaceIs("ConfigMap", "other-map", ctx.DeploymentNamespace(), health.HealthStatusHealthy)).
Expect(ResourceSyncStatusWithNamespaceIs("ConfigMap", "other-map", ctx.DeploymentNamespace(), SyncStatusCodeSynced)).
Expect(ResourceHealthWithNamespaceIs("ConfigMap", "yet-another-map", ctx.DeploymentNamespace(), health.HealthStatusHealthy)).
Expect(ResourceSyncStatusWithNamespaceIs("ConfigMap", "yet-another-map", ctx.DeploymentNamespace(), SyncStatusCodeSynced))
}
func TestInstallationID(t *testing.T) {
@@ -3047,12 +3038,12 @@ func TestInstallationID(t *testing.T) {
ctx.
SetTrackingMethod(string(TrackingMethodAnnotation)).
And(func() {
_, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(
_, err := fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(
t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "test-configmap",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/test-configmap", ctx.AppName(), fixture.DeploymentNamespace()),
common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/test-configmap", ctx.AppName(), ctx.DeploymentNamespace()),
},
},
}, metav1.CreateOptions{})
@@ -3078,11 +3069,11 @@ func TestInstallationID(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(app *Application) {
require.Len(t, app.Status.Resources, 2)
svc, err := fixture.KubeClientset.CoreV1().Services(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
svc, err := fixture.KubeClientset.CoreV1().Services(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
require.Equal(t, "test", svc.Annotations[common.AnnotationInstallationID])
deploy, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deploy, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
require.Equal(t, "test", deploy.Annotations[common.AnnotationInstallationID])
})
@@ -3092,7 +3083,7 @@ func TestDeletionConfirmation(t *testing.T) {
ctx := Given(t)
ctx.
And(func() {
_, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(
_, err := fixture.KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Create(
t.Context(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "test-configmap",
@@ -3296,7 +3287,8 @@ func TestServerSideDiffErrorHandling(t *testing.T) {
// TestServerSideDiffWithLocal tests server-side diff with --local flag
func TestServerSideDiffWithLocal(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path("guestbook").
When().
CreateApp().
@@ -3307,7 +3299,7 @@ func TestServerSideDiffWithLocal(t *testing.T) {
And(func(_ *Application) {
// Modify the live deployment in the cluster to create differences
// Apply patches to the deployment
_, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
_, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.JSONPatchType, []byte(`[
{"op": "add", "path": "/spec/template/spec/containers/0/env", "value": [{"name": "LOCAL_CHANGE", "value": "true"}]},
{"op": "replace", "path": "/spec/replicas", "value": 2}
@@ -3315,7 +3307,7 @@ func TestServerSideDiffWithLocal(t *testing.T) {
require.NoError(t, err)
// Verify the patch was applied by reading back the deployment
modifiedDeployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
modifiedDeployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(2), *modifiedDeployment.Spec.Replicas, "Replica count should be updated to 2")
assert.Len(t, modifiedDeployment.Spec.Template.Spec.Containers[0].Env, 1, "Should have one environment variable")

View File

@@ -28,12 +28,12 @@ func TestMultiSourceAppCreation(t *testing.T) {
CreateMultiSourceAppFromFile().
Then().
And(func(app *Application) {
assert.Equal(t, Name(), app.Name)
assert.Equal(t, ctx.GetName(), app.Name)
for i, source := range app.Spec.GetSources() {
assert.Equal(t, sources[i].RepoURL, source.RepoURL)
assert.Equal(t, sources[i].Path, source.Path)
}
assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(Event(EventReasonResourceCreated, "create")).
@@ -41,7 +41,7 @@ func TestMultiSourceAppCreation(t *testing.T) {
// app should be listed
output, err := RunCli("app", "list")
require.NoError(t, err)
assert.Contains(t, output, Name())
assert.Contains(t, output, ctx.GetName())
}).
Expect(Success("")).
Given().Timeout(60).
@@ -83,12 +83,12 @@ func TestMultiSourceAppWithHelmExternalValueFiles(t *testing.T) {
CreateMultiSourceAppFromFile().
Then().
And(func(app *Application) {
assert.Equal(t, Name(), app.Name)
assert.Equal(t, ctx.GetName(), app.Name)
for i, source := range app.Spec.GetSources() {
assert.Equal(t, sources[i].RepoURL, source.RepoURL)
assert.Equal(t, sources[i].Path, source.Path)
}
assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(Event(EventReasonResourceCreated, "create")).
@@ -96,7 +96,7 @@ func TestMultiSourceAppWithHelmExternalValueFiles(t *testing.T) {
// app should be listed
output, err := RunCli("app", "list")
require.NoError(t, err)
assert.Contains(t, output, Name())
assert.Contains(t, output, ctx.GetName())
}).
Expect(Success("")).
Given().Timeout(60).
@@ -111,7 +111,7 @@ func TestMultiSourceAppWithHelmExternalValueFiles(t *testing.T) {
assert.Equal(t, SyncStatusCodeSynced, statusByName["guestbook-ui"])
// Confirm that the deployment has 3 replicas.
output, err := Run("", "kubectl", "get", "deployment", "guestbook-ui", "-n", DeploymentNamespace(), "-o", "jsonpath={.spec.replicas}")
output, err := Run("", "kubectl", "get", "deployment", "guestbook-ui", "-n", ctx.DeploymentNamespace(), "-o", "jsonpath={.spec.replicas}")
require.NoError(t, err)
assert.Equal(t, "3", output, "Expected 3 replicas for the helm-guestbook deployment")
})
@@ -135,12 +135,12 @@ func TestMultiSourceAppWithSourceOverride(t *testing.T) {
CreateMultiSourceAppFromFile().
Then().
And(func(app *Application) {
assert.Equal(t, Name(), app.Name)
assert.Equal(t, ctx.GetName(), app.Name)
for i, source := range app.Spec.GetSources() {
assert.Equal(t, sources[i].RepoURL, source.RepoURL)
assert.Equal(t, sources[i].Path, source.Path)
}
assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(Event(EventReasonResourceCreated, "create")).
@@ -148,7 +148,7 @@ func TestMultiSourceAppWithSourceOverride(t *testing.T) {
// app should be listed
output, err := RunCli("app", "list")
require.NoError(t, err)
assert.Contains(t, output, Name())
assert.Contains(t, output, ctx.GetName())
}).
Expect(Success("")).
Given().Timeout(60).
@@ -166,7 +166,7 @@ func TestMultiSourceAppWithSourceOverride(t *testing.T) {
assert.Equal(t, SyncStatusCodeSynced, statusByName["guestbook-ui"])
// check if label was added to the pod to make sure resource was taken from the later source
output, err := Run("", "kubectl", "describe", "pods", "pod-1", "-n", DeploymentNamespace())
output, err := Run("", "kubectl", "describe", "pods", "pod-1", "-n", ctx.DeploymentNamespace())
require.NoError(t, err)
assert.Contains(t, output, "foo=bar")
})
@@ -189,19 +189,19 @@ func TestMultiSourceAppWithSourceName(t *testing.T) {
CreateMultiSourceAppFromFile().
Then().
And(func(app *Application) {
assert.Equal(t, Name(), app.Name)
assert.Equal(t, ctx.GetName(), app.Name)
for i, source := range app.Spec.GetSources() {
assert.Equal(t, sources[i].RepoURL, source.RepoURL)
assert.Equal(t, sources[i].Path, source.Path)
assert.Equal(t, sources[i].Name, source.Name)
}
assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(Event(EventReasonResourceCreated, "create")).
And(func(_ *Application) {
// we remove the first source
output, err := RunCli("app", "remove-source", Name(), "--source-name", sources[0].Name)
output, err := RunCli("app", "remove-source", ctx.GetName(), "--source-name", sources[0].Name)
require.NoError(t, err)
assert.Contains(t, output, "updated successfully")
}).
@@ -209,7 +209,7 @@ func TestMultiSourceAppWithSourceName(t *testing.T) {
And(func(app *Application) {
assert.Len(t, app.Spec.GetSources(), 1)
// we add a source
output, err := RunCli("app", "add-source", Name(), "--source-name", sources[0].Name, "--repo", RepoURL(RepoURLTypeFile), "--path", guestbookPath)
output, err := RunCli("app", "add-source", ctx.GetName(), "--source-name", sources[0].Name, "--repo", RepoURL(RepoURLTypeFile), "--path", guestbookPath)
require.NoError(t, err)
assert.Contains(t, output, "updated successfully")
}).
@@ -251,18 +251,18 @@ func TestMultiSourceAppSetWithSourceName(t *testing.T) {
CreateMultiSourceAppFromFile().
Then().
And(func(app *Application) {
assert.Equal(t, Name(), app.Name)
assert.Equal(t, ctx.GetName(), app.Name)
for i, source := range app.Spec.GetSources() {
assert.Equal(t, sources[i].RepoURL, source.RepoURL)
assert.Equal(t, sources[i].Path, source.Path)
assert.Equal(t, sources[i].Name, source.Name)
}
assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(Event(EventReasonResourceCreated, "create")).
And(func(_ *Application) {
_, err := RunCli("app", "set", Name(), "--source-name", sources[1].Name, "--path", "deployment")
_, err := RunCli("app", "set", ctx.GetName(), "--source-name", sources[1].Name, "--path", "deployment")
require.NoError(t, err)
}).
Expect(Success("")).
@@ -289,11 +289,11 @@ func TestMultiSourceApptErrorWhenSourceNameAndSourcePosition(t *testing.T) {
Then().
Expect(Event(EventReasonResourceCreated, "create")).
And(func(_ *Application) {
_, err := RunCli("app", "get", Name(), "--source-name", sources[1].Name, "--source-position", "1")
_, err := RunCli("app", "get", ctx.GetName(), "--source-name", sources[1].Name, "--source-position", "1")
assert.ErrorContains(t, err, "Only one of source-position and source-name can be specified.")
}).
And(func(_ *Application) {
_, err := RunCli("app", "manifests", Name(), "--revisions", "0.0.2", "--source-names", sources[0].Name, "--revisions", "0.0.2", "--source-positions", "1")
_, err := RunCli("app", "manifests", ctx.GetName(), "--revisions", "0.0.2", "--source-names", sources[0].Name, "--revisions", "0.0.2", "--source-positions", "1")
assert.ErrorContains(t, err, "Only one of source-positions and source-names can be specified.")
})
}

View File

@@ -30,7 +30,7 @@ func TestAppCreationInOtherNamespace(t *testing.T) {
assert.Equal(t, AppNamespace(), app.Namespace)
assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL)
assert.Equal(t, guestbookPath, app.Spec.GetSource().Path)
assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(NamespacedEvent(ctx.AppNamespace(), EventReasonResourceCreated, "create")).

View File

@@ -69,9 +69,6 @@ func TestSimpleGitDirectoryGenerator(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},
@@ -132,7 +129,7 @@ func TestSimpleGitDirectoryGenerator(t *testing.T) {
}).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
@@ -178,9 +175,6 @@ func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -242,7 +236,7 @@ func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) {
}).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
@@ -307,9 +301,6 @@ func TestSimpleGitDirectoryGeneratorGPGEnabledUnsignedCommits(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},
@@ -342,7 +333,7 @@ func TestSimpleGitDirectoryGeneratorGPGEnabledUnsignedCommits(t *testing.T) {
}).
Then().Expect(ApplicationsDoNotExist(expectedApps)).
// verify the ApplicationSet error status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)).
Expect(ApplicationSetHasConditions(expectedConditionsParamsError)).
When().
Delete().Then().Expect(ApplicationsDoNotExist(expectedApps))
}
@@ -409,9 +400,6 @@ func TestSimpleGitDirectoryGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) {
IgnoreErrors().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},
@@ -447,7 +435,7 @@ func TestSimpleGitDirectoryGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) {
},
}).Then().
// verify the ApplicationSet error status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)).
Expect(ApplicationSetHasConditions(expectedConditionsParamsError)).
Expect(ApplicationsDoNotExist(expectedApps)).
When().
Delete().Then().Expect(ApplicationsDoNotExist(expectedApps))
@@ -492,9 +480,6 @@ func TestSimpleGitFilesGenerator(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"},
@@ -555,7 +540,7 @@ func TestSimpleGitFilesGenerator(t *testing.T) {
}).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
@@ -621,9 +606,6 @@ func TestSimpleGitFilesGeneratorGPGEnabledUnsignedCommits(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"},
@@ -655,7 +637,7 @@ func TestSimpleGitFilesGeneratorGPGEnabledUnsignedCommits(t *testing.T) {
},
}).Then().Expect(ApplicationsDoNotExist(expectedApps)).
// verify the ApplicationSet error status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)).
Expect(ApplicationSetHasConditions(expectedConditionsParamsError)).
When().
Delete().Then().Expect(ApplicationsDoNotExist(expectedApps))
}
@@ -722,9 +704,6 @@ func TestSimpleGitFilesGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) {
IgnoreErrors().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"},
@@ -756,7 +735,7 @@ func TestSimpleGitFilesGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) {
},
}).Then().
// verify the ApplicationSet error status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-git-generator", expectedConditionsParamsError)).
Expect(ApplicationSetHasConditions(expectedConditionsParamsError)).
Expect(ApplicationsDoNotExist(expectedApps)).
When().
Delete().Then().Expect(ApplicationsDoNotExist(expectedApps))
@@ -801,9 +780,6 @@ func TestSimpleGitFilesGeneratorGoTemplate(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -865,7 +841,7 @@ func TestSimpleGitFilesGeneratorGoTemplate(t *testing.T) {
}).Then().Expect(ApplicationsExist(expectedAppsNewMetadata)).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-git-generator", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
@@ -878,9 +854,6 @@ func TestSimpleGitFilesPreserveResourcesOnDeletion(t *testing.T) {
CreateNamespace(utils.ApplicationsResourcesNamespace).
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"},
@@ -938,9 +911,6 @@ func TestSimpleGitFilesPreserveResourcesOnDeletionGoTemplate(t *testing.T) {
CreateNamespace(utils.ApplicationsResourcesNamespace).
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -1032,9 +1002,6 @@ func TestGitGeneratorPrivateRepo(t *testing.T) {
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator-private",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},
@@ -1108,9 +1075,6 @@ func TestGitGeneratorPrivateRepoGoTemplate(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator-private",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -1184,9 +1148,6 @@ func TestSimpleGitGeneratorPrivateRepoWithNoRepo(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator-private",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},
@@ -1249,20 +1210,15 @@ func TestSimpleGitGeneratorPrivateRepoWithMatchingProject(t *testing.T) {
}
}
ctx := Given(t)
expectedApps := []v1alpha1.Application{
generateExpectedApp("https-kustomize-base"),
}
var expectedAppsNewNamespace []v1alpha1.Application
Given(t).
HTTPSInsecureRepoURLAdded("default").
ctx.HTTPSInsecureRepoURLAdded("default").
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator-private",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},
@@ -1295,7 +1251,7 @@ func TestSimpleGitGeneratorPrivateRepoWithMatchingProject(t *testing.T) {
}).Then().Expect(ApplicationsExist(expectedApps)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
Delete().Then().Expect(ApplicationsDoNotExist(expectedAppsNewNamespace))
Delete().Then().Expect(ApplicationsDoNotExist(expectedApps))
}
func TestSimpleGitGeneratorPrivateRepoWithMismatchingProject(t *testing.T) {
@@ -1336,9 +1292,6 @@ func TestSimpleGitGeneratorPrivateRepoWithMismatchingProject(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator-private",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},
@@ -1412,9 +1365,6 @@ func TestGitGeneratorPrivateRepoWithTemplatedProject(t *testing.T) {
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator-private",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},
@@ -1499,9 +1449,6 @@ func TestGitGeneratorPrivateRepoWithTemplatedProjectAndProjectScopedRepo(t *test
When().
// Create a GitGenerator-based ApplicationSet
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-git-generator-private",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"},

View File

@@ -85,10 +85,6 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) {
When().
SwitchToExternalNamespace(utils.ArgoCDExternalNamespace).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-list-generator-external",
Namespace: externalNamespace,
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -145,7 +141,7 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) {
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-list-generator-external", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
@@ -213,7 +209,6 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) {
SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-list-generator-external",
Namespace: externalNamespace2,
},
Spec: v1alpha1.ApplicationSetSpec{
@@ -248,7 +243,6 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) {
SwitchToExternalNamespace(utils.ArgoCDExternalNamespace).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-list-generator-external",
Namespace: externalNamespace,
},
Spec: v1alpha1.ApplicationSetSpec{
@@ -319,7 +313,7 @@ func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) {
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-list-generator-external", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
When().
SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2).
Then().
@@ -367,37 +361,35 @@ func TestSimpleListGenerator(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-list-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster}}-guestbook"},
Spec: v1alpha1.ApplicationSpec{
Project: "default",
Source: &v1alpha1.ApplicationSource{
RepoURL: "https://github.com/argoproj/argocd-example-apps.git",
TargetRevision: "HEAD",
Path: "guestbook",
When().
Create(v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster}}-guestbook"},
Spec: v1alpha1.ApplicationSpec{
Project: "default",
Source: &v1alpha1.ApplicationSource{
RepoURL: "https://github.com/argoproj/argocd-example-apps.git",
TargetRevision: "HEAD",
Path: "guestbook",
},
Destination: v1alpha1.ApplicationDestination{
Server: "{{url}}",
Namespace: "guestbook",
},
},
Destination: v1alpha1.ApplicationDestination{
Server: "{{url}}",
Namespace: "guestbook",
},
Generators: []v1alpha1.ApplicationSetGenerator{
{
List: &v1alpha1.ListGenerator{
Elements: []apiextensionsv1.JSON{{
Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`),
}},
},
},
},
},
Generators: []v1alpha1.ApplicationSetGenerator{
{
List: &v1alpha1.ListGenerator{
Elements: []apiextensionsv1.JSON{{
Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`),
}},
},
},
},
},
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})).
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})).
// Update the ApplicationSet template namespace, and verify it updates the Applications
When().
@@ -422,7 +414,7 @@ func TestSimpleListGenerator(t *testing.T) {
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-list-generator", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
@@ -459,9 +451,6 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-list-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -514,7 +503,7 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) {
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("simple-list-generator", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
@@ -555,9 +544,6 @@ func TestRenderHelmValuesObject(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test-values-object",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -653,9 +639,6 @@ func TestTemplatePatch(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "patch-template",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -716,7 +699,7 @@ func TestTemplatePatch(t *testing.T) {
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("patch-template", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it deletes the Applications
When().
@@ -757,9 +740,6 @@ func TestUpdateHelmValuesObject(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test-values-object-patch",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -793,7 +773,7 @@ func TestUpdateHelmValuesObject(t *testing.T) {
},
},
}).Then().
Expect(ApplicationSetHasConditions("test-values-object-patch", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
When().
// Update the app spec with some knew ValuesObject to force a merge
Update(func(as *v1alpha1.ApplicationSet) {
@@ -838,9 +818,6 @@ func TestSyncPolicyCreateUpdate(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "sync-policy-create-update",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -913,7 +890,7 @@ func TestSyncPolicyCreateUpdate(t *testing.T) {
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("sync-policy-create-update", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it not deletes the Applications
// As policy is create-update, AppSet controller will remove all generated applications's ownerReferences on delete AppSet
@@ -951,9 +928,6 @@ func TestSyncPolicyCreateDelete(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "sync-policy-create-delete",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -1014,7 +988,7 @@ func TestSyncPolicyCreateDelete(t *testing.T) {
}).Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace})).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("sync-policy-create-delete", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet
When().
@@ -1050,9 +1024,6 @@ func TestSyncPolicyCreateOnly(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "sync-policy-create-only",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -1116,7 +1087,7 @@ func TestSyncPolicyCreateOnly(t *testing.T) {
}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})).
// verify the ApplicationSet status conditions were set correctly
Expect(ApplicationSetHasConditions("sync-policy-create-only", ExpectedConditions)).
Expect(ApplicationSetHasConditions(ExpectedConditions)).
// Delete the ApplicationSet, and verify it not deletes the Applications
// As policy is create-update, AppSet controller will remove all generated applications's ownerReferences on delete AppSet
@@ -1367,9 +1338,6 @@ func TestSimpleSCMProviderGenerator(t *testing.T) {
Given(t).
// Create an SCMProviderGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-scm-provider-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"},
@@ -1442,9 +1410,6 @@ func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) {
Given(t).
// Create an SCMProviderGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-scm-provider-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -1509,12 +1474,9 @@ func TestSCMProviderGeneratorSCMProviderNotAllowed(t *testing.T) {
// Because you can't &"".
repoMatch := "argo-cd"
Given(t).
// Create an SCMProviderGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "scm-provider-generator-scm-provider-not-allowed",
},
ctx := Given(t)
// Create an SCMProviderGenerator-based ApplicationSet
ctx.When().Create(v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -1551,7 +1513,7 @@ func TestSCMProviderGeneratorSCMProviderNotAllowed(t *testing.T) {
}).Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})).
And(func() {
// app should be listed
output, err := fixture.RunCli("appset", "get", "scm-provider-generator-scm-provider-not-allowed")
output, err := fixture.RunCli("appset", "get", ctx.GetName())
require.NoError(t, err)
assert.Contains(t, output, "scm provider not allowed")
})
@@ -1585,9 +1547,6 @@ func TestCustomApplicationFinalizers(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-list-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{
@@ -1652,9 +1611,6 @@ func TestCustomApplicationFinalizersGoTemplate(t *testing.T) {
Given(t).
// Create a ListGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-list-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -1785,9 +1741,6 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictOk(t *testing.T) {
}).
// Create an SCMProviderGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-scm-provider-generator-strict",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"},
@@ -1871,29 +1824,26 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) {
// Because you can't &"".
repoMatch := "argo-cd"
Given(t).
And(func() {
_, err := utils.GetE2EFixtureK8sClient(t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Create(t.Context(), &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: fixture.TestNamespace(),
Name: secretName,
Labels: map[string]string{
// Try to exfiltrate cluster secret
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
ctx := Given(t)
ctx.And(func() {
_, err := utils.GetE2EFixtureK8sClient(t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Create(t.Context(), &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: fixture.TestNamespace(),
Name: secretName,
Labels: map[string]string{
// Try to exfiltrate cluster secret
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
Data: map[string][]byte{
"hello": []byte("world"),
},
}, metav1.CreateOptions{})
},
Data: map[string][]byte{
"hello": []byte("world"),
},
}, metav1.CreateOptions{})
assert.NoError(t, err)
}).
assert.NoError(t, err)
}).
// Create an SCMProviderGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-scm-provider-generator-strict-ko",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"},
@@ -1934,7 +1884,7 @@ func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) {
When().
And(func() {
// app should be listed
output, err := fixture.RunCli("appset", "get", "simple-scm-provider-generator-strict-ko")
output, err := fixture.RunCli("appset", "get", ctx.GetName())
require.NoError(t, err)
assert.Contains(t, output, fmt.Sprintf("scm provider: error fetching Github token: secret %s/%s is not a valid SCM creds secret", fixture.TestNamespace(), secretName))
err2 := utils.GetE2EFixtureK8sClient(t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(t.Context(), secretName, metav1.DeleteOptions{})
@@ -1980,9 +1930,6 @@ func TestSimplePullRequestGenerator(t *testing.T) {
Given(t).
// Create an PullRequestGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-pull-request-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "guestbook-{{ number }}"},
@@ -2059,9 +2006,6 @@ func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) {
Given(t).
// Create an PullRequestGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-pull-request-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -2134,12 +2078,9 @@ func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) {
},
}
Given(t).
// Create an PullRequestGenerator-based ApplicationSet
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "pull-request-generator-not-allowed-scm",
},
ctx := Given(t)
// Create an PullRequestGenerator-based ApplicationSet
ctx.When().Create(v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -2181,7 +2122,7 @@ func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) {
}).Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedApp})).
And(func() {
// app should be listed
output, err := fixture.RunCli("appset", "get", "pull-request-generator-not-allowed-scm")
output, err := fixture.RunCli("appset", "get", ctx.GetName())
require.NoError(t, err)
assert.Contains(t, output, "scm provider not allowed")
})
@@ -2189,11 +2130,8 @@ func TestPullRequestGeneratorNotAllowedSCMProvider(t *testing.T) {
// TestApplicationSetAPIListResourceEvents tests the ApplicationSet ListResourceEvents API
func TestApplicationSetAPIListResourceEvents(t *testing.T) {
Given(t).
When().Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "api-test-events",
},
ctx := Given(t)
ctx.When().Create(v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{
@@ -2228,7 +2166,7 @@ func TestApplicationSetAPIListResourceEvents(t *testing.T) {
defer utilio.Close(closer)
events, err := appSetClient.ListResourceEvents(t.Context(), &applicationset.ApplicationSetGetQuery{
Name: "api-test-events",
Name: ctx.GetName(),
})
require.NoError(t, err)
// Events list should be returned (may be empty if no events have been generated yet)

View File

@@ -42,7 +42,7 @@ func TestCliAppCommand(t *testing.T) {
And(func() {
output, err := RunCli("app", "sync", ctx.AppName(), "--timeout", "90")
require.NoError(t, err)
vars := map[string]any{"Name": ctx.AppName(), "Namespace": DeploymentNamespace()}
vars := map[string]any{"Name": ctx.AppName(), "Namespace": ctx.DeploymentNamespace()}
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} pod Synced Progressing pod/pod created`, vars))
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} hook Succeeded Synced Sync pod/hook created`, vars))
}).
@@ -55,7 +55,7 @@ func TestCliAppCommand(t *testing.T) {
expected := Tmpl(
t,
`{{.Name}} https://kubernetes.default.svc {{.Namespace}} default Synced Healthy Manual <none>`,
map[string]any{"Name": a.GetName(), "Namespace": DeploymentNamespace()})
map[string]any{"Name": a.GetName(), "Namespace": ctx.DeploymentNamespace()})
assert.Contains(t, NormalizeOutput(output), expected)
})
}
@@ -86,7 +86,7 @@ func TestNormalArgoCDCommandsExecuteOverPluginsWithSameName(t *testing.T) {
assert.NotContains(t, NormalizeOutput(output), "I am a plugin, not Argo CD!")
vars := map[string]any{"Name": ctx.AppName(), "Namespace": DeploymentNamespace()}
vars := map[string]any{"Name": ctx.AppName(), "Namespace": ctx.DeploymentNamespace()}
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} pod Synced Progressing pod/pod created`, vars))
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} hook Succeeded Synced Sync pod/hook created`, vars))
}).
@@ -102,7 +102,7 @@ func TestNormalArgoCDCommandsExecuteOverPluginsWithSameName(t *testing.T) {
expected := Tmpl(
t,
`{{.Name}} https://kubernetes.default.svc {{.Namespace}} default Synced Healthy Manual <none>`,
map[string]any{"Name": ctx.AppName(), "Namespace": DeploymentNamespace()})
map[string]any{"Name": ctx.AppName(), "Namespace": ctx.DeploymentNamespace()})
assert.Contains(t, NormalizeOutput(output), expected)
})
}

View File

@@ -49,9 +49,6 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) {
CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
SwitchToExternalNamespace(utils.ArgoCDExternalNamespace).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -147,9 +144,6 @@ func TestSimpleClusterGenerator(t *testing.T) {
When().
CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -272,9 +266,6 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) {
// Create a ClusterGenerator-based ApplicationSet
When().
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "in-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -363,9 +354,6 @@ func TestSimpleClusterGeneratorAddingCluster(t *testing.T) {
When().
CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -446,9 +434,6 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) {
CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -539,9 +524,6 @@ func TestClusterGeneratorWithFlatListMode(t *testing.T) {
When().
CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
GoTemplate: true,
Template: v1alpha1.ApplicationSetTemplate{

View File

@@ -25,20 +25,19 @@ func TestClusterList(t *testing.T) {
expected := fmt.Sprintf(`SERVER NAME VERSION STATUS MESSAGE PROJECT
https://kubernetes.default.svc in-cluster %v Successful `, fixture.GetVersions(t).ServerVersion)
clusterFixture.
Given(t).
Project(fixture.ProjectName)
ctx := clusterFixture.Given(t)
ctx.Project(fixture.ProjectName)
// We need an application targeting the cluster, otherwise the test will
// fail if run isolated.
app.GivenWithSameState(t).
app.GivenWithSameState(ctx).
Path(guestbookPath).
When().
CreateApp()
tries := 25
for i := 0; i <= tries; i++ {
clusterFixture.GivenWithSameState(t).
clusterFixture.GivenWithSameState(ctx).
When().
List().
Then().
@@ -70,15 +69,15 @@ func TestClusterAdd(t *testing.T) {
}
func TestClusterAddPermissionDenied(t *testing.T) {
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login().
SetPermissions([]fixture.ACL{}, "org-admin")
clusterFixture.
GivenWithSameState(t).
GivenWithSameState(ctx).
Project(fixture.ProjectName).
Upsert(true).
Server(KubernetesInternalAPIServerAddr).
@@ -92,8 +91,8 @@ func TestClusterAddPermissionDenied(t *testing.T) {
}
func TestClusterAddAllowed(t *testing.T) {
accountFixture.Given(t).
Name("test").
accountCtx := accountFixture.Given(t)
accountCtx.Name("test").
When().
Create().
Login().
@@ -110,7 +109,7 @@ func TestClusterAddAllowed(t *testing.T) {
},
}, "org-admin")
ctx := clusterFixture.GivenWithSameState(t)
ctx := clusterFixture.GivenWithSameState(accountCtx)
ctx.Project(fixture.ProjectName).
Project(fixture.ProjectName).
Upsert(true).
@@ -125,8 +124,8 @@ func TestClusterAddAllowed(t *testing.T) {
}
func TestClusterListDenied(t *testing.T) {
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login().
@@ -139,7 +138,7 @@ func TestClusterListDenied(t *testing.T) {
}, "org-admin")
clusterFixture.
GivenWithSameState(t).
GivenWithSameState(ctx).
Project(fixture.ProjectName).
Upsert(true).
Server(KubernetesInternalAPIServerAddr).
@@ -153,17 +152,14 @@ func TestClusterListDenied(t *testing.T) {
}
func TestClusterSet(t *testing.T) {
fixture.EnsureCleanState(t)
defer fixture.RecordTestRun(t)
clusterFixture.
GivenWithSameState(t).
Project(fixture.ProjectName).
Name("in-cluster").
ctx := clusterFixture.Given(t)
ctx.Project(fixture.ProjectName).
Namespaces([]string{"namespace-edit-1", "namespace-edit-2"}).
Server(KubernetesInternalAPIServerAddr).
When().
Create().
SetNamespaces().
GetByName("in-cluster").
GetByName().
Then().
AndCLIOutput(func(output string, _ error) {
assert.Contains(t, output, "namespace-edit-1")
@@ -222,8 +218,8 @@ func TestClusterURLInRestAPI(t *testing.T) {
}
func TestClusterDeleteDenied(t *testing.T) {
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login().
@@ -242,7 +238,7 @@ func TestClusterDeleteDenied(t *testing.T) {
// Attempt to remove cluster creds by name
clusterFixture.
GivenWithSameState(t).
GivenWithSameState(ctx).
Project(fixture.ProjectName).
Upsert(true).
Server(KubernetesInternalAPIServerAddr).
@@ -256,7 +252,7 @@ func TestClusterDeleteDenied(t *testing.T) {
// Attempt to remove cluster creds by server
clusterFixture.
GivenWithSameState(t).
GivenWithSameState(ctx).
Project(fixture.ProjectName).
Upsert(true).
Server(KubernetesInternalAPIServerAddr).
@@ -270,8 +266,8 @@ func TestClusterDeleteDenied(t *testing.T) {
}
func TestClusterDelete(t *testing.T) {
accountFixture.Given(t).
Name("default").
ctx := clusterFixture.Given(t)
accountFixture.GivenWithSameState(ctx).
When().
Create().
Login().
@@ -293,14 +289,18 @@ func TestClusterDelete(t *testing.T) {
},
}, "org-admin")
clstAction := clusterFixture.
GivenWithSameState(t).
Name("default").
clstAction := ctx.
Project(fixture.ProjectName).
Upsert(true).
Server(KubernetesInternalAPIServerAddr).
When().
CreateWithRBAC()
clstAction.
Then().
Expect().
AndCLIOutput(func(_ string, err error) {
assert.NoError(t, err)
})
// Check that RBAC is created
_, err := fixture.Run("", "kubectl", "get", "serviceaccount", "argocd-manager", "-n", "kube-system")
@@ -315,7 +315,7 @@ func TestClusterDelete(t *testing.T) {
clstAction.DeleteByName().
Then().
AndCLIOutput(func(output string, _ error) {
assert.Equal(t, "Cluster 'default' removed", output)
assert.Equal(t, fmt.Sprintf("Cluster '%s' removed", ctx.GetName()), output)
})
// Check that RBAC is removed after delete

View File

@@ -63,9 +63,6 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) {
StatusUpdatePlacementDecision("my-placementdecision", clusterList).
SwitchToExternalNamespace(utils.ArgoCDExternalNamespace).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -169,9 +166,6 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) {
CreatePlacementDecision("my-placementdecision").
StatusUpdatePlacementDecision("my-placementdecision", clusterList).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -280,9 +274,6 @@ func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) {
CreatePlacementDecision("my-placementdecision").
StatusUpdatePlacementDecision("my-placementdecision", clusterList).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -376,9 +367,6 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing.
CreatePlacementDecision("my-placementdecision").
StatusUpdatePlacementDecision("my-placementdecision", clusterList).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
@@ -480,9 +468,6 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *te
CreatePlacementDecision("my-placementdecision").
StatusUpdatePlacementDecision("my-placementdecision", clusterList).
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "simple-cluster-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},

View File

@@ -23,7 +23,8 @@ import (
func TestCrossNamespaceOwnership(t *testing.T) {
var clusterRoleUID string
Given(t).
ctx := Given(t)
ctx.
Path("cross-namespace-ownership").
When().
CreateApp().
@@ -54,14 +55,14 @@ metadata:
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]`, DeploymentNamespace(), clusterRoleUID)
verbs: ["get", "list"]`, ctx.DeploymentNamespace(), clusterRoleUID)
_, err := Run("", "sh", "-c", fmt.Sprintf("echo '%s' | kubectl apply -f -", roleYaml))
require.NoError(t, err)
t.Logf("Created Role in app namespace: %s", DeploymentNamespace())
t.Logf("Created Role in app namespace: %s", ctx.DeploymentNamespace())
// Create another namespace for cross-namespace testing
otherNamespace := DeploymentNamespace() + "-other"
otherNamespace := ctx.DeploymentNamespace() + "-other"
_, err = Run("", "kubectl", "create", "namespace", otherNamespace)
if err != nil {
// Namespace might already exist, that's ok
@@ -185,7 +186,8 @@ rules:
func TestCrossNamespaceOwnershipWithRefresh(t *testing.T) {
var clusterRoleUID string
Given(t).
ctx := Given(t)
ctx.
Path("cross-namespace-ownership").
When().
CreateApp().
@@ -215,7 +217,7 @@ metadata:
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]`, DeploymentNamespace(), clusterRoleUID)
verbs: ["get", "list"]`, ctx.DeploymentNamespace(), clusterRoleUID)
_, err := Run("", "sh", "-c", fmt.Sprintf("echo '%s' | kubectl apply -f -", roleYaml))
require.NoError(t, err)

View File

@@ -35,7 +35,7 @@ func TestCustomToolWithGitCreds(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitAskpass}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitAskpass}")
require.NoError(t, err)
assert.Equal(t, "argocd", output)
})
@@ -61,17 +61,17 @@ func TestCustomToolWithGitCredsTemplate(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitAskpass}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitAskpass}")
require.NoError(t, err)
assert.Equal(t, "argocd", output)
}).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitUsername}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitUsername}")
require.NoError(t, err)
assert.Empty(t, output)
}).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitPassword}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitPassword}")
require.NoError(t, err)
assert.Empty(t, output)
})
@@ -97,12 +97,12 @@ func TestCustomToolWithSSHGitCreds(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", fixture.Name(), "-o", "jsonpath={.metadata.annotations.GitSSHCommand}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.GetName(), "-o", "jsonpath={.metadata.annotations.GitSSHCommand}")
require.NoError(t, err)
assert.Regexp(t, `-i [^ ]+`, output, "test plugin expects $GIT_SSH_COMMAND to contain the option '-i <path to ssh private key>'")
}).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", fixture.Name(), "-o", "jsonpath={.metadata.annotations.GitSSHCredsFileSHA}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.GetName(), "-o", "jsonpath={.metadata.annotations.GitSSHCredsFileSHA}")
require.NoError(t, err)
assert.Regexp(t, `\w+\s+[\/\w]+`, output, "git ssh credentials file should be able to be read, hashing the contents")
})
@@ -153,18 +153,18 @@ func TestCustomToolWithEnv(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}")
require.NoError(t, err)
assert.Equal(t, "baz", output)
}).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Foo}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Foo}")
require.NoError(t, err)
assert.Equal(t, "bar", output)
}).
And(func(_ *Application) {
expectedKubeVersion := fixture.GetVersions(t).ServerVersion.Format("%s.%s")
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeVersion}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeVersion}")
require.NoError(t, err)
assert.Equal(t, expectedKubeVersion, output)
}).
@@ -173,7 +173,7 @@ func TestCustomToolWithEnv(t *testing.T) {
expectedAPIVersionSlice := strings.Split(expectedAPIVersion, ",")
sort.Strings(expectedAPIVersionSlice)
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeApiVersion}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeApiVersion}")
require.NoError(t, err)
outputSlice := strings.Split(output, ",")
sort.Strings(outputSlice)
@@ -268,13 +268,13 @@ func TestCMPDiscoverWithFindCommandWithEnv(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
And(func(_ *Application) {
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}")
require.NoError(t, err)
assert.Equal(t, "baz", output)
}).
And(func(_ *Application) {
expectedKubeVersion := fixture.GetVersions(t).ServerVersion.Format("%s.%s")
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeVersion}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeVersion}")
require.NoError(t, err)
assert.Equal(t, expectedKubeVersion, output)
}).
@@ -283,7 +283,7 @@ func TestCMPDiscoverWithFindCommandWithEnv(t *testing.T) {
expectedAPIVersionSlice := strings.Split(expectedAPIVersion, ",")
sort.Strings(expectedAPIVersionSlice)
output, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeApiVersion}")
output, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.KubeApiVersion}")
require.NoError(t, err)
outputSlice := strings.Split(output, ",")
sort.Strings(outputSlice)
@@ -307,7 +307,7 @@ func TestPruneResourceFromCMP(t *testing.T) {
Then().
Expect(DoesNotExist()).
AndAction(func() {
_, err := fixture.Run("", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "deployment", "guestbook-ui")
_, err := fixture.Run("", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "deployment", "guestbook-ui")
require.Error(t, err)
})
}

View File

@@ -70,7 +70,7 @@ func TestDeploymentWithAnnotationTrackingMode(t *testing.T) {
require.NoError(t, err)
assert.Contains(t, out, fmt.Sprintf(`annotations:
argocd.argoproj.io/tracking-id: %s:apps/Deployment:%s/nginx-deployment
`, ctx.AppName(), DeploymentNamespace()))
`, ctx.AppName(), ctx.DeploymentNamespace()))
})
}
@@ -116,7 +116,7 @@ func TestDeploymentWithoutTrackingMode(t *testing.T) {
require.NoError(t, err)
assert.Contains(t, out, fmt.Sprintf(`annotations:
argocd.argoproj.io/tracking-id: %s:apps/Deployment:%s/nginx-deployment
`, ctx.AppName(), DeploymentNamespace()))
`, ctx.AppName(), ctx.DeploymentNamespace()))
})
}
@@ -128,19 +128,20 @@ func TestDeployToKubernetesAPIURLWithQueryParameter(t *testing.T) {
// We test with both a cluster-scoped, and a non-cluster scoped, Argo CD Cluster Secret.
clusterScopedParam := []bool{false, true}
for _, clusterScoped := range clusterScopedParam {
EnsureCleanState(t)
ctx := Given(t)
// Simulate two users, each with their own Argo CD cluster secret that can only deploy to their Namespace
users := []string{E2ETestPrefix + "user1", E2ETestPrefix + "user2"}
users := []string{"user1", "user2"}
for _, username := range users {
createNamespaceScopedUser(t, username, clusterScoped)
ns, _, destName := createNamespaceScopedUser(ctx, username, clusterScoped)
GivenWithSameState(t).
GivenWithSameState(ctx).
Name("e2e-test-app-"+username).
DestName(destName).
Path("deployment").
When().
CreateWithNoNameSpace("--dest-namespace", username).
CreateWithNoNameSpace("--dest-namespace", ns).
Sync().
Then().
Expect(OperationPhaseIs(OperationSucceeded)).
@@ -159,13 +160,23 @@ func TestArgoCDSupportsMultipleServiceAccountsWithDifferingRBACOnSameCluster(t *
clusterScopedParam := []bool{ /*false,*/ true}
for _, clusterScoped := range clusterScopedParam {
EnsureCleanState(t)
ctx := Given(t)
// Simulate two users, each with their own Argo CD cluster secret that can only deploy to their Namespace
users := []string{E2ETestPrefix + "user1", E2ETestPrefix + "user2"}
users := []string{"user1", "user2"}
nsInfo := make(map[string]struct {
namespace string
serviceAccount string
destName string
})
for _, username := range users {
createNamespaceScopedUser(t, username, clusterScoped)
ns, sa, destName := createNamespaceScopedUser(ctx, username, clusterScoped)
nsInfo[username] = struct {
namespace string
serviceAccount string
destName string
}{namespace: ns, serviceAccount: sa, destName: destName}
}
for idx, username := range users {
@@ -174,21 +185,21 @@ func TestArgoCDSupportsMultipleServiceAccountsWithDifferingRBACOnSameCluster(t *
otherUser := users[(idx+1)%len(users)]
// e.g. Attempt to deploy to user1's namespace, with user2's cluster Secret. This should fail, as user2's cluster Secret does not have the requisite permissions.
consequences := GivenWithSameState(t).
consequences := GivenWithSameState(ctx).
Name("e2e-test-app-"+username).
DestName(E2ETestPrefix+"cluster-"+otherUser).
DestName(nsInfo[otherUser].destName).
Path("deployment").
When().
CreateWithNoNameSpace("--dest-namespace", username).IgnoreErrors().
CreateWithNoNameSpace("--dest-namespace", nsInfo[username].namespace).IgnoreErrors().
Sync().Then()
// The error message differs based on whether the Argo CD Cluster Secret is namespace-scoped or cluster-scoped, but the idea is the same:
// - Even when deploying to the same cluster using 2 separate ServiceAccounts, the RBAC of those ServiceAccounts should continue to fully enforce RBAC boundaries.
if !clusterScoped {
consequences.Expect(Condition(ApplicationConditionComparisonError, "Namespace \""+username+"\" for Deployment \"nginx-deployment\" is not managed"))
consequences.Expect(Condition(ApplicationConditionComparisonError, "Namespace \""+nsInfo[username].namespace+"\" for Deployment \"nginx-deployment\" is not managed"))
} else {
consequences.Expect(OperationMessageContains("User \"system:serviceaccount:" + otherUser + ":" + otherUser + "-serviceaccount\" cannot create resource \"deployments\" in API group \"apps\" in the namespace \"" + username + "\""))
consequences.Expect(OperationMessageContains("User \"system:serviceaccount:" + nsInfo[otherUser].namespace + ":" + nsInfo[otherUser].serviceAccount + "\" cannot create resource \"deployments\" in API group \"apps\" in the namespace \"" + nsInfo[username].namespace + "\""))
}
}
}
@@ -196,10 +207,13 @@ func TestArgoCDSupportsMultipleServiceAccountsWithDifferingRBACOnSameCluster(t *
// generateReadOnlyClusterRoleandBindingForServiceAccount creates a ClusterRole/Binding that allows a ServiceAccount in a given namespace to read all resources on a cluster.
// - This allows the ServiceAccount to be used within a cluster-scoped Argo CD Cluster Secret
func generateReadOnlyClusterRoleandBindingForServiceAccount(roleSuffix string, serviceAccountNS string) (rbacv1.ClusterRole, rbacv1.ClusterRoleBinding) {
func generateReadOnlyClusterRoleandBindingForServiceAccount(c *Context, username, serviceAccountName, namespace string) (rbacv1.ClusterRole, rbacv1.ClusterRoleBinding) {
clusterRole := rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: E2ETestPrefix + "read-all-" + roleSuffix,
Name: DnsFriendly("read-all-"+username, "-"+c.ShortID()),
Labels: map[string]string{
TestingLabel: "true",
},
},
Rules: []rbacv1.PolicyRule{{
Verbs: []string{"get", "list", "watch"},
@@ -210,12 +224,15 @@ func generateReadOnlyClusterRoleandBindingForServiceAccount(roleSuffix string, s
clusterRoleBinding := rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: E2ETestPrefix + "read-all-" + roleSuffix,
Name: DnsFriendly("read-all-"+username, "-"+c.ShortID()),
Labels: map[string]string{
TestingLabel: "true",
},
},
Subjects: []rbacv1.Subject{{
Kind: rbacv1.ServiceAccountKind,
Namespace: serviceAccountNS,
Name: roleSuffix + "-serviceaccount",
Namespace: namespace,
Name: serviceAccountName,
}},
RoleRef: rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
@@ -258,26 +275,29 @@ func buildArgoCDClusterSecret(secretName, secretNamespace, clusterName, clusterS
// createNamespaceScopedUser
// - username = name of Namespace the simulated user is able to deploy to
// - clusterScopedSecrets = whether the Service Account is namespace-scoped or cluster-scoped.
func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecrets bool) {
t.Helper()
func createNamespaceScopedUser(c *Context, username string, clusterScopedSecrets bool) (string, string, string) {
c.T().Helper()
// Create a new Namespace for our simulated user
ns := corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: username,
Name: DnsFriendly(username, "-"+c.ShortID()),
Labels: map[string]string{
TestingLabel: "true",
},
},
}
_, err := KubeClientset.CoreV1().Namespaces().Create(t.Context(), &ns, metav1.CreateOptions{})
require.NoError(t, err)
_, err := KubeClientset.CoreV1().Namespaces().Create(c.T().Context(), &ns, metav1.CreateOptions{})
require.NoError(c.T(), err)
// Create a ServiceAccount in that Namespace, which will be used for the Argo CD Cluster SEcret
serviceAccountName := username + "-serviceaccount"
serviceAccountName := DnsFriendly(username, "-sa-"+c.ShortID())
err = clusterauth.CreateServiceAccount(KubeClientset, serviceAccountName, ns.Name)
require.NoError(t, err)
require.NoError(c.T(), err)
// Create a Role that allows the ServiceAccount to read/write all within the Namespace
role := rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{
Name: E2ETestPrefix + "allow-all",
Name: DnsFriendly("allow-all", "-"+c.ShortID()),
Namespace: ns.Name,
},
Rules: []rbacv1.PolicyRule{{
@@ -286,13 +306,13 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre
APIGroups: []string{"*"},
}},
}
_, err = KubeClientset.RbacV1().Roles(role.Namespace).Create(t.Context(), &role, metav1.CreateOptions{})
require.NoError(t, err)
_, err = KubeClientset.RbacV1().Roles(role.Namespace).Create(c.T().Context(), &role, metav1.CreateOptions{})
require.NoError(c.T(), err)
// Bind the Role with the ServiceAccount in the Namespace
roleBinding := rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: E2ETestPrefix + "allow-all-binding",
Name: DnsFriendly("allow-all-binding", "-"+c.ShortID()),
Namespace: ns.Name,
},
Subjects: []rbacv1.Subject{{
@@ -306,32 +326,32 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre
Name: role.Name,
},
}
_, err = KubeClientset.RbacV1().RoleBindings(roleBinding.Namespace).Create(t.Context(), &roleBinding, metav1.CreateOptions{})
require.NoError(t, err)
_, err = KubeClientset.RbacV1().RoleBindings(roleBinding.Namespace).Create(c.T().Context(), &roleBinding, metav1.CreateOptions{})
require.NoError(c.T(), err)
var token string
// Attempting to patch the ServiceAccount can intermittently fail with 'failed to patch serviceaccount "(...)" with bearer token secret: Operation cannot be fulfilled on serviceaccounts "(...)": the object has been modified; please apply your changes to the latest version and try again'
// We thus keep trying for up to 20 seconds.
waitErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 20*time.Second, true, func(context.Context) (done bool, err error) {
waitErr := wait.PollUntilContextTimeout(c.T().Context(), 1*time.Second, 20*time.Second, true, func(context.Context) (done bool, err error) {
// Retrieve the bearer token from the ServiceAccount
token, err = clusterauth.GetServiceAccountBearerToken(KubeClientset, ns.Name, serviceAccountName, time.Second*60)
// Success is no error and a real token, otherwise keep trying
return (err == nil && token != ""), nil
})
require.NoError(t, waitErr)
require.NotEmpty(t, token)
require.NoError(c.T(), waitErr)
require.NotEmpty(c.T(), token)
// In order to test a cluster-scoped Argo CD Cluster Secret, we may optionally grant the ServiceAccount read-all permissions at cluster scope.
if clusterScopedSecrets {
clusterRole, clusterRoleBinding := generateReadOnlyClusterRoleandBindingForServiceAccount(username, username)
clusterRole, clusterRoleBinding := generateReadOnlyClusterRoleandBindingForServiceAccount(c, username, serviceAccountName, ns.Name)
_, err := KubeClientset.RbacV1().ClusterRoles().Create(t.Context(), &clusterRole, metav1.CreateOptions{})
require.NoError(t, err)
_, err := KubeClientset.RbacV1().ClusterRoles().Create(c.T().Context(), &clusterRole, metav1.CreateOptions{})
require.NoError(c.T(), err)
_, err = KubeClientset.RbacV1().ClusterRoleBindings().Create(t.Context(), &clusterRoleBinding, metav1.CreateOptions{})
require.NoError(t, err)
_, err = KubeClientset.RbacV1().ClusterRoleBindings().Create(c.T().Context(), &clusterRoleBinding, metav1.CreateOptions{})
require.NoError(c.T(), err)
}
// Build the Argo CD Cluster Secret by using the service account token, and extracting needed values from kube config
@@ -343,10 +363,10 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre
}
jsonStringBytes, err := json.Marshal(clusterSecretConfigJSON)
require.NoError(t, err)
require.NoError(c.T(), err)
_, apiURL, err := extractKubeConfigValues()
require.NoError(t, err)
require.NoError(c.T(), err)
clusterResourcesField := ""
namespacesField := ""
@@ -358,13 +378,14 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre
// We create an Argo CD cluster Secret declaratively, using the K8s client, rather than via CLI, as the CLI doesn't currently
// support Kubernetes API server URLs with query parameters.
secret := buildArgoCDClusterSecret("test-"+username, ArgoCDNamespace, E2ETestPrefix+"cluster-"+username, apiURL+"?user="+username,
clusterName := DnsFriendly("test-"+username, "-"+c.ShortID())
secret := buildArgoCDClusterSecret(clusterName, ArgoCDNamespace, clusterName, apiURL+"?user="+username,
string(jsonStringBytes), clusterResourcesField, namespacesField)
// Finally, create the Cluster secret in the Argo CD E2E namespace
_, err = KubeClientset.CoreV1().Secrets(secret.Namespace).Create(t.Context(), &secret, metav1.CreateOptions{})
require.NoError(t, err)
_, err = KubeClientset.CoreV1().Secrets(secret.Namespace).Create(c.T().Context(), &secret, metav1.CreateOptions{})
require.NoError(c.T(), err)
return ns.Name, serviceAccountName, clusterName
}
// extractKubeConfigValues returns contents of the local environment's kubeconfig, using standard path resolution mechanism.

View File

@@ -1,4 +1,4 @@
package project
package account
import (
"time"
@@ -19,59 +19,59 @@ type Actions struct {
}
func (a *Actions) prepareCanIGetLogsArgs() []string {
a.context.t.Helper()
a.context.T().Helper()
return []string{
"account", "can-i", "get", "logs", a.context.project + "/*",
}
}
func (a *Actions) CanIGetLogs() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli(a.prepareCanIGetLogsArgs()...)
return a
}
func (a *Actions) prepareSetPasswordArgs(account string) []string {
a.context.t.Helper()
a.context.T().Helper()
return []string{
"account", "update-password", "--account", account, "--current-password", fixture.AdminPassword, "--new-password", fixture.DefaultTestUserPassword,
}
}
func (a *Actions) Create() *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetAccounts(map[string][]string{
a.context.name: {"login"},
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetAccounts(map[string][]string{
a.context.GetName(): {"login"},
}))
_, _ = fixture.RunCli(a.prepareSetPasswordArgs(a.context.name)...)
_, _ = fixture.RunCli(a.prepareSetPasswordArgs(a.context.GetName())...)
return a
}
func (a *Actions) SetPermissions(permissions []fixture.ACL, roleName string) *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetPermissions(permissions, a.context.name, roleName))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetPermissions(permissions, a.context.GetName(), roleName))
return a
}
func (a *Actions) SetParamInSettingConfigMap(key, value string) *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetParamInSettingConfigMap(key, value))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetParamInSettingConfigMap(key, value))
return a
}
func (a *Actions) Login() *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.LoginAs(a.context.name))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.LoginAs(a.context.GetName()))
return a
}
func (a *Actions) runCli(args ...string) {
a.context.t.Helper()
a.context.T().Helper()
a.lastOutput, a.lastError = fixture.RunCli(args...)
}
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
a.context.T().Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -1,4 +1,4 @@
package project
package account
import (
"context"
@@ -21,19 +21,19 @@ type Consequences struct {
}
func (c *Consequences) And(block func(account *account.Account, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.get())
return c
}
func (c *Consequences) AndCLIOutput(block func(output string, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.actions.lastOutput, c.actions.lastError)
return c
}
func (c *Consequences) CurrentUser(block func(user *session.GetUserInfoResponse, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.getCurrentUser())
return c
}
@@ -45,7 +45,7 @@ func (c *Consequences) get() (*account.Account, error) {
return nil, err
}
for _, acc := range accList.Items {
if acc.Name == c.context.name {
if acc.Name == c.context.GetName() {
return acc, nil
}
}
@@ -53,9 +53,9 @@ func (c *Consequences) get() (*account.Account, error) {
}
func (c *Consequences) getCurrentUser() (*session.GetUserInfoResponse, error) {
c.context.t.Helper()
c.context.T().Helper()
closer, client, err := fixture.ArgoCDClientset.NewSessionClient()
require.NoError(c.context.t, err)
require.NoError(c.context.T(), err)
defer utilio.Close(closer)
return client.GetUserInfo(context.Background(), &session.GetUserInfoRequest{})
}

View File

@@ -1,4 +1,4 @@
package project
package account
import (
"testing"
@@ -7,18 +7,25 @@ import (
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
// this implements the "given" part of given/when/then
// Context implements the "given" part of given/when/then.
// It embeds fixture.TestState to provide test-specific state that enables parallel test execution.
type Context struct {
t *testing.T
// seconds
name string
*fixture.TestState
project string
}
func Given(t *testing.T) *Context {
t.Helper()
fixture.EnsureCleanState(t)
return &Context{t: t, name: fixture.Name()}
state := fixture.EnsureCleanState(t)
return &Context{TestState: state}
}
// GivenWithSameState creates a new Context that shares the same TestState as an existing context.
// Use this when you need multiple fixture contexts within the same test.
func GivenWithSameState(ctx fixture.TestContext) *Context {
ctx.T().Helper()
return &Context{TestState: fixture.NewTestStateFromContext(ctx)}
}
func (c *Context) Project(project string) *Context {
@@ -26,12 +33,8 @@ func (c *Context) Project(project string) *Context {
return c
}
func (c *Context) GetName() string {
return c.name
}
func (c *Context) Name(name string) *Context {
c.name = name
c.SetName(name)
return c
}

View File

@@ -17,43 +17,43 @@ type Actions struct {
}
func (a *Actions) prepareExportCommand() []string {
a.context.t.Helper()
a.context.T().Helper()
args := []string{"export", "--application-namespaces", fixture.AppNamespace()}
return args
}
func (a *Actions) prepareImportCommand() []string {
a.context.t.Helper()
a.context.T().Helper()
args := []string{"import", "--application-namespaces", fixture.AppNamespace(), "-"}
return args
}
func (a *Actions) RunExport() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli(a.prepareExportCommand()...)
return a
}
func (a *Actions) RunImport(stdin string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCliWithStdin(stdin, a.prepareImportCommand()...)
return a
}
func (a *Actions) runCli(args ...string) {
a.context.t.Helper()
a.context.T().Helper()
a.lastOutput, a.lastError = RunCli(args...)
}
func (a *Actions) runCliWithStdin(stdin string, args ...string) {
a.context.t.Helper()
a.context.T().Helper()
a.lastOutput, a.lastError = RunCliWithStdin(stdin, args...)
}
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
a.context.T().Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -14,13 +14,13 @@ type Consequences struct {
}
func (c *Consequences) And(block func()) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block()
return c
}
func (c *Consequences) AndCLIOutput(block func(output string, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.actions.lastOutput, c.actions.lastError)
return c
}

View File

@@ -7,20 +7,23 @@ import (
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
// this implements the "given" part of given/when/then
// Context implements the "given" part of given/when/then.
// It embeds fixture.TestState to provide test-specific state that enables parallel test execution.
type Context struct {
t *testing.T
*fixture.TestState
}
func Given(t *testing.T) *Context {
t.Helper()
fixture.EnsureCleanState(t)
return GivenWithSameState(t)
state := fixture.EnsureCleanState(t)
return &Context{TestState: state}
}
func GivenWithSameState(t *testing.T) *Context {
t.Helper()
return &Context{t}
// GivenWithSameState creates a new Context that shares the same TestState as an existing context.
// Use this when you need multiple fixture contexts within the same test.
func GivenWithSameState(ctx fixture.TestContext) *Context {
ctx.T().Helper()
return &Context{TestState: fixture.NewTestStateFromContext(ctx)}
}
func (c *Context) And(block func()) *Context {

View File

@@ -1,6 +1,7 @@
package app
import (
"context"
"encoding/json"
"fmt"
"os"
@@ -8,6 +9,7 @@ import (
"strconv"
"time"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
log "github.com/sirupsen/logrus"
@@ -42,71 +44,71 @@ func (a *Actions) DoNotIgnoreErrors() *Actions {
}
func (a *Actions) PatchFile(file string, jsonPatch string) *Actions {
a.context.t.Helper()
fixture.Patch(a.context.t, a.context.path+"/"+file, jsonPatch)
a.context.T().Helper()
fixture.Patch(a.context.T(), a.context.path+"/"+file, jsonPatch)
return a
}
func (a *Actions) DeleteFile(file string) *Actions {
a.context.t.Helper()
fixture.Delete(a.context.t, a.context.path+"/"+file)
a.context.T().Helper()
fixture.Delete(a.context.T(), a.context.path+"/"+file)
return a
}
func (a *Actions) WriteFile(fileName, fileContents string) *Actions {
a.context.t.Helper()
fixture.WriteFile(a.context.t, a.context.path+"/"+fileName, fileContents)
a.context.T().Helper()
fixture.WriteFile(a.context.T(), a.context.path+"/"+fileName, fileContents)
return a
}
func (a *Actions) AddFile(fileName, fileContents string) *Actions {
a.context.t.Helper()
fixture.AddFile(a.context.t, a.context.path+"/"+fileName, fileContents)
a.context.T().Helper()
fixture.AddFile(a.context.T(), a.context.path+"/"+fileName, fileContents)
return a
}
func (a *Actions) AddSignedFile(fileName, fileContents string) *Actions {
a.context.t.Helper()
fixture.AddSignedFile(a.context.t, a.context.path+"/"+fileName, fileContents)
a.context.T().Helper()
fixture.AddSignedFile(a.context.T(), a.context.path+"/"+fileName, fileContents)
return a
}
func (a *Actions) AddSignedTag(name string) *Actions {
a.context.t.Helper()
fixture.AddSignedTag(a.context.t, name)
a.context.T().Helper()
fixture.AddSignedTag(a.context.T(), name)
return a
}
func (a *Actions) AddTag(name string) *Actions {
a.context.t.Helper()
fixture.AddTag(a.context.t, name)
a.context.T().Helper()
fixture.AddTag(a.context.T(), name)
return a
}
func (a *Actions) AddAnnotatedTag(name string, message string) *Actions {
a.context.t.Helper()
fixture.AddAnnotatedTag(a.context.t, name, message)
a.context.T().Helper()
fixture.AddAnnotatedTag(a.context.T(), name, message)
return a
}
func (a *Actions) AddTagWithForce(name string) *Actions {
a.context.t.Helper()
fixture.AddTagWithForce(a.context.t, name)
a.context.T().Helper()
fixture.AddTagWithForce(a.context.T(), name)
return a
}
func (a *Actions) RemoveSubmodule() *Actions {
a.context.t.Helper()
fixture.RemoveSubmodule(a.context.t)
a.context.T().Helper()
fixture.RemoveSubmodule(a.context.T())
return a
}
func (a *Actions) CreateFromPartialFile(data string, flags ...string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
tmpFile, err := os.CreateTemp("", "")
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
_, err = tmpFile.WriteString(data)
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
args := append([]string{
"app", "create",
@@ -114,7 +116,7 @@ func (a *Actions) CreateFromPartialFile(data string, flags ...string) *Actions {
"--name", a.context.AppName(),
"--repo", fixture.RepoURL(a.context.repoURLType),
"--dest-server", a.context.destServer,
"--dest-namespace", fixture.DeploymentNamespace(),
"--dest-namespace", a.context.DeploymentNamespace(),
}, flags...)
if a.context.appNamespace != "" {
args = append(args, "--app-namespace", a.context.appNamespace)
@@ -125,7 +127,7 @@ func (a *Actions) CreateFromPartialFile(data string, flags ...string) *Actions {
}
func (a *Actions) CreateFromFile(handler func(app *v1alpha1.Application), flags ...string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
app := &v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: a.context.AppName(),
@@ -139,7 +141,7 @@ func (a *Actions) CreateFromFile(handler func(app *v1alpha1.Application), flags
},
Destination: v1alpha1.ApplicationDestination{
Server: a.context.destServer,
Namespace: fixture.DeploymentNamespace(),
Namespace: a.context.DeploymentNamespace(),
},
},
}
@@ -168,9 +170,9 @@ func (a *Actions) CreateFromFile(handler func(app *v1alpha1.Application), flags
handler(app)
data := grpc.MustMarshal(app)
tmpFile, err := os.CreateTemp("", "")
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
_, err = tmpFile.Write(data)
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
args := append([]string{
"app", "create",
@@ -182,7 +184,7 @@ func (a *Actions) CreateFromFile(handler func(app *v1alpha1.Application), flags
}
func (a *Actions) CreateMultiSourceAppFromFile(flags ...string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
app := &v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: a.context.AppName(),
@@ -193,7 +195,7 @@ func (a *Actions) CreateMultiSourceAppFromFile(flags ...string) *Actions {
Sources: a.context.sources,
Destination: v1alpha1.ApplicationDestination{
Server: a.context.destServer,
Namespace: fixture.DeploymentNamespace(),
Namespace: a.context.DeploymentNamespace(),
},
SyncPolicy: &v1alpha1.SyncPolicy{
Automated: &v1alpha1.SyncPolicyAutomated{
@@ -205,9 +207,9 @@ func (a *Actions) CreateMultiSourceAppFromFile(flags ...string) *Actions {
data := grpc.MustMarshal(app)
tmpFile, err := os.CreateTemp("", "")
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
_, err = tmpFile.Write(data)
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
args := append([]string{
"app", "create",
@@ -227,7 +229,7 @@ func (a *Actions) CreateWithNoNameSpace(args ...string) *Actions {
func (a *Actions) CreateApp(args ...string) *Actions {
args = a.prepareCreateAppArgs(args)
args = append(args, "--dest-namespace", fixture.DeploymentNamespace())
args = append(args, "--dest-namespace", a.context.DeploymentNamespace())
// are you adding new context values? if you only use them for this func, then use args instead
a.runCli(args...)
@@ -236,7 +238,7 @@ func (a *Actions) CreateApp(args ...string) *Actions {
}
func (a *Actions) prepareCreateAppArgs(args []string) []string {
a.context.t.Helper()
a.context.T().Helper()
args = append([]string{
"app", "create", a.context.AppQualifiedName(),
}, args...)
@@ -327,33 +329,33 @@ func (a *Actions) prepareCreateAppArgs(args []string) []string {
}
func (a *Actions) Declarative(filename string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
return a.DeclarativeWithCustomRepo(filename, fixture.RepoURL(a.context.repoURLType))
}
func (a *Actions) DeclarativeWithCustomRepo(filename string, repoURL string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
values := map[string]any{
"ArgoCDNamespace": fixture.TestNamespace(),
"DeploymentNamespace": fixture.DeploymentNamespace(),
"DeploymentNamespace": a.context.DeploymentNamespace(),
"Name": a.context.AppName(),
"Path": a.context.path,
"Project": a.context.project,
"RepoURL": repoURL,
}
a.lastOutput, a.lastError = fixture.Declarative(a.context.t, filename, values)
a.lastOutput, a.lastError = fixture.Declarative(a.context.T(), filename, values)
a.verifyAction()
return a
}
func (a *Actions) PatchApp(patch string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("app", "patch", a.context.AppQualifiedName(), "--patch", patch)
return a
}
func (a *Actions) PatchAppHttp(patch string) *Actions { //nolint:revive //FIXME(var-naming)
a.context.t.Helper()
a.context.T().Helper()
var application v1alpha1.Application
patchType := "merge"
appName := a.context.AppQualifiedName()
@@ -365,17 +367,17 @@ func (a *Actions) PatchAppHttp(patch string) *Actions { //nolint:revive //FIXME(
AppNamespace: &appNamespace,
}
jsonBytes, err := json.MarshalIndent(patchRequest, "", " ")
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
err = fixture.DoHttpJsonRequest("PATCH",
fmt.Sprintf("/api/v1/applications/%v", appName),
&application,
jsonBytes...)
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
return a
}
func (a *Actions) AppSet(flags ...string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
args := []string{"app", "set", a.context.AppQualifiedName()}
args = append(args, flags...)
a.runCli(args...)
@@ -383,7 +385,7 @@ func (a *Actions) AppSet(flags ...string) *Actions {
}
func (a *Actions) AppUnSet(flags ...string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
args := []string{"app", "unset", a.context.AppQualifiedName()}
args = append(args, flags...)
a.runCli(args...)
@@ -391,9 +393,9 @@ func (a *Actions) AppUnSet(flags ...string) *Actions {
}
func (a *Actions) Sync(args ...string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
args = append([]string{"app", "sync"}, args...)
if a.context.name != "" {
if a.context.GetName() != "" {
args = append(args, a.context.AppQualifiedName())
}
args = append(args, "--timeout", strconv.Itoa(a.context.timeout))
@@ -437,7 +439,7 @@ func (a *Actions) Sync(args ...string) *Actions {
}
func (a *Actions) ConfirmDeletion() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("app", "confirm-deletion", a.context.AppQualifiedName())
@@ -449,13 +451,13 @@ func (a *Actions) ConfirmDeletion() *Actions {
}
func (a *Actions) TerminateOp() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("app", "terminate-op", a.context.AppQualifiedName())
return a
}
func (a *Actions) Refresh(refreshType v1alpha1.RefreshType) *Actions {
a.context.t.Helper()
a.context.T().Helper()
flag := map[v1alpha1.RefreshType]string{
v1alpha1.RefreshTypeNormal: "--refresh",
v1alpha1.RefreshTypeHard: "--hard-refresh",
@@ -467,33 +469,33 @@ func (a *Actions) Refresh(refreshType v1alpha1.RefreshType) *Actions {
}
func (a *Actions) Get() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("app", "get", a.context.AppQualifiedName())
return a
}
func (a *Actions) Delete(cascade bool) *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("app", "delete", a.context.AppQualifiedName(), fmt.Sprintf("--cascade=%v", cascade), "--yes")
return a
}
func (a *Actions) DeleteBySelector(selector string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("app", "delete", "--selector="+selector, "--yes")
return a
}
func (a *Actions) DeleteBySelectorWithWait(selector string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("app", "delete", "--selector="+selector, "--yes", "--wait")
return a
}
func (a *Actions) Wait(args ...string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
args = append([]string{"app", "wait"}, args...)
if a.context.name != "" {
if a.context.GetName() != "" {
args = append(args, a.context.AppQualifiedName())
}
args = append(args, "--timeout", strconv.Itoa(a.context.timeout))
@@ -502,65 +504,111 @@ func (a *Actions) Wait(args ...string) *Actions {
}
func (a *Actions) SetParamInSettingConfigMap(key, value string) *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetParamInSettingConfigMap(key, value))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetParamInSettingConfigMap(key, value))
return a
}
func (a *Actions) And(block func()) *Actions {
a.context.t.Helper()
a.context.T().Helper()
block()
return a
}
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
a.context.T().Helper()
return &Consequences{a.context, a, 15}
}
func (a *Actions) runCli(args ...string) {
a.context.t.Helper()
a.context.T().Helper()
a.lastOutput, a.lastError = fixture.RunCli(args...)
a.verifyAction()
}
func (a *Actions) verifyAction() {
a.context.t.Helper()
a.context.T().Helper()
if !a.ignoreErrors {
a.Then().Expect(Success(""))
}
}
func (a *Actions) SetTrackingMethod(trackingMethod string) *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetTrackingMethod(trackingMethod))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetTrackingMethod(trackingMethod))
return a
}
func (a *Actions) SetInstallationID(installationID string) *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetInstallationID(installationID))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetInstallationID(installationID))
return a
}
func (a *Actions) SetTrackingLabel(trackingLabel string) *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetTrackingLabel(trackingLabel))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetTrackingLabel(trackingLabel))
return a
}
func (a *Actions) WithImpersonationEnabled(serviceAccountName string, policyRules []rbacv1.PolicyRule) *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetImpersonationEnabled("true"))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetImpersonationEnabled("true"))
if serviceAccountName == "" || policyRules == nil {
return a
}
require.NoError(a.context.t, fixture.CreateRBACResourcesForImpersonation(serviceAccountName, policyRules))
require.NoError(a.context.T(), createRBACResourcesForImpersonation(a.context.DeploymentNamespace(), serviceAccountName, policyRules))
return a
}
func (a *Actions) WithImpersonationDisabled() *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetImpersonationEnabled("false"))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetImpersonationEnabled("false"))
return a
}
// TODO: Ensure service account name and other resources have unique names based on the test context
// TODO: This function should be moved to the project context since impersonation is a project concept, not application.
func createRBACResourcesForImpersonation(namespace string, serviceAccountName string, policyRules []rbacv1.PolicyRule) error {
sa := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: serviceAccountName,
},
}
_, err := fixture.KubeClientset.CoreV1().ServiceAccounts(namespace).Create(context.Background(), sa, metav1.CreateOptions{})
if err != nil {
return err
}
role := &rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s", serviceAccountName, "role"),
},
Rules: policyRules,
}
_, err = fixture.KubeClientset.RbacV1().Roles(namespace).Create(context.Background(), role, metav1.CreateOptions{})
if err != nil {
return err
}
rolebinding := &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s", serviceAccountName, "rolebinding"),
},
RoleRef: rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "Role",
Name: fmt.Sprintf("%s-%s", serviceAccountName, "role"),
},
Subjects: []rbacv1.Subject{
{
Kind: "ServiceAccount",
Name: serviceAccountName,
Namespace: namespace,
},
},
}
_, err = fixture.KubeClientset.RbacV1().RoleBindings(namespace).Create(context.Background(), rolebinding, metav1.CreateOptions{})
if err != nil {
return err
}
return nil
}

View File

@@ -25,7 +25,7 @@ type Consequences struct {
func (c *Consequences) Expect(e Expectation) *Consequences {
// this invocation makes sure this func is not reported as the cause of the failure - we are a "test helper"
c.context.t.Helper()
c.context.T().Helper()
var message string
var state state
sleepIntervals := []time.Duration{
@@ -50,19 +50,19 @@ func (c *Consequences) Expect(e Expectation) *Consequences {
log.Infof("expectation succeeded: %s", message)
return c
case failed:
c.context.t.Fatalf("failed expectation: %s", message)
c.context.T().Fatalf("failed expectation: %s", message)
return c
}
log.Infof("pending: %s", message)
}
c.context.t.Fatal("timeout waiting for: " + message)
c.context.T().Fatal("timeout waiting for: " + message)
return c
}
// ExpectConsistently will continuously evaluate a condition, and it must be true each time it is evaluated, otherwise the test is failed. The condition will be repeatedly evaluated until 'expirationDuration' is met, waiting 'waitDuration' after each success.
func (c *Consequences) ExpectConsistently(e Expectation, waitDuration time.Duration, expirationDuration time.Duration) *Consequences {
// this invocation makes sure this func is not reported as the cause of the failure - we are a "test helper"
c.context.t.Helper()
c.context.T().Helper()
expiration := time.Now().Add(expirationDuration)
for time.Now().Before(expiration) {
@@ -71,7 +71,7 @@ func (c *Consequences) ExpectConsistently(e Expectation, waitDuration time.Durat
case succeeded:
log.Infof("expectation succeeded: %s", message)
case failed:
c.context.t.Fatalf("failed expectation: %s", message)
c.context.T().Fatalf("failed expectation: %s", message)
return c
}
@@ -85,13 +85,13 @@ func (c *Consequences) ExpectConsistently(e Expectation, waitDuration time.Durat
}
func (c *Consequences) And(block func(app *v1alpha1.Application)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.app())
return c
}
func (c *Consequences) AndAction(block func()) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block()
return c
}
@@ -106,9 +106,9 @@ func (c *Consequences) When() *Actions {
}
func (c *Consequences) app() *v1alpha1.Application {
c.context.t.Helper()
c.context.T().Helper()
app, err := c.get()
require.NoError(c.context.t, err)
require.NoError(c.context.T(), err)
return app
}
@@ -117,16 +117,16 @@ func (c *Consequences) get() (*v1alpha1.Application, error) {
}
func (c *Consequences) resource(kind, name, namespace string) v1alpha1.ResourceStatus {
c.context.t.Helper()
c.context.T().Helper()
closer, client, err := fixture.ArgoCDClientset.NewApplicationClient()
require.NoError(c.context.t, err)
require.NoError(c.context.T(), err)
defer utilio.Close(closer)
app, err := client.Get(context.Background(), &applicationpkg.ApplicationQuery{
Name: ptr.To(c.context.AppName()),
Projects: []string{c.context.project},
AppNamespace: ptr.To(c.context.appNamespace),
})
require.NoError(c.context.t, err)
require.NoError(c.context.T(), err)
for _, r := range app.Status.Resources {
if r.Kind == kind && r.Name == name && (namespace == "" || namespace == r.Namespace) {
return r
@@ -141,7 +141,7 @@ func (c *Consequences) resource(kind, name, namespace string) v1alpha1.ResourceS
}
func (c *Consequences) AndCLIOutput(block func(output string, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.actions.lastOutput, c.actions.lastError)
return c
}

View File

@@ -16,17 +16,18 @@ import (
"github.com/argoproj/argo-cd/v3/util/settings"
)
// Context implements the "given" part of given/when/then
// Context implements the "given" part of given/when/then.
// It embeds fixture.TestState to provide test-specific state that enables parallel test execution.
type Context struct {
t *testing.T
*fixture.TestState
path string
chart string
ociRegistry string
ociRegistryPath string
repoURLType fixture.RepoURLType
// seconds
timeout int
name string
timeout int
appNamespace string
destServer string
destName string
@@ -65,8 +66,8 @@ type ContextArgs struct {
func Given(t *testing.T, opts ...fixture.TestOption) *Context {
t.Helper()
fixture.EnsureCleanState(t, opts...)
return GivenWithSameState(t)
state := fixture.EnsureCleanState(t, opts...)
return GivenWithSameState(state)
}
func GivenWithNamespace(t *testing.T, namespace string) *Context {
@@ -76,17 +77,18 @@ func GivenWithNamespace(t *testing.T, namespace string) *Context {
return ctx
}
func GivenWithSameState(t *testing.T) *Context {
t.Helper()
// GivenWithSameState creates a new Context that shares the same TestState as an existing context.
// Use this when you need multiple fixture contexts within the same test.
func GivenWithSameState(ctx fixture.TestContext) *Context {
ctx.T().Helper()
// ARGOCD_E2E_DEFAULT_TIMEOUT can be used to override the default timeout
// for any context.
timeout := env.ParseNumFromEnv("ARGOCD_E2E_DEFAULT_TIMEOUT", 20, 0, 180)
return &Context{
t: t,
TestState: fixture.NewTestStateFromContext(ctx),
destServer: v1alpha1.KubernetesInternalAPIServerAddr,
destName: "in-cluster",
repoURLType: fixture.RepoURLTypeFile,
name: fixture.Name(),
timeout: timeout,
project: "default",
prune: true,
@@ -94,15 +96,16 @@ func GivenWithSameState(t *testing.T) *Context {
}
}
func (c *Context) Name(name string) *Context {
c.SetName(name)
return c
}
// AppName returns the unique application name for the test context.
// Unique application names protects from potential conflicts between test run
// caused by the tracking annotation on existing objects
func (c *Context) AppName() string {
suffix := "-" + fixture.ShortId()
if strings.HasSuffix(c.name, suffix) {
return c.name
}
return fixture.DnsFriendly(c.name, suffix)
return c.GetName()
}
func (c *Context) AppQualifiedName() string {
@@ -126,129 +129,134 @@ func (c *Context) SetAppNamespace(namespace string) *Context {
}
func (c *Context) GPGPublicKeyAdded() *Context {
gpgkeys.AddGPGPublicKey(c.t)
gpgkeys.AddGPGPublicKey(c.T())
return c
}
func (c *Context) GPGPublicKeyRemoved() *Context {
gpgkeys.DeleteGPGPublicKey(c.t)
gpgkeys.DeleteGPGPublicKey(c.T())
return c
}
func (c *Context) CustomCACertAdded() *Context {
certs.AddCustomCACert(c.t)
certs.AddCustomCACert(c.T())
return c
}
func (c *Context) CustomSSHKnownHostsAdded() *Context {
certs.AddCustomSSHKnownHostsKeys(c.t)
certs.AddCustomSSHKnownHostsKeys(c.T())
return c
}
func (c *Context) HTTPSRepoURLAdded(withCreds bool, opts ...repos.AddRepoOpts) *Context {
repos.AddHTTPSRepo(c.t, false, withCreds, "", fixture.RepoURLTypeHTTPS, opts...)
repos.AddHTTPSRepo(c.T(), false, withCreds, "", fixture.RepoURLTypeHTTPS, opts...)
return c
}
func (c *Context) HTTPSInsecureRepoURLAdded(withCreds bool, opts ...repos.AddRepoOpts) *Context {
repos.AddHTTPSRepo(c.t, true, withCreds, "", fixture.RepoURLTypeHTTPS, opts...)
repos.AddHTTPSRepo(c.T(), true, withCreds, "", fixture.RepoURLTypeHTTPS, opts...)
return c
}
func (c *Context) HTTPSInsecureRepoURLWithClientCertAdded() *Context {
repos.AddHTTPSRepoClientCert(c.t, true)
repos.AddHTTPSRepoClientCert(c.T(), true)
return c
}
func (c *Context) HTTPSRepoURLWithClientCertAdded() *Context {
repos.AddHTTPSRepoClientCert(c.t, false)
repos.AddHTTPSRepoClientCert(c.T(), false)
return c
}
func (c *Context) SubmoduleHTTPSRepoURLAdded(withCreds bool) *Context {
fixture.CreateSubmoduleRepos(c.t, "https")
repos.AddHTTPSRepo(c.t, false, withCreds, "", fixture.RepoURLTypeHTTPSSubmoduleParent)
fixture.CreateSubmoduleRepos(c.T(), "https")
repos.AddHTTPSRepo(c.T(), false, withCreds, "", fixture.RepoURLTypeHTTPSSubmoduleParent)
return c
}
func (c *Context) WriteCredentials(insecure bool) *Context {
repos.AddWriteCredentials(c.T(), c.GetName(), insecure, c.repoURLType)
return c
}
func (c *Context) SSHRepoURLAdded(withCreds bool) *Context {
repos.AddSSHRepo(c.t, false, withCreds, fixture.RepoURLTypeSSH)
repos.AddSSHRepo(c.T(), false, withCreds, fixture.RepoURLTypeSSH)
return c
}
func (c *Context) SSHInsecureRepoURLAdded(withCreds bool) *Context {
repos.AddSSHRepo(c.t, true, withCreds, fixture.RepoURLTypeSSH)
repos.AddSSHRepo(c.T(), true, withCreds, fixture.RepoURLTypeSSH)
return c
}
func (c *Context) SubmoduleSSHRepoURLAdded(withCreds bool) *Context {
fixture.CreateSubmoduleRepos(c.t, "ssh")
repos.AddSSHRepo(c.t, false, withCreds, fixture.RepoURLTypeSSHSubmoduleParent)
fixture.CreateSubmoduleRepos(c.T(), "ssh")
repos.AddSSHRepo(c.T(), false, withCreds, fixture.RepoURLTypeSSHSubmoduleParent)
return c
}
func (c *Context) HelmRepoAdded(name string) *Context {
repos.AddHelmRepo(c.t, name)
repos.AddHelmRepo(c.T(), name)
return c
}
func (c *Context) HelmOCIRepoAdded(name string) *Context {
repos.AddHelmOCIRepo(c.t, name)
repos.AddHelmOCIRepo(c.T(), name)
return c
}
func (c *Context) PushImageToOCIRegistry(pathName, tag string) *Context {
repos.PushImageToOCIRegistry(c.t, pathName, tag)
repos.PushImageToOCIRegistry(c.T(), pathName, tag)
return c
}
func (c *Context) PushImageToAuthenticatedOCIRegistry(pathName, tag string) *Context {
repos.PushImageToAuthenticatedOCIRegistry(c.t, pathName, tag)
repos.PushImageToAuthenticatedOCIRegistry(c.T(), pathName, tag)
return c
}
func (c *Context) PushChartToOCIRegistry(chartPathName, chartName, chartVersion string) *Context {
repos.PushChartToOCIRegistry(c.t, chartPathName, chartName, chartVersion)
repos.PushChartToOCIRegistry(c.T(), chartPathName, chartName, chartVersion)
return c
}
func (c *Context) PushChartToAuthenticatedOCIRegistry(chartPathName, chartName, chartVersion string) *Context {
repos.PushChartToAuthenticatedOCIRegistry(c.t, chartPathName, chartName, chartVersion)
repos.PushChartToAuthenticatedOCIRegistry(c.T(), chartPathName, chartName, chartVersion)
return c
}
func (c *Context) HTTPSCredentialsUserPassAdded() *Context {
repos.AddHTTPSCredentialsUserPass(c.t)
repos.AddHTTPSCredentialsUserPass(c.T())
return c
}
func (c *Context) HelmHTTPSCredentialsUserPassAdded() *Context {
repos.AddHelmHTTPSCredentialsTLSClientCert(c.t)
repos.AddHelmHTTPSCredentialsTLSClientCert(c.T())
return c
}
func (c *Context) HelmoOCICredentialsWithoutUserPassAdded() *Context {
repos.AddHelmoOCICredentialsWithoutUserPass(c.t)
repos.AddHelmoOCICredentialsWithoutUserPass(c.T())
return c
}
func (c *Context) HTTPSCredentialsTLSClientCertAdded() *Context {
repos.AddHTTPSCredentialsTLSClientCert(c.t)
repos.AddHTTPSCredentialsTLSClientCert(c.T())
return c
}
func (c *Context) SSHCredentialsAdded() *Context {
repos.AddSSHCredentials(c.t)
repos.AddSSHCredentials(c.T())
return c
}
func (c *Context) OCIRepoAdded(name, imagePath string) *Context {
repos.AddOCIRepo(c.t, name, imagePath)
repos.AddOCIRepo(c.T(), name, imagePath)
return c
}
func (c *Context) AuthenticatedOCIRepoAdded(name, imagePath string) *Context {
repos.AddAuthenticatedOCIRepo(c.t, name, imagePath)
repos.AddAuthenticatedOCIRepo(c.T(), name, imagePath)
return c
}
@@ -258,8 +266,8 @@ func (c *Context) OCIRegistry(registry string) *Context {
}
func (c *Context) ProjectSpec(spec v1alpha1.AppProjectSpec) *Context {
c.t.Helper()
require.NoError(c.t, fixture.SetProjectSpec(c.project, spec))
c.T().Helper()
require.NoError(c.T(), fixture.SetProjectSpec(c.project, spec))
return c
}
@@ -273,15 +281,6 @@ func (c *Context) RepoURLType(urlType fixture.RepoURLType) *Context {
return c
}
func (c *Context) GetName() string {
return c.name
}
func (c *Context) Name(name string) *Context {
c.name = name
return c
}
func (c *Context) Path(path string) *Context {
c.path = path
return c
@@ -344,6 +343,10 @@ func (c *Context) DestServer(destServer string) *Context {
}
func (c *Context) DestName(destName string) *Context {
if destName != "in-cluster" {
suffix := "-" + c.ShortID()
destName = fixture.DnsFriendly(strings.TrimSuffix(destName, suffix), suffix)
}
c.destName = destName
c.isDestServerInferred = true
return c
@@ -376,14 +379,14 @@ func (c *Context) NameSuffix(nameSuffix string) *Context {
}
func (c *Context) ResourceOverrides(overrides map[string]v1alpha1.ResourceOverride) *Context {
c.t.Helper()
require.NoError(c.t, fixture.SetResourceOverrides(overrides))
c.T().Helper()
require.NoError(c.T(), fixture.SetResourceOverrides(overrides))
return c
}
func (c *Context) ResourceFilter(filter settings.ResourcesFilter) *Context {
c.t.Helper()
require.NoError(c.t, fixture.SetResourceFilter(filter))
c.T().Helper()
require.NoError(c.T(), fixture.SetResourceFilter(filter))
return c
}
@@ -453,14 +456,14 @@ func (c *Context) HelmSkipTests() *Context {
}
func (c *Context) SetTrackingMethod(trackingMethod string) *Context {
c.t.Helper()
require.NoError(c.t, fixture.SetTrackingMethod(trackingMethod))
c.T().Helper()
require.NoError(c.T(), fixture.SetTrackingMethod(trackingMethod))
return c
}
func (c *Context) SetInstallationID(installationID string) *Context {
c.t.Helper()
require.NoError(c.t, fixture.SetInstallationID(installationID))
c.T().Helper()
require.NoError(c.T(), fixture.SetInstallationID(installationID))
return c
}
@@ -474,7 +477,7 @@ func (c *Context) Sources(sources []v1alpha1.ApplicationSource) *Context {
}
func (c *Context) RegisterKustomizeVersion(version, path string) *Context {
c.t.Helper()
require.NoError(c.t, fixture.RegisterKustomizeVersion(version, path))
c.T().Helper()
require.NoError(c.T(), fixture.RegisterKustomizeVersion(version, path))
return c
}

View File

@@ -16,9 +16,9 @@ import (
// RunningCMPServer starts a CMP server with the given config directory and waits for it to be ready.
// It blocks until the CMP socket is created or times out after 10 seconds.
func (c *Context) RunningCMPServer(configFile string) *Context {
c.t.Helper()
startCMPServer(c.t, configFile)
c.t.Setenv("ARGOCD_BINARY_NAME", "argocd")
c.T().Helper()
startCMPServer(c.T(), configFile)
c.T().Setenv("ARGOCD_BINARY_NAME", "argocd")
return c
}

View File

@@ -283,8 +283,8 @@ func App(predicate func(app *v1alpha1.Application) bool) Expectation {
}
func Pod(predicate func(p corev1.Pod) bool) Expectation {
return func(_ *Consequences) (state, string) {
pods, err := pods()
return func(c *Consequences) (state, string) {
pods, err := pods(c.context.DeploymentNamespace())
if err != nil {
return failed, err.Error()
}
@@ -298,8 +298,8 @@ func Pod(predicate func(p corev1.Pod) bool) Expectation {
}
func NotPod(predicate func(p corev1.Pod) bool) Expectation {
return func(_ *Consequences) (state, string) {
pods, err := pods()
return func(c *Consequences) (state, string) {
pods, err := pods(c.context.DeploymentNamespace())
if err != nil {
return failed, err.Error()
}
@@ -312,9 +312,8 @@ func NotPod(predicate func(p corev1.Pod) bool) Expectation {
}
}
func pods() (*corev1.PodList, error) {
fixture.KubeClientset.CoreV1()
pods, err := fixture.KubeClientset.CoreV1().Pods(fixture.DeploymentNamespace()).List(context.Background(), metav1.ListOptions{})
func pods(namespace string) (*corev1.PodList, error) {
pods, err := fixture.KubeClientset.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{})
return pods, err
}
@@ -330,7 +329,6 @@ func NoNamespace(name string) Expectation {
}
func namespace(name string) (*corev1.Namespace, error) {
fixture.KubeClientset.CoreV1()
return fixture.KubeClientset.CoreV1().Namespaces().Get(context.Background(), name, metav1.GetOptions{})
}

View File

@@ -54,13 +54,13 @@ func (a *Actions) DoNotIgnoreErrors() *Actions {
}
func (a *Actions) And(block func()) *Actions {
a.context.t.Helper()
a.context.T().Helper()
block()
return a
}
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
a.context.T().Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}
@@ -80,8 +80,8 @@ func (a *Actions) SwitchToArgoCDNamespace() *Actions {
// CreateClusterSecret creates a faux cluster secret, with the given cluster server and cluster name (this cluster
// will not actually be used by the Argo CD controller, but that's not needed for our E2E tests)
func (a *Actions) CreateClusterSecret(secretName string, clusterName string, clusterServer string) *Actions {
a.context.t.Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t)
a.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T())
var serviceAccountName string
@@ -154,8 +154,8 @@ func (a *Actions) CreateClusterSecret(secretName string, clusterName string, clu
// DeleteClusterSecret deletes a faux cluster secret
func (a *Actions) DeleteClusterSecret(secretName string) *Actions {
a.context.t.Helper()
err := utils.GetE2EFixtureK8sClient(a.context.t).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{})
a.context.T().Helper()
err := utils.GetE2EFixtureK8sClient(a.context.T()).KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{})
a.describeAction = fmt.Sprintf("deleting cluster Secret '%s'", secretName)
a.lastOutput, a.lastError = "", err
@@ -166,8 +166,8 @@ func (a *Actions) DeleteClusterSecret(secretName string) *Actions {
// DeleteConfigMap deletes a faux cluster secret
func (a *Actions) DeleteConfigMap(configMapName string) *Actions {
a.context.t.Helper()
err := utils.GetE2EFixtureK8sClient(a.context.t).KubeClientset.CoreV1().ConfigMaps(fixture.TestNamespace()).Delete(context.Background(), configMapName, metav1.DeleteOptions{})
a.context.T().Helper()
err := utils.GetE2EFixtureK8sClient(a.context.T()).KubeClientset.CoreV1().ConfigMaps(fixture.TestNamespace()).Delete(context.Background(), configMapName, metav1.DeleteOptions{})
a.describeAction = fmt.Sprintf("deleting configMap '%s'", configMapName)
a.lastOutput, a.lastError = "", err
@@ -178,8 +178,8 @@ func (a *Actions) DeleteConfigMap(configMapName string) *Actions {
// DeletePlacementDecision deletes a faux cluster secret
func (a *Actions) DeletePlacementDecision(placementDecisionName string) *Actions {
a.context.t.Helper()
err := utils.GetE2EFixtureK8sClient(a.context.t).DynamicClientset.Resource(pdGVR).Namespace(fixture.TestNamespace()).Delete(context.Background(), placementDecisionName, metav1.DeleteOptions{})
a.context.T().Helper()
err := utils.GetE2EFixtureK8sClient(a.context.T()).DynamicClientset.Resource(pdGVR).Namespace(fixture.TestNamespace()).Delete(context.Background(), placementDecisionName, metav1.DeleteOptions{})
a.describeAction = fmt.Sprintf("deleting placement decision '%s'", placementDecisionName)
a.lastOutput, a.lastError = "", err
@@ -191,9 +191,9 @@ func (a *Actions) DeletePlacementDecision(placementDecisionName string) *Actions
// Create a temporary namespace, from utils.ApplicationSet, for use by the test.
// This namespace will be deleted on subsequent tests.
func (a *Actions) CreateNamespace(namespace string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t)
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T())
_, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Create(context.Background(),
&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, metav1.CreateOptions{})
@@ -207,9 +207,9 @@ func (a *Actions) CreateNamespace(namespace string) *Actions {
// Create creates an ApplicationSet using the provided value
func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions {
a.context.t.Helper()
a.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t)
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T())
appSet.APIVersion = "argoproj.io/v1alpha1"
appSet.Kind = "ApplicationSet"
@@ -227,10 +227,12 @@ func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions {
appSetClientSet = fixtureClient.AppSetClientset
}
// AppSet name is not configurable and should always be unique, based on the context name
appSet.Name = a.context.GetName()
newResource, err := appSetClientSet.Create(context.Background(), utils.MustToUnstructured(&appSet), metav1.CreateOptions{})
if err == nil {
a.context.name = newResource.GetName()
a.context.namespace = newResource.GetNamespace()
}
@@ -243,8 +245,8 @@ func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions {
// Create Role/RoleBinding to allow ApplicationSet to list the PlacementDecisions
func (a *Actions) CreatePlacementRoleAndRoleBinding() *Actions {
a.context.t.Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t)
a.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T())
var err error
@@ -293,9 +295,9 @@ func (a *Actions) CreatePlacementRoleAndRoleBinding() *Actions {
// Create a ConfigMap for the ClusterResourceList generator
func (a *Actions) CreatePlacementDecisionConfigMap(configMapName string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t)
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T())
_, err := fixtureClient.KubeClientset.CoreV1().ConfigMaps(fixture.TestNamespace()).Get(context.Background(), configMapName, metav1.GetOptions{})
@@ -325,9 +327,9 @@ func (a *Actions) CreatePlacementDecisionConfigMap(configMapName string) *Action
}
func (a *Actions) CreatePlacementDecision(placementDecisionName string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t).DynamicClientset
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T()).DynamicClientset
_, err := fixtureClient.Resource(pdGVR).Namespace(fixture.TestNamespace()).Get(
context.Background(),
@@ -363,9 +365,9 @@ func (a *Actions) CreatePlacementDecision(placementDecisionName string) *Actions
}
func (a *Actions) StatusUpdatePlacementDecision(placementDecisionName string, clusterList []any) *Actions {
a.context.t.Helper()
a.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t).DynamicClientset
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T()).DynamicClientset
placementDecision, err := fixtureClient.Resource(pdGVR).Namespace(fixture.TestNamespace()).Get(
context.Background(),
placementDecisionName,
@@ -390,9 +392,9 @@ func (a *Actions) StatusUpdatePlacementDecision(placementDecisionName string, cl
// Delete deletes the ApplicationSet within the context
func (a *Actions) Delete() *Actions {
a.context.t.Helper()
a.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t)
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T())
var appSetClientSet dynamic.ResourceInterface
@@ -408,8 +410,8 @@ func (a *Actions) Delete() *Actions {
}
deleteProp := metav1.DeletePropagationForeground
err := appSetClientSet.Delete(context.Background(), a.context.name, metav1.DeleteOptions{PropagationPolicy: &deleteProp})
a.describeAction = fmt.Sprintf("Deleting ApplicationSet '%s/%s' %v", a.context.namespace, a.context.name, err)
err := appSetClientSet.Delete(context.Background(), a.context.GetName(), metav1.DeleteOptions{PropagationPolicy: &deleteProp})
a.describeAction = fmt.Sprintf("Deleting ApplicationSet '%s/%s' %v", a.context.namespace, a.context.GetName(), err)
a.lastOutput, a.lastError = "", err
a.verifyAction()
@@ -420,7 +422,7 @@ func (a *Actions) Delete() *Actions {
func (a *Actions) get() (*v1alpha1.ApplicationSet, error) {
appSet := v1alpha1.ApplicationSet{}
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t)
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T())
var appSetClientSet dynamic.ResourceInterface
@@ -434,7 +436,7 @@ func (a *Actions) get() (*v1alpha1.ApplicationSet, error) {
appSetClientSet = fixtureClient.AppSetClientset
}
newResource, err := appSetClientSet.Get(context.Background(), a.context.name, metav1.GetOptions{})
newResource, err := appSetClientSet.Get(context.Background(), a.context.GetName(), metav1.GetOptions{})
if err != nil {
return nil, err
}
@@ -455,7 +457,7 @@ func (a *Actions) get() (*v1alpha1.ApplicationSet, error) {
// Update retrieves the latest copy the ApplicationSet, then allows the caller to mutate it via 'toUpdate', with
// the result applied back to the cluster resource
func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions {
a.context.t.Helper()
a.context.T().Helper()
timeout := 30 * time.Second
@@ -483,7 +485,7 @@ func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions {
toUpdate(appSet)
a.describeAction = fmt.Sprintf("updating ApplicationSet '%s/%s'", appSet.Namespace, appSet.Name)
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.t)
fixtureClient := utils.GetE2EFixtureK8sClient(a.context.T())
var appSetClientSet dynamic.ResourceInterface
@@ -515,7 +517,7 @@ func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions {
}
func (a *Actions) verifyAction() {
a.context.t.Helper()
a.context.T().Helper()
if a.describeAction != "" {
log.Infof("action: %s", a.describeAction)
@@ -528,7 +530,7 @@ func (a *Actions) verifyAction() {
}
func (a *Actions) AppSet(appName string, flags ...string) *Actions {
a.context.t.Helper()
a.context.T().Helper()
args := []string{"app", "set", appName}
args = append(args, flags...)
a.runCli(args...)
@@ -536,13 +538,13 @@ func (a *Actions) AppSet(appName string, flags ...string) *Actions {
}
func (a *Actions) runCli(args ...string) {
a.context.t.Helper()
a.context.T().Helper()
a.lastOutput, a.lastError = fixture.RunCli(args...)
a.verifyAction()
}
func (a *Actions) AddSignedFile(fileName, fileContents string) *Actions {
a.context.t.Helper()
fixture.AddSignedFile(a.context.t, a.context.path+"/"+fileName, fileContents)
a.context.T().Helper()
fixture.AddSignedFile(a.context.T(), a.context.path+"/"+fileName, fileContents)
return a
}

View File

@@ -27,7 +27,7 @@ func (c *Consequences) Expect(e Expectation) *Consequences {
func (c *Consequences) ExpectWithDuration(e Expectation, timeout time.Duration) *Consequences {
// this invocation makes sure this func is not reported as the cause of the failure - we are a "test helper"
c.context.t.Helper()
c.context.T().Helper()
var message string
var state state
sleepIntervals := []time.Duration{
@@ -51,17 +51,17 @@ func (c *Consequences) ExpectWithDuration(e Expectation, timeout time.Duration)
log.Infof("expectation succeeded: %s", message)
return c
case failed:
c.context.t.Fatalf("failed expectation: %s", message)
c.context.T().Fatalf("failed expectation: %s", message)
return c
}
log.Infof("expectation pending: %s", message)
}
c.context.t.Fatal("timeout waiting for: " + message)
c.context.T().Fatal("timeout waiting for: " + message)
return c
}
func (c *Consequences) And(block func()) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block()
return c
}
@@ -88,7 +88,7 @@ func (c *Consequences) app(name string) *v1alpha1.Application {
}
func (c *Consequences) apps() []v1alpha1.Application {
c.context.t.Helper()
c.context.T().Helper()
var namespace string
if c.context.switchToNamespace != "" {
namespace = string(c.context.switchToNamespace)
@@ -96,7 +96,7 @@ func (c *Consequences) apps() []v1alpha1.Application {
namespace = fixture.TestNamespace()
}
fixtureClient := utils.GetE2EFixtureK8sClient(c.context.t)
fixtureClient := utils.GetE2EFixtureK8sClient(c.context.T())
list, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(namespace).List(context.Background(), metav1.ListOptions{})
errors.CheckError(err)
@@ -108,8 +108,8 @@ func (c *Consequences) apps() []v1alpha1.Application {
}
func (c *Consequences) applicationSet(applicationSetName string) *v1alpha1.ApplicationSet {
c.context.t.Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(c.context.t)
c.context.T().Helper()
fixtureClient := utils.GetE2EFixtureK8sClient(c.context.T())
var appSetClientSet dynamic.ResourceInterface
@@ -119,7 +119,7 @@ func (c *Consequences) applicationSet(applicationSetName string) *v1alpha1.Appli
appSetClientSet = fixtureClient.AppSetClientset
}
list, err := appSetClientSet.Get(context.Background(), c.actions.context.name, metav1.GetOptions{})
list, err := appSetClientSet.Get(context.Background(), applicationSetName, metav1.GetOptions{})
errors.CheckError(err)
var appSet v1alpha1.ApplicationSet

View File

@@ -12,10 +12,8 @@ import (
// Context implements the "given" part of given/when/then
type Context struct {
t *testing.T
*fixture.TestState
// name is the ApplicationSet's name, created by a Create action
name string
namespace string
switchToNamespace utils.ExternalNamespace
path string
@@ -24,11 +22,12 @@ type Context struct {
func Given(t *testing.T) *Context {
t.Helper()
fixture.EnsureCleanState(t)
state := fixture.EnsureCleanState(t)
// TODO: Appset EnsureCleanState specific logic should be moved to the main EnsureCleanState function (https://github.com/argoproj/argo-cd/issues/24307)
utils.EnsureCleanState(t)
return &Context{t: t}
return &Context{TestState: state}
}
func (c *Context) When() *Actions {
@@ -52,11 +51,11 @@ func (c *Context) Path(path string) *Context {
}
func (c *Context) GPGPublicKeyAdded() *Context {
gpgkeys.AddGPGPublicKey(c.t)
gpgkeys.AddGPGPublicKey(c.T())
return c
}
func (c *Context) HTTPSInsecureRepoURLAdded(project string) *Context {
repos.AddHTTPSRepo(c.t, true, true, project, fixture.RepoURLTypeHTTPS)
repos.AddHTTPSRepo(c.T(), true, true, project, fixture.RepoURLTypeHTTPS)
return c
}

View File

@@ -81,12 +81,12 @@ func ApplicationsExist(expectedApps []v1alpha1.Application) Expectation {
// ApplicationSetHasConditions checks whether each of the 'expectedConditions' exist in the ApplicationSet status, and are
// equivalent to provided values.
func ApplicationSetHasConditions(applicationSetName string, expectedConditions []v1alpha1.ApplicationSetCondition) Expectation {
func ApplicationSetHasConditions(expectedConditions []v1alpha1.ApplicationSetCondition) Expectation {
return func(c *Consequences) (state, string) {
// retrieve the application set
foundApplicationSet := c.applicationSet(applicationSetName)
foundApplicationSet := c.applicationSet(c.context.GetName())
if foundApplicationSet == nil {
return pending, fmt.Sprintf("application set '%s' not found", applicationSetName)
return pending, fmt.Sprintf("application set '%s' not found", c.context.GetName())
}
if !conditionsAreEqual(&expectedConditions, &foundApplicationSet.Status.Conditions) {

View File

@@ -4,11 +4,13 @@ import (
"context"
"errors"
"log"
"os"
"strings"
"time"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"github.com/argoproj/argo-cd/v3/common"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
@@ -45,7 +47,7 @@ func (a *Actions) Create() *Actions {
_, err := clusterClient.Create(context.Background(), &clusterpkg.ClusterCreateRequest{
Cluster: &v1alpha1.Cluster{
Server: a.context.server,
Name: a.context.name,
Name: a.context.GetName(),
Config: v1alpha1.ClusterConfig{BearerToken: a.context.bearerToken},
Namespaces: a.context.namespaces,
RefreshRequestedAt: nil,
@@ -87,54 +89,106 @@ func (a *Actions) CreateWithRBAC() *Actions {
return a
}
// Create a kubeconfig with the current cluster name
err = a.createKubeconfigForCluster(config, a.context.GetName())
if err != nil {
a.lastError = err
return a
}
return a.Create()
}
// Helper function to create a kubeconfig file with the given cluster name
func (a *Actions) createKubeconfigForCluster(config *clientcmdapi.Config, newClusterName string) error {
// Get the current context
currentContext := config.Contexts[config.CurrentContext]
if currentContext == nil {
return errors.New("no current context found")
}
// Get the original cluster
originalCluster := config.Clusters[currentContext.Cluster]
if originalCluster == nil {
return errors.New("cluster not found in config")
}
// Create a new cluster entry with the same config but different name
newCluster := originalCluster.DeepCopy()
config.Clusters[newClusterName] = newCluster
// Create a new context pointing to the new cluster
newContext := currentContext.DeepCopy()
newContext.Cluster = newClusterName
config.Contexts[newClusterName] = newContext
// Set the new context as current
config.CurrentContext = newClusterName
// Write to a temporary kubeconfig file
tmpFile, err := os.CreateTemp("", "kubeconfig-*.yaml")
if err != nil {
return err
}
defer tmpFile.Close()
// Write the modified config to the temp file
if err := clientcmd.WriteToFile(*config, tmpFile.Name()); err != nil {
return err
}
// Set the KUBECONFIG environment variable to use this temp file
// This will be use by subsequent kubectl/argocd commands to connect to the cluster
a.context.T().Setenv("KUBECONFIG", tmpFile.Name())
return nil
}
func (a *Actions) List() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("cluster", "list")
return a
}
func (a *Actions) Get() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("cluster", "get", a.context.server)
return a
}
func (a *Actions) GetByName(name string) *Actions {
a.context.t.Helper()
a.runCli("cluster", "get", name)
func (a *Actions) GetByName() *Actions {
a.context.T().Helper()
a.runCli("cluster", "get", a.context.GetName())
return a
}
func (a *Actions) SetNamespaces() *Actions {
a.context.t.Helper()
a.runCli("cluster", "set", a.context.name, "--namespace", strings.Join(a.context.namespaces, ","))
a.context.T().Helper()
a.runCli("cluster", "set", a.context.GetName(), "--namespace", strings.Join(a.context.namespaces, ","))
return a
}
func (a *Actions) DeleteByName() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("cluster", "rm", a.context.name, "--yes")
a.runCli("cluster", "rm", a.context.GetName(), "--yes")
return a
}
func (a *Actions) DeleteByServer() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("cluster", "rm", a.context.server, "--yes")
return a
}
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
a.context.T().Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}
func (a *Actions) runCli(args ...string) {
a.context.t.Helper()
a.context.T().Helper()
a.lastOutput, a.lastError = fixture.RunCli(args...)
}

View File

@@ -21,13 +21,13 @@ func (c *Consequences) Expect() *Consequences {
}
func (c *Consequences) And(block func(cluster *v1alpha1.Cluster, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.cluster())
return c
}
func (c *Consequences) AndCLIOutput(block func(output string, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.actions.lastOutput, c.actions.lastError)
return c
}

View File

@@ -7,10 +7,11 @@ import (
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
// this implements the "given" part of given/when/then
// Context implements the "given" part of given/when/then.
// It embeds fixture.TestState to provide test-specific state that enables parallel test execution.
type Context struct {
t *testing.T
name string
*fixture.TestState
project string
server string
upsert bool
@@ -20,21 +21,19 @@ type Context struct {
func Given(t *testing.T) *Context {
t.Helper()
fixture.EnsureCleanState(t)
return GivenWithSameState(t)
state := fixture.EnsureCleanState(t)
return GivenWithSameState(state)
}
func GivenWithSameState(t *testing.T) *Context {
t.Helper()
return &Context{t: t, name: fixture.Name(), project: "default"}
}
func (c *Context) GetName() string {
return c.name
// GivenWithSameState creates a new Context that shares the same TestState as an existing context.
// Use this when you need multiple fixture contexts within the same test.
func GivenWithSameState(ctx fixture.TestContext) *Context {
ctx.T().Helper()
return &Context{TestState: fixture.NewTestStateFromContext(ctx), project: "default"}
}
func (c *Context) Name(name string) *Context {
c.name = name
c.SetName(name)
return c
}

119
test/e2e/fixture/context.go Normal file
View File

@@ -0,0 +1,119 @@
package fixture
import (
"fmt"
"strings"
"testing"
"github.com/argoproj/argo-cd/v3/util/rand"
"github.com/argoproj/argo-cd/v3/util/errors"
)
// TestContext defines the interface for test-specific state that enables parallel test execution.
// All fixture Context types should implement this interface by embedding TestState.
type TestContext interface {
// SetName sets the DNS-friendly name for this context
SetName(name string)
// GetName returns the DNS-friendly name for this context
GetName() string
// DeploymentNamespace returns the namespace where test resources are deployed
DeploymentNamespace() string
// ID returns the unique identifier for this test run
ID() string
// ShortID returns the short unique identifier suffix for this test run
ShortID() string
// Token returns the authentication token for API calls
Token() string
// SetToken sets the authentication token
SetToken(token string)
// T returns the testing.T instance for this test
T() *testing.T
}
// TestState holds test-specific variables that were previously global.
// Embed this in Context structs to enable parallel test execution.
type TestState struct {
t *testing.T
id string
shortId string
name string
deploymentNamespace string
token string
}
// NewTestState creates a new TestState with unique identifiers for this test run.
// This generates fresh id, name, and deploymentNamespace values.
func NewTestState(t *testing.T) *TestState {
t.Helper()
randString, err := rand.String(5)
errors.CheckError(err)
shortId := strings.ToLower(randString)
return &TestState{
t: t,
token: token, // Initialize with current global token
id: fmt.Sprintf("%s-%s", t.Name(), shortId),
shortId: shortId,
name: DnsFriendly(t.Name(), "-"+shortId),
deploymentNamespace: DnsFriendly("argocd-e2e-"+t.Name(), "-"+shortId),
}
}
// NewTestStateFromContext creates a TestState from an existing TestContext.
// This allows GivenWithSameState functions to work across different Context types.
func NewTestStateFromContext(ctx TestContext) *TestState {
return &TestState{
t: ctx.T(),
id: ctx.ID(),
shortId: ctx.ShortID(),
name: ctx.GetName(),
deploymentNamespace: ctx.DeploymentNamespace(),
token: ctx.Token(),
}
}
// Name sets the DNS-friendly name for this context
func (s *TestState) SetName(name string) {
if name == "" {
s.name = ""
return
}
suffix := "-" + s.shortId
s.name = DnsFriendly(strings.TrimSuffix(name, suffix), suffix)
}
// GetName returns the DNS-friendly name for this context
func (s *TestState) GetName() string {
return s.name
}
// DeploymentNamespace returns the namespace where test resources are deployed
func (s *TestState) DeploymentNamespace() string {
return s.deploymentNamespace
}
// ID returns the unique identifier for this test run
func (s *TestState) ID() string {
return s.id
}
// ShortID returns the short unique identifier suffix for this test run
func (s *TestState) ShortID() string {
return s.shortId
}
// Token returns the authentication token for API calls
func (s *TestState) Token() string {
return s.token
}
// SetToken sets the authentication token
func (s *TestState) SetToken(token string) {
s.token = token
}
// T returns the testing.T instance for this test
func (s *TestState) T() *testing.T {
return s.t
}

View File

@@ -16,7 +16,6 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
jsonpatch "github.com/evanphx/json-patch"
log "github.com/sirupsen/logrus"
@@ -39,7 +38,6 @@ import (
"github.com/argoproj/argo-cd/v3/util/errors"
grpcutil "github.com/argoproj/argo-cd/v3/util/grpc"
utilio "github.com/argoproj/argo-cd/v3/util/io"
"github.com/argoproj/argo-cd/v3/util/rand"
"github.com/argoproj/argo-cd/v3/util/settings"
)
@@ -69,8 +67,6 @@ const (
// cmp plugin sock file path
PluginSockFilePath = "/app/config/plugin"
E2ETestPrefix = "e2e-test-"
// finalizer to add to resources during tests. Make sure that the resource Kind of your object
// is included in the test EnsureCleanState code
TestFinalizer = TestingLabel + "/finalizer"
@@ -90,10 +86,6 @@ const (
)
var (
id string
shortId string
deploymentNamespace string
name string
KubeClientset kubernetes.Interface
KubeConfig *rest.Config
DynamicClientset dynamic.Interface
@@ -305,14 +297,6 @@ func LoginAs(username string) error {
return loginAs(username, password)
}
func Name() string {
return name
}
func ShortId() string {
return shortId
}
func repoDirectory() string {
return path.Join(TmpDir(), repoDir)
}
@@ -384,10 +368,6 @@ func RepoBaseURL(urlType RepoURLType) string {
return path.Base(RepoURL(urlType))
}
func DeploymentNamespace() string {
return deploymentNamespace
}
// Convenience wrapper for updating argocd-cm
func updateSettingConfigMap(updater func(cm *corev1.ConfigMap) error) error {
return updateGenericConfigMap(common.ArgoCDConfigMapName, updater)
@@ -499,50 +479,6 @@ func SetImpersonationEnabled(impersonationEnabledFlag string) error {
})
}
func CreateRBACResourcesForImpersonation(serviceAccountName string, policyRules []rbacv1.PolicyRule) error {
sa := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: serviceAccountName,
},
}
_, err := KubeClientset.CoreV1().ServiceAccounts(DeploymentNamespace()).Create(context.Background(), sa, metav1.CreateOptions{})
if err != nil {
return err
}
role := &rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s", serviceAccountName, "role"),
},
Rules: policyRules,
}
_, err = KubeClientset.RbacV1().Roles(DeploymentNamespace()).Create(context.Background(), role, metav1.CreateOptions{})
if err != nil {
return err
}
rolebinding := &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s", serviceAccountName, "rolebinding"),
},
RoleRef: rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "Role",
Name: fmt.Sprintf("%s-%s", serviceAccountName, "role"),
},
Subjects: []rbacv1.Subject{
{
Kind: "ServiceAccount",
Name: serviceAccountName,
Namespace: DeploymentNamespace(),
},
},
}
_, err = KubeClientset.RbacV1().RoleBindings(DeploymentNamespace()).Create(context.Background(), rolebinding, metav1.CreateOptions{})
if err != nil {
return err
}
return nil
}
func SetResourceOverridesSplitKeys(overrides map[string]v1alpha1.ResourceOverride) error {
return updateSettingConfigMap(func(cm *corev1.ConfigMap) error {
for k, v := range overrides {
@@ -669,7 +605,7 @@ func WithTestData(testdata string) TestOption {
}
}
func EnsureCleanState(t *testing.T, opts ...TestOption) {
func EnsureCleanState(t *testing.T, opts ...TestOption) *TestState {
t.Helper()
opt := newTestOption(opts...)
// In large scenarios, we can skip tests that already run
@@ -679,6 +615,9 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
RecordTestRun(t)
})
// Create TestState to hold test-specific variables
state := NewTestState(t)
start := time.Now()
policy := metav1.DeletePropagationBackground
@@ -757,6 +696,20 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
metav1.DeleteOptions{PropagationPolicy: &policy},
metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepoCreds})
},
func() error {
// kubectl delete secrets -l argocd.argoproj.io/secret-type=repository-write
return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(
t.Context(),
metav1.DeleteOptions{PropagationPolicy: &policy},
metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepositoryWrite})
},
func() error {
// kubectl delete secrets -l argocd.argoproj.io/secret-type=repo-write-creds
return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(
t.Context(),
metav1.DeleteOptions{PropagationPolicy: &policy},
metav1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepoCredsWrite})
},
func() error {
// kubectl delete secrets -l argocd.argoproj.io/secret-type=cluster
return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(
@@ -771,8 +724,21 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
metav1.DeleteOptions{PropagationPolicy: &policy},
metav1.ListOptions{LabelSelector: TestingLabel + "=true"})
},
func() error {
// kubectl delete clusterroles -l e2e.argoproj.io=true
return KubeClientset.RbacV1().ClusterRoles().DeleteCollection(
t.Context(),
metav1.DeleteOptions{PropagationPolicy: &policy},
metav1.ListOptions{LabelSelector: TestingLabel + "=true"})
},
func() error {
// kubectl delete clusterrolebindings -l e2e.argoproj.io=true
return KubeClientset.RbacV1().ClusterRoleBindings().DeleteCollection(
t.Context(),
metav1.DeleteOptions{PropagationPolicy: &policy},
metav1.ListOptions{LabelSelector: TestingLabel + "=true"})
},
})
RunFunctionsInParallelAndCheckErrors(t, []func() error{
func() error {
// delete old namespaces which were created by tests
@@ -811,23 +777,6 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
return err
}
}
namespaces, err = KubeClientset.CoreV1().Namespaces().List(t.Context(), metav1.ListOptions{})
if err != nil {
return err
}
testNamespaceNames := []corev1.Namespace{}
for _, namespace := range namespaces.Items {
if strings.HasPrefix(namespace.Name, E2ETestPrefix) {
testNamespaceNames = append(testNamespaceNames, namespace)
}
}
if len(testNamespaceNames) > 0 {
err = deleteNamespaces(testNamespaceNames, true)
if err != nil {
return err
}
}
return nil
},
func() error {
@@ -835,70 +784,6 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
_, err := Run("", "kubectl", "delete", "crd", "-l", TestingLabel+"=true", "--wait=false")
return err
},
func() error {
// delete old ClusterRoles which were created by tests
clusterRoles, err := KubeClientset.RbacV1().ClusterRoles().List(
t.Context(),
metav1.ListOptions{
LabelSelector: fmt.Sprintf("%s=%s", TestingLabel, "true"),
},
)
if err != nil {
return err
}
if len(clusterRoles.Items) > 0 {
args := []string{"delete", "clusterrole", "--wait=false"}
for _, clusterRole := range clusterRoles.Items {
args = append(args, clusterRole.Name)
}
_, err := Run("", "kubectl", args...)
if err != nil {
return err
}
}
clusterRoles, err = KubeClientset.RbacV1().ClusterRoles().List(t.Context(), metav1.ListOptions{})
if err != nil {
return err
}
testClusterRoleNames := []string{}
for _, clusterRole := range clusterRoles.Items {
if strings.HasPrefix(clusterRole.Name, E2ETestPrefix) {
testClusterRoleNames = append(testClusterRoleNames, clusterRole.Name)
}
}
if len(testClusterRoleNames) > 0 {
args := []string{"delete", "clusterrole"}
args = append(args, testClusterRoleNames...)
_, err := Run("", "kubectl", args...)
if err != nil {
return err
}
}
return nil
},
func() error {
// delete old ClusterRoleBindings which were created by tests
clusterRoleBindings, err := KubeClientset.RbacV1().ClusterRoleBindings().List(t.Context(), metav1.ListOptions{})
if err != nil {
return err
}
testClusterRoleBindingNames := []string{}
for _, clusterRoleBinding := range clusterRoleBindings.Items {
if strings.HasPrefix(clusterRoleBinding.Name, E2ETestPrefix) {
testClusterRoleBindingNames = append(testClusterRoleBindingNames, clusterRoleBinding.Name)
}
}
if len(testClusterRoleBindingNames) > 0 {
args := []string{"delete", "clusterrolebinding"}
args = append(args, testClusterRoleBindingNames...)
_, err := Run("", "kubectl", args...)
if err != nil {
return err
}
}
return nil
},
func() error {
err := updateSettingConfigMap(func(cm *corev1.ConfigMap) error {
cm.Data = map[string]string{}
@@ -1072,22 +957,12 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
return nil
},
func() error {
// random id - unique across test runs
randString, err := rand.String(5)
// create namespace for this test
_, err := Run("", "kubectl", "create", "ns", state.deploymentNamespace)
if err != nil {
return err
}
shortId = strings.ToLower(randString)
id = fmt.Sprintf("%s-%s", t.Name(), shortId)
name = DnsFriendly(t.Name(), "-"+shortId)
deploymentNamespace = DnsFriendly("argocd-e2e-"+t.Name(), "-"+shortId)
// create namespace
_, err = Run("", "kubectl", "create", "ns", DeploymentNamespace())
if err != nil {
return err
}
_, err = Run("", "kubectl", "label", "ns", DeploymentNamespace(), TestingLabel+"=true")
_, err = Run("", "kubectl", "label", "ns", state.deploymentNamespace, TestingLabel+"=true")
return err
},
})
@@ -1095,10 +970,12 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) {
log.WithFields(log.Fields{
"duration": time.Since(start),
"name": t.Name(),
"id": id,
"id": state.id,
"username": "admin",
"password": "password",
}).Info("clean state")
return state
}
// RunCliWithRetry executes an Argo CD CLI command with retry logic.

View File

@@ -19,19 +19,19 @@ type Actions struct {
}
func (a *Actions) SetParamInNotificationConfigMap(key, value string) *Actions {
a.context.t.Helper()
require.NoError(a.context.t, fixture.SetParamInNotificationsConfigMap(key, value))
a.context.T().Helper()
require.NoError(a.context.T(), fixture.SetParamInNotificationsConfigMap(key, value))
return a
}
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
a.context.T().Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}
func (a *Actions) Healthcheck() *Actions {
a.context.t.Helper()
a.context.T().Helper()
_, err := fixture.DoHttpRequest("GET",
"/metrics",
fixture.GetNotificationServerAddress())

View File

@@ -15,25 +15,25 @@ type Consequences struct {
}
func (c *Consequences) Services(block func(services *notification.ServiceList, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.listServices())
return c
}
func (c *Consequences) Healthy(block func(healthy bool)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.actions.healthy)
return c
}
func (c *Consequences) Triggers(block func(services *notification.TriggerList, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.listTriggers())
return c
}
func (c *Consequences) Templates(block func(services *notification.TemplateList, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.listTemplates())
return c
}

View File

@@ -7,15 +7,23 @@ import (
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
// this implements the "given" part of given/when/then
// Context implements the "given" part of given/when/then.
// It embeds fixture.TestState to provide test-specific state that enables parallel test execution.
type Context struct {
t *testing.T
*fixture.TestState
}
func Given(t *testing.T) *Context {
t.Helper()
fixture.EnsureCleanState(t)
return &Context{t: t}
state := fixture.EnsureCleanState(t)
return &Context{TestState: state}
}
// GivenWithSameState creates a new Context that shares the same TestState as an existing context.
// Use this when you need multiple fixture contexts within the same test.
func GivenWithSameState(ctx fixture.TestContext) *Context {
ctx.T().Helper()
return &Context{TestState: fixture.NewTestStateFromContext(ctx)}
}
func (c *Context) And(block func()) *Context {

View File

@@ -42,38 +42,38 @@ func (a *Actions) Create(args ...string) *Actions {
}
func (a *Actions) AddDestination(cluster string, namespace string) *Actions {
a.runCli("proj", "add-destination", a.context.name, cluster, namespace)
a.runCli("proj", "add-destination", a.context.GetName(), cluster, namespace)
return a
}
func (a *Actions) AddDestinationServiceAccount(cluster string, namespace string) *Actions {
a.runCli("proj", "add-destination-service-account", a.context.name, cluster, namespace)
a.runCli("proj", "add-destination-service-account", a.context.GetName(), cluster, namespace)
return a
}
func (a *Actions) AddSource(repo string) *Actions {
a.runCli("proj", "add-source", a.context.name, repo)
a.runCli("proj", "add-source", a.context.GetName(), repo)
return a
}
func (a *Actions) UpdateProject(updater func(project *v1alpha1.AppProject)) *Actions {
proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.TODO(), a.context.name, metav1.GetOptions{})
require.NoError(a.context.t, err)
proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.TODO(), a.context.GetName(), metav1.GetOptions{})
require.NoError(a.context.T(), err)
updater(proj)
_, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Update(context.TODO(), proj, metav1.UpdateOptions{})
require.NoError(a.context.t, err)
require.NoError(a.context.T(), err)
return a
}
func (a *Actions) Name(name string) *Actions {
a.context.name = name
func (a *Actions) SetName(name string) *Actions {
a.context.SetName(name)
return a
}
func (a *Actions) prepareCreateArgs(args []string) []string {
a.context.t.Helper()
a.context.T().Helper()
args = append([]string{
"proj", "create", a.context.name,
"proj", "create", a.context.GetName(),
}, args...)
if a.context.destination != "" {
@@ -99,27 +99,27 @@ func (a *Actions) prepareCreateArgs(args []string) []string {
}
func (a *Actions) Delete() *Actions {
a.context.t.Helper()
a.runCli("proj", "delete", a.context.name)
a.context.T().Helper()
a.runCli("proj", "delete", a.context.GetName())
return a
}
func (a *Actions) And(block func()) *Actions {
a.context.t.Helper()
a.context.T().Helper()
block()
return a
}
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
a.context.T().Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}
func (a *Actions) runCli(args ...string) {
a.context.t.Helper()
a.context.T().Helper()
_, a.lastError = fixture.RunCli(args...)
if !a.ignoreErrors {
require.NoError(a.context.t, a.lastError)
require.NoError(a.context.T(), a.lastError)
}
}

View File

@@ -20,7 +20,7 @@ func (c *Consequences) Expect() *Consequences {
}
func (c *Consequences) And(block func(app *project.DetailedProjectsResponse, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.detailedProject())
return c
}
@@ -33,7 +33,7 @@ func (c *Consequences) detailedProject() (*project.DetailedProjectsResponse, err
func (c *Consequences) get() (*project.DetailedProjectsResponse, error) {
_, projectClient, _ := fixture.ArgoCDClientset.NewProjectClient()
prj, err := projectClient.GetDetailedProject(context.Background(), &project.ProjectQuery{
Name: c.context.name,
Name: c.context.GetName(),
})
return prj, err

View File

@@ -7,10 +7,11 @@ import (
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
// this implements the "given" part of given/when/then
// Context implements the "given" part of given/when/then.
// It embeds fixture.TestState to provide test-specific state that enables parallel test execution.
type Context struct {
t *testing.T
name string
*fixture.TestState
destination string
destinationServiceAccounts []string
repos []string
@@ -19,21 +20,19 @@ type Context struct {
func Given(t *testing.T) *Context {
t.Helper()
fixture.EnsureCleanState(t)
return GivenWithSameState(t)
state := fixture.EnsureCleanState(t)
return GivenWithSameState(state)
}
func GivenWithSameState(t *testing.T) *Context {
t.Helper()
return &Context{t: t, name: fixture.Name()}
}
func (c *Context) GetName() string {
return c.name
// GivenWithSameState creates a new Context that shares the same TestState as an existing context.
// Use this when you need multiple fixture contexts within the same test.
func GivenWithSameState(ctx fixture.TestContext) *Context {
ctx.T().Helper()
return &Context{TestState: fixture.NewTestStateFromContext(ctx)}
}
func (c *Context) Name(name string) *Context {
c.name = name
c.SetName(name)
return c
}

View File

@@ -38,7 +38,7 @@ func (a *Actions) Create(args ...string) *Actions {
}
func (a *Actions) prepareCreateArgs(args []string) []string {
a.context.t.Helper()
a.context.T().Helper()
args = append([]string{
"repo", "add", a.context.path,
}, args...)
@@ -49,19 +49,19 @@ func (a *Actions) prepareCreateArgs(args []string) []string {
}
func (a *Actions) Delete() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("repo", "rm", a.context.path)
return a
}
func (a *Actions) List() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("repo", "list")
return a
}
func (a *Actions) Get() *Actions {
a.context.t.Helper()
a.context.T().Helper()
a.runCli("repo", "get", a.context.path)
return a
}
@@ -77,13 +77,13 @@ func (a *Actions) Project(project string) *Actions {
}
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
a.context.T().Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}
func (a *Actions) runCli(args ...string) {
a.context.t.Helper()
a.context.T().Helper()
a.lastOutput, a.lastError = fixture.RunCli(args...)
if !a.ignoreErrors && a.lastError != nil {
log.Fatal(a.lastOutput)

View File

@@ -21,13 +21,13 @@ func (c *Consequences) Expect() *Consequences {
}
func (c *Consequences) And(block func(repository *v1alpha1.Repository, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.repo())
return c
}
func (c *Consequences) AndCLIOutput(block func(output string, err error)) *Consequences {
c.context.t.Helper()
c.context.T().Helper()
block(c.actions.lastOutput, c.actions.lastError)
return c
}

View File

@@ -7,33 +7,30 @@ import (
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
// this implements the "given" part of given/when/then
// Context implements the "given" part of given/when/then.
// It embeds fixture.TestState to provide test-specific state that enables parallel test execution.
type Context struct {
t *testing.T
*fixture.TestState
path string
name string
project string
}
func Given(t *testing.T) *Context {
t.Helper()
fixture.EnsureCleanState(t)
return GivenWithSameState(t)
state := fixture.EnsureCleanState(t)
return GivenWithSameState(state)
}
// GivenWithSameState skips cleaning state. Use this when you've already ensured you have a clean
// state in your test setup don't want to waste time by doing so again.
func GivenWithSameState(t *testing.T) *Context {
t.Helper()
return &Context{t: t, name: fixture.Name(), project: "default"}
}
func (c *Context) GetName() string {
return c.name
// GivenWithSameState creates a new Context that shares the same TestState as an existing context.
// Use this when you need multiple fixture contexts within the same test.
func GivenWithSameState(ctx fixture.TestContext) *Context {
ctx.T().Helper()
return &Context{TestState: fixture.NewTestStateFromContext(ctx), project: "default"}
}
func (c *Context) Name(name string) *Context {
c.name = name
c.SetName(name)
return c
}

View File

@@ -320,23 +320,16 @@ func PushImageToAuthenticatedOCIRegistry(t *testing.T, pathName, tag string) {
))
}
// AddHTTPSWriteCredentials adds write credentials for an HTTPS repository.
// AddWriteCredentials adds write credentials for a repository.
// Write credentials are used by the commit-server to push hydrated manifests back to the repository.
// TODO: add CLI support for managing write credentials and use that here instead.
func AddHTTPSWriteCredentials(t *testing.T, insecure bool, repoURLType fixture.RepoURLType) {
func AddWriteCredentials(t *testing.T, name string, insecure bool, repoURLType fixture.RepoURLType) {
t.Helper()
repoURL := fixture.RepoURL(repoURLType)
// Create a Kubernetes secret with the repository-write label
// Replace invalid characters for secret name
secretName := "write-creds-" + fixture.Name()
// Delete existing secret if it exists (ignore error if not found)
_ = fixture.KubeClientset.CoreV1().Secrets(fixture.ArgoCDNamespace).Delete(
context.Background(),
secretName,
metav1.DeleteOptions{},
)
secretName := "write-creds-" + name
_, err := fixture.KubeClientset.CoreV1().Secrets(fixture.ArgoCDNamespace).Create(
context.Background(),

View File

@@ -21,6 +21,7 @@ func DnsFriendly(str string, postfix string) string { //nolint:revive //FIXME(va
str = matchAllCap.ReplaceAllString(str, "${1}-${2}")
str = strings.ToLower(str)
str = strings.ReplaceAll(str, "/", "-")
str = strings.ReplaceAll(str, "_", "-")
if diff := len(str) + len(postfix) - 63; diff > 0 {
str = str[:len(str)-diff]

View File

@@ -157,8 +157,8 @@ func TestAnnotatedTagInStatusSyncRevision(t *testing.T) {
// Test updates to K8s resources should not trigger a self-heal when self-heal is false.
func TestAutomatedSelfHealingAgainstAnnotatedTag(t *testing.T) {
Given(t).
Path(guestbookPath).
ctx := Given(t)
ctx.Path(guestbookPath).
When().
AddAnnotatedTag("annotated-tag", "my-generic-tag-message").
// App should be auto-synced once created
@@ -178,7 +178,7 @@ func TestAutomatedSelfHealingAgainstAnnotatedTag(t *testing.T) {
And(func() {
// Deployment revisionHistoryLimit should switch to 10
timeoutErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
if err != nil {
return false, nil
}
@@ -190,14 +190,14 @@ func TestAutomatedSelfHealingAgainstAnnotatedTag(t *testing.T) {
}).
// Update the Deployment to a different revisionHistoryLimit
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 9}}`), metav1.PatchOptions{}))
}).
// The revisionHistoryLimit should NOT be self-healed, because selfHealing: false. It should remain at 9.
And(func() {
// Wait up to 10 seconds to ensure that deployment revisionHistoryLimit does NOT should switch to 10, it should remain at 9.
waitErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
if err != nil {
return false, nil
}
@@ -210,8 +210,8 @@ func TestAutomatedSelfHealingAgainstAnnotatedTag(t *testing.T) {
}
func TestAutomatedSelfHealingAgainstLightweightTag(t *testing.T) {
Given(t).
Path(guestbookPath).
ctx := Given(t)
ctx.Path(guestbookPath).
When().
AddTag("annotated-tag").
// App should be auto-synced once created
@@ -231,7 +231,7 @@ func TestAutomatedSelfHealingAgainstLightweightTag(t *testing.T) {
And(func() {
// Deployment revisionHistoryLimit should switch to 10
timeoutErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
if err != nil {
return false, nil
}
@@ -243,14 +243,14 @@ func TestAutomatedSelfHealingAgainstLightweightTag(t *testing.T) {
}).
// Update the Deployment to a different revisionHistoryLimit
And(func() {
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.MergePatchType, []byte(`{"spec": {"revisionHistoryLimit": 9}}`), metav1.PatchOptions{}))
}).
// The revisionHistoryLimit should NOT be self-healed, because selfHealing: false
And(func() {
// Wait up to 10 seconds to ensure that deployment revisionHistoryLimit does NOT should switch to 10, it should remain at 9.
waitErr := wait.PollUntilContextTimeout(t.Context(), 1*time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) {
deployment, err := fixture.KubeClientset.AppsV1().Deployments(fixture.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
deployment, err := fixture.KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Get(t.Context(), "guestbook-ui", metav1.GetOptions{})
if err != nil {
return false, nil
}

View File

@@ -21,8 +21,8 @@ import (
)
func TestHelmHooksAreCreated(t *testing.T) {
Given(t).
Path("hook").
ctx := Given(t)
ctx.Path("hook").
When().
PatchFile("hook.yaml", `[{"op": "replace", "path": "/metadata/annotations", "value": {"helm.sh/hook": "pre-install"}}]`).
CreateApp().
@@ -31,7 +31,7 @@ func TestHelmHooksAreCreated(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(HealthIs(health.HealthStatusHealthy)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: fixture.DeploymentNamespace(), Name: "hook", Message: "pod/hook created", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, HookType: HookTypePreSync, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhasePreSync}))
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: ctx.DeploymentNamespace(), Name: "hook", Message: "pod/hook created", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, HookType: HookTypePreSync, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhasePreSync}))
}
// make sure we treat Helm weights as a sync wave
@@ -313,8 +313,8 @@ func TestHelmSetFile(t *testing.T) {
// ensure we can use envsubst in "set" variables
func TestHelmSetEnv(t *testing.T) {
Given(t).
Path("helm-values").
ctx := Given(t)
ctx.Path("helm-values").
When().
CreateApp().
AppSet("--helm-set", "foo=$ARGOCD_APP_NAME").
@@ -323,13 +323,13 @@ func TestHelmSetEnv(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
assert.Equal(t, fixture.Name(), errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
assert.Equal(t, ctx.GetName(), errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
})
}
func TestHelmSetStringEnv(t *testing.T) {
Given(t).
Path("helm-values").
ctx := Given(t)
ctx.Path("helm-values").
When().
CreateApp().
AppSet("--helm-set-string", "foo=$ARGOCD_APP_NAME").
@@ -338,22 +338,22 @@ func TestHelmSetStringEnv(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
assert.Equal(t, fixture.Name(), errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
assert.Equal(t, ctx.GetName(), errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
})
}
// make sure kube-version gets passed down to resources
func TestKubeVersion(t *testing.T) {
fixture.SkipOnEnv(t, "HELM")
Given(t).
Path("helm-kube-version").
ctx := Given(t)
ctx.Path("helm-kube-version").
When().
CreateApp().
Sync().
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
kubeVersion := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map",
kubeVersion := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map",
"-o", "jsonpath={.data.kubeVersion}")).(string)
// Capabilities.KubeVersion defaults to 1.9.0, we assume here you are running a later version
assert.LessOrEqual(t, fixture.GetVersions(t).ServerVersion.Format("v%s.%s"), kubeVersion)
@@ -365,7 +365,7 @@ func TestKubeVersion(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
assert.Equal(t, "v999.999.999", errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map",
assert.Equal(t, "v999.999.999", errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map",
"-o", "jsonpath={.data.kubeVersion}")).(string))
})
}
@@ -373,15 +373,15 @@ func TestKubeVersion(t *testing.T) {
// make sure api versions gets passed down to resources
func TestApiVersions(t *testing.T) {
fixture.SkipOnEnv(t, "HELM")
Given(t).
Path("helm-api-versions").
ctx := Given(t)
ctx.Path("helm-api-versions").
When().
CreateApp().
Sync().
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map",
apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map",
"-o", "jsonpath={.data.apiVersions}")).(string)
// The v1 API shouldn't be going anywhere.
assert.Contains(t, apiVersions, "v1")
@@ -393,7 +393,7 @@ func TestApiVersions(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map",
apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map",
"-o", "jsonpath={.data.apiVersions}")).(string)
assert.Contains(t, apiVersions, "v1/MyTestResource")
})
@@ -470,18 +470,16 @@ func TestHelmWithMultipleDependencies(t *testing.T) {
func TestHelmDependenciesPermissionDenied(t *testing.T) {
fixture.SkipOnEnv(t, "HELM")
projName := "argo-helm-project-denied"
projectFixture.
Given(t).
Name(projName).
ctx := projectFixture.Given(t)
ctx.Name("argo-helm-project-denied").
Destination("*,*").
When().
Create().
AddSource(fixture.RepoURL(fixture.RepoURLTypeFile))
expectedErr := fmt.Sprintf("helm repos localhost:5000/myrepo are not permitted in project '%s'", projName)
GivenWithSameState(t).
Project(projName).
expectedErr := fmt.Sprintf("helm repos localhost:5000/myrepo are not permitted in project '%s'", ctx.GetName())
GivenWithSameState(ctx).
Project(ctx.GetName()).
Path("helm-oci-with-dependencies").
CustomCACertAdded().
HelmHTTPSCredentialsUserPassAdded().
@@ -492,9 +490,9 @@ func TestHelmDependenciesPermissionDenied(t *testing.T) {
Then().
Expect(Error("", expectedErr))
expectedErr = fmt.Sprintf("helm repos https://localhost:9443/argo-e2e/testdata.git/helm-repo/local, https://localhost:9443/argo-e2e/testdata.git/helm-repo/local2 are not permitted in project '%s'", projName)
GivenWithSameState(t).
Project(projName).
expectedErr = fmt.Sprintf("helm repos https://localhost:9443/argo-e2e/testdata.git/helm-repo/local, https://localhost:9443/argo-e2e/testdata.git/helm-repo/local2 are not permitted in project '%s'", ctx.GetName())
GivenWithSameState(ctx).
Project(ctx.GetName()).
Path("helm-with-multiple-dependencies-permission-denied").
CustomCACertAdded().
HelmHTTPSCredentialsUserPassAdded().

View File

@@ -37,7 +37,8 @@ func TestPostSyncHookSuccessful(t *testing.T) {
// make sure we can run a standard sync hook
func testHookSuccessful(t *testing.T, hookType HookType) {
t.Helper()
Given(t).
ctx := Given(t)
ctx.
Path("hook").
When().
PatchFile("hook.yaml", fmt.Sprintf(`[{"op": "replace", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/hook": %q}}]`, hookType)).
@@ -49,11 +50,12 @@ func testHookSuccessful(t *testing.T, hookType HookType) {
Expect(ResourceSyncStatusIs("Pod", "pod", SyncStatusCodeSynced)).
Expect(ResourceHealthIs("Pod", "pod", health.HealthStatusHealthy)).
Expect(ResourceResultNumbering(2)).
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Name: "hook", Message: "pod/hook created", HookType: hookType, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)}))
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: ctx.DeploymentNamespace(), Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Name: "hook", Message: "pod/hook created", HookType: hookType, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)}))
}
func TestPreDeleteHook(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path("pre-delete-hook").
When().
CreateApp().
@@ -61,7 +63,7 @@ func TestPreDeleteHook(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
_, err := KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Get(
_, err := KubeClientset.CoreV1().ConfigMaps(ctx.DeploymentNamespace()).Get(
t.Context(), "guestbook-ui", metav1.GetOptions{},
)
require.NoError(t, err)
@@ -115,13 +117,14 @@ func TestPostDeleteHook(t *testing.T) {
// make sure that hooks do not appear in "argocd app diff"
func TestHookDiff(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path("hook").
When().
CreateApp().
Then().
And(func(_ *Application) {
output, err := RunCli("app", "diff", Name())
output, err := RunCli("app", "diff", ctx.GetName())
require.Error(t, err)
assert.Contains(t, output, "name: pod")
assert.NotContains(t, output, "name: hook")
@@ -221,7 +224,8 @@ func TestPostSyncHookPodFailure(t *testing.T) {
func TestSyncFailHookPodFailure(t *testing.T) {
// Tests that a SyncFail hook will successfully run upon a pod failure (which leads to a sync failure)
Given(t).
ctx := Given(t)
ctx.
Path("hook").
When().
IgnoreErrors().
@@ -246,13 +250,14 @@ spec:
CreateApp().
Sync().
Then().
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Name: "sync-fail-hook", Message: "pod/sync-fail-hook created", HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhaseSyncFail})).
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: ctx.DeploymentNamespace(), Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Name: "sync-fail-hook", Message: "pod/sync-fail-hook created", HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhaseSyncFail})).
Expect(OperationPhaseIs(OperationFailed))
}
func TestSyncFailHookPodFailureSyncFailFailure(t *testing.T) {
// Tests that a failing SyncFail hook will successfully be marked as failed
Given(t).
ctx := Given(t)
ctx.
Path("hook").
When().
IgnoreErrors().
@@ -293,8 +298,8 @@ spec:
CreateApp().
Sync().
Then().
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "successful-sync-fail-hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: "pod/successful-sync-fail-hook created", HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhaseSyncFail})).
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "failed-sync-fail-hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: `container "main" failed with exit code 1`, HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationFailed, SyncPhase: SyncPhaseSyncFail})).
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: ctx.DeploymentNamespace(), Name: "successful-sync-fail-hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: "pod/successful-sync-fail-hook created", HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhaseSyncFail})).
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: ctx.DeploymentNamespace(), Name: "failed-sync-fail-hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: `container "main" failed with exit code 1`, HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationFailed, SyncPhase: SyncPhaseSyncFail})).
Expect(OperationPhaseIs(OperationFailed))
}
@@ -360,7 +365,8 @@ func TestHookDeletePolicyHookFailedHookExit1(t *testing.T) {
// make sure that we can run the hook twice
func TestHookBeforeHookCreation(t *testing.T) {
var creationTimestamp1 string
Given(t).
ctx := Given(t)
ctx.
Path("hook").
When().
PatchFile("hook.yaml", `[{"op": "add", "path": "/metadata/annotations/argocd.argoproj.io~1hook-delete-policy", "value": "BeforeHookCreation"}]`).
@@ -375,7 +381,7 @@ func TestHookBeforeHookCreation(t *testing.T) {
Expect(Pod(func(p corev1.Pod) bool { return p.Name == "hook" })).
And(func(_ *Application) {
var err error
creationTimestamp1, err = getCreationTimestamp()
creationTimestamp1, err = getCreationTimestamp(ctx.DeploymentNamespace())
require.NoError(t, err)
assert.NotEmpty(t, creationTimestamp1)
// pause to ensure that timestamp will change
@@ -390,7 +396,7 @@ func TestHookBeforeHookCreation(t *testing.T) {
Expect(ResourceResultNumbering(2)).
Expect(Pod(func(p corev1.Pod) bool { return p.Name == "hook" })).
And(func(_ *Application) {
creationTimestamp2, err := getCreationTimestamp()
creationTimestamp2, err := getCreationTimestamp(ctx.DeploymentNamespace())
require.NoError(t, err)
assert.NotEmpty(t, creationTimestamp2)
assert.NotEqual(t, creationTimestamp1, creationTimestamp2)
@@ -417,8 +423,8 @@ func TestHookBeforeHookCreationFailure(t *testing.T) {
Expect(ResourceResultNumbering(2))
}
func getCreationTimestamp() (string, error) {
return Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "pod", "hook", "-o", "jsonpath={.metadata.creationTimestamp}")
func getCreationTimestamp(deploymentNamespace string) (string, error) {
return Run(".", "kubectl", "-n", deploymentNamespace, "get", "pod", "hook", "-o", "jsonpath={.metadata.creationTimestamp}")
}
// make sure that we never create something annotated with Skip
@@ -486,7 +492,8 @@ func TestHookFinalizerPostSync(t *testing.T) {
func testHookFinalizer(t *testing.T, hookType HookType) {
t.Helper()
Given(t).
ctx := Given(t)
ctx.
And(func() {
require.NoError(t, SetResourceOverrides(map[string]ResourceOverride{
lua.GetConfigMapKey(schema.FromAPIVersionAndKind("batch/v1", "Job")): {
@@ -522,5 +529,5 @@ func testHookFinalizer(t *testing.T, hookType HookType) {
Expect(ResourceSyncStatusIs("Pod", "pod", SyncStatusCodeSynced)).
Expect(ResourceHealthIs("Pod", "pod", health.HealthStatusHealthy)).
Expect(ResourceResultNumbering(2)).
Expect(ResourceResultIs(ResourceResult{Group: "batch", Version: "v1", Kind: "Job", Namespace: DeploymentNamespace(), Name: "hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: "Resource has finalizer", HookType: hookType, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)}))
Expect(ResourceResultIs(ResourceResult{Group: "batch", Version: "v1", Kind: "Job", Namespace: ctx.DeploymentNamespace(), Name: "hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: "Resource has finalizer", HookType: hookType, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)}))
}

View File

@@ -8,7 +8,6 @@ import (
. "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
. "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos"
. "github.com/argoproj/gitops-engine/pkg/sync/common"
)
@@ -137,8 +136,8 @@ func TestKustomizeVersionOverride(t *testing.T) {
}
func TestHydratorWithHelm(t *testing.T) {
Given(t).
Path("hydrator-helm").
ctx := Given(t)
ctx.Path("hydrator-helm").
When().
CreateFromFile(func(app *Application) {
app.Spec.Source = nil
@@ -169,7 +168,7 @@ func TestHydratorWithHelm(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
// Verify that the inline helm parameter was applied
output, err := fixture.Run("", "kubectl", "-n="+fixture.DeploymentNamespace(),
output, err := fixture.Run("", "kubectl", "-n="+ctx.DeploymentNamespace(),
"get", "configmap", "my-map",
"-ojsonpath={.data.message}")
require.NoError(t, err)
@@ -178,8 +177,8 @@ func TestHydratorWithHelm(t *testing.T) {
}
func TestHydratorWithKustomize(t *testing.T) {
Given(t).
Path("hydrator-kustomize").
ctx := Given(t)
ctx.Path("hydrator-kustomize").
When().
CreateFromFile(func(app *Application) {
app.Spec.Source = nil
@@ -210,15 +209,15 @@ func TestHydratorWithKustomize(t *testing.T) {
// Verify that the inline kustomize nameSuffix was applied
// kustomization.yaml has namePrefix: kustomize-, and we added nameSuffix: -inline
// So the ConfigMap name should be kustomize-my-map-inline
_, err := fixture.Run("", "kubectl", "-n="+fixture.DeploymentNamespace(),
_, err := fixture.Run("", "kubectl", "-n="+ctx.DeploymentNamespace(),
"get", "configmap", "kustomize-my-map-inline")
require.NoError(t, err)
})
}
func TestHydratorWithDirectory(t *testing.T) {
Given(t).
Path("hydrator-directory").
ctx := Given(t)
ctx.Path("hydrator-directory").
When().
CreateFromFile(func(app *Application) {
app.Spec.Source = nil
@@ -247,7 +246,7 @@ func TestHydratorWithDirectory(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
// Verify that the recurse option was applied by checking the ConfigMap from subdir
_, err := fixture.Run("", "kubectl", "-n="+fixture.DeploymentNamespace(),
_, err := fixture.Run("", "kubectl", "-n="+ctx.DeploymentNamespace(),
"get", "configmap", "my-map-subdir")
require.NoError(t, err)
})
@@ -287,7 +286,7 @@ func TestHydratorWithPlugin(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
// Verify that the inline plugin env was applied
output, err := fixture.Run("", "kubectl", "-n="+fixture.DeploymentNamespace(),
output, err := fixture.Run("", "kubectl", "-n="+ctx.DeploymentNamespace(),
"get", "configmap", "plugin-generated-map",
"-ojsonpath={.data.plugin-env}")
require.NoError(t, err)
@@ -352,12 +351,10 @@ func TestHydratorWithAuthenticatedRepo(t *testing.T) {
// need to fetch existing git notes from the authenticated repository, which requires
// credentials.
Given(t).
HTTPSInsecureRepoURLAdded(true).
RepoURLType(fixture.RepoURLTypeHTTPS).
HTTPSInsecureRepoURLAdded(true).
// Add write credentials for commit-server to push hydrated manifests
And(func() {
repos.AddHTTPSWriteCredentials(t, true, fixture.RepoURLTypeHTTPS)
}).
WriteCredentials(true).
DrySourcePath("guestbook").
DrySourceRevision("HEAD").
SyncSourcePath("guestbook").

View File

@@ -75,7 +75,8 @@ func TestJsonnetTlaParameterAppliedCorrectly(t *testing.T) {
}
func TestJsonnetTlaEnv(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path("jsonnet-tla-cm").
When().
CreateApp("--jsonnet-tla-str", "foo=$ARGOCD_APP_NAME", "--jsonnet-tla-code", "bar='$ARGOCD_APP_NAME'").
@@ -84,13 +85,14 @@ func TestJsonnetTlaEnv(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
assert.Equal(t, Name(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
assert.Equal(t, Name(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.bar}")).(string))
assert.Equal(t, ctx.GetName(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
assert.Equal(t, ctx.GetName(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.bar}")).(string))
})
}
func TestJsonnetExtVarEnv(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path("jsonnet-ext-var").
When().
CreateApp("--jsonnet-ext-var-str", "foo=$ARGOCD_APP_NAME", "--jsonnet-ext-var-code", "bar='$ARGOCD_APP_NAME'").
@@ -99,8 +101,8 @@ func TestJsonnetExtVarEnv(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
assert.Equal(t, Name(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
assert.Equal(t, Name(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.bar}")).(string))
assert.Equal(t, ctx.GetName(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
assert.Equal(t, ctx.GetName(), errors.NewHandler(t).FailOnErr(Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.bar}")).(string))
})
}

View File

@@ -16,11 +16,12 @@ import (
)
func TestKustomize2AppSource(t *testing.T) {
ctx := Given(t)
patchLabelMatchesFor := func(kind string) func(app *Application) {
return func(_ *Application) {
name := "k2-patched-guestbook-ui-deploy1"
labelValue, err := fixture.Run(
"", "kubectl", "-n="+fixture.DeploymentNamespace(),
"", "kubectl", "-n="+ctx.DeploymentNamespace(),
"get", kind, name,
"-ojsonpath={.metadata.labels.patched-by}")
require.NoError(t, err)
@@ -28,7 +29,7 @@ func TestKustomize2AppSource(t *testing.T) {
}
}
Given(t).
ctx.
Path(guestbookPath).
NamePrefix("k2-").
NameSuffix("-deploy1").
@@ -181,13 +182,14 @@ func TestKustomizeImages(t *testing.T) {
// make sure we we can invoke the CLI to replace replicas and actual deployment is set to correct value
func TestKustomizeReplicas2AppSource(t *testing.T) {
ctx := Given(t)
deploymentName := "guestbook-ui"
deploymentReplicas := 2
checkReplicasFor := func(kind string) func(app *Application) {
return func(_ *Application) {
name := deploymentName
replicas, err := fixture.Run(
"", "kubectl", "-n="+fixture.DeploymentNamespace(),
"", "kubectl", "-n="+ctx.DeploymentNamespace(),
"get", kind, name,
"-ojsonpath={.spec.replicas}")
require.NoError(t, err)
@@ -195,7 +197,7 @@ func TestKustomizeReplicas2AppSource(t *testing.T) {
}
}
Given(t).
ctx.
Path("guestbook").
When().
CreateApp().
@@ -289,8 +291,8 @@ func TestKustomizeUnsetOverrideDeployment(t *testing.T) {
// make sure kube-version gets passed down to resources
func TestKustomizeKubeVersion(t *testing.T) {
Given(t).
Path("kustomize-kube-version").
ctx := Given(t)
ctx.Path("kustomize-kube-version").
And(func() {
errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm",
"-n", fixture.TestNamespace(),
@@ -302,7 +304,7 @@ func TestKustomizeKubeVersion(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
kubeVersion := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map",
kubeVersion := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map",
"-o", "jsonpath={.data.kubeVersion}")).(string)
// Capabilities.KubeVersion defaults to 1.9.0, we assume here you are running a later version
assert.LessOrEqual(t, fixture.GetVersions(t).ServerVersion.Format("v%s.%s"), kubeVersion)
@@ -314,15 +316,15 @@ func TestKustomizeKubeVersion(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
assert.Equal(t, "v999.999.999", errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map",
assert.Equal(t, "v999.999.999", errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map",
"-o", "jsonpath={.data.kubeVersion}")).(string))
})
}
// make sure api versions gets passed down to resources
func TestKustomizeApiVersions(t *testing.T) {
Given(t).
Path("kustomize-api-versions").
ctx := Given(t)
ctx.Path("kustomize-api-versions").
And(func() {
errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm",
"-n", fixture.TestNamespace(),
@@ -334,7 +336,7 @@ func TestKustomizeApiVersions(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map",
apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map",
"-o", "jsonpath={.data.apiVersions}")).(string)
// The v1 API shouldn't be going anywhere.
assert.Contains(t, apiVersions, "v1")
@@ -346,7 +348,7 @@ func TestKustomizeApiVersions(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
And(func(_ *Application) {
apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", fixture.DeploymentNamespace(), "get", "cm", "my-map",
apiVersions := errors.NewHandler(t).FailOnErr(fixture.Run(".", "kubectl", "-n", ctx.DeploymentNamespace(), "get", "cm", "my-map",
"-o", "jsonpath={.data.apiVersions}")).(string)
assert.Contains(t, apiVersions, "v1/MyTestResource")
})

View File

@@ -23,7 +23,8 @@ const managedByURLTestPath = "guestbook"
func TestManagedByURLWithAnnotation(t *testing.T) {
managedByURL := "https://argocd-instance-b.example.com"
Given(t).
ctx := Given(t)
ctx.
Project("default").
Path(managedByURLTestPath).
When().
@@ -31,7 +32,7 @@ func TestManagedByURLWithAnnotation(t *testing.T) {
And(func() {
// Add managed-by-url annotation to the application with retry logic
for i := 0; i < 3; i++ {
appObj, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.ArgoCDNamespace).Get(t.Context(), fixture.Name(), metav1.GetOptions{})
appObj, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.ArgoCDNamespace).Get(t.Context(), ctx.GetName(), metav1.GetOptions{})
require.NoError(t, err)
if appObj.Annotations == nil {

View File

@@ -56,9 +56,6 @@ func TestListMatrixGenerator(t *testing.T) {
// Create a ClusterGenerator-based ApplicationSet
When().
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "matrix-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{values.name}}-{{path.basename}}"},
@@ -181,9 +178,6 @@ func TestClusterMatrixGenerator(t *testing.T) {
CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "matrix-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-{{path.basename}}"},
@@ -303,9 +297,6 @@ func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) {
// Create ApplicationSet with LabelSelector on an ApplicationSetTerminalGenerator
When().
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "matrix-generator-nested-matrix",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{values.name}}-{{path.basename}}"},
@@ -442,9 +433,6 @@ func TestMatrixTerminalMergeGeneratorSelector(t *testing.T) {
// Create ApplicationSet with LabelSelector on an ApplicationSetTerminalGenerator
When().
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "matrix-generator-nested-merge",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}-{{name-suffix}}"},

View File

@@ -54,9 +54,6 @@ func TestListMergeGenerator(t *testing.T) {
// Create a ClusterGenerator-based ApplicationSet
When().
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "merge-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}-{{name-suffix}}"},
@@ -180,9 +177,6 @@ func TestClusterMergeGenerator(t *testing.T) {
CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "merge-generator",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-{{path.basename}}-{{values.name-suffix}}"},
@@ -318,9 +312,6 @@ func TestMergeTerminalMergeGeneratorSelector(t *testing.T) {
// Create ApplicationSet with LabelSelector on an ApplicationSetTerminalGenerator
When().
Create(v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "merge-generator-nested-merge",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}-{{name-suffix}}"},

View File

@@ -27,10 +27,10 @@ func TestKubectlMetrics(t *testing.T) {
Then().
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
And(func(app *Application) {
assert.Equal(t, fixture.Name(), app.Name)
assert.Equal(t, ctx.GetName(), app.Name)
assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL)
assert.Equal(t, guestbookPath, app.Spec.GetSource().Path)
assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, ctx.DeploymentNamespace(), app.Spec.Destination.Namespace)
assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server)
}).
Expect(Event(argo.EventReasonResourceCreated, "create")).
@@ -38,7 +38,7 @@ func TestKubectlMetrics(t *testing.T) {
// app should be listed
output, err := fixture.RunCli("app", "list")
require.NoError(t, err)
assert.Contains(t, output, fixture.Name())
assert.Contains(t, output, ctx.GetName())
}).
When().
// ensure that create is idempotent

View File

@@ -42,9 +42,9 @@ func assertProjHasEvent(t *testing.T, a *v1alpha1.AppProject, message string, re
}
func TestProjectCreation(t *testing.T) {
fixture.EnsureCleanState(t)
ctx := fixture.EnsureCleanState(t)
projectName := "proj-" + fixture.Name()
projectName := "proj-" + ctx.GetName()
_, err := fixture.RunCli("proj", "create", projectName,
"--description", "Test description",
"-d", "https://192.168.99.100:8443,default",
@@ -445,9 +445,9 @@ func TestRemoveOrphanedIgnore(t *testing.T) {
assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated)
}
func createAndConfigGlobalProject(ctx context.Context) error {
func createAndConfigGlobalProject(ctx context.Context, testName string) error {
// Create global project
projectGlobalName := "proj-g-" + fixture.Name()
projectGlobalName := "proj-g-" + testName
_, err := fixture.RunCli("proj", "create", projectGlobalName,
"--description", "Test description",
"-d", "https://192.168.99.100:8443,default",
@@ -512,12 +512,12 @@ func createAndConfigGlobalProject(ctx context.Context) error {
}
func TestGetVirtualProjectNoMatch(t *testing.T) {
fixture.EnsureCleanState(t)
err := createAndConfigGlobalProject(t.Context())
ctx := fixture.EnsureCleanState(t)
err := createAndConfigGlobalProject(t.Context(), ctx.GetName())
require.NoError(t, err)
// Create project which does not match global project settings
projectName := "proj-" + fixture.Name()
projectName := "proj-" + ctx.GetName()
_, err = fixture.RunCli("proj", "create", projectName,
"--description", "Test description",
"-d", v1alpha1.KubernetesInternalAPIServerAddr+",*",
@@ -529,27 +529,27 @@ func TestGetVirtualProjectNoMatch(t *testing.T) {
require.NoError(t, err)
// Create an app belongs to proj project
_, err = fixture.RunCli("app", "create", fixture.Name(), "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
"--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace())
_, err = fixture.RunCli("app", "create", ctx.GetName(), "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
"--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", ctx.DeploymentNamespace())
require.NoError(t, err)
// App trying to sync a resource which is not blacked listed anywhere
_, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", strconv.Itoa(10))
_, err = fixture.RunCli("app", "sync", ctx.GetName(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", strconv.Itoa(10))
require.NoError(t, err)
// app trying to sync a resource which is black listed by global project
_, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", strconv.Itoa(10))
_, err = fixture.RunCli("app", "sync", ctx.GetName(), "--resource", ":Service:guestbook-ui", "--timeout", strconv.Itoa(10))
require.NoError(t, err)
}
func TestGetVirtualProjectMatch(t *testing.T) {
fixture.EnsureCleanState(t)
testCtx := fixture.EnsureCleanState(t)
ctx := t.Context()
err := createAndConfigGlobalProject(ctx)
err := createAndConfigGlobalProject(ctx, testCtx.GetName())
require.NoError(t, err)
// Create project which matches global project settings
projectName := "proj-" + fixture.Name()
projectName := "proj-" + testCtx.GetName()
_, err = fixture.RunCli("proj", "create", projectName,
"--description", "Test description",
"-d", v1alpha1.KubernetesInternalAPIServerAddr+",*",
@@ -566,16 +566,16 @@ func TestGetVirtualProjectMatch(t *testing.T) {
require.NoError(t, err)
// Create an app belongs to proj project
_, err = fixture.RunCli("app", "create", fixture.Name(), "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
"--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace())
_, err = fixture.RunCli("app", "create", testCtx.GetName(), "--repo", fixture.RepoURL(fixture.RepoURLTypeFile),
"--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", testCtx.DeploymentNamespace())
require.NoError(t, err)
// App trying to sync a resource which is not blacked listed anywhere
_, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", strconv.Itoa(10))
_, err = fixture.RunCli("app", "sync", testCtx.GetName(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", strconv.Itoa(10))
require.ErrorContains(t, err, "blocked by sync window")
// app trying to sync a resource which is black listed by global project
_, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", strconv.Itoa(10))
_, err = fixture.RunCli("app", "sync", testCtx.GetName(), "--resource", ":Service:guestbook-ui", "--timeout", strconv.Itoa(10))
assert.ErrorContains(t, err, "blocked by sync window")
}

View File

@@ -16,22 +16,22 @@ import (
)
func TestCreateRepositoryWithProject(t *testing.T) {
prjConsequence := projectFixture.Given(t).
ctx := projectFixture.Given(t).Name("argo-project")
prjConsequence := ctx.
When().
Name("argo-project").
Create().
Then()
path := "https://github.com/argoproj/argo-cd.git"
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(path).
Project("argo-project").
Project(ctx.GetName()).
Create().
Then().
And(func(r *Repository, _ error) {
assert.Equal(t, r.Repo, path)
assert.Equal(t, "argo-project", r.Project)
assert.Equal(t, path, r.Repo)
assert.Equal(t, ctx.GetName(), r.Project)
prjConsequence.And(func(projectResponse *project.DetailedProjectsResponse, _ error) {
assert.Len(t, projectResponse.Repositories, 1)
@@ -41,14 +41,14 @@ func TestCreateRepositoryWithProject(t *testing.T) {
}
func TestCreateRepositoryNonAdminUserPermissionDenied(t *testing.T) {
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login()
path := "https://github.com/argoproj/argo-cd.git"
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(path).
Project("argo-project").
@@ -61,8 +61,8 @@ func TestCreateRepositoryNonAdminUserPermissionDenied(t *testing.T) {
}
func TestCreateRepositoryNonAdminUserWithWrongProject(t *testing.T) {
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login().
@@ -75,7 +75,7 @@ func TestCreateRepositoryNonAdminUserWithWrongProject(t *testing.T) {
}, "org-admin")
path := "https://github.com/argoproj/argo-cd.git"
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(path).
Project("argo-project").
@@ -88,8 +88,8 @@ func TestCreateRepositoryNonAdminUserWithWrongProject(t *testing.T) {
}
func TestDeleteRepositoryRbacAllowed(t *testing.T) {
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login().
@@ -112,7 +112,7 @@ func TestDeleteRepositoryRbacAllowed(t *testing.T) {
}, "org-admin")
path := "https://github.com/argoproj/argo-cd.git"
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(path).
Project("argo-project").
@@ -131,8 +131,8 @@ func TestDeleteRepositoryRbacAllowed(t *testing.T) {
}
func TestDeleteRepositoryRbacDenied(t *testing.T) {
accountFixture.Given(t).
Name("test").
ctx := accountFixture.Given(t)
ctx.Name("test").
When().
Create().
Login().
@@ -155,7 +155,7 @@ func TestDeleteRepositoryRbacDenied(t *testing.T) {
}, "org-admin")
path := "https://github.com/argoproj/argo-cd.git"
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(path).
Project("argo-project").
@@ -234,22 +234,22 @@ git https://github.com/argoproj/argo-cd.git false false false fal
}
func TestCreateRepoWithSameURLInTwoProjects(t *testing.T) {
projectFixture.Given(t).
ctx := projectFixture.Given(t)
ctx.Name("project-one").
When().
Name("project-one").
Create().
Then()
projectFixture.Given(t).
When().
Name("project-two").
When().
Create().
Then()
path := "https://github.com/argoproj/argo-cd.git"
// Create repository in first project
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(path).
Project("project-one").
@@ -260,7 +260,7 @@ func TestCreateRepoWithSameURLInTwoProjects(t *testing.T) {
})
// Create repository with same URL in second project
repoFixture.GivenWithSameState(t).
repoFixture.GivenWithSameState(ctx).
When().
Path(path).
Project("project-two").

View File

@@ -57,8 +57,8 @@ func TestSelectiveSyncWithoutNamespace(t *testing.T) {
errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "delete", "namespace", selectedResourceNamespace))
}
}()
Given(t).
Prune(true).
ctx := Given(t)
ctx.Prune(true).
Path("guestbook-with-namespace").
And(func() {
errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "create", "namespace", selectedResourceNamespace))
@@ -74,9 +74,9 @@ func TestSelectiveSyncWithoutNamespace(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
Expect(ResourceHealthWithNamespaceIs("Deployment", "guestbook-ui", selectedResourceNamespace, health.HealthStatusHealthy)).
Expect(ResourceHealthWithNamespaceIs("Deployment", "guestbook-ui", fixture.DeploymentNamespace(), health.HealthStatusHealthy)).
Expect(ResourceHealthWithNamespaceIs("Deployment", "guestbook-ui", ctx.DeploymentNamespace(), health.HealthStatusHealthy)).
Expect(ResourceSyncStatusWithNamespaceIs("Deployment", "guestbook-ui", selectedResourceNamespace, SyncStatusCodeSynced)).
Expect(ResourceSyncStatusWithNamespaceIs("Deployment", "guestbook-ui", fixture.DeploymentNamespace(), SyncStatusCodeSynced))
Expect(ResourceSyncStatusWithNamespaceIs("Deployment", "guestbook-ui", ctx.DeploymentNamespace(), SyncStatusCodeSynced))
}
// In selectedResource to sync, namespace is provided
@@ -87,8 +87,8 @@ func TestSelectiveSyncWithNamespace(t *testing.T) {
errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "delete", "namespace", selectedResourceNamespace))
}
}()
Given(t).
Prune(true).
ctx := Given(t)
ctx.Prune(true).
Path("guestbook-with-namespace").
And(func() {
errors.NewHandler(t).FailOnErr(fixture.Run("", "kubectl", "create", "namespace", selectedResourceNamespace))
@@ -104,9 +104,9 @@ func TestSelectiveSyncWithNamespace(t *testing.T) {
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
Expect(ResourceHealthWithNamespaceIs("Deployment", "guestbook-ui", selectedResourceNamespace, health.HealthStatusHealthy)).
Expect(ResourceHealthWithNamespaceIs("Deployment", "guestbook-ui", fixture.DeploymentNamespace(), health.HealthStatusMissing)).
Expect(ResourceHealthWithNamespaceIs("Deployment", "guestbook-ui", ctx.DeploymentNamespace(), health.HealthStatusMissing)).
Expect(ResourceSyncStatusWithNamespaceIs("Deployment", "guestbook-ui", selectedResourceNamespace, SyncStatusCodeSynced)).
Expect(ResourceSyncStatusWithNamespaceIs("Deployment", "guestbook-ui", fixture.DeploymentNamespace(), SyncStatusCodeOutOfSync))
Expect(ResourceSyncStatusWithNamespaceIs("Deployment", "guestbook-ui", ctx.DeploymentNamespace(), SyncStatusCodeOutOfSync))
}
func getNewNamespace(t *testing.T) string {

View File

@@ -119,7 +119,8 @@ func TestSyncOptionsValidateTrue(t *testing.T) {
}
func TestSyncWithStatusIgnored(t *testing.T) {
Given(t).
ctx := Given(t)
ctx.
Path(guestbookPath).
When().
And(func() {
@@ -143,7 +144,7 @@ func TestSyncWithStatusIgnored(t *testing.T) {
// app should remain synced if k8s change detected
When().
And(func() {
errors.NewHandler(t).FailOnErr(KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Patch(t.Context(),
errors.NewHandler(t).FailOnErr(KubeClientset.AppsV1().Deployments(ctx.DeploymentNamespace()).Patch(t.Context(),
"guestbook-ui", types.JSONPatchType, []byte(`[{ "op": "replace", "path": "/status/observedGeneration", "value": 2 }]`), metav1.PatchOptions{}))
}).
Then().
@@ -199,13 +200,14 @@ func TestSyncWithSkipHook(t *testing.T) {
}
func TestSyncWithForceReplace(t *testing.T) {
ctx := Given(t)
t.Cleanup(func() {
// remove finalizer to ensure easy cleanup
_, err := Run("", "kubectl", "patch", "deployment", "guestbook-ui", "-n", DeploymentNamespace(), "-p", `{"metadata":{"finalizers":[]}}`, "--type=merge")
_, err := Run("", "kubectl", "patch", "deployment", "guestbook-ui", "-n", ctx.DeploymentNamespace(), "-p", `{"metadata":{"finalizers":[]}}`, "--type=merge")
require.NoError(t, err)
})
Given(t).
ctx.
Path(guestbookPath).
When().
CreateApp().

View File

@@ -53,21 +53,20 @@ func TestSyncWithNoDestinationServiceAccountsInProject(t *testing.T) {
}
func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) {
projectName := "sync-test-project"
serviceAccountName := "test-account"
projectCtx := project.Given(t)
appCtx := Given(t)
appCtx := GivenWithSameState(projectCtx)
projectCtx.
Name(projectName).
Name("sync-test-project").
SourceNamespaces([]string{"*"}).
SourceRepositories([]string{"*"}).
Destination("*,*").
DestinationServiceAccounts(
[]string{
fmt.Sprintf("%s,%s,%s", "*", fixture.DeploymentNamespace(), serviceAccountName),
fmt.Sprintf("%s,%s,%s", v1alpha1.KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace(), "missing-serviceAccount"),
fmt.Sprintf("%s,%s,%s", "*", projectCtx.DeploymentNamespace(), serviceAccountName),
fmt.Sprintf("%s,%s,%s", v1alpha1.KubernetesInternalAPIServerAddr, projectCtx.DeploymentNamespace(), "missing-serviceAccount"),
}).
When().
Create().
@@ -75,6 +74,7 @@ func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) {
Expect()
appCtx.
Project(projectCtx.GetName()).
SetTrackingMethod("annotation").
Path("guestbook").
When().
@@ -92,7 +92,6 @@ func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) {
}).
CreateFromFile(func(app *v1alpha1.Application) {
app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}}
app.Spec.Project = projectName
}).
Then().
// With the impersonation feature enabled, Application sync should succeed
@@ -102,21 +101,20 @@ func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) {
}
func TestSyncWithMissingServiceAccount(t *testing.T) {
projectName := "false-test-project"
serviceAccountName := "test-account"
projectCtx := project.Given(t)
appCtx := Given(t)
appCtx := GivenWithSameState(projectCtx)
projectCtx.
Name(projectName).
Name("false-test-project").
SourceNamespaces([]string{"*"}).
SourceRepositories([]string{"*"}).
Destination("*,*").
DestinationServiceAccounts(
[]string{
fmt.Sprintf("%s,%s,%s", v1alpha1.KubernetesInternalAPIServerAddr, fixture.DeploymentNamespace(), "missing-serviceAccount"),
fmt.Sprintf("%s,%s,%s", "*", fixture.DeploymentNamespace(), serviceAccountName),
fmt.Sprintf("%s,%s,%s", v1alpha1.KubernetesInternalAPIServerAddr, projectCtx.DeploymentNamespace(), "missing-serviceAccount"),
fmt.Sprintf("%s,%s,%s", "*", projectCtx.DeploymentNamespace(), serviceAccountName),
}).
When().
Create().
@@ -124,6 +122,7 @@ func TestSyncWithMissingServiceAccount(t *testing.T) {
Expect()
appCtx.
Project(projectCtx.GetName()).
SetTrackingMethod("annotation").
Path("guestbook").
When().
@@ -141,7 +140,6 @@ func TestSyncWithMissingServiceAccount(t *testing.T) {
}).
CreateFromFile(func(app *v1alpha1.Application) {
app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}}
app.Spec.Project = projectName
}).
Then().
// With the impersonation feature enabled, Application sync must fail
@@ -152,20 +150,19 @@ func TestSyncWithMissingServiceAccount(t *testing.T) {
}
func TestSyncWithValidSAButDisallowedDestination(t *testing.T) {
projectName := "negation-test-project"
serviceAccountName := "test-account"
projectCtx := project.Given(t)
appCtx := Given(t)
appCtx := GivenWithSameState(projectCtx)
projectCtx.
Name(projectName).
Name("negation-test-project").
SourceNamespaces([]string{"*"}).
SourceRepositories([]string{"*"}).
Destination("*,*").
DestinationServiceAccounts(
[]string{
fmt.Sprintf("%s,%s,%s", "*", fixture.DeploymentNamespace(), serviceAccountName),
fmt.Sprintf("%s,%s,%s", "*", projectCtx.DeploymentNamespace(), serviceAccountName),
}).
When().
Create().
@@ -173,6 +170,7 @@ func TestSyncWithValidSAButDisallowedDestination(t *testing.T) {
Expect()
appCtx.
Project(projectCtx.GetName()).
SetTrackingMethod("annotation").
Path("guestbook").
When().
@@ -190,16 +188,15 @@ func TestSyncWithValidSAButDisallowedDestination(t *testing.T) {
}).
CreateFromFile(func(app *v1alpha1.Application) {
app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}}
app.Spec.Project = projectName
}).
Then().
Expect(SyncStatusIs(v1alpha1.SyncStatusCodeSynced)).
When().
And(func() {
// Patch destination to disallow target destination namespace
patch := []byte(fmt.Sprintf(`{"spec": {"destinations": [{"namespace": %q}]}}`, "!"+fixture.DeploymentNamespace()))
patch := []byte(fmt.Sprintf(`{"spec": {"destinations": [{"namespace": %q}]}}`, "!"+appCtx.DeploymentNamespace()))
_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Patch(t.Context(), projectName, types.MergePatchType, patch, metav1.PatchOptions{})
_, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Patch(t.Context(), projectCtx.GetName(), types.MergePatchType, patch, metav1.PatchOptions{})
require.NoError(t, err)
}).
Refresh(v1alpha1.RefreshTypeNormal).