-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1710 from prafull01/webhook-test
✨ Add scaffolding for the webhook test suite (go/v3-alpha)
- Loading branch information
Showing
9 changed files
with
818 additions
and
0 deletions.
There are no files selected for viewing
225 changes: 225 additions & 0 deletions
225
pkg/plugin/v3/scaffolds/internal/templates/config/api/webhook_suitetest.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
package api | ||
|
||
import ( | ||
"fmt" | ||
"path/filepath" | ||
|
||
"sigs.k8s.io/kubebuilder/pkg/model/file" | ||
) | ||
|
||
var _ file.Template = &WebhookSuite{} | ||
var _ file.Inserter = &WebhookSuite{} | ||
|
||
// WebhookSuite scaffolds the webhook_suite.go file to setup the webhook test | ||
type WebhookSuite struct { | ||
file.TemplateMixin | ||
file.MultiGroupMixin | ||
file.BoilerplateMixin | ||
file.ResourceMixin | ||
|
||
// BaseDirectoryRelativePath define the Path for the base directory when it is multigroup | ||
BaseDirectoryRelativePath string | ||
} | ||
|
||
// SetTemplateDefaults implements file.Template | ||
func (f *WebhookSuite) SetTemplateDefaults() error { | ||
if f.Path == "" { | ||
if f.MultiGroup { | ||
if f.Resource.Group != "" { | ||
f.Path = filepath.Join("apis", "%[group]", "%[version]", "webhook_suite_test.go") | ||
} else { | ||
f.Path = filepath.Join("apis", "%[version]", "webhook_suite_test.go") | ||
} | ||
} else { | ||
f.Path = filepath.Join("api", "%[version]", "webhook_suite_test.go") | ||
} | ||
} | ||
f.Path = f.Resource.Replacer().Replace(f.Path) | ||
|
||
f.TemplateBody = fmt.Sprintf(webhookTestSuiteTemplate, | ||
file.NewMarkerFor(f.Path, importMarker), | ||
file.NewMarkerFor(f.Path, addSchemeMarker), | ||
file.NewMarkerFor(f.Path, addWebhookManagerMarker), | ||
"%s", | ||
"%d", | ||
) | ||
|
||
// If is multigroup the path needs to be ../../.. since it has the group dir. | ||
f.BaseDirectoryRelativePath = `"..", ".."` | ||
if f.MultiGroup && f.Resource.Group != "" { | ||
f.BaseDirectoryRelativePath = `"..", "..",".."` | ||
} | ||
|
||
return nil | ||
} | ||
|
||
const ( | ||
// TODO: admission webhook versions should be based on the input of the user. For More Info #1664 | ||
admissionImportAlias = "admissionv1beta1" | ||
admissionPath = "k8s.io/api/admission/v1beta1" | ||
importMarker = "imports" | ||
addWebhookManagerMarker = "webhook" | ||
addSchemeMarker = "scheme" | ||
) | ||
|
||
// GetMarkers implements file.Inserter | ||
func (f *WebhookSuite) GetMarkers() []file.Marker { | ||
return []file.Marker{ | ||
file.NewMarkerFor(f.Path, importMarker), | ||
file.NewMarkerFor(f.Path, addSchemeMarker), | ||
file.NewMarkerFor(f.Path, addWebhookManagerMarker), | ||
} | ||
} | ||
|
||
const ( | ||
apiImportCodeFragment = `%s "%s" | ||
` | ||
addschemeCodeFragment = `err = %s.AddToScheme(scheme ) | ||
Expect(err).NotTo(HaveOccurred()) | ||
` | ||
addWebhookManagerCodeFragment = `err = (&%s{}).SetupWebhookWithManager(mgr) | ||
Expect(err).NotTo(HaveOccurred()) | ||
` | ||
) | ||
|
||
// GetCodeFragments implements file.Inserter | ||
func (f *WebhookSuite) GetCodeFragments() file.CodeFragmentsMap { | ||
fragments := make(file.CodeFragmentsMap, 3) | ||
|
||
// Generate import code fragments | ||
imports := make([]string, 0) | ||
imports = append(imports, fmt.Sprintf(apiImportCodeFragment, admissionImportAlias, admissionPath)) | ||
|
||
// Generate add scheme code fragments | ||
addScheme := make([]string, 0) | ||
addScheme = append(addScheme, fmt.Sprintf(addschemeCodeFragment, admissionImportAlias)) | ||
|
||
// Generate add webhookManager code fragments | ||
addWebhookManager := make([]string, 0) | ||
addWebhookManager = append(addWebhookManager, fmt.Sprintf(addWebhookManagerCodeFragment, f.Resource.Kind)) | ||
|
||
// Only store code fragments in the map if the slices are non-empty | ||
if len(addWebhookManager) != 0 { | ||
fragments[file.NewMarkerFor(f.Path, addWebhookManagerMarker)] = addWebhookManager | ||
} | ||
if len(imports) != 0 { | ||
fragments[file.NewMarkerFor(f.Path, importMarker)] = imports | ||
} | ||
if len(addScheme) != 0 { | ||
fragments[file.NewMarkerFor(f.Path, addSchemeMarker)] = addScheme | ||
} | ||
|
||
return fragments | ||
} | ||
|
||
const ( | ||
webhookTestSuiteTemplate = ` | ||
package {{ .Resource.Version }} | ||
import ( | ||
"path/filepath" | ||
"testing" | ||
"fmt" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
%s | ||
"k8s.io/client-go/kubernetes/scheme" | ||
"k8s.io/client-go/rest" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/envtest" | ||
"sigs.k8s.io/controller-runtime/pkg/envtest/printer" | ||
logf "sigs.k8s.io/controller-runtime/pkg/log" | ||
"sigs.k8s.io/controller-runtime/pkg/log/zap" | ||
) | ||
// These tests use Ginkgo (BDD-style Go testing framework). Refer to | ||
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. | ||
var cfg *rest.Config | ||
var k8sClient client.Client | ||
var testEnv *envtest.Environment | ||
var stopCh = make(chan struct{}) | ||
func TestAPIs(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecsWithDefaultAndCustomReporters(t, | ||
"Webhook Suite", | ||
[]Reporter{printer.NewlineReporter{}}) | ||
} | ||
var _ = BeforeSuite(func(done Done) { | ||
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) | ||
By("bootstrapping test environment") | ||
testEnv = &envtest.Environment{ | ||
CRDDirectoryPaths: []string{filepath.Join({{ .BaseDirectoryRelativePath }}, "config", "crd", "bases")}, | ||
WebhookInstallOptions: envtest.WebhookInstallOptions{ | ||
DirectoryPaths: []string{filepath.Join({{ .BaseDirectoryRelativePath }}, "config", "webhook")}, | ||
}, | ||
} | ||
var err error | ||
cfg, err = testEnv.Start() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(cfg).NotTo(BeNil()) | ||
scheme := runtime.NewScheme() | ||
err = AddToScheme(scheme) | ||
Expect(err).NotTo(HaveOccurred()) | ||
%s | ||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(k8sClient).NotTo(BeNil()) | ||
// start webhook server using Manager | ||
webhookInstallOptions := &testEnv.WebhookInstallOptions | ||
mgr, err := ctrl.NewManager(cfg, ctrl.Options{ | ||
Scheme: scheme, | ||
Host: webhookInstallOptions.LocalServingHost, | ||
Port: webhookInstallOptions.LocalServingPort, | ||
CertDir: webhookInstallOptions.LocalServingCertDir, | ||
LeaderElection: false, | ||
MetricsBindAddress: "0", | ||
}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
%s | ||
go func() { | ||
err = mgr.Start(stopCh) | ||
if err != nil { | ||
Expect(err).NotTo(HaveOccurred()) | ||
} | ||
}() | ||
// wait for the webhook server to get ready | ||
dialer := &net.Dialer{Timeout: time.Second} | ||
addrPort := fmt.Sprintf("%s:%s", 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 | ||
}).Should(Succeed()) | ||
close(done) | ||
}, 60) | ||
var _ = AfterSuite(func() { | ||
close(stopCh) | ||
By("tearing down the test environment") | ||
err := testEnv.Stop() | ||
Expect(err).NotTo(HaveOccurred()) | ||
}) | ||
` | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
testdata/project-v3-multigroup/apis/crew/v1/webhook_suite_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package v1 | ||
|
||
import ( | ||
"crypto/tls" | ||
"fmt" | ||
"net" | ||
"path/filepath" | ||
"testing" | ||
"time" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
|
||
admissionv1beta1 "k8s.io/api/admission/v1beta1" | ||
// +kubebuilder:scaffold:imports | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/client-go/rest" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/envtest" | ||
"sigs.k8s.io/controller-runtime/pkg/envtest/printer" | ||
logf "sigs.k8s.io/controller-runtime/pkg/log" | ||
"sigs.k8s.io/controller-runtime/pkg/log/zap" | ||
) | ||
|
||
// These tests use Ginkgo (BDD-style Go testing framework). Refer to | ||
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. | ||
|
||
var cfg *rest.Config | ||
var k8sClient client.Client | ||
var testEnv *envtest.Environment | ||
var stopCh = make(chan struct{}) | ||
|
||
func TestAPIs(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
|
||
RunSpecsWithDefaultAndCustomReporters(t, | ||
"Webhook Suite", | ||
[]Reporter{printer.NewlineReporter{}}) | ||
} | ||
|
||
var _ = BeforeSuite(func(done Done) { | ||
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) | ||
|
||
By("bootstrapping test environment") | ||
testEnv = &envtest.Environment{ | ||
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, | ||
WebhookInstallOptions: envtest.WebhookInstallOptions{ | ||
DirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, | ||
}, | ||
} | ||
|
||
var err error | ||
cfg, err = testEnv.Start() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(cfg).NotTo(BeNil()) | ||
|
||
scheme := runtime.NewScheme() | ||
err = AddToScheme(scheme) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
err = admissionv1beta1.AddToScheme(scheme) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
// +kubebuilder:scaffold:scheme | ||
|
||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(k8sClient).NotTo(BeNil()) | ||
|
||
// start webhook server using Manager | ||
webhookInstallOptions := &testEnv.WebhookInstallOptions | ||
mgr, err := ctrl.NewManager(cfg, ctrl.Options{ | ||
Scheme: scheme, | ||
Host: webhookInstallOptions.LocalServingHost, | ||
Port: webhookInstallOptions.LocalServingPort, | ||
CertDir: webhookInstallOptions.LocalServingCertDir, | ||
LeaderElection: false, | ||
MetricsBindAddress: "0", | ||
}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
err = (&Captain{}).SetupWebhookWithManager(mgr) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
// +kubebuilder:scaffold:webhook | ||
|
||
go func() { | ||
err = mgr.Start(stopCh) | ||
if err != nil { | ||
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 | ||
} | ||
conn.Close() | ||
return nil | ||
}).Should(Succeed()) | ||
|
||
close(done) | ||
}, 60) | ||
|
||
var _ = AfterSuite(func() { | ||
close(stopCh) | ||
By("tearing down the test environment") | ||
err := testEnv.Stop() | ||
Expect(err).NotTo(HaveOccurred()) | ||
}) |
Oops, something went wrong.