Skip to content

Commit 24bd217

Browse files
committed
Add tests for WithSelector
1 parent 29386f1 commit 24bd217

1 file changed

Lines changed: 138 additions & 39 deletions

File tree

pkg/reconciler/reconciler_test.go

Lines changed: 138 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"errors"
2323
"fmt"
2424
"strconv"
25+
"strings"
26+
"sync"
2527
"time"
2628

2729
. "github.com/onsi/ginkgo/v2"
@@ -49,6 +51,7 @@ import (
4951
"sigs.k8s.io/controller-runtime/pkg/client/fake"
5052
"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
5153
"sigs.k8s.io/controller-runtime/pkg/config"
54+
"sigs.k8s.io/controller-runtime/pkg/controller"
5255
"sigs.k8s.io/controller-runtime/pkg/event"
5356
"sigs.k8s.io/controller-runtime/pkg/log/zap"
5457
"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -1492,45 +1495,6 @@ var _ = Describe("Reconciler", func() {
14921495
})
14931496
})
14941497
})
1495-
When("label selector set", func() {
1496-
It("reconcile only matching CR", func() {
1497-
By("adding selector to the reconciler", func() {
1498-
selectorFoo := metav1.LabelSelector{MatchLabels: map[string]string{"app": "foo"}}
1499-
Expect(WithSelector(selectorFoo)(r)).To(Succeed())
1500-
})
1501-
1502-
By("adding not matching label to the CR", func() {
1503-
Expect(mgr.GetClient().Get(ctx, objKey, obj)).To(Succeed())
1504-
obj.SetLabels(map[string]string{"app": "bar"})
1505-
Expect(mgr.GetClient().Update(ctx, obj)).To(Succeed())
1506-
})
1507-
1508-
By("reconciling skipped and no actions for the release", func() {
1509-
res, err := r.Reconcile(ctx, req)
1510-
Expect(res).To(Equal(reconcile.Result{}))
1511-
Expect(err).ToNot(HaveOccurred())
1512-
})
1513-
1514-
By("verifying the release has not changed", func() {
1515-
rel, err := ac.Get(obj.GetName())
1516-
Expect(err).ToNot(HaveOccurred())
1517-
Expect(rel).NotTo(BeNil())
1518-
Expect(*rel).To(Equal(*currentRelease))
1519-
})
1520-
1521-
By("adding matching label to the CR", func() {
1522-
Expect(mgr.GetClient().Get(ctx, objKey, obj)).To(Succeed())
1523-
obj.SetLabels(map[string]string{"app": "foo"})
1524-
Expect(mgr.GetClient().Update(ctx, obj)).To(Succeed())
1525-
})
1526-
1527-
By("successfully reconciling with correct labels", func() {
1528-
res, err := r.Reconcile(ctx, req)
1529-
Expect(res).To(Equal(reconcile.Result{}))
1530-
Expect(err).ToNot(HaveOccurred())
1531-
})
1532-
})
1533-
})
15341498
})
15351499
})
15361500
})
@@ -1545,6 +1509,141 @@ var _ = Describe("Reconciler", func() {
15451509
})
15461510
})
15471511

