Files
mariadb-operator/internal/webhook/v1alpha1/webhook_suite_test.go
2025-06-26 21:13:53 +02:00

186 lines
5.4 KiB
Go

package v1alpha1
import (
"context"
"crypto/tls"
"fmt"
"net"
"os"
"path/filepath"
"testing"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"go.uber.org/zap/zapcore"
certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
log "sigs.k8s.io/controller-runtime/pkg/log"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"github.com/mariadb-operator/mariadb-operator/api/v1alpha1"
// +kubebuilder:scaffold:imports
)
var (
ctx context.Context
cancel context.CancelFunc
k8sClient client.Client
testEnv *envtest.Environment
testCtx = context.Background()
testNamespace = "default"
)
func TestAPIs(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Webhook Suite")
}
var _ = BeforeSuite(func() {
log.SetLogger(zap.New(
zap.WriteTo(GinkgoWriter),
zap.UseDevMode(true),
zap.Level(zapcore.InfoLevel),
))
ctx, cancel = context.WithCancel(context.TODO())
var err error
scheme := runtime.NewScheme()
err = v1alpha1.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())
Expect(admissionv1.AddToScheme(scheme)).NotTo(HaveOccurred())
Expect(monitoringv1.AddToScheme(scheme)).NotTo(HaveOccurred())
Expect(certmanagerv1.AddToScheme(scheme)).NotTo(HaveOccurred())
// +kubebuilder:scaffold:scheme
By("Bootstrapping test environment")
testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")},
ErrorIfCRDPathMissing: false,
WebhookInstallOptions: envtest.WebhookInstallOptions{
Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")},
},
UseExistingCluster: ptr.To(false),
}
// Retrieve the first found binary directory to allow running tests from IDEs
if getFirstFoundEnvTestBinaryDir() != "" {
testEnv.BinaryAssetsDirectory = getFirstFoundEnvTestBinaryDir()
}
cfg, err := testEnv.Start()
Expect(err).NotTo(HaveOccurred())
Expect(cfg).NotTo(BeNil())
DeferCleanup(testEnv.Stop)
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())
webhookInstallOptions := &testEnv.WebhookInstallOptions
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
LeaderElection: false,
Metrics: metricsserver.Options{
BindAddress: "0",
},
WebhookServer: webhook.NewServer(webhook.Options{
Host: webhookInstallOptions.LocalServingHost,
Port: webhookInstallOptions.LocalServingPort,
CertDir: webhookInstallOptions.LocalServingCertDir,
}),
})
Expect(err).NotTo(HaveOccurred())
err = SetupMariaDBWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupMaxScaleWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupBackupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupPhysicalBackupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupRestoreWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupConnectionWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupUserWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupGrantWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupDatabaseWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = SetupSqlJobWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
// +kubebuilder:scaffold:webhook
go func() {
defer GinkgoRecover()
err = mgr.Start(ctx)
Expect(err).NotTo(HaveOccurred())
}()
// wait for the webhook server to get ready.
dialer := &net.Dialer{Timeout: time.Second}
addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
Eventually(func() error {
conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return err
}
return conn.Close()
}).Should(Succeed())
})
var _ = AfterSuite(func() {
By("tearing down the test environment")
cancel()
err := testEnv.Stop()
Expect(err).NotTo(HaveOccurred())
})
// getFirstFoundEnvTestBinaryDir locates the first binary in the specified path.
// ENVTEST-based tests depend on specific binaries, usually located in paths set by
// controller-runtime. When running tests directly (e.g., via an IDE) without using
// Makefile targets, the 'BinaryAssetsDirectory' must be explicitly configured.
//
// This function streamlines the process by finding the required binaries, similar to
// setting the 'KUBEBUILDER_ASSETS' environment variable. To ensure the binaries are
// properly set up, run 'make setup-envtest' beforehand.
func getFirstFoundEnvTestBinaryDir() string {
basePath := filepath.Join("..", "..", "..", "bin", "k8s")
entries, err := os.ReadDir(basePath)
if err != nil {
logf.Log.Error(err, "Failed to read directory", "path", basePath)
return ""
}
for _, entry := range entries {
if entry.IsDir() {
return filepath.Join(basePath, entry.Name())
}
}
return ""
}