Skip to content

Commit 7278e60

Browse files
committed
fix review findings
1 parent 3c9b982 commit 7278e60

File tree

1 file changed

+21
-18
lines changed

1 file changed

+21
-18
lines changed

pkg/manager/integration/manager_test.go

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ var (
6767
{
6868
Name: crewv1.GroupVersion.Version,
6969
Served: true,
70-
// At creation v1 will be the storage version.
71-
// During the test v2 will become the storage version.
70+
// v1 will be the storage version.
71+
// Reconciler and index will use v2 so we can validate the conversion webhook works.
7272
Storage: true,
7373
Schema: &apiextensionsv1.CustomResourceValidation{
7474
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
@@ -91,23 +91,22 @@ var (
9191
}
9292
)
9393

94-
var _ = Describe("manger.Manager", func() {
94+
var _ = Describe("manger.Manager Start", func() {
9595
// This test ensure the Manager starts without running into any deadlocks as it can be very tricky
9696
// to start health probes, webhooks, caches (including informers) and reconcilers in the right order.
9797
//
9898
// To verify this we set up a test environment in the following state:
9999
// * Ensure Informer sync requires a functioning conversion webhook (and thus readiness probe)
100100
// * Driver CRD is deployed with v1 as storage version
101101
// * A Driver CR is created and stored in the v1 version
102-
// * The CRD is updated to make v2 the storage version
103-
// * This ensures every Driver list call goes through conversion.
104102
// * Setup manager:
105103
// * Set up health probes
106-
// * Set up a Driver reconciler to verify reconciliation works
107-
// * Set up a conversion webhook which only works if readiness probe succeeds (just like a Kubernetes service)
104+
// * Set up a Driver v2 reconciler to verify reconciliation works
105+
// * Set up a conversion webhook which only works if readiness probe succeeds (just like via a Kubernetes service)
108106
// * Add an index on v2 Driver to ensure we start and wait for an informer during cache.Start (as part of manager.Start)
109107
// * Note: cache.Start would fail if the conversion webhook doesn't work (which in turn depends on the readiness probe)
110-
Describe("Start should start all components without deadlock", func() {
108+
// * Note: Adding the index for v2 ensures the Driver list call during Informer sync goes through conversion.
109+
It("should start all components without deadlock", func() {
111110
ctx := ctrl.SetupSignalHandler()
112111

113112
// Set up schema.
@@ -123,6 +122,7 @@ var _ = Describe("manger.Manager", func() {
123122
CRDs: []*apiextensionsv1.CustomResourceDefinition{driverCRD},
124123
},
125124
}
125+
// Note: The test env configures a conversion webhook on driverCRD during Start.
126126
cfg, err := env.Start()
127127
Expect(err).NotTo(HaveOccurred())
128128
Expect(cfg).NotTo(BeNil())
@@ -139,12 +139,6 @@ var _ = Describe("manger.Manager", func() {
139139
driverV1.SetNamespace(metav1.NamespaceDefault)
140140
Expect(c.Create(ctx, driverV1)).To(Succeed())
141141

142-
// Update driver CRD to make v2 the storage version.
143-
driverCRDV2Storage := driverCRD.DeepCopy()
144-
driverCRDV2Storage.Spec.Versions[0].Storage = false
145-
driverCRDV2Storage.Spec.Versions[0].Storage = true
146-
Expect(c.Patch(ctx, driverCRDV2Storage, client.MergeFrom(driverCRD))).To(Succeed())
147-
148142
// Set up Manager.
149143
ctrl.SetLogger(zap.New())
150144
mgr, err := manager.New(env.Config, manager.Options{
@@ -164,17 +158,18 @@ var _ = Describe("manger.Manager", func() {
164158
Expect(mgr.AddReadyzCheck("webhook", mgr.GetWebhookServer().StartedChecker())).To(Succeed())
165159
Expect(mgr.AddHealthzCheck("webhook", mgr.GetWebhookServer().StartedChecker())).To(Succeed())
166160

167-
// Set up Driver reconciler.
161+
// Set up Driver reconciler (using v2).
168162
driverReconciler := &DriverReconciler{
169163
Client: mgr.GetClient(),
170164
}
171-
Expect(ctrl.NewControllerManagedBy(mgr).For(&crewv1.Driver{}).Complete(driverReconciler)).To(Succeed())
165+
Expect(ctrl.NewControllerManagedBy(mgr).For(&crewv2.Driver{}).Complete(driverReconciler)).To(Succeed())
172166

173167
// Set up a conversion webhook.
174168
conversionWebhook := createConversionWebhook(mgr)
175169
mgr.GetWebhookServer().Register("/convert", conversionWebhook)
176170

177-
// Add an index on v2 Driver.
171+
// Add an index on Driver (using v2).
172+
// Note: This triggers the creation of an Informer for Driver v2.
178173
Expect(mgr.GetCache().IndexField(ctx, &crewv2.Driver{}, "name", func(object client.Object) []string {
179174
return []string{object.GetName()}
180175
})).To(Succeed())
@@ -187,6 +182,9 @@ var _ = Describe("manger.Manager", func() {
187182
}()
188183

189184
// Verify manager.Start successfully started health probes, webhooks, caches (including informers) and reconcilers.
185+
// Notes:
186+
// * The cache will only start successfully if the informer for v2 Driver is synced.
187+
// * The informer for v2 Driver will only sync if a list on v2 Driver succeeds (which requires a working conversion webhook)
190188
<-mgr.Elected()
191189

192190
// Verify the reconciler reconciles.
@@ -197,7 +195,8 @@ var _ = Describe("manger.Manager", func() {
197195
// Verify conversion webhook was called.
198196
Expect(atomic.LoadUint64(&conversionWebhook.ConversionCount)).Should(BeNumerically(">", 0))
199197

200-
// Verify the conversion webhook works.
198+
// Verify the conversion webhook works by getting the Driver as v1 and v2.
199+
Expect(c.Get(ctx, client.ObjectKeyFromObject(driverV1), driverV1)).To(Succeed())
201200
driverV2 := &unstructured.Unstructured{}
202201
driverV2.SetGroupVersionKind(crewv2.GroupVersion.WithKind("Driver"))
203202
driverV2.SetName("driver1")
@@ -234,6 +233,10 @@ func (r *DriverReconciler) Reconcile(ctx context.Context, req reconcile.Request)
234233
return reconcile.Result{}, nil
235234
}
236235

236+
// ConversionWebhook is just a shim around the conversion handler from
237+
// the webhook package. We use it to simulate the behavior of a conversion
238+
// webhook in a real cluster, i.e. the conversion webhook only works after the
239+
// controller Pod is ready (the readiness probe is up).
237240
type ConversionWebhook struct {
238241
httpClient http.Client
239242
conversionHandler http.Handler

0 commit comments

Comments
 (0)