func TestNamespaceController(t *testing.T) { cluster1 := NewCluster("cluster1", apiv1.ConditionTrue) cluster2 := NewCluster("cluster2", apiv1.ConditionTrue) ns1 := apiv1.Namespace{ ObjectMeta: apiv1.ObjectMeta{ Name: "test-namespace", SelfLink: "/api/v1/namespaces/test-namespace", }, Spec: apiv1.NamespaceSpec{ Finalizers: []apiv1.FinalizerName{apiv1.FinalizerKubernetes}, }, } fakeClient := &fakefedclientset.Clientset{} RegisterFakeList("clusters", &fakeClient.Fake, &federationapi.ClusterList{Items: []federationapi.Cluster{*cluster1}}) RegisterFakeList("namespaces", &fakeClient.Fake, &apiv1.NamespaceList{Items: []apiv1.Namespace{}}) namespaceWatch := RegisterFakeWatch("namespaces", &fakeClient.Fake) namespaceCreateChan := RegisterFakeCopyOnCreate("namespaces", &fakeClient.Fake, namespaceWatch) clusterWatch := RegisterFakeWatch("clusters", &fakeClient.Fake) cluster1Client := &fakekubeclientset.Clientset{} cluster1Watch := RegisterFakeWatch("namespaces", &cluster1Client.Fake) RegisterFakeList("namespaces", &cluster1Client.Fake, &apiv1.NamespaceList{Items: []apiv1.Namespace{}}) cluster1CreateChan := RegisterFakeCopyOnCreate("namespaces", &cluster1Client.Fake, cluster1Watch) // cluster1UpdateChan := RegisterFakeCopyOnUpdate("namespaces", &cluster1Client.Fake, cluster1Watch) cluster2Client := &fakekubeclientset.Clientset{} cluster2Watch := RegisterFakeWatch("namespaces", &cluster2Client.Fake) RegisterFakeList("namespaces", &cluster2Client.Fake, &apiv1.NamespaceList{Items: []apiv1.Namespace{}}) cluster2CreateChan := RegisterFakeCopyOnCreate("namespaces", &cluster2Client.Fake, cluster2Watch) RegisterFakeList("replicasets", &fakeClient.Fake, &extensionsv1.ReplicaSetList{Items: []extensionsv1.ReplicaSet{ { ObjectMeta: apiv1.ObjectMeta{ Name: "test-rs", Namespace: ns1.Namespace, }}}}) RegisterFakeList("secrets", &fakeClient.Fake, &apiv1.SecretList{Items: []apiv1.Secret{ { ObjectMeta: apiv1.ObjectMeta{ Name: "test-secret", Namespace: ns1.Namespace, }}}}) RegisterFakeList("services", &fakeClient.Fake, &apiv1.ServiceList{Items: []apiv1.Service{ { ObjectMeta: apiv1.ObjectMeta{ Name: "test-service", Namespace: ns1.Namespace, }}}}) nsDeleteChan := RegisterDelete(&fakeClient.Fake, "namespaces") rsDeleteChan := RegisterDeleteCollection(&fakeClient.Fake, "replicasets") serviceDeleteChan := RegisterDeleteCollection(&fakeClient.Fake, "services") secretDeleteChan := RegisterDeleteCollection(&fakeClient.Fake, "secrets") namespaceController := NewNamespaceController(fakeClient) informerClientFactory := func(cluster *federationapi.Cluster) (kubeclientset.Interface, error) { switch cluster.Name { case cluster1.Name: return cluster1Client, nil case cluster2.Name: return cluster2Client, nil default: return nil, fmt.Errorf("Unknown cluster") } } setClientFactory(namespaceController.namespaceFederatedInformer, informerClientFactory) namespaceController.clusterAvailableDelay = time.Second namespaceController.namespaceReviewDelay = 50 * time.Millisecond namespaceController.smallDelay = 20 * time.Millisecond namespaceController.updateTimeout = 5 * time.Second stop := make(chan struct{}) namespaceController.Run(stop) // Test add federated namespace. namespaceWatch.Add(&ns1) // Verify that the DeleteFromUnderlyingClusters finalizer is added to the namespace. // Note: finalize invokes the create action in Fake client. // TODO: Seems like a bug. Should invoke update. Fix it. updatedNamespace := GetNamespaceFromChan(namespaceCreateChan) assert.True(t, namespaceController.hasFinalizerFunc(updatedNamespace, deletionhelper.FinalizerDeleteFromUnderlyingClusters)) ns1 = *updatedNamespace // Verify that the namespace is created in underlying cluster1. createdNamespace := GetNamespaceFromChan(cluster1CreateChan) assert.NotNil(t, createdNamespace) assert.Equal(t, ns1.Name, createdNamespace.Name) // Wait for the namespace to appear in the informer store err := WaitForStoreUpdate( namespaceController.namespaceFederatedInformer.GetTargetStore(), cluster1.Name, ns1.Name, wait.ForeverTestTimeout) assert.Nil(t, err, "namespace should have appeared in the informer store") /* // TODO: Uncomment this once we have figured out why this is flaky. // Test update federated namespace. ns1.Annotations = map[string]string{ "A": "B", } namespaceWatch.Modify(&ns1) updatedNamespace = GetNamespaceFromChan(cluster1UpdateChan) assert.NotNil(t, updatedNamespace) assert.Equal(t, ns1.Name, updatedNamespace.Name) // assert.Contains(t, updatedNamespace.Annotations, "A") */ // Test add cluster clusterWatch.Add(cluster2) createdNamespace2 := GetNamespaceFromChan(cluster2CreateChan) assert.NotNil(t, createdNamespace2) assert.Equal(t, ns1.Name, createdNamespace2.Name) // assert.Contains(t, createdNamespace2.Annotations, "A") // Delete the namespace with orphan finalizer (let namespaces // in underlying clusters be as is). // TODO: Add a test without orphan finalizer. ns1.ObjectMeta.Finalizers = append(ns1.ObjectMeta.Finalizers, apiv1.FinalizerOrphan) ns1.DeletionTimestamp = &metav1.Time{Time: time.Now()} namespaceWatch.Modify(&ns1) assert.Equal(t, ns1.Name, GetStringFromChan(nsDeleteChan)) assert.Equal(t, "all", GetStringFromChan(rsDeleteChan)) assert.Equal(t, "all", GetStringFromChan(serviceDeleteChan)) assert.Equal(t, "all", GetStringFromChan(secretDeleteChan)) close(stop) }
func TestNamespaceController(t *testing.T) { cluster1 := NewCluster("cluster1", api_v1.ConditionTrue) cluster2 := NewCluster("cluster2", api_v1.ConditionTrue) ns1 := api_v1.Namespace{ ObjectMeta: api_v1.ObjectMeta{ Name: "test-namespace", SelfLink: "/api/v1/namespaces/test-namespace", }, } fakeClient := &fake_fedclientset.Clientset{} RegisterFakeList("clusters", &fakeClient.Fake, &federation_api.ClusterList{Items: []federation_api.Cluster{*cluster1}}) RegisterFakeList("namespaces", &fakeClient.Fake, &api_v1.NamespaceList{Items: []api_v1.Namespace{}}) namespaceWatch := RegisterFakeWatch("namespaces", &fakeClient.Fake) clusterWatch := RegisterFakeWatch("clusters", &fakeClient.Fake) cluster1Client := &fake_kubeclientset.Clientset{} cluster1Watch := RegisterFakeWatch("namespaces", &cluster1Client.Fake) RegisterFakeList("namespaces", &cluster1Client.Fake, &api_v1.NamespaceList{Items: []api_v1.Namespace{}}) cluster1CreateChan := RegisterFakeCopyOnCreate("namespaces", &cluster1Client.Fake, cluster1Watch) cluster1UpdateChan := RegisterFakeCopyOnUpdate("namespaces", &cluster1Client.Fake, cluster1Watch) cluster2Client := &fake_kubeclientset.Clientset{} cluster2Watch := RegisterFakeWatch("namespaces", &cluster2Client.Fake) RegisterFakeList("namespaces", &cluster2Client.Fake, &api_v1.NamespaceList{Items: []api_v1.Namespace{}}) cluster2CreateChan := RegisterFakeCopyOnCreate("namespaces", &cluster2Client.Fake, cluster2Watch) RegisterFakeList("replicasets", &fakeClient.Fake, &extensionsv1.ReplicaSetList{Items: []extensionsv1.ReplicaSet{ { ObjectMeta: api_v1.ObjectMeta{ Name: "test-rs", Namespace: ns1.Namespace, }}}}) RegisterFakeList("secrets", &fakeClient.Fake, &api_v1.SecretList{Items: []api_v1.Secret{ { ObjectMeta: api_v1.ObjectMeta{ Name: "test-secret", Namespace: ns1.Namespace, }}}}) RegisterFakeList("services", &fakeClient.Fake, &api_v1.ServiceList{Items: []api_v1.Service{ { ObjectMeta: api_v1.ObjectMeta{ Name: "test-service", Namespace: ns1.Namespace, }}}}) nsDeleteChan := RegisterDelete(&fakeClient.Fake, "namespaces") rsDeleteChan := RegisterDeleteCollection(&fakeClient.Fake, "replicasets") serviceDeleteChan := RegisterDeleteCollection(&fakeClient.Fake, "services") secretDeleteChan := RegisterDeleteCollection(&fakeClient.Fake, "secrets") namespaceController := NewNamespaceController(fakeClient) informer := ToFederatedInformerForTestOnly(namespaceController.namespaceFederatedInformer) informer.SetClientFactory(func(cluster *federation_api.Cluster) (kubeclientset.Interface, error) { switch cluster.Name { case cluster1.Name: return cluster1Client, nil case cluster2.Name: return cluster2Client, nil default: return nil, fmt.Errorf("Unknown cluster") } }) namespaceController.clusterAvailableDelay = time.Second namespaceController.namespaceReviewDelay = 50 * time.Millisecond namespaceController.smallDelay = 20 * time.Millisecond namespaceController.updateTimeout = 5 * time.Second stop := make(chan struct{}) namespaceController.Run(stop) // Test add federated namespace. namespaceWatch.Add(&ns1) createdNamespace := GetNamespaceFromChan(cluster1CreateChan) assert.NotNil(t, createdNamespace) assert.Equal(t, ns1.Name, createdNamespace.Name) // Test update federated namespace. ns1.Annotations = map[string]string{ "A": "B", } namespaceWatch.Modify(&ns1) updatedNamespace := GetNamespaceFromChan(cluster1UpdateChan) assert.NotNil(t, updatedNamespace) assert.Equal(t, ns1.Name, updatedNamespace.Name) // assert.Contains(t, updatedNamespace.Annotations, "A") // Test add cluster clusterWatch.Add(cluster2) createdNamespace2 := GetNamespaceFromChan(cluster2CreateChan) assert.NotNil(t, createdNamespace2) assert.Equal(t, ns1.Name, createdNamespace2.Name) // assert.Contains(t, createdNamespace2.Annotations, "A") ns1.DeletionTimestamp = &unversioned.Time{Time: time.Now()} namespaceWatch.Modify(&ns1) assert.Equal(t, ns1.Name, GetStringFromChan(nsDeleteChan)) assert.Equal(t, "all", GetStringFromChan(rsDeleteChan)) assert.Equal(t, "all", GetStringFromChan(serviceDeleteChan)) assert.Equal(t, "all", GetStringFromChan(secretDeleteChan)) close(stop) }