Repository: kubernetes/kubernetes
File: staging/src/k8s.io/apiserver/pkg/admission/configuration/mutating_webhook_manager_test.go (Go)

Code before:
	defer close(stop)

	manager := NewMutatingWebhookConfigurationManager(informerFactory).(*mutatingWebhookConfigurationManager)
	informerFactory.Start(stop)
	informerFactory.WaitForCacheSync(stop)

	// Wait for background activity (including setting up the watch!) to settle.
	synctest.Wait()

	// no configurations
	if configurations := manager.Webhooks(); len(configurations) != 0 {
		t.Errorf("expected empty webhooks, but got %v", configurations)
	}

	webhookConfiguration := &v1.MutatingWebhookConfiguration{
		ObjectMeta: metav1.ObjectMeta{Name: "webhook1"},
		Webhooks:   []v1.MutatingWebhook{{Name: "webhook1.1"}},
	}

	client.
		AdmissionregistrationV1().
		MutatingWebhookConfigurations().
		Create(context.TODO(), webhookConfiguration, metav1.CreateOptions{})

	// Wait for the notification to be delivered.
	synctest.Wait()
	configurations := manager.Webhooks()

	if len(configurations) == 0 {
		t.Errorf("expected non empty webhooks")
	}
	for i := range configurations {
		h, ok := configurations[i].GetMutatingWebhook()
		if !ok {
			t.Errorf("Expected mutating webhook")
			continue
		}
		if !reflect.DeepEqual(h, &webhookConfiguration.Webhooks[i]) {
			t.Errorf("Expected\n%#v\ngot\n%#v", &webhookConfiguration.Webhooks[i], h)
		}
	}
}

// mockCreateMutatingWebhookAccessor is a struct used to compute how many times
// the function webhook.NewMutatingWebhookAccessor is being called when refreshing
// webhookAccessors.
//
// NOTE: Maybe there some testing help that we can import and reuse instead.
type mockCreateMutatingWebhookAccessor struct {
	numberOfCalls int
}

Review comment (suggestion):
The old code assumed that within 10 seconds, all work that was kicked of has completed.

`synctest.Wait` removes that assumption. It will always wait as long as it takes, no matter how long that is. Then once it returns, we can check once what the code was previously polling.



Code after:
	defer close(stop)

	manager := NewMutatingWebhookConfigurationManager(informerFactory).(*mutatingWebhookConfigurationManager)
	informerFactory.Start(stop)
	informerFactory.WaitForCacheSync(stop)

	// Wait for background activity to settle.
	synctest.Wait()

	// no configurations
	if configurations := manager.Webhooks(); len(configurations) != 0 {
		t.Errorf("expected empty webhooks, but got %v", configurations)
	}

	webhookConfiguration := &v1.MutatingWebhookConfiguration{
		ObjectMeta: metav1.ObjectMeta{Name: "webhook1"},
		Webhooks:   []v1.MutatingWebhook{{Name: "webhook1.1"}},
	}

	client.
		AdmissionregistrationV1().
		MutatingWebhookConfigurations().
		Create(context.TODO(), webhookConfiguration, metav1.CreateOptions{})

	// Wait for the notification to be delivered.
	synctest.Wait()
	configurations := manager.Webhooks()

	if len(configurations) == 0 {
		t.Errorf("expected non empty webhooks")
	}
	for i := range configurations {
		h, ok := configurations[i].GetMutatingWebhook()
		if !ok {
			t.Errorf("Expected mutating webhook")
			continue
		}
		if !reflect.DeepEqual(h, &webhookConfiguration.Webhooks[i]) {
			t.Errorf("Expected\n%#v\ngot\n%#v", &webhookConfiguration.Webhooks[i], h)
		}
	}
}

// mockCreateMutatingWebhookAccessor is a struct used to compute how many times
// the function webhook.NewMutatingWebhookAccessor is being called when refreshing
// webhookAccessors.
//
// NOTE: Maybe there some testing help that we can import and reuse instead.
type mockCreateMutatingWebhookAccessor struct {
	numberOfCalls int
}