Run tests as project admin (#1384)

* Create Broker explicitly rather than by labeling namespace

* creating explicity is allowed for users with project admin permissions
in the given project

* Use Role instead of ClusterRole to work with Sources

* this allows for running the tests as project admin users and don't
require cluster-admin permissions

* Separate SourceList test for cluster admin and regular user

* Instructions for running E2E as project admin

* Fix imports

* Define output as a new variable in source_list_crd_test

* Fix golint

* Reference an issue created for source list-types
This commit is contained in:
Martin Gencur 2021-07-14 09:53:31 +02:00 committed by GitHub
parent 804d021e13
commit 2d6cab730d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 109 additions and 40 deletions

View File

@ -18,10 +18,31 @@ import (
"strings"
"time"
"gotest.tools/v3/assert"
"knative.dev/client/pkg/util"
"k8s.io/apimachinery/pkg/util/wait"
eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1"
)
// BrokerCreate creates a broker with the given name.
func BrokerCreate(r *KnRunResultCollector, name string) {
out := r.KnTest().Kn().Run("broker", "create", name)
r.AssertNoError(out)
assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "Broker", name, "created", "namespace", r.KnTest().Kn().Namespace()))
}
// BrokerDelete deletes a broker with the given name.
func BrokerDelete(r *KnRunResultCollector, name string, wait bool) {
args := []string{"broker", "delete", name}
if wait {
args = append(args, "--wait")
}
out := r.KnTest().Kn().Run(args...)
r.AssertNoError(out)
assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "Broker", name, "deleted", "namespace", r.KnTest().Kn().Namespace()))
}
// LabelNamespaceForDefaultBroker adds label 'knative-eventing-injection=enabled' to the configured namespace
func LabelNamespaceForDefaultBroker(r *KnRunResultCollector) error {
cmd := []string{"label", "namespace", r.KnTest().Kn().Namespace(), eventingv1.InjectionAnnotation + "=enabled"}

View File

@ -66,6 +66,29 @@ mode, use
```bash
test/local-e2e-tests.sh -short
```
### Running E2E tests as a project admin
It is possible to run the E2E tests by a user with reduced privileges, e.g. project admin.
Some tests require cluster-admin privileges and those tests are excluded from execution in this case.
Running the E2E tests then consists of these steps:
1. The cluster admin creates test namespaces. Each test requires a separate namespace.
By default, the namespace names consist of `kne2etests` prefix and numeric suffix starting from 0:
`kne2etests0`, `kne2etests1`, etc. The prefix can be configured using the KN_E2E_NAMESPACE env
variable. The namespace can be created as follows:
```bash
for i in $(seq 0 40); do kubectl create ns "${KN_E2E_NAMESPACE}${i}"; done
```
Note: There are currently slightly over 30 tests but the number will grow so the number of created
namespaces need to be adjusted.
1. The project admin runs the test suite with specific flags:
```bash
E2E_TAGS="project_admin" test/local-e2e-tests.sh --reusenamespace
```
It is expected that the current user is a project admin for all test namespaces
and their KUBECONFIG is located at `$HOME/.kube/config` or the env
variable `$KUBECONFIG` points to it.
### E2E tests prow jobs
Two e2e tests prow jobs are run in CI:

View File

@ -38,47 +38,31 @@ func TestBroker(t *testing.T) {
defer r.DumpIfFailed()
t.Log("create broker, list and describe it")
brokerCreate(r, "foo1")
test.BrokerCreate(r, "foo1")
verifyBrokerList(r, "foo1")
verifyBrokerListOutputName(r, "foo1")
verifyBrokerDescribe(r, "foo1")
brokerDelete(r, "foo1", false)
test.BrokerDelete(r, "foo1", false)
t.Log("create broker and delete it")
brokerCreate(r, "foo2")
test.BrokerCreate(r, "foo2")
verifyBrokerList(r, "foo2")
brokerDelete(r, "foo2", true)
test.BrokerDelete(r, "foo2", true)
verifyBrokerNotfound(r, "foo2")
t.Log("create multiple brokers and list them")
brokerCreate(r, "foo3")
brokerCreate(r, "foo4")
test.BrokerCreate(r, "foo3")
test.BrokerCreate(r, "foo4")
verifyBrokerList(r, "foo3", "foo4")
verifyBrokerListOutputName(r, "foo3", "foo4")
brokerDelete(r, "foo3", true)
brokerDelete(r, "foo4", true)
test.BrokerDelete(r, "foo3", true)
test.BrokerDelete(r, "foo4", true)
verifyBrokerNotfound(r, "foo3")
verifyBrokerNotfound(r, "foo4")
}
// Private functions
func brokerCreate(r *test.KnRunResultCollector, name string) {
out := r.KnTest().Kn().Run("broker", "create", name)
r.AssertNoError(out)
assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "Broker", name, "created", "namespace", r.KnTest().Kn().Namespace()))
}
func brokerDelete(r *test.KnRunResultCollector, name string, wait bool) {
args := []string{"broker", "delete", name}
if wait {
args = append(args, "--wait")
}
out := r.KnTest().Kn().Run(args...)
r.AssertNoError(out)
assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "Broker", name, "deleted", "namespace", r.KnTest().Kn().Namespace()))
}
func verifyBrokerList(r *test.KnRunResultCollector, brokers ...string) {
out := r.KnTest().Kn().Run("broker", "list")
r.AssertNoError(out)

View File

@ -37,9 +37,8 @@ func TestSink(t *testing.T) {
defer r.DumpIfFailed()
// create broker
err = test.LabelNamespaceForDefaultBroker(r)
assert.NilError(t, err)
defer test.UnlabelNamespaceForDefaultBroker(r)
test.BrokerCreate(r, "default")
defer test.BrokerDelete(r, "default", true)
t.Log("Create Ping source with a sink to the default broker")
pingSourceCreate(r, "testpingsource0", "* * * * */1", "ping", "broker:default")

View File

@ -113,14 +113,14 @@ func setupForSourceAPIServer(t *testing.T, it *test.KnTest) {
_, err := test.NewKubectl(it.Kn().Namespace()).Run("create", "serviceaccount", testServiceAccount)
assert.NilError(t, err)
_, err = test.Kubectl{}.Run("create", "clusterrole", clusterRolePrefix+it.Kn().Namespace(), "--verb=get,list,watch", "--resource=events,namespaces")
_, err = test.Kubectl{}.Run("create", "role", clusterRolePrefix+it.Kn().Namespace(), "--verb=get,list,watch", "--resource=events,namespaces")
assert.NilError(t, err)
_, err = test.Kubectl{}.Run(
"create",
"clusterrolebinding",
"rolebinding",
clusterRoleBindingPrefix+it.Kn().Namespace(),
"--clusterrole="+clusterRolePrefix+it.Kn().Namespace(),
"--role="+clusterRolePrefix+it.Kn().Namespace(),
"--serviceaccount="+it.Kn().Namespace()+":"+testServiceAccount)
assert.NilError(t, err)
}
@ -132,13 +132,13 @@ func tearDownForSourceAPIServer(t *testing.T, it *test.KnTest) error {
return fmt.Errorf("Error executing %q: %w", strings.Join(saCmd, " "), err)
}
crCmd := []string{"delete", "clusterrole", clusterRolePrefix + it.Kn().Namespace()}
crCmd := []string{"delete", "role", clusterRolePrefix + it.Kn().Namespace()}
_, err = test.Kubectl{}.Run(crCmd...)
if err != nil {
return fmt.Errorf("Error executing %q: %w", strings.Join(saCmd, " "), err)
}
crbCmd := []string{"delete", "clusterrolebinding", clusterRoleBindingPrefix + it.Kn().Namespace()}
crbCmd := []string{"delete", "rolebinding", clusterRoleBindingPrefix + it.Kn().Namespace()}
_, err = test.Kubectl{}.Run(crbCmd...)
if err != nil {
return fmt.Errorf("Error executing %q: %w", strings.Join(saCmd, " "), err)

View File

@ -0,0 +1,48 @@
// Copyright 2019 The Knative Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or im
// See the License for the specific language governing permissions and
// limitations under the License.
// +build e2e
// +build !serving
// +build !project_admin
package e2e
import (
"testing"
"gotest.tools/v3/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util"
)
// This test requires cluster admin permissions due to working with CustomResourceDefinitions.
// It can be excluded from test execution by using the project_admin build tag.
// See https://github.com/knative/client/issues/1385
func TestSourceListTypesCRD(t *testing.T) {
t.Parallel()
it, err := test.NewKnTest()
assert.NilError(t, err)
defer func() {
assert.NilError(t, it.Teardown())
}()
r := test.NewKnRunResultCollector(t, it)
defer r.DumpIfFailed()
t.Log("List available source types in YAML format")
output := sourceListTypes(r, "-oyaml")
assert.Check(t, util.ContainsAll(output, "apiextensions.k8s.io/v1", "CustomResourceDefinition", "Ping", "ApiServer"))
}

View File

@ -40,11 +40,6 @@ func TestSourceListTypes(t *testing.T) {
t.Log("List available source types")
output := sourceListTypes(r)
assert.Check(t, util.ContainsAll(output, "TYPE", "S", "NAME", "DESCRIPTION", "Ping", "ApiServer"))
t.Log("List available source types in YAML format")
output = sourceListTypes(r, "-oyaml")
assert.Check(t, util.ContainsAll(output, "apiextensions.k8s.io/v1", "CustomResourceDefinition", "Ping", "ApiServer"))
}
func TestSourceList(t *testing.T) {

View File

@ -37,9 +37,8 @@ func TestBrokerTrigger(t *testing.T) {
r := test.NewKnRunResultCollector(t, it)
defer r.DumpIfFailed()
err = test.LabelNamespaceForDefaultBroker(r)
assert.NilError(t, err)
defer test.UnlabelNamespaceForDefaultBroker(r)
test.BrokerCreate(r, "default")
defer test.BrokerDelete(r, "default", true)
test.ServiceCreate(r, "sinksvc0")
test.ServiceCreate(r, "sinksvc1")