Skip to content

Commit 761835c

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

2 files changed

Lines changed: 64 additions & 10 deletions

File tree

controllers/kustomization_wait_test.go

Lines changed: 58 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,22 @@ 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

129+
g.Expect(conditions.IsTrue(resultK, kustomizev1.HealthyCondition)).To(BeTrue())
130+
g.Expect(conditions.GetReason(resultK, kustomizev1.HealthyCondition)).To(BeIdenticalTo(meta.SucceededReason))
131+
132132
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation))
133+
134+
kstatusCheck.CheckErr(ctx, resultK)
133135
})
134136

135-
t.Run("reports unhealthy status", func(t *testing.T) {
136-
reconcileRequestAt := metav1.Now().String()
137+
t.Run("reports progressing status", func(t *testing.T) {
137138
g.Eventually(func() error {
138139
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
139140
resultK.SetAnnotations(map[string]string{
@@ -166,7 +167,9 @@ parameters:
166167
g.Expect(conditions.GetMessage(resultK, c)).To(ContainSubstring(expectedMessage))
167168
g.Expect(conditions.GetObservedGeneration(resultK, c)).To(BeIdenticalTo(resultK.Generation))
168169
}
170+
})
169171

172+
t.Run("reports unhealthy status", func(t *testing.T) {
170173
g.Eventually(func() bool {
171174
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
172175
return isReconcileFailure(resultK)
@@ -179,11 +182,14 @@ parameters:
179182
g.Expect(conditions.GetObservedGeneration(resultK, c)).To(BeIdenticalTo(resultK.Generation))
180183
}
181184

185+
expectedMessage := "Running health checks"
182186
g.Expect(conditions.GetReason(resultK, meta.ReconcilingCondition)).To(BeIdenticalTo(meta.ProgressingReason))
183187
g.Expect(conditions.GetMessage(resultK, meta.ReconcilingCondition)).To(ContainSubstring(expectedMessage))
184188

185189
g.Expect(resultK.Status.LastHandledReconcileAt).To(BeIdenticalTo(reconcileRequestAt))
186190
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation - 1))
191+
192+
kstatusCheck.CheckErr(ctx, resultK)
187193
})
188194

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

220226
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation))
227+
228+
kstatusCheck.CheckErr(ctx, resultK)
221229
})
222230

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

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)