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

     1  package e2e
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
     7  
     8  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     9  
    10  	"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
    11  	. "github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets"
    12  	"github.com/argoproj/argo-cd/v3/test/e2e/fixture/applicationsets/utils"
    13  
    14  	"github.com/argoproj/argo-cd/v3/pkg/apis/application"
    15  )
    16  
    17  var tenSec = int64(10)
    18  
    19  func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) {
    20  	externalNamespace := string(utils.ArgoCDExternalNamespace)
    21  
    22  	expectedApp := v1alpha1.Application{
    23  		TypeMeta: metav1.TypeMeta{
    24  			Kind:       "Application",
    25  			APIVersion: "argoproj.io/v1alpha1",
    26  		},
    27  		ObjectMeta: metav1.ObjectMeta{
    28  			Name:       "cluster1-guestbook",
    29  			Namespace:  externalNamespace,
    30  			Finalizers: []string{v1alpha1.ResourcesFinalizerName},
    31  		},
    32  		Spec: v1alpha1.ApplicationSpec{
    33  			Project: "default",
    34  			Source: &v1alpha1.ApplicationSource{
    35  				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
    36  				TargetRevision: "HEAD",
    37  				Path:           "guestbook",
    38  			},
    39  			Destination: v1alpha1.ApplicationDestination{
    40  				Name:      "cluster1",
    41  				Namespace: "guestbook",
    42  			},
    43  		},
    44  	}
    45  
    46  	var expectedAppNewNamespace *v1alpha1.Application
    47  	var expectedAppNewMetadata *v1alpha1.Application
    48  
    49  	clusterList := []any{
    50  		map[string]any{
    51  			"clusterName": "cluster1",
    52  			"reason":      "argotest",
    53  		},
    54  	}
    55  
    56  	Given(t).
    57  		// Create a ClusterGenerator-based ApplicationSet
    58  		When().
    59  		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
    60  		CreatePlacementRoleAndRoleBinding().
    61  		CreatePlacementDecisionConfigMap("my-configmap").
    62  		CreatePlacementDecision("my-placementdecision").
    63  		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
    64  		CreateNamespace(externalNamespace).
    65  		SwitchToExternalNamespace(utils.ArgoCDExternalNamespace).
    66  		Create(v1alpha1.ApplicationSet{
    67  			ObjectMeta: metav1.ObjectMeta{
    68  				Name: "simple-cluster-generator",
    69  			},
    70  			Spec: v1alpha1.ApplicationSetSpec{
    71  				Template: v1alpha1.ApplicationSetTemplate{
    72  					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
    73  					Spec: v1alpha1.ApplicationSpec{
    74  						Project: "default",
    75  						Source: &v1alpha1.ApplicationSource{
    76  							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
    77  							TargetRevision: "HEAD",
    78  							Path:           "guestbook",
    79  						},
    80  						Destination: v1alpha1.ApplicationDestination{
    81  							Name: "{{clusterName}}",
    82  							// Server:    "{{server}}",
    83  							Namespace: "guestbook",
    84  						},
    85  					},
    86  				},
    87  				Generators: []v1alpha1.ApplicationSetGenerator{
    88  					{
    89  						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
    90  							ConfigMapRef: "my-configmap",
    91  							Name:         "my-placementdecision",
    92  						},
    93  					},
    94  				},
    95  			},
    96  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})).
    97  
    98  		// Update the ApplicationSet template namespace, and verify it updates the Applications
    99  		When().
   100  		And(func() {
   101  			expectedAppNewNamespace = expectedApp.DeepCopy()
   102  			expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2"
   103  		}).
   104  		Update(func(appset *v1alpha1.ApplicationSet) {
   105  			appset.Spec.Template.Spec.Destination.Namespace = "guestbook2"
   106  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})).
   107  
   108  		// Update the metadata fields in the appset template, and make sure it propagates to the apps
   109  		When().
   110  		And(func() {
   111  			expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
   112  			expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
   113  			expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{
   114  				"label-key": "label-value",
   115  			}
   116  		}).
   117  		Update(func(appset *v1alpha1.ApplicationSet) {
   118  			appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
   119  			appset.Spec.Template.Labels = map[string]string{
   120  				"label-key": "label-value",
   121  			}
   122  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})).
   123  
   124  		// Delete the ApplicationSet, and verify it deletes the Applications
   125  		When().
   126  		Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace}))
   127  }
   128  
   129  func TestSimpleClusterDecisionResourceGenerator(t *testing.T) {
   130  	expectedApp := v1alpha1.Application{
   131  		TypeMeta: metav1.TypeMeta{
   132  			Kind:       application.ApplicationKind,
   133  			APIVersion: "argoproj.io/v1alpha1",
   134  		},
   135  		ObjectMeta: metav1.ObjectMeta{
   136  			Name:       "cluster1-guestbook",
   137  			Namespace:  fixture.TestNamespace(),
   138  			Finalizers: []string{v1alpha1.ResourcesFinalizerName},
   139  		},
   140  		Spec: v1alpha1.ApplicationSpec{
   141  			Project: "default",
   142  			Source: &v1alpha1.ApplicationSource{
   143  				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
   144  				TargetRevision: "HEAD",
   145  				Path:           "guestbook",
   146  			},
   147  			Destination: v1alpha1.ApplicationDestination{
   148  				Name:      "cluster1",
   149  				Namespace: "guestbook",
   150  			},
   151  		},
   152  	}
   153  
   154  	var expectedAppNewNamespace *v1alpha1.Application
   155  	var expectedAppNewMetadata *v1alpha1.Application
   156  
   157  	clusterList := []any{
   158  		map[string]any{
   159  			"clusterName": "cluster1",
   160  			"reason":      "argotest",
   161  		},
   162  	}
   163  
   164  	Given(t).
   165  		// Create a ClusterGenerator-based ApplicationSet
   166  		When().
   167  		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
   168  		CreatePlacementRoleAndRoleBinding().
   169  		CreatePlacementDecisionConfigMap("my-configmap").
   170  		CreatePlacementDecision("my-placementdecision").
   171  		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
   172  		Create(v1alpha1.ApplicationSet{
   173  			ObjectMeta: metav1.ObjectMeta{
   174  				Name: "simple-cluster-generator",
   175  			},
   176  			Spec: v1alpha1.ApplicationSetSpec{
   177  				Template: v1alpha1.ApplicationSetTemplate{
   178  					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
   179  					Spec: v1alpha1.ApplicationSpec{
   180  						Project: "default",
   181  						Source: &v1alpha1.ApplicationSource{
   182  							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
   183  							TargetRevision: "HEAD",
   184  							Path:           "guestbook",
   185  						},
   186  						Destination: v1alpha1.ApplicationDestination{
   187  							Name: "{{clusterName}}",
   188  							// Server:    "{{server}}",
   189  							Namespace: "guestbook",
   190  						},
   191  					},
   192  				},
   193  				Generators: []v1alpha1.ApplicationSetGenerator{
   194  					{
   195  						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
   196  							ConfigMapRef: "my-configmap",
   197  							Name:         "my-placementdecision",
   198  						},
   199  					},
   200  				},
   201  			},
   202  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedApp})).
   203  
   204  		// Update the ApplicationSet template namespace, and verify it updates the Applications
   205  		When().
   206  		And(func() {
   207  			expectedAppNewNamespace = expectedApp.DeepCopy()
   208  			expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2"
   209  		}).
   210  		Update(func(appset *v1alpha1.ApplicationSet) {
   211  			appset.Spec.Template.Spec.Destination.Namespace = "guestbook2"
   212  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewNamespace})).
   213  
   214  		// Update the metadata fields in the appset template, and make sure it propagates to the apps
   215  		When().
   216  		And(func() {
   217  			expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy()
   218  			expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"}
   219  			expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"}
   220  		}).
   221  		Update(func(appset *v1alpha1.ApplicationSet) {
   222  			appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"}
   223  			appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"}
   224  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{*expectedAppNewMetadata})).
   225  
   226  		// Delete the ApplicationSet, and verify it deletes the Applications
   227  		When().
   228  		Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{*expectedAppNewNamespace}))
   229  }
   230  
   231  func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) {
   232  	expectedAppTemplate := v1alpha1.Application{
   233  		TypeMeta: metav1.TypeMeta{
   234  			Kind:       application.ApplicationKind,
   235  			APIVersion: "argoproj.io/v1alpha1",
   236  		},
   237  		ObjectMeta: metav1.ObjectMeta{
   238  			Name:       "{{name}}-guestbook",
   239  			Namespace:  fixture.TestNamespace(),
   240  			Finalizers: []string{v1alpha1.ResourcesFinalizerName},
   241  		},
   242  		Spec: v1alpha1.ApplicationSpec{
   243  			Project: "default",
   244  			Source: &v1alpha1.ApplicationSource{
   245  				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
   246  				TargetRevision: "HEAD",
   247  				Path:           "guestbook",
   248  			},
   249  			Destination: v1alpha1.ApplicationDestination{
   250  				Name:      "{{clusterName}}",
   251  				Namespace: "guestbook",
   252  			},
   253  		},
   254  	}
   255  
   256  	expectedAppCluster1 := *expectedAppTemplate.DeepCopy()
   257  	expectedAppCluster1.Spec.Destination.Name = "cluster1"
   258  	expectedAppCluster1.Name = "cluster1-guestbook"
   259  
   260  	expectedAppCluster2 := *expectedAppTemplate.DeepCopy()
   261  	expectedAppCluster2.Spec.Destination.Name = "cluster2"
   262  	expectedAppCluster2.Name = "cluster2-guestbook"
   263  
   264  	clusterList := []any{
   265  		map[string]any{
   266  			"clusterName": "cluster1",
   267  			"reason":      "argotest",
   268  		},
   269  		map[string]any{
   270  			"clusterName": "cluster2",
   271  			"reason":      "argotest",
   272  		},
   273  	}
   274  
   275  	Given(t).
   276  		// Create a ClusterGenerator-based ApplicationSet
   277  		When().
   278  		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
   279  		CreatePlacementRoleAndRoleBinding().
   280  		CreatePlacementDecisionConfigMap("my-configmap").
   281  		CreatePlacementDecision("my-placementdecision").
   282  		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
   283  		Create(v1alpha1.ApplicationSet{
   284  			ObjectMeta: metav1.ObjectMeta{
   285  				Name: "simple-cluster-generator",
   286  			},
   287  			Spec: v1alpha1.ApplicationSetSpec{
   288  				Template: v1alpha1.ApplicationSetTemplate{
   289  					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
   290  					Spec: v1alpha1.ApplicationSpec{
   291  						Project: "default",
   292  						Source: &v1alpha1.ApplicationSource{
   293  							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
   294  							TargetRevision: "HEAD",
   295  							Path:           "guestbook",
   296  						},
   297  						Destination: v1alpha1.ApplicationDestination{
   298  							Name: "{{clusterName}}",
   299  							// Server:    "{{server}}",
   300  							Namespace: "guestbook",
   301  						},
   302  					},
   303  				},
   304  				Generators: []v1alpha1.ApplicationSetGenerator{
   305  					{
   306  						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
   307  							ConfigMapRef:        "my-configmap",
   308  							Name:                "my-placementdecision",
   309  							RequeueAfterSeconds: &tenSec,
   310  						},
   311  					},
   312  				},
   313  			},
   314  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})).
   315  
   316  		// Update the ApplicationSet template namespace, and verify it updates the Applications
   317  		When().
   318  		CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
   319  		Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})).
   320  
   321  		// Delete the ApplicationSet, and verify it deletes the Applications
   322  		When().
   323  		Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2}))
   324  }
   325  
   326  func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing.T) {
   327  	expectedAppTemplate := v1alpha1.Application{
   328  		TypeMeta: metav1.TypeMeta{
   329  			Kind:       application.ApplicationKind,
   330  			APIVersion: "argoproj.io/v1alpha1",
   331  		},
   332  		ObjectMeta: metav1.ObjectMeta{
   333  			Name:       "{{name}}-guestbook",
   334  			Namespace:  fixture.TestNamespace(),
   335  			Finalizers: []string{v1alpha1.ResourcesFinalizerName},
   336  		},
   337  		Spec: v1alpha1.ApplicationSpec{
   338  			Project: "default",
   339  			Source: &v1alpha1.ApplicationSource{
   340  				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
   341  				TargetRevision: "HEAD",
   342  				Path:           "guestbook",
   343  			},
   344  			Destination: v1alpha1.ApplicationDestination{
   345  				Name:      "{{name}}",
   346  				Namespace: "guestbook",
   347  			},
   348  		},
   349  	}
   350  
   351  	expectedAppCluster1 := *expectedAppTemplate.DeepCopy()
   352  	expectedAppCluster1.Spec.Destination.Name = "cluster1"
   353  	expectedAppCluster1.Name = "cluster1-guestbook"
   354  
   355  	expectedAppCluster2 := *expectedAppTemplate.DeepCopy()
   356  	expectedAppCluster2.Spec.Destination.Name = "cluster2"
   357  	expectedAppCluster2.Name = "cluster2-guestbook"
   358  
   359  	clusterList := []any{
   360  		map[string]any{
   361  			"clusterName": "cluster1",
   362  			"reason":      "argotest",
   363  		},
   364  		map[string]any{
   365  			"clusterName": "cluster2",
   366  			"reason":      "argotest",
   367  		},
   368  	}
   369  
   370  	Given(t).
   371  		// Create a ClusterGenerator-based ApplicationSet
   372  		When().
   373  		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
   374  		CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
   375  		CreatePlacementRoleAndRoleBinding().
   376  		CreatePlacementDecisionConfigMap("my-configmap").
   377  		CreatePlacementDecision("my-placementdecision").
   378  		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
   379  		Create(v1alpha1.ApplicationSet{
   380  			ObjectMeta: metav1.ObjectMeta{
   381  				Name: "simple-cluster-generator",
   382  			},
   383  			Spec: v1alpha1.ApplicationSetSpec{
   384  				Template: v1alpha1.ApplicationSetTemplate{
   385  					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
   386  					Spec: v1alpha1.ApplicationSpec{
   387  						Project: "default",
   388  						Source: &v1alpha1.ApplicationSource{
   389  							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
   390  							TargetRevision: "HEAD",
   391  							Path:           "guestbook",
   392  						},
   393  						Destination: v1alpha1.ApplicationDestination{
   394  							Name: "{{clusterName}}",
   395  							// Server:    "{{server}}",
   396  							Namespace: "guestbook",
   397  						},
   398  					},
   399  				},
   400  				Generators: []v1alpha1.ApplicationSetGenerator{
   401  					{
   402  						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
   403  							ConfigMapRef:        "my-configmap",
   404  							Name:                "my-placementdecision",
   405  							RequeueAfterSeconds: &tenSec,
   406  						},
   407  					},
   408  				},
   409  			},
   410  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})).
   411  
   412  		// Update the ApplicationSet template namespace, and verify it updates the Applications
   413  		When().
   414  		DeleteClusterSecret("my-secret2").
   415  		Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})).
   416  		Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster2})).
   417  
   418  		// Delete the ApplicationSet, and verify it deletes the Applications
   419  		When().
   420  		Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster1}))
   421  }
   422  
   423  func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *testing.T) {
   424  	expectedAppTemplate := v1alpha1.Application{
   425  		TypeMeta: metav1.TypeMeta{
   426  			Kind:       application.ApplicationKind,
   427  			APIVersion: "argoproj.io/v1alpha1",
   428  		},
   429  		ObjectMeta: metav1.ObjectMeta{
   430  			Name:       "{{name}}-guestbook",
   431  			Namespace:  fixture.TestNamespace(),
   432  			Finalizers: []string{v1alpha1.ResourcesFinalizerName},
   433  		},
   434  		Spec: v1alpha1.ApplicationSpec{
   435  			Project: "default",
   436  			Source: &v1alpha1.ApplicationSource{
   437  				RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
   438  				TargetRevision: "HEAD",
   439  				Path:           "guestbook",
   440  			},
   441  			Destination: v1alpha1.ApplicationDestination{
   442  				Name:      "{{name}}",
   443  				Namespace: "guestbook",
   444  			},
   445  		},
   446  	}
   447  
   448  	expectedAppCluster1 := *expectedAppTemplate.DeepCopy()
   449  	expectedAppCluster1.Spec.Destination.Name = "cluster1"
   450  	expectedAppCluster1.Name = "cluster1-guestbook"
   451  
   452  	expectedAppCluster2 := *expectedAppTemplate.DeepCopy()
   453  	expectedAppCluster2.Spec.Destination.Name = "cluster2"
   454  	expectedAppCluster2.Name = "cluster2-guestbook"
   455  
   456  	clusterList := []any{
   457  		map[string]any{
   458  			"clusterName": "cluster1",
   459  			"reason":      "argotest",
   460  		},
   461  		map[string]any{
   462  			"clusterName": "cluster2",
   463  			"reason":      "argotest",
   464  		},
   465  	}
   466  
   467  	clusterListSmall := []any{
   468  		map[string]any{
   469  			"clusterName": "cluster1",
   470  			"reason":      "argotest",
   471  		},
   472  	}
   473  
   474  	Given(t).
   475  		// Create a ClusterGenerator-based ApplicationSet
   476  		When().
   477  		CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc").
   478  		CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc").
   479  		CreatePlacementRoleAndRoleBinding().
   480  		CreatePlacementDecisionConfigMap("my-configmap").
   481  		CreatePlacementDecision("my-placementdecision").
   482  		StatusUpdatePlacementDecision("my-placementdecision", clusterList).
   483  		Create(v1alpha1.ApplicationSet{
   484  			ObjectMeta: metav1.ObjectMeta{
   485  				Name: "simple-cluster-generator",
   486  			},
   487  			Spec: v1alpha1.ApplicationSetSpec{
   488  				Template: v1alpha1.ApplicationSetTemplate{
   489  					ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"},
   490  					Spec: v1alpha1.ApplicationSpec{
   491  						Project: "default",
   492  						Source: &v1alpha1.ApplicationSource{
   493  							RepoURL:        "https://github.com/argoproj/argocd-example-apps.git",
   494  							TargetRevision: "HEAD",
   495  							Path:           "guestbook",
   496  						},
   497  						Destination: v1alpha1.ApplicationDestination{
   498  							Name: "{{clusterName}}",
   499  							// Server:    "{{server}}",
   500  							Namespace: "guestbook",
   501  						},
   502  					},
   503  				},
   504  				Generators: []v1alpha1.ApplicationSetGenerator{
   505  					{
   506  						ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{
   507  							ConfigMapRef:        "my-configmap",
   508  							Name:                "my-placementdecision",
   509  							RequeueAfterSeconds: &tenSec,
   510  						},
   511  					},
   512  				},
   513  			},
   514  		}).Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1, expectedAppCluster2})).
   515  
   516  		// Update the ApplicationSet template namespace, and verify it updates the Applications
   517  		When().
   518  		StatusUpdatePlacementDecision("my-placementdecision", clusterListSmall).
   519  		Then().Expect(ApplicationsExist([]v1alpha1.Application{expectedAppCluster1})).
   520  		Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster2})).
   521  
   522  		// Delete the ApplicationSet, and verify it deletes the Applications
   523  		When().
   524  		Delete().Then().Expect(ApplicationsDoNotExist([]v1alpha1.Application{expectedAppCluster1}))
   525  }