@@ -69,6 +69,38 @@ func TestStatusReader_Supports(t *testing.T) {
6969 },
7070 result : false ,
7171 },
72+ {
73+ name : "group-only healthcheck supports any kind in that group" ,
74+ supportedGK : schema.GroupKind {
75+ Group : "test" ,
76+ },
77+ gk : schema.GroupKind {
78+ Group : "test" ,
79+ Kind : "AnyKind" ,
80+ },
81+ result : true ,
82+ },
83+ {
84+ name : "group-only healthcheck does not support other groups" ,
85+ supportedGK : schema.GroupKind {
86+ Group : "test" ,
87+ },
88+ gk : schema.GroupKind {
89+ Group : "other" ,
90+ Kind : "AnyKind" ,
91+ },
92+ result : false ,
93+ },
94+ {
95+ name : "group-only healthcheck supports GK with empty Kind in that group" ,
96+ supportedGK : schema.GroupKind {
97+ Group : "test" ,
98+ },
99+ gk : schema.GroupKind {
100+ Group : "test" ,
101+ },
102+ result : true ,
103+ },
72104 } {
73105 t .Run (tt .name , func (t * testing.T ) {
74106 t .Parallel ()
@@ -239,6 +271,93 @@ func TestStatusReader_ReadStatusForObject(t *testing.T) {
239271 }
240272}
241273
274+ func TestStatusReader_ReadStatusForObject_GroupOnlyHealthCheck (t * testing.T ) {
275+ g := NewWithT (t )
276+
277+ // Register a single group-only healthcheck (empty Kind) for group "bitnami.com".
278+ // It should apply to any Kind in that group.
279+ ctor , err := cel .NewStatusReader ([]kustomize.CustomHealthCheck {{
280+ APIVersion : "bitnami.com/v1alpha1" ,
281+ HealthCheckExpressions : kustomize.HealthCheckExpressions {
282+ Current : "data.current" ,
283+ },
284+ }})
285+ g .Expect (err ).NotTo (HaveOccurred ())
286+
287+ sr := ctor (nil )
288+
289+ for _ , kind := range []string {"SealedSecret" , "AnotherKind" } {
290+ result , err := sr .ReadStatusForObject (context .Background (), nil , & unstructured.Unstructured {
291+ Object : map [string ]any {
292+ "apiVersion" : "bitnami.com/v1alpha1" ,
293+ "kind" : kind ,
294+ "data" : map [string ]any {
295+ "current" : true ,
296+ },
297+ },
298+ })
299+ g .Expect (err ).NotTo (HaveOccurred ())
300+ g .Expect (result .Status ).To (Equal (status .CurrentStatus ))
301+ }
302+
303+ // A resource from a different group must not be supported.
304+ _ , err = sr .ReadStatusForObject (context .Background (), nil , & unstructured.Unstructured {
305+ Object : map [string ]any {
306+ "apiVersion" : "other.com/v1" ,
307+ "kind" : "Foo" ,
308+ "data" : map [string ]any {"current" : true },
309+ },
310+ })
311+ g .Expect (err ).To (MatchError (ContainSubstring ("the GroupKind Foo.other.com is not supported" )))
312+ }
313+
314+ func TestStatusReader_ReadStatusForObject_SpecificKindOverridesGroupOnly (t * testing.T ) {
315+ g := NewWithT (t )
316+
317+ // Register a group-only healthcheck that would always return Failed,
318+ // plus a specific-kind healthcheck that returns Current. The specific
319+ // one must take precedence for its Kind.
320+ ctor , err := cel .NewStatusReader ([]kustomize.CustomHealthCheck {
321+ {
322+ APIVersion : "bitnami.com/v1alpha1" ,
323+ HealthCheckExpressions : kustomize.HealthCheckExpressions {
324+ Failed : "true" ,
325+ Current : "false" ,
326+ },
327+ },
328+ {
329+ APIVersion : "bitnami.com/v1alpha1" ,
330+ Kind : "SealedSecret" ,
331+ HealthCheckExpressions : kustomize.HealthCheckExpressions {
332+ Current : "true" ,
333+ },
334+ },
335+ })
336+ g .Expect (err ).NotTo (HaveOccurred ())
337+
338+ sr := ctor (nil )
339+
340+ // SealedSecret hits the specific-kind evaluator -> Current.
341+ result , err := sr .ReadStatusForObject (context .Background (), nil , & unstructured.Unstructured {
342+ Object : map [string ]any {
343+ "apiVersion" : "bitnami.com/v1alpha1" ,
344+ "kind" : "SealedSecret" ,
345+ },
346+ })
347+ g .Expect (err ).NotTo (HaveOccurred ())
348+ g .Expect (result .Status ).To (Equal (status .CurrentStatus ))
349+
350+ // A different Kind in the same group falls back to the group-only evaluator -> Failed.
351+ result , err = sr .ReadStatusForObject (context .Background (), nil , & unstructured.Unstructured {
352+ Object : map [string ]any {
353+ "apiVersion" : "bitnami.com/v1alpha1" ,
354+ "kind" : "OtherKind" ,
355+ },
356+ })
357+ g .Expect (err ).NotTo (HaveOccurred ())
358+ g .Expect (result .Status ).To (Equal (status .FailedStatus ))
359+ }
360+
242361func TestNewStatusReader_DuplicateGroupKindError (t * testing.T ) {
243362 g := NewWithT (t )
244363
@@ -265,6 +384,30 @@ func TestNewStatusReader_DuplicateGroupKindError(t *testing.T) {
265384 g .Expect (result ).To (BeNil ())
266385}
267386
387+ func TestNewStatusReader_DuplicateGroupOnlyError (t * testing.T ) {
388+ g := NewWithT (t )
389+
390+ result , err := cel .NewStatusReader ([]kustomize.CustomHealthCheck {
391+ {
392+ APIVersion : "bitnami.com/v1alpha1" ,
393+ HealthCheckExpressions : kustomize.HealthCheckExpressions {
394+ Current : "true" ,
395+ },
396+ },
397+ {
398+ APIVersion : "bitnami.com/v1alpha1" ,
399+ HealthCheckExpressions : kustomize.HealthCheckExpressions {
400+ Current : "true" ,
401+ },
402+ },
403+ })
404+
405+ g .Expect (err ).To (HaveOccurred ())
406+ g .Expect (err .Error ()).To (ContainSubstring ("duplicate custom health check for GroupKind" ))
407+ g .Expect (err .Error ()).To (ContainSubstring ("healthchecks[1]" ))
408+ g .Expect (result ).To (BeNil ())
409+ }
410+
268411func TestNewStatusReader_CELCompileError (t * testing.T ) {
269412 g := NewWithT (t )
270413
0 commit comments