Skip to content

Commit

Permalink
feat: allow integration tests to run concurrently
Browse files Browse the repository at this point in the history
  • Loading branch information
KevFan committed May 8, 2024
1 parent 1336391 commit 9794f9a
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 13 deletions.
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
74 changes: 64 additions & 10 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package controllers

import (
"encoding/json"
"os"
"path/filepath"
"testing"
Expand All @@ -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"
Expand All @@ -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")},
Expand All @@ -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,
Expand Down Expand Up @@ -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")
})

Expand Down

0 comments on commit 9794f9a

Please sign in to comment.