Skip to content

Commit b247c0d

Browse files
committed
Add kstatus conformance tests
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
1 parent 7799bb0 commit b247c0d

2 files changed

Lines changed: 61 additions & 10 deletions

File tree

controllers/kustomization_wait_test.go

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ import (
2323
"time"
2424

2525
. "github.com/onsi/gomega"
26+
apierrors "k8s.io/apimachinery/pkg/api/errors"
2627
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2728
"k8s.io/apimachinery/pkg/types"
2829
"sigs.k8s.io/controller-runtime/pkg/client"
30+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2931

3032
"github.com/fluxcd/pkg/apis/meta"
3133
"github.com/fluxcd/pkg/runtime/conditions"
@@ -39,6 +41,8 @@ func TestKustomizationReconciler_WaitConditions(t *testing.T) {
3941
g := NewWithT(t)
4042
id := "wait-" + randStringRunes(5)
4143
revision := "v1.0.0"
44+
resultK := &kustomizev1.Kustomization{}
45+
reconcileRequestAt := metav1.Now().String()
4246

4347
err := createNamespace(id)
4448
g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
@@ -115,25 +119,19 @@ parameters:
115119

116120
g.Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
117121

118-
resultK := &kustomizev1.Kustomization{}
119-
120-
g.Eventually(func() bool {
121-
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
122-
return resultK.Status.LastAppliedRevision == revision
123-
}, timeout, time.Second).Should(BeTrue())
124-
125122
t.Run("reports healthy status", func(t *testing.T) {
126123
g.Eventually(func() bool {
127124
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
128125
return isReconcileSuccess(resultK)
129-
}, time.Second, time.Second).Should(BeTrue())
126+
}, timeout, time.Second).Should(BeTrue())
130127
logStatus(t, resultK)
131128

132129
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation))
130+
131+
kstatusCheck.CheckErr(ctx, resultK)
133132
})
134133

