Path: blob/main/pkg/operator/hierarchy/hierarchy_test.go
4094 views
//go:build !nonetwork && !nodocker && !race12package hierarchy34import (5"context"6"testing"7"time"89"github.com/go-kit/log"10"github.com/grafana/agent/pkg/util/k8s"11"github.com/stretchr/testify/require"12v1 "k8s.io/api/core/v1"13metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"14"k8s.io/apimachinery/pkg/labels"15"k8s.io/apimachinery/pkg/types"16"k8s.io/client-go/util/workqueue"17"sigs.k8s.io/controller-runtime/pkg/event"18)1920// TestNotifier tests that notifier properly handles events for changed21// objects.22func TestNotifier(t *testing.T) {23l := log.NewNopLogger()2425ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)26defer cancel()2728cluster, err := k8s.NewCluster(ctx, k8s.Options{})29require.NoError(t, err)30defer cluster.Stop()3132cli := cluster.Client()3334// Tests will rely on a namespace existing, so let's create a namespace with35// some labels.36testNs := v1.Namespace{37TypeMeta: metav1.TypeMeta{38APIVersion: "v1",39Kind: "Namespace",40},41ObjectMeta: metav1.ObjectMeta{42Name: "enqueue-test",43Labels: map[string]string{"foo": "bar"},44},45}46err = cli.Create(ctx, &testNs)47require.NoError(t, err)4849testPod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{50Name: "test-pod",51Namespace: "enqueue-test",52Labels: map[string]string{"fizz": "buzz"},53}}5455tt := []struct {56name string57sel Selector58expectEnqueue bool59}{60{61name: "no watchers",62sel: nil,63expectEnqueue: false,64},65{66name: "matches watcher",67sel: &LabelsSelector{68NamespaceName: "enqueue-test",69NamespaceLabels: parseSelector(t, "foo in (bar)"),70Labels: parseSelector(t, "fizz in (buzz)"),71},72expectEnqueue: true,73},74{75name: "matches watcher with explicit namespace",76sel: &LabelsSelector{77NamespaceName: "enqueue-test",78Labels: parseSelector(t, "fizz in (buzz)"),79},80expectEnqueue: true,81},82{83name: "bad namespace name selector",84sel: &LabelsSelector{85NamespaceName: "default",86Labels: labels.Everything(),87},88expectEnqueue: false,89},90{91name: "bad namespace label selector",92sel: &LabelsSelector{93NamespaceName: "enqueue-test",94NamespaceLabels: parseSelector(t, "foo notin (bar)"),95Labels: labels.Everything(),96},97expectEnqueue: false,98},99{100name: "bad label selector",101sel: &LabelsSelector{102NamespaceName: "default",103NamespaceLabels: labels.Everything(),104Labels: parseSelector(t, "fizz notin (buzz)"),105},106expectEnqueue: false,107},108}109110for _, tc := range tt {111t.Run(tc.name, func(t *testing.T) {112limiter := workqueue.DefaultControllerRateLimiter()113q := workqueue.NewRateLimitingQueue(limiter)114115notifier := NewNotifier(l, cli)116117if tc.sel != nil {118err := notifier.Notify(Watcher{119Object: &v1.Pod{},120Owner: types.NamespacedName{Name: "watcher", Namespace: "enqueue-test"},121Selector: tc.sel,122})123require.NoError(t, err)124}125126e := notifier.EventHandler()127e.Create(event.CreateEvent{Object: testPod}, q)128if tc.expectEnqueue {129require.Equal(t, 1, q.Len(), "expected change enqueue")130} else {131require.Equal(t, 0, q.Len(), "no changes should have been enqueued")132}133})134}135}136137func parseSelector(t *testing.T, selector string) labels.Selector {138t.Helper()139s, err := labels.Parse(selector)140require.NoError(t, err)141return s142}143144145