mirror of https://github.com/knative/client.git
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:
parent
804d021e13
commit
2d6cab730d
|
|
@ -18,10 +18,31 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gotest.tools/v3/assert"
|
||||||
|
"knative.dev/client/pkg/util"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1"
|
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
|
// LabelNamespaceForDefaultBroker adds label 'knative-eventing-injection=enabled' to the configured namespace
|
||||||
func LabelNamespaceForDefaultBroker(r *KnRunResultCollector) error {
|
func LabelNamespaceForDefaultBroker(r *KnRunResultCollector) error {
|
||||||
cmd := []string{"label", "namespace", r.KnTest().Kn().Namespace(), eventingv1.InjectionAnnotation + "=enabled"}
|
cmd := []string{"label", "namespace", r.KnTest().Kn().Namespace(), eventingv1.InjectionAnnotation + "=enabled"}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,29 @@ mode, use
|
||||||
```bash
|
```bash
|
||||||
test/local-e2e-tests.sh -short
|
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
|
### E2E tests prow jobs
|
||||||
|
|
||||||
Two e2e tests prow jobs are run in CI:
|
Two e2e tests prow jobs are run in CI:
|
||||||
|
|
|
||||||
|
|
@ -38,47 +38,31 @@ func TestBroker(t *testing.T) {
|
||||||
defer r.DumpIfFailed()
|
defer r.DumpIfFailed()
|
||||||
|
|
||||||
t.Log("create broker, list and describe it")
|
t.Log("create broker, list and describe it")
|
||||||
brokerCreate(r, "foo1")
|
test.BrokerCreate(r, "foo1")
|
||||||
verifyBrokerList(r, "foo1")
|
verifyBrokerList(r, "foo1")
|
||||||
verifyBrokerListOutputName(r, "foo1")
|
verifyBrokerListOutputName(r, "foo1")
|
||||||
verifyBrokerDescribe(r, "foo1")
|
verifyBrokerDescribe(r, "foo1")
|
||||||
brokerDelete(r, "foo1", false)
|
test.BrokerDelete(r, "foo1", false)
|
||||||
|
|
||||||
t.Log("create broker and delete it")
|
t.Log("create broker and delete it")
|
||||||
brokerCreate(r, "foo2")
|
test.BrokerCreate(r, "foo2")
|
||||||
verifyBrokerList(r, "foo2")
|
verifyBrokerList(r, "foo2")
|
||||||
brokerDelete(r, "foo2", true)
|
test.BrokerDelete(r, "foo2", true)
|
||||||
verifyBrokerNotfound(r, "foo2")
|
verifyBrokerNotfound(r, "foo2")
|
||||||
|
|
||||||
t.Log("create multiple brokers and list them")
|
t.Log("create multiple brokers and list them")
|
||||||
brokerCreate(r, "foo3")
|
test.BrokerCreate(r, "foo3")
|
||||||
brokerCreate(r, "foo4")
|
test.BrokerCreate(r, "foo4")
|
||||||
verifyBrokerList(r, "foo3", "foo4")
|
verifyBrokerList(r, "foo3", "foo4")
|
||||||
verifyBrokerListOutputName(r, "foo3", "foo4")
|
verifyBrokerListOutputName(r, "foo3", "foo4")
|
||||||
brokerDelete(r, "foo3", true)
|
test.BrokerDelete(r, "foo3", true)
|
||||||
brokerDelete(r, "foo4", true)
|
test.BrokerDelete(r, "foo4", true)
|
||||||
verifyBrokerNotfound(r, "foo3")
|
verifyBrokerNotfound(r, "foo3")
|
||||||
verifyBrokerNotfound(r, "foo4")
|
verifyBrokerNotfound(r, "foo4")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private functions
|
// 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) {
|
func verifyBrokerList(r *test.KnRunResultCollector, brokers ...string) {
|
||||||
out := r.KnTest().Kn().Run("broker", "list")
|
out := r.KnTest().Kn().Run("broker", "list")
|
||||||
r.AssertNoError(out)
|
r.AssertNoError(out)
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,8 @@ func TestSink(t *testing.T) {
|
||||||
defer r.DumpIfFailed()
|
defer r.DumpIfFailed()
|
||||||
|
|
||||||
// create broker
|
// create broker
|
||||||
err = test.LabelNamespaceForDefaultBroker(r)
|
test.BrokerCreate(r, "default")
|
||||||
assert.NilError(t, err)
|
defer test.BrokerDelete(r, "default", true)
|
||||||
defer test.UnlabelNamespaceForDefaultBroker(r)
|
|
||||||
|
|
||||||
t.Log("Create Ping source with a sink to the default broker")
|
t.Log("Create Ping source with a sink to the default broker")
|
||||||
pingSourceCreate(r, "testpingsource0", "* * * * */1", "ping", "broker:default")
|
pingSourceCreate(r, "testpingsource0", "* * * * */1", "ping", "broker:default")
|
||||||
|
|
|
||||||
|
|
@ -113,14 +113,14 @@ func setupForSourceAPIServer(t *testing.T, it *test.KnTest) {
|
||||||
_, err := test.NewKubectl(it.Kn().Namespace()).Run("create", "serviceaccount", testServiceAccount)
|
_, err := test.NewKubectl(it.Kn().Namespace()).Run("create", "serviceaccount", testServiceAccount)
|
||||||
assert.NilError(t, err)
|
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)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
_, err = test.Kubectl{}.Run(
|
_, err = test.Kubectl{}.Run(
|
||||||
"create",
|
"create",
|
||||||
"clusterrolebinding",
|
"rolebinding",
|
||||||
clusterRoleBindingPrefix+it.Kn().Namespace(),
|
clusterRoleBindingPrefix+it.Kn().Namespace(),
|
||||||
"--clusterrole="+clusterRolePrefix+it.Kn().Namespace(),
|
"--role="+clusterRolePrefix+it.Kn().Namespace(),
|
||||||
"--serviceaccount="+it.Kn().Namespace()+":"+testServiceAccount)
|
"--serviceaccount="+it.Kn().Namespace()+":"+testServiceAccount)
|
||||||
assert.NilError(t, err)
|
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)
|
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...)
|
_, err = test.Kubectl{}.Run(crCmd...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error executing %q: %w", strings.Join(saCmd, " "), err)
|
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...)
|
_, err = test.Kubectl{}.Run(crbCmd...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error executing %q: %w", strings.Join(saCmd, " "), err)
|
return fmt.Errorf("Error executing %q: %w", strings.Join(saCmd, " "), err)
|
||||||
|
|
|
||||||
|
|
@ -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"))
|
||||||
|
}
|
||||||
|
|
@ -40,11 +40,6 @@ func TestSourceListTypes(t *testing.T) {
|
||||||
t.Log("List available source types")
|
t.Log("List available source types")
|
||||||
output := sourceListTypes(r)
|
output := sourceListTypes(r)
|
||||||
assert.Check(t, util.ContainsAll(output, "TYPE", "S", "NAME", "DESCRIPTION", "Ping", "ApiServer"))
|
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) {
|
func TestSourceList(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,8 @@ func TestBrokerTrigger(t *testing.T) {
|
||||||
r := test.NewKnRunResultCollector(t, it)
|
r := test.NewKnRunResultCollector(t, it)
|
||||||
defer r.DumpIfFailed()
|
defer r.DumpIfFailed()
|
||||||
|
|
||||||
err = test.LabelNamespaceForDefaultBroker(r)
|
test.BrokerCreate(r, "default")
|
||||||
assert.NilError(t, err)
|
defer test.BrokerDelete(r, "default", true)
|
||||||
defer test.UnlabelNamespaceForDefaultBroker(r)
|
|
||||||
|
|
||||||
test.ServiceCreate(r, "sinksvc0")
|
test.ServiceCreate(r, "sinksvc0")
|
||||||
test.ServiceCreate(r, "sinksvc1")
|
test.ServiceCreate(r, "sinksvc1")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue