func RunFunctionalTestSuiteWithWebhooks()

in oracle/controllers/testhelpers/envtest.go [152:289]


func RunFunctionalTestSuiteWithWebhooks(
	t *testing.T,
	k8sClient *client.Client,
	k8sManager *ctrl.Manager,
	schemeBuilders []*runtime.SchemeBuilder,
	description string,
	controllers func() []Reconciler,
	crdPaths []string,
	webhooks func() []Webhook,
	admissionWebhookHandlers func() map[string]AdmissionWebhook,
	webhookPaths []string,
) {
	// Define the test environment.
	crdPaths = append(crdPaths, filepath.Join("config", "crd", "bases"), filepath.Join("config", "crd", "testing"))

	var testEnvLock sync.Mutex
	testEnv := envtest.Environment{
		CRDDirectoryPaths:        crdPaths,
		ControlPlaneStartTimeout: 60 * time.Second, // Default 20s may not be enough for test pods.
	}
	// Set up webhooks
	if len(webhookPaths) != 0 {
		testEnv.WebhookInstallOptions = envtest.WebhookInstallOptions{
			Paths:                    webhookPaths,
			IgnoreErrorIfPathMissing: true,
		}
	}
	if runfiles, err := bazel.RunfilesPath(); err == nil {
		// Running with bazel test, find binary assets in runfiles.
		testEnv.BinaryAssetsDirectory = filepath.Join(runfiles, "external/kubebuilder_tools/bin")
	}

	// k8s 1.21 introduced graceful shutdown so testEnv wont shutdown if we
	// keep a connection open. By using a context with cancel we can
	// shutdown our managers before we try to shutdown the testEnv and
	// ensure no hanging connections keep the apiserver from stopping.
	mgrCtx, mgrCancel := context.WithCancel(ctrl.SetupSignalHandler())

	BeforeSuite(func(done Done) {
		testEnvLock.Lock()
		defer testEnvLock.Unlock()
		klog.SetOutput(GinkgoWriter)
		logf.SetLogger(klogr.NewWithOptions(klogr.WithFormat(klogr.FormatKlog)))
		log := logf.FromContext(nil)

		var err error
		var cfg *rest.Config

		var backoff = wait.Backoff{
			Steps:    6,
			Duration: 100 * time.Millisecond,
			Factor:   5.0,
			Jitter:   0.1,
		}
		Expect(retry.OnError(backoff, func(error) bool { return true }, func() error {
			cfg, err = testEnv.Start()
			if err != nil {
				log.Error(err, "Envtest startup failed, retrying")
			}
			return err
		})).Should(Succeed())

		for _, sb := range schemeBuilders {
			utilruntime.Must(sb.AddToScheme(scheme.Scheme))
		}

		if len(webhookPaths) != 0 {
			// start webhook server using Manager
			webhookInstallOptions := &testEnv.WebhookInstallOptions
			*k8sManager, err = ctrl.NewManager(cfg, ctrl.Options{
				Scheme:             scheme.Scheme,
				Host:               webhookInstallOptions.LocalServingHost,
				Port:               webhookInstallOptions.LocalServingPort,
				CertDir:            webhookInstallOptions.LocalServingCertDir,
				LeaderElection:     false,
				MetricsBindAddress: "0",
			})
			Expect(err).NotTo(HaveOccurred())
		} else {
			*k8sManager, err = ctrl.NewManager(cfg, ctrl.Options{
				Scheme:             scheme.Scheme,
				MetricsBindAddress: "0",
			})
			Expect(err).ToNot(HaveOccurred())
		}

		*k8sClient = (*k8sManager).GetClient()

		// Install controllers into the manager.
		for _, c := range controllers() {
			Expect(c.SetupWithManager(*k8sManager)).To(Succeed())
		}
		// Install webhooks into the manager.
		for _, c := range webhooks() {
			Expect(c.SetupWebhookWithManager(*k8sManager)).To(Succeed())
		}
		// Register admission webhook handlers into the webhook in the manager
		for path, handler := range admissionWebhookHandlers() {
			(*k8sManager).GetWebhookServer().Register(path, handler)
		}

		go func() {
			defer GinkgoRecover()
			err = (*k8sManager).Start(mgrCtx)
			Expect(err).ToNot(HaveOccurred())
		}()

		if len(webhookPaths) != 0 {
			// wait for the webhook server to get ready
			webhookInstallOptions := &testEnv.WebhookInstallOptions
			dialer := &net.Dialer{Timeout: 60 * 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
				}
				conn.Close()
				return nil
			}, 60*time.Second, 5*time.Second).Should(Succeed())
		}

		close(done)
	}, 600)

	AfterSuite(func() {
		testEnvLock.Lock()
		defer testEnvLock.Unlock()
		By("Stopping control plane")
		mgrCancel()
		Expect(testEnv.Stop()).To(Succeed())
	})

	RegisterFailHandler(Fail)
	RunSpecsWithDefaultAndCustomReporters(t,
		description,
		[]Reporter{printer.NewlineReporter{}})
}