135-
t.Run("reports unhealthy status", func(t *testing.T) {
136-
reconcileRequestAt := metav1.Now().String()
134+
t.Run("reports progressing status", func(t *testing.T) {
137135
g.Eventually(func() error {
138136
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
139137
resultK.SetAnnotations(map[string]string{
@@ -166,7 +164,9 @@ parameters:
166164
g.Expect(conditions.GetMessage(resultK, c)).To(ContainSubstring(expectedMessage))
167165
g.Expect(conditions.GetObservedGeneration(resultK, c)).To(BeIdenticalTo(resultK.Generation))
168166
}
167+
})
169168

169+
t.Run("reports unhealthy status", func(t *testing.T) {
170170
g.Eventually(func() bool {
171171
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
172172
return isReconcileFailure(resultK)
@@ -179,11 +179,14 @@ parameters:
179179
g.Expect(conditions.GetObservedGeneration(resultK, c)).To(BeIdenticalTo(resultK.Generation))
180180
}
181181

182+
expectedMessage := "Running health checks"
182183
g.Expect(conditions.GetReason(resultK, meta.ReconcilingCondition)).To(BeIdenticalTo(meta.ProgressingReason))
183184
g.Expect(conditions.GetMessage(resultK, meta.ReconcilingCondition)).To(ContainSubstring(expectedMessage))
184185

185186
g.Expect(resultK.Status.LastHandledReconcileAt).To(BeIdenticalTo(reconcileRequestAt))
186187
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation - 1))
188+
189+
kstatusCheck.CheckErr(ctx, resultK)
187190
})
188191

189192
t.Run("emits unhealthy event", func(t *testing.T) {
@@ -218,6 +221,8 @@ parameters:
218221
g.Expect(conditions.GetMessage(resultK, meta.ReadyCondition)).To(BeIdenticalTo(fmt.Sprintf("Applied revision: %s", revision)))
219222

220223
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation))
224+
225+
kstatusCheck.CheckErr(ctx, resultK)
221226
})
222227

223228
t.Run("emits recovery event", func(t *testing.T) {
@@ -227,4 +232,44 @@ parameters:
227232
g.Expect(events[len(events)-2].Type).To(BeIdenticalTo("Normal"))
228233
g.Expect(events[len(events)-2].Message).To(ContainSubstring(expectedMessage))
229234
})
235+
236+
t.Run("reports new revision healthy status", func(t *testing.T) {
237+
revision = "v2.0.0"
238+
artifact, err = testServer.ArtifactFromFiles(manifests(id, revision))
239+
g.Expect(err).NotTo(HaveOccurred())
240+
err = applyGitRepository(repositoryName, artifact, revision)
241+
g.Expect(err).NotTo(HaveOccurred())
242+
243+
g.Eventually(func() bool {
244+
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
245+
return resultK.Status.LastAppliedRevision == revision
246+
}, timeout, time.Second).Should(BeTrue())
247+
logStatus(t, resultK)
248+
249+
g.Expect(conditions.IsTrue(resultK, kustomizev1.HealthyCondition)).To(BeTrue())
250+
g.Expect(conditions.IsTrue(resultK, meta.ReadyCondition)).To(BeTrue())
251+
g.Expect(conditions.GetMessage(resultK, meta.ReadyCondition)).To(BeIdenticalTo(fmt.Sprintf("Applied revision: %s", revision)))
252+
253+
g.Expect(resultK.Status.LastAttemptedRevision).To(BeIdenticalTo(resultK.Status.LastAppliedRevision))
254+
255+
kstatusCheck.CheckErr(ctx, resultK)
256+
})
257+
258+
t.Run("emits event for the new revision", func(t *testing.T) {
259+
expectedMessage := "Health check passed"
260+
events := getEvents(resultK.GetName(), map[string]string{"kustomize.toolkit.fluxcd.io/revision": revision})
261+
g.Expect(len(events) > 1).To(BeTrue())
262+
g.Expect(events[len(events)-2].Type).To(BeIdenticalTo("Normal"))
263+
g.Expect(events[len(events)-2].Message).To(ContainSubstring(expectedMessage))
264+
})
265+
266+
t.Run("finalizes object", func(t *testing.T) {
267+
g.Expect(controllerutil.ContainsFinalizer(resultK, kustomizev1.KustomizationFinalizer)).To(BeTrue())
268+
g.Expect(k8sClient.Delete(context.Background(), resultK)).To(Succeed())
269+
270+
g.Eventually(func() bool {
271+
err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
272+
return apierrors.IsNotFound(err)
273+
}, timeout, time.Second).Should(BeTrue())
274+
})
230275
}

controllers/suite_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141

4242
"github.com/fluxcd/pkg/apis/meta"
4343
"github.com/fluxcd/pkg/runtime/conditions"
44+
kcheck "github.com/fluxcd/pkg/runtime/conditions/check"
4445
"github.com/fluxcd/pkg/runtime/controller"
4546
"github.com/fluxcd/pkg/runtime/testenv"
4647
"github.com/fluxcd/pkg/testserver"
@@ -69,6 +70,7 @@ var (
6970
testMetricsH controller.Metrics
7071
ctx = ctrl.SetupSignalHandler()
7172
kubeConfig []byte
73+
kstatusCheck *kcheck.Checker
7274
debugMode = os.Getenv("DEBUG_TEST") != ""
7375
)
7476

@@ -160,6 +162,10 @@ func TestMain(m *testing.M) {
160162
runInContext(func(testEnv *testenv.Environment) {
161163
controllerName := "kustomize-controller"
162164
testMetricsH = controller.MustMakeMetrics(testEnv)
165+
kstatusCheck = kcheck.NewChecker(testEnv.Client,
166+
&kcheck.Conditions{
167+
NegativePolarity: []string{meta.StalledCondition, meta.ReconcilingCondition},
168+
})
163169
reconciler = &KustomizationReconciler{
164170
ControllerName: controllerName,
165171
Client: testEnv,

0 commit comments

Comments
 (0)