diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c9d3343d..bf176647 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -22,10 +22,18 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Cache Binaries + id: cache-binaries + uses: actions/cache@v3 + with: + path: bin + key: ${{ runner.os }}-bin + - name: Install k3d tools run: | make -C hack/ci/ install-k3d-tools + - name: Install Kyma CLI & setup k3d cluster using kyma CLI run: | make kyma diff --git a/.golangci.yaml b/.golangci.yaml index ee4bad9b..cbecb050 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -19,7 +19,6 @@ linters: - varcheck # deprecated (since v1.49.0) and replaced by 'unused' - wsl # too strict and mostly code is not more readable ### disabled for now... will be enabled 1 by 1 - - containedctx - dupl - errorlint - forcetypeassert @@ -31,7 +30,6 @@ linters: - goconst - gocritic - godox - - goerr113 - gomnd - gosec - inamedparam @@ -39,12 +37,9 @@ linters: - maintidx - noctx - nolintlint - - nonamedreturns - paralleltest - - perfsprint - prealloc - stylecheck - - testifylint - testpackage - thelper - tparallel @@ -54,7 +49,6 @@ linters: - wrapcheck - godot - tagalign - - whitespace linters-settings: stylecheck: diff --git a/Makefile b/Makefile index 5eb988a2..d112b48c 100644 --- a/Makefile +++ b/Makefile @@ -223,6 +223,7 @@ ENVTEST ?= $(LOCALBIN)/setup-envtest ## Tool Versions KUSTOMIZE_VERSION ?= v5.0.0 CONTROLLER_TOOLS_VERSION ?= v0.11.3 +GOLANG_CI_LINT_VERSION ?= v1.55.2 KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" .PHONY: kustomize @@ -245,8 +246,15 @@ envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. $(ENVTEST): $(LOCALBIN) test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest -lint: - golangci-lint run --fix --timeout 5m +golangci_lint: + test -s $(LOCALBIN)/golangci-lint && $(LOCALBIN)/golangci-lint version | grep -q $(GOLANG_CI_LINT_VERSION) || \ + GOBIN=$(LOCALBIN) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANG_CI_LINT_VERSION) + +lint: golangci_lint + $(LOCALBIN)/golangci-lint run + +lint-fix: golangci_lint + $(LOCALBIN)/golangci-lint run --fix go-gen: go generate ./... diff --git a/api/eventing/v1alpha1/fixtures_test.go b/api/eventing/v1alpha1/fixtures_test.go index 1ee905f2..0ddd7ddb 100644 --- a/api/eventing/v1alpha1/fixtures_test.go +++ b/api/eventing/v1alpha1/fixtures_test.go @@ -1,7 +1,7 @@ package v1alpha1_test import ( - "fmt" + "strconv" kmetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -136,7 +136,7 @@ func newV2DefaultSubscription(opts ...eventingtesting.SubscriptionOpt) *v1alpha2 Sink: defaultSink, ID: defaultID, Config: map[string]string{ - v1alpha2.MaxInFlightMessages: fmt.Sprint(defaultMaxInFlight), + v1alpha2.MaxInFlightMessages: strconv.Itoa(defaultMaxInFlight), }, }, Status: v1alpha2.SubscriptionStatus{ diff --git a/api/eventing/v1alpha1/subscription_conversion.go b/api/eventing/v1alpha1/subscription_conversion.go index 5e3cb7df..e0fea092 100644 --- a/api/eventing/v1alpha1/subscription_conversion.go +++ b/api/eventing/v1alpha1/subscription_conversion.go @@ -141,7 +141,7 @@ func (src *Subscription) setProtocolSettings(dst *v1alpha2.Subscription) { dst.Spec.Config[v1alpha2.ProtocolSettingsContentMode] = *src.Spec.ProtocolSettings.ContentMode } if src.Spec.ProtocolSettings.ExemptHandshake != nil { - dst.Spec.Config[v1alpha2.ProtocolSettingsExemptHandshake] = fmt.Sprint(*src.Spec.ProtocolSettings.ExemptHandshake) + dst.Spec.Config[v1alpha2.ProtocolSettingsExemptHandshake] = strconv.FormatBool(*src.Spec.ProtocolSettings.ExemptHandshake) } if src.Spec.ProtocolSettings.Qos != nil { dst.Spec.Config[v1alpha2.ProtocolSettingsQos] = *src.Spec.ProtocolSettings.Qos @@ -270,7 +270,7 @@ func (src *Subscription) natsSpecConfigToV2(dst *v1alpha2.Subscription) { if dst.Spec.Config == nil { dst.Spec.Config = map[string]string{} } - dst.Spec.Config[v1alpha2.MaxInFlightMessages] = fmt.Sprint(src.Spec.Config.MaxInFlightMessages) + dst.Spec.Config[v1alpha2.MaxInFlightMessages] = strconv.Itoa(src.Spec.Config.MaxInFlightMessages) } } diff --git a/api/eventing/v1alpha1/subscription_conversion_unit_test.go b/api/eventing/v1alpha1/subscription_conversion_unit_test.go index 0fda40c4..d7134938 100644 --- a/api/eventing/v1alpha1/subscription_conversion_unit_test.go +++ b/api/eventing/v1alpha1/subscription_conversion_unit_test.go @@ -208,7 +208,7 @@ func Test_Conversion(t *testing.T) { convertedV1Alpha2 := &v1alpha2.Subscription{} err := v1alpha1.V1ToV2(testCase.alpha1Sub, convertedV1Alpha2) if err != nil && testCase.wantErrMsgV1toV2 != "" { - require.Equal(t, err.Error(), testCase.wantErrMsgV1toV2) + require.Equal(t, testCase.wantErrMsgV1toV2, err.Error()) } else { require.NoError(t, err) v1ToV2Assertions(t, testCase.alpha2Sub, convertedV1Alpha2) @@ -224,7 +224,7 @@ func Test_Conversion(t *testing.T) { convertedV1Alpha1 := &v1alpha1.Subscription{} err := v1alpha1.V2ToV1(convertedV1Alpha1, testCase.alpha2Sub) if err != nil && testCase.wantErrMsgV2toV1 != "" { - require.Equal(t, err.Error(), testCase.wantErrMsgV2toV1) + require.Equal(t, testCase.wantErrMsgV2toV1, err.Error()) } else { require.NoError(t, err) v2ToV1Assertions(t, testCase.alpha1Sub, convertedV1Alpha1) diff --git a/api/eventing/v1alpha2/subscription_webhook_unit_test.go b/api/eventing/v1alpha2/subscription_webhook_unit_test.go index c99597fe..596ef797 100644 --- a/api/eventing/v1alpha2/subscription_webhook_unit_test.go +++ b/api/eventing/v1alpha2/subscription_webhook_unit_test.go @@ -74,7 +74,7 @@ func Test_Default(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() tc.givenSub.Default() - require.Equal(t, tc.givenSub, tc.wantSub) + require.Equal(t, tc.wantSub, tc.givenSub) }) } } @@ -425,7 +425,7 @@ func Test_validateSubscription(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() _, err := tc.givenSub.ValidateSubscription() - require.Equal(t, err, tc.wantErr) + require.Equal(t, tc.wantErr, err) }) } } diff --git a/api/operator/v1alpha1/status_test.go b/api/operator/v1alpha1/status_test.go index af39b57b..e5c61af4 100644 --- a/api/operator/v1alpha1/status_test.go +++ b/api/operator/v1alpha1/status_test.go @@ -21,13 +21,13 @@ func TestClearConditions(t *testing.T) { }, }, } - require.NotEqual(t, 0, len(givenEventingStatus.Conditions)) + require.NotEmpty(t, givenEventingStatus.Conditions) // when givenEventingStatus.ClearConditions() // then - require.Len(t, givenEventingStatus.Conditions, 0) + require.Empty(t, givenEventingStatus.Conditions) } func TestClearPublisherService(t *testing.T) { diff --git a/api/operator/v1alpha1/zz_generated.deepcopy.go b/api/operator/v1alpha1/zz_generated.deepcopy.go index a7bd0a7a..1a8cdd8f 100644 --- a/api/operator/v1alpha1/zz_generated.deepcopy.go +++ b/api/operator/v1alpha1/zz_generated.deepcopy.go @@ -22,7 +22,7 @@ limitations under the License. package v1alpha1 import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) diff --git a/hack/e2e/common/eventing/publisher.go b/hack/e2e/common/eventing/publisher.go index daf560fe..f279076e 100644 --- a/hack/e2e/common/eventing/publisher.go +++ b/hack/e2e/common/eventing/publisher.go @@ -22,17 +22,20 @@ const ( CloudEventPublishEndpointFormat = "%s/publish" ) +var ( + ErrFailedSendingCE = errors.New("failed to send cloudevent") + ErrEncodingNotSupported = errors.New("unsupported cloudevent encoding") +) + type Publisher struct { - ctx context.Context clientCE client.Client clientHTTP *http.Client publisherURL string logger *zap.Logger } -func NewPublisher(ctx context.Context, clientCE client.Client, clientHTTP *http.Client, publisherURL string, logger *zap.Logger) *Publisher { +func NewPublisher(clientCE client.Client, clientHTTP *http.Client, publisherURL string, logger *zap.Logger) *Publisher { return &Publisher{ - ctx: ctx, clientCE: clientCE, clientHTTP: clientHTTP, publisherURL: publisherURL, @@ -125,7 +128,7 @@ func (p *Publisher) SendCloudEvent(event *cloudevents.Event, encoding binding.En } default: { - return fmt.Errorf("failed to use unsupported cloudevent encoding:[%s]", encoding.String()) + return fmt.Errorf("%w:[%s]", ErrEncodingNotSupported, encoding.String()) } } @@ -142,11 +145,11 @@ func (p *Publisher) SendCloudEvent(event *cloudevents.Event, encoding binding.En switch { case cloudevents.IsUndelivered(result): { - return fmt.Errorf("failed to send cloudevent-%s undelivered:[%s] response:[%s]", encoding.String(), ce.Type(), result) + return fmt.Errorf("%w: encoding:[%s] undelivered:[%s] response:[%s]", ErrFailedSendingCE, encoding.String(), ce.Type(), result) } case cloudevents.IsNACK(result): { - return fmt.Errorf("failed to send cloudevent-%s nack:[%s] response:[%s]", encoding.String(), ce.Type(), result) + return fmt.Errorf("%w: encoding:[%s] nack:[%s] response:[%s]", ErrFailedSendingCE, encoding.String(), ce.Type(), result) } case cloudevents.IsACK(result): { @@ -155,7 +158,7 @@ func (p *Publisher) SendCloudEvent(event *cloudevents.Event, encoding binding.En } default: { - return fmt.Errorf("failed to send cloudevent-%s unknown:[%s] response:[%s]", encoding.String(), ce.Type(), result) + return fmt.Errorf("%w: encoding:[%s] unknown:[%s] response:[%s]", ErrFailedSendingCE, encoding.String(), ce.Type(), result) } } } diff --git a/hack/e2e/common/eventing/sinkclient.go b/hack/e2e/common/eventing/sinkclient.go index a8911b9d..78ed63d0 100644 --- a/hack/e2e/common/eventing/sinkclient.go +++ b/hack/e2e/common/eventing/sinkclient.go @@ -2,7 +2,6 @@ package eventing import ( "bytes" - "context" "encoding/json" "fmt" "io" @@ -22,7 +21,6 @@ const ( ) type SinkClient struct { - ctx context.Context clientHTTP *http.Client sinkURL string logger *zap.Logger @@ -34,9 +32,8 @@ type SinkEvent struct { ceevent.Event } -func NewSinkClient(ctx context.Context, clientHTTP *http.Client, sinkURL string, logger *zap.Logger) *SinkClient { +func NewSinkClient(clientHTTP *http.Client, sinkURL string, logger *zap.Logger) *SinkClient { return &SinkClient{ - ctx: ctx, clientHTTP: clientHTTP, sinkURL: sinkURL, logger: logger, diff --git a/hack/e2e/common/eventing/utils.go b/hack/e2e/common/eventing/utils.go index d718698f..6486eb7e 100644 --- a/hack/e2e/common/eventing/utils.go +++ b/hack/e2e/common/eventing/utils.go @@ -93,7 +93,7 @@ func NewCloudEvent(eventSource, eventType string, encoding binding.Encoding) (*c ce.SetType(eventType) ce.SetSource(eventSource) if err := ce.SetData(cloudevents.ApplicationJSON, data); err != nil { - return nil, fmt.Errorf("failed to set cloudevent-%s data with error:[%s]", encoding.String(), err) + return nil, fmt.Errorf("failed to set cloudevent-%s data with error:[%w]", encoding.String(), err) } return &ce, nil } diff --git a/hack/e2e/common/fixtures/fixtures.go b/hack/e2e/common/fixtures/fixtures.go index 4db73194..90bd6484 100644 --- a/hack/e2e/common/fixtures/fixtures.go +++ b/hack/e2e/common/fixtures/fixtures.go @@ -278,6 +278,7 @@ func ConvertSelectorLabelsToString(labels map[string]string) string { return strings.Join(result, ",") } +//nolint:goerr113 //TODO: this is ERRORHANDLING NOT a LOGGER!!!! func AppendMsgToError(err error, msg string) error { return errors.Join(err, fmt.Errorf("\n==> %s", msg)) } diff --git a/hack/e2e/common/testenvironment/test_environment.go b/hack/e2e/common/testenvironment/test_environment.go index 3c92c831..6edf86c6 100644 --- a/hack/e2e/common/testenvironment/test_environment.go +++ b/hack/e2e/common/testenvironment/test_environment.go @@ -40,9 +40,17 @@ const ( ThreeAttempts = 3 ) +var ( + ErrSubscriptionNotReconciled = errors.New("subscription not reconciled") + ErrSubscriptionNotReady = errors.New("subscription not READY") + ErrDeploymentNotReady = errors.New("deployment not READY") + ErrWrongActiveType = errors.New("specified backend not active") + ErrEventingNotReady = errors.New("eventing not READY") + ErrInvalidDeployment = errors.New("deployment.spec invalid") +) + // TestEnvironment provides mocked resources for integration tests. type TestEnvironment struct { - Context context.Context Logger *zap.Logger K8sClientset *kubernetes.Clientset K8sClient client.Client @@ -74,7 +82,6 @@ func NewTestEnvironment() *TestEnvironment { } return &TestEnvironment{ - Context: context.TODO(), Logger: logger, K8sClientset: clientSet, K8sClient: k8sClient, @@ -86,14 +93,14 @@ func NewTestEnvironment() *TestEnvironment { func (te *TestEnvironment) CreateTestNamespace() error { return common.Retry(Attempts, Interval, func() error { // It's fine if the Namespace already exists. - return client.IgnoreAlreadyExists(te.K8sClient.Create(te.Context, fixtures.Namespace(te.TestConfigs.TestNamespace))) + return client.IgnoreAlreadyExists(te.K8sClient.Create(context.TODO(), fixtures.Namespace(te.TestConfigs.TestNamespace))) }) } func (te *TestEnvironment) DeleteTestNamespace() error { return common.Retry(FewAttempts, Interval, func() error { // It's fine if the Namespace does not exist. - return client.IgnoreNotFound(te.K8sClient.Delete(te.Context, fixtures.Namespace(te.TestConfigs.TestNamespace))) + return client.IgnoreNotFound(te.K8sClient.Delete(context.TODO(), fixtures.Namespace(te.TestConfigs.TestNamespace))) }) } @@ -108,7 +115,7 @@ func (te *TestEnvironment) InitEventPublisherClient() error { if err != nil { return err } - te.EventPublisher = eventing.NewPublisher(context.Background(), *clientCE, clientHTTP, te.TestConfigs.PublisherURL, te.Logger) + te.EventPublisher = eventing.NewPublisher(*clientCE, clientHTTP, te.TestConfigs.PublisherURL, te.Logger) return nil } @@ -119,7 +126,7 @@ func (te *TestEnvironment) InitSinkClient() { idleConnTimeout := 1 * time.Minute t := http.NewTransport(maxIdleConns, maxConnsPerHost, maxIdleConnsPerHost, idleConnTimeout) clientHTTP := http.NewHttpClient(t.Clone()) - te.SinkClient = eventing.NewSinkClient(context.Background(), clientHTTP, te.TestConfigs.SinkPortForwardedURL, te.Logger) + te.SinkClient = eventing.NewSinkClient(clientHTTP, te.TestConfigs.SinkPortForwardedURL, te.Logger) } func (te *TestEnvironment) CreateAllSubscriptions() error { @@ -218,7 +225,7 @@ func (te *TestEnvironment) WaitForSubscription(ctx context.Context, subsToTest e "in namespace: %s to get recocniled by backend: %s", subsToTest.Name, te.TestConfigs.TestNamespace, te.TestConfigs.BackendType) te.Logger.Debug(errMsg) - return errors.New(errMsg) + return fmt.Errorf("%s, %w", errMsg, ErrSubscriptionNotReconciled) } // check if subscription is ready. @@ -226,7 +233,7 @@ func (te *TestEnvironment) WaitForSubscription(ctx context.Context, subsToTest e errMsg := fmt.Sprintf("waiting subscription: %s "+ "in namespace: %s to get ready", subsToTest.Name, te.TestConfigs.TestNamespace) te.Logger.Debug(errMsg) - return errors.New(errMsg) + return fmt.Errorf("%s, %w", errMsg, ErrSubscriptionNotReady) } return nil }) @@ -263,7 +270,7 @@ func (te *TestEnvironment) DeleteSinkResources() error { func (te *TestEnvironment) CreateSinkDeployment(name, namespace, image string) error { return common.Retry(FewAttempts, Interval, func() error { - return te.K8sClient.Patch(te.Context, fixtures.NewSinkDeployment(name, namespace, image), + return te.K8sClient.Patch(context.TODO(), fixtures.NewSinkDeployment(name, namespace, image), client.Apply, &client.PatchOptions{ Force: ptr.To(true), @@ -274,7 +281,7 @@ func (te *TestEnvironment) CreateSinkDeployment(name, namespace, image string) e func (te *TestEnvironment) CreateSinkService(name, namespace string) error { return common.Retry(FewAttempts, Interval, func() error { - return te.K8sClient.Patch(te.Context, fixtures.NewSinkService(name, namespace), + return te.K8sClient.Patch(context.TODO(), fixtures.NewSinkService(name, namespace), client.Apply, &client.PatchOptions{ Force: ptr.To(true), @@ -285,7 +292,7 @@ func (te *TestEnvironment) CreateSinkService(name, namespace string) error { func (te *TestEnvironment) DeleteDeployment(name, namespace string) error { return common.Retry(FewAttempts, Interval, func() error { - return te.K8sClient.Delete(te.Context, &kappsv1.Deployment{ + return te.K8sClient.Delete(context.TODO(), &kappsv1.Deployment{ ObjectMeta: kmetav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -296,7 +303,7 @@ func (te *TestEnvironment) DeleteDeployment(name, namespace string) error { func (te *TestEnvironment) DeleteService(name, namespace string) error { return common.Retry(FewAttempts, Interval, func() error { - return te.K8sClient.Delete(te.Context, &kcorev1.Service{ + return te.K8sClient.Delete(context.TODO(), &kcorev1.Service{ ObjectMeta: kmetav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -306,7 +313,7 @@ func (te *TestEnvironment) DeleteService(name, namespace string) error { } func (te *TestEnvironment) GetDeploymentFromK8s(name, namespace string) (*kappsv1.Deployment, error) { - return te.K8sClientset.AppsV1().Deployments(namespace).Get(te.Context, name, kmetav1.GetOptions{}) + return te.K8sClientset.AppsV1().Deployments(namespace).Get(context.TODO(), name, kmetav1.GetOptions{}) } func (te *TestEnvironment) WaitForDeploymentReady(name, namespace, image string) error { @@ -323,7 +330,7 @@ func (te *TestEnvironment) WaitForDeploymentReady(name, namespace, image string) // if image is provided, then check if the deployment has correct image. if image != "" && gotDeployment.Spec.Template.Spec.Containers[0].Image != image { - err = fmt.Errorf("expected deployment (%s) image to be: %s, but found: %s", name, image, + err = fmt.Errorf("%w: expected deployment (%s) image to be: %s, but found: %s", ErrInvalidDeployment, name, image, gotDeployment.Spec.Template.Spec.Containers[0].Image, ) te.Logger.Debug(err.Error()) @@ -334,7 +341,7 @@ func (te *TestEnvironment) WaitForDeploymentReady(name, namespace, image string) if *gotDeployment.Spec.Replicas != gotDeployment.Status.UpdatedReplicas || *gotDeployment.Spec.Replicas != gotDeployment.Status.ReadyReplicas || *gotDeployment.Spec.Replicas != gotDeployment.Status.AvailableReplicas { - err = fmt.Errorf("waiting for deployment: %s to get ready", name) + err = fmt.Errorf("waiting for deployment: %s to get ready: %w", name, ErrDeploymentNotReady) te.Logger.Debug(err.Error()) return err } @@ -357,7 +364,7 @@ func (te *TestEnvironment) DeleteSubscriptionFromK8s(name, namespace string) err // delete with retries. return common.Retry(FewAttempts, Interval, func() error { // delete subscription from cluster. - err := te.K8sClient.Delete(te.Context, sub) + err := te.K8sClient.Delete(context.TODO(), sub) if err != nil && !kerrors.IsNotFound(err) { te.Logger.Debug(fmt.Sprintf("failed to delete subscription: %s "+ "in namespace: %s", name, te.TestConfigs.TestNamespace)) @@ -518,14 +525,14 @@ func (te *TestEnvironment) SetupEventingCR() error { func (te *TestEnvironment) DeleteEventingCR() error { return common.Retry(Attempts, Interval, func() error { - return client.IgnoreNotFound(te.K8sClient.Delete(te.Context, + return client.IgnoreNotFound(te.K8sClient.Delete(context.TODO(), fixtures.EventingCR(operatorv1alpha1.BackendType(te.TestConfigs.BackendType)))) }) } func (te *TestEnvironment) GetEventingCRFromK8s(name, namespace string) (*operatorv1alpha1.Eventing, error) { var eventingCR operatorv1alpha1.Eventing - err := te.K8sClient.Get(te.Context, ktypes.NamespacedName{ + err := te.K8sClient.Get(context.TODO(), ktypes.NamespacedName{ Name: name, Namespace: namespace, }, &eventingCR) @@ -533,7 +540,7 @@ func (te *TestEnvironment) GetEventingCRFromK8s(name, namespace string) (*operat } func (te *TestEnvironment) GetDeployment(name, namespace string) (*kappsv1.Deployment, error) { - return te.K8sClientset.AppsV1().Deployments(namespace).Get(te.Context, name, kmetav1.GetOptions{}) + return te.K8sClientset.AppsV1().Deployments(namespace).Get(context.TODO(), name, kmetav1.GetOptions{}) } func (te *TestEnvironment) WaitForEventingCRReady() error { @@ -551,13 +558,13 @@ func (te *TestEnvironment) WaitForEventingCRReady() error { } if gotEventingCR.Spec.Backend.Type != gotEventingCR.Status.ActiveBackend { - err := fmt.Errorf("waiting for Eventing CR to switch backend") - te.Logger.Debug(err.Error()) - return err + msg := "waiting for Eventing CR to switch backend" + te.Logger.Debug(msg) + return fmt.Errorf("%s: %w", msg, ErrWrongActiveType) } if gotEventingCR.Status.State != operatorv1alpha1.StateReady { - err := fmt.Errorf("waiting for Eventing CR to get ready state") + err := fmt.Errorf("waiting for Eventing CR to get ready state: %w", ErrEventingNotReady) te.Logger.Debug(err.Error()) return err } @@ -569,9 +576,9 @@ func (te *TestEnvironment) WaitForEventingCRReady() error { }) } -func (env *TestEnvironment) GetPeerAuthenticationFromK8s(name, namespace string) (*istiopkgsecurityv1beta1.PeerAuthentication, error) { - result, err := env.K8sDynamicClient.Resource(fixtures.PeerAuthenticationGVR()).Namespace( - namespace).Get(env.Context, name, kmetav1.GetOptions{}) +func (te *TestEnvironment) GetPeerAuthenticationFromK8s(name, namespace string) (*istiopkgsecurityv1beta1.PeerAuthentication, error) { + result, err := te.K8sDynamicClient.Resource(fixtures.PeerAuthenticationGVR()).Namespace( + namespace).Get(context.TODO(), name, kmetav1.GetOptions{}) if err != nil { return nil, err } diff --git a/internal/controller/errors/skip_unit_test.go b/internal/controller/errors/skip_unit_test.go index 55b52805..c237f0c5 100644 --- a/internal/controller/errors/skip_unit_test.go +++ b/internal/controller/errors/skip_unit_test.go @@ -5,17 +5,21 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + controllererrors "github.com/kyma-project/eventing-manager/internal/controller/errors" ) +var ErrGeneric = errors.New("some error") + func Test_NewSkippable(t *testing.T) { testCases := []struct { error error }{ {error: controllererrors.NewSkippable(nil)}, {error: controllererrors.NewSkippable(controllererrors.NewSkippable(nil))}, - {error: controllererrors.NewSkippable(fmt.Errorf("some error"))}, - {error: controllererrors.NewSkippable(controllererrors.NewSkippable(fmt.Errorf("some error")))}, + {error: controllererrors.NewSkippable(ErrGeneric)}, + {error: controllererrors.NewSkippable(controllererrors.NewSkippable(ErrGeneric))}, } for _, tc := range testCases { @@ -24,9 +28,7 @@ func Test_NewSkippable(t *testing.T) { t.Errorf("test NewSkippable retuned nil error") continue } - if err := errors.Unwrap(skippableErr); tc.error != err { - t.Errorf("test NewSkippable failed, want: %#v but got: %#v", tc.error, err) - } + require.ErrorIs(t, skippableErr, tc.error) } } @@ -43,17 +45,17 @@ func Test_IsSkippable(t *testing.T) { }, { name: "skippable error, should be skipped", - givenError: controllererrors.NewSkippable(fmt.Errorf("some errore")), + givenError: controllererrors.NewSkippable(ErrGeneric), wantSkippable: true, }, { name: "not-skippable error, should not be skipped", - givenError: fmt.Errorf("some error"), + givenError: ErrGeneric, wantSkippable: false, }, { name: "not-skippable error which wraps a skippable error, should not be skipped", - givenError: fmt.Errorf("some error %w", controllererrors.NewSkippable(fmt.Errorf("some error"))), + givenError: fmt.Errorf("some error %w", controllererrors.NewSkippable(ErrGeneric)), wantSkippable: false, }, } diff --git a/internal/controller/eventing/subscription/eventmesh/reconciler.go b/internal/controller/eventing/subscription/eventmesh/reconciler.go index b513bb7b..2ad1d7cd 100644 --- a/internal/controller/eventing/subscription/eventmesh/reconciler.go +++ b/internal/controller/eventing/subscription/eventmesh/reconciler.go @@ -44,7 +44,6 @@ type syncConditionWebhookCallStatusFunc func(subscription *eventingv1alpha2.Subs // Reconciler reconciles a Subscription object. type Reconciler struct { - ctx context.Context client.Client logger *logger.Logger recorder record.EventRecorder @@ -70,7 +69,7 @@ const ( backendType = "EventMesh" ) -func NewReconciler(ctx context.Context, client client.Client, logger *logger.Logger, recorder record.EventRecorder, +func NewReconciler(client client.Client, logger *logger.Logger, recorder record.EventRecorder, cfg env.Config, cleaner cleaner.Cleaner, eventMeshBackend eventmesh.Backend, credential *eventmesh.OAuth2ClientCredentials, mapper backendutils.NameMapper, validator sink.Validator, collector *metrics.Collector, domain string, @@ -81,7 +80,6 @@ func NewReconciler(ctx context.Context, client client.Client, logger *logger.Log panic(err) } return &Reconciler{ - ctx: ctx, Client: client, logger: logger, recorder: recorder, @@ -359,7 +357,7 @@ func syncConditionWebhookCallStatus(subscription *eventingv1alpha2.Subscription) func (r *Reconciler) syncAPIRule(ctx context.Context, subscription *eventingv1alpha2.Subscription, logger *zap.SugaredLogger, ) (*apigatewayv1beta1.APIRule, error) { - if err := r.sinkValidator.Validate(subscription); err != nil { + if err := r.sinkValidator.Validate(ctx, subscription); err != nil { return nil, err } @@ -739,7 +737,7 @@ func (r *Reconciler) emitConditionEvent(subscription *eventingv1alpha2.Subscript } // SetupUnmanaged creates a controller under the client control. -func (r *Reconciler) SetupUnmanaged(mgr kctrl.Manager) error { +func (r *Reconciler) SetupUnmanaged(ctx context.Context, mgr kctrl.Manager) error { ctru, err := controller.NewUnmanaged(reconcilerName, mgr, controller.Options{Reconciler: r}) if err != nil { return fmt.Errorf("failed to create unmanaged controller: %w", err) @@ -757,7 +755,7 @@ func (r *Reconciler) SetupUnmanaged(mgr kctrl.Manager) error { } go func(r *Reconciler, c controller.Controller) { - if err := c.Start(r.ctx); err != nil { + if err := c.Start(ctx); err != nil { r.namedLogger().Fatalw("Failed to start controller", "name", reconcilerName, "error", err) } @@ -767,7 +765,7 @@ func (r *Reconciler) SetupUnmanaged(mgr kctrl.Manager) error { } // checkStatusActive checks if the subscription is active and if not, sets a timer for retry. -func (r *Reconciler) checkStatusActive(subscription *eventingv1alpha2.Subscription) (active bool, err error) { +func (r *Reconciler) checkStatusActive(subscription *eventingv1alpha2.Subscription) (bool, error) { if subscription.Status.Backend.EventMeshSubscriptionStatus == nil { return false, nil } @@ -788,13 +786,13 @@ func (r *Reconciler) checkStatusActive(subscription *eventingv1alpha2.Subscripti } // check the timeout - if t0, er := time.Parse(time.RFC3339, subscription.Status.Backend.FailedActivation); er != nil { - err = er + if t0, err := time.Parse(time.RFC3339, subscription.Status.Backend.FailedActivation); err != nil { + return false, err } else if t1.Sub(t0) > timeoutRetryActiveEmsStatus { - err = xerrors.Errorf("timeout waiting for the subscription to be active: %s", subscription.Name) + return false, errors.Errorf("timeout waiting for the subscription to be active: %s", subscription.Name) } - return false, err + return false, nil } // checkLastFailedDelivery checks if LastFailedDelivery exists and if it happened after LastSuccessfulDelivery. @@ -809,7 +807,7 @@ func checkLastFailedDelivery(subscription *eventingv1alpha2.Subscription) (bool, var err error var lastFailedDeliveryTime time.Time if lastFailedDeliveryTime, err = time.Parse(time.RFC3339, lastFailed); err != nil { - return true, xerrors.Errorf("failed to parse LastFailedDelivery: %v", err) + return true, errors.Errorf("failed to parse LastFailedDelivery: %v", err) } // Check if LastSuccessfulDelivery exists. If not, LastFailedDelivery happened last. @@ -821,7 +819,7 @@ func checkLastFailedDelivery(subscription *eventingv1alpha2.Subscription) (bool, // Try to parse LastSuccessfulDelivery. var lastSuccessfulDeliveryTime time.Time if lastSuccessfulDeliveryTime, err = time.Parse(time.RFC3339, lastSuccessful); err != nil { - return true, xerrors.Errorf("failed to parse LastSuccessfulDelivery: %v", err) + return true, errors.Errorf("failed to parse LastSuccessfulDelivery: %v", err) } return lastFailedDeliveryTime.After(lastSuccessfulDeliveryTime), nil diff --git a/internal/controller/eventing/subscription/eventmesh/reconciler_internal_integration_test.go b/internal/controller/eventing/subscription/eventmesh/reconciler_internal_integration_test.go index 3d431dab..533e3285 100644 --- a/internal/controller/eventing/subscription/eventmesh/reconciler_internal_integration_test.go +++ b/internal/controller/eventing/subscription/eventmesh/reconciler_internal_integration_test.go @@ -43,7 +43,6 @@ import ( // and if so with how much initial delay. Returning error or a `Result{Requeue: true}` would cause the reconciliation to be requeued. // Everything else is mocked since we are only interested in the logic of the Reconcile method and not the reconciler dependencies. func TestReconciler_Reconcile(t *testing.T) { - ctx := context.Background() req := require.New(t) col := metrics.NewCollector() @@ -77,8 +76,8 @@ func TestReconciler_Reconcile(t *testing.T) { backendSyncErr := errors.New("backend sync error") backendDeleteErr := errors.New("backend delete error") validatorErr := errors.New("invalid sink") - happyValidator := sink.ValidatorFunc(func(s *eventingv1alpha2.Subscription) error { return nil }) - unhappyValidator := sink.ValidatorFunc(func(s *eventingv1alpha2.Subscription) error { return validatorErr }) + happyValidator := sink.ValidatorFunc(func(_ context.Context, s *eventingv1alpha2.Subscription) error { return nil }) + unhappyValidator := sink.ValidatorFunc(func(_ context.Context, s *eventingv1alpha2.Subscription) error { return validatorErr }) testCases := []struct { name string @@ -94,7 +93,7 @@ func TestReconciler_Reconcile(t *testing.T) { te := setupTestEnvironment(t, testSub) te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -116,7 +115,7 @@ func TestReconciler_Reconcile(t *testing.T) { givenReconcilerSetup: func() *Reconciler { te := setupTestEnvironment(t) te.backend.On("Initialize", mock.Anything).Return(nil) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -139,7 +138,7 @@ func TestReconciler_Reconcile(t *testing.T) { te := setupTestEnvironment(t, testSub) te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(false, backendSyncErr) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -162,7 +161,7 @@ func TestReconciler_Reconcile(t *testing.T) { te := setupTestEnvironment(t, testSubUnderDeletion) te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("DeleteSubscription", mock.Anything).Return(backendDeleteErr) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -184,7 +183,7 @@ func TestReconciler_Reconcile(t *testing.T) { givenReconcilerSetup: func() *Reconciler { te := setupTestEnvironment(t, testSub) te.backend.On("Initialize", mock.Anything).Return(nil) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -207,7 +206,7 @@ func TestReconciler_Reconcile(t *testing.T) { te := setupTestEnvironment(t, testSubPaused) te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -235,8 +234,8 @@ func TestReconciler_Reconcile(t *testing.T) { Name: tc.givenSubscription.Name, }} res, err := reconciler.Reconcile(context.Background(), r) - req.Equal(res, tc.wantReconcileResult) - req.Equal(err, tc.wantReconcileError) + req.Equal(tc.wantReconcileResult, res) + req.Equal(tc.wantReconcileError, err) }) } } @@ -259,7 +258,7 @@ func TestReconciler_APIRuleConfig(t *testing.T) { eventingtesting.WithEmsSubscriptionStatus(string(types.SubscriptionStatusActive)), ) - validator := sink.ValidatorFunc(func(s *eventingv1alpha2.Subscription) error { return nil }) + validator := sink.ValidatorFunc(func(_ context.Context, s *eventingv1alpha2.Subscription) error { return nil }) col := metrics.NewCollector() @@ -280,7 +279,7 @@ func TestReconciler_APIRuleConfig(t *testing.T) { te.credentials = credentials te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -310,7 +309,7 @@ func TestReconciler_APIRuleConfig(t *testing.T) { te.credentials = credentials te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -389,7 +388,7 @@ func TestReconciler_APIRuleConfig_Upgrade(t *testing.T) { eventingtesting.WithEmsSubscriptionStatus(string(types.SubscriptionStatusActive)), ) - validator := sink.ValidatorFunc(func(s *eventingv1alpha2.Subscription) error { return nil }) + validator := sink.ValidatorFunc(func(_ context.Context, s *eventingv1alpha2.Subscription) error { return nil }) col := metrics.NewCollector() testCases := []struct { @@ -410,7 +409,7 @@ func TestReconciler_APIRuleConfig_Upgrade(t *testing.T) { te.credentials = credentials te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -446,7 +445,7 @@ func TestReconciler_APIRuleConfig_Upgrade(t *testing.T) { te.credentials = credentials te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) - return NewReconciler(ctx, + return NewReconciler( te.fakeClient, te.logger, te.recorder, @@ -575,7 +574,7 @@ func TestReconciler_APIRuleConfig_Upgrade(t *testing.T) { func TestReconciler_PreserveBackendHashes(t *testing.T) { ctx := context.Background() collector := metrics.NewCollector() - validator := sink.ValidatorFunc(func(s *eventingv1alpha2.Subscription) error { return nil }) + validator := sink.ValidatorFunc(func(_ context.Context, s *eventingv1alpha2.Subscription) error { return nil }) const ( ev2hash = int64(118518533334734) @@ -612,7 +611,7 @@ func TestReconciler_PreserveBackendHashes(t *testing.T) { te := setupTestEnvironment(t, s) te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) - return NewReconciler(ctx, te.fakeClient, te.logger, te.recorder, te.cfg, te.cleaner, + return NewReconciler(te.fakeClient, te.logger, te.recorder, te.cfg, te.cleaner, te.backend, te.credentials, te.mapper, validator, collector, utils.Domain), te.fakeClient }, wantEv2Hash: ev2hash, @@ -639,7 +638,7 @@ func TestReconciler_PreserveBackendHashes(t *testing.T) { te := setupTestEnvironment(t, s) te.backend.On("Initialize", mock.Anything).Return(nil) te.backend.On("SyncSubscription", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) - return NewReconciler(ctx, te.fakeClient, te.logger, te.recorder, te.cfg, te.cleaner, + return NewReconciler(te.fakeClient, te.logger, te.recorder, te.cfg, te.cleaner, te.backend, te.credentials, te.mapper, validator, collector, utils.Domain), te.fakeClient }, wantEv2Hash: ev2hash, @@ -1249,11 +1248,11 @@ func Test_checkStatusActive(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { gotStatus, err := r.checkStatusActive(tc.subscription) - assert.Equal(t, tc.wantStatus, gotStatus) + require.Equal(t, tc.wantStatus, gotStatus) if tc.wantError == nil { - assert.NoError(t, err) + require.NoError(t, err) } else { - assert.Error(t, tc.wantError, err) + require.ErrorContains(t, err, tc.wantError.Error()) } }) } @@ -1346,11 +1345,11 @@ func Test_checkLastFailedDelivery(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { result, err := checkLastFailedDelivery(tc.givenSubscription) - assert.Equal(t, tc.wantResult, result) + require.Equal(t, tc.wantResult, result) if tc.wantError == nil { - assert.NoError(t, err) + require.NoError(t, err) } else { - assert.Error(t, tc.wantError, err) + require.ErrorContains(t, err, tc.wantError.Error()) } }) } diff --git a/internal/controller/eventing/subscription/eventmesh/test/reconciler_integration_test.go b/internal/controller/eventing/subscription/eventmesh/test/reconciler_integration_test.go index d74691e3..4723c7fc 100644 --- a/internal/controller/eventing/subscription/eventmesh/test/reconciler_integration_test.go +++ b/internal/controller/eventing/subscription/eventmesh/test/reconciler_integration_test.go @@ -13,6 +13,7 @@ import ( "github.com/onsi/gomega" gomegatypes "github.com/onsi/gomega/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" kcorev1 "k8s.io/api/core/v1" kmetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -693,7 +694,7 @@ func Test_FixingSinkAndApiRule(t *testing.T) { // check if the created APIRule is as required apiRules, err := getAPIRulesList(ctx, subscriberSvc) - assert.NoError(t, err) + require.NoError(t, err) apiRuleUpdated := filterAPIRulesForASvc(apiRules, subscriberSvc) getAPIRuleAssert(ctx, g, &apiRuleUpdated).Should(gomega.And( eventingtesting.HaveNotEmptyHost(), diff --git a/internal/controller/eventing/subscription/eventmesh/test/utils.go b/internal/controller/eventing/subscription/eventmesh/test/utils.go index ef1e20c7..f5d829bf 100644 --- a/internal/controller/eventing/subscription/eventmesh/test/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/test/utils.go @@ -139,7 +139,7 @@ func setupSuite() error { // setup eventMesh reconciler recorder := k8sManager.GetEventRecorderFor("eventing-controller") - sinkValidator := sink.NewValidator(context.Background(), k8sManager.GetClient(), recorder) + sinkValidator := sink.NewValidator(k8sManager.GetClient(), recorder) credentials := &backendeventmesh.OAuth2ClientCredentials{ ClientID: "foo-client-id", ClientSecret: "foo-client-secret", @@ -149,7 +149,6 @@ func setupSuite() error { emTestEnsemble.envConfig = getEnvConfig() col := metrics.NewCollector() testReconciler := subscriptioncontrollereventmesh.NewReconciler( - context.Background(), k8sManager.GetClient(), defaultLogger, recorder, @@ -163,7 +162,7 @@ func setupSuite() error { testutils.Domain, ) - if err = testReconciler.SetupUnmanaged(k8sManager); err != nil { + if err = testReconciler.SetupUnmanaged(context.Background(), k8sManager); err != nil { return err } diff --git a/internal/controller/eventing/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go index a5f4c5a5..067ce78c 100644 --- a/internal/controller/eventing/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go +++ b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/reconciler_integration_test.go @@ -120,8 +120,8 @@ func Test_UpdateWebhookAuthConfig(t *testing.T) { // ensure expected EventMesh mock requests require.NotEqual(t, webhookAuthHashBefore, webhookAuthHashAfter) require.Equal(t, deleteRequestsBefore, deleteRequestsAfter) - require.Equal(t, patchRequestsBefore, 0) - require.Equal(t, patchRequestsAfter, 1) + require.Equal(t, 0, patchRequestsBefore) + require.Equal(t, 1, patchRequestsAfter) // cleanup require.NoError(t, tearDownSuite()) diff --git a/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go index d1ade3b4..cd637a19 100644 --- a/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/testwebhookauth/utils.go @@ -140,12 +140,11 @@ func setupSuite() error { // setup eventMesh reconciler recorder := k8sManager.GetEventRecorderFor("eventing-controller") - sinkValidator := sink.NewValidator(context.Background(), k8sManager.GetClient(), recorder) + sinkValidator := sink.NewValidator(k8sManager.GetClient(), recorder) emTestEnsemble.envConfig = getEnvConfig() eventMeshBackend = backendeventmesh.NewEventMesh(credentials, emTestEnsemble.nameMapper, defaultLogger) col := metrics.NewCollector() testReconciler = subscriptioncontrollereventmesh.NewReconciler( - context.Background(), k8sManager.GetClient(), defaultLogger, recorder, @@ -159,7 +158,7 @@ func setupSuite() error { testutils.Domain, ) - if err = testReconciler.SetupUnmanaged(k8sManager); err != nil { + if err = testReconciler.SetupUnmanaged(context.Background(), k8sManager); err != nil { return err } diff --git a/internal/controller/eventing/subscription/eventmesh/utils.go b/internal/controller/eventing/subscription/eventmesh/utils.go index 286ac1b1..a8265050 100644 --- a/internal/controller/eventing/subscription/eventmesh/utils.go +++ b/internal/controller/eventing/subscription/eventmesh/utils.go @@ -13,6 +13,8 @@ import ( eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" ) +var ErrInvalidSink = errors.New("invalid sink") + // isInDeletion checks if the Subscription shall be deleted. func isInDeletion(subscription *eventingv1alpha2.Subscription) bool { return !subscription.DeletionTimestamp.IsZero() @@ -55,7 +57,7 @@ func removeFinalizer(sub *eventingv1alpha2.Subscription) { func getSvcNsAndName(url string) (string, string, error) { parts := strings.Split(url, ".") if len(parts) < 2 { - return "", "", fmt.Errorf("invalid sinkURL for cluster local svc: %s", url) + return "", "", fmt.Errorf("%w url: %s", ErrInvalidSink, url) } return parts[1], parts[0], nil } diff --git a/internal/controller/eventing/subscription/jetstream/matchers_test.go b/internal/controller/eventing/subscription/jetstream/matchers_test.go index 0017b63b..c389d56f 100644 --- a/internal/controller/eventing/subscription/jetstream/matchers_test.go +++ b/internal/controller/eventing/subscription/jetstream/matchers_test.go @@ -40,6 +40,7 @@ func BeJetStreamSubscriptionWithSubject(source, subject string, } result := info.Config.FilterSubject == js.GetJetStreamSubject(source, subject, typeMatching) if !result { + //nolint: goerr113 // no production code, but test helper functionality return false, fmt.Errorf( "BeJetStreamSubscriptionWithSubject expected %v to be equal to %v", info.Config.FilterSubject, diff --git a/internal/controller/eventing/subscription/jetstream/reconciler.go b/internal/controller/eventing/subscription/jetstream/reconciler.go index 8bbc07f1..87421573 100644 --- a/internal/controller/eventing/subscription/jetstream/reconciler.go +++ b/internal/controller/eventing/subscription/jetstream/reconciler.go @@ -38,7 +38,6 @@ const ( type Reconciler struct { client.Client - ctx context.Context Backend jetstream.Backend recorder record.EventRecorder logger *logger.Logger @@ -48,13 +47,12 @@ type Reconciler struct { collector *metrics.Collector } -func NewReconciler(ctx context.Context, client client.Client, jsBackend jetstream.Backend, +func NewReconciler(client client.Client, jsBackend jetstream.Backend, logger *logger.Logger, recorder record.EventRecorder, cleaner cleaner.Cleaner, defaultSinkValidator sink.Validator, collector *metrics.Collector, ) *Reconciler { reconciler := &Reconciler{ Client: client, - ctx: ctx, Backend: jsBackend, recorder: recorder, logger: logger, @@ -67,7 +65,7 @@ func NewReconciler(ctx context.Context, client client.Client, jsBackend jetstrea } // SetupUnmanaged creates a controller under the client control. -func (r *Reconciler) SetupUnmanaged(mgr kctrl.Manager) error { +func (r *Reconciler) SetupUnmanaged(ctx context.Context, mgr kctrl.Manager) error { ctru, err := controller.NewUnmanaged(reconcilerName, mgr, controller.Options{Reconciler: r}) if err != nil { r.namedLogger().Errorw("Failed to create unmanaged controller", "error", err) @@ -87,7 +85,7 @@ func (r *Reconciler) SetupUnmanaged(mgr kctrl.Manager) error { } go func(r *Reconciler, c controller.Controller) { - if err := c.Start(r.ctx); err != nil { + if err := c.Start(ctx); err != nil { r.namedLogger().Fatalw("Failed to start controller", "error", err) } }(r, ctru) @@ -140,7 +138,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req kctrl.Request) (kctrl.Re } // Check for valid sink - if err := r.sinkValidator.Validate(desiredSubscription); err != nil { + if err := r.sinkValidator.Validate(ctx, desiredSubscription); err != nil { if deleteErr := r.Backend.DeleteSubscriptionsOnly(desiredSubscription); deleteErr != nil { r.namedLogger().Errorw( "Failed to delete JetStream subscriptions", diff --git a/internal/controller/eventing/subscription/jetstream/reconciler_integration_test.go b/internal/controller/eventing/subscription/jetstream/reconciler_integration_test.go index 03695bc8..ec8dd23a 100644 --- a/internal/controller/eventing/subscription/jetstream/reconciler_integration_test.go +++ b/internal/controller/eventing/subscription/jetstream/reconciler_integration_test.go @@ -1,6 +1,7 @@ package jetstream_test import ( + "context" "fmt" "log" "os" @@ -189,7 +190,7 @@ func Test_Idempotency(t *testing.T) { "newLabel": "label", } sub.ObjectMeta.Labels = newLabels - require.NoError(t, jsTestEnsemble.K8sClient.Update(jsTestEnsemble.Ctx, sub)) + require.NoError(t, jsTestEnsemble.K8sClient.Update(context.Background(), sub)) // check the labels got updated assert.Equal(t, sub.Labels, newLabels) @@ -532,10 +533,10 @@ func Test_ChangeSubscription(t *testing.T) { // when t.Log("change and update the subscription") - require.NoError(t, EventuallyUpdateSubscriptionOnK8s(jsTestEnsemble.Ctx, jsTestEnsemble.Ensemble, + require.NoError(t, EventuallyUpdateSubscriptionOnK8s(context.Background(), jsTestEnsemble.Ensemble, sub, func(sub *eventingv1alpha2.Subscription) error { tc.changeSubscription(sub) - return jsTestEnsemble.K8sClient.Update(jsTestEnsemble.Ctx, sub) + return jsTestEnsemble.K8sClient.Update(context.Background(), sub) })) // then diff --git a/internal/controller/eventing/subscription/jetstream/reconciler_internal_unit_test.go b/internal/controller/eventing/subscription/jetstream/reconciler_internal_unit_test.go index 9ca5e2ee..bb1a2108 100644 --- a/internal/controller/eventing/subscription/jetstream/reconciler_internal_unit_test.go +++ b/internal/controller/eventing/subscription/jetstream/reconciler_internal_unit_test.go @@ -41,7 +41,6 @@ const ( // Everything else is mocked since we are only interested in the logic of the Reconcile method // and not the reconciler dependencies. func Test_Reconcile(t *testing.T) { - ctx := context.Background() req := require.New(t) // A subscription with the correct Finalizer, ready for reconciliation with the backend. @@ -62,8 +61,8 @@ func Test_Reconcile(t *testing.T) { missingSubSyncErr := jetstream.ErrMissingSubscription backendDeleteErr := errors.New("backend delete error") validatorErr := errors.New("invalid sink") - happyValidator := sink.ValidatorFunc(func(s *eventingv1alpha2.Subscription) error { return nil }) - unhappyValidator := sink.ValidatorFunc(func(s *eventingv1alpha2.Subscription) error { return validatorErr }) + happyValidator := sink.ValidatorFunc(func(_ context.Context, s *eventingv1alpha2.Subscription) error { return nil }) + unhappyValidator := sink.ValidatorFunc(func(_ context.Context, s *eventingv1alpha2.Subscription) error { return validatorErr }) collector := metrics.NewCollector() testCases := []struct { @@ -82,7 +81,7 @@ func Test_Reconcile(t *testing.T) { te.Backend.On("GetJetStreamSubjects", mock.Anything, mock.Anything, mock.Anything).Return( []string{eventingtesting.JetStreamSubject}) te.Backend.On("GetConfig", mock.Anything).Return(env.NATSConfig{JSStreamName: "sap"}) - return NewReconciler(ctx, + return NewReconciler( te.Client, te.Backend, te.Logger, @@ -100,7 +99,7 @@ func Test_Reconcile(t *testing.T) { givenSubscription: testSub, givenReconcilerSetup: func() (*Reconciler, *backendjetstreammocks.Backend) { te := setupTestEnvironment(t) - return NewReconciler(ctx, + return NewReconciler( te.Client, te.Backend, te.Logger, @@ -118,7 +117,7 @@ func Test_Reconcile(t *testing.T) { givenSubscription: eventingtesting.NewSubscription(subscriptionName, namespaceName), givenReconcilerSetup: func() (*Reconciler, *backendjetstreammocks.Backend) { te := setupTestEnvironment(t, eventingtesting.NewSubscription(subscriptionName, namespaceName)) - return NewReconciler(ctx, + return NewReconciler( te.Client, te.Backend, te.Logger, @@ -140,8 +139,7 @@ func Test_Reconcile(t *testing.T) { te.Backend.On("GetJetStreamSubjects", mock.Anything, mock.Anything, mock.Anything).Return( []string{eventingtesting.JetStreamSubject}) te.Backend.On("GetConfig", mock.Anything).Return(env.NATSConfig{JSStreamName: "sap"}) - return NewReconciler(ctx, - + return NewReconciler( te.Client, te.Backend, te.Logger, @@ -164,7 +162,7 @@ func Test_Reconcile(t *testing.T) { te.Backend.On("GetJetStreamSubjects", mock.Anything, mock.Anything, mock.Anything).Return( []string{eventingtesting.JetStreamSubject}) te.Backend.On("GetConfig", mock.Anything).Return(env.NATSConfig{JSStreamName: "sap"}) - return NewReconciler(ctx, + return NewReconciler( te.Client, te.Backend, te.Logger, @@ -183,7 +181,7 @@ func Test_Reconcile(t *testing.T) { givenReconcilerSetup: func() (*Reconciler, *backendjetstreammocks.Backend) { te := setupTestEnvironment(t, testSubUnderDeletion) te.Backend.On("DeleteSubscription", mock.Anything).Return(backendDeleteErr) - return NewReconciler(ctx, + return NewReconciler( te.Client, te.Backend, te.Logger, @@ -205,7 +203,7 @@ func Test_Reconcile(t *testing.T) { te.Backend.On("GetJetStreamSubjects", mock.Anything, mock.Anything, mock.Anything).Return( []string{eventingtesting.JetStreamSubject}) te.Backend.On("GetConfig", mock.Anything).Return(env.NATSConfig{JSStreamName: "sap"}) - return NewReconciler(ctx, + return NewReconciler( te.Client, te.Backend, te.Logger, @@ -234,7 +232,7 @@ func Test_Reconcile(t *testing.T) { res, err := reconciler.Reconcile(context.Background(), r) // then - req.Equal(res, tc.wantReconcileResult) + req.Equal(tc.wantReconcileResult, res) req.ErrorIs(err, tc.wantReconcileError) mockedBackend.AssertExpectations(t) }) @@ -289,7 +287,7 @@ func Test_handleSubscriptionDeletion(t *testing.T) { ) testEnvironment := setupTestEnvironment(t, sub) - ctx, r, mockedBackend := testEnvironment.Context, testEnvironment.Reconciler, testEnvironment.Backend + ctx, r, mockedBackend := context.Background(), testEnvironment.Reconciler, testEnvironment.Backend if testCase.wantDeleteCall { if errors.Is(testCase.wantError, errFailedToDeleteSub) { @@ -367,7 +365,7 @@ func Test_addFinalizer(t *testing.T) { _, err := r.addFinalizer(ctx, sub) require.NoError(t, err) - fetchedSub, err := fetchTestSubscription(testEnvironment.Context, r) + fetchedSub, err := fetchTestSubscription(context.Background(), r) require.NoError(t, err) if tC.wantErrorMessage != "" { @@ -453,7 +451,7 @@ func Test_syncSubscriptionStatus(t *testing.T) { sub := testCase.givenSub testEnvironment := setupTestEnvironment(t, sub) - ctx, r := testEnvironment.Context, testEnvironment.Reconciler + ctx, r := context.Background(), testEnvironment.Reconciler // when err := r.syncSubscriptionStatus(ctx, sub, testCase.givenError, r.namedLogger()) @@ -632,7 +630,7 @@ func Test_updateStatus(t *testing.T) { // then require.NoError(t, updateStatusErr) - fetchedSub, err := fetchTestSubscription(testEnvironment.Context, r) + fetchedSub, err := fetchTestSubscription(context.Background(), r) require.NoError(t, err) require.Equal(t, tC.wantChange, fetchedSub.ResourceVersion != resourceVersionBefore) @@ -705,7 +703,7 @@ func Test_updateSubscription(t *testing.T) { } // then - fetchedSub, err := fetchTestSubscription(testEnvironment.Context, r) + fetchedSub, err := fetchTestSubscription(context.Background(), r) require.NoError(t, err) require.Equal(t, tC.wantChange, fetchedSub.ResourceVersion != resourceVersionBefore) @@ -723,7 +721,6 @@ func Test_updateSubscription(t *testing.T) { // TestEnvironment provides mocked resources for tests. type TestEnvironment struct { - Context context.Context Client client.Client Backend *backendjetstreammocks.Backend Reconciler *Reconciler @@ -735,7 +732,6 @@ type TestEnvironment struct { // setupTestEnvironment is a TestEnvironment constructor. func setupTestEnvironment(t *testing.T, objs ...client.Object) *TestEnvironment { mockedBackend := &backendjetstreammocks.Backend{} - ctx := context.Background() fakeClient := createFakeClientBuilder(t).WithObjects(objs...).WithStatusSubresource(objs...).Build() recorder := &record.FakeRecorder{} @@ -744,7 +740,7 @@ func setupTestEnvironment(t *testing.T, objs ...client.Object) *TestEnvironment t.Fatalf("initialize logger failed: %v", err) } jsCleaner := cleaner.NewJetStreamCleaner(defaultLogger) - defaultSinkValidator := sink.NewValidator(ctx, fakeClient, recorder) + defaultSinkValidator := sink.NewValidator(fakeClient, recorder) r := Reconciler{ Backend: mockedBackend, @@ -757,7 +753,6 @@ func setupTestEnvironment(t *testing.T, objs ...client.Object) *TestEnvironment } return &TestEnvironment{ - Context: ctx, Client: fakeClient, Backend: mockedBackend, Reconciler: &r, diff --git a/internal/controller/eventing/subscription/jetstream/test_utils_test.go b/internal/controller/eventing/subscription/jetstream/test_utils_test.go index a7120e4e..772628f2 100644 --- a/internal/controller/eventing/subscription/jetstream/test_utils_test.go +++ b/internal/controller/eventing/subscription/jetstream/test_utils_test.go @@ -72,7 +72,6 @@ type Ensemble struct { DefaultSubscriptionConfig env.DefaultSubscriptionConfig SubscriberSvc *kcorev1.Service Cancel context.CancelFunc - Ctx context.Context G *gomega.GomegaWithT T *testing.T } @@ -92,7 +91,6 @@ type Want struct { } func setupSuite() error { - ctx := context.Background() useExistingCluster := useExistingCluster natsPort, err := eventingtesting.GetFreePort() @@ -103,7 +101,6 @@ func setupSuite() error { log.Printf("NATS server with JetStream started %v", natsServer.ClientURL()) ens := &Ensemble{ - Ctx: ctx, DefaultSubscriptionConfig: env.DefaultSubscriptionConfig{ MaxInFlightMessages: 1, }, @@ -192,17 +189,17 @@ func startReconciler() error { k8sClient := k8sManager.GetClient() recorder := k8sManager.GetEventRecorderFor("eventing-controller-jetstream") - jsTestEnsemble.Reconciler = subscriptioncontrollerjetstream.NewReconciler(ctx, + jsTestEnsemble.Reconciler = subscriptioncontrollerjetstream.NewReconciler( k8sClient, jetStreamHandler, defaultLogger, recorder, cleaner, - sink.NewValidator(ctx, k8sClient, recorder), + sink.NewValidator(k8sClient, recorder), metricsCollector, ) - if err := jsTestEnsemble.Reconciler.SetupUnmanaged(k8sManager); err != nil { + if err := jsTestEnsemble.Reconciler.SetupUnmanaged(ctx, k8sManager); err != nil { return err } @@ -268,7 +265,7 @@ func testSubscriptionOnNATS(g *gomega.GomegaWithT, subscription *eventingv1alpha // testSubscriptionDeletion deletes the subscription and ensures it is not found anymore on the apiserver. func testSubscriptionDeletion(g *gomega.GomegaWithT, subscription *eventingv1alpha2.Subscription) { g.Eventually(func() error { - return jsTestEnsemble.K8sClient.Delete(jsTestEnsemble.Ctx, subscription) + return jsTestEnsemble.K8sClient.Delete(context.Background(), subscription) }, SmallTimeout, SmallPollingInterval).ShouldNot(gomega.HaveOccurred()) IsSubscriptionDeletedOnK8s(g, jsTestEnsemble.Ensemble, subscription). Should(eventingtesting.HaveNotFoundSubscription(), "Failed to delete subscription") @@ -374,7 +371,7 @@ func IsSubscriptionDeletedOnK8s(g *gomega.WithT, ens *Ensemble, Namespace: subscription.Namespace, Name: subscription.Name, } - if err := ens.K8sClient.Get(ens.Ctx, lookupKey, subscription); err != nil { + if err := ens.K8sClient.Get(context.Background(), lookupKey, subscription); err != nil { return kerrors.IsNotFound(err) } return false @@ -457,7 +454,7 @@ func createSubscriberSvcInK8s(ens *Ensemble) error { if ens.SubscriberSvc.Namespace != "default " { namespace := fixtureNamespace(ens.SubscriberSvc.Namespace) err := doRetry(func() error { - if err := ens.K8sClient.Create(ens.Ctx, namespace); !kerrors.IsAlreadyExists(err) { + if err := ens.K8sClient.Create(context.Background(), namespace); !kerrors.IsAlreadyExists(err) { return err } return nil @@ -468,7 +465,7 @@ func createSubscriberSvcInK8s(ens *Ensemble) error { } return doRetry(func() error { - return ens.K8sClient.Create(ens.Ctx, ens.SubscriberSvc) + return ens.K8sClient.Create(context.Background(), ens.SubscriberSvc) }, "Failed to create the subscriber service") } @@ -478,7 +475,7 @@ func EnsureNamespaceCreatedForSub(t *testing.T, ens *Ensemble, subscription *eve if subscription.Namespace != "default " { // create testing namespace namespace := fixtureNamespace(subscription.Namespace) - err := ens.K8sClient.Create(ens.Ctx, namespace) + err := ens.K8sClient.Create(context.Background(), namespace) if !kerrors.IsAlreadyExists(err) { require.NoError(t, err) } @@ -490,13 +487,13 @@ func EnsureNamespaceCreatedForSub(t *testing.T, ens *Ensemble, subscription *eve func ensureSubscriptionCreated(ens *Ensemble, subscription *eventingv1alpha2.Subscription) error { // create subscription on cluster return doRetry(func() error { - return ens.K8sClient.Create(ens.Ctx, subscription) + return ens.K8sClient.Create(context.Background(), subscription) }, "failed to create a subscription") } // EnsureK8sResourceNotCreated ensures that the obj creation in K8s fails. func EnsureK8sResourceNotCreated(t *testing.T, ens *Ensemble, obj client.Object, err error) { - require.Equal(t, ens.K8sClient.Create(ens.Ctx, obj), err) + require.Equal(t, ens.K8sClient.Create(context.Background(), obj), err) } func fixtureNamespace(name string) *kcorev1.Namespace { @@ -521,7 +518,7 @@ func getSubscriptionOnK8S(g *gomega.WithT, ens *Ensemble, Namespace: subscription.Namespace, Name: subscription.Name, } - if err := ens.K8sClient.Get(ens.Ctx, lookupKey, subscription); err != nil { + if err := ens.K8sClient.Get(context.Background(), lookupKey, subscription); err != nil { return &eventingv1alpha2.Subscription{} } return subscription @@ -533,7 +530,7 @@ func getSubscriptionOnK8S(g *gomega.WithT, ens *Ensemble, func getK8sEvents(g *gomega.WithT, ens *Ensemble) gomega.AsyncAssertion { eventList := kcorev1.EventList{} return g.Eventually(func() kcorev1.EventList { - err := ens.K8sClient.List(ens.Ctx, &eventList, client.InNamespace(ens.SubscriberSvc.Namespace)) + err := ens.K8sClient.List(context.Background(), &eventList, client.InNamespace(ens.SubscriberSvc.Namespace)) if err != nil { return kcorev1.EventList{} } diff --git a/internal/controller/operator/eventing/controller.go b/internal/controller/operator/eventing/controller.go index 85494795..e07f3923 100644 --- a/internal/controller/operator/eventing/controller.go +++ b/internal/controller/operator/eventing/controller.go @@ -71,6 +71,14 @@ const ( SubscriptionExistsErrMessage = "cannot delete the eventing module as subscription exists" ) +var ( + ErrSubscriptionExists = errors.New(SubscriptionExistsErrMessage) + ErrUnsupportedBackedType = errors.New("backend type not supported") + ErrNatsModuleMissing = errors.New("NATS module has to be installed") + ErrNATSServerUnavailable = errors.New(NatsServerNotAvailableMsg) + ErrAPIGatewayModuleMissing = errors.New("API-Gateway module is needed for EventMesh backend. APIRules CRD is not installed") +) + // Reconciler reconciles an Eventing object // //go:generate go run github.com/vektra/mockery/v2 --name=Controller --dir=../../../../vendor/sigs.k8s.io/controller-runtime/pkg/controller --outpkg=mocks --case=underscore @@ -393,8 +401,7 @@ func (r *Reconciler) handleEventingDeletion(ctx context.Context, eventing *opera } if exists { eventing.Status.SetStateWarning() - return kctrl.Result{Requeue: true}, r.syncStatusWithDeletionErr(ctx, eventing, - errors.New(SubscriptionExistsErrMessage), log) + return kctrl.Result{Requeue: true}, r.syncStatusWithDeletionErr(ctx, eventing, ErrSubscriptionExists, log) } log.Info("handling Eventing deletion...") @@ -486,7 +493,7 @@ func (r *Reconciler) handleEventingReconcile(ctx context.Context, case operatorv1alpha1.EventMeshBackendType: return r.reconcileEventMeshBackend(ctx, eventing, log) default: - return kctrl.Result{Requeue: false}, fmt.Errorf("not supported backend type %s", eventing.Spec.Backend.Type) + return kctrl.Result{Requeue: false}, fmt.Errorf("%w: %s", ErrUnsupportedBackedType, eventing.Spec.Backend.Type) } } @@ -530,7 +537,7 @@ func (r *Reconciler) reconcileNATSBackend(ctx context.Context, eventing *operato return kctrl.Result{}, delErr } // update the Eventing CR status. - notFoundErr := fmt.Errorf("NATS module has to be installed: %v", err) + notFoundErr := fmt.Errorf("%w: %v", ErrNatsModuleMissing, err) return kctrl.Result{}, r.syncStatusWithNATSState(ctx, operatorv1alpha1.StateWarning, eventing, notFoundErr, log) } @@ -569,7 +576,7 @@ func (r *Reconciler) checkNATSAvailability(ctx context.Context, eventing *operat return err } if !natsAvailable { - return fmt.Errorf(NatsServerNotAvailableMsg) + return ErrNATSServerUnavailable } return nil } @@ -608,8 +615,7 @@ func (r *Reconciler) reconcileEventMeshBackend(ctx context.Context, eventing *op if err != nil { return kctrl.Result{}, r.syncStatusWithSubscriptionManagerErr(ctx, eventing, err, log) } else if !isAPIRuleCRDEnabled { - apiRuleMissingErr := errors.New("API-Gateway module is needed for EventMesh backend. APIRules CRD is not installed") - return kctrl.Result{}, r.syncStatusWithSubscriptionManagerErr(ctx, eventing, apiRuleMissingErr, log) + return kctrl.Result{}, r.syncStatusWithSubscriptionManagerErr(ctx, eventing, ErrAPIGatewayModuleMissing, log) } // retrieve secret used to authenticate with EventMesh @@ -617,10 +623,10 @@ func (r *Reconciler) reconcileEventMeshBackend(ctx context.Context, eventing *op if err != nil { if kerrors.IsNotFound(err) { return kctrl.Result{}, r.syncSubManagerStatusWithNATSState(ctx, operatorv1alpha1.StateWarning, eventing, - fmt.Errorf(EventMeshSecretMissingMessage), log) + ErrEventMeshSecretMissing, log) } return kctrl.Result{}, r.syncStatusWithSubscriptionManagerErr(ctx, eventing, - fmt.Errorf("failed to get EventMesh secret: %v", err), log) + fmt.Errorf("failed to get EventMesh secret: %w", err), log) } // Start the EventMesh subscription controller diff --git a/internal/controller/operator/eventing/controller_test.go b/internal/controller/operator/eventing/controller_test.go index 620b1aa1..f85dba1c 100644 --- a/internal/controller/operator/eventing/controller_test.go +++ b/internal/controller/operator/eventing/controller_test.go @@ -1,7 +1,7 @@ package eventing import ( - "errors" + "context" "fmt" "testing" @@ -78,7 +78,7 @@ func Test_handleEventingCRAllowedCheck(t *testing.T) { logger := testEnv.Reconciler.logger.WithContext().Named(ControllerName) // when - result, err := testEnv.Reconciler.handleEventingCRAllowedCheck(testEnv.Context, tc.givenEventing, logger) + result, err := testEnv.Reconciler.handleEventingCRAllowedCheck(context.Background(), tc.givenEventing, logger) // then require.NoError(t, err) @@ -176,13 +176,13 @@ func Test_handleBackendSwitching(t *testing.T) { ), givenNATSSubManagerMock: func() *submgrmanagermocks.Manager { managerMock := new(submgrmanagermocks.Manager) - managerMock.On("Stop", true).Return(errors.New("failed to stop")).Once() + managerMock.On("Stop", true).Return(ErrFailedToStop).Once() return managerMock }, givenEventMeshSubManagerMock: func() *submgrmanagermocks.Manager { return new(submgrmanagermocks.Manager) }, - wantError: errors.New("failed to stop"), + wantError: ErrFailedToStop, wantEventingState: operatorv1alpha1.StateReady, wantEventingConditionsLen: 1, wantNATSStopped: false, @@ -223,10 +223,10 @@ func Test_handleBackendSwitching(t *testing.T) { }, givenEventMeshSubManagerMock: func() *submgrmanagermocks.Manager { managerMock := new(submgrmanagermocks.Manager) - managerMock.On("Stop", true).Return(errors.New("failed to stop")).Once() + managerMock.On("Stop", true).Return(ErrFailedToStop).Once() return managerMock }, - wantError: errors.New("failed to stop"), + wantError: ErrFailedToStop, wantEventingState: operatorv1alpha1.StateReady, wantEventingConditionsLen: 1, wantNATSStopped: false, @@ -320,7 +320,7 @@ func Test_startNatsCRWatch(t *testing.T) { { name: "NATS watcher error", watchStarted: false, - watchErr: errors.New("NATS watcher error"), + watchErr: ErrUseMeInMocks, }, } @@ -395,8 +395,8 @@ func Test_stopNatsCRWatch(t *testing.T) { testEnv.Reconciler.stopNATSCRWatch(eventing) // Check the results - require.Equal(t, tc.watchNatsWatcher, nil) - require.Equal(t, tc.natsCRWatchStarted, false) + require.Equal(t, nil, tc.watchNatsWatcher) + require.False(t, tc.natsCRWatchStarted) }) } } diff --git a/internal/controller/operator/eventing/domain.go b/internal/controller/operator/eventing/domain.go index 581e2e77..bbe4cb61 100644 --- a/internal/controller/operator/eventing/domain.go +++ b/internal/controller/operator/eventing/domain.go @@ -2,6 +2,7 @@ package eventing import ( "context" + "errors" "fmt" ) @@ -9,11 +10,13 @@ const ( shootInfoConfigMapName = "shoot-info" shootInfoConfigMapNamespace = "kube-system" shootInfoConfigMapKeyDomain = "domain" - domainMissingMessageFormat = `domain configuration is missing. domain must be configured in either the Eventing` + + domainMissingMessageFormat = `%w. domain must be configured in either the Eventing` + ` CustomResource under "Spec.Backend.Config.Domain" or in the ConfigMap "%s/%s" under "data.%s"` - domainMissingMessageFormatWithError = domainMissingMessageFormat + `: %v` + domainMissingMessageFormatWithError = domainMissingMessageFormat + `: %w` ) +var ErrDomainConfigMissing = errors.New("domain configuration missing") + func (r *Reconciler) readDomainFromConfigMap(ctx context.Context) (string, error) { cm, err := r.kubeClient.GetConfigMap(ctx, shootInfoConfigMapName, shootInfoConfigMapNamespace) if err != nil { @@ -25,13 +28,12 @@ func (r *Reconciler) readDomainFromConfigMap(ctx context.Context) (string, error func domainMissingError(err error) error { if err != nil { return fmt.Errorf( - domainMissingMessageFormatWithError, + domainMissingMessageFormatWithError, ErrDomainConfigMissing, shootInfoConfigMapNamespace, shootInfoConfigMapName, shootInfoConfigMapKeyDomain, err, ) } - return fmt.Errorf( - domainMissingMessageFormat, + domainMissingMessageFormat, ErrDomainConfigMissing, shootInfoConfigMapNamespace, shootInfoConfigMapName, shootInfoConfigMapKeyDomain, ) } diff --git a/internal/controller/operator/eventing/domain_test.go b/internal/controller/operator/eventing/domain_test.go index cf244047..c6255ef3 100644 --- a/internal/controller/operator/eventing/domain_test.go +++ b/internal/controller/operator/eventing/domain_test.go @@ -2,11 +2,11 @@ package eventing import ( "context" - "fmt" - "strings" "testing" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" kcorev1 "k8s.io/api/core/v1" k8smocks "github.com/kyma-project/eventing-manager/pkg/k8s/mocks" @@ -45,15 +45,17 @@ func Test_readDomainFromConfigMap(t *testing.T) { func Test_domainMissingError(t *testing.T) { // given const errorMessage = "some error" - err := fmt.Errorf(errorMessage) + err := errors.New(errorMessage) // when err0 := domainMissingError(nil) err1 := domainMissingError(err) // then - assert.NotNil(t, err0) - assert.NotNil(t, err1) - assert.False(t, strings.Contains(strings.ToLower(err0.Error()), "nil")) - assert.True(t, strings.Contains(err1.Error(), errorMessage)) + require.Error(t, err0) + require.Error(t, err1) + require.ErrorIs(t, err0, ErrDomainConfigMissing) + require.ErrorIs(t, err1, ErrDomainConfigMissing) + require.NotErrorIs(t, err0, err) + require.ErrorIs(t, err1, err) } diff --git a/internal/controller/operator/eventing/eventmesh.go b/internal/controller/operator/eventing/eventmesh.go index cd1a092f..5013f99f 100644 --- a/internal/controller/operator/eventing/eventmesh.go +++ b/internal/controller/operator/eventing/eventmesh.go @@ -27,6 +27,14 @@ const ( secretKeyClientSecret = "client_secret" secretKeyTokenURL = "token_url" secretKeyCertsURL = "certs_url" + + EventMeshSecretMissingMessage = "The specified EventMesh secret is not found. Please provide an existing secret." +) + +var ( + ErrEMSecretMessagingMissing = errors.New("messaging is missing from EM secret") + ErrEMSecretNamespaceMissing = errors.New("namespace is missing from EM secret") + ErrEventMeshSecretMissing = errors.New(EventMeshSecretMissingMessage) ) type oauth2Credentials struct { @@ -36,26 +44,25 @@ type oauth2Credentials struct { certsURL []byte } -const EventMeshSecretMissingMessage = "The specified EventMesh secret is not found. Please provide an existing secret." - func (r *Reconciler) reconcileEventMeshSubManager(ctx context.Context, eventing *v1alpha1.Eventing, eventMeshSecret *kcorev1.Secret, log *zap.SugaredLogger, ) error { // gets oauth2ClientID and secret and stops the EventMesh subscription manager if changed err := r.syncOauth2ClientIDAndSecret(ctx, eventing) if err != nil { - return errors.Errorf("failed to sync OAuth secret: %v", err) + return fmt.Errorf("failed to sync OAuth secret: %w", err) } + // CreateOrUpdate deployment for publisher proxy secret secretForPublisher, err := r.SyncPublisherProxySecret(ctx, eventMeshSecret) if err != nil { - return errors.Errorf("failed to sync Publisher Proxy secret: %v", err) + return fmt.Errorf("failed to sync Publisher Proxy secret: %w", err) } // Set environment with secrets for EventMesh subscription controller err = setUpEnvironmentForEventMesh(secretForPublisher, eventing) if err != nil { - return fmt.Errorf("failed to setup environment variables for EventMesh controller: %v", err) + return fmt.Errorf("failed to setup environment variables for EventMesh controller: %w", err) } // Read the cluster domain from the Eventing CR, or @@ -174,7 +181,7 @@ func (r *Reconciler) stopEventMeshSubManager(runCleanup bool, log *zap.SugaredLo func (r *Reconciler) SyncPublisherProxySecret(ctx context.Context, secret *kcorev1.Secret) (*kcorev1.Secret, error) { desiredSecret, err := getSecretForPublisher(secret) if err != nil { - return nil, fmt.Errorf("invalid secret for Event Publisher: %v", err) + return nil, fmt.Errorf("invalid secret for Event Publisher: %w", err) } err = r.kubeClient.PatchApply(ctx, desiredSecret) @@ -301,12 +308,12 @@ func getSecretForPublisher(eventMeshSecret *kcorev1.Secret) (*kcorev1.Secret, er } if _, ok := eventMeshSecret.Data["messaging"]; !ok { - return nil, errors.New("message is missing from BEB secret") + return nil, ErrEMSecretMessagingMissing } messagingBytes := eventMeshSecret.Data["messaging"] if _, ok := eventMeshSecret.Data["namespace"]; !ok { - return nil, errors.New("namespace is missing from BEB secret") + return nil, ErrEMSecretNamespaceMissing } namespaceBytes := eventMeshSecret.Data["namespace"] @@ -356,31 +363,31 @@ func getSecretStringData(clientID, clientSecret, tokenEndpoint, grantType, publi func setUpEnvironmentForEventMesh(secret *kcorev1.Secret, eventingCR *v1alpha1.Eventing) error { err := os.Setenv("BEB_API_URL", fmt.Sprintf("%s%s", string(secret.Data[PublisherSecretEMSHostKey]), EventMeshPublishEndpointForSubscriber)) if err != nil { - return fmt.Errorf("set BEB_API_URL env var failed: %v", err) + return fmt.Errorf("set BEB_API_URL env var failed: %w", err) } err = os.Setenv("CLIENT_ID", string(secret.Data[eventing.PublisherSecretClientIDKey])) if err != nil { - return fmt.Errorf("set CLIENT_ID env var failed: %v", err) + return fmt.Errorf("set CLIENT_ID env var failed: %w", err) } err = os.Setenv("CLIENT_SECRET", string(secret.Data[eventing.PublisherSecretClientSecretKey])) if err != nil { - return fmt.Errorf("set CLIENT_SECRET env var failed: %v", err) + return fmt.Errorf("set CLIENT_SECRET env var failed: %w", err) } err = os.Setenv("TOKEN_ENDPOINT", string(secret.Data[eventing.PublisherSecretTokenEndpointKey])) if err != nil { - return fmt.Errorf("set TOKEN_ENDPOINT env var failed: %v", err) + return fmt.Errorf("set TOKEN_ENDPOINT env var failed: %w", err) } err = os.Setenv("BEB_NAMESPACE", fmt.Sprintf("%s%s", NamespacePrefix, string(secret.Data[eventing.PublisherSecretBEBNamespaceKey]))) if err != nil { - return fmt.Errorf("set BEB_NAMESPACE env var failed: %v", err) + return fmt.Errorf("set BEB_NAMESPACE env var failed: %w", err) } if err := os.Setenv("EVENT_TYPE_PREFIX", eventingCR.Spec.Backend.Config.EventTypePrefix); err != nil { - return fmt.Errorf("set EVENT_TYPE_PREFIX env var failed: %v", err) + return fmt.Errorf("set EVENT_TYPE_PREFIX env var failed: %w", err) } return nil diff --git a/internal/controller/operator/eventing/eventmesh_test.go b/internal/controller/operator/eventing/eventmesh_test.go index 4d017295..b2765043 100644 --- a/internal/controller/operator/eventing/eventmesh_test.go +++ b/internal/controller/operator/eventing/eventmesh_test.go @@ -5,7 +5,6 @@ import ( "errors" "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" kcorev1 "k8s.io/api/core/v1" @@ -31,6 +30,12 @@ const ( defaultEventingWebhookAuthSecretNamespace = "kyma-system" ) +var ( + ErrFailedToStart = errors.New("failed to start") + ErrFailedToStop = errors.New("failed to stop") +) + +//nolint:goerr113 // all tests here need to be fixed, as they use require.ErrorAs and use it wrongly func Test_reconcileEventMeshSubManager(t *testing.T) { t.Parallel() @@ -463,11 +468,11 @@ func Test_stopEventMeshSubManager(t *testing.T) { name: "should return error when subscription manager fails to stop", givenEventMeshSubManagerMock: func() *submgrmanagermocks.Manager { managerMock := new(submgrmanagermocks.Manager) - managerMock.On("Stop", mock.Anything).Return(errors.New("failed to stop")).Once() + managerMock.On("Stop", mock.Anything).Return(ErrFailedToStop).Once() return managerMock }, givenIsEventMeshSubManagerStarted: true, - wantError: errors.New("failed to stop"), + wantError: ErrFailedToStop, wantAssertCheck: true, }, { @@ -545,7 +550,7 @@ func Test_GetSecretForPublisher(t *testing.T) { name string messagingData []byte namespaceData []byte - expectedSecret kcorev1.Secret + expectedSecret *kcorev1.Secret expectedError error }{ { @@ -598,7 +603,7 @@ func Test_GetSecretForPublisher(t *testing.T) { } ] `), namespaceData: []byte("valid/namespace"), - expectedSecret: kcorev1.Secret{ + expectedSecret: &kcorev1.Secret{ TypeMeta: kmetav1.TypeMeta{ Kind: "Secret", APIVersion: kcorev1.SchemeGroupVersion.String(), @@ -623,7 +628,7 @@ func Test_GetSecretForPublisher(t *testing.T) { { name: "with empty message data", namespaceData: []byte("valid/namespace"), - expectedError: errors.New("message is missing from BEB secret"), + expectedError: ErrEMSecretMessagingMissing, }, { name: "with empty namespace data", @@ -674,7 +679,7 @@ func Test_GetSecretForPublisher(t *testing.T) { "uri": "https://rest-messaging" } ]`), - expectedError: errors.New("namespace is missing from BEB secret"), + expectedError: ErrEMSecretNamespaceMissing, }, } @@ -684,12 +689,12 @@ func Test_GetSecretForPublisher(t *testing.T) { gotPublisherSecret, err := getSecretForPublisher(publisherSecret) if tc.expectedError != nil { - assert.NotNil(t, err) - assert.Equal(t, tc.expectedError.Error(), err.Error(), "invalid error") + require.Error(t, err) + require.ErrorContains(t, err, tc.expectedError.Error()) return } - assert.Nil(t, err) - assert.Equal(t, tc.expectedSecret, *gotPublisherSecret, "invalid publisher secret") + require.NoError(t, err) + require.Equal(t, tc.expectedSecret, gotPublisherSecret, "invalid publisher secret") }) } } @@ -902,7 +907,7 @@ func Test_SyncPublisherProxySecret(t *testing.T) { givenSecret: utils.NewEventMeshSecret("valid", "test-namespace"), mockKubeClient: func() *k8smocks.Client { kubeClient := new(k8smocks.Client) - kubeClient.On("PatchApply", mock.Anything, mock.Anything).Return(errors.New("fake error")).Once() + kubeClient.On("PatchApply", mock.Anything, mock.Anything).Return(ErrUseMeInMocks).Once() return kubeClient }, wantErr: true, diff --git a/internal/controller/operator/eventing/integrationtests/controller/integration_test.go b/internal/controller/operator/eventing/integrationtests/controller/integration_test.go index 3d11f90b..9420519f 100644 --- a/internal/controller/operator/eventing/integrationtests/controller/integration_test.go +++ b/internal/controller/operator/eventing/integrationtests/controller/integration_test.go @@ -11,6 +11,7 @@ import ( natstestutils "github.com/kyma-project/nats-manager/testutils" "github.com/onsi/gomega" gomegatypes "github.com/onsi/gomega/types" + "github.com/pkg/errors" "github.com/stretchr/testify/require" kappsv1 "k8s.io/api/apps/v1" kapiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -34,6 +35,8 @@ const ( var testEnvironment *testutilsintegration.TestEnvironment //nolint:gochecknoglobals // used in tests +var ErrPatchApplyFailed = errors.New("patch apply failed") + // TestMain pre-hook and post-hook to run before and after all tests. func TestMain(m *testing.M) { // Note: The setup will provision a single K8s env and @@ -611,7 +614,7 @@ func Test_CreateEventingCR_EventMesh(t *testing.T) { wantMatches: gomega.And( matchers.HaveStatusError(), matchers.HaveEventMeshSubManagerNotReadyCondition( - "failed to sync Publisher Proxy secret: unexpected error"), + "failed to sync Publisher Proxy secret: patch apply failed"), matchers.HaveFinalizer(), ), shouldFailSubManager: true, @@ -1113,5 +1116,5 @@ func (mkc *MockKubeClient) GetCRD(ctx context.Context, name string) (*kapiextens } func (mkc *MockKubeClient) PatchApply(ctx context.Context, object kctrlclient.Object) error { - return fmt.Errorf("unexpected error") + return ErrPatchApplyFailed } diff --git a/internal/controller/operator/eventing/mocks/controller.go b/internal/controller/operator/eventing/mocks/controller.go index 7cc68336..ecb91c2e 100644 --- a/internal/controller/operator/eventing/mocks/controller.go +++ b/internal/controller/operator/eventing/mocks/controller.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -35,6 +35,10 @@ func (_m *Controller) EXPECT() *Controller_Expecter { func (_m *Controller) GetLogger() logr.Logger { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetLogger") + } + var r0 logr.Logger if rf, ok := ret.Get(0).(func() logr.Logger); ok { r0 = rf() @@ -76,6 +80,10 @@ func (_c *Controller_GetLogger_Call) RunAndReturn(run func() logr.Logger) *Contr func (_m *Controller) Reconcile(_a0 context.Context, _a1 reconcile.Request) (reconcile.Result, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for Reconcile") + } + var r0 reconcile.Result var r1 error if rf, ok := ret.Get(0).(func(context.Context, reconcile.Request) (reconcile.Result, error)); ok { @@ -129,6 +137,10 @@ func (_c *Controller_Reconcile_Call) RunAndReturn(run func(context.Context, reco func (_m *Controller) Start(ctx context.Context) error { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for Start") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(ctx) @@ -178,6 +190,10 @@ func (_m *Controller) Watch(src source.Source, eventhandler handler.EventHandler _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for Watch") + } + var r0 error if rf, ok := ret.Get(0).(func(source.Source, handler.EventHandler, ...predicate.Predicate) error); ok { r0 = rf(src, eventhandler, predicates...) diff --git a/internal/controller/operator/eventing/mocks/manager.go b/internal/controller/operator/eventing/mocks/manager.go index 5f61310d..12739e00 100644 --- a/internal/controller/operator/eventing/mocks/manager.go +++ b/internal/controller/operator/eventing/mocks/manager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -48,6 +48,10 @@ func (_m *Manager) EXPECT() *Manager_Expecter { func (_m *Manager) Add(_a0 manager.Runnable) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Add") + } + var r0 error if rf, ok := ret.Get(0).(func(manager.Runnable) error); ok { r0 = rf(_a0) @@ -90,6 +94,10 @@ func (_c *Manager_Add_Call) RunAndReturn(run func(manager.Runnable) error) *Mana func (_m *Manager) AddHealthzCheck(name string, check healthz.Checker) error { ret := _m.Called(name, check) + if len(ret) == 0 { + panic("no return value specified for AddHealthzCheck") + } + var r0 error if rf, ok := ret.Get(0).(func(string, healthz.Checker) error); ok { r0 = rf(name, check) @@ -133,6 +141,10 @@ func (_c *Manager_AddHealthzCheck_Call) RunAndReturn(run func(string, healthz.Ch func (_m *Manager) AddReadyzCheck(name string, check healthz.Checker) error { ret := _m.Called(name, check) + if len(ret) == 0 { + panic("no return value specified for AddReadyzCheck") + } + var r0 error if rf, ok := ret.Get(0).(func(string, healthz.Checker) error); ok { r0 = rf(name, check) @@ -176,6 +188,10 @@ func (_c *Manager_AddReadyzCheck_Call) RunAndReturn(run func(string, healthz.Che func (_m *Manager) Elected() <-chan struct{} { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Elected") + } + var r0 <-chan struct{} if rf, ok := ret.Get(0).(func() <-chan struct{}); ok { r0 = rf() @@ -219,6 +235,10 @@ func (_c *Manager_Elected_Call) RunAndReturn(run func() <-chan struct{}) *Manage func (_m *Manager) GetAPIReader() client.Reader { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetAPIReader") + } + var r0 client.Reader if rf, ok := ret.Get(0).(func() client.Reader); ok { r0 = rf() @@ -262,6 +282,10 @@ func (_c *Manager_GetAPIReader_Call) RunAndReturn(run func() client.Reader) *Man func (_m *Manager) GetCache() cache.Cache { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetCache") + } + var r0 cache.Cache if rf, ok := ret.Get(0).(func() cache.Cache); ok { r0 = rf() @@ -305,6 +329,10 @@ func (_c *Manager_GetCache_Call) RunAndReturn(run func() cache.Cache) *Manager_G func (_m *Manager) GetClient() client.Client { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetClient") + } + var r0 client.Client if rf, ok := ret.Get(0).(func() client.Client); ok { r0 = rf() @@ -348,6 +376,10 @@ func (_c *Manager_GetClient_Call) RunAndReturn(run func() client.Client) *Manage func (_m *Manager) GetConfig() *rest.Config { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetConfig") + } + var r0 *rest.Config if rf, ok := ret.Get(0).(func() *rest.Config); ok { r0 = rf() @@ -391,6 +423,10 @@ func (_c *Manager_GetConfig_Call) RunAndReturn(run func() *rest.Config) *Manager func (_m *Manager) GetControllerOptions() config.Controller { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetControllerOptions") + } + var r0 config.Controller if rf, ok := ret.Get(0).(func() config.Controller); ok { r0 = rf() @@ -432,6 +468,10 @@ func (_c *Manager_GetControllerOptions_Call) RunAndReturn(run func() config.Cont func (_m *Manager) GetEventRecorderFor(name string) record.EventRecorder { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for GetEventRecorderFor") + } + var r0 record.EventRecorder if rf, ok := ret.Get(0).(func(string) record.EventRecorder); ok { r0 = rf(name) @@ -476,6 +516,10 @@ func (_c *Manager_GetEventRecorderFor_Call) RunAndReturn(run func(string) record func (_m *Manager) GetFieldIndexer() client.FieldIndexer { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetFieldIndexer") + } + var r0 client.FieldIndexer if rf, ok := ret.Get(0).(func() client.FieldIndexer); ok { r0 = rf() @@ -519,6 +563,10 @@ func (_c *Manager_GetFieldIndexer_Call) RunAndReturn(run func() client.FieldInde func (_m *Manager) GetHTTPClient() *http.Client { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetHTTPClient") + } + var r0 *http.Client if rf, ok := ret.Get(0).(func() *http.Client); ok { r0 = rf() @@ -562,6 +610,10 @@ func (_c *Manager_GetHTTPClient_Call) RunAndReturn(run func() *http.Client) *Man func (_m *Manager) GetLogger() logr.Logger { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetLogger") + } + var r0 logr.Logger if rf, ok := ret.Get(0).(func() logr.Logger); ok { r0 = rf() @@ -603,6 +655,10 @@ func (_c *Manager_GetLogger_Call) RunAndReturn(run func() logr.Logger) *Manager_ func (_m *Manager) GetRESTMapper() meta.RESTMapper { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetRESTMapper") + } + var r0 meta.RESTMapper if rf, ok := ret.Get(0).(func() meta.RESTMapper); ok { r0 = rf() @@ -646,6 +702,10 @@ func (_c *Manager_GetRESTMapper_Call) RunAndReturn(run func() meta.RESTMapper) * func (_m *Manager) GetScheme() *runtime.Scheme { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetScheme") + } + var r0 *runtime.Scheme if rf, ok := ret.Get(0).(func() *runtime.Scheme); ok { r0 = rf() @@ -689,6 +749,10 @@ func (_c *Manager_GetScheme_Call) RunAndReturn(run func() *runtime.Scheme) *Mana func (_m *Manager) GetWebhookServer() webhook.Server { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetWebhookServer") + } + var r0 webhook.Server if rf, ok := ret.Get(0).(func() webhook.Server); ok { r0 = rf() @@ -732,6 +796,10 @@ func (_c *Manager_GetWebhookServer_Call) RunAndReturn(run func() webhook.Server) func (_m *Manager) Start(ctx context.Context) error { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for Start") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(ctx) diff --git a/internal/controller/operator/eventing/mocks/nats_config_handler.go b/internal/controller/operator/eventing/mocks/nats_config_handler.go index adc5591a..b6403fb0 100644 --- a/internal/controller/operator/eventing/mocks/nats_config_handler.go +++ b/internal/controller/operator/eventing/mocks/nats_config_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -29,6 +29,10 @@ func (_m *NatsConfigHandler) EXPECT() *NatsConfigHandler_Expecter { func (_m *NatsConfigHandler) GetNatsConfig(ctx context.Context, _a1 v1alpha1.Eventing) (*env.NATSConfig, error) { ret := _m.Called(ctx, _a1) + if len(ret) == 0 { + panic("no return value specified for GetNatsConfig") + } + var r0 *env.NATSConfig var r1 error if rf, ok := ret.Get(0).(func(context.Context, v1alpha1.Eventing) (*env.NATSConfig, error)); ok { diff --git a/internal/controller/operator/eventing/nats.go b/internal/controller/operator/eventing/nats.go index 877c975b..fca7b348 100644 --- a/internal/controller/operator/eventing/nats.go +++ b/internal/controller/operator/eventing/nats.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/pkg/errors" "go.uber.org/zap" "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" @@ -13,6 +14,8 @@ import ( "github.com/kyma-project/eventing-manager/pkg/subscriptionmanager/manager" ) +var ErrCannotBuildNATSURL = errors.New("NATS CR is not found to build NATS server URL") + func (r *Reconciler) reconcileNATSSubManager(ctx context.Context, eventing *v1alpha1.Eventing, log *zap.SugaredLogger) error { // get the subscription config defaultSubsConfig := r.getDefaultSubscriptionConfig() @@ -162,5 +165,5 @@ func (n *NatsConfigHandlerImpl) getNATSUrl(ctx context.Context, namespace string for _, nats := range natsList.Items { return fmt.Sprintf("nats://%s.%s.svc.cluster.local:%d", nats.Name, nats.Namespace, natsClientPort), nil } - return "", fmt.Errorf("NATS CR is not found to build NATS server URL") + return "", ErrCannotBuildNATSURL } diff --git a/internal/controller/operator/eventing/nats_test.go b/internal/controller/operator/eventing/nats_test.go index 8cd25e3f..7dfc87c2 100644 --- a/internal/controller/operator/eventing/nats_test.go +++ b/internal/controller/operator/eventing/nats_test.go @@ -3,7 +3,6 @@ package eventing import ( "context" "errors" - "fmt" "testing" "time" @@ -23,6 +22,8 @@ import ( "github.com/kyma-project/eventing-manager/test/utils" ) +var ErrUseMeInMocks = errors.New("use me in mocks") + func Test_reconcileNATSSubManager(t *testing.T) { t.Parallel() @@ -135,7 +136,7 @@ func Test_reconcileNATSSubManager(t *testing.T) { givenNATSSubManagerMock: func() *submgrmanagermocks.Manager { jetStreamSubManagerMock := new(submgrmanagermocks.Manager) jetStreamSubManagerMock.On("Init", mock.Anything).Return(nil).Once() - jetStreamSubManagerMock.On("Start", mock.Anything, mock.Anything).Return(errors.New("failed to start")).Twice() + jetStreamSubManagerMock.On("Start", mock.Anything, mock.Anything).Return(ErrUseMeInMocks).Twice() return jetStreamSubManagerMock }, givenEventingManagerMock: func() *eventingmocks.Manager { @@ -155,7 +156,7 @@ func Test_reconcileNATSSubManager(t *testing.T) { }, wantAssertCheck: true, givenShouldRetry: true, - wantError: errors.New("failed to start"), + wantError: ErrUseMeInMocks, wantHashAfter: int64(-7550677537009891034), }, { @@ -248,15 +249,15 @@ func Test_reconcileNATSSubManager(t *testing.T) { givenEventing.Status.BackendConfigHash = tc.givenHashBefore // when - err := testEnv.Reconciler.reconcileNATSSubManager(testEnv.Context, givenEventing, logger) + err := testEnv.Reconciler.reconcileNATSSubManager(context.Background(), givenEventing, logger) if err != nil && tc.givenShouldRetry { // This is to test the scenario where initialization of natsSubManager was successful but // starting the natsSubManager failed. So on next try it should again try to start the natsSubManager. - err = testEnv.Reconciler.reconcileNATSSubManager(testEnv.Context, givenEventing, logger) + err = testEnv.Reconciler.reconcileNATSSubManager(context.Background(), givenEventing, logger) } if tc.givenUpdateTest { // Run reconcile again with newBackendConfig: - err = testEnv.Reconciler.reconcileNATSSubManager(testEnv.Context, givenEventing, logger) + err = testEnv.Reconciler.reconcileNATSSubManager(context.Background(), givenEventing, logger) require.NoError(t, err) } @@ -308,11 +309,11 @@ func Test_stopNATSSubManager(t *testing.T) { name: "should return error when subscription manager fails to stop", givenNATSSubManagerMock: func() *submgrmanagermocks.Manager { managerMock := new(submgrmanagermocks.Manager) - managerMock.On("Stop", mock.Anything).Return(errors.New("failed to stop")).Once() + managerMock.On("Stop", mock.Anything).Return(ErrUseMeInMocks).Once() return managerMock }, givenIsNATSSubManagerStarted: true, - wantError: errors.New("failed to stop"), + wantError: ErrUseMeInMocks, wantAssertCheck: true, }, { @@ -419,7 +420,7 @@ func Test_GetNatsConfig(t *testing.T) { ), givenNatsResources: nil, expectedConfig: nil, - expectedError: fmt.Errorf("failed to get NATS URL"), + expectedError: ErrUseMeInMocks, }, } @@ -478,15 +479,15 @@ func Test_getNATSUrl(t *testing.T) { givenNamespace: "test-namespace", want: "", getNATSResourcesErr: nil, - wantErr: fmt.Errorf("NATS CR is not found to build NATS server URL"), + wantErr: ErrCannotBuildNATSURL, }, { name: "NATS resource does not exist", givenNatsResources: nil, givenNamespace: "test-namespace", want: "", - getNATSResourcesErr: fmt.Errorf("NATS CR is not found to build NATS server URL"), - wantErr: fmt.Errorf("NATS CR is not found to build NATS server URL"), + getNATSResourcesErr: ErrCannotBuildNATSURL, + wantErr: ErrCannotBuildNATSURL, }, } @@ -551,7 +552,7 @@ func Test_UpdateNatsConfig(t *testing.T) { utils.WithEventingStreamData("Memory", "700Mi", 2, 1000), ), givenNatsResources: nil, - expectedError: fmt.Errorf("failed to get NATS URL"), + expectedError: ErrCannotBuildNATSURL, }, } diff --git a/internal/controller/operator/eventing/unit_test.go b/internal/controller/operator/eventing/unit_test.go index 72e2bb99..4461528c 100644 --- a/internal/controller/operator/eventing/unit_test.go +++ b/internal/controller/operator/eventing/unit_test.go @@ -27,7 +27,6 @@ import ( // MockedUnitTestEnvironment provides mocked resources for unit tests. type MockedUnitTestEnvironment struct { - Context context.Context Client client.Client kubeClient *k8s.Client eventingManager *eventingmocks.Manager @@ -38,9 +37,6 @@ type MockedUnitTestEnvironment struct { } func NewMockedUnitTestEnvironment(t *testing.T, objs ...client.Object) *MockedUnitTestEnvironment { - // setup context - ctx := context.Background() - // setup logger ctrLogger, err := logger.New("json", "info") require.NoError(t, err) @@ -91,7 +87,6 @@ func NewMockedUnitTestEnvironment(t *testing.T, objs ...client.Object) *MockedUn reconciler.ctrlManager = mockManager return &MockedUnitTestEnvironment{ - Context: ctx, Client: fakeClient, kubeClient: &kubeClient, Reconciler: reconciler, @@ -104,7 +99,7 @@ func NewMockedUnitTestEnvironment(t *testing.T, objs ...client.Object) *MockedUn func (testEnv *MockedUnitTestEnvironment) GetEventing(name, namespace string) (operatorv1alpha1.Eventing, error) { var evnt operatorv1alpha1.Eventing - err := testEnv.Client.Get(testEnv.Context, types.NamespacedName{ + err := testEnv.Client.Get(context.Background(), types.NamespacedName{ Name: name, Namespace: namespace, }, &evnt) diff --git a/internal/controller/operator/eventing/utils_test.go b/internal/controller/operator/eventing/utils_test.go index 418918d3..03f338ee 100644 --- a/internal/controller/operator/eventing/utils_test.go +++ b/internal/controller/operator/eventing/utils_test.go @@ -4,7 +4,6 @@ import ( "context" "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" operatorv1alpha1 "github.com/kyma-project/eventing-manager/api/operator/v1alpha1" @@ -92,17 +91,18 @@ func Test_removeFinalizer(t *testing.T) { func TestReconciler_getEventMeshBackendConfigHash(t *testing.T) { hash, err := getEventMeshBackendConfigHash("kyma-system/eventing-backend", "sap.kyma.custom", "domain.com") - assert.NoError(t, err) - assert.NotEqual(t, 0, hash) + require.NoError(t, err) + require.NotZero(t, hash) } func TestReconciler_getEventMeshBackendConfigHash_EnsureConsistencyAndUniqueness(t *testing.T) { hash1, err1 := getEventMeshBackendConfigHash("kyma-system/eventing-backend", "sap.kyma.custom", "domain.com") + require.NoError(t, err1) hash2, err2 := getEventMeshBackendConfigHash("kyma-system/eventing-backend", "sap.kyma.custom", "domain.com") + require.NoError(t, err2) hash3, err3 := getEventMeshBackendConfigHash("kyma-system/eventing-backen", "dsap.kyma.cust", "omdomain.com") - assert.NoError(t, err1) - assert.NoError(t, err2) - assert.NoError(t, err3) - assert.Equal(t, hash1, hash2) - assert.NotEqual(t, hash1, hash3) + require.NoError(t, err3) + + require.Equal(t, hash1, hash2) + require.NotEqual(t, hash1, hash3) } diff --git a/pkg/backend/eventmesh/eventmesh.go b/pkg/backend/eventmesh/eventmesh.go index 99f3fc88..361d7be6 100644 --- a/pkg/backend/eventmesh/eventmesh.go +++ b/pkg/backend/eventmesh/eventmesh.go @@ -31,6 +31,8 @@ const ( // Perform a compile time check. var _ Backend = &EventMesh{} +var ErrEMSubjectInvalid = errors.New("EventMesh subject invalid") + type Backend interface { // Initialize should initialize the communication layer with the messaging backend system Initialize(cfg env.Config) error @@ -216,7 +218,7 @@ func (em *EventMesh) getProcessedEventTypes(kymaSubscription *eventingv1alpha2.S if isEventTypeSegmentsOverLimit(eventMeshSubject) { return nil, fmt.Errorf("EventMesh subject exceeds the limit of segments, "+ - "max number of segements allowed: %d", eventTypeSegmentsLimit) + "max number of segements allowed: %d, %w", eventTypeSegmentsLimit, ErrEMSubjectInvalid) } result = append(result, backendutils.EventTypeInfo{ @@ -396,7 +398,7 @@ func (em *EventMesh) getSubscriptionIgnoreNotFound(name string) (*types.Subscrip func (em *EventMesh) getSubscription(name string) (*types.Subscription, error) { eventMeshSubscription, resp, err := em.client.Get(name) if err != nil { - return nil, fmt.Errorf("get subscription failed: %v", err) + return nil, fmt.Errorf("get subscription failed: %w", err) } if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("get subscription failed: %w; %v", @@ -410,7 +412,7 @@ func (em *EventMesh) deleteSubscription(name string) error { em.namedLogger().Debugf("Deleting EventMesh subscription: %s", name) resp, err := em.client.Delete(name) if err != nil { - return fmt.Errorf("delete subscription failed: %v", err) + return fmt.Errorf("delete subscription failed: %w", err) } if resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusNotFound { return fmt.Errorf("delete subscription failed: %w; %v", @@ -423,7 +425,7 @@ func (em *EventMesh) deleteSubscription(name string) error { func (em *EventMesh) createSubscription(subscription *types.Subscription) error { createResponse, err := em.client.Create(subscription) if err != nil { - return fmt.Errorf("create subscription failed: %v", err) + return fmt.Errorf("create subscription failed: %w", err) } if createResponse.StatusCode > http.StatusAccepted && createResponse.StatusCode != http.StatusConflict { return fmt.Errorf("create subscription failed: %w; %v", diff --git a/pkg/backend/eventmesh/eventmesh_integration_test.go b/pkg/backend/eventmesh/eventmesh_integration_test.go index 391e5757..ad7c8a92 100644 --- a/pkg/backend/eventmesh/eventmesh_integration_test.go +++ b/pkg/backend/eventmesh/eventmesh_integration_test.go @@ -565,11 +565,10 @@ func Test_handleKymaSubStatusUpdate(t *testing.T) { isChanged, _ := eventMesh.handleKymaSubStatusUpdate(tc.givenEventMeshSub, tc.givenEventMeshSub, tc.givenKymaSub, tc.givenTypeInfos) // then - require.Equal(t, isChanged, true) - require.Equal(t, tc.givenKymaSub.Status.Types, tc.wantEventTypes) - require.Equal(t, tc.givenKymaSub.Status.Backend.EmsTypes, tc.wantEventMeshTypes) - require.Equal(t, tc.givenKymaSub.Status.Backend.EventMeshSubscriptionStatus.StatusReason, - tc.givenEventMeshSub.SubscriptionStatusReason) + require.True(t, isChanged) + require.Equal(t, tc.wantEventTypes, tc.givenKymaSub.Status.Types) + require.Equal(t, tc.wantEventMeshTypes, tc.givenKymaSub.Status.Backend.EmsTypes) + require.Equal(t, tc.givenEventMeshSub.SubscriptionStatusReason, tc.givenKymaSub.Status.Backend.EventMeshSubscriptionStatus.StatusReason) }) } } @@ -720,7 +719,7 @@ func Test_handleWebhookAuthChange(t *testing.T) { if test.givenSameHash { hash, hashErr := backendutils.GetWebhookAuthHash(emSub.WebhookAuth) require.NoError(t, hashErr) - require.True(t, hash != 0) + require.NotEqual(t, 0, hash) kymaSub.Status.Backend.WebhookAuthHash = hash // simulate equal hashes } @@ -739,9 +738,9 @@ func Test_handleWebhookAuthChange(t *testing.T) { putURI := fmt.Sprintf("/messaging/events/subscriptions/%s/state", emSubName) // then - require.Equal(t, mock.CountRequests(http.MethodDelete, deleteURI), test.wantDeleteCount) - require.Equal(t, mock.CountRequests(http.MethodPatch, patchURI), test.wantPatchCount) - require.Equal(t, mock.CountRequests(http.MethodPut, putURI), test.wantPutCount) + require.Equal(t, test.wantDeleteCount, mock.CountRequests(http.MethodDelete, deleteURI)) + require.Equal(t, test.wantPatchCount, mock.CountRequests(http.MethodPatch, patchURI)) + require.Equal(t, test.wantPutCount, mock.CountRequests(http.MethodPut, putURI)) }) } } diff --git a/pkg/backend/eventmesh/types.go b/pkg/backend/eventmesh/types.go index 9dfeef50..30fd3328 100644 --- a/pkg/backend/eventmesh/types.go +++ b/pkg/backend/eventmesh/types.go @@ -1,13 +1,15 @@ package eventmesh -import "fmt" +import ( + "strconv" +) type HTTPStatusError struct { StatusCode int } func (e HTTPStatusError) Error() string { - return fmt.Sprintf("%v", e.StatusCode) + return strconv.Itoa(e.StatusCode) } func (e *HTTPStatusError) Is(target error) bool { diff --git a/pkg/backend/eventmesh/utils_unit_test.go b/pkg/backend/eventmesh/utils_unit_test.go index 521470fc..47e4b918 100644 --- a/pkg/backend/eventmesh/utils_unit_test.go +++ b/pkg/backend/eventmesh/utils_unit_test.go @@ -123,7 +123,7 @@ func Test_setEventMeshServerSubHashInStatus(t *testing.T) { // then require.NoError(t, err) - require.Equal(t, kymaSubscription.Status.Backend.EventMeshHash, wantHash) + require.Equal(t, wantHash, kymaSubscription.Status.Backend.EventMeshHash) } func Test_setEventMeshLocalSubHashInStatus(t *testing.T) { @@ -140,7 +140,7 @@ func Test_setEventMeshLocalSubHashInStatus(t *testing.T) { // then require.NoError(t, err) - require.Equal(t, kymaSubscription.Status.Backend.Ev2hash, wantHash) + require.Equal(t, wantHash, kymaSubscription.Status.Backend.Ev2hash) } func Test_updateHashesInStatus(t *testing.T) { @@ -157,8 +157,8 @@ func Test_updateHashesInStatus(t *testing.T) { // then require.NoError(t, err) - require.Equal(t, kymaSubscription.Status.Backend.Ev2hash, wantHash) - require.Equal(t, kymaSubscription.Status.Backend.EventMeshHash, wantHash) + require.Equal(t, wantHash, kymaSubscription.Status.Backend.Ev2hash) + require.Equal(t, wantHash, kymaSubscription.Status.Backend.EventMeshHash) } func Test_setEmsSubscriptionStatus(t *testing.T) { diff --git a/pkg/backend/eventtype/parse.go b/pkg/backend/eventtype/parse.go index 34fad73d..847cbf50 100644 --- a/pkg/backend/eventtype/parse.go +++ b/pkg/backend/eventtype/parse.go @@ -6,6 +6,11 @@ import ( "strings" ) +var ( + ErrPrefixNotFound = errors.New("prefix not found") + ErrInvalidFormat = errors.New("invalid format") +) + // parse splits the event-type using the given prefix and returns the application name, event and version // or an error if the event-type format is invalid. // A valid even-type format should be: prefix.application.event.version or application.event.version @@ -13,7 +18,7 @@ import ( // Constraint: the application segment in the input event-type should not contain ".". func parse(eventType, prefix string) (string, string, string, error) { if !strings.HasPrefix(eventType, prefix) { - return "", "", "", errors.New("prefix not found") + return "", "", "", ErrPrefixNotFound } // remove the prefix @@ -24,7 +29,7 @@ func parse(eventType, prefix string) (string, string, string, error) { // (e.g. application.businessObject.operation.version) parts := strings.Split(eventType, ".") if len(parts) < 4 { - return "", "", "", errors.New("invalid format") + return "", "", "", ErrInvalidFormat } // parse the event-type segments diff --git a/pkg/backend/jetstream/config_internal_unit_test.go b/pkg/backend/jetstream/config_internal_unit_test.go index 98af3ecd..f6dd6ade 100644 --- a/pkg/backend/jetstream/config_internal_unit_test.go +++ b/pkg/backend/jetstream/config_internal_unit_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/kyma-project/eventing-manager/pkg/env" ) @@ -57,7 +57,7 @@ func TestUnitValidate_For_Errors(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { err := Validate(tc.givenConfig) - assert.ErrorIs(t, err, tc.wantError) + require.ErrorIs(t, err, tc.wantError) }) } } diff --git a/pkg/backend/jetstream/connection_integration_test.go b/pkg/backend/jetstream/connection_integration_test.go index 6988d8c3..240afb81 100644 --- a/pkg/backend/jetstream/connection_integration_test.go +++ b/pkg/backend/jetstream/connection_integration_test.go @@ -39,10 +39,10 @@ func Test_ConnectionBuilder_Build(t *testing.T) { require.True(t, ok) // ensure the options are set - assert.Equal(t, natsConn.Opts.Name, "Kyma Controller") + assert.Equal(t, "Kyma Controller", natsConn.Opts.Name) assert.Equal(t, natsConn.Opts.MaxReconnect, config.MaxReconnects) assert.Equal(t, natsConn.Opts.ReconnectWait, config.ReconnectWait) - assert.Equal(t, natsConn.Opts.RetryOnFailedConnect, true) + assert.True(t, natsConn.Opts.RetryOnFailedConnect) } func Test_ConnectionBuilder_Build_ForErrConnect(t *testing.T) { @@ -62,7 +62,7 @@ func Test_ConnectionBuilder_Build_ForErrConnect(t *testing.T) { _, err := cb.Build() // then - assert.ErrorIs(t, err, jetstream.ErrConnect) + require.ErrorIs(t, err, jetstream.ErrConnect) } // Test_ConnectionBuilder_IsConnected ensures that the IsConnected method always returns the correct value. @@ -81,8 +81,8 @@ func Test_ConnectionBuilder_IsConnected(t *testing.T) { connection, err := cb.Build() // then + require.NoError(t, err) assert.True(t, connection.IsConnected()) - assert.NoError(t, err) assert.NotNil(t, connection) // when: NATS server is offline diff --git a/pkg/backend/jetstream/jetstream.go b/pkg/backend/jetstream/jetstream.go index f470d0e9..36f9b3c5 100644 --- a/pkg/backend/jetstream/jetstream.go +++ b/pkg/backend/jetstream/jetstream.go @@ -232,7 +232,7 @@ func (js *JetStream) validateConfig() error { return pkgerrors.New("Stream name cannot be empty") } if len(js.Config.JSStreamName) > jsMaxStreamNameLength { - return fmt.Errorf("stream name should be max %d characters long", jsMaxStreamNameLength) + return ErrStreamNameTooLong } if _, err := toJetStreamStorageType(js.Config.JSStreamStorageType); err != nil { return err diff --git a/pkg/backend/jetstream/jetstream_integration_test.go b/pkg/backend/jetstream/jetstream_integration_test.go index a9c50974..277c03de 100644 --- a/pkg/backend/jetstream/jetstream_integration_test.go +++ b/pkg/backend/jetstream/jetstream_integration_test.go @@ -1,7 +1,6 @@ package jetstream import ( - "errors" "fmt" "net" "testing" @@ -9,7 +8,6 @@ import ( kymalogger "github.com/kyma-project/kyma/common/logging/logger" "github.com/nats-io/nats.go" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" eventingv1alpha2 "github.com/kyma-project/eventing-manager/api/eventing/v1alpha2" @@ -439,7 +437,7 @@ func TestJetStream_NATSSubscriptionCount(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { // create a new subscription with no filters - sub := eventingtesting.NewSubscription("sub"+fmt.Sprint(i), "foo", + sub := eventingtesting.NewSubscription(fmt.Sprintf("sub%v", i), "foo", tc.subOpts..., ) AddJSCleanEventTypesToStatus(sub, testEnvironment.cleaner) @@ -447,7 +445,7 @@ func TestJetStream_NATSSubscriptionCount(t *testing.T) { // when err := jsBackend.SyncSubscription(sub) require.NoError(t, err) - require.Equal(t, len(jsBackend.subscriptions), tc.wantNatsSubsLen) + require.Len(t, jsBackend.subscriptions, tc.wantNatsSubsLen) if tc.givenManuallyDeleteSubscription { // manually delete the subscription from map @@ -464,7 +462,7 @@ func TestJetStream_NATSSubscriptionCount(t *testing.T) { // because the subscription was manually deleted from the js.subscriptions map // hence the consumer will be shown in the NATS Backend as still bound err = jsBackend.SyncSubscription(sub) - assert.ErrorIs(t, err, tc.wantErr) + require.ErrorIs(t, err, tc.wantErr) } // empty the js.subscriptions map @@ -564,7 +562,7 @@ func TestJetStream_ServerRestart(t *testing.T) { _, err = testEnvironment.jsClient.StreamInfo(testEnvironment.natsConfig.JSStreamName) if tc.givenStorageType == StorageTypeMemory && tc.givenMaxReconnects == 0 { // for memory storage with reconnects disabled - require.True(t, errors.Is(err, nats.ErrStreamNotFound)) + require.ErrorIs(t, nats.ErrStreamNotFound, err) } else { // check that the stream is still present for file storage // or recreated via reconnect handler for memory storage diff --git a/pkg/backend/jetstream/jetstream_internal_unit_test.go b/pkg/backend/jetstream/jetstream_internal_unit_test.go index ac1399ab..6739de4c 100644 --- a/pkg/backend/jetstream/jetstream_internal_unit_test.go +++ b/pkg/backend/jetstream/jetstream_internal_unit_test.go @@ -30,7 +30,7 @@ func Test_SyncConsumersAndSubscriptions_ForEmptyTypes(t *testing.T) { err := js.syncConsumerAndSubscription(subWithOneType, callback) // then - assert.NoError(t, err) + require.NoError(t, err) } func Test_streamIsConfiguredCorrectly(t *testing.T) { @@ -168,7 +168,7 @@ func Test_GetOrCreateConsumer(t *testing.T) { // then assert.Equal(t, tc.wantConsumerInfo, consumerInfo) - assert.ErrorIs(t, tc.wantError, err) + require.ErrorIs(t, tc.wantError, err) }) } } @@ -248,7 +248,7 @@ func Test_SyncConsumersAndSubscriptions_ForBindInvalidSubscriptions(t *testing.T tc.mocks(subWithOneType, js, jsCtxMock, jsSubKey) // when - assert.NoError(t, js.syncConsumerAndSubscription(subWithOneType, callback)) + require.NoError(t, js.syncConsumerAndSubscription(subWithOneType, callback)) // then jsCtxMock.AssertExpectations(t) @@ -319,7 +319,7 @@ func Test_SyncConsumersAndSubscriptions_ForSyncConsumerMaxInFlight(t *testing.T) err := js.syncConsumerMaxInFlight(sub, consumer) // then - assert.NoError(t, err) + require.NoError(t, err) jsCtxMock.AssertExpectations(t) }) } @@ -431,7 +431,7 @@ func Test_SyncConsumersAndSubscriptions_ForErrors(t *testing.T) { err := js.syncConsumerAndSubscription(subWithOneType, callback) // then - assert.ErrorIs(t, err, testCase.wantError) + require.ErrorIs(t, err, testCase.wantError) }) } } @@ -542,7 +542,7 @@ func Test_DeleteSubscriptionFromJetStream(t *testing.T) { resultErr := jsBackend.deleteSubscriptionFromJetStream(jsBackend.subscriptions[jsSubKey], jsSubKey) // then - assert.ErrorIs(t, resultErr, testCase.wantError) + require.ErrorIs(t, resultErr, testCase.wantError) if testCase.wantError == nil { assert.Equal(t, testCase.wantSubscriptionMap, jsBackend.subscriptions) } @@ -626,7 +626,7 @@ func Test_DeleteInvalidConsumers(t *testing.T) { // then if tc.wantError != nil { - assert.ErrorIs(t, err, tc.wantError) + require.ErrorIs(t, err, tc.wantError) } else { cons := jsBackend.jsCtx.Consumers("") actualConsumers := []*nats.ConsumerInfo{} diff --git a/pkg/backend/jetstream/mocks/Backend.go b/pkg/backend/jetstream/mocks/Backend.go index c3e98314..74fd1a32 100644 --- a/pkg/backend/jetstream/mocks/Backend.go +++ b/pkg/backend/jetstream/mocks/Backend.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -31,6 +31,10 @@ func (_m *Backend) EXPECT() *Backend_Expecter { func (_m *Backend) DeleteInvalidConsumers(subscriptions []v1alpha2.Subscription) error { ret := _m.Called(subscriptions) + if len(ret) == 0 { + panic("no return value specified for DeleteInvalidConsumers") + } + var r0 error if rf, ok := ret.Get(0).(func([]v1alpha2.Subscription) error); ok { r0 = rf(subscriptions) @@ -73,6 +77,10 @@ func (_c *Backend_DeleteInvalidConsumers_Call) RunAndReturn(run func([]v1alpha2. func (_m *Backend) DeleteSubscription(subscription *v1alpha2.Subscription) error { ret := _m.Called(subscription) + if len(ret) == 0 { + panic("no return value specified for DeleteSubscription") + } + var r0 error if rf, ok := ret.Get(0).(func(*v1alpha2.Subscription) error); ok { r0 = rf(subscription) @@ -115,6 +123,10 @@ func (_c *Backend_DeleteSubscription_Call) RunAndReturn(run func(*v1alpha2.Subsc func (_m *Backend) DeleteSubscriptionsOnly(subscription *v1alpha2.Subscription) error { ret := _m.Called(subscription) + if len(ret) == 0 { + panic("no return value specified for DeleteSubscriptionsOnly") + } + var r0 error if rf, ok := ret.Get(0).(func(*v1alpha2.Subscription) error); ok { r0 = rf(subscription) @@ -157,6 +169,10 @@ func (_c *Backend_DeleteSubscriptionsOnly_Call) RunAndReturn(run func(*v1alpha2. func (_m *Backend) GetConfig() env.NATSConfig { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetConfig") + } + var r0 env.NATSConfig if rf, ok := ret.Get(0).(func() env.NATSConfig); ok { r0 = rf() @@ -198,6 +214,10 @@ func (_c *Backend_GetConfig_Call) RunAndReturn(run func() env.NATSConfig) *Backe func (_m *Backend) GetJetStreamContext() nats.JetStreamContext { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetJetStreamContext") + } + var r0 nats.JetStreamContext if rf, ok := ret.Get(0).(func() nats.JetStreamContext); ok { r0 = rf() @@ -241,6 +261,10 @@ func (_c *Backend_GetJetStreamContext_Call) RunAndReturn(run func() nats.JetStre func (_m *Backend) GetJetStreamSubjects(source string, subjects []string, typeMatching v1alpha2.TypeMatching) []string { ret := _m.Called(source, subjects, typeMatching) + if len(ret) == 0 { + panic("no return value specified for GetJetStreamSubjects") + } + var r0 []string if rf, ok := ret.Get(0).(func(string, []string, v1alpha2.TypeMatching) []string); ok { r0 = rf(source, subjects, typeMatching) @@ -287,6 +311,10 @@ func (_c *Backend_GetJetStreamSubjects_Call) RunAndReturn(run func(string, []str func (_m *Backend) Initialize(connCloseHandler utils.ConnClosedHandler) error { ret := _m.Called(connCloseHandler) + if len(ret) == 0 { + panic("no return value specified for Initialize") + } + var r0 error if rf, ok := ret.Get(0).(func(utils.ConnClosedHandler) error); ok { r0 = rf(connCloseHandler) @@ -361,6 +389,10 @@ func (_c *Backend_Shutdown_Call) RunAndReturn(run func()) *Backend_Shutdown_Call func (_m *Backend) SyncSubscription(subscription *v1alpha2.Subscription) error { ret := _m.Called(subscription) + if len(ret) == 0 { + panic("no return value specified for SyncSubscription") + } + var r0 error if rf, ok := ret.Get(0).(func(*v1alpha2.Subscription) error); ok { r0 = rf(subscription) diff --git a/pkg/backend/jetstream/mocks/JetStreamContext.go b/pkg/backend/jetstream/mocks/JetStreamContext.go index a2150ef3..c23f16b2 100644 --- a/pkg/backend/jetstream/mocks/JetStreamContext.go +++ b/pkg/backend/jetstream/mocks/JetStreamContext.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -30,6 +30,10 @@ func (_m *JetStreamContext) AccountInfo(opts ...nats.JSOpt) (*nats.AccountInfo, _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for AccountInfo") + } + var r0 *nats.AccountInfo var r1 error if rf, ok := ret.Get(0).(func(...nats.JSOpt) (*nats.AccountInfo, error)); ok { @@ -98,6 +102,10 @@ func (_m *JetStreamContext) AddConsumer(stream string, cfg *nats.ConsumerConfig, _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for AddConsumer") + } + var r0 *nats.ConsumerInfo var r1 error if rf, ok := ret.Get(0).(func(string, *nats.ConsumerConfig, ...nats.JSOpt) (*nats.ConsumerInfo, error)); ok { @@ -168,6 +176,10 @@ func (_m *JetStreamContext) AddStream(cfg *nats.StreamConfig, opts ...nats.JSOpt _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for AddStream") + } + var r0 *nats.StreamInfo var r1 error if rf, ok := ret.Get(0).(func(*nats.StreamConfig, ...nats.JSOpt) (*nats.StreamInfo, error)); ok { @@ -237,6 +249,10 @@ func (_m *JetStreamContext) ChanQueueSubscribe(subj string, queue string, ch cha _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for ChanQueueSubscribe") + } + var r0 *nats.Subscription var r1 error if rf, ok := ret.Get(0).(func(string, string, chan *nats.Msg, ...nats.SubOpt) (*nats.Subscription, error)); ok { @@ -308,6 +324,10 @@ func (_m *JetStreamContext) ChanSubscribe(subj string, ch chan *nats.Msg, opts . _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for ChanSubscribe") + } + var r0 *nats.Subscription var r1 error if rf, ok := ret.Get(0).(func(string, chan *nats.Msg, ...nats.SubOpt) (*nats.Subscription, error)); ok { @@ -378,6 +398,10 @@ func (_m *JetStreamContext) ConsumerInfo(stream string, name string, opts ...nat _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for ConsumerInfo") + } + var r0 *nats.ConsumerInfo var r1 error if rf, ok := ret.Get(0).(func(string, string, ...nats.JSOpt) (*nats.ConsumerInfo, error)); ok { @@ -448,6 +472,10 @@ func (_m *JetStreamContext) ConsumerNames(stream string, opts ...nats.JSOpt) <-c _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for ConsumerNames") + } + var r0 <-chan string if rf, ok := ret.Get(0).(func(string, ...nats.JSOpt) <-chan string); ok { r0 = rf(stream, opts...) @@ -507,6 +535,10 @@ func (_m *JetStreamContext) Consumers(stream string, opts ...nats.JSOpt) <-chan _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for Consumers") + } + var r0 <-chan *nats.ConsumerInfo if rf, ok := ret.Get(0).(func(string, ...nats.JSOpt) <-chan *nats.ConsumerInfo); ok { r0 = rf(stream, opts...) @@ -566,6 +598,10 @@ func (_m *JetStreamContext) ConsumersInfo(stream string, opts ...nats.JSOpt) <-c _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for ConsumersInfo") + } + var r0 <-chan *nats.ConsumerInfo if rf, ok := ret.Get(0).(func(string, ...nats.JSOpt) <-chan *nats.ConsumerInfo); ok { r0 = rf(stream, opts...) @@ -618,6 +654,10 @@ func (_c *JetStreamContext_ConsumersInfo_Call) RunAndReturn(run func(string, ... func (_m *JetStreamContext) CreateKeyValue(cfg *nats.KeyValueConfig) (nats.KeyValue, error) { ret := _m.Called(cfg) + if len(ret) == 0 { + panic("no return value specified for CreateKeyValue") + } + var r0 nats.KeyValue var r1 error if rf, ok := ret.Get(0).(func(*nats.KeyValueConfig) (nats.KeyValue, error)); ok { @@ -672,6 +712,10 @@ func (_c *JetStreamContext_CreateKeyValue_Call) RunAndReturn(run func(*nats.KeyV func (_m *JetStreamContext) CreateObjectStore(cfg *nats.ObjectStoreConfig) (nats.ObjectStore, error) { ret := _m.Called(cfg) + if len(ret) == 0 { + panic("no return value specified for CreateObjectStore") + } + var r0 nats.ObjectStore var r1 error if rf, ok := ret.Get(0).(func(*nats.ObjectStoreConfig) (nats.ObjectStore, error)); ok { @@ -733,6 +777,10 @@ func (_m *JetStreamContext) DeleteConsumer(stream string, consumer string, opts _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for DeleteConsumer") + } + var r0 error if rf, ok := ret.Get(0).(func(string, string, ...nats.JSOpt) error); ok { r0 = rf(stream, consumer, opts...) @@ -784,6 +832,10 @@ func (_c *JetStreamContext_DeleteConsumer_Call) RunAndReturn(run func(string, st func (_m *JetStreamContext) DeleteKeyValue(bucket string) error { ret := _m.Called(bucket) + if len(ret) == 0 { + panic("no return value specified for DeleteKeyValue") + } + var r0 error if rf, ok := ret.Get(0).(func(string) error); ok { r0 = rf(bucket) @@ -833,6 +885,10 @@ func (_m *JetStreamContext) DeleteMsg(name string, seq uint64, opts ...nats.JSOp _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for DeleteMsg") + } + var r0 error if rf, ok := ret.Get(0).(func(string, uint64, ...nats.JSOpt) error); ok { r0 = rf(name, seq, opts...) @@ -884,6 +940,10 @@ func (_c *JetStreamContext_DeleteMsg_Call) RunAndReturn(run func(string, uint64, func (_m *JetStreamContext) DeleteObjectStore(bucket string) error { ret := _m.Called(bucket) + if len(ret) == 0 { + panic("no return value specified for DeleteObjectStore") + } + var r0 error if rf, ok := ret.Get(0).(func(string) error); ok { r0 = rf(bucket) @@ -933,6 +993,10 @@ func (_m *JetStreamContext) DeleteStream(name string, opts ...nats.JSOpt) error _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for DeleteStream") + } + var r0 error if rf, ok := ret.Get(0).(func(string, ...nats.JSOpt) error); ok { r0 = rf(name, opts...) @@ -990,6 +1054,10 @@ func (_m *JetStreamContext) GetLastMsg(name string, subject string, opts ...nats _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for GetLastMsg") + } + var r0 *nats.RawStreamMsg var r1 error if rf, ok := ret.Get(0).(func(string, string, ...nats.JSOpt) (*nats.RawStreamMsg, error)); ok { @@ -1060,6 +1128,10 @@ func (_m *JetStreamContext) GetMsg(name string, seq uint64, opts ...nats.JSOpt) _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for GetMsg") + } + var r0 *nats.RawStreamMsg var r1 error if rf, ok := ret.Get(0).(func(string, uint64, ...nats.JSOpt) (*nats.RawStreamMsg, error)); ok { @@ -1123,6 +1195,10 @@ func (_c *JetStreamContext_GetMsg_Call) RunAndReturn(run func(string, uint64, .. func (_m *JetStreamContext) KeyValue(bucket string) (nats.KeyValue, error) { ret := _m.Called(bucket) + if len(ret) == 0 { + panic("no return value specified for KeyValue") + } + var r0 nats.KeyValue var r1 error if rf, ok := ret.Get(0).(func(string) (nats.KeyValue, error)); ok { @@ -1177,6 +1253,10 @@ func (_c *JetStreamContext_KeyValue_Call) RunAndReturn(run func(string) (nats.Ke func (_m *JetStreamContext) KeyValueStoreNames() <-chan string { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for KeyValueStoreNames") + } + var r0 <-chan string if rf, ok := ret.Get(0).(func() <-chan string); ok { r0 = rf() @@ -1220,6 +1300,10 @@ func (_c *JetStreamContext_KeyValueStoreNames_Call) RunAndReturn(run func() <-ch func (_m *JetStreamContext) KeyValueStores() <-chan nats.KeyValueStatus { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for KeyValueStores") + } + var r0 <-chan nats.KeyValueStatus if rf, ok := ret.Get(0).(func() <-chan nats.KeyValueStatus); ok { r0 = rf() @@ -1263,6 +1347,10 @@ func (_c *JetStreamContext_KeyValueStores_Call) RunAndReturn(run func() <-chan n func (_m *JetStreamContext) ObjectStore(bucket string) (nats.ObjectStore, error) { ret := _m.Called(bucket) + if len(ret) == 0 { + panic("no return value specified for ObjectStore") + } + var r0 nats.ObjectStore var r1 error if rf, ok := ret.Get(0).(func(string) (nats.ObjectStore, error)); ok { @@ -1323,6 +1411,10 @@ func (_m *JetStreamContext) ObjectStoreNames(opts ...nats.ObjectOpt) <-chan stri _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for ObjectStoreNames") + } + var r0 <-chan string if rf, ok := ret.Get(0).(func(...nats.ObjectOpt) <-chan string); ok { r0 = rf(opts...) @@ -1380,6 +1472,10 @@ func (_m *JetStreamContext) ObjectStores(opts ...nats.ObjectOpt) <-chan nats.Obj _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for ObjectStores") + } + var r0 <-chan nats.ObjectStoreStatus if rf, ok := ret.Get(0).(func(...nats.ObjectOpt) <-chan nats.ObjectStoreStatus); ok { r0 = rf(opts...) @@ -1438,6 +1534,10 @@ func (_m *JetStreamContext) Publish(subj string, data []byte, opts ...nats.PubOp _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for Publish") + } + var r0 *nats.PubAck var r1 error if rf, ok := ret.Get(0).(func(string, []byte, ...nats.PubOpt) (*nats.PubAck, error)); ok { @@ -1508,6 +1608,10 @@ func (_m *JetStreamContext) PublishAsync(subj string, data []byte, opts ...nats. _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for PublishAsync") + } + var r0 nats.PubAckFuture var r1 error if rf, ok := ret.Get(0).(func(string, []byte, ...nats.PubOpt) (nats.PubAckFuture, error)); ok { @@ -1571,6 +1675,10 @@ func (_c *JetStreamContext_PublishAsync_Call) RunAndReturn(run func(string, []by func (_m *JetStreamContext) PublishAsyncComplete() <-chan struct{} { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for PublishAsyncComplete") + } + var r0 <-chan struct{} if rf, ok := ret.Get(0).(func() <-chan struct{}); ok { r0 = rf() @@ -1614,6 +1722,10 @@ func (_c *JetStreamContext_PublishAsyncComplete_Call) RunAndReturn(run func() <- func (_m *JetStreamContext) PublishAsyncPending() int { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for PublishAsyncPending") + } + var r0 int if rf, ok := ret.Get(0).(func() int); ok { r0 = rf() @@ -1662,6 +1774,10 @@ func (_m *JetStreamContext) PublishMsg(m *nats.Msg, opts ...nats.PubOpt) (*nats. _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for PublishMsg") + } + var r0 *nats.PubAck var r1 error if rf, ok := ret.Get(0).(func(*nats.Msg, ...nats.PubOpt) (*nats.PubAck, error)); ok { @@ -1731,6 +1847,10 @@ func (_m *JetStreamContext) PublishMsgAsync(m *nats.Msg, opts ...nats.PubOpt) (n _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for PublishMsgAsync") + } + var r0 nats.PubAckFuture var r1 error if rf, ok := ret.Get(0).(func(*nats.Msg, ...nats.PubOpt) (nats.PubAckFuture, error)); ok { @@ -1800,6 +1920,10 @@ func (_m *JetStreamContext) PullSubscribe(subj string, durable string, opts ...n _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for PullSubscribe") + } + var r0 *nats.Subscription var r1 error if rf, ok := ret.Get(0).(func(string, string, ...nats.SubOpt) (*nats.Subscription, error)); ok { @@ -1870,6 +1994,10 @@ func (_m *JetStreamContext) PurgeStream(name string, opts ...nats.JSOpt) error { _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for PurgeStream") + } + var r0 error if rf, ok := ret.Get(0).(func(string, ...nats.JSOpt) error); ok { r0 = rf(name, opts...) @@ -1927,6 +2055,10 @@ func (_m *JetStreamContext) QueueSubscribe(subj string, queue string, cb nats.Ms _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for QueueSubscribe") + } + var r0 *nats.Subscription var r1 error if rf, ok := ret.Get(0).(func(string, string, nats.MsgHandler, ...nats.SubOpt) (*nats.Subscription, error)); ok { @@ -1998,6 +2130,10 @@ func (_m *JetStreamContext) QueueSubscribeSync(subj string, queue string, opts . _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for QueueSubscribeSync") + } + var r0 *nats.Subscription var r1 error if rf, ok := ret.Get(0).(func(string, string, ...nats.SubOpt) (*nats.Subscription, error)); ok { @@ -2068,6 +2204,10 @@ func (_m *JetStreamContext) SecureDeleteMsg(name string, seq uint64, opts ...nat _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for SecureDeleteMsg") + } + var r0 error if rf, ok := ret.Get(0).(func(string, uint64, ...nats.JSOpt) error); ok { r0 = rf(name, seq, opts...) @@ -2126,6 +2266,10 @@ func (_m *JetStreamContext) StreamInfo(stream string, opts ...nats.JSOpt) (*nats _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for StreamInfo") + } + var r0 *nats.StreamInfo var r1 error if rf, ok := ret.Get(0).(func(string, ...nats.JSOpt) (*nats.StreamInfo, error)); ok { @@ -2195,6 +2339,10 @@ func (_m *JetStreamContext) StreamNameBySubject(_a0 string, _a1 ...nats.JSOpt) ( _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for StreamNameBySubject") + } + var r0 string var r1 error if rf, ok := ret.Get(0).(func(string, ...nats.JSOpt) (string, error)); ok { @@ -2261,6 +2409,10 @@ func (_m *JetStreamContext) StreamNames(opts ...nats.JSOpt) <-chan string { _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for StreamNames") + } + var r0 <-chan string if rf, ok := ret.Get(0).(func(...nats.JSOpt) <-chan string); ok { r0 = rf(opts...) @@ -2318,6 +2470,10 @@ func (_m *JetStreamContext) Streams(opts ...nats.JSOpt) <-chan *nats.StreamInfo _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for Streams") + } + var r0 <-chan *nats.StreamInfo if rf, ok := ret.Get(0).(func(...nats.JSOpt) <-chan *nats.StreamInfo); ok { r0 = rf(opts...) @@ -2375,6 +2531,10 @@ func (_m *JetStreamContext) StreamsInfo(opts ...nats.JSOpt) <-chan *nats.StreamI _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for StreamsInfo") + } + var r0 <-chan *nats.StreamInfo if rf, ok := ret.Get(0).(func(...nats.JSOpt) <-chan *nats.StreamInfo); ok { r0 = rf(opts...) @@ -2433,6 +2593,10 @@ func (_m *JetStreamContext) Subscribe(subj string, cb nats.MsgHandler, opts ...n _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for Subscribe") + } + var r0 *nats.Subscription var r1 error if rf, ok := ret.Get(0).(func(string, nats.MsgHandler, ...nats.SubOpt) (*nats.Subscription, error)); ok { @@ -2503,6 +2667,10 @@ func (_m *JetStreamContext) SubscribeSync(subj string, opts ...nats.SubOpt) (*na _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for SubscribeSync") + } + var r0 *nats.Subscription var r1 error if rf, ok := ret.Get(0).(func(string, ...nats.SubOpt) (*nats.Subscription, error)); ok { @@ -2572,6 +2740,10 @@ func (_m *JetStreamContext) UpdateConsumer(stream string, cfg *nats.ConsumerConf _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for UpdateConsumer") + } + var r0 *nats.ConsumerInfo var r1 error if rf, ok := ret.Get(0).(func(string, *nats.ConsumerConfig, ...nats.JSOpt) (*nats.ConsumerInfo, error)); ok { @@ -2642,6 +2814,10 @@ func (_m *JetStreamContext) UpdateStream(cfg *nats.StreamConfig, opts ...nats.JS _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for UpdateStream") + } + var r0 *nats.StreamInfo var r1 error if rf, ok := ret.Get(0).(func(*nats.StreamConfig, ...nats.JSOpt) (*nats.StreamInfo, error)); ok { diff --git a/pkg/backend/jetstream/utils_internal_unit_test.go b/pkg/backend/jetstream/utils_internal_unit_test.go index eec0628b..f1f0cdc4 100644 --- a/pkg/backend/jetstream/utils_internal_unit_test.go +++ b/pkg/backend/jetstream/utils_internal_unit_test.go @@ -237,7 +237,7 @@ func TestGetCleanEventTypesFromStatus(t *testing.T) { // when cleanTypes := GetCleanEventTypesFromEventTypes(sub.Status.Types) // then - require.Equal(t, cleanTypes, []string{eventingtesting.OrderCreatedCleanEvent, eventingtesting.OrderCreatedEventType}) + require.Equal(t, []string{eventingtesting.OrderCreatedCleanEvent, eventingtesting.OrderCreatedEventType}, cleanTypes) } func TestGetCleanEventTypes(t *testing.T) { @@ -536,7 +536,7 @@ func TestSubscriptionSubjectIdentifierConsumerNameLength(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() - require.Equal(t, tc.wantConsumerNameLength, len(tc.givenIdentifier.ConsumerName())) + require.Len(t, tc.givenIdentifier.ConsumerName(), tc.wantConsumerNameLength) }) } } diff --git a/pkg/backend/metrics/collector.go b/pkg/backend/metrics/collector.go index f83cf2a7..6417c665 100644 --- a/pkg/backend/metrics/collector.go +++ b/pkg/backend/metrics/collector.go @@ -1,7 +1,7 @@ package metrics import ( - "fmt" + "strconv" "time" "github.com/prometheus/client_golang/prometheus" @@ -132,8 +132,8 @@ func (c *Collector) RecordDeliveryPerSubscription(subscriptionName, subscription subscriptionName, subscriptionNamespace, eventType, - fmt.Sprintf("%v", sink), - fmt.Sprintf("%v", statusCode), + sink, + strconv.Itoa(statusCode), consumerName).Inc() } @@ -147,8 +147,8 @@ func (c *Collector) RecordLatencyPerSubscription( subscriptionName, subscriptionNamespace, eventType, - fmt.Sprintf("%v", sink), - fmt.Sprintf("%v", statusCode), + sink, + strconv.Itoa(statusCode), consumerName).Observe(duration.Seconds()) } diff --git a/pkg/backend/sink/validator.go b/pkg/backend/sink/validator.go index b7cc2e40..bf55f8b1 100644 --- a/pkg/backend/sink/validator.go +++ b/pkg/backend/sink/validator.go @@ -16,18 +16,17 @@ import ( ) type Validator interface { - Validate(subscription *v1alpha2.Subscription) error + Validate(ctx context.Context, subscription *v1alpha2.Subscription) error } // ValidatorFunc implements the Validator interface. -type ValidatorFunc func(*v1alpha2.Subscription) error +type ValidatorFunc func(context.Context, *v1alpha2.Subscription) error -func (vf ValidatorFunc) Validate(sub *v1alpha2.Subscription) error { - return vf(sub) +func (vf ValidatorFunc) Validate(ctx context.Context, sub *v1alpha2.Subscription) error { + return vf(ctx, sub) } type defaultSinkValidator struct { - ctx context.Context client client.Client recorder record.EventRecorder } @@ -35,11 +34,11 @@ type defaultSinkValidator struct { // Perform a compile-time check. var _ Validator = &defaultSinkValidator{} -func NewValidator(ctx context.Context, client client.Client, recorder record.EventRecorder) Validator { - return &defaultSinkValidator{ctx: ctx, client: client, recorder: recorder} +func NewValidator(client client.Client, recorder record.EventRecorder) Validator { + return &defaultSinkValidator{client: client, recorder: recorder} } -func (s defaultSinkValidator) Validate(subscription *v1alpha2.Subscription) error { +func (s defaultSinkValidator) Validate(ctx context.Context, subscription *v1alpha2.Subscription) error { _, subDomains, err := utils.GetSinkData(subscription.Spec.Sink) if err != nil { return err @@ -48,7 +47,7 @@ func (s defaultSinkValidator) Validate(subscription *v1alpha2.Subscription) erro svcName := subDomains[0] // Validate svc is a cluster-local one - if _, err := GetClusterLocalService(s.ctx, s.client, svcNs, svcName); err != nil { + if _, err := GetClusterLocalService(ctx, s.client, svcNs, svcName); err != nil { if kerrors.IsNotFound(err) { events.Warn(s.recorder, subscription, events.ReasonValidationFailed, "Sink does not correspond to a valid cluster local svc") return xerrors.Errorf("failed to validate subscription sink URL. It is not a valid cluster local svc: %v", err) diff --git a/pkg/backend/sink/validator_test.go b/pkg/backend/sink/validator_test.go index 02270051..e2a7f529 100644 --- a/pkg/backend/sink/validator_test.go +++ b/pkg/backend/sink/validator_test.go @@ -22,7 +22,7 @@ func TestSinkValidator(t *testing.T) { fakeClient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build() ctx := context.Background() recorder := &record.FakeRecorder{} - sinkValidator := NewValidator(ctx, fakeClient, recorder) + sinkValidator := NewValidator(fakeClient, recorder) testCases := []struct { name string @@ -80,7 +80,7 @@ func TestSinkValidator(t *testing.T) { // when // call the defaultSinkValidator function - err := sinkValidator.Validate(sub) + err := sinkValidator.Validate(ctx, sub) // then // given error should match expected error diff --git a/pkg/backend/utils/eventmesh_utils.go b/pkg/backend/utils/eventmesh_utils.go index 7b1649fe..8c62dee2 100644 --- a/pkg/backend/utils/eventmesh_utils.go +++ b/pkg/backend/utils/eventmesh_utils.go @@ -2,6 +2,7 @@ package utils import ( "crypto/sha1" //nolint:gosec + "encoding/hex" "fmt" "strconv" @@ -70,7 +71,7 @@ func GetWebhookAuthHash(webhookAuth *types.WebhookAuth) (int64, error) { func hashSubscriptionFullName(domainName, namespace, name string) string { hash := sha1.Sum([]byte(domainName + namespace + name)) //nolint:gosec - return fmt.Sprintf("%x", hash) + return hex.EncodeToString(hash[:]) } func getDefaultSubscriptionV1Alpha2(protocolSettings *ProtocolSettings) (*types.Subscription, error) { diff --git a/pkg/ems/api/events/client/mocks/PublisherManager.go b/pkg/ems/api/events/client/mocks/PublisherManager.go index c575f6f7..a10f800a 100644 --- a/pkg/ems/api/events/client/mocks/PublisherManager.go +++ b/pkg/ems/api/events/client/mocks/PublisherManager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -26,6 +26,10 @@ func (_m *PublisherManager) EXPECT() *PublisherManager_Expecter { func (_m *PublisherManager) Create(subscription *types.Subscription) (*types.CreateResponse, error) { ret := _m.Called(subscription) + if len(ret) == 0 { + panic("no return value specified for Create") + } + var r0 *types.CreateResponse var r1 error if rf, ok := ret.Get(0).(func(*types.Subscription) (*types.CreateResponse, error)); ok { @@ -80,6 +84,10 @@ func (_c *PublisherManager_Create_Call) RunAndReturn(run func(*types.Subscriptio func (_m *PublisherManager) Delete(name string) (*types.DeleteResponse, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for Delete") + } + var r0 *types.DeleteResponse var r1 error if rf, ok := ret.Get(0).(func(string) (*types.DeleteResponse, error)); ok { @@ -134,6 +142,10 @@ func (_c *PublisherManager_Delete_Call) RunAndReturn(run func(string) (*types.De func (_m *PublisherManager) Get(name string) (*types.Subscription, *types.Response, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for Get") + } + var r0 *types.Subscription var r1 *types.Response var r2 error @@ -197,6 +209,10 @@ func (_c *PublisherManager_Get_Call) RunAndReturn(run func(string) (*types.Subsc func (_m *PublisherManager) List() (*types.Subscriptions, *types.Response, error) { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for List") + } + var r0 *types.Subscriptions var r1 *types.Response var r2 error @@ -259,6 +275,10 @@ func (_c *PublisherManager_List_Call) RunAndReturn(run func() (*types.Subscripti func (_m *PublisherManager) Publish(cloudEvent event.Event, qos types.Qos) (*types.PublishResponse, error) { ret := _m.Called(cloudEvent, qos) + if len(ret) == 0 { + panic("no return value specified for Publish") + } + var r0 *types.PublishResponse var r1 error if rf, ok := ret.Get(0).(func(event.Event, types.Qos) (*types.PublishResponse, error)); ok { @@ -314,6 +334,10 @@ func (_c *PublisherManager_Publish_Call) RunAndReturn(run func(event.Event, type func (_m *PublisherManager) TriggerHandshake(name string) (*types.TriggerHandshake, error) { ret := _m.Called(name) + if len(ret) == 0 { + panic("no return value specified for TriggerHandshake") + } + var r0 *types.TriggerHandshake var r1 error if rf, ok := ret.Get(0).(func(string) (*types.TriggerHandshake, error)); ok { @@ -368,6 +392,10 @@ func (_c *PublisherManager_TriggerHandshake_Call) RunAndReturn(run func(string) func (_m *PublisherManager) Update(name string, webhookAuth *types.WebhookAuth) (*types.UpdateResponse, error) { ret := _m.Called(name, webhookAuth) + if len(ret) == 0 { + panic("no return value specified for Update") + } + var r0 *types.UpdateResponse var r1 error if rf, ok := ret.Get(0).(func(string, *types.WebhookAuth) (*types.UpdateResponse, error)); ok { @@ -423,6 +451,10 @@ func (_c *PublisherManager_Update_Call) RunAndReturn(run func(string, *types.Web func (_m *PublisherManager) UpdateState(name string, state types.State) (*types.UpdateStateResponse, error) { ret := _m.Called(name, state) + if len(ret) == 0 { + panic("no return value specified for UpdateState") + } + var r0 *types.UpdateStateResponse var r1 error if rf, ok := ret.Get(0).(func(string, types.State) (*types.UpdateStateResponse, error)); ok { diff --git a/pkg/ems/httpclient/error_unit_test.go b/pkg/ems/httpclient/error_unit_test.go index 70fafe80..5880dbb6 100644 --- a/pkg/ems/httpclient/error_unit_test.go +++ b/pkg/ems/httpclient/error_unit_test.go @@ -1,3 +1,4 @@ +//nolint:goerr113 // no need to wrap errors in the test for the error package package httpclient import ( diff --git a/pkg/env/config.go b/pkg/env/config.go index d4eabf1f..5604f5cb 100644 --- a/pkg/env/config.go +++ b/pkg/env/config.go @@ -8,6 +8,7 @@ import ( "time" "github.com/kelseyhightower/envconfig" + "github.com/pkg/errors" ) const ( @@ -17,6 +18,8 @@ const ( backendValueNats = "NATS" ) +var ErrInvalidBackend = errors.New("invalid backend") + // Backend returns the selected backend based on the environment variable // "BACKEND". "NATS" is the default value in case of an empty variable. func Backend() (string, error) { @@ -28,7 +31,7 @@ func Backend() (string, error) { case backendValueNats, "": return backendValueNats, nil default: - return "", fmt.Errorf("invalid BACKEND set: %v", backend) + return "", fmt.Errorf("%w: %v", ErrInvalidBackend, backend) } } diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go index ea0580b0..51d74aa0 100644 --- a/pkg/errors/errors.go +++ b/pkg/errors/errors.go @@ -14,7 +14,7 @@ import ( // errors.Is(err, pkg.ErrPermission) instead of // err == pkg.ErrPermission { … }. func MakeError(actualError, underlyingError error) error { - return fmt.Errorf("%w: %v", actualError, underlyingError) + return fmt.Errorf("%w: %w", actualError, underlyingError) } // MakeSubscriptionError creates a new error and includes the underlyingError in the message diff --git a/pkg/errors/errors_unit_test.go b/pkg/errors/errors_unit_test.go index a520fa6d..b420ef94 100644 --- a/pkg/errors/errors_unit_test.go +++ b/pkg/errors/errors_unit_test.go @@ -1,3 +1,4 @@ +//nolint:goerr113 // no need to wrap errors in the test for the error package package errors_test import ( @@ -76,7 +77,7 @@ func Test_ArgumentError_Is(t *testing.T) { ok := errors.Is(tc.givenError(), errInvalidStorageType) // then - assert.Equal(t, ok, tc.wantIsTrue) + assert.Equal(t, tc.wantIsTrue, ok) }) } } diff --git a/pkg/eventing/deployment_test.go b/pkg/eventing/deployment_test.go index 421eea39..a134237a 100644 --- a/pkg/eventing/deployment_test.go +++ b/pkg/eventing/deployment_test.go @@ -86,8 +86,8 @@ func TestNewDeployment(t *testing.T) { container := findPublisherContainer(publisherName, *deployment) assert.NotNil(t, container) - assert.Equal(t, fmt.Sprint(container.Name), publisherName) - assert.Equal(t, fmt.Sprint(container.Image), publisherConfig.Image) + assert.Equal(t, container.Name, publisherName) + assert.Equal(t, container.Image, publisherConfig.Image) assert.Equal(t, fmt.Sprint(container.ImagePullPolicy), publisherConfig.ImagePullPolicy) tc.wantBackendAssertions(t, publisherName, *deployment) @@ -293,11 +293,11 @@ func natsBackendAssertions(t *testing.T, publisherName string, deployment kappsv assert.NotNil(t, container) streamName := test.FindEnvVar(container.Env, "JS_STREAM_NAME") - assert.Equal(t, streamName.Value, "kyma") + assert.Equal(t, "kyma", streamName.Value) url := test.FindEnvVar(container.Env, "NATS_URL") - assert.Equal(t, url.Value, natsURL) + assert.Equal(t, natsURL, url.Value) eventTypePrefixEnv := test.FindEnvVar(container.Env, "EVENT_TYPE_PREFIX") - assert.Equal(t, eventTypePrefixEnv.Value, eventTypePrefix) + assert.Equal(t, eventTypePrefix, eventTypePrefixEnv.Value) // check the affinity was set affinityLabels := deployment.Spec.Template.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.LabelSelector.MatchLabels diff --git a/pkg/eventing/manager.go b/pkg/eventing/manager.go index fde4d4e4..65397e0a 100644 --- a/pkg/eventing/manager.go +++ b/pkg/eventing/manager.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/pkg/errors" kappsv1 "k8s.io/api/apps/v1" kmetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/record" @@ -29,6 +30,11 @@ var allowedAnnotations = map[string]string{ "kubectl.kubernetes.io/restartedAt": "", } +var ( + ErrUnknownBackendType = errors.New("unknown backend type") + ErrEPPDeployFailed = errors.New("failed to apply Publisher Proxy deployment") +) + //go:generate go run github.com/vektra/mockery/v2 --name=Manager --outpkg=mocks --case=underscore type Manager interface { IsNATSAvailable(ctx context.Context, namespace string) (bool, error) @@ -45,7 +51,6 @@ type Manager interface { } type EventingManager struct { - ctx context.Context client.Client backendConfig env.BackendConfig kubeClient k8s.Client @@ -62,7 +67,6 @@ func NewEventingManager( recorder record.EventRecorder, ) Manager { return &EventingManager{ - ctx: ctx, Client: client, backendConfig: backendConfig, kubeClient: kubeClient, @@ -99,16 +103,16 @@ func (em *EventingManager) applyPublisherProxyDeployment( case v1alpha1.EventMeshBackendType: desiredPublisher = newEventMeshPublisherDeployment(eventing, em.backendConfig.PublisherConfig) default: - return nil, fmt.Errorf("unknown EventingBackend type %q", backendType) + return nil, fmt.Errorf("%w: %q", ErrUnknownBackendType, backendType) } if err := controllerutil.SetControllerReference(eventing, desiredPublisher, em.Scheme()); err != nil { - return nil, fmt.Errorf("failed to set controller reference: %v", err) + return nil, fmt.Errorf("failed to set controller reference: %w", err) } currentPublisher, err := em.kubeClient.GetDeployment(ctx, GetPublisherDeploymentName(*eventing), eventing.Namespace) if err != nil { - return nil, fmt.Errorf("failed to get Event Publisher deployment: %v", err) + return nil, fmt.Errorf("failed to get Event Publisher deployment: %w", err) } if currentPublisher != nil { @@ -122,7 +126,7 @@ func (em *EventingManager) applyPublisherProxyDeployment( // if a publisher deploy from eventing-controller exists, then update it. if err := em.migratePublisherDeploymentFromEC(ctx, eventing, *currentPublisher, *desiredPublisher); err != nil { - return nil, fmt.Errorf("failed to migrate publisher: %v", err) + return nil, fmt.Errorf("failed to migrate publisher: %w", err) } } @@ -135,7 +139,7 @@ func (em *EventingManager) applyPublisherProxyDeployment( // Update publisher proxy deployment if err := em.kubeClient.PatchApply(ctx, desiredPublisher); err != nil { - return nil, fmt.Errorf("failed to apply Publisher Proxy deployment: %v", err) + return nil, fmt.Errorf("%w: %w", ErrEPPDeployFailed, err) } return desiredPublisher, nil @@ -156,7 +160,7 @@ func (em *EventingManager) migratePublisherDeploymentFromEC( // change OwnerReference to Eventing CR. updatedPublisher.OwnerReferences = nil if err := controllerutil.SetControllerReference(eventing, updatedPublisher, em.Scheme()); err != nil { - return fmt.Errorf("failed to set controller reference: %v", err) + return fmt.Errorf("failed to set controller reference: %w", err) } // copy Spec from desired publisher // because some ENV variables conflicts with server-side patch apply. @@ -286,6 +290,6 @@ func convertECBackendType(backendType v1alpha1.BackendType) (eventingv1alpha1.Ba case v1alpha1.NatsBackendType: return eventingv1alpha1.NatsBackendType, nil default: - return "", fmt.Errorf("unknown backend type: %s", backendType) + return "", fmt.Errorf("%w: %s", ErrUnknownBackendType, backendType) } } diff --git a/pkg/eventing/manager_test.go b/pkg/eventing/manager_test.go index aefe0ad7..544de214 100644 --- a/pkg/eventing/manager_test.go +++ b/pkg/eventing/manager_test.go @@ -3,7 +3,6 @@ package eventing import ( "context" "errors" - "fmt" "testing" natsv1alpha1 "github.com/kyma-project/nats-manager/api/v1alpha1" @@ -26,6 +25,8 @@ import ( testutils "github.com/kyma-project/eventing-manager/test/utils" ) +var ErrUseMeWithMocks = errors.New("use me with mocks") + func Test_ApplyPublisherProxyDeployment(t *testing.T) { // given newScheme := runtime.NewScheme() @@ -77,7 +78,7 @@ func Test_ApplyPublisherProxyDeployment(t *testing.T) { testutils.WithEventingCRMinimal(), ), givenBackendType: "unknown-backend", - wantErr: fmt.Errorf("unknown EventingBackend type %q", "unknown-backend"), + wantErr: ErrUnknownBackendType, }, { name: "PatchApply failure", @@ -86,9 +87,8 @@ func Test_ApplyPublisherProxyDeployment(t *testing.T) { testutils.WithEventingEventTypePrefix("test-prefix"), ), givenBackendType: v1alpha1.NatsBackendType, - patchApplyErr: errors.New("patch apply error"), - wantErr: fmt.Errorf("failed to apply Publisher Proxy deployment: %v", - errors.New("patch apply error")), + patchApplyErr: ErrUseMeWithMocks, + wantErr: ErrUseMeWithMocks, }, } @@ -122,7 +122,7 @@ func Test_ApplyPublisherProxyDeployment(t *testing.T) { deployment, err := em.applyPublisherProxyDeployment(ctx, tc.givenEventing, &env.NATSConfig{}, tc.givenBackendType) // then - require.Equal(t, tc.wantErr, err) + require.ErrorIs(t, err, tc.wantErr) if tc.wantedDeployment != nil { require.NotNil(t, deployment) require.Equal(t, tc.wantedDeployment.Spec.Template.ObjectMeta.Annotations, @@ -289,7 +289,7 @@ func Test_IsNATSAvailable(t *testing.T) { givenNATSResources: nil, givenNamespace: "test-namespace", wantAvailable: false, - wantErr: errors.New("failed to get NATS resources"), + wantErr: ErrUseMeWithMocks, }, } @@ -339,7 +339,7 @@ func Test_ConvertECBackendType(t *testing.T) { name: "Unknown backend type", backendType: "unknown", expectedResult: "", - expectedError: fmt.Errorf("unknown backend type: unknown"), + expectedError: ErrUnknownBackendType, }, } @@ -349,7 +349,7 @@ func Test_ConvertECBackendType(t *testing.T) { // when result, err := convertECBackendType(tc.backendType) // then - require.Equal(t, tc.expectedError, err) + require.ErrorIs(t, err, tc.expectedError) require.Equal(t, tc.expectedResult, result) }) } @@ -407,7 +407,7 @@ func Test_DeployPublisherProxyResources(t *testing.T) { var createdObjects []client.Object // define mocks behaviours. if tc.wantError { - kubeClient.On("PatchApply", ctx, mock.Anything).Return(errors.New("failed")) + kubeClient.On("PatchApply", ctx, mock.Anything).Return(ErrUseMeWithMocks) } else { kubeClient.On("PatchApply", ctx, mock.Anything).Run(func(args mock.Arguments) { obj := args.Get(1).(client.Object) @@ -430,7 +430,7 @@ func Test_DeployPublisherProxyResources(t *testing.T) { } require.NoError(t, err) - require.Equal(t, tc.wantCreatedResourcesCount, len(createdObjects)) + require.Len(t, createdObjects, tc.wantCreatedResourcesCount) // check ServiceAccount. sa, err := testutils.FindObjectByKind("ServiceAccount", createdObjects) @@ -521,7 +521,7 @@ func Test_DeletePublisherProxyResources(t *testing.T) { // define mocks behaviours. if tc.wantError { - kubeClient.On("DeleteResource", ctx, mock.Anything).Return(errors.New("failed")) + kubeClient.On("DeleteResource", ctx, mock.Anything).Return(ErrUseMeWithMocks) } else { kubeClient.On("DeleteResource", ctx, mock.Anything).Return(nil).Times(tc.wantDeletedResourcesCount) } @@ -586,7 +586,7 @@ func Test_SubscriptionExists(t *testing.T) { { name: "error should have occurred", wantResult: false, - wantError: errors.New("client error"), + wantError: ErrUseMeWithMocks, }, } diff --git a/pkg/eventing/mocks/manager.go b/pkg/eventing/mocks/manager.go index 276ce666..3d3ca7e0 100644 --- a/pkg/eventing/mocks/manager.go +++ b/pkg/eventing/mocks/manager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -31,6 +31,10 @@ func (_m *Manager) EXPECT() *Manager_Expecter { func (_m *Manager) DeletePublisherProxyResources(ctx context.Context, _a1 *v1alpha1.Eventing) error { ret := _m.Called(ctx, _a1) + if len(ret) == 0 { + panic("no return value specified for DeletePublisherProxyResources") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Eventing) error); ok { r0 = rf(ctx, _a1) @@ -74,6 +78,10 @@ func (_c *Manager_DeletePublisherProxyResources_Call) RunAndReturn(run func(cont func (_m *Manager) DeployPublisherProxy(ctx context.Context, _a1 *v1alpha1.Eventing, natsConfig *env.NATSConfig, backendType v1alpha1.BackendType) (*v1.Deployment, error) { ret := _m.Called(ctx, _a1, natsConfig, backendType) + if len(ret) == 0 { + panic("no return value specified for DeployPublisherProxy") + } + var r0 *v1.Deployment var r1 error if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Eventing, *env.NATSConfig, v1alpha1.BackendType) (*v1.Deployment, error)); ok { @@ -131,6 +139,10 @@ func (_c *Manager_DeployPublisherProxy_Call) RunAndReturn(run func(context.Conte func (_m *Manager) DeployPublisherProxyResources(_a0 context.Context, _a1 *v1alpha1.Eventing, _a2 *v1.Deployment) error { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for DeployPublisherProxyResources") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Eventing, *v1.Deployment) error); ok { r0 = rf(_a0, _a1, _a2) @@ -175,6 +187,10 @@ func (_c *Manager_DeployPublisherProxyResources_Call) RunAndReturn(run func(cont func (_m *Manager) GetBackendConfig() *env.BackendConfig { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetBackendConfig") + } + var r0 *env.BackendConfig if rf, ok := ret.Get(0).(func() *env.BackendConfig); ok { r0 = rf() @@ -218,6 +234,10 @@ func (_c *Manager_GetBackendConfig_Call) RunAndReturn(run func() *env.BackendCon func (_m *Manager) IsNATSAvailable(ctx context.Context, namespace string) (bool, error) { ret := _m.Called(ctx, namespace) + if len(ret) == 0 { + panic("no return value specified for IsNATSAvailable") + } + var r0 bool var r1 error if rf, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok { @@ -304,6 +324,10 @@ func (_c *Manager_SetBackendConfig_Call) RunAndReturn(run func(env.BackendConfig func (_m *Manager) SubscriptionExists(ctx context.Context) (bool, error) { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for SubscriptionExists") + } + var r0 bool var r1 error if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { diff --git a/pkg/k8s/client.go b/pkg/k8s/client.go index 6d39e4f9..08fef405 100644 --- a/pkg/k8s/client.go +++ b/pkg/k8s/client.go @@ -30,6 +30,8 @@ var NatsGVK = schema.GroupVersionResource{ Resource: "nats", } +var ErrSecretRefInvalid = errors.New("invalid namespaced name. It must be in the format of 'namespace/name'") + //nolint:interfacebloat // FIXME //go:generate go run github.com/vektra/mockery/v2 --name=Client --outpkg=mocks --case=underscore type Client interface { @@ -194,7 +196,7 @@ func (c *KubeClient) PatchApply(ctx context.Context, object client.Object) error func (c *KubeClient) GetSecret(ctx context.Context, namespacedName string) (*kcorev1.Secret, error) { substrings := strings.Split(namespacedName, "/") if len(substrings) != 2 { - return nil, errors.New("invalid namespaced name. It must be in the format of 'namespace/name'") + return nil, ErrSecretRefInvalid } secret := &kcorev1.Secret{} err := c.client.Get(ctx, client.ObjectKey{ diff --git a/pkg/k8s/client_test.go b/pkg/k8s/client_test.go index 99269c55..6f999009 100644 --- a/pkg/k8s/client_test.go +++ b/pkg/k8s/client_test.go @@ -3,7 +3,6 @@ package k8s import ( "context" "crypto/rand" - "errors" "testing" "github.com/stretchr/testify/require" @@ -301,7 +300,7 @@ func Test_DeleteResource(t *testing.T) { err := kubeClient.DeleteDeployment(ctx, tc.givenDeployment.Name, tc.givenDeployment.Namespace) // then - require.Nil(t, err) + require.NoError(t, err) // Check that the deployment must not exist. err = fakeClient.Get(ctx, types.NamespacedName{ Name: tc.givenDeployment.Name, @@ -359,7 +358,7 @@ func Test_DeleteDeployment(t *testing.T) { err := kubeClient.DeleteDeployment(ctx, deployment.Name, deployment.Namespace) // then - require.Nil(t, err) + require.NoError(t, err) // Check that the deployment was deleted err = fakeClient.Get(ctx, types.NamespacedName{Name: "test-deployment", Namespace: tc.namespace}, &kappsv1.Deployment{}) @@ -412,7 +411,7 @@ func Test_DeleteClusterRole(t *testing.T) { err := kubeClient.DeleteClusterRole(ctx, clusterRole.Name, clusterRole.Namespace) // then - require.Nil(t, err) + require.NoError(t, err) // Check that the deployment was deleted err = fakeClient.Get(ctx, types.NamespacedName{Name: clusterRole.Name, Namespace: clusterRole.Namespace}, &krbacv1.ClusterRole{}) @@ -465,7 +464,7 @@ func Test_DeleteClusterRoleBinding(t *testing.T) { err := kubeClient.DeleteClusterRoleBinding(ctx, clusterRoleBinding.Name, clusterRoleBinding.Namespace) // then - require.Nil(t, err) + require.NoError(t, err) // Check that the deployment was deleted err = fakeClient.Get(ctx, types.NamespacedName{Name: clusterRoleBinding.Name, Namespace: clusterRoleBinding.Namespace}, &krbacv1.ClusterRoleBinding{}) @@ -511,7 +510,7 @@ func Test_GetSecret(t *testing.T) { name: "namespaced name format error", givenNamespacedName: "my-secret", wantSecret: nil, - wantError: errors.New("invalid namespaced name. It must be in the format of 'namespace/name'"), + wantError: ErrSecretRefInvalid, }, } @@ -538,7 +537,7 @@ func Test_GetSecret(t *testing.T) { if tc.wantNotFoundError { require.True(t, kerrors.IsNotFound(err)) } else { - require.Equal(t, tc.wantError, err) + require.ErrorIs(t, err, tc.wantError) } require.Equal(t, tc.wantSecret, secret) }) @@ -886,9 +885,9 @@ func TestGetSubscriptions(t *testing.T) { // Assert the result of the method if tc.wantSubscriptionList != nil && len(tc.wantSubscriptionList.Items) > 0 { - require.True(t, len(result.Items) > 0) + require.NotEmpty(t, result.Items) } else { - require.Equal(t, 0, len(result.Items)) + require.Empty(t, result.Items) } }) } diff --git a/pkg/k8s/mocks/client.go b/pkg/k8s/mocks/client.go index 87946f13..b05dd234 100644 --- a/pkg/k8s/mocks/client.go +++ b/pkg/k8s/mocks/client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -40,6 +40,10 @@ func (_m *Client) EXPECT() *Client_Expecter { func (_m *Client) APIRuleCRDExists(ctx context.Context) (bool, error) { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for APIRuleCRDExists") + } + var r0 bool var r1 error if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { @@ -92,6 +96,10 @@ func (_c *Client_APIRuleCRDExists_Call) RunAndReturn(run func(context.Context) ( func (_m *Client) ApplicationCRDExists(ctx context.Context) (bool, error) { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for ApplicationCRDExists") + } + var r0 bool var r1 error if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { @@ -144,6 +152,10 @@ func (_c *Client_ApplicationCRDExists_Call) RunAndReturn(run func(context.Contex func (_m *Client) DeleteClusterRole(ctx context.Context, name string, namespace string) error { ret := _m.Called(ctx, name, namespace) + if len(ret) == 0 { + panic("no return value specified for DeleteClusterRole") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { r0 = rf(ctx, name, namespace) @@ -188,6 +200,10 @@ func (_c *Client_DeleteClusterRole_Call) RunAndReturn(run func(context.Context, func (_m *Client) DeleteClusterRoleBinding(ctx context.Context, name string, namespace string) error { ret := _m.Called(ctx, name, namespace) + if len(ret) == 0 { + panic("no return value specified for DeleteClusterRoleBinding") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { r0 = rf(ctx, name, namespace) @@ -232,6 +248,10 @@ func (_c *Client_DeleteClusterRoleBinding_Call) RunAndReturn(run func(context.Co func (_m *Client) DeleteDeployment(ctx context.Context, name string, namespace string) error { ret := _m.Called(ctx, name, namespace) + if len(ret) == 0 { + panic("no return value specified for DeleteDeployment") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { r0 = rf(ctx, name, namespace) @@ -276,6 +296,10 @@ func (_c *Client_DeleteDeployment_Call) RunAndReturn(run func(context.Context, s func (_m *Client) DeleteResource(ctx context.Context, object client.Object) error { ret := _m.Called(ctx, object) + if len(ret) == 0 { + panic("no return value specified for DeleteResource") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, client.Object) error); ok { r0 = rf(ctx, object) @@ -319,6 +343,10 @@ func (_c *Client_DeleteResource_Call) RunAndReturn(run func(context.Context, cli func (_m *Client) GetCRD(ctx context.Context, name string) (*v1.CustomResourceDefinition, error) { ret := _m.Called(ctx, name) + if len(ret) == 0 { + panic("no return value specified for GetCRD") + } + var r0 *v1.CustomResourceDefinition var r1 error if rf, ok := ret.Get(0).(func(context.Context, string) (*v1.CustomResourceDefinition, error)); ok { @@ -374,6 +402,10 @@ func (_c *Client_GetCRD_Call) RunAndReturn(run func(context.Context, string) (*v func (_m *Client) GetConfigMap(ctx context.Context, name string, namespace string) (*corev1.ConfigMap, error) { ret := _m.Called(ctx, name, namespace) + if len(ret) == 0 { + panic("no return value specified for GetConfigMap") + } + var r0 *corev1.ConfigMap var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, string) (*corev1.ConfigMap, error)); ok { @@ -430,6 +462,10 @@ func (_c *Client_GetConfigMap_Call) RunAndReturn(run func(context.Context, strin func (_m *Client) GetDeployment(ctx context.Context, name string, namespace string) (*appsv1.Deployment, error) { ret := _m.Called(ctx, name, namespace) + if len(ret) == 0 { + panic("no return value specified for GetDeployment") + } + var r0 *appsv1.Deployment var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, string) (*appsv1.Deployment, error)); ok { @@ -486,6 +522,10 @@ func (_c *Client_GetDeployment_Call) RunAndReturn(run func(context.Context, stri func (_m *Client) GetDeploymentDynamic(ctx context.Context, name string, namespace string) (*appsv1.Deployment, error) { ret := _m.Called(ctx, name, namespace) + if len(ret) == 0 { + panic("no return value specified for GetDeploymentDynamic") + } + var r0 *appsv1.Deployment var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, string) (*appsv1.Deployment, error)); ok { @@ -542,6 +582,10 @@ func (_c *Client_GetDeploymentDynamic_Call) RunAndReturn(run func(context.Contex func (_m *Client) GetMutatingWebHookConfiguration(ctx context.Context, name string) (*admissionregistrationv1.MutatingWebhookConfiguration, error) { ret := _m.Called(ctx, name) + if len(ret) == 0 { + panic("no return value specified for GetMutatingWebHookConfiguration") + } + var r0 *admissionregistrationv1.MutatingWebhookConfiguration var r1 error if rf, ok := ret.Get(0).(func(context.Context, string) (*admissionregistrationv1.MutatingWebhookConfiguration, error)); ok { @@ -597,6 +641,10 @@ func (_c *Client_GetMutatingWebHookConfiguration_Call) RunAndReturn(run func(con func (_m *Client) GetNATSResources(ctx context.Context, namespace string) (*v1alpha1.NATSList, error) { ret := _m.Called(ctx, namespace) + if len(ret) == 0 { + panic("no return value specified for GetNATSResources") + } + var r0 *v1alpha1.NATSList var r1 error if rf, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.NATSList, error)); ok { @@ -652,6 +700,10 @@ func (_c *Client_GetNATSResources_Call) RunAndReturn(run func(context.Context, s func (_m *Client) GetSecret(ctx context.Context, namespacedName string) (*corev1.Secret, error) { ret := _m.Called(ctx, namespacedName) + if len(ret) == 0 { + panic("no return value specified for GetSecret") + } + var r0 *corev1.Secret var r1 error if rf, ok := ret.Get(0).(func(context.Context, string) (*corev1.Secret, error)); ok { @@ -707,6 +759,10 @@ func (_c *Client_GetSecret_Call) RunAndReturn(run func(context.Context, string) func (_m *Client) GetSubscriptions(ctx context.Context) (*v1alpha2.SubscriptionList, error) { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for GetSubscriptions") + } + var r0 *v1alpha2.SubscriptionList var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*v1alpha2.SubscriptionList, error)); ok { @@ -761,6 +817,10 @@ func (_c *Client_GetSubscriptions_Call) RunAndReturn(run func(context.Context) ( func (_m *Client) GetValidatingWebHookConfiguration(ctx context.Context, name string) (*admissionregistrationv1.ValidatingWebhookConfiguration, error) { ret := _m.Called(ctx, name) + if len(ret) == 0 { + panic("no return value specified for GetValidatingWebHookConfiguration") + } + var r0 *admissionregistrationv1.ValidatingWebhookConfiguration var r1 error if rf, ok := ret.Get(0).(func(context.Context, string) (*admissionregistrationv1.ValidatingWebhookConfiguration, error)); ok { @@ -816,6 +876,10 @@ func (_c *Client_GetValidatingWebHookConfiguration_Call) RunAndReturn(run func(c func (_m *Client) PatchApply(ctx context.Context, object client.Object) error { ret := _m.Called(ctx, object) + if len(ret) == 0 { + panic("no return value specified for PatchApply") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, client.Object) error); ok { r0 = rf(ctx, object) @@ -859,6 +923,10 @@ func (_c *Client_PatchApply_Call) RunAndReturn(run func(context.Context, client. func (_m *Client) PatchApplyPeerAuthentication(ctx context.Context, authentication *v1beta1.PeerAuthentication) error { ret := _m.Called(ctx, authentication) + if len(ret) == 0 { + panic("no return value specified for PatchApplyPeerAuthentication") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, *v1beta1.PeerAuthentication) error); ok { r0 = rf(ctx, authentication) @@ -902,6 +970,10 @@ func (_c *Client_PatchApplyPeerAuthentication_Call) RunAndReturn(run func(contex func (_m *Client) PeerAuthenticationCRDExists(ctx context.Context) (bool, error) { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for PeerAuthenticationCRDExists") + } + var r0 bool var r1 error if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { @@ -954,6 +1026,10 @@ func (_c *Client_PeerAuthenticationCRDExists_Call) RunAndReturn(run func(context func (_m *Client) UpdateDeployment(ctx context.Context, deployment *appsv1.Deployment) error { ret := _m.Called(ctx, deployment) + if len(ret) == 0 { + panic("no return value specified for UpdateDeployment") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, *appsv1.Deployment) error); ok { r0 = rf(ctx, deployment) diff --git a/pkg/logger/logger_test.go b/pkg/logger/logger_test.go index 3064cefb..c00c9cd0 100644 --- a/pkg/logger/logger_test.go +++ b/pkg/logger/logger_test.go @@ -3,13 +3,13 @@ package logger_test import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/kyma-project/eventing-manager/pkg/logger" ) func Test_Build(t *testing.T) { kymaLogger, err := logger.New("json", "warn") - assert.NoError(t, err) - assert.NotNil(t, kymaLogger) + require.NoError(t, err) + require.NotNil(t, kymaLogger) } diff --git a/pkg/signals/signals.go b/pkg/signals/signals.go index 0f60480b..4f84f343 100644 --- a/pkg/signals/signals.go +++ b/pkg/signals/signals.go @@ -15,18 +15,20 @@ var ( // shutdownSignals array of system signals to cause shutdown. shutdownSignals = []os.Signal{syscall.SIGINT, syscall.SIGTERM} + + ErrTerminationRequested = errors.New("received a termination signal") ) // SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned // which is closed on one of these signals. If a second signal is caught, the program // is terminated with exit code 1. -func SetupSignalHandler() (stopCh <-chan struct{}) { +func SetupSignalHandler() <-chan struct{} { close(onlyOneSignalHandler) // panics when called twice return setupStopChannel() } -func setupStopChannel() (stopCh <-chan struct{}) { +func setupStopChannel() <-chan struct{} { stop := make(chan struct{}) osSignal := make(chan os.Signal, 2) signal.Notify(osSignal, shutdownSignals...) @@ -58,8 +60,8 @@ func NewReusableContext() context.Context { } // Deadline implements context.Context. -func (scc *signalContext) Deadline() (deadline time.Time, ok bool) { - return +func (scc *signalContext) Deadline() (time.Time, bool) { + return time.Time{}, false } // Done implements context.Context. @@ -72,7 +74,7 @@ func (scc *signalContext) Err() error { select { case _, ok := <-scc.Done(): if !ok { - return errors.New("received a termination signal") + return ErrTerminationRequested } default: } diff --git a/pkg/subscriptionmanager/eventmesh/eventmesh.go b/pkg/subscriptionmanager/eventmesh/eventmesh.go index b766056a..f3e7bd20 100644 --- a/pkg/subscriptionmanager/eventmesh/eventmesh.go +++ b/pkg/subscriptionmanager/eventmesh/eventmesh.go @@ -2,7 +2,6 @@ package eventmesh import ( "context" - "fmt" "strings" "time" @@ -37,6 +36,11 @@ const ( subscriptionManagerName = "beb-subscription-manager" ) +var ( + ErrDecodingOauthCredentialFailed = errors.New("in") + ErrDomainEmpty = errors.New("domain must be a non-empty value") +) + // AddToScheme adds the own schemes to the runtime scheme. func AddToScheme(scheme *runtime.Scheme) error { if err := kkubernetesscheme.AddToScheme(scheme); err != nil { @@ -92,7 +96,7 @@ func NewSubscriptionManager(restCfg *rest.Config, metricsAddr string, resyncPeri // Init implements the subscriptionmanager.Manager interface. func (c *SubscriptionManager) Init(mgr manager.Manager) error { if len(c.domain) == 0 { - return fmt.Errorf("domain must be a non-empty value") + return ErrDomainEmpty } c.mgr = mgr return nil @@ -104,10 +108,7 @@ func (c *SubscriptionManager) Start(_ env.DefaultSubscriptionConfig, params subm ctx, cancel := context.WithCancel(context.Background()) c.cancel = cancel - oauth2credential, err := getOAuth2ClientCredentials(params) - if err != nil { - return errors.Wrap(err, "get oauth2client credentials failed") - } + oauth2credential := getOAuth2ClientCredentials(params) // Need to read env to read BEB related secrets c.envCfg = env.GetConfig() @@ -128,7 +129,6 @@ func (c *SubscriptionManager) Start(_ env.DefaultSubscriptionConfig, params subm eventMeshHandler := backendeventmesh.NewEventMesh(oauth2credential, nameMapper, c.logger) eventMeshcleaner := cleaner.NewEventMeshCleaner(c.logger) eventMeshReconciler := eventmesh.NewReconciler( - ctx, client, c.logger, recorder, @@ -137,12 +137,12 @@ func (c *SubscriptionManager) Start(_ env.DefaultSubscriptionConfig, params subm eventMeshHandler, oauth2credential, nameMapper, - sink.NewValidator(ctx, client, recorder), + sink.NewValidator(client, recorder), c.collector, c.domain, ) c.eventMeshBackend = eventMeshReconciler.Backend - if err := eventMeshReconciler.SetupUnmanaged(c.mgr); err != nil { + if err := eventMeshReconciler.SetupUnmanaged(ctx, c.mgr); err != nil { return xerrors.Errorf("setup EventMesh subscription controller failed: %v", err) } c.namedLogger().Info("Started v1alpha2 EventMesh subscription manager") @@ -252,37 +252,13 @@ func cleanupEventMesh(backend backendeventmesh.Backend, dynamicClient dynamic.In return nil } -func getOAuth2ClientCredentials(params submgrmanager.Params) (*backendeventmesh.OAuth2ClientCredentials, error) { - val := params[submgrmanager.ParamNameClientID] - id, ok := val.([]byte) - if !ok { - return nil, fmt.Errorf("expected []byte value for %s", submgrmanager.ParamNameClientID) - } - - val = params[submgrmanager.ParamNameClientSecret] - secret, ok := val.([]byte) - if !ok { - return nil, fmt.Errorf("expected []byte value for %s", submgrmanager.ParamNameClientSecret) - } - - val = params[submgrmanager.ParamNameTokenURL] - tokenURL, ok := val.([]byte) - if !ok { - return nil, fmt.Errorf("expected []byte value for %s", submgrmanager.ParamNameTokenURL) - } - - val = params[submgrmanager.ParamNameCertsURL] - certsURL, ok := val.([]byte) - if !ok { - return nil, fmt.Errorf("expected []byte value for %s", submgrmanager.ParamNameCertsURL) - } - +func getOAuth2ClientCredentials(params submgrmanager.Params) *backendeventmesh.OAuth2ClientCredentials { return &backendeventmesh.OAuth2ClientCredentials{ - ClientID: string(id), - ClientSecret: string(secret), - TokenURL: string(tokenURL), - CertsURL: string(certsURL), - }, nil + ClientID: string(params[submgrmanager.ParamNameClientID]), + ClientSecret: string(params[submgrmanager.ParamNameClientSecret]), + TokenURL: string(params[submgrmanager.ParamNameTokenURL]), + CertsURL: string(params[submgrmanager.ParamNameCertsURL]), + } } func (c *SubscriptionManager) namedLogger() *zap.SugaredLogger { diff --git a/pkg/subscriptionmanager/eventmesh/eventmesh_test.go b/pkg/subscriptionmanager/eventmesh/eventmesh_test.go index 89c5fa07..0b9f2ceb 100644 --- a/pkg/subscriptionmanager/eventmesh/eventmesh_test.go +++ b/pkg/subscriptionmanager/eventmesh/eventmesh_test.go @@ -114,7 +114,7 @@ func Test_cleanupEventMesh(t *testing.T) { resp, err := http.Get(getSubscriptionURL) require.NoError(t, err) defer resp.Body.Close() - require.Equal(t, resp.StatusCode, http.StatusOK) + require.Equal(t, http.StatusOK, resp.StatusCode) // check that the Kyma subscription exists unstructuredSub, err := bebSubMgr.Client.Resource(eventingtesting.SubscriptionGroupVersionResource()).Namespace( @@ -138,7 +138,7 @@ func Test_cleanupEventMesh(t *testing.T) { resp, err = http.Get(getSubscriptionURL) require.NoError(t, err) defer resp.Body.Close() - require.Equal(t, resp.StatusCode, http.StatusNotFound) + require.Equal(t, http.StatusNotFound, resp.StatusCode) // the Kyma subscription status should be empty unstructuredSub, err = bebSubMgr.Client.Resource(eventingtesting.SubscriptionGroupVersionResource()).Namespace( @@ -194,7 +194,7 @@ func Test_markAllV1Alpha2SubscriptionsAsNotReady(t *testing.T) { require.NoError(t, err) gotSub, err := eventingtesting.ToSubscription(unstructuredSub) require.NoError(t, err) - require.Equal(t, true, gotSub.Status.Ready) + require.True(t, gotSub.Status.Ready) // when err = markAllV1Alpha2SubscriptionsAsNotReady(fakeClient, defaultLogger.WithContext()) @@ -206,7 +206,7 @@ func Test_markAllV1Alpha2SubscriptionsAsNotReady(t *testing.T) { require.NoError(t, err) gotSub, err = eventingtesting.ToSubscription(unstructuredSub) require.NoError(t, err) - require.Equal(t, false, gotSub.Status.Ready) + require.False(t, gotSub.Status.Ready) // ensure hashes are preserved require.Equal(t, ev2Hash, gotSub.Status.Backend.Ev2hash) diff --git a/pkg/subscriptionmanager/jetstream/jetstream.go b/pkg/subscriptionmanager/jetstream/jetstream.go index f064ac65..b15a471d 100644 --- a/pkg/subscriptionmanager/jetstream/jetstream.go +++ b/pkg/subscriptionmanager/jetstream/jetstream.go @@ -105,13 +105,12 @@ func (sm *SubscriptionManager) Start(defaultSubsConfig env.DefaultSubscriptionCo jetStreamHandler := backendjetstream.NewJetStream(sm.envCfg, sm.metricsCollector, jsCleaner, defaultSubsConfig, sm.logger) jetStreamReconciler := subscriptioncontrollerjetstream.NewReconciler( - ctx, client, jetStreamHandler, sm.logger, recorder, jsCleaner, - sink.NewValidator(ctx, client, recorder), + sink.NewValidator(client, recorder), sm.metricsCollector, ) sm.backendv2 = jetStreamReconciler.Backend @@ -130,7 +129,7 @@ func (sm *SubscriptionManager) Start(defaultSubsConfig env.DefaultSubscriptionCo } // start the subscription controller - if err := jetStreamReconciler.SetupUnmanaged(sm.mgr); err != nil { + if err := jetStreamReconciler.SetupUnmanaged(ctx, sm.mgr); err != nil { return xerrors.Errorf("unable to setup the NATS subscription controller: %v", err) } sm.namedLogger().Info("Started v1alpha2 JetStream subscription manager") diff --git a/pkg/subscriptionmanager/jetstream/jetstream_test.go b/pkg/subscriptionmanager/jetstream/jetstream_test.go index 0edf6eb6..825d8bb5 100644 --- a/pkg/subscriptionmanager/jetstream/jetstream_test.go +++ b/pkg/subscriptionmanager/jetstream/jetstream_test.go @@ -1,7 +1,6 @@ package jetstream import ( - "context" "fmt" "testing" "time" @@ -46,7 +45,6 @@ func TestCleanup(t *testing.T) { // utilities and helper functions type TestEnvironment struct { - ctx context.Context dynamicClient dynamic.Interface jsBackend *jetstream.JetStream jsCtx nats.JetStreamContext @@ -110,7 +108,6 @@ func (te *TestEnvironment) consumersEquals(t *testing.T, length int) { } func setUpTestEnvironment(t *testing.T) *TestEnvironment { - ctx := context.Background() // create a test subscriber and natsServer subscriber := eventingtesting.NewSubscriber() // create NATS Server with JetStream enabled @@ -143,7 +140,6 @@ func setUpTestEnvironment(t *testing.T) *TestEnvironment { require.NoError(t, err) return &TestEnvironment{ - ctx: ctx, dynamicClient: fakeClient, jsBackend: jsBackend, jsCtx: jsClient, diff --git a/pkg/subscriptionmanager/manager/manager.go b/pkg/subscriptionmanager/manager/manager.go index 9f6052ab..5e7285b8 100644 --- a/pkg/subscriptionmanager/manager/manager.go +++ b/pkg/subscriptionmanager/manager/manager.go @@ -13,7 +13,7 @@ const ( ParamNameCertsURL = "certs_url" ) -type Params map[string]interface{} +type Params map[string][]byte // Manager defines the interface that subscription managers for different messaging backends should implement. // diff --git a/pkg/subscriptionmanager/manager/mocks/manager.go b/pkg/subscriptionmanager/manager/mocks/manager.go index 25b716cd..b31299a2 100644 --- a/pkg/subscriptionmanager/manager/mocks/manager.go +++ b/pkg/subscriptionmanager/manager/mocks/manager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -28,6 +28,10 @@ func (_m *Manager) EXPECT() *Manager_Expecter { func (_m *Manager) Init(mgr manager.Manager) error { ret := _m.Called(mgr) + if len(ret) == 0 { + panic("no return value specified for Init") + } + var r0 error if rf, ok := ret.Get(0).(func(manager.Manager) error); ok { r0 = rf(mgr) @@ -70,6 +74,10 @@ func (_c *Manager_Init_Call) RunAndReturn(run func(manager.Manager) error) *Mana func (_m *Manager) Start(defaultSubsConfig env.DefaultSubscriptionConfig, params subscriptionmanagermanager.Params) error { ret := _m.Called(defaultSubsConfig, params) + if len(ret) == 0 { + panic("no return value specified for Start") + } + var r0 error if rf, ok := ret.Get(0).(func(env.DefaultSubscriptionConfig, subscriptionmanagermanager.Params) error); ok { r0 = rf(defaultSubsConfig, params) @@ -113,6 +121,10 @@ func (_c *Manager_Start_Call) RunAndReturn(run func(env.DefaultSubscriptionConfi func (_m *Manager) Stop(runCleanup bool) error { ret := _m.Called(runCleanup) + if len(ret) == 0 { + panic("no return value specified for Stop") + } + var r0 error if rf, ok := ret.Get(0).(func(bool) error); ok { r0 = rf(runCleanup) diff --git a/pkg/subscriptionmanager/mocks/manager_factory.go b/pkg/subscriptionmanager/mocks/manager_factory.go index 1eb0e996..9e7d9b18 100644 --- a/pkg/subscriptionmanager/mocks/manager_factory.go +++ b/pkg/subscriptionmanager/mocks/manager_factory.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -27,6 +27,10 @@ func (_m *ManagerFactory) EXPECT() *ManagerFactory_Expecter { func (_m *ManagerFactory) NewEventMeshManager(domain string) (manager.Manager, error) { ret := _m.Called(domain) + if len(ret) == 0 { + panic("no return value specified for NewEventMeshManager") + } + var r0 manager.Manager var r1 error if rf, ok := ret.Get(0).(func(string) (manager.Manager, error)); ok { @@ -81,6 +85,10 @@ func (_c *ManagerFactory_NewEventMeshManager_Call) RunAndReturn(run func(string) func (_m *ManagerFactory) NewJetStreamManager(_a0 v1alpha1.Eventing, _a1 env.NATSConfig) manager.Manager { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for NewJetStreamManager") + } + var r0 manager.Manager if rf, ok := ret.Get(0).(func(v1alpha1.Eventing, env.NATSConfig) manager.Manager); ok { r0 = rf(_a0, _a1) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index f1a09b40..97bfd872 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -51,14 +51,15 @@ func ContainsString(slice []string, s string) bool { return false } -func RemoveString(slice []string, s string) (result []string) { +func RemoveString(slice []string, s string) []string { + var result []string for _, item := range slice { if item == s { continue } result = append(result, item) } - return + return result } func BoolPtr(b bool) *bool { diff --git a/pkg/utils/utils_unit_test.go b/pkg/utils/utils_unit_test.go index 7a338c2f..9f67f063 100644 --- a/pkg/utils/utils_unit_test.go +++ b/pkg/utils/utils_unit_test.go @@ -174,7 +174,7 @@ func TestIsValidScheme(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() gotValid := IsValidScheme(tc.givenSink) - require.Equal(t, gotValid, tc.wantValid) + require.Equal(t, tc.wantValid, gotValid) }) } } @@ -207,8 +207,8 @@ func TestGetSinkData(t *testing.T) { t.Parallel() gotTrimmedHost, gotSubDomain, gotErr := GetSinkData(tc.givenSink) require.ErrorIs(t, gotErr, tc.wantError) - require.Equal(t, gotTrimmedHost, tc.wantTrimmedHost) - require.Equal(t, gotSubDomain, tc.wantSubDomains) + require.Equal(t, tc.wantTrimmedHost, gotTrimmedHost) + require.Equal(t, tc.wantSubDomains, gotSubDomain) }) } } diff --git a/pkg/watcher/mocks/watcher.go b/pkg/watcher/mocks/watcher.go index 4341c7ec..96b0f584 100644 --- a/pkg/watcher/mocks/watcher.go +++ b/pkg/watcher/mocks/watcher.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. +// Code generated by mockery v2.38.0. DO NOT EDIT. package mocks @@ -24,6 +24,10 @@ func (_m *Watcher) EXPECT() *Watcher_Expecter { func (_m *Watcher) GetEventsChannel() <-chan event.GenericEvent { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetEventsChannel") + } + var r0 <-chan event.GenericEvent if rf, ok := ret.Get(0).(func() <-chan event.GenericEvent); ok { r0 = rf() @@ -67,6 +71,10 @@ func (_c *Watcher_GetEventsChannel_Call) RunAndReturn(run func() <-chan event.Ge func (_m *Watcher) IsStarted() bool { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for IsStarted") + } + var r0 bool if rf, ok := ret.Get(0).(func() bool); ok { r0 = rf() diff --git a/test/utils/integration/integration.go b/test/utils/integration/integration.go index 0cf9999d..490bf840 100644 --- a/test/utils/integration/integration.go +++ b/test/utils/integration/integration.go @@ -68,7 +68,6 @@ const ( // TestEnvironment provides mocked resources for integration tests. type TestEnvironment struct { - Context context.Context EnvTestInstance *envtest.Environment k8sClient client.Client KubeClient k8s.Client @@ -237,7 +236,6 @@ func NewTestEnvironment(config TestEnvironmentConfig) (*TestEnvironment, error) } return &TestEnvironment{ - Context: ctx, k8sClient: k8sClient, KubeClient: kubeClient, K8sDynamicClient: dynamicClient, @@ -391,15 +389,15 @@ func (env TestEnvironment) EnsureNamespaceCreation(t *testing.T, namespace strin } // create namespace ns := natstestutils.NewNamespace(namespace) - require.NoError(t, client.IgnoreAlreadyExists(env.k8sClient.Create(env.Context, ns))) + require.NoError(t, client.IgnoreAlreadyExists(env.k8sClient.Create(context.Background(), ns))) } func (env TestEnvironment) CreateK8sResource(obj client.Object) error { - return env.k8sClient.Create(env.Context, obj) + return env.k8sClient.Create(context.Background(), obj) } func (env TestEnvironment) EnsureK8sResourceCreated(t *testing.T, obj client.Object) { - require.NoError(t, env.k8sClient.Create(env.Context, obj)) + require.NoError(t, env.k8sClient.Create(context.Background(), obj)) } func (env TestEnvironment) EnsureEPPK8sResourcesExists(t *testing.T, eventingCR v1alpha1.Eventing) { @@ -474,11 +472,11 @@ func (env TestEnvironment) EnsureSubscriptionExists(t *testing.T, name, namespac } func (env TestEnvironment) EnsureK8sResourceUpdated(t *testing.T, obj client.Object) { - require.NoError(t, env.k8sClient.Update(env.Context, obj)) + require.NoError(t, env.k8sClient.Update(context.Background(), obj)) } func (env TestEnvironment) EnsureK8sResourceDeleted(t *testing.T, obj client.Object) { - require.NoError(t, env.k8sClient.Delete(env.Context, obj)) + require.NoError(t, env.k8sClient.Delete(context.Background(), obj)) } func (env TestEnvironment) EnsureNATSCRDDeleted(t *testing.T) { @@ -491,21 +489,21 @@ func (env TestEnvironment) EnsureNATSCRDDeleted(t *testing.T) { Name: k8s.NatsGVK.GroupResource().String(), }, } - require.NoError(t, env.k8sClient.Delete(env.Context, crdManifest)) + require.NoError(t, env.k8sClient.Delete(context.Background(), crdManifest)) require.Eventually(t, func() bool { - _, err := env.KubeClient.GetCRD(env.Context, crdManifest.Name) + _, err := env.KubeClient.GetCRD(context.Background(), crdManifest.Name) return err != nil && errors.IsNotFound(err) }, BigTimeOut, BigPollingInterval, "failed to ensure deletion of NATS CRD") } func (env TestEnvironment) EnsureCRDCreated(t *testing.T, crd *kapiextensionsv1.CustomResourceDefinition) { crd.ResourceVersion = "" - require.NoError(t, env.k8sClient.Create(env.Context, crd)) + require.NoError(t, env.k8sClient.Create(context.Background(), crd)) } func (env TestEnvironment) EnsureNamespaceDeleted(t *testing.T, namespace string) { - require.NoError(t, env.k8sClient.Delete(env.Context, &kcorev1.Namespace{ + require.NoError(t, env.k8sClient.Delete(context.Background(), &kcorev1.Namespace{ ObjectMeta: kmetav1.ObjectMeta{ Name: namespace, }, @@ -605,7 +603,7 @@ func (env TestEnvironment) EnsureEventingResourceDeletionStateError(t *testing.T } env.EnsureK8sResourceDeleted(t, eventing) require.Eventually(t, func() bool { - err := env.k8sClient.Get(env.Context, types.NamespacedName{Name: name, Namespace: namespace}, eventing) + err := env.k8sClient.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, eventing) return err == nil && eventing.Status.State == v1alpha1.StateError }, SmallTimeOut, SmallPollingInterval, "failed to ensure deletion of Eventing") } @@ -627,7 +625,7 @@ func (env TestEnvironment) EnsureSubscriptionResourceDeletion(t *testing.T, name func (env TestEnvironment) EnsureNATSResourceStateReady(t *testing.T, nats *natsv1alpha1.NATS) { env.makeNATSCrReady(t, nats) require.Eventually(t, func() bool { - err := env.k8sClient.Get(env.Context, types.NamespacedName{Name: nats.Name, Namespace: nats.Namespace}, nats) + err := env.k8sClient.Get(context.Background(), types.NamespacedName{Name: nats.Name, Namespace: nats.Namespace}, nats) return err == nil && nats.Status.State == natsv1alpha1.StateReady }, BigTimeOut, BigPollingInterval, "failed to ensure NATS CR is stored") } @@ -635,7 +633,7 @@ func (env TestEnvironment) EnsureNATSResourceStateReady(t *testing.T, nats *nats func (env TestEnvironment) EnsureNATSResourceStateError(t *testing.T, nats *natsv1alpha1.NATS) { env.makeNatsCrError(t, nats) require.Eventually(t, func() bool { - err := env.k8sClient.Get(env.Context, types.NamespacedName{Name: nats.Name, Namespace: nats.Namespace}, nats) + err := env.k8sClient.Get(context.Background(), types.NamespacedName{Name: nats.Name, Namespace: nats.Namespace}, nats) return err == nil && nats.Status.State == natsv1alpha1.StateError }, BigTimeOut, BigPollingInterval, "failed to ensure NATS CR is stored") } @@ -832,14 +830,14 @@ func (env TestEnvironment) EnsureCABundleInjectedIntoWebhooks(t *testing.T) { } // get Mutating and validating webhook configurations from k8s. - mwh, err := env.KubeClient.GetMutatingWebHookConfiguration(env.Context, + mwh, err := env.KubeClient.GetMutatingWebHookConfiguration(context.Background(), getTestBackendConfig().MutatingWebhookName) if err != nil { env.Logger.WithContext().Error(err) return false } - vwh, err := env.KubeClient.GetValidatingWebHookConfiguration(env.Context, + vwh, err := env.KubeClient.GetValidatingWebHookConfiguration(context.Background(), getTestBackendConfig().ValidatingWebhookName) if err != nil { env.Logger.WithContext().Error(err) @@ -902,7 +900,7 @@ func (env TestEnvironment) EnsurePublishServiceInEventingStatus(t *testing.T, na } func (env TestEnvironment) DeleteServiceFromK8s(name, namespace string) error { - return env.k8sClient.Delete(env.Context, &kcorev1.Service{ + return env.k8sClient.Delete(context.Background(), &kcorev1.Service{ ObjectMeta: kmetav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -911,7 +909,7 @@ func (env TestEnvironment) DeleteServiceFromK8s(name, namespace string) error { } func (env TestEnvironment) DeleteServiceAccountFromK8s(name, namespace string) error { - return env.k8sClient.Delete(env.Context, &kcorev1.ServiceAccount{ + return env.k8sClient.Delete(context.Background(), &kcorev1.ServiceAccount{ ObjectMeta: kmetav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -920,7 +918,7 @@ func (env TestEnvironment) DeleteServiceAccountFromK8s(name, namespace string) e } func (env TestEnvironment) DeleteClusterRoleFromK8s(name, namespace string) error { - return env.k8sClient.Delete(env.Context, &krbacv1.ClusterRole{ + return env.k8sClient.Delete(context.Background(), &krbacv1.ClusterRole{ ObjectMeta: kmetav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -929,7 +927,7 @@ func (env TestEnvironment) DeleteClusterRoleFromK8s(name, namespace string) erro } func (env TestEnvironment) DeleteClusterRoleBindingFromK8s(name, namespace string) error { - return env.k8sClient.Delete(env.Context, &krbacv1.ClusterRoleBinding{ + return env.k8sClient.Delete(context.Background(), &krbacv1.ClusterRoleBinding{ ObjectMeta: kmetav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -938,7 +936,7 @@ func (env TestEnvironment) DeleteClusterRoleBindingFromK8s(name, namespace strin } func (env TestEnvironment) DeleteHPAFromK8s(name, namespace string) error { - return env.k8sClient.Delete(env.Context, &kautoscalingv1.HorizontalPodAutoscaler{ + return env.k8sClient.Delete(context.Background(), &kautoscalingv1.HorizontalPodAutoscaler{ ObjectMeta: kmetav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -947,12 +945,12 @@ func (env TestEnvironment) DeleteHPAFromK8s(name, namespace string) error { } func (env TestEnvironment) UpdateEventingStatus(eventing *v1alpha1.Eventing) error { - return env.k8sClient.Status().Update(env.Context, eventing) + return env.k8sClient.Status().Update(context.Background(), eventing) } func (env TestEnvironment) UpdateNATSStatus(nats *natsv1alpha1.NATS) error { baseNats := &natsv1alpha1.NATS{} - if err := env.k8sClient.Get(env.Context, + if err := env.k8sClient.Get(context.Background(), types.NamespacedName{ Namespace: nats.Namespace, Name: nats.Name, @@ -960,7 +958,7 @@ func (env TestEnvironment) UpdateNATSStatus(nats *natsv1alpha1.NATS) error { return err } baseNats.Status = nats.Status - return env.k8sClient.Status().Update(env.Context, baseNats) + return env.k8sClient.Status().Update(context.Background(), baseNats) } func (env TestEnvironment) makeNATSCrReady(t *testing.T, nats *natsv1alpha1.NATS) { @@ -991,7 +989,7 @@ func (env TestEnvironment) makeNatsCrError(t *testing.T, nats *natsv1alpha1.NATS func (env TestEnvironment) GetNATSFromK8s(name, namespace string) (*natsv1alpha1.NATS, error) { var nats *natsv1alpha1.NATS - err := env.k8sClient.Get(env.Context, types.NamespacedName{ + err := env.k8sClient.Get(context.Background(), types.NamespacedName{ Name: name, Namespace: namespace, }, nats) @@ -1043,7 +1041,7 @@ func getTestBackendConfig() env.BackendConfig { func (env TestEnvironment) GetEventingFromK8s(name, namespace string) (*v1alpha1.Eventing, error) { eventing := &v1alpha1.Eventing{} - err := env.k8sClient.Get(env.Context, types.NamespacedName{ + err := env.k8sClient.Get(context.Background(), types.NamespacedName{ Name: name, Namespace: namespace, }, eventing) @@ -1057,11 +1055,11 @@ func (env TestEnvironment) DeleteEventingFromK8s(name, namespace string) error { Namespace: namespace, }, } - return env.k8sClient.Delete(env.Context, cr) + return env.k8sClient.Delete(context.Background(), cr) } func (env TestEnvironment) DeleteSecretFromK8s(name, namespace string) error { - return env.k8sClient.Delete(env.Context, &kcorev1.Secret{ + return env.k8sClient.Delete(context.Background(), &kcorev1.Secret{ ObjectMeta: kmetav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -1075,7 +1073,7 @@ func (env TestEnvironment) GetDeploymentFromK8s(name, namespace string) (*kappsv Namespace: namespace, } result := &kappsv1.Deployment{} - if err := env.k8sClient.Get(env.Context, nn, result); err != nil { + if err := env.k8sClient.Get(context.Background(), nn, result); err != nil { return nil, err } return result, nil @@ -1087,7 +1085,7 @@ func (env TestEnvironment) GetServiceFromK8s(name, namespace string) (*kcorev1.S Namespace: namespace, } result := &kcorev1.Service{} - if err := env.k8sClient.Get(env.Context, nn, result); err != nil { + if err := env.k8sClient.Get(context.Background(), nn, result); err != nil { return nil, err } return result, nil @@ -1098,7 +1096,7 @@ func (env TestEnvironment) GetSecretFromK8s(name, namespace string) (*kcorev1.Se Name: name, Namespace: namespace, } - return env.KubeClient.GetSecret(env.Context, nn.String()) + return env.KubeClient.GetSecret(context.Background(), nn.String()) } func (env TestEnvironment) GetServiceAccountFromK8s(name, namespace string) (*kcorev1.ServiceAccount, error) { @@ -1107,7 +1105,7 @@ func (env TestEnvironment) GetServiceAccountFromK8s(name, namespace string) (*kc Namespace: namespace, } result := &kcorev1.ServiceAccount{} - if err := env.k8sClient.Get(env.Context, nn, result); err != nil { + if err := env.k8sClient.Get(context.Background(), nn, result); err != nil { return nil, err } return result, nil @@ -1119,7 +1117,7 @@ func (env TestEnvironment) GetClusterRoleFromK8s(name, namespace string) (*krbac Namespace: namespace, } result := &krbacv1.ClusterRole{} - if err := env.k8sClient.Get(env.Context, nn, result); err != nil { + if err := env.k8sClient.Get(context.Background(), nn, result); err != nil { return nil, err } return result, nil @@ -1131,7 +1129,7 @@ func (env TestEnvironment) GetClusterRoleBindingFromK8s(name, namespace string) Namespace: namespace, } result := &krbacv1.ClusterRoleBinding{} - if err := env.k8sClient.Get(env.Context, nn, result); err != nil { + if err := env.k8sClient.Get(context.Background(), nn, result); err != nil { return nil, err } return result, nil @@ -1143,7 +1141,7 @@ func (env TestEnvironment) GetHPAFromK8s(name, namespace string) (*kautoscalingv Namespace: namespace, } result := &kautoscalingv1.HorizontalPodAutoscaler{} - if err := env.k8sClient.Get(env.Context, nn, result); err != nil { + if err := env.k8sClient.Get(context.Background(), nn, result); err != nil { return nil, err } return result, nil @@ -1155,20 +1153,20 @@ func (env TestEnvironment) GetSubscriptionFromK8s(name, namespace string) (*even Namespace: namespace, } result := &eventingv1alpha2.Subscription{} - if err := env.k8sClient.Get(env.Context, nn, result); err != nil { + if err := env.k8sClient.Get(context.Background(), nn, result); err != nil { return nil, err } return result, nil } func (env TestEnvironment) CreateUnstructuredK8sResource(obj *unstructured.Unstructured) error { - return env.k8sClient.Create(env.Context, obj) + return env.k8sClient.Create(context.Background(), obj) } func (env TestEnvironment) UpdateUnstructuredK8sResource(obj *unstructured.Unstructured) error { - return env.k8sClient.Update(env.Context, obj) + return env.k8sClient.Update(context.Background(), obj) } func (env TestEnvironment) EnsureK8sUnStructResourceCreated(t *testing.T, obj *unstructured.Unstructured) { - require.NoError(t, env.k8sClient.Create(env.Context, obj)) + require.NoError(t, env.k8sClient.Create(context.Background(), obj)) } diff --git a/test/utils/utils.go b/test/utils/utils.go index 2e4a804f..93f58ee9 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -32,7 +32,10 @@ const ( PublisherProxySuffix = "publisher-proxy" ) -var seededRand = rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosec,gochecknoglobals // used in tests +var ( + seededRand = rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosec,gochecknoglobals // used in tests + ErrNotFound = errors.New("not found") +) func GetRandString(length int) string { b := make([]byte, length) @@ -373,7 +376,7 @@ func FindObjectByKind(kind string, objects []client.Object) (client.Object, erro } } - return nil, errors.New("not found") + return nil, ErrNotFound } func FindServiceFromK8sObjects(name string, objects []client.Object) (client.Object, error) { @@ -384,5 +387,5 @@ func FindServiceFromK8sObjects(name string, objects []client.Object) (client.Obj } } - return nil, errors.New("not found") + return nil, ErrNotFound } diff --git a/testing/event/cehelper/converter.go b/testing/event/cehelper/converter.go index 7c398108..92f9123b 100644 --- a/testing/event/cehelper/converter.go +++ b/testing/event/cehelper/converter.go @@ -29,7 +29,7 @@ func RequestToEventString(r *http.Request) (string, error) { msg := cehttp.NewMessageFromHttpRequest(r) event, err := cebinding.ToEvent(context.Background(), msg) if err != nil { - return "", fmt.Errorf("failed to build a CloudEvent: %s", err.Error()) + return "", fmt.Errorf("failed to build a CloudEvent: %w", err) } return event.String(), nil } diff --git a/testing/subscriber.go b/testing/subscriber.go index 1d5dde12..d6919646 100644 --- a/testing/subscriber.go +++ b/testing/subscriber.go @@ -26,6 +26,12 @@ const ( checkRetriesEndpoint = "/check_retries" ) +var ( + ErrEventNotReceived = errors.New("event not received") + ErrUnexpectedResponseCode = errors.New("unexpected response code received") + ErrWrongRetries = errors.New("wrong number of retries") +) + type Subscriber struct { server *httptest.Server SinkURL string @@ -120,7 +126,7 @@ func getCloudEventServeMux() *http.ServeMux { }) // this Endpoint returns the number of attempted retries. mux.HandleFunc(checkRetriesEndpoint, func(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(fmt.Sprintf("%d", retries.Load()))) + _, err := w.Write([]byte(strconv.Itoa(int(retries.Load())))) if err != nil { log.Printf("check_retries failed: %v", err) w.WriteHeader(http.StatusInternalServerError) @@ -176,7 +182,7 @@ func getDataServeMux() *http.ServeMux { }) // this Endpoint returns the number of attempted retries. mux.HandleFunc(checkRetriesEndpoint, func(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(fmt.Sprintf("%d", retries.Load()))) + _, err := w.Write([]byte(strconv.Itoa(int(retries.Load())))) if err != nil { log.Printf("check_retries failed: %v", err) w.WriteHeader(http.StatusInternalServerError) @@ -207,22 +213,22 @@ func (s Subscriber) CheckEvent(expectedData string) error { // check if a response was received and that it's code is in 2xx-range resp, err := http.Get(s.checkURL) if err != nil { - return errors.Wrapf(err, "get HTTP request failed") + return fmt.Errorf("get HTTP request failed: %w", err) } if !is2XXStatusCode(resp.StatusCode) { - return fmt.Errorf("expected resonse code 2xx, actual response code: %d", resp.StatusCode) + return fmt.Errorf("%w: expected: 2xx, actual: %d", ErrUnexpectedResponseCode, resp.StatusCode) } // try to read the response body defer func() { _ = resp.Body.Close() }() body, err = io.ReadAll(resp.Body) if err != nil { - return errors.Wrapf(err, "read data failed") + return fmt.Errorf("read data failed: %w", err) } // compare response body with expectations if expectedData != string(body) { - return fmt.Errorf("event not received") + return ErrEventNotReceived } return nil }, @@ -232,7 +238,7 @@ func (s Subscriber) CheckEvent(expectedData string) error { retry.OnRetry(func(n uint, err error) { log.Printf("[%v] try failed: %s", n, err) }), ) if err != nil { - return errors.Wrapf(err, "check event after retries failed") + return fmt.Errorf("check event after retries failed: %w", err) } log.Print("event received") @@ -248,22 +254,22 @@ func (s Subscriber) CheckRetries(expectedNoOfRetries int, expectedData string) e func() error { resp, err := http.Get(s.checkRetriesURL) if err != nil { - return errors.Wrapf(err, "get HTTP request failed") + return fmt.Errorf("get HTTP request failed: %w", err) } if !is2XXStatusCode(resp.StatusCode) { - return fmt.Errorf("expected resonse code 2xx, actual response code: %d", resp.StatusCode) + return fmt.Errorf("%w: expected: 2xx, actual: %d", ErrUnexpectedResponseCode, resp.StatusCode) } defer func() { _ = resp.Body.Close() }() body, err = io.ReadAll(resp.Body) if err != nil { - return errors.Wrapf(err, "read data failed") + return fmt.Errorf("read data failed: %w", err) } actualRetires, err := strconv.Atoi(string(body)) if err != nil { - return errors.Wrapf(err, "read data failed") + return fmt.Errorf("read data failed: %w", err) } if actualRetires < expectedNoOfRetries { - return fmt.Errorf("number of retries do not match (actualRetires=%d, expectedRetries=%d)", actualRetires, expectedNoOfRetries) + return fmt.Errorf("%w: actualRetires:%d, expectedRetries:%d", ErrWrongRetries, actualRetires, expectedNoOfRetries) } return nil }, diff --git a/testing/test_helpers.go b/testing/test_helpers.go index 493abe84..ee7e3a3e 100644 --- a/testing/test_helpers.go +++ b/testing/test_helpers.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "net/http" + "strconv" apigatewayv1beta1 "github.com/kyma-project/api-gateway/apis/gateway/v1beta1" kcorev1 "k8s.io/api/core/v1" @@ -74,17 +75,19 @@ type APIRuleOption func(r *apigatewayv1beta1.APIRule) // GetFreePort determines a free port on the host. It does so by delegating the job to net.ListenTCP. // Then providing a port of 0 to net.ListenTCP, it will automatically choose a port for us. -func GetFreePort() (port int, err error) { +func GetFreePort() (int, error) { var a *net.TCPAddr - if a, err = net.ResolveTCPAddr("tcp", "localhost:0"); err == nil { - var l *net.TCPListener - if l, err = net.ListenTCP("tcp", a); err == nil { - port := l.Addr().(*net.TCPAddr).Port - err = l.Close() - return port, err - } + a, err := net.ResolveTCPAddr("tcp", "localhost:0") + if err != nil { + return 0, err + } + l, err := net.ListenTCP("tcp", a) + if err != nil { + return 0, err } - return + port := l.Addr().(*net.TCPAddr).Port + l.Close() + return port, err } type ProtoOpt func(p *eventingv1alpha1.ProtocolSettings) @@ -804,7 +807,7 @@ func WithTypeMatchingExact() SubscriptionOpt { func WithMaxInFlight(maxInFlight int) SubscriptionOpt { return func(subscription *eventingv1alpha2.Subscription) { subscription.Spec.Config = map[string]string{ - eventingv1alpha2.MaxInFlightMessages: fmt.Sprint(maxInFlight), + eventingv1alpha2.MaxInFlightMessages: strconv.Itoa(maxInFlight), } } }