package match import ( "testing" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" ) func TestObject(t *testing.T) { tcs := map[string]struct { obj client.Object matcher Matcher exp bool }{ "nil object is false": { nil, AnyInMetadata{"key": "value"}, false, }, "nil matcher is false": { &unstructured.Unstructured{}, nil, false, }, "actually matches": { func() client.Object { o := &unstructured.Unstructured{} o.SetGroupVersionKind(schema.GroupVersionKind{ Group: "apps", Version: "v1", Kind: "Deployment", }) return o }(), Kind{"Deployment"}, true, }, } for name, tc := range tcs { t.Run(name, func(t *testing.T) { ok := Object(tc.obj, tc.matcher) if ok != tc.exp { t.Errorf("unexpected Match() result: wanted %t, got %t", tc.exp, ok) } }) } } func TestMatchers(t *testing.T) { empty := &unstructured.Unstructured{} type testCase struct { obj client.Object matcher Matcher exp bool } tcs := map[string]map[string]testCase{ "Namespace": { "Matches": { &unstructured.Unstructured{Object: map[string]any{ "metadata": map[string]any{ "namespace": "kube-system", }, }}, Namespace{"kube-system"}, true, }, "Doesn't Match": { &unstructured.Unstructured{Object: map[string]any{ "metadata": map[string]any{ "namespace": "kube-system", }, }}, Namespace{"test"}, false, }, "Empty Doesn't Match": { empty, Namespace{"test"}, false, }, }, "Name": { "Matches": { &unstructured.Unstructured{Object: map[string]any{ "metadata": map[string]any{ "name": "bundle-of-joy", }, }}, Name{"bundle-of-joy"}, true, }, "Doesn't Match": { &unstructured.Unstructured{Object: map[string]any{ "metadata": map[string]any{ "name": "unexpected-encounter", }, }}, Name{"bundle-of-joy"}, false, }, "Empty Doesn't Match": { empty, Name{"bundle-of-joy"}, false, }, }, "Kind": { "Matches": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", }}, Kind{"Deployment"}, true, }, "Doesn't Match": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", }}, Kind{"Pod"}, false, }, "Empty Doesn't Match": { empty, Kind{"Pod"}, false, }, }, "GroupVersion": { "Matches": { &unstructured.Unstructured{Object: map[string]any{ "apiVersion": "apps/v1", }}, GroupVersion{Group: "apps", Version: "v1"}, true, }, "Doesn't Match": { &unstructured.Unstructured{Object: map[string]any{ "apiVersion": "apps/v1", }}, GroupVersion{Group: "", Version: "v1beta1"}, false, }, "Doesn't Match Version": { &unstructured.Unstructured{Object: map[string]any{ "apiVersion": "apps/v1", }}, GroupVersion{Group: "apps", Version: "v1beta1"}, false, }, "Empty Doesn't Match": { empty, GroupVersion{Group: "apps", Version: "v1"}, false, }, }, "AnyInMetadata": { "Matches": { objWithMeta(map[string]any{ "labels": map[string]any{ "key": "value", }, }), AnyInMetadata{"key": "value"}, true, }, "Partial Match Annotations": { objWithMeta(map[string]any{ "annotations": map[string]any{ "key": "value", }, }), AnyInMetadata{"key": "value", "key2": "value2"}, true, }, "Partial Match Labels": { objWithMeta(map[string]any{ "labels": map[string]any{ "key": "value", }, }), AnyInMetadata{"key": "value", "key2": "value2"}, true, }, "Matches Case Insensitive": { objWithMeta(map[string]any{ "labels": map[string]any{ "key": "valUe", }, }), AnyInMetadata{"key": "value"}, true, }, "Doesn't Match": { objWithMeta(map[string]any{ "labels": map[string]any{ "key2": "value", }, "annotations": map[string]any{ "key": "value2", }, }), AnyInMetadata{"key": "value", "key2": "value2"}, false, }, "Empty Doesn't Match": { empty, AnyInMetadata{"key": "value"}, false, }, }, "Labels": { "Matches": { objWithMeta(map[string]any{ "labels": map[string]any{ "label": "labelValue", }, }), Labels{"label": "labelValue"}, true, }, "Matches Multiple": { objWithMeta(map[string]any{ "labels": map[string]any{ "key": "value", "key2": "value2", }, }), Labels{ "key": "value", "key2": "value2", }, true, }, "Matches Case Insensitive": { objWithMeta(map[string]any{ "labels": map[string]any{ "key": "valUe", }, }), Labels{"key": "valUe"}, true, }, "Doesn't Match Partially": { objWithMeta(map[string]any{ "labels": map[string]any{ "key": "value", "key2": "value3", }, }), Labels{"key": "value", "key2": "value2"}, false, }, "Empty Doesn't Match": { empty, Labels{"key": "value"}, false, }, }, "Annotations": { "Matches": { objWithMeta(map[string]any{ "annotations": map[string]any{ "key": "value", }, }), Annotations{"key": "value"}, true, }, "Matches Multiple": { objWithMeta(map[string]any{ "annotations": map[string]any{ "key": "value", "key2": "value2", }, }), Annotations{"key": "value", "key2": "value2"}, true, }, "Matches Case Insensitive": { objWithMeta(map[string]any{ "annotations": map[string]any{ "key": "valUe", }, }), Annotations{"key": "valUe"}, true, }, "Doesn't Match Partially": { objWithMeta(map[string]any{ "annotations": map[string]any{ "key": "value", "key2": "value3", }, }), Annotations{"key": "value", "key2": "value2"}, false, }, "Empty Doesn't Match": { empty, Annotations{"key": "value"}, false, }, }, "Any": { "Matches": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", }}, Any{Kind{"Deployment"}}, true, }, "Partial Matches": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", }}, Any{Kind{"Deployment"}, Name{"bundle-of-joy"}}, true, }, "Ignores nil Matchers": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", "metadata": map[string]any{ "name": "bundle-of-joy", }, }}, Any{Kind{"Deployment"}, nil, Name{"bundle-of-joy"}}, true, }, "Doesn't Match": { empty, Any{Kind{"Deployment"}, Name{"bundle-of-joy"}}, false, }, "Empty Doesn't Match": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", "metadata": map[string]any{ "name": "bundle-of-joy", }, }}, Any{}, false, }, }, "All": { "Matches": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", }}, All{Kind{"Deployment"}}, true, }, "Partial Doesn't Match": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", }}, All{Kind{"Deployment"}, Name{"bundle-of-joy"}}, false, }, "Ignores nil Matchers": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", "metadata": map[string]any{ "name": "bundle-of-joy", }, }}, All{Kind{"Deployment"}, nil, Name{"bundle-of-joy"}}, true, }, "Doesn't Match": { empty, All{Kind{"Deployment"}, Name{"bundle-of-joy"}}, false, }, "Empty Doesn't Match": { &unstructured.Unstructured{Object: map[string]any{ "kind": "Deployment", "metadata": map[string]any{ "name": "bundle-of-joy", }, }}, All{}, false, }, }, } for fn, fnTestCases := range tcs { t.Run(fn, func(t *testing.T) { for name, tc := range fnTestCases { t.Run(name, func(t *testing.T) { ok := tc.matcher.Match(tc.obj) if ok != tc.exp { t.Errorf("unexpected Match() result: wanted %t, got %t", tc.exp, ok) } }) } }) } } func objWithMeta(meta map[string]any) *unstructured.Unstructured { return &unstructured.Unstructured{Object: map[string]any{ "metadata": meta, }} }