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  }