func TestDaemonSetController(t *testing.T) {
	cluster1 := NewCluster("cluster1", api_v1.ConditionTrue)
	cluster2 := NewCluster("cluster2", api_v1.ConditionTrue)

	fakeClient := &fake_fedclientset.Clientset{}
	RegisterFakeList("clusters", &fakeClient.Fake, &federation_api.ClusterList{Items: []federation_api.Cluster{*cluster1}})
	RegisterFakeList("daemonsets", &fakeClient.Fake, &extensionsv1.DaemonSetList{Items: []extensionsv1.DaemonSet{}})
	daemonsetWatch := RegisterFakeWatch("daemonsets", &fakeClient.Fake)
	clusterWatch := RegisterFakeWatch("clusters", &fakeClient.Fake)

	cluster1Client := &fake_kubeclientset.Clientset{}
	cluster1Watch := RegisterFakeWatch("daemonsets", &cluster1Client.Fake)
	RegisterFakeList("daemonsets", &cluster1Client.Fake, &extensionsv1.DaemonSetList{Items: []extensionsv1.DaemonSet{}})
	cluster1CreateChan := RegisterFakeCopyOnCreate("daemonsets", &cluster1Client.Fake, cluster1Watch)
	cluster1UpdateChan := RegisterFakeCopyOnUpdate("daemonsets", &cluster1Client.Fake, cluster1Watch)

	cluster2Client := &fake_kubeclientset.Clientset{}
	cluster2Watch := RegisterFakeWatch("daemonsets", &cluster2Client.Fake)
	RegisterFakeList("daemonsets", &cluster2Client.Fake, &extensionsv1.DaemonSetList{Items: []extensionsv1.DaemonSet{}})
	cluster2CreateChan := RegisterFakeCopyOnCreate("daemonsets", &cluster2Client.Fake, cluster2Watch)

	daemonsetController := NewDaemonSetController(fakeClient)
	informer := ToFederatedInformerForTestOnly(daemonsetController.daemonsetFederatedInformer)
	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")
		}
	})

	daemonsetController.clusterAvailableDelay = time.Second
	daemonsetController.daemonsetReviewDelay = 50 * time.Millisecond
	daemonsetController.smallDelay = 20 * time.Millisecond
	daemonsetController.updateTimeout = 5 * time.Second

	stop := make(chan struct{})
	daemonsetController.Run(stop)

	daemonset1 := extensionsv1.DaemonSet{
		ObjectMeta: api_v1.ObjectMeta{
			Name:      "test-daemonset",
			Namespace: "ns",
			SelfLink:  "/api/v1/namespaces/ns/daemonsets/test-daemonset",
		},
		Spec: extensionsv1.DaemonSetSpec{
			Selector: &extensionsv1.LabelSelector{
				MatchLabels: make(map[string]string),
			},
		},
	}

	// Test add federated daemonset.
	daemonsetWatch.Add(&daemonset1)
	createdDaemonSet := GetDaemonSetFromChan(cluster1CreateChan)
	assert.NotNil(t, createdDaemonSet)
	assert.Equal(t, daemonset1.Namespace, createdDaemonSet.Namespace)
	assert.Equal(t, daemonset1.Name, createdDaemonSet.Name)
	assert.True(t, daemonsetsEqual(daemonset1, *createdDaemonSet))

	// Wait for the daemonset to appear in the informer store
	err := WaitForStoreUpdate(
		daemonsetController.daemonsetFederatedInformer.GetTargetStore(),
		cluster1.Name, getDaemonSetKey(daemonset1.Namespace, daemonset1.Name), wait.ForeverTestTimeout)
	assert.Nil(t, err, "daemonset should have appeared in the informer store")

	// Test update federated daemonset.
	daemonset1.Annotations = map[string]string{
		"A": "B",
	}
	daemonsetWatch.Modify(&daemonset1)
	updatedDaemonSet := GetDaemonSetFromChan(cluster1UpdateChan)
	assert.NotNil(t, updatedDaemonSet)
	assert.Equal(t, daemonset1.Name, updatedDaemonSet.Name)
	assert.Equal(t, daemonset1.Namespace, updatedDaemonSet.Namespace)
	assert.True(t, daemonsetsEqual(daemonset1, *updatedDaemonSet))

	// Test update federated daemonset.
	daemonset1.Spec.Template.Name = "TEST"
	daemonsetWatch.Modify(&daemonset1)
	updatedDaemonSet = GetDaemonSetFromChan(cluster1UpdateChan)
	assert.NotNil(t, updatedDaemonSet)
	assert.Equal(t, daemonset1.Name, updatedDaemonSet.Name)
	assert.Equal(t, daemonset1.Namespace, updatedDaemonSet.Namespace)
	assert.True(t, daemonsetsEqual(daemonset1, *updatedDaemonSet))

	// Test add cluster
	clusterWatch.Add(cluster2)
	createdDaemonSet2 := GetDaemonSetFromChan(cluster2CreateChan)
	assert.NotNil(t, createdDaemonSet2)
	assert.Equal(t, daemonset1.Name, createdDaemonSet2.Name)
	assert.Equal(t, daemonset1.Namespace, createdDaemonSet2.Namespace)
	assert.True(t, daemonsetsEqual(daemonset1, *createdDaemonSet2))

	close(stop)
}
func TestDaemonSetController(t *testing.T) {
	cluster1 := NewCluster("cluster1", apiv1.ConditionTrue)
	cluster2 := NewCluster("cluster2", apiv1.ConditionTrue)

	fakeClient := &fakefedclientset.Clientset{}
	RegisterFakeList("clusters", &fakeClient.Fake, &federationapi.ClusterList{Items: []federationapi.Cluster{*cluster1}})
	RegisterFakeList("daemonsets", &fakeClient.Fake, &extensionsv1.DaemonSetList{Items: []extensionsv1.DaemonSet{}})
	daemonsetWatch := RegisterFakeWatch("daemonsets", &fakeClient.Fake)
	daemonsetUpdateChan := RegisterFakeCopyOnUpdate("daemonsets", &fakeClient.Fake, daemonsetWatch)
	clusterWatch := RegisterFakeWatch("clusters", &fakeClient.Fake)

	cluster1Client := &fakekubeclientset.Clientset{}
	cluster1Watch := RegisterFakeWatch("daemonsets", &cluster1Client.Fake)
	RegisterFakeList("daemonsets", &cluster1Client.Fake, &extensionsv1.DaemonSetList{Items: []extensionsv1.DaemonSet{}})
	cluster1CreateChan := RegisterFakeCopyOnCreate("daemonsets", &cluster1Client.Fake, cluster1Watch)
	cluster1UpdateChan := RegisterFakeCopyOnUpdate("daemonsets", &cluster1Client.Fake, cluster1Watch)

	cluster2Client := &fakekubeclientset.Clientset{}
	cluster2Watch := RegisterFakeWatch("daemonsets", &cluster2Client.Fake)
	RegisterFakeList("daemonsets", &cluster2Client.Fake, &extensionsv1.DaemonSetList{Items: []extensionsv1.DaemonSet{}})
	cluster2CreateChan := RegisterFakeCopyOnCreate("daemonsets", &cluster2Client.Fake, cluster2Watch)

	daemonsetController := NewDaemonSetController(fakeClient)
	informer := ToFederatedInformerForTestOnly(daemonsetController.daemonsetFederatedInformer)
	informer.SetClientFactory(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")
		}
	})

	daemonsetController.clusterAvailableDelay = time.Second
	daemonsetController.daemonsetReviewDelay = 50 * time.Millisecond
	daemonsetController.smallDelay = 20 * time.Millisecond
	daemonsetController.updateTimeout = 5 * time.Second

	stop := make(chan struct{})
	daemonsetController.Run(stop)

	daemonset1 := extensionsv1.DaemonSet{
		ObjectMeta: apiv1.ObjectMeta{
			Name:      "test-daemonset",
			Namespace: "ns",
			SelfLink:  "/api/v1/namespaces/ns/daemonsets/test-daemonset",
		},
		Spec: extensionsv1.DaemonSetSpec{
			Selector: &metav1.LabelSelector{
				MatchLabels: make(map[string]string),
			},
		},
	}

	// Test add federated daemonset.
	daemonsetWatch.Add(&daemonset1)

	// There should be 2 updates to add both the finalizers.
	updatedDaemonSet := GetDaemonSetFromChan(daemonsetUpdateChan)
	assert.True(t, daemonsetController.hasFinalizerFunc(updatedDaemonSet, deletionhelper.FinalizerDeleteFromUnderlyingClusters))
	updatedDaemonSet = GetDaemonSetFromChan(daemonsetUpdateChan)
	assert.True(t, daemonsetController.hasFinalizerFunc(updatedDaemonSet, apiv1.FinalizerOrphan))
	daemonset1 = *updatedDaemonSet

	createdDaemonSet := GetDaemonSetFromChan(cluster1CreateChan)
	assert.NotNil(t, createdDaemonSet)
	assert.Equal(t, daemonset1.Namespace, createdDaemonSet.Namespace)
	assert.Equal(t, daemonset1.Name, createdDaemonSet.Name)
	assert.True(t, daemonsetsEqual(daemonset1, *createdDaemonSet),
		fmt.Sprintf("expected: %v, actual: %v", daemonset1, *createdDaemonSet))

	// Wait for the daemonset to appear in the informer store
	err := WaitForStoreUpdate(
		daemonsetController.daemonsetFederatedInformer.GetTargetStore(),
		cluster1.Name, getDaemonSetKey(daemonset1.Namespace, daemonset1.Name), wait.ForeverTestTimeout)
	assert.Nil(t, err, "daemonset should have appeared in the informer store")

	// TODO: Re-enable this when we have fixed these flaky tests: https://github.com/kubernetes/kubernetes/issues/36540.
	// Test update federated daemonset.
	daemonset1.Annotations = map[string]string{
		"A": "B",
	}
	daemonsetWatch.Modify(&daemonset1)
	updatedDaemonSet = GetDaemonSetFromChan(cluster1UpdateChan)
	assert.NotNil(t, updatedDaemonSet)
	assert.Equal(t, daemonset1.Name, updatedDaemonSet.Name)
	assert.Equal(t, daemonset1.Namespace, updatedDaemonSet.Namespace)
	assert.True(t, daemonsetsEqual(daemonset1, *updatedDaemonSet),
		fmt.Sprintf("expected: %v, actual: %v", daemonset1, *updatedDaemonSet))

	// Test update federated daemonset.
	daemonset1.Spec.Template.Name = "TEST"
	daemonsetWatch.Modify(&daemonset1)
	err = CheckObjectFromChan(cluster1UpdateChan, MetaAndSpecCheckingFunction(&daemonset1))
	assert.NoError(t, err)

	// Test add cluster
	clusterWatch.Add(cluster2)
	createdDaemonSet2 := GetDaemonSetFromChan(cluster2CreateChan)
	assert.NotNil(t, createdDaemonSet2)
	assert.Equal(t, daemonset1.Name, createdDaemonSet2.Name)
	assert.Equal(t, daemonset1.Namespace, createdDaemonSet2.Namespace)
	assert.True(t, daemonsetsEqual(daemonset1, *createdDaemonSet2),
		fmt.Sprintf("expected: %v, actual: %v", daemonset1, *createdDaemonSet2))

	close(stop)
}