1512+
_ = Describe("WithSelector integration test", func() {
1513+
var (
1514+
mgr manager.Manager
1515+
ctx context.Context
1516+
cancel context.CancelFunc
1517+
reconciledCRs []string
1518+
reconciledCRsMutex sync.Mutex
1519+
labeledObj *unstructured.Unstructured
1520+
unlabeledObj *unstructured.Unstructured
1521+
labeledObjKey types.NamespacedName
1522+
unlabeledObjKey types.NamespacedName
1523+
)
1524+
1525+
BeforeEach(func() {
1526+
reconciledCRs = []string{}
1527+
mgr = getManagerOrFail()
1528+
matchingLabels := map[string]string{"app": "foo"}
1529+
1530+
r, err := New(
1531+
WithGroupVersionKind(gvk),
1532+
WithChart(chrt),
1533+
WithSelector(metav1.LabelSelector{MatchLabels: matchingLabels}),
1534+
)
1535+
Expect(err).ToNot(HaveOccurred())
1536+
1537+
originalReconciler := r
1538+
wrappedReconciler := &Reconciler{}
1539+
*wrappedReconciler = *originalReconciler
1540+
wrappedReconciler.client = mgr.GetClient()
1541+
1542+
// Override Reconcile to track reconciliations
1543+
reconciler := reconcile.Func(func(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
1544+
reconciledCRsMutex.Lock()
1545+
reconciledCRs = append(reconciledCRs, req.NamespacedName.String())
1546+
reconciledCRsMutex.Unlock()
1547+
return wrappedReconciler.Reconcile(ctx, req)
1548+
})
1549+
1550+
controllerName := fmt.Sprintf("%v-controller", strings.ToLower(gvk.Kind))
1551+
Expect(wrappedReconciler.addDefaults(mgr, controllerName)).To(Succeed())
1552+
wrappedReconciler.setupScheme(mgr)
1553+
1554+
c, err := controller.New(controllerName, mgr, controller.Options{
1555+
Reconciler: reconciler,
1556+
MaxConcurrentReconciles: 1,
1557+
})
1558+
Expect(err).ToNot(HaveOccurred())
1559+
Expect(wrappedReconciler.setupWatches(mgr, c)).To(Succeed())
1560+
1561+
labeledObj = testutil.BuildTestCR(gvk)
1562+
labeledObj.SetName("labeled-cr")
1563+
labeledObj.SetLabels(matchingLabels)
1564+
labeledObjKey = types.NamespacedName{Namespace: labeledObj.GetNamespace(), Name: labeledObj.GetName()}
1565+
1566+
unlabeledObj = testutil.BuildTestCR(gvk)
1567+
unlabeledObj.SetName("unlabeled-cr")
1568+
unlabeledObjKey = types.NamespacedName{Namespace: unlabeledObj.GetNamespace(), Name: unlabeledObj.GetName()}
1569+
1570+
ctx, cancel = context.WithCancel(context.Background())
1571+
go func() {
1572+
Expect(mgr.Start(ctx)).To(Succeed())
1573+
}()
1574+
Expect(mgr.GetCache().WaitForCacheSync(ctx)).To(BeTrue())
1575+
})
1576+
1577+
AfterEach(func() {
1578+
By("ensuring the labeled CR is deleted", func() {
1579+
err := mgr.GetAPIReader().Get(ctx, labeledObjKey, labeledObj)
1580+
if !apierrors.IsNotFound(err) {
1581+
Expect(err).ToNot(HaveOccurred())
1582+
labeledObj.SetFinalizers([]string{})
1583+
Expect(mgr.GetClient().Update(ctx, labeledObj)).To(Succeed())
1584+
Expect(mgr.GetClient().Delete(ctx, labeledObj)).To(Succeed())
1585+
}
1586+
})
1587+
1588+
By("ensuring the unlabeled CR is deleted", func() {
1589+
err := mgr.GetAPIReader().Get(ctx, unlabeledObjKey, unlabeledObj)
1590+
if !apierrors.IsNotFound(err) {
1591+
Expect(err).ToNot(HaveOccurred())
1592+
unlabeledObj.SetFinalizers([]string{})
1593+
Expect(mgr.GetClient().Update(ctx, unlabeledObj)).To(Succeed())
1594+
Expect(mgr.GetClient().Delete(ctx, unlabeledObj)).To(Succeed())
1595+
}
1596+
})
1597+
1598+
cancel()
1599+
})
1600+
1601+
It("should only reconcile CRs matching the label selector", func() {
1602+
By("creating a CR with matching labels", func() {
1603+
Expect(mgr.GetClient().Create(ctx, labeledObj)).To(Succeed())
1604+
})
1605+
1606+
By("creating a CR without matching labels", func() {
1607+
Expect(mgr.GetClient().Create(ctx, unlabeledObj)).To(Succeed())
1608+
})
1609+
1610+
By("waiting for reconciliations to complete", func() {
1611+
Eventually(func() []string {
1612+
reconciledCRsMutex.Lock()
1613+
defer reconciledCRsMutex.Unlock()
1614+
return reconciledCRs
1615+
}, "5s", "100ms").Should(ContainElement(labeledObjKey.String()))
1616+
})
1617+
1618+
By("verifying only the labeled CR was reconciled", func() {
1619+
reconciledCRsMutex.Lock()
1620+
defer reconciledCRsMutex.Unlock()
1621+
Expect(reconciledCRs).To(ContainElement(labeledObjKey.String()))
1622+
Expect(reconciledCRs).NotTo(ContainElement(unlabeledObjKey.String()))
1623+
})
1624+
1625+
By("updating the unlabeled CR to have matching labels", func() {
1626+
Expect(mgr.GetClient().Get(ctx, unlabeledObjKey, unlabeledObj)).To(Succeed())
1627+
unlabeledObj.SetLabels(map[string]string{"app": "foo"})
1628+
Expect(mgr.GetClient().Update(ctx, unlabeledObj)).To(Succeed())
1629+
})
1630+
1631+
By("waiting for the previously unlabeled CR to be reconciled", func() {
1632+
Eventually(func() []string {
1633+
reconciledCRsMutex.Lock()
1634+
defer reconciledCRsMutex.Unlock()
1635+
return reconciledCRs
1636+
}, "5s", "100ms").Should(ContainElement(unlabeledObjKey.String()))
1637+
})
1638+
1639+
By("verifying the previously unlabeled CR was reconciled after label change", func() {
1640+
reconciledCRsMutex.Lock()
1641+
defer reconciledCRsMutex.Unlock()
1642+
Expect(reconciledCRs).To(ContainElement(unlabeledObjKey.String()))
1643+
})
1644+
})
1645+
})
1646+
15481647
_ = Describe("Test custom controller setup", func() {
15491648
var (
15501649
mgr manager.Manager

0 commit comments

Comments
 (0)