Skip to content

Commit

Permalink
Use the webhook server in e2e tests (#2265)
Browse files Browse the repository at this point in the history
* Use the webhook server in e2e tests
  • Loading branch information
barkbay committed Dec 17, 2019
1 parent 65e2c96 commit 1c6fb41
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 44 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ e2e-local:
--auto-port-forwarding \
--local \
--log-verbosity=$(LOG_VERBOSITY) \
--ignore-webhook-failures \
--test-timeout=$(TEST_TIMEOUT)
@E2E_JSON=$(E2E_JSON) test/e2e/run.sh -run "$(TESTS_MATCH)" -args -testContextPath $(LOCAL_E2E_CTX)

Expand Down
13 changes: 10 additions & 3 deletions config/e2e/global_operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ spec:
requests:
cpu: 100m
memory: 20Mi
readinessProbe:
httpGet:
path: /validate-elasticsearch-k8s-elastic-co-v1-elasticsearch
port: webhook-server
scheme: HTTPS
failureThreshold: 3
periodSeconds: 5
ports:
- containerPort: 9443
name: webhook-server
Expand Down Expand Up @@ -213,7 +220,7 @@ webhooks:
namespace: {{ .GlobalOperator.Namespace }}
# this is the path controller-runtime automatically generates
path: /validate-elasticsearch-k8s-elastic-co-v1beta1-elasticsearch
failurePolicy: Ignore
failurePolicy: {{ if .IgnoreWebhookFailures }}Ignore{{ else }}Fail{{ end }}
name: elastic-es-validation.k8s.elastic.co
rules:
- apiGroups:
Expand All @@ -232,7 +239,7 @@ webhooks:
namespace: {{ .GlobalOperator.Namespace }}
# this is the path controller-runtime automatically generates
path: /validate-elasticsearch-k8s-elastic-co-v1-elasticsearch
failurePolicy: Ignore
failurePolicy: {{ if .IgnoreWebhookFailures }}Ignore{{ else }}Fail{{ end }}
name: elastic-es-validation.k8s.elastic.co
rules:
- apiGroups:
Expand All @@ -255,4 +262,4 @@ spec:
- port: 443
targetPort: 9443
selector:
control-plane: elastic-operator
control-plane: {{ .GlobalOperator.Name }}
36 changes: 19 additions & 17 deletions test/e2e/cmd/run/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,24 @@ import (
)

type runFlags struct {
managedNamespaces []string
e2eImage string
elasticStackVersion string
kubeConfig string
operatorImage string
testContextOutPath string
testLicense string
scratchDirRoot string
testRegex string
testRunName string
commandTimeout time.Duration
autoPortForwarding bool
skipCleanup bool
local bool
logToFile bool
logVerbosity int
testTimeout time.Duration
managedNamespaces []string
e2eImage string
elasticStackVersion string
kubeConfig string
operatorImage string
testContextOutPath string
testLicense string
scratchDirRoot string
testRegex string
testRunName string
commandTimeout time.Duration
autoPortForwarding bool
skipCleanup bool
local bool
logToFile bool
ignoreWebhookFailures bool
logVerbosity int
testTimeout time.Duration
}

var log logr.Logger
Expand Down Expand Up @@ -78,6 +79,7 @@ func Command() *cobra.Command {
cmd.Flags().StringVar(&flags.testRunName, "test-run-name", randomTestRunName(), "Name of this test run")
cmd.Flags().DurationVar(&flags.testTimeout, "test-timeout", 5*time.Minute, "Timeout before failing a test")
cmd.Flags().BoolVar(&flags.logToFile, "log-to-file", false, "Specifies if should log test output to file. Disabled by default.")
cmd.Flags().BoolVar(&flags.ignoreWebhookFailures, "ignore-webhook-failures", false, "Specifies if webhook errors should be ignored. Useful when running test locally. False by default")
logutil.BindFlags(cmd.PersistentFlags())

// enable setting flags via environment variables
Expand Down
11 changes: 6 additions & 5 deletions test/e2e/cmd/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,12 @@ func (h *helper) initTestContext() error {
},
ManagedNamespaces: make([]string, len(h.managedNamespaces)),
},
OperatorImage: h.operatorImage,
TestLicense: h.testLicense,
TestRegex: h.testRegex,
TestRun: h.testRunName,
TestTimeout: h.testTimeout,
OperatorImage: h.operatorImage,
TestLicense: h.testLicense,
TestRegex: h.testRegex,
TestRun: h.testRunName,
TestTimeout: h.testTimeout,
IgnoreWebhookFailures: h.ignoreWebhookFailures,
}

