github.com/argoproj/argo-cd/v3@v3.2.1/test/e2e/sync_waves_test.go (about)

     1  package e2e
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/argoproj/gitops-engine/pkg/health"
     8  	. "github.com/argoproj/gitops-engine/pkg/sync/common"
     9  	"github.com/stretchr/testify/require"
    10  	corev1 "k8s.io/api/core/v1"
    11  
    12  	. "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
    13  	. "github.com/argoproj/argo-cd/v3/test/e2e/fixture"
    14  	. "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app"
    15  )
    16  
    17  func TestFixingDegradedApp(t *testing.T) {
    18  	var lastTransitionTime string
    19  	Given(t).
    20  		Path("sync-waves").
    21  		When().
    22  		IgnoreErrors().
    23  		CreateApp().
    24  		And(func() {
    25  			require.NoError(t, SetResourceOverrides(map[string]ResourceOverride{
    26  				"ConfigMap": {
    27  					HealthLua: `return { status = obj.metadata.annotations and obj.metadata.annotations['health'] or 'Degraded' }`,
    28  				},
    29  			}))
    30  		}).
    31  		Sync().
    32  		Then().
    33  		Expect(OperationPhaseIs(OperationFailed)).
    34  		Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
    35  		Expect(HealthIs(health.HealthStatusDegraded)).
    36  		Expect(ResourceResultNumbering(1)).
    37  		Expect(ResourceSyncStatusIs("ConfigMap", "cm-1", SyncStatusCodeSynced)).
    38  		Expect(ResourceHealthIs("ConfigMap", "cm-1", health.HealthStatusDegraded)).
    39  		Expect(ResourceSyncStatusIs("ConfigMap", "cm-2", SyncStatusCodeOutOfSync)).
    40  		Expect(ResourceHealthIs("ConfigMap", "cm-2", health.HealthStatusMissing)).
    41  		When().
    42  		Then().
    43  		And(func(app *Application) {
    44  			lastTransitionTime = app.Status.Health.LastTransitionTime.UTC().Format(time.RFC3339)
    45  		}).
    46  		When().
    47  		PatchFile("cm-1.yaml", `[{"op": "replace", "path": "/metadata/annotations/health", "value": "Healthy"}]`).
    48  		PatchFile("cm-2.yaml", `[{"op": "replace", "path": "/metadata/annotations/health", "value": "Healthy"}]`).
    49  		// need to force a refresh here
    50  		Refresh(RefreshTypeNormal).
    51  		Then().
    52  		Expect(ResourceSyncStatusIs("ConfigMap", "cm-1", SyncStatusCodeOutOfSync)).
    53  		When().
    54  		Sync().
    55  		Then().
    56  		Expect(OperationPhaseIs(OperationSucceeded)).
    57  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
    58  		Expect(HealthIs(health.HealthStatusHealthy)).
    59  		Expect(ResourceResultNumbering(2)).
    60  		Expect(ResourceSyncStatusIs("ConfigMap", "cm-1", SyncStatusCodeSynced)).
    61  		Expect(ResourceHealthIs("ConfigMap", "cm-1", health.HealthStatusHealthy)).
    62  		Expect(ResourceSyncStatusIs("ConfigMap", "cm-2", SyncStatusCodeSynced)).
    63  		Expect(ResourceHealthIs("ConfigMap", "cm-2", health.HealthStatusHealthy)).
    64  		When().
    65  		Then().
    66  		And(func(app *Application) {
    67  			// check that the last transition time is updated
    68  			require.NotEqual(t, lastTransitionTime, app.Status.Health.LastTransitionTime.UTC().Format(time.RFC3339))
    69  		})
    70  }
    71  
    72  func TestOneProgressingDeploymentIsSucceededAndSynced(t *testing.T) {
    73  	Given(t).
    74  		Path("one-deployment").
    75  		When().
    76  		// make this deployment get stuck in progressing due to "invalidimagename"
    77  		PatchFile("deployment.yaml", `[
    78      {
    79          "op": "replace",
    80          "path": "/spec/template/spec/containers/0/image",
    81          "value": "alpine:ops!"
    82      }
    83  ]`).
    84  		CreateApp().
    85  		Sync().
    86  		Then().
    87  		Expect(OperationPhaseIs(OperationSucceeded)).
    88  		Expect(HealthIs(health.HealthStatusProgressing)).
    89  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
    90  		Expect(ResourceResultNumbering(1))
    91  }
    92  
    93  func TestDegradedDeploymentIsSucceededAndSynced(t *testing.T) {
    94  	Given(t).
    95  		Path("one-deployment").
    96  		When().
    97  		// make this deployment get stuck in progressing due to "invalidimagename"
    98  		PatchFile("deployment.yaml", `[
    99      {
   100          "op": "replace",
   101          "path": "/spec/progressDeadlineSeconds",
   102          "value": 1
   103      },
   104      {
   105          "op": "replace",
   106          "path": "/spec/template/spec/containers/0/image",
   107          "value": "alpine:ops!"
   108      }
   109  ]`).
   110  		CreateApp().
   111  		Sync().
   112  		Then().
   113  		Expect(OperationPhaseIs(OperationSucceeded)).
   114  		Expect(HealthIs(health.HealthStatusDegraded)).
   115  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   116  		Expect(ResourceResultNumbering(1))
   117  }
   118  
   119  // resources should be pruned in reverse of creation order(syncwaves order)
   120  func TestSyncPruneOrderWithSyncWaves(t *testing.T) {
   121  	ctx := Given(t).Timeout(60)
   122  
   123  	// remove finalizer to ensure proper cleanup if test fails at early stage
   124  	defer func() {
   125  		_, _ = RunCli("app", "patch-resource", ctx.AppQualifiedName(),
   126  			"--kind", "Pod",
   127  			"--resource-name", "pod-with-finalizers",
   128  			"--patch", `[{"op": "remove", "path": "/metadata/finalizers"}]`,
   129  			"--patch-type", "application/json-patch+json", "--all",
   130  		)
   131  	}()
   132  
   133  	ctx.Path("syncwaves-prune-order").
   134  		When().
   135  		CreateApp().
   136  		// creation order: sa & role -> rolebinding -> pod
   137  		Sync().
   138  		Wait().
   139  		Then().
   140  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   141  		Expect(HealthIs(health.HealthStatusHealthy)).
   142  		When().
   143  		// delete files to remove resources
   144  		DeleteFile("pod.yaml").
   145  		DeleteFile("rbac.yaml").
   146  		Refresh(RefreshTypeHard).
   147  		IgnoreErrors().
   148  		Then().
   149  		Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
   150  		When().
   151  		// prune order: pod -> rolebinding -> sa & role
   152  		Sync("--prune").
   153  		Wait().
   154  		Then().
   155  		Expect(OperationPhaseIs(OperationSucceeded)).
   156  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   157  		Expect(HealthIs(health.HealthStatusHealthy)).
   158  		Expect(NotPod(func(p corev1.Pod) bool { return p.Name == "pod-with-finalizers" })).
   159  		Expect(ResourceResultNumbering(4))
   160  }