From 4786c3b595e1d893beaec3ba5db4f416e894ee12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:27:26 +0100 Subject: [PATCH 1/6] Bump istio.io/client-go from 1.20.0 to 1.20.1 (#321) Bumps [istio.io/client-go](https://github.com/istio/client-go) from 1.20.0 to 1.20.1. - [Commits](https://github.com/istio/client-go/compare/1.20.0...1.20.1) --- updated-dependencies: - dependency-name: istio.io/client-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 73aa8edc3..ea2669c1c 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( golang.org/x/oauth2 v0.15.0 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 istio.io/api v1.20.1 - istio.io/client-go v1.20.0 + istio.io/client-go v1.20.1 k8s.io/api v0.28.4 k8s.io/apiextensions-apiserver v0.28.4 k8s.io/apimachinery v0.28.4 diff --git a/go.sum b/go.sum index e30cb228f..94f945076 100644 --- a/go.sum +++ b/go.sum @@ -712,8 +712,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= istio.io/api v1.20.1 h1:Itku+LK5FwNzkKJY+5BGRCTRimVA5gShwFXdNNXtAHk= istio.io/api v1.20.1/go.mod h1:hm1PE/mGdIAsjCDkTIAplP53H7TjO5LUQCiVvF26SVg= -istio.io/client-go v1.20.0 h1:TSSv6A4sYvuBtoKOwyuRmBmPwSb4s++lWlh7RB7+7gY= -istio.io/client-go v1.20.0/go.mod h1:6D76gZsdjz8JtVeIarUYdOn3WA8Zh+j8fIv2+2K3M+Q= +istio.io/client-go v1.20.1 h1:0kObqt2b6mJ1lM+PEOWQ9/MQbhJFMBZ2K7krAz/Qrto= +istio.io/client-go v1.20.1/go.mod h1:5Je53KEbCFhBedeu1wIf02ekK2v7bAQEAfR9e0/u1LI= k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU= From f9a3f90e6638fafa5f2dcc61edcd22d5e1aa4a92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:33:25 +0100 Subject: [PATCH 2/6] Bump github.com/google/uuid from 1.4.0 to 1.5.0 (#322) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ea2669c1c..1c0a50849 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/cloudevents/sdk-go/v2 v2.14.0 github.com/go-logr/logr v1.3.0 github.com/go-logr/zapr v1.3.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.5.0 github.com/kelseyhightower/envconfig v1.4.0 github.com/kyma-project/api-gateway v0.0.0-20231205091251-e217d20481f1 github.com/kyma-project/kyma/common/logging v0.0.0-20231113125307-562a57ab5198 diff --git a/go.sum b/go.sum index 94f945076..9e2710679 100644 --- a/go.sum +++ b/go.sum @@ -172,8 +172,8 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= From 29e19fa97a9fea74dd9a078bfd3e11fb2d6acf78 Mon Sep 17 00:00:00 2001 From: Nina Hingerl <76950046+NHingerl@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:37:26 +0100 Subject: [PATCH 3/6] docs: Adjust Eventing to new content guidelines (#315) * adjust Eventing to new content guidelines * adjust sidebars * fix capitalization * Apply Natalia's suggestions Co-authored-by: Natalia Sitko <80401180+nataliasitko@users.noreply.github.com> * remove "documentation overview", redundant with sidebar * prevent link check error * adjust diagrams to styleguide * adjust reconcile diagram * No more title case for Kyma dashboard --------- Co-authored-by: Natalia Sitko <80401180+nataliasitko@users.noreply.github.com> --- README.md | 21 +++++---- docs/assets/evnt-architecture.svg | 4 +- docs/assets/evnt-pubsub.svg | 4 +- docs/assets/reconcileLoop.svg | 2 +- docs/contributor/development.md | 3 +- docs/contributor/governance.md | 6 ++- docs/contributor/installation.md | 17 +++---- docs/contributor/testing.md | 4 +- docs/contributor/troubleshooting.md | 10 ++-- docs/user/01-manager.md | 6 +-- docs/user/README.md | 47 ++----------------- docs/user/_sidebar.md | 38 ++++++++------- docs/user/evnt-architecture.md | 4 +- docs/user/evnt-event-names.md | 11 +++-- docs/user/evnt-eventing-metrics.md | 8 ++-- docs/user/resources/_sidebar.md | 3 -- docs/user/resources/evnt-cr-subscription.md | 8 ++-- docs/user/troubleshooting/_sidebar.md | 9 ---- .../evnt-01-eventing-troubleshooting.md | 14 +++--- .../evnt-04-free-jetstream-storage.md | 7 +-- docs/user/tutorials/_sidebar.md | 7 --- docs/user/tutorials/evnt-01-prerequisites.md | 14 ++++-- .../evnt-02-subs-with-multiple-filters.md | 27 ++++++----- docs/user/tutorials/evnt-03-type-cleanup.md | 31 +++++++----- .../evnt-04-change-max-in-flight-in-sub.md | 35 ++++++++------ .../tutorials/evnt-05-send-legacy-events.md | 15 ++++-- 26 files changed, 164 insertions(+), 191 deletions(-) delete mode 100644 docs/user/resources/_sidebar.md delete mode 100644 docs/user/troubleshooting/_sidebar.md delete mode 100644 docs/user/tutorials/_sidebar.md diff --git a/README.md b/README.md index 96f8320d7..a577ef514 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Eventing Manager is a standard Kubernetes [operator](https://kubernetes.io/docs/ This project is scaffolded using [Kubebuilder](https://book.kubebuilder.io), and all the Kubebuilder `makefile` helpers mentioned [here](https://book.kubebuilder.io/reference/makefile-helpers.html) can be used. -## Get started +## Get Started You need a Kubernetes cluster to run against. You can use [k3d](https://k3d.io/) to get a local cluster for testing, or run against a remote cluster. > **Note:** Your controller automatically uses the current context in your kubeconfig file, that is, whatever cluster `kubectl cluster-info` shows. @@ -42,7 +42,7 @@ You need a Kubernetes cluster to run against. You can use [k3d](https://k3d.io/) - [kustomize](https://kustomize.io/) - Access to Kubernetes cluster ([k3d](https://k3d.io/) / k8s) -### Run Eventing Manager locally +### Run Eventing Manager Locally 1. Install the CRDs into the cluster: @@ -58,7 +58,7 @@ You need a Kubernetes cluster to run against. You can use [k3d](https://k3d.io/) > **NOTE:** You can also run this in one step with the command: `make install run`. -### Run tests +### Run Tests Run the unit and integration tests: @@ -76,7 +76,7 @@ make generate-and-test make lint ``` -### Modify the API definitions +### Modify the API Definitions If you are editing the API definitions, generate the manifests such as CRs or CRDs: @@ -88,7 +88,7 @@ make manifests For more information, see the [Kubebuilder documentation](https://book.kubebuilder.io/introduction.html). -### Build container images +### Build Container Images Build and push your image to the location specified by `IMG`: @@ -107,7 +107,7 @@ make docker-buildx IMG=/eventing-manager: You need a Kubernetes cluster to run against. You can use [k3d](https://k3d.io/) to get a local cluster for testing, or run against a remote cluster. > **Note:** Your controller automatically uses the current context in your kubeconfig file, that is, whatever cluster `kubectl cluster-info` shows. -### Deploy on the cluster +### Deploy on the Cluster 1. Download Go packages: @@ -133,14 +133,15 @@ You need a Kubernetes cluster to run against. You can use [k3d](https://k3d.io/) make deploy IMG=/eventing-manager: ``` -4. [Optional] Install `Eventing` Custom Resource: +5. [Optional] Install `Eventing` Custom Resource: ```sh kubectl apply -f config/samples/default.yaml ``` -5. For EventMesh backend, if the Kyma Kubernetes cluster is managed by Gardener, then the Eventing Manager reads the cluster public domain from the ConfigMap **kube-system/shoot-info**. +6. For EventMesh backend, if the Kyma Kubernetes cluster is managed by Gardener, then the Eventing Manager reads the cluster public domain from the ConfigMap **kube-system/shoot-info**. Otherwise, set the **spec.backend.config.domain** to the cluster public domain in the `eventing` custom resource; for example: + ```yaml spec: backend: @@ -167,7 +168,7 @@ To delete the CRDs from the cluster: make uninstall ``` -### Deploy Eventing Manager module with [Kyma Lifecycle Manager](https://github.com/kyma-project/lifecycle-manager/tree/main) +### Deploy Eventing Manager Module With [Kyma Lifecycle Manager](https://github.com/kyma-project/lifecycle-manager/tree/main) 1. Deploy the Lifecycle Manager to the Kubernetes cluster: @@ -203,7 +204,7 @@ To delete the CRDs from the cluster: kubectl get -n kyma-system kyma ``` -### Uninstall Eventing Manager module with [Kyma Lifecycle Manager](https://github.com/kyma-project/lifecycle-manager/tree/main) +### Uninstall Eventing Manager Module With [Kyma Lifecycle Manager](https://github.com/kyma-project/lifecycle-manager/tree/main) 1. Delete Eventing custom resource (CR) from the Kubernetes cluster (if exists): diff --git a/docs/assets/evnt-architecture.svg b/docs/assets/evnt-architecture.svg index 2e27ffbe6..9347ff5e5 100644 --- a/docs/assets/evnt-architecture.svg +++ b/docs/assets/evnt-architecture.svg @@ -1,4 +1,4 @@ - + -
Event Source
Event Source
User Namespace
User Namespace
Subscription CR
sink: function: test
Subscription CR...
kyma-system Namespace
kyma-system Namespace
Kyma cluster
Kyma cluster
NATS publisher proxy
NATS publisher pr...
NATS
 server
NATS...
publishes events
publishes events
sends event
sends event
dispatches events
dispatches events
1
1
2%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bfont%20color%3D%26quot%3B%23ffffff%26quot%3B%20style%3D%26quot%3Bfont-size%3A%2019px%26quot%3B%26gt%3B1%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BstrokeColor%3D%230A6ED1%3BfillColor%3D%230A6ED1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22185%22%20y%3D%22220%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E
2%3Cmx...
4
4
3
3
5
5
creates infrastructure
creates infrastructure
watches subscription
watches subscription
dispatches event
dispatches event
6
6
Reference key:
Reference key:
function: test
function: test
Dashed connectors represent background processes
Dashed connectors represent background processes
NATS eventing controller
NATS eventing contro...
Text is not SVG - cannot display
\ No newline at end of file +Kyma ClusterUser Namespace
Event Source
Event Source
Subscription CR
sink: function: test
Subscription CR...
<kyma-system> Namespace
NATS publisher proxy
NATS publisher pr...
NATS
 server
NATS...
function: test
function: test
NATS eventing controller
NATS eventing con...
Reference key:
Reference key:
Dashed connectors represent background processes
Dashed connectors represent background processes
watches subscription
watches subscription
dispatches event
dispatches event
1
1
6
6
dispatches events
dispatches events
creates infrastructure
creates infrastructure
2%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bfont%20color%3D%26quot%3B%23ffffff%26quot%3B%20style%3D%26quot%3Bfont-size%3A%2019px%26quot%3B%26gt%3B1%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BstrokeColor%3D%230A6ED1%3BfillColor%3D%230A6ED1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22185%22%20y%3D%22220%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E
2%3Cmx...
5
5
sends event
sends event
4
4
publishes
 events
publishes...
3
3
Text is not SVG - cannot display
\ No newline at end of file diff --git a/docs/assets/evnt-pubsub.svg b/docs/assets/evnt-pubsub.svg index e82bc8fcc..c29eb07db 100644 --- a/docs/assets/evnt-pubsub.svg +++ b/docs/assets/evnt-pubsub.svg @@ -1,4 +1,4 @@ - + -
Publisher
Publisher
Backend
Backend
publish events
(A and B)
publish events...
filter and
send events
filter and...
Subscriber (A)
Subscriber (A)
Subscriber
Subscriber
Subscribers (B)
Subscribers (B)
Text is not SVG - cannot display
\ No newline at end of file +
Publisher
Publisher
Backend
Backend
Subscriber (A)
Subscriber (A)
Subscriber
Subscriber
publish events
(A and B)
publish events...
filter and
send events
filter and...
Subscribers (B)
Subscribers (B)
Text is not SVG - cannot display
\ No newline at end of file diff --git a/docs/assets/reconcileLoop.svg b/docs/assets/reconcileLoop.svg index 1605fbbfd..8ade93cc3 100644 --- a/docs/assets/reconcileLoop.svg +++ b/docs/assets/reconcileLoop.svg @@ -1,4 +1,4 @@ -
Eventing CR
Eventing CR
Eventing Reconciler
Eventing Reconciler
NATS Path
NATS Path
EventMesh Path
EventMesh Path
Reconciliation Loop
Reconciliation Loop
Text is not SVG - cannot display
\ No newline at end of file +
Eventing CR
Eventing CR
Eventing Reconciler
Eventing Reconciler
NATS Path
NATS Path
EventMesh Path
EventMesh Path
Reconciliation Loop
Reconciliation Loop
Text is not SVG - cannot display
\ No newline at end of file diff --git a/docs/contributor/development.md b/docs/contributor/development.md index c3db1814e..96fef0227 100644 --- a/docs/contributor/development.md +++ b/docs/contributor/development.md @@ -13,7 +13,8 @@ Projects created by Kubebuilder contain a Makefile with tooling that must be loc - [kustomize](https://kustomize.io/) - [golangci-lint](https://golangci-lint.run/) -## Available commands +## Available Commands + Commands are available for easier development and installation of Eventing Manager. To find out which commands are available and for some more details about each command, run: diff --git a/docs/contributor/governance.md b/docs/contributor/governance.md index 9d111c79f..508dca1be 100644 --- a/docs/contributor/governance.md +++ b/docs/contributor/governance.md @@ -3,7 +3,7 @@ Some quality aspects are covered by automated verification, so you must execute tooling locally before a commit. This document guides you through the development flow. -## Modifying the API definitions +## Modifying the API Definitions This project uses the [controller-gen](https://book.kubebuilder.io/reference/controller-gen.html) tool provided by [Kubebuilder](https://book.kubebuilder.io/). To modify the API definitions, you must adapt the ["marker comments"](https://book.kubebuilder.io/reference/markers.html) in the Go code. @@ -13,17 +13,19 @@ The rules are written using the [Common Expression Language](https://github.com/ For further information and examples, look to the [Kubernetes documentation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) of validation rules and the CEL [language definition](https://github.com/google/cel-spec/blob/v0.10.0/doc/langdef.md). After the modifications, run the following command to generate the new manifests, such as custom resources (CRs) and CustomResourceDefinitions (CRDs): + ```sh make manifests ``` If changes to the `runtime.Object` interface were made, the `DeepCopy` functions must be updated as well. The generation is controlled by [Kubebuilder markers](https://book.kubebuilder.io/reference/markers/object.html?highlight=deep#objectdeepcopy). + ```sh make generate ``` -## Source code linting +## Source Code Linting The quality of this project is ensured by source code linting using [golangci-lint](https://golangci-lint.run/). diff --git a/docs/contributor/installation.md b/docs/contributor/installation.md index a9bd95eb2..01e4553ac 100644 --- a/docs/contributor/installation.md +++ b/docs/contributor/installation.md @@ -1,14 +1,15 @@ -# Installation and uninstallation +# Installation and Uninstallation There are several ways to install Eventing Manager. For development, you must run some make targets beforehand. For information about the prerequisites, refer to [Development](./development.md) and for a detailed guide to the development flow, visit [Governance](./governance.md). -## Run the manager on a (k3d) cluster using a Docker image +## Run the Manager on a (k3d) Cluster Using a Docker Image ### Installation 1. Ensure you have a k3d cluster ready. + ```sh k3d create cluster ``` @@ -57,9 +58,9 @@ This step depends on your desired backend: NATS or EventMesh. ```sh kubectl apply -f config/samples/default.yaml ``` - + The `spec.backend.type` needs to be set to `NATS`. You can configure the backend using the `NATS` related field in `spec.backend.config`. - + ```sh spec: backend: @@ -78,12 +79,12 @@ This step depends on your desired backend: NATS or EventMesh. ```sh kubectl apply -f config/samples/default_eventmesh.yaml ``` - + - `spec.backend.type`: set to `EventMesh` - `spec.backend.config.eventMeshSecret`: set it to the `/` where you applied the secret - `spec.backend.config.eventTypePrefix`: change to your desired value or leave as is - `spec.backend.config.domain`: set to the cluster public domain - + If the Kyma Kubernetes cluster is managed by Gardener, Eventing Manager reads the cluster public domain automatically from the ConfigMap `kube-system/shoot-info`. Otherwise, you need to additionally set `spec.backend.config.domain` in the configuration. @@ -123,7 +124,7 @@ This step depends on your desired backend: NATS or EventMesh. make uninstall ``` -## Run Eventing Manager on a cluster using the Go runtime environment +## Run Eventing Manager on a Cluster Using the Go Runtime Environment ### Installation @@ -157,7 +158,7 @@ Remove the resources. make uninstall ``` -## Run Eventing Manager using Kyma's Lifecycle Manager +## Run Eventing Manager Using Kyma’s Lifecycle Manager [Kyma's Lifecycle Manager](https://github.com/kyma-project/lifecycle-manager) helps manage the lifecycle of each module in the cluster and can be used to install Eventing Manager. diff --git a/docs/contributor/testing.md b/docs/contributor/testing.md index 30a07abdb..3a08b1ace 100644 --- a/docs/contributor/testing.md +++ b/docs/contributor/testing.md @@ -12,7 +12,7 @@ This document provides an overview of the testing activities used in this projec > **NOTE:** The validation and defaulting rules are tested within the integration tests. -### Unit tests and env-tests +### Unit Tests and Env-Tests To run the unit and integration tests, the following command must be executed. If necessary, the needed binaries for the integration tests are downloaded to `./bin`. Further information about integration tests can be found in the [Kubebuilder book](https://book.kubebuilder.io/reference/envtest.html). @@ -27,7 +27,7 @@ If changes to the source code were made, or if this is your first time to execut make test ``` -### E2E tests +### E2E Tests Because E2E tests need a Kubernetes cluster to run on, they are separate from the remaining tests. diff --git a/docs/contributor/troubleshooting.md b/docs/contributor/troubleshooting.md index 3bc553443..47315c2cf 100644 --- a/docs/contributor/troubleshooting.md +++ b/docs/contributor/troubleshooting.md @@ -4,23 +4,23 @@ This document contains tips and tricks for common problems with Eventing Manager If you cannot find your issue described here, take a look at the [Eventing Troubleshooting](https://github.com/kyma-project/eventing-manager/blob/main/docs/user/troubleshooting/README.md) -## Troubleshooting: Installing Eventing Manager using a Docker image +## Troubleshooting: Installing Eventing Manager Using a Docker Image -### Error while deploying Eventing Manager +### Error While Deploying Eventing Manager **Symptom:** The `make deploy` step fails with the following error message: `Error from server (NotFound): error when creating "STDIN": namespaces kyma-system not found` -**Cause:** The Namespace of the Deployment does not exist yet. +**Cause:** The namespace of the Deployment does not exist yet. -**Remedy:** Create the Namespace. +**Remedy:** Create the namespace. ```sh kubectl create ns kyma-system ``` -## Reach out to us +## Reach Out to Us If you encounter an issue or want to report a bug, please create a [GitHub issue](https://github.com/kyma-project/nats-manager/issues) with background information and steps on how to reproduce. diff --git a/docs/user/01-manager.md b/docs/user/01-manager.md index 6a6c3063a..1833f0767 100644 --- a/docs/user/01-manager.md +++ b/docs/user/01-manager.md @@ -1,8 +1,8 @@ -# Eventing manager +# Eventing Manager This module ships Eventing Manager. Once this module is enabled, it provides the functionality to send and receive events. -## Module lifecycle +## Module Lifecycle Upon starting Eventing Manager, the controller (following the [Kubebuilder concept](https://book.kubebuilder.io/architecture.html)) creates, watches, and reconciles the following resources: @@ -31,6 +31,6 @@ Eventing Manager supports switching between two different backends. [NATS](https For more information about the possible configuration of Eventing Manager using NATS or EventMesh backend, refer to the [backend configuration](02-configuration.md#reference). -## Removing the module +## Removing the Module The module cannot be removed as long as Subscription CRs exist. After the user cleans up all the subscriptions, the Eventing module can be removed. The module takes care of cleaning up all resources owned by it. diff --git a/docs/user/README.md b/docs/user/README.md index 76a405f33..2c2704a9f 100644 --- a/docs/user/README.md +++ b/docs/user/README.md @@ -1,6 +1,6 @@ -# Eventing module +# Eventing Module -This module ships Eventing Manager, which is a standard Kubernetes operator that observes the state of Eventing resources and reconciles them according to the desired state. +The Eventing module ships Eventing Manager, which is a standard Kubernetes operator that observes the state of Eventing resources and reconciles them according to the desired state. With Kyma Eventing, you can focus on your business workflows and trigger them with events to implement asynchronous flows within Kyma. Generally, eventing consists of event producers (or publishers) and consumers (or subscribers) that send events to or receive events from an event processing backend. @@ -12,7 +12,7 @@ Kyma Eventing uses the following technology: - [HTTP POST](https://www.w3schools.com/tags/ref_httpmethods.asp) requests to simplify sending and receiving events - Declarative [Subscription custom resource (CR)](./resources/evnt-cr-subscription.md) to subscribe to events -## Kyma Eventing flow +## Kyma Eventing Flow Kyma Eventing follows the PubSub messaging pattern: Kyma publishes messages to a messaging backend, which filters these messages and sends them to interested subscribers. Kyma does not send messages directly to the subscribers as shown below: @@ -39,44 +39,3 @@ For more information, read [Eventing architecture](evnt-architecture.md). - **Delivery Guarantees** - `at least once` delivery: With NATS JetStream, Kyma ensures that for each event published, all the subscribers subscribed to that event receive the event at least once. - `max bytes and discard policy`: NATS JetStream uses these configurations to ensure that no messages are lost when the storage is almost full. By default, Kyma ensures that no new messages are accepted when the storage reaches 90% capacity. - -## Documentation overview - -To learn more about how Eventing works, see: - -- [Eventing module](01-manager.md) - provides a general overview of the Eventing module -- [Eventing module configuration](02-configuration.md) - contains information about configuring the Eventing module -- [Eventing architecture](evnt-architecture.md) - describes how Eventing works and the main actors involved, such as Eventing Manager and Event Publisher Proxy. -- [Event names](evnt-event-names.md) - contains information about event names and event name cleanup. -- [Subscription CR](./resources/evnt-cr-subscription.md) - describes the Subscription custom resource, which you need to subscribe to events. -- [CloudEvents](https://cloudevents.io/) - provides information about the CloudEvents specification used in Kyma. -- [NATS JetStream](https://docs.nats.io/nats-concepts/jetstream) - provides more information about the backend technology behind Eventing in Kyma. [Eventing Architecture](evnt-architecture.md#jet-stream) provides details on the functionalities and higher qualities of service on top of Core NATS. - -To learn more about technical details aimed at possible contributors, check out the following documents: -- [Development](../contributor/development.md) - provides general information about the setup -- [Governance](../contributor/governance.md) - provides information about the rules and norms of this project -- [Installation guide](../contributor/installation.md) - contains information about the different ways to install the Eventing module -- [Testing](../contributor/testing.md) - describes the test coverage of the project -- [Troubleshooting](../contributor/troubleshooting.md) - provides general information about troubleshooting the module - -To perform tasks with Eventing, go through these tutorials: - -- [Tutorial: Trigger your workload with an event](https://kyma-project.io/#/02-get-started/04-trigger-workload-with-event) - shows how to deploy a Function and trigger it with an event. -- [Tutorial: Create Subscription subscribing to multiple event types](tutorials/evnt-02-subs-with-multiple-filters.md) - shows how to subscribe to one or more event types using the Kyma Subscription. -- [Tutorial: Event name cleanup in Subscriptions](tutorials/evnt-03-type-cleanup.md) - explains how Kyma Eventing filters out prohibited characters from event names. -- [Tutorial: Changing Events Max-In-Flight in Subscriptions](tutorials/evnt-04-change-max-in-flight-in-sub.md) - shows how to set idle "in-flight messages" limit in Kyma Subscriptions. -- [Tutorial: Publish legacy events using Kyma Eventing](tutorials/evnt-05-send-legacy-events.md) - demonstrates how to send legacy events using Kyma Eventing. - -To troubleshoot Eventing-related issues: - -- [Basic Eventing Troubleshooting](troubleshooting/evnt-01-eventing-troubleshooting.md) -- [NATS JetStream Troubleshooting](troubleshooting/evnt-02-jetstream-troubleshooting.md) -- [Event Type Collision](troubleshooting/evnt-03-type-collision.md) -- [Eventing Backend Storage Full](troubleshooting/evnt-04-free-jetstream-storage.md) - -For other technical resources, check out these links on the Kyma GitHub repository: - -- [Eventing Helm chart](https://github.com/kyma-project/kyma/tree/main/resources/eventing) -- [Event Publishing Proxy](https://github.com/kyma-project/kyma/tree/main/components/event-publisher-proxy) -- [Eventing Manager](https://github.com/kyma-project/kyma/tree/main/components/eventing-controller) -- [Eventing Metrics](evnt-eventing-metrics.md) diff --git a/docs/user/_sidebar.md b/docs/user/_sidebar.md index 23ab3f949..23828dfe7 100644 --- a/docs/user/_sidebar.md +++ b/docs/user/_sidebar.md @@ -1,21 +1,23 @@ -* [Home](/README.md) -* [Eventing module](README.md) -* [Module lifecycle](01-manager.md) -* [Configuration](02-configuration.md) -* [Eventing architecture](evnt-architecture.md) -* [Event names](evnt-event-names.md) -* [Eventing metrics](evnt-eventing-metrics.md) + +* [Back to Kyma Home](/) +* [Eventing module](/eventing-manager/user/README.md) +* [Module lifecycle](/eventing-manager/user/01-manager.md) +* [Configuration](/eventing-manager/user/02-configuration.md) +* [Eventing Architecture](/eventing-manager/user/evnt-architecture.md) +* [Event Names](/eventing-manager/user/evnt-event-names.md) +* [Eventing Metrics](/eventing-manager/user/evnt-eventing-metrics.md) * Tutorials - * [Prerequisites](./tutorials/evnt-01-prerequisites.md) - * [Create Subscription subscribing to multiple event types](./tutorials/evnt-02-subs-with-multiple-filters.md) - * [Event name cleanup in Subscriptions](./tutorials/evnt-03-type-cleanup.md) - * [Changing events max-in-flight in Subscriptions](./tutorials/evnt-04-change-max-in-flight-in-sub.md) - * [Publish legacy events using Kyma Eventing](./tutorials/evnt-05-send-legacy-events.md) + * [Prerequisites](/eventing-manager/user/tutorials/evnt-01-prerequisites.md) + * [Create Subscription Subscribing to Multiple Event Types](/eventing-manager/user/tutorials/evnt-02-subs-with-multiple-filters.md) + * [Event Name Cleanup in Subscriptions](/eventing-manager/user/tutorials/evnt-03-type-cleanup.md) + * [Changing Events Max-In-Flight in Subscriptions](/eventing-manager/user/tutorials/evnt-04-change-max-in-flight-in-sub.md) + * [Publish Legacy Events Using Kyma Eventing](/eventing-manager/user/tutorials/evnt-05-send-legacy-events.md) * Resources - * [Subscription CR](./resources/evnt-cr-subscription.md) + * [Subscription CR](/eventing-manager/user/resources/evnt-cr-subscription.md) * Troubleshooting - * [Kyma Eventing - basic diagnostics](./troubleshooting/evnt-01-eventing-troubleshooting.md) - * [NATS JetStream backend troubleshooting](./troubleshooting/evnt-02-jetstream-troubleshooting.md) - * [Subscriber receives irrelevant events](./troubleshooting/evnt-03-type-collision.md) - * [Eventing backend stopped receiving events due to full storage](./troubleshooting/evnt-04-free-jetstream-storage.md) - * [Published events are pending in the stream](./troubleshooting/evnt-05-fix-pending-messages.md) + * [Kyma Eventing - Basic Diagnostics](/eventing-manager/user/troubleshooting/evnt-01-eventing-troubleshooting.md) + * [NATS JetStream Backend Troubleshooting](/eventing-manager/user/troubleshooting/evnt-02-jetstream-troubleshooting.md) + * [Subscriber Receives Irrelevant Events](/eventing-manager/user/troubleshooting/evnt-03-type-collision.md) + * [Eventing Backend Stopped Receiving Events Due To Full Storage](/eventing-manager/user/troubleshooting/evnt-04-free-jetstream-storage.md) + * [Published Events Are Pending in the Stream](/eventing-manager/user/troubleshooting/evnt-05-fix-pending-messages.md) + diff --git a/docs/user/evnt-architecture.md b/docs/user/evnt-architecture.md index 264b7987e..e53043cdd 100644 --- a/docs/user/evnt-architecture.md +++ b/docs/user/evnt-architecture.md @@ -1,8 +1,8 @@ -# Eventing architecture +# Eventing Architecture Eventing uses Event Publisher Proxy and Eventing Manager to connect to the default NATS JetStream backend. They work together to process and deliver events in Kyma. -## Event processing and delivery +## Event Processing and Delivery The event processing and delivery flow uses the NATS server to process events and send them to subscribers. This diagram explains the event flow in Kyma, from the moment an event source sends an event, to the point when the event triggers the Function. diff --git a/docs/user/evnt-event-names.md b/docs/user/evnt-event-names.md index da1d8e5b2..a6c6aad5f 100644 --- a/docs/user/evnt-event-names.md +++ b/docs/user/evnt-event-names.md @@ -1,27 +1,30 @@ -# Event names +# Event Names Event names depend on the type of event. Eventing supports the following event types: + - [CloudEvents](https://cloudevents.io/) - they use a specification for describing event data in a common way. - legacy events - they are converted to CloudEvents by [Event Publisher Proxy](evnt-architecture.md#event-publisher-proxy). -## Event name format +## Event Name Format For a Subscription custom resource (CR), the fully qualified event name takes the sample form of `order.created.v1` or `Account.Root.Created.v1`. The event type is composed of the following components: + - Event: can have two or more segments separated by `.`; for example, `order.created` or `Account.Root.Created` - Version: `v1` For publishers, the event type takes this sample form: + - `order.created` or `Account.Root.Created` for legacy events coming from the `commerce` application - `order.created.v1` or `Account.Root.Created.v1` for CloudEvents -## Event name cleanup +## Event Name Cleanup To conform to Cloud Event specifications, sometimes Eventing must modify the event name before dispatching an event. -### Special characters +### Special Characters If the event name contains any prohibited characters as per [NATS JetStream specifications](https://docs.nats.io/running-a-nats-service/nats_admin/jetstream_admin/naming), the underlying Eventing services use a clean name with allowed characters only; for example, `system>prod*` becomes `systemprod`. diff --git a/docs/user/evnt-eventing-metrics.md b/docs/user/evnt-eventing-metrics.md index 53645ffae..08d4d215b 100644 --- a/docs/user/evnt-eventing-metrics.md +++ b/docs/user/evnt-eventing-metrics.md @@ -1,9 +1,9 @@ -# Kyma Eventing metrics +# Kyma Eventing Metrics Kyma Eventing provides various metrics, so you can monitor statistics and other information in real time. The metrics follow the [Prometheus naming convention](https://prometheus.io/docs/practices/naming/). -## Metrics emitted by Eventing Publisher Proxy +## Metrics Emitted by Eventing Publisher Proxy | Metric | Description | | ---------------------------------------------- | :------------------------------------------------------------------------------- | @@ -13,7 +13,7 @@ The metrics follow the [Prometheus naming convention](https://prometheus.io/docs | **eventing_epp_requests_duration_seconds** | The duration of processing an incoming request (includes sending to the backend) | | **eventing_epp_requests_total** | The total number of requests | -## Metrics emitted by Eventing Manager +## Metrics Emitted by Eventing Manager | Metric | Description | | --------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | @@ -23,6 +23,6 @@ The metrics follow the [Prometheus naming convention](https://prometheus.io/docs | **eventing_ec_nats_subscriber_dispatch_duration_seconds** | The duration of sending an incoming NATS message to the subscriber (not including processing the message in the dispatcher) | | **eventing_ec_subscription_status** | The status of a subscription. `1` indicates the subscription is marked as ready | -### Metrics emitted by NATS Exporter: +### Metrics Emitted by NATS Exporter The [Prometheus NATS Exporter](https://github.com/nats-io/prometheus-nats-exporter) also emits metrics that you can monitor. Learn more about [NATS Monitoring](https://docs.nats.io/running-a-nats-service/configuration/monitoring#jetstream-information). diff --git a/docs/user/resources/_sidebar.md b/docs/user/resources/_sidebar.md deleted file mode 100644 index 60cea1afe..000000000 --- a/docs/user/resources/_sidebar.md +++ /dev/null @@ -1,3 +0,0 @@ -- [Eventing module](../README.md) -- Resources - - [Subscription](evnt-cr-subscription.md) \ No newline at end of file diff --git a/docs/user/resources/evnt-cr-subscription.md b/docs/user/resources/evnt-cr-subscription.md index e10549ded..30594c53f 100644 --- a/docs/user/resources/evnt-cr-subscription.md +++ b/docs/user/resources/evnt-cr-subscription.md @@ -4,13 +4,13 @@ The `subscriptions.eventing.kyma-project.io` CustomResourceDefinition (CRD) is a `kubectl get crd subscriptions.eventing.kyma-project.io -o yaml` -## Sample custom resource +## Sample Custom Resource This sample Subscription custom resource (CR) subscribes to an event called `order.created.v1`. > **WARNING:** Prohibited characters in event names under the **spec.types** property, are not supported in some backends. If any are detected, Eventing will remove them. Read [Event names](../evnt-event-names.md#event-name-cleanup) for more information. -> **NOTE:** Both the subscriber and the Subscription should exist in the same Namespace. +> **NOTE:** Both the subscriber and the Subscription should exist in the same namespace. ```yaml apiVersion: eventing.kyma-project.io/v1alpha2 @@ -28,7 +28,7 @@ spec: maxInFlightMessages: "10" ``` -## Custom resource parameters +## Custom Resource Parameters This table lists all the possible parameters of a given resource together with their descriptions: @@ -145,7 +145,7 @@ This table lists all the possible parameters of a given resource together with t -## Related resources and components +## Related Resources and Components These components use this CR: diff --git a/docs/user/troubleshooting/_sidebar.md b/docs/user/troubleshooting/_sidebar.md deleted file mode 100644 index 6eedc6bbc..000000000 --- a/docs/user/troubleshooting/_sidebar.md +++ /dev/null @@ -1,9 +0,0 @@ -- [Eventing module](../README.md) -- Troubleshooting - - [Troubleshooting - Eventing](README.md) - - [Kyma Eventing - basic diagnostics](evnt-01-eventing-troubleshooting.md) - - [NATS JetStream backend troubleshooting](evnt-02-jetstream-troubleshooting.md) - - [Subscriber receives irrelevant events](evnt-03-type-collision.md) - - [Eventing backend stopped receiving events due to full storage](evnt-04-free-jetstream-storage.md) - - [Published events are pending in the stream](evnt-05-fix-pending-messages.md) - \ No newline at end of file diff --git a/docs/user/troubleshooting/evnt-01-eventing-troubleshooting.md b/docs/user/troubleshooting/evnt-01-eventing-troubleshooting.md index 4298dcafd..50e06814a 100644 --- a/docs/user/troubleshooting/evnt-01-eventing-troubleshooting.md +++ b/docs/user/troubleshooting/evnt-01-eventing-troubleshooting.md @@ -1,4 +1,4 @@ -# Kyma Eventing - basic diagnostics +# Kyma Eventing - Basic Diagnostics ## Symptom @@ -16,7 +16,7 @@ Trouble with Kyma Eventing may be caused by various issues, so this document gui Follow these steps to detect the source of the problem: -### Step 1: Check the status of the Eventing custom resource (CR) +### Step 1: Check the Status of the Eventing Custom Resource (CR) 1. Check the Eventing CR. Is the **State** field `Ready`? @@ -32,7 +32,7 @@ Follow these steps to detect the source of the problem: 3. If the **State** is `Ready`, the Eventing CR is not an issue. Follow the next steps to find the source of the problem. -### Step 2: Check the status of the Subscription +### Step 2: Check the Status of the Subscription 1. Check whether the Subscription is `Ready`. Run the command: @@ -50,7 +50,7 @@ Follow these steps to detect the source of the problem: 3. Check if the event type defined in the Subscription is correctly formatted as specified in the [Event names](../evnt-event-names.md) guidelines. -### Step 3: Check if the event was published correctly +### Step 3: Check if the Event Was Published Correctly 1. Check the HTTP status code returned after sending an event. @@ -67,7 +67,7 @@ Follow these steps to detect the source of the problem: kubectl -n {NAMESPACE} get subscriptions.eventing.kyma-project.io {NAME} -o jsonpath='{.spec.filter.filters}' ``` -### Step 4: Check the Eventing Manager logs +### Step 4: Check the Eventing Manager Logs 1. Check the logs from the Eventing Manager Pod for any errors and to verify that the event is dispatched. To fetch these logs, run this command: @@ -84,7 +84,7 @@ Follow these steps to detect the source of the problem: - Eventing Manager cannot connect to NATS Server. -### Step 5: Check if the Subscription sink is healthy +### Step 5: Check if the Subscription Sink Is Healthy 1. Check whether the workload URL defined in the Subscription sink is correct and healthy to receive events. To get the sink from the Subscription, run this command: @@ -102,7 +102,7 @@ Follow these steps to detect the source of the problem: If the returned HTTP status code is not 2xx, check the logs of the subscriber instance. -### Step 6: Check NATS JetStream status +### Step 6: Check NATS JetStream Status 1. Check the health of NATS Pods. Run the command: diff --git a/docs/user/troubleshooting/evnt-04-free-jetstream-storage.md b/docs/user/troubleshooting/evnt-04-free-jetstream-storage.md index 7b7b20ed8..caa4bdc00 100644 --- a/docs/user/troubleshooting/evnt-04-free-jetstream-storage.md +++ b/docs/user/troubleshooting/evnt-04-free-jetstream-storage.md @@ -1,4 +1,4 @@ -# Eventing backend stopped receiving events due to full storage +# Eventing Backend Stopped Receiving Events Due To Full Storage ## Symptom @@ -26,12 +26,9 @@ There are several ways to free the space on NATS JetStream backend: - If the published events are too large, the consumer cannot deliver them fast enough before the storage is full. In that case, either slow down the events' publish rate until the events are delivered, or scale the NATS backend with additional replicas. - - Check the [NATS JetStream backend status](evnt-01-eventing-troubleshooting.md#step-6-check-nats-jetstream-status) and if [the sink is reachable and can accept the events](evnt-01-eventing-troubleshooting.md#step-5-check-if-the-subscription-sink-is-healthy). - - The `Interest` retention policy specifies that events published to the subject are not kept in the stream if they don't match any consumer filter. You can delete a Kyma Subscription, which automatically removes all the pending messages in the stream that were published to that Subscription's subject. - -- In case the events' publish rate is very high (more than 1.5k events per second), speed up the event dispatching by increasing the `maxInFlightMessages` configuration of the Subscription (default is set to 10) accordingly. Due to low `maxInFlightMessages`, the dispatcher will not be able to keep up with the publisher, and as a result, the stream size will keep growing. +- If the events' publish rate is very high (more than 1.5k events per second), speed up the event dispatching by increasing the `maxInFlightMessages` configuration of the Subscription (default is set to 10) accordingly. Due to low `maxInFlightMessages`, the dispatcher will not be able to keep up with the publisher, and as a result, the stream size will keep growing. diff --git a/docs/user/tutorials/_sidebar.md b/docs/user/tutorials/_sidebar.md deleted file mode 100644 index c7fcfcd9c..000000000 --- a/docs/user/tutorials/_sidebar.md +++ /dev/null @@ -1,7 +0,0 @@ -- [Eventing module](../README.md) -- Tutorials - - [Prerequisites](evnt-01-prerequisites.md) - - [Create Subscription subscribing to multiple event types](evnt-02-subs-with-multiple-filters.md) - - [Event name cleanup in Subscriptions](evnt-03-type-cleanup.md) - - [Changing events max-in-flight in Subscriptions](evnt-04-change-max-in-flight-in-sub.md) - - [Publish legacy events using Kyma Eventing](evnt-05-send-legacy-events.md) diff --git a/docs/user/tutorials/evnt-01-prerequisites.md b/docs/user/tutorials/evnt-01-prerequisites.md index af0bd5ecb..a6951e6a5 100644 --- a/docs/user/tutorials/evnt-01-prerequisites.md +++ b/docs/user/tutorials/evnt-01-prerequisites.md @@ -1,21 +1,25 @@ -# Eventing - tutorials +# Eventing Tutorials Browse the tutorials for Eventing to learn how to use it step-by-step in different scenarios. -### Prerequisites +## Prerequisites -To perform the steps described in the Eventing tutorials, you need the following: +To perform the Eventing tutorials, you need the following setup: 1. [Kyma cluster provisioned](https://kyma-project.io/#/02-get-started/01-quick-install). -2. (Optional) [Kyma Dashboard](https://kyma-project.io/#/01-overview/ui/README?id=kyma-dashboard) deployed on the Kyma cluster. To access the Dashboard, run: +2. (Optional) [Kyma dashboard](https://kyma-project.io/#/01-overview/ui/README?id=kyma-dashboard) deployed on the Kyma cluster. To access the Dashboard, run: + ```bash kyma dashboard ``` + Alternatively, you can just use the `kubectl` CLI instead. -3. (Optional) [CloudEvents Conformance Tool](https://github.com/cloudevents/conformance) for publishing events. +3. (Optional) [CloudEvents Conformance Tool](https://github.com/cloudevents/conformance) for publishing events. + ```bash go install github.com/cloudevents/conformance/cmd/cloudevents@latest ``` + Alternatively, you can just use `curl` to publish events. diff --git a/docs/user/tutorials/evnt-02-subs-with-multiple-filters.md b/docs/user/tutorials/evnt-02-subs-with-multiple-filters.md index e6a03edce..688fc127b 100644 --- a/docs/user/tutorials/evnt-02-subs-with-multiple-filters.md +++ b/docs/user/tutorials/evnt-02-subs-with-multiple-filters.md @@ -1,4 +1,4 @@ -# Create Subscription subscribing to multiple event types +# Create Subscription Subscribing to Multiple Event Types The [Subscription](../resources/evnt-cr-subscription.md) CustomResourceDefinition (CRD) is used to subscribe to events. In this tutorial, you learn how to subscribe to one or more event types using the Kyma Subscription. @@ -9,7 +9,7 @@ The [Subscription](../resources/evnt-cr-subscription.md) CustomResourceDefinitio 1. Follow the [Prerequisites steps](evnt-01-prerequisites.md) for the Eventing tutorials. 2. [Create a Function](https://kyma-project.io/#/02-get-started/04-trigger-workload-with-event#create-a-function). -## Create a Subscription with multiple event types +## Create a Subscription With Multiple Event Types To subscribe to multiple events, you need a [Subscription](../resources/evnt-cr-subscription.md) custom resource (CR). In the following example, you learn how to subscribe to events of two types: `order.received.v1` and `order.changed.v1`. @@ -19,7 +19,7 @@ To subscribe to multiple events, you need a [Subscription](../resources/evnt-cr- Kyma Dashboard -1. Go to **Namespaces** and select the default Namespace. +1. Go to **Namespaces** and select the default namespace. 2. Go to **Configuration** > **Subscriptions** and click **Create Subscription+**. 3. Provide the following parameters: - **Subscription name**: `lastorder-sub` @@ -40,6 +40,7 @@ To subscribe to multiple events, you need a [Subscription](../resources/evnt-cr- Run: + ```bash cat < @@ -92,13 +96,13 @@ In the following example, you port-forward the [Event Publisher Proxy](../evnt-a --data "{\"orderCode\":\"3211213\", \"orderStatus\":\"received\"}" \ --yaml ``` - +
curl - + ```bash curl -v -X POST \ -H "ce-specversion: 1.0" \ @@ -120,7 +124,7 @@ In the following example, you port-forward the [Event Publisher Proxy](../evnt-a CloudEvents Conformance Tool - + ```bash cloudevents send http://localhost:3000/publish \ --type order.changed.v1 \ @@ -130,13 +134,13 @@ In the following example, you port-forward the [Event Publisher Proxy](../evnt-a --data "{\"orderCode\":\"3211213\", \"orderStatus\":\"changed\"}" \ --yaml ``` - +
curl - + ```bash curl -v -X POST \ -H "ce-specversion: 1.0" \ @@ -151,12 +155,13 @@ In the following example, you port-forward the [Event Publisher Proxy](../evnt-a
-## Verify the event delivery +## Verify the Event Delivery To verify that the events were properly delivered, check the logs of the Function (see [Verify the event delivery](https://kyma-project.io/#/02-get-started/04-trigger-workload-with-event?id=verify-the-event-delivery)). -You will see the received event in the logs: -``` +You see the received event in the logs: + +```sh Received event: { orderCode: '3211213', orderStatus: 'received' } Received event: { orderCode: '3211213', orderStatus: 'changed' } ``` diff --git a/docs/user/tutorials/evnt-03-type-cleanup.md b/docs/user/tutorials/evnt-03-type-cleanup.md index 8ed1dd969..29fda5f7f 100644 --- a/docs/user/tutorials/evnt-03-type-cleanup.md +++ b/docs/user/tutorials/evnt-03-type-cleanup.md @@ -1,4 +1,4 @@ -# Event name cleanup in Subscriptions +# Event Name Cleanup in Subscriptions To conform to Cloud Event specifications, sometimes Eventing must modify the event names to filter out prohibited characters. This tutorial presents one example of event name cleanup. You learn how Eventing behaves when you create a [Subscription](../resources/evnt-cr-subscription.md) having prohibited characters in the event names. Read more about [Event name format and cleanup](../evnt-event-names.md). @@ -25,13 +25,13 @@ You learn how Eventing behaves when you create a [Subscription](../resources/evn } } ``` - +
kubectl - + ```bash cat < -## Create a Subscription with Event type consisting of alphanumeric characters +## Create a Subscription With Event Type Consisting of Alphanumeric Characters Create a [Subscription](../resources/evnt-cr-subscription.md) custom resource (CR) and subscribe for events of the type: `order.payment*success.v1`. Note that `order.payment*success.v1` contains a prohibited character, the asterisk `*`. @@ -72,7 +72,7 @@ Create a [Subscription](../resources/evnt-cr-subscription.md) custom resource (C Kyma Dashboard -1. Go to **Namespaces** and select the default Namespace. +1. Go to **Namespaces** and select the default namespace. 2. Go to **Configuration** > **Subscriptions** and click **Create Subscription+**. 3. Provide the following parameters: - **Subscription name**: `lastorder-payment-sub` @@ -91,6 +91,7 @@ Create a [Subscription](../resources/evnt-cr-subscription.md) custom resource (C Run: + ```bash cat < -## Check the Subscription cleaned Event type +## Check the Subscription Cleaned Event Type To check the Subscription cleaned Event type, run: + ```bash kubectl get subscriptions lastorder-payment-sub -o=jsonpath="{.status.types}" ``` Note that the returned event type `["order.paymentsuccess.v1"]` does not contain the asterisk `*` in the `payment*success` part. That's because Kyma Eventing cleans out the prohibited characters from the event name and uses the cleaned event name in the underlying Eventing backend. -## Trigger the workload with an event +## Trigger the Workload With an Event You created the `lastorder` Function, and subscribed to the `order.payment*success.v1` events by creating a Subscription CR. Next, you see that you can still publish events with the original Event name (i.e. `order.payment*success.v1`) even though it contains the prohibited character, and it triggers the Function. 1. Port-forward the [Event Publisher Proxy](../evnt-architecture.md) Service to localhost, using port `3000`. Run: + ```bash kubectl -n kyma-system port-forward service/eventing-publisher-proxy 3000:80 ``` + 2. Publish an event to trigger your Function. In another terminal window, run:
@@ -140,7 +145,7 @@ Next, you see that you can still publish events with the original Event name (i. CloudEvents Conformance Tool - + ```bash cloudevents send http://localhost:3000/publish \ --type "order.payment*success.v1" \ @@ -150,13 +155,13 @@ Next, you see that you can still publish events with the original Event name (i. --data "{\"orderCode\":\"3211213\", \"orderAmount\":\"1250\"}" \ --yaml ``` - +
curl - + ```bash curl -v -X POST \ -H "ce-specversion: 1.0" \ @@ -171,14 +176,16 @@ Next, you see that you can still publish events with the original Event name (i.
-## Verify the event delivery +## Verify the Event Delivery To verify that the event was properly delivered, check the logs of the Function (see [Verify the event delivery](https://kyma-project.io/#/02-get-started/04-trigger-workload-with-event?id=verify-the-event-delivery)). You see the received event in the logs: -``` + +```sh Received event: { orderCode: '3211213', orderAmount: '1250' } , Event Type: order.paymentsuccess.v1 ``` + Note that the `Event Type` of the received event is not the same as defined in the Subscription. ## Conclusion diff --git a/docs/user/tutorials/evnt-04-change-max-in-flight-in-sub.md b/docs/user/tutorials/evnt-04-change-max-in-flight-in-sub.md index 9a0da5a44..c5a058fa7 100644 --- a/docs/user/tutorials/evnt-04-change-max-in-flight-in-sub.md +++ b/docs/user/tutorials/evnt-04-change-max-in-flight-in-sub.md @@ -1,4 +1,4 @@ -# Changing events max-in-flight in Subscriptions +# Changing Events Max-In-Flight in Subscriptions In this tutorial, you learn how to set idle "in-flight messages" limit in Kyma Subscriptions. The "in-flight messages" config defines the number of events that Kyma Eventing forwards in parallel to the sink, without waiting for a response. @@ -16,7 +16,7 @@ The "in-flight messages" config defines the number of events that Kyma Eventing Kyma Dashboard - + ```js module.exports = { main: async function (event, context) { @@ -28,13 +28,13 @@ The "in-flight messages" config defines the number of events that Kyma Eventing } } ``` - +
kubectl - + ```bash cat < -## Create a Subscription with Max-In-Flight config +## Create a Subscription With Max-In-Flight Config Create a [Subscription](../resources/evnt-cr-subscription.md) custom resource (CR). Subscribe for events of the type: `order.received.v1` and set the `maxInFlightMessages` to `5`, so that Kyma Eventing forwards maximum 5 events in parallel to the sink without waiting for a response. @@ -78,7 +78,7 @@ Create a [Subscription](../resources/evnt-cr-subscription.md) custom resource (C Kyma Dashboard -1. Go to **Namespaces** and select the default Namespace. +1. Go to **Namespaces** and select the default namespace. 2. Go to **Configuration** > **Subscriptions** and click **Create Subscription+**. 3. Switch to the **Advanced** tab, and provide the following parameters: - **Subscription name**: `lastorder-sub` @@ -87,7 +87,7 @@ Create a [Subscription](../resources/evnt-cr-subscription.md) custom resource (C - **Service**: `lastorder` (The sink field will be populated automatically.) - **Type matching:**: `standard` - **Source**: `myapp` - + 4. Click **Create**. 5. Wait a few seconds for the Subscription to have status `READY`. @@ -98,6 +98,7 @@ Create a [Subscription](../resources/evnt-cr-subscription.md) custom resource (C Run: + ```bash cat < -## Trigger the workload with multiple events +## Trigger the Workload With Multiple Events You created the `lastorder` Function, and subscribed to the `order.received.v1` events by creating a Subscription CR. Next, publish 15 events at once and see how Kyma Eventing triggers the workload. 1. Port-forward the [Event Publisher Proxy](../evnt-architecture.md) Service to localhost, using port `3000`. Run: + ```bash kubectl -n kyma-system port-forward service/eventing-publisher-proxy 3000:80 ``` + 2. Now publish 15 events to the Event Publisher Proxy Service. In another terminal window, run:
@@ -140,7 +144,7 @@ Next, publish 15 events at once and see how Kyma Eventing triggers the workload. CloudEvents Conformance Tool - + ```bash for i in {1..15} do @@ -153,13 +157,13 @@ Next, publish 15 events at once and see how Kyma Eventing triggers the workload. --yaml done ``` - +
curl - + ```bash for i in {1..15} do @@ -177,12 +181,13 @@ Next, publish 15 events at once and see how Kyma Eventing triggers the workload.
-## Verify the event delivery +## Verify the Event Delivery To verify that the events ware properly delivered, check the logs of the Function (see [Verify the event delivery](https://kyma-project.io/#/02-get-started/04-trigger-workload-with-event?id=verify-the-event-delivery)). You will see the received events in the logs as: -``` + +```sh Processing event: { orderCode: '1' } Processing event: { orderCode: '2' } Processing event: { orderCode: '3' } @@ -215,4 +220,4 @@ Completely processed event: { orderCode: '14' } Completely processed event: { orderCode: '15' } ``` -You can see that only 5 events at maximum were delivered to the Function in parallel and as soon as the Function completes the processing of the event and returns the response, Kyma Eventing delivers the next in-line event to the Function. +You can see that only 5 events at maximum were delivered to the Function in parallel and as soon as the Function completes the processing of the event and returns the response, Kyma Eventing delivers the next in-line event to the Function. diff --git a/docs/user/tutorials/evnt-05-send-legacy-events.md b/docs/user/tutorials/evnt-05-send-legacy-events.md index d22209173..2067050ad 100644 --- a/docs/user/tutorials/evnt-05-send-legacy-events.md +++ b/docs/user/tutorials/evnt-05-send-legacy-events.md @@ -1,4 +1,4 @@ -# Publish legacy events using Kyma Eventing +# Publish Legacy Events Using Kyma Eventing Kyma Eventing also supports sending and receiving of legacy events. In this tutorial we will show how to send legacy events. @@ -21,7 +21,7 @@ To subscribe to events, we need a [Subscription](../resources/evnt-cr-subscripti Kyma Dashboard -1. Go to **Namespaces** and select the default Namespace. +1. Go to **Namespaces** and select the default namespace. 2. Go to **Configuration** > **Subscriptions** and click **Create Subscription+**. 3. Provide the following parameters: - **Subscription name**: `lastorder-sub` @@ -40,6 +40,7 @@ To subscribe to events, we need a [Subscription](../resources/evnt-cr-subscripti Run: + ```bash cat < -## Publish a legacy event to trigger the workload +## Publish a Legacy Event To Trigger the Workload You created the `lastorder` Function, and subscribed to the `order.received.v1` events by creating a Subscription CR. Now it's time to send an event and trigger the Function. 1. Port-forward the [Event Publisher Proxy](../evnt-architecture.md) Service to localhost, using port `3000`. Run: + ```bash kubectl -n kyma-system port-forward service/eventing-publisher-proxy 3000:80 ``` + 2. Publish an event to trigger your Function. In another terminal window, run: ```bash @@ -92,11 +96,12 @@ You created the `lastorder` Function, and subscribed to the `order.received.v1` > **NOTE:** If you want to use a Function to publish a CloudEvent, see the [Event object SDK specification](https://kyma-project.io/#/serverless-manager/user/technical-reference/07-70-function-specification?id=event-object-sdk). -## Verify the legacy event delivery +## Publish Legacy Events Using Kyma Eventing To verify that the event was properly delivered, check the logs of the Function (see [Verify the event delivery](https://kyma-project.io/#/02-get-started/04-trigger-workload-with-event?id=verify-the-event-delivery)). You see the received event in the logs: -``` + +```sh Received event: { orderCode: '3211213' } ``` From a5d84e4d2b168c34958b08fd4ddd09cef1de459d Mon Sep 17 00:00:00 2001 From: Friedrich Date: Fri, 15 Dec 2023 10:45:26 +0100 Subject: [PATCH 4/6] Fix release of manifests (#340) * clean up create-release.yml Clean up the create-release.yml by removing a number of unused and outcommented lines. * rename release.sh to render_and_upload_manifests.sh Rename the scripts/release.sh to render_and_upload_manifests.sh to point clearly out, what the script is about. * call manifest release from create-release.yml Call the render_and_upload_manifests.sh because it no longer created by a prow job. * deactivate module-template upload Deactivate the upload of the module-template. All functionality for the module-template will be removed eventually, in a follow up PR. * fix reference of env var --- .github/workflows/create-release.yml | 17 +++--- ...ease.sh => render_and_upload_manifests.sh} | 59 ++++++++++--------- 2 files changed, 37 insertions(+), 39 deletions(-) rename scripts/{release.sh => render_and_upload_manifests.sh} (53%) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index c34cd594f..07dd8687a 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -32,11 +32,6 @@ jobs: - name: Check image Tag run: ./scripts/check_tag_info.sh ${{ github.event.inputs.name }} - # run-unit-tests: - # name: Unit tests - # needs: verify-head-status - # uses: "./.github/workflows/run-unit-tests.yaml" - create-draft: name: Create draft release needs: verify-head-status @@ -69,14 +64,16 @@ jobs: - name: Verify job status run: ./scripts/verify-status.sh ${{ github.ref_name }} 600 10 30 + - name: Create and upload eventing-manager.yaml and eventing-default-cr.yaml + env: + PULL_BASE_REF: ${{ PULL_BASE_REF }} + BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} + run: | + ./scripts/render_and_upload_manifests.sh ${{ PULL_BASE_REF }} ${{ BOT_GITHUB_TOKEN }} + outputs: release_id: ${{ steps.create-draft.outputs.release_id }} - # devOps-Insights: - # name: DevOps Insights - # needs: [verify-head-status, create-draft, run-unit-tests] - # uses: "./.github/workflows/metrics.yaml" - publish-release: name: Publish release needs: [verify-head-status, create-draft] diff --git a/scripts/release.sh b/scripts/render_and_upload_manifests.sh similarity index 53% rename from scripts/release.sh rename to scripts/render_and_upload_manifests.sh index 3fcd427df..16a1e7732 100755 --- a/scripts/release.sh +++ b/scripts/render_and_upload_manifests.sh @@ -11,23 +11,23 @@ set -o pipefail # prevents errors in a pipeline from being masked # BOT_GITHUB_TOKEN - github token used to upload the template yaml uploadFile() { - filePath=${1} - ghAsset=${2} + filePath=${1} + ghAsset=${2} - echo "Uploading ${filePath} as ${ghAsset}" - response=$(curl -s -o output.txt -w "%{http_code}" \ - --request POST --data-binary @"$filePath" \ - -H "Authorization: token $BOT_GITHUB_TOKEN" \ - -H "Content-Type: text/yaml" \ - $ghAsset) - if [[ "$response" != "201" ]]; then - echo "Unable to upload the asset ($filePath): " - echo "HTTP Status: $response" - cat output.txt - exit 1 - else - echo "$filePath uploaded" - fi + echo "Uploading ${filePath} as ${ghAsset}" + response=$(curl -s -o output.txt -w "%{http_code}" \ + --request POST --data-binary @"$filePath" \ + -H "Authorization: token $BOT_GITHUB_TOKEN" \ + -H "Content-Type: text/yaml" \ + $ghAsset) + if [[ "$response" != "201" ]]; then + echo "Unable to upload the asset ($filePath): " + echo "HTTP Status: $response" + cat output.txt + exit 1 + else + echo "$filePath uploaded" + fi } echo "PULL_BASE_REF ${PULL_BASE_REF}" @@ -39,33 +39,34 @@ cat eventing-manager.yaml MODULE_VERSION=${PULL_BASE_REF} make module-build -echo "Generated moduletemplate.yaml:" -cat module-template.yaml +# TODO completly remove the rendering of the module-template from the repository. +# echo "Generated moduletemplate.yaml:" +# cat module-template.yaml echo "Updating github release with eventing-manager.yaml" echo "Finding release id for: ${PULL_BASE_REF}" CURL_RESPONSE=$(curl -w "%{http_code}" -sL \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer $BOT_GITHUB_TOKEN" \ - https://api.github.com/repos/kyma-project/eventing-manager/releases) -JSON_RESPONSE=$(sed '$ d' <<< "${CURL_RESPONSE}") -HTTP_CODE=$(tail -n1 <<< "${CURL_RESPONSE}") + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $BOT_GITHUB_TOKEN" \ + https://api.github.com/repos/kyma-project/eventing-manager/releases) +JSON_RESPONSE=$(sed '$ d' <<<"${CURL_RESPONSE}") +HTTP_CODE=$(tail -n1 <<<"${CURL_RESPONSE}") if [[ "${HTTP_CODE}" != "200" ]]; then - echo "${JSON_RESPONSE}" && exit 1 + echo "${JSON_RESPONSE}" && exit 1 fi echo "Finding release id for: ${PULL_BASE_REF}" RELEASE_ID=$(jq <<<${JSON_RESPONSE} --arg tag "${PULL_BASE_REF}" '.[] | select(.tag_name == $ARGS.named.tag) | .id') -if [ -z "${RELEASE_ID}" ] -then - echo "No release with tag = ${PULL_BASE_REF}" - exit 1 +if [ -z "${RELEASE_ID}" ]; then + echo "No release with tag = ${PULL_BASE_REF}" + exit 1 fi UPLOAD_URL="https://uploads.github.com/repos/kyma-project/eventing-manager/releases/${RELEASE_ID}/assets" uploadFile "eventing-manager.yaml" "${UPLOAD_URL}?name=eventing-manager.yaml" -uploadFile "module-template.yaml" "${UPLOAD_URL}?name=module-template.yaml" +# TODO completly remove the rendering of the module-template from the repository. +# uploadFile "module-template.yaml" "${UPLOAD_URL}?name=module-template.yaml" uploadFile "config/samples/default.yaml" "${UPLOAD_URL}?name=eventing_default_cr.yaml" From e0a307dab0d295a2c4c2e8e265a4f553dd3650d3 Mon Sep 17 00:00:00 2001 From: Korbinian Stoemmer Date: Fri, 15 Dec 2023 13:51:28 +0100 Subject: [PATCH 5/6] enable more linters (#288) * enable containedctx * modify lint target to download golangci-lint * enable testifylint * enable whitespace * enable nonamedreturns * enable perfsprint * enable goerr113 * fix broken build * add cache * generate code * organize code --- .github/workflows/e2e.yml | 8 + .golangci.yaml | 6 - Makefile | 12 +- api/eventing/v1alpha1/fixtures_test.go | 4 +- .../v1alpha1/subscription_conversion.go | 4 +- .../subscription_conversion_unit_test.go | 4 +- .../subscription_webhook_unit_test.go | 4 +- api/operator/v1alpha1/status_test.go | 4 +- .../v1alpha1/zz_generated.deepcopy.go | 2 +- hack/e2e/common/eventing/publisher.go | 17 +- hack/e2e/common/eventing/sinkclient.go | 5 +- hack/e2e/common/eventing/utils.go | 2 +- hack/e2e/common/fixtures/fixtures.go | 1 + .../testenvironment/test_environment.go | 59 +++--- internal/controller/errors/skip_unit_test.go | 18 +- .../subscription/eventmesh/reconciler.go | 24 ++- .../reconciler_internal_integration_test.go | 51 +++-- .../test/reconciler_integration_test.go | 3 +- .../subscription/eventmesh/test/utils.go | 5 +- .../reconciler_integration_test.go | 4 +- .../eventmesh/testwebhookauth/utils.go | 5 +- .../eventing/subscription/eventmesh/utils.go | 4 +- .../subscription/jetstream/matchers_test.go | 1 + .../subscription/jetstream/reconciler.go | 10 +- .../jetstream/reconciler_integration_test.go | 7 +- .../reconciler_internal_unit_test.go | 37 ++-- .../subscription/jetstream/test_utils_test.go | 27 ++- .../operator/eventing/controller.go | 24 ++- .../operator/eventing/controller_test.go | 18 +- .../controller/operator/eventing/domain.go | 12 +- .../operator/eventing/domain_test.go | 16 +- .../controller/operator/eventing/eventmesh.go | 35 ++-- .../operator/eventing/eventmesh_test.go | 29 +-- .../controller/integration_test.go | 7 +- .../operator/eventing/mocks/controller.go | 18 +- .../operator/eventing/mocks/manager.go | 70 ++++++- .../eventing/mocks/nats_config_handler.go | 6 +- internal/controller/operator/eventing/nats.go | 5 +- .../controller/operator/eventing/nats_test.go | 27 +-- .../controller/operator/eventing/unit_test.go | 7 +- .../operator/eventing/utils_test.go | 16 +- pkg/backend/eventmesh/eventmesh.go | 10 +- .../eventmesh/eventmesh_integration_test.go | 17 +- pkg/backend/eventmesh/types.go | 6 +- pkg/backend/eventmesh/utils_unit_test.go | 8 +- pkg/backend/eventtype/parse.go | 9 +- .../jetstream/config_internal_unit_test.go | 4 +- .../jetstream/connection_integration_test.go | 8 +- pkg/backend/jetstream/jetstream.go | 2 +- .../jetstream/jetstream_integration_test.go | 10 +- .../jetstream/jetstream_internal_unit_test.go | 14 +- pkg/backend/jetstream/mocks/Backend.go | 34 +++- .../jetstream/mocks/JetStreamContext.go | 178 +++++++++++++++++- .../jetstream/utils_internal_unit_test.go | 4 +- pkg/backend/metrics/collector.go | 10 +- pkg/backend/sink/validator.go | 17 +- pkg/backend/sink/validator_test.go | 4 +- pkg/backend/utils/eventmesh_utils.go | 3 +- .../events/client/mocks/PublisherManager.go | 34 +++- pkg/ems/httpclient/error_unit_test.go | 1 + pkg/env/config.go | 5 +- pkg/errors/errors.go | 2 +- pkg/errors/errors_unit_test.go | 3 +- pkg/eventing/deployment_test.go | 10 +- pkg/eventing/manager.go | 22 ++- pkg/eventing/manager_test.go | 26 +-- pkg/eventing/mocks/manager.go | 26 ++- pkg/k8s/client.go | 4 +- pkg/k8s/client_test.go | 17 +- pkg/k8s/mocks/client.go | 78 +++++++- pkg/logger/logger_test.go | 6 +- pkg/signals/signals.go | 12 +- .../eventmesh/eventmesh.go | 54 ++---- .../eventmesh/eventmesh_test.go | 8 +- .../jetstream/jetstream.go | 5 +- .../jetstream/jetstream_test.go | 4 - pkg/subscriptionmanager/manager/manager.go | 2 +- .../manager/mocks/manager.go | 14 +- .../mocks/manager_factory.go | 10 +- pkg/utils/utils.go | 5 +- pkg/utils/utils_unit_test.go | 6 +- pkg/watcher/mocks/watcher.go | 10 +- test/utils/integration/integration.go | 76 ++++---- test/utils/utils.go | 9 +- testing/event/cehelper/converter.go | 2 +- testing/subscriber.go | 30 +-- testing/test_helpers.go | 23 ++- 87 files changed, 975 insertions(+), 485 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c9d3343d5..bf176647b 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 ee4bad9b7..cbecb050f 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 5eb988a29..d112b48c0 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 1ee905f21..0ddd7ddbd 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 5e3cb7dff..e0fea0925 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 0fda40c4f..d7134938d 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 c99597fed..596ef7972 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 af39b57b6..e5c61af48 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 a7bd0a7a6..1a8cdd8f8 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 daf560fec..f279076e4 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 a8911b9d1..78ed63d08 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 d718698f5..6486eb7ef 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 4db731945..90bd6484f 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 3c92c831b..6edf86c6e 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 55b528058..c237f0c59 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 b513bb7b1..2ad1d7cd6 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 3d431dab8..533e3285b 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 d74691e3f..4723c7fcc 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 ef1e20c74..f5d829bfd 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 a5f4c5a5e..067ce78c2 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 d1ade3b40..cd637a193 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 286ac1b11..a82650503 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 0017b63bc..c389d56fa 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 8bbc07f15..874215731 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 03695bc8d..ec8dd23a0 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 9ca5e2ee4..bb1a2108e 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 a7120e4e4..772628f2c 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 85494795f..e07f39235 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 620b1aa1c..f85dba1c3 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 581e2e77a..bbe4cb618 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 cf2440474..c6255ef34 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 cd1a092f4..5013f99fb 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 4d0172958..b2765043b 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 3d11f90bb..9420519fb 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 7cc68336e..ecb91c2ee 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 5f61310da..12739e009 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 adc5591af..b6403fb04 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 877c975bf..fca7b3487 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 8cd25e3f6..7dfc87c25 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 72e2bb998..4461528c8 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 418918d3d..03f338ee5 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 99f3fc88b..361d7be61 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 391e5757a..ad7c8a92a 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 9dfeef50a..30fd33289 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 521470fc0..47e4b918a 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 34fad73d3..847cbf50a 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 98af3ecdf..f6dd6adea 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 6988d8c3f..240afb810 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 f470d0e93..36f9b3c5c 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 a9c509744..277c03de8 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 ac1399ab7..6739de4c2 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 c3e983145..74fd1a325 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 a2150ef35..c23f16b24 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 eec0628bb..f1f0cdc46 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 f83cf2a7d..6417c665e 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 b7cc2e40e..bf55f8b11 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 022700510..e2a7f5295 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 7b1649fe2..8c62dee28 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 c575f6f7b..a10f800a4 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 70fafe807..5880dbb6e 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 d4eabf1fd..5604f5cb3 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 ea0580b0b..51d74aa04 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 a520fa6d9..b420ef94b 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 421eea390..a134237a3 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 fde4d4e40..65397e0ae 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 aefe0ad75..544de214c 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 276ce6666..3d3ca7e08 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 6d39e4f96..08fef405a 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 99269c552..6f9990097 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 87946f13c..b05dd2345 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 3064cefb5..c00c9cd02 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 0f60480bc..4f84f3437 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 b766056a2..f3e7bd201 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 89c5fa077..0b9f2ceb2 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 f064ac656..b15a471d7 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 0edf6eb68..825d8bb59 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 9f6052abb..5e7285b8e 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 25b716cdf..b31299a2a 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 1eb0e996e..9e7d9b182 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 f1a09b400..97bfd8720 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 7a338c2fa..9f67f0635 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 4341c7ec9..96b0f5848 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 0cf9999de..490bf840b 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 2e4a804f4..93f58ee93 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 7c3981083..92f9123b0 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 1d5dde121..d6919646a 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 493abe841..ee7e3a3e2 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), } } } From 1817db97b5daa712da92f72d9e67019fbf137f52 Mon Sep 17 00:00:00 2001 From: Friedrich Date: Fri, 15 Dec 2023 17:49:25 +0100 Subject: [PATCH 6/6] Cherry pick fixes to release channel (#349) * fix reference to release name (#342) * add missing env vars for IMG and MODULE_REGISTERY (#343) * add missing env vars for IMG and MODULE_REGISTERY * remove arg * add KUSTOMIZE_VERSION * fix wrong token (#344) * add missing env vars for IMG and MODULE_REGISTERY * remove arg * replace the BOT_GITHUB_TOKEN with the GITHUB_TOKEN * remove call of make module-build (#347) * remove call of make module-build We really only need to render the manifests so lets remove module-build. * revert removal of MODULE_REGISTERY * fix spelling of env var name (#348) --- .github/workflows/create-release.yml | 9 ++++++--- scripts/render_and_upload_manifests.sh | 9 ++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 07dd8687a..af73a0d33 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -66,10 +66,13 @@ jobs: - name: Create and upload eventing-manager.yaml and eventing-default-cr.yaml env: - PULL_BASE_REF: ${{ PULL_BASE_REF }} - BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} + PULL_BASE_REF: ${{ github.event.inputs.name }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + IMG: "europe-docker.pkg.dev/kyma-project/prod/eventing-manager:${{ github.event.inputs.name }}" + MODULE_REGISTRY: "europe-docker.pkg.dev/kyma-project/prod/unsigned" + KUSTOMIZE_VERSION: "v4.5.6" run: | - ./scripts/render_and_upload_manifests.sh ${{ PULL_BASE_REF }} ${{ BOT_GITHUB_TOKEN }} + ./scripts/render_and_upload_manifests.sh outputs: release_id: ${{ steps.create-draft.outputs.release_id }} diff --git a/scripts/render_and_upload_manifests.sh b/scripts/render_and_upload_manifests.sh index 16a1e7732..8ca2f33ab 100755 --- a/scripts/render_and_upload_manifests.sh +++ b/scripts/render_and_upload_manifests.sh @@ -8,7 +8,7 @@ set -o pipefail # prevents errors in a pipeline from being masked # Expected variables: # PULL_BASE_REF - name of the tag -# BOT_GITHUB_TOKEN - github token used to upload the template yaml +# GITHUB_TOKEN - github token used to upload the template yaml uploadFile() { filePath=${1} @@ -17,7 +17,7 @@ uploadFile() { echo "Uploading ${filePath} as ${ghAsset}" response=$(curl -s -o output.txt -w "%{http_code}" \ --request POST --data-binary @"$filePath" \ - -H "Authorization: token $BOT_GITHUB_TOKEN" \ + -H "Authorization: token $GITHUB_TOKEN" \ -H "Content-Type: text/yaml" \ $ghAsset) if [[ "$response" != "201" ]]; then @@ -37,8 +37,7 @@ MODULE_VERSION=${PULL_BASE_REF} make render-manifest echo "Generated eventing-manager.yaml:" cat eventing-manager.yaml -MODULE_VERSION=${PULL_BASE_REF} make module-build - +# MODULE_VERSION=${PULL_BASE_REF} make module-build # TODO completly remove the rendering of the module-template from the repository. # echo "Generated moduletemplate.yaml:" # cat module-template.yaml @@ -48,7 +47,7 @@ echo "Updating github release with eventing-manager.yaml" echo "Finding release id for: ${PULL_BASE_REF}" CURL_RESPONSE=$(curl -w "%{http_code}" -sL \ -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer $BOT_GITHUB_TOKEN" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ https://api.github.com/repos/kyma-project/eventing-manager/releases) JSON_RESPONSE=$(sed '$ d' <<<"${CURL_RESPONSE}") HTTP_CODE=$(tail -n1 <<<"${CURL_RESPONSE}")