for i, ns := range h.managedNamespaces {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/es/naming_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func testRejectionOfLongName(t *testing.T) {
err := k.Client.Create(obj)
if err != nil {
// validating webhook is active and rejected the request
require.Contains(t, err.Error(), `admission webhook "validation.elasticsearch.elastic.co" denied the request`)
require.Contains(t, err.Error(), `admission webhook "elastic-es-validation.k8s.elastic.co" denied the request`)
return
}

Expand Down
34 changes: 18 additions & 16 deletions test/e2e/test/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ func initializeContext() {

func defaultContext() Context {
return Context{
AutoPortForwarding: false,
ElasticStackVersion: defaultElasticStackVersion,
AutoPortForwarding: false,
ElasticStackVersion: defaultElasticStackVersion,
IgnoreWebhookFailures: false,
GlobalOperator: ClusterResource{
Name: "elastic-global-operator",
Namespace: "elastic-system",
Expand All @@ -80,20 +81,21 @@ func defaultContext() Context {

// Context encapsulates data about a specific test run
type Context struct {
GlobalOperator ClusterResource `json:"global_operator"`
NamespaceOperator NamespaceOperator `json:"namespace_operator"`
E2EImage string `json:"e2e_image"`
E2ENamespace string `json:"e2e_namespace"`
E2EServiceAccount string `json:"e2e_service_account"`
ElasticStackVersion string `json:"elastic_stack_version"`
LogVerbosity int `json:"log_verbosity"`
OperatorImage string `json:"operator_image"`
TestLicense string `json:"test_license"`
TestRegex string `json:"test_regex"`
TestRun string `json:"test_run"`
TestTimeout time.Duration `json:"test_timeout"`
AutoPortForwarding bool `json:"auto_port_forwarding"`
Local bool `json:"local"`
GlobalOperator ClusterResource `json:"global_operator"`
NamespaceOperator NamespaceOperator `json:"namespace_operator"`
E2EImage string `json:"e2e_image"`
E2ENamespace string `json:"e2e_namespace"`
E2EServiceAccount string `json:"e2e_service_account"`
ElasticStackVersion string `json:"elastic_stack_version"`
LogVerbosity int `json:"log_verbosity"`
OperatorImage string `json:"operator_image"`
TestLicense string `json:"test_license"`
TestRegex string `json:"test_regex"`
TestRun string `json:"test_run"`
TestTimeout time.Duration `json:"test_timeout"`
AutoPortForwarding bool `json:"auto_port_forwarding"`
Local bool `json:"local"`
IgnoreWebhookFailures bool `json:"ignore_webhook_failures"`
}

// ManagedNamespace returns the nth managed namespace.
Expand Down
27 changes: 25 additions & 2 deletions test/e2e/test/elasticsearch/steps_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import (
"testing"

esv1 "github.com/elastic/cloud-on-k8s/pkg/apis/elasticsearch/v1"
"github.com/elastic/cloud-on-k8s/pkg/controller/webhook"
"github.com/elastic/cloud-on-k8s/pkg/utils/k8s"
"github.com/elastic/cloud-on-k8s/test/e2e/test"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
)

// InitTestSteps includes pre-requisite tests (eg. is k8s accessible),
Expand All @@ -29,7 +31,6 @@ func (b Builder) InitTestSteps(k *test.K8sClient) test.StepList {
require.NoError(t, err)
},
},

{
Name: "Elasticsearch CRDs should exist",
Test: func(t *testing.T) {
Expand All @@ -42,7 +43,29 @@ func (b Builder) InitTestSteps(k *test.K8sClient) test.StepList {
}
},
},

{
Name: "Webhook endpoint should not be empty",
Test: test.Eventually(func() error {
if test.Ctx().IgnoreWebhookFailures {
return nil
}
webhookEndpoints := &corev1.Endpoints{}
if err := k.Client.Get(types.NamespacedName{
Namespace: test.Ctx().GlobalOperator.Namespace,
Name: webhook.WebhookServiceName,
}, webhookEndpoints); err != nil {
return err
}
if len(webhookEndpoints.Subsets) == 0 {
return fmt.Errorf(
"endpoint %s/%s is empty",
webhookEndpoints.Namespace,
webhookEndpoints.Name,
)
}
return nil
}),
},
{
Name: "Remove Elasticsearch if it already exists",
Test: func(t *testing.T) {
Expand Down

0 comments on commit 1c6fb41

Please sign in to comment.