diff --git a/pkg/controllers/utils/expectations/active_expectation.go b/pkg/controllers/utils/expectations/active_expectation.go index fb9dbf28..0b5dc9d1 100644 --- a/pkg/controllers/utils/expectations/active_expectation.go +++ b/pkg/controllers/utils/expectations/active_expectation.go @@ -70,18 +70,10 @@ func init() { } } -func ActiveExpectationKeyFunc(object interface{}) (string, error) { - expectation, ok := object.(*ActiveExpectation) - if !ok { - return "", fmt.Errorf("fail to convert to active expectation") - } - return expectation.key, nil -} - func NewActiveExpectations(client client.Client) *ActiveExpectations { return &ActiveExpectations{ Client: client, - subjects: cache.NewStore(ActiveExpectationKeyFunc), + subjects: cache.NewStore(ExpKeyFunc), } } diff --git a/pkg/controllers/utils/expectations/active_expectation_test.go b/pkg/controllers/utils/expectations/active_expectation_test.go index 03aca21a..c995fca9 100644 --- a/pkg/controllers/utils/expectations/active_expectation_test.go +++ b/pkg/controllers/utils/expectations/active_expectation_test.go @@ -24,34 +24,9 @@ import ( "golang.org/x/net/context" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -var c client.Client - -var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} - -var depKey = types.NamespacedName{Name: "foo-deployment", Namespace: "default"} - -func Setup(t *testing.T) (g *gomega.GomegaWithT, r reconcile.Reconciler, mgr manager.Manager, client client.Client, stopFun func()) { - g = gomega.NewGomegaWithT(t) - mgr, err := manager.New(cfg, manager.Options{ - MetricsBindAddress: "0", - }) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c = mgr.GetClient() - - stopMgr, mgrStopped := StartTestManager(mgr, g) - return g, r, mgr, mgr.GetClient(), func() { - close(stopMgr) - mgrStopped.Wait() - } -} - -func TestReconcileResponsePodEvent(t *testing.T) { +func TestActiveExpectations(t *testing.T) { g, _, _, client, stopFunc := Setup(t) defer func() { stopFunc() diff --git a/pkg/controllers/utils/expectations/expectation.go b/pkg/controllers/utils/expectations/expectation.go index 35450fc0..5bb2b059 100644 --- a/pkg/controllers/utils/expectations/expectation.go +++ b/pkg/controllers/utils/expectations/expectation.go @@ -229,5 +229,8 @@ var ExpKeyFunc = func(obj interface{}) (string, error) { if e, ok := obj.(*ResourceVersionExpectationItem); ok { return e.key, nil } + if e, ok := obj.(*ActiveExpectation); ok { + return e.key, nil + } panic(fmt.Sprintf("Could not find key for obj %#v", obj)) } diff --git a/pkg/controllers/utils/expectations/expectations_suite_test.go b/pkg/controllers/utils/expectations/expectations_suite_test.go index 2714e9dc..2cdd137c 100644 --- a/pkg/controllers/utils/expectations/expectations_suite_test.go +++ b/pkg/controllers/utils/expectations/expectations_suite_test.go @@ -27,6 +27,7 @@ import ( "github.com/onsi/gomega" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -83,3 +84,17 @@ func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{} }() return stop, wg } + +func Setup(t *testing.T) (g *gomega.GomegaWithT, r reconcile.Reconciler, mgr manager.Manager, client client.Client, stopFun func()) { + g = gomega.NewGomegaWithT(t) + mgr, err := manager.New(cfg, manager.Options{ + MetricsBindAddress: "0", + }) + g.Expect(err).NotTo(gomega.HaveOccurred()) + + stopMgr, mgrStopped := StartTestManager(mgr, g) + return g, r, mgr, mgr.GetClient(), func() { + close(stopMgr) + mgrStopped.Wait() + } +} diff --git a/pkg/controllers/utils/expectations/resourceversion_expectation.go b/pkg/controllers/utils/expectations/resourceversion_expectation.go index e416d426..cd097372 100644 --- a/pkg/controllers/utils/expectations/resourceversion_expectation.go +++ b/pkg/controllers/utils/expectations/resourceversion_expectation.go @@ -53,24 +53,24 @@ func (r *ResourceVersionExpectation) DeleteExpectations(controllerKey string) { func (r *ResourceVersionExpectation) SatisfiedExpectations(controllerKey string, resourceVersion string) bool { if exp, exists, err := r.GetExpectations(controllerKey); exists { if exp.Fulfilled(resourceVersion) { - klog.Infof("Accuracy expectations fulfilled %s", controllerKey) + klog.Infof("ResourceVersion expectations fulfilled %s", controllerKey) return true } else if exp.isExpired() { - klog.Errorf("Accuracy expectation expired for key %s", controllerKey) - panic(fmt.Sprintf("expected panic for accuracy expectation timeout for key %s", controllerKey)) + klog.Errorf("ResourceVersion expectation expired for key %s", controllerKey) + panic(fmt.Sprintf("expected panic for resourceversion expectation timeout for key %s", controllerKey)) } else { - klog.V(4).Infof("Controller still waiting on accuracy expectations %s", controllerKey) + klog.V(4).Infof("Controller still waiting on resourceversion expectations %s", controllerKey) return false } } else if err != nil { - klog.V(2).Infof("Error encountered while checking accuracy expectations %#v, forcing sync", err) + klog.V(2).Infof("Error encountered while checking resourceversion expectations %#v, forcing sync", err) } else { // When a new controller is created, it doesn't have expectations. // When it doesn't see expected watch events for > TTL, the expectations expire. // - In this case it wakes up, creates/deletes controllees, and sets expectations again. // When it has satisfied expectations and no controllees need to be created/destroyed > TTL, the expectations expire. // - In this case it continues without setting expectations till it needs to create/delete controllees. - klog.V(4).Infof("Accuracy controller %v either never recorded expectations, or the ttl expired.", controllerKey) + klog.V(4).Infof("ResourceVersion controller %v either never recorded expectations, or the ttl expired.", controllerKey) } // Trigger a sync if we either encountered and error (which shouldn't happen since we're // getting from local store) or this controller hasn't established expectations. diff --git a/pkg/controllers/utils/expectations/resourceversion_expectation_test.go b/pkg/controllers/utils/expectations/resourceversion_expectation_test.go new file mode 100644 index 00000000..297a3078 --- /dev/null +++ b/pkg/controllers/utils/expectations/resourceversion_expectation_test.go @@ -0,0 +1,53 @@ +/* +Copyright 2023 The KusionStack Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package expectations + +import ( + "testing" + + "github.com/onsi/gomega" +) + +func TestResourceVersionExpectation(t *testing.T) { + g := gomega.NewGomegaWithT(t) + + exp := NewResourceVersionExpectation() + exp.SetExpectations("test", "1") + item, ok, err := exp.GetExpectations("test") + g.Expect(err).Should(gomega.BeNil()) + g.Expect(ok).Should(gomega.BeTrue()) + g.Expect(item.resourceVersion).Should(gomega.Equal(int64(1))) + + exp.ExpectUpdate("test", "2") + item, ok, err = exp.GetExpectations("test") + g.Expect(err).Should(gomega.BeNil()) + g.Expect(ok).Should(gomega.BeTrue()) + g.Expect(item.resourceVersion).Should(gomega.Equal(int64(2))) + + ok = exp.SatisfiedExpectations("test", "1") + g.Expect(ok).Should(gomega.BeFalse()) + ok = exp.SatisfiedExpectations("test", "2") + g.Expect(ok).Should(gomega.BeFalse()) + ok = exp.SatisfiedExpectations("test", "3") + g.Expect(ok).Should(gomega.BeTrue()) + + exp.DeleteExpectations("test") + item, ok, err = exp.GetExpectations("test") + g.Expect(err).Should(gomega.BeNil()) + g.Expect(ok).Should(gomega.BeFalse()) + g.Expect(item).Should(gomega.BeNil()) +}