diff --git a/Makefile b/Makefile index ab54bde2..691f3539 100644 --- a/Makefile +++ b/Makefile @@ -91,6 +91,8 @@ IMG ?= $(DEFAULT_IMG) UNIT_DIRS := ./pkg/... ./api/... INTEGRATION_TEST_SUITE_PATHS := ./controllers/... INTEGRATION_COVER_PKGS := ./pkg/...,./controllers/...,./api/... +INTEGRATION_TEST_NUM_CORES ?= 4 +INTEGRATION_TEST_NUM_PROCESSES ?= 10 # Limitador Operator replaced version DEFAULT_REPLACES_VERSION = 0.0.0-alpha @@ -228,8 +230,15 @@ test-integration: clean-cov generate fmt vet ginkgo ## Run Integration tests. --coverpkg $(INTEGRATION_COVER_PKGS) \ --output-dir $(PROJECT_PATH)/coverage/integration \ --coverprofile cover.out \ - --fail-fast \ -v \ + --compilers=$(INTEGRATION_TEST_NUM_CORES) \ + --procs=$(INTEGRATION_TEST_NUM_PROCESSES) \ + --randomize-all \ + --randomize-suites \ + --fail-on-pending \ + --keep-going \ + --race \ + --trace \ $(INTEGRATION_TEST_SUITE_PATHS) ifdef TEST_NAME @@ -249,8 +258,8 @@ run: export LOG_MODE = development run: manifests generate fmt vet ## Run a controller from your host. go run ./main.go -docker-build: ## Build docker image with the manager. - docker build -t $(IMG) . +docker-build: ## Build docker image with the manager. Explicitly load docker image as using Podman runtime may otherwise just keep the image in cache instead + docker build -t $(IMG) . --load docker-push: ## Push docker image with the manager. docker push $(IMG) diff --git a/controllers/suite_test.go b/controllers/suite_test.go index a985ed77..29f7c77b 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -17,6 +17,7 @@ limitations under the License. package controllers import ( + "encoding/json" "os" "path/filepath" "testing" @@ -25,7 +26,9 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -51,7 +54,18 @@ func TestAPIs(t *testing.T) { RunSpecs(t, "Controller Suite") } -var _ = BeforeSuite(func() { +// SharedConfig contains minimum cluster connection config that can be safely marshalled as rest.Config is unsafe to marshall +type SharedConfig struct { + Host string `json:"host"` + TLSClientConfig struct { + Insecure bool `json:"insecure"` + CertData []uint8 `json:"certData,omitempty"` + KeyData []uint8 `json:"keyData,omitempty"` + CAData []uint8 `json:"caData,omitempty"` + } `json:"tlsClientConfig"` +} + +var _ = SynchronizedBeforeSuite(func() []byte { By("bootstrapping test environment") testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, @@ -63,14 +77,7 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = limitadorv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) + Expect(limitadorv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) mgr, err := ctrl.NewManager(cfg, ctrl.Options{ Scheme: scheme.Scheme, @@ -101,9 +108,56 @@ var _ = BeforeSuite(func() { Expect(err).ToNot(HaveOccurred()) }() + // Create a shared configuration struct to pass Config information to all sub processes + sharedCfg := SharedConfig{ + Host: cfg.Host, + TLSClientConfig: struct { + Insecure bool `json:"insecure"` + CertData []uint8 `json:"certData,omitempty"` + KeyData []uint8 `json:"keyData,omitempty"` + CAData []uint8 `json:"caData,omitempty"` + }{ + Insecure: cfg.TLSClientConfig.Insecure, + CertData: cfg.TLSClientConfig.CertData, + KeyData: cfg.TLSClientConfig.KeyData, + CAData: cfg.TLSClientConfig.CAData, + }, + } + + // Marshal the shared configuration struct + data, err := json.Marshal(sharedCfg) + Expect(err).NotTo(HaveOccurred()) + + return data +}, func(data []byte) { + // Unmarshal the shared configuration struct + var sharedCfg SharedConfig + Expect(json.Unmarshal(data, &sharedCfg)).To(Succeed()) + + // Create the rest.Config object from the shared configuration + cfg := &rest.Config{ + Host: sharedCfg.Host, + TLSClientConfig: rest.TLSClientConfig{ + Insecure: sharedCfg.TLSClientConfig.Insecure, + CertData: sharedCfg.TLSClientConfig.CertData, + KeyData: sharedCfg.TLSClientConfig.KeyData, + CAData: sharedCfg.TLSClientConfig.CAData, + }, + } + + // Create new scheme for each client + s := runtime.NewScheme() + Expect(scheme.AddToScheme(s)).To(Succeed()) + err := limitadorv1alpha1.AddToScheme(s) + Expect(err).NotTo(HaveOccurred()) + + // Set the shared configuration + k8sClient, err = client.New(cfg, client.Options{Scheme: s}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) }) -var _ = AfterSuite(func() { +var _ = SynchronizedAfterSuite(func() {}, func() { By("tearing down the test environment") })