github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/controllers/requeue_after_test.go (about) 1 package controllers 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 corev1 "k8s.io/api/core/v1" 10 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 11 "k8s.io/apimachinery/pkg/runtime" 12 "k8s.io/apimachinery/pkg/runtime/schema" 13 dynfake "k8s.io/client-go/dynamic/fake" 14 kubefake "k8s.io/client-go/kubernetes/fake" 15 "k8s.io/client-go/tools/record" 16 "sigs.k8s.io/controller-runtime/pkg/client/fake" 17 18 "github.com/argoproj/argo-cd/v3/applicationset/generators" 19 appsetmetrics "github.com/argoproj/argo-cd/v3/applicationset/metrics" 20 "github.com/argoproj/argo-cd/v3/applicationset/services/mocks" 21 argov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" 22 ) 23 24 func TestRequeueAfter(t *testing.T) { 25 mockServer := &mocks.Repos{} 26 ctx := t.Context() 27 scheme := runtime.NewScheme() 28 err := argov1alpha1.AddToScheme(scheme) 29 require.NoError(t, err) 30 gvrToListKind := map[schema.GroupVersionResource]string{{ 31 Group: "mallard.io", 32 Version: "v1", 33 Resource: "ducks", 34 }: "DuckList"} 35 appClientset := kubefake.NewSimpleClientset() 36 k8sClient := fake.NewClientBuilder().Build() 37 duckType := &unstructured.Unstructured{ 38 Object: map[string]any{ 39 "apiVersion": "v2quack", 40 "kind": "Duck", 41 "metadata": map[string]any{ 42 "name": "mightyduck", 43 "namespace": "namespace", 44 "labels": map[string]any{"duck": "all-species"}, 45 }, 46 "status": map[string]any{ 47 "decisions": []any{ 48 map[string]any{ 49 "clusterName": "staging-01", 50 }, 51 map[string]any{ 52 "clusterName": "production-01", 53 }, 54 }, 55 }, 56 }, 57 } 58 fakeDynClient := dynfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), gvrToListKind, duckType) 59 scmConfig := generators.NewSCMConfig("", []string{""}, true, true, nil, true) 60 terminalGenerators := map[string]generators.Generator{ 61 "List": generators.NewListGenerator(), 62 "Clusters": generators.NewClusterGenerator(ctx, k8sClient, appClientset, "argocd"), 63 "Git": generators.NewGitGenerator(mockServer, "namespace"), 64 "SCMProvider": generators.NewSCMProviderGenerator(fake.NewClientBuilder().WithObjects(&corev1.Secret{}).Build(), scmConfig), 65 "ClusterDecisionResource": generators.NewDuckTypeGenerator(ctx, fakeDynClient, appClientset, "argocd"), 66 "PullRequest": generators.NewPullRequestGenerator(k8sClient, scmConfig), 67 } 68 69 nestedGenerators := map[string]generators.Generator{ 70 "List": terminalGenerators["List"], 71 "Clusters": terminalGenerators["Clusters"], 72 "Git": terminalGenerators["Git"], 73 "SCMProvider": terminalGenerators["SCMProvider"], 74 "ClusterDecisionResource": terminalGenerators["ClusterDecisionResource"], 75 "PullRequest": terminalGenerators["PullRequest"], 76 "Matrix": generators.NewMatrixGenerator(terminalGenerators), 77 "Merge": generators.NewMergeGenerator(terminalGenerators), 78 } 79 80 topLevelGenerators := map[string]generators.Generator{ 81 "List": terminalGenerators["List"], 82 "Clusters": terminalGenerators["Clusters"], 83 "Git": terminalGenerators["Git"], 84 "SCMProvider": terminalGenerators["SCMProvider"], 85 "ClusterDecisionResource": terminalGenerators["ClusterDecisionResource"], 86 "PullRequest": terminalGenerators["PullRequest"], 87 "Matrix": generators.NewMatrixGenerator(nestedGenerators), 88 "Merge": generators.NewMergeGenerator(nestedGenerators), 89 } 90 91 client := fake.NewClientBuilder().WithScheme(scheme).Build() 92 metrics := appsetmetrics.NewFakeAppsetMetrics() 93 r := ApplicationSetReconciler{ 94 Client: client, 95 Scheme: scheme, 96 Recorder: record.NewFakeRecorder(0), 97 Generators: topLevelGenerators, 98 Metrics: metrics, 99 } 100 101 type args struct { 102 appset *argov1alpha1.ApplicationSet 103 requeueAfterOverride string 104 } 105 tests := []struct { 106 name string 107 args args 108 want time.Duration 109 wantErr assert.ErrorAssertionFunc 110 }{ 111 {name: "Cluster", args: args{ 112 appset: &argov1alpha1.ApplicationSet{ 113 Spec: argov1alpha1.ApplicationSetSpec{ 114 Generators: []argov1alpha1.ApplicationSetGenerator{{Clusters: &argov1alpha1.ClusterGenerator{}}}, 115 }, 116 }, requeueAfterOverride: "", 117 }, want: generators.NoRequeueAfter, wantErr: assert.NoError}, 118 {name: "ClusterMergeNested", args: args{&argov1alpha1.ApplicationSet{ 119 Spec: argov1alpha1.ApplicationSetSpec{ 120 Generators: []argov1alpha1.ApplicationSetGenerator{ 121 {Clusters: &argov1alpha1.ClusterGenerator{}}, 122 {Merge: &argov1alpha1.MergeGenerator{ 123 Generators: []argov1alpha1.ApplicationSetNestedGenerator{ 124 { 125 Clusters: &argov1alpha1.ClusterGenerator{}, 126 Git: &argov1alpha1.GitGenerator{}, 127 }, 128 }, 129 }}, 130 }, 131 }, 132 }, ""}, want: generators.DefaultRequeueAfter, wantErr: assert.NoError}, 133 {name: "ClusterMatrixNested", args: args{&argov1alpha1.ApplicationSet{ 134 Spec: argov1alpha1.ApplicationSetSpec{ 135 Generators: []argov1alpha1.ApplicationSetGenerator{ 136 {Clusters: &argov1alpha1.ClusterGenerator{}}, 137 {Matrix: &argov1alpha1.MatrixGenerator{ 138 Generators: []argov1alpha1.ApplicationSetNestedGenerator{ 139 { 140 Clusters: &argov1alpha1.ClusterGenerator{}, 141 Git: &argov1alpha1.GitGenerator{}, 142 }, 143 }, 144 }}, 145 }, 146 }, 147 }, ""}, want: generators.DefaultRequeueAfter, wantErr: assert.NoError}, 148 {name: "ListGenerator", args: args{appset: &argov1alpha1.ApplicationSet{ 149 Spec: argov1alpha1.ApplicationSetSpec{ 150 Generators: []argov1alpha1.ApplicationSetGenerator{{List: &argov1alpha1.ListGenerator{}}}, 151 }, 152 }}, want: generators.NoRequeueAfter, wantErr: assert.NoError}, 153 {name: "DuckGenerator", args: args{appset: &argov1alpha1.ApplicationSet{ 154 Spec: argov1alpha1.ApplicationSetSpec{ 155 Generators: []argov1alpha1.ApplicationSetGenerator{{ClusterDecisionResource: &argov1alpha1.DuckTypeGenerator{}}}, 156 }, 157 }}, want: generators.DefaultRequeueAfter, wantErr: assert.NoError}, 158 {name: "OverrideRequeueDuck", args: args{ 159 appset: &argov1alpha1.ApplicationSet{ 160 Spec: argov1alpha1.ApplicationSetSpec{ 161 Generators: []argov1alpha1.ApplicationSetGenerator{{ClusterDecisionResource: &argov1alpha1.DuckTypeGenerator{}}}, 162 }, 163 }, requeueAfterOverride: "1h", 164 }, want: 1 * time.Hour, wantErr: assert.NoError}, 165 {name: "OverrideRequeueGit", args: args{&argov1alpha1.ApplicationSet{ 166 Spec: argov1alpha1.ApplicationSetSpec{ 167 Generators: []argov1alpha1.ApplicationSetGenerator{ 168 {Git: &argov1alpha1.GitGenerator{}}, 169 }, 170 }, 171 }, "1h"}, want: 1 * time.Hour, wantErr: assert.NoError}, 172 {name: "OverrideRequeueMatrix", args: args{&argov1alpha1.ApplicationSet{ 173 Spec: argov1alpha1.ApplicationSetSpec{ 174 Generators: []argov1alpha1.ApplicationSetGenerator{ 175 {Clusters: &argov1alpha1.ClusterGenerator{}}, 176 {Merge: &argov1alpha1.MergeGenerator{ 177 Generators: []argov1alpha1.ApplicationSetNestedGenerator{ 178 { 179 Clusters: &argov1alpha1.ClusterGenerator{}, 180 Git: &argov1alpha1.GitGenerator{}, 181 }, 182 }, 183 }}, 184 }, 185 }, 186 }, "5m"}, want: 5 * time.Minute, wantErr: assert.NoError}, 187 {name: "OverrideRequeueMerge", args: args{&argov1alpha1.ApplicationSet{ 188 Spec: argov1alpha1.ApplicationSetSpec{ 189 Generators: []argov1alpha1.ApplicationSetGenerator{ 190 {Clusters: &argov1alpha1.ClusterGenerator{}}, 191 {Merge: &argov1alpha1.MergeGenerator{ 192 Generators: []argov1alpha1.ApplicationSetNestedGenerator{ 193 { 194 Clusters: &argov1alpha1.ClusterGenerator{}, 195 Git: &argov1alpha1.GitGenerator{}, 196 }, 197 }, 198 }}, 199 }, 200 }, 201 }, "12s"}, want: 12 * time.Second, wantErr: assert.NoError}, 202 } 203 for _, tt := range tests { 204 t.Run(tt.name, func(t *testing.T) { 205 t.Setenv("ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER", tt.args.requeueAfterOverride) 206 assert.Equalf(t, tt.want, r.getMinRequeueAfter(tt.args.appset), "getMinRequeueAfter(%v)", tt.args.appset) 207 }) 208 } 209 }