(refactor) address the e2e extract / refactor of issue #763 (#765)

* (refactor) address the e2e extract / refactor of issue #763

* various updates to address reviewers feedback

* renamed lib/test/integration to lib/test and package to test
This commit is contained in:
dr.max 2020-04-01 09:21:18 -07:00 committed by GitHub
parent 521a0b423d
commit df78b8b40c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 815 additions and 703 deletions

View File

@ -17,9 +17,12 @@
[cols="1,10,3", options="header", width="100%"] [cols="1,10,3", options="header", width="100%"]
|=== |===
| | Description | PR | | Description | PR
|=== |===
| 🐣
| Refactor `e2e` common code into `lib/test/integration`
| https://github.com/knative/client/pull/765[#765]
## v0.13.1 (2020-03-25) ## v0.13.1 (2020-03-25)
[cols="1,10,3", options="header", width="100%"] [cols="1,10,3", options="header", width="100%"]

1
go.mod
View File

@ -14,6 +14,7 @@ require (
github.com/spf13/viper v1.4.0 github.com/spf13/viper v1.4.0
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
gomodules.xyz/jsonpatch/v2 v2.1.0 // indirect gomodules.xyz/jsonpatch/v2 v2.1.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
k8s.io/api v0.17.0 k8s.io/api v0.17.0
k8s.io/apimachinery v0.17.0 k8s.io/apimachinery v0.17.0

2
go.sum
View File

@ -543,6 +543,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=

View File

@ -16,7 +16,7 @@
set -o pipefail set -o pipefail
source_dirs="cmd pkg test" source_dirs="cmd pkg test lib"
# Store for later # Store for later
if [ -z "$1" ]; then if [ -z "$1" ]; then

View File

@ -12,153 +12,65 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package e2e package test
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"os/exec" "os/exec"
"strings" "strings"
"testing"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
type kn struct {
namespace string
}
const ( const (
seperatorHeavy = "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" seperatorHeavy = "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
seperatorLight = "╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍" seperatorLight = "╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍"
) )
// Run the 'kn' CLI with args and opts // Kn type
func (k kn) Run(args ...string) KnRunResult { type Kn struct {
return RunKn(k.namespace, args)
}
// Helper methods for calling out to the test cluster
type kubectl struct {
namespace string namespace string
} }
// Run the 'kubectl' CLI with args and opts // New Kn object
func (k kubectl) Run(args ...string) (string, error) { func NewKn() Kn {
return Kn{}
}
// Run the 'kn' CLI with args
func (k Kn) Run(args ...string) KnRunResult {
return RunKn(k.namespace, args)
}
// Namespace that this Kn instance uses
func (k Kn) Namespace() string {
return k.namespace
}
// Kubectl type
type Kubectl struct {
namespace string
}
// New Kubectl object
func NewKubectl(namespace string) Kubectl {
return Kubectl{
namespace: namespace,
}
}
// Run the 'kubectl' CLI with args
func (k Kubectl) Run(args ...string) (string, error) {
return RunKubectl(k.namespace, args...) return RunKubectl(k.namespace, args...)
} }
// Collector for results // Namespace that this Kubectl instance uses
type KnRunResultCollector struct { func (k Kubectl) Namespace() string {
results []KnRunResult return k.namespace
extraDumps []string
t *testing.T
} }
func NewKnRunResultCollector(t *testing.T) *KnRunResultCollector { // Public functions
return &KnRunResultCollector{
results: []KnRunResult{},
t: t,
extraDumps: []string{},
}
}
func (c *KnRunResultCollector) AssertNoError(result KnRunResult) {
c.results = append(c.results, result)
if result.Error != nil {
c.t.Logf("ERROR: %v", result.Stderr)
c.t.FailNow()
}
}
func (c *KnRunResultCollector) AssertError(result KnRunResult) {
c.results = append(c.results, result)
if result.Error == nil {
c.t.Log("ERROR: Error expected but no error happened")
c.t.FailNow()
}
}
// AddDump adds extra dump information to the collector which is printed
// out if an error occurs
func (c *KnRunResultCollector) AddDump(kind string, name string, namespace string) {
dumpInfo := extractDumpInfoWithName(kind, name, namespace)
if dumpInfo != "" {
c.extraDumps = append(c.extraDumps, dumpInfo)
}
}
func (c *KnRunResultCollector) DumpIfFailed() {
if c.t.Failed() {
c.t.Log(c.errorDetails())
}
}
func (c *KnRunResultCollector) errorDetails() string {
var out = bytes.Buffer{}
fmt.Fprintln(&out, "=== FAIL: =======================[[ERROR]]========================")
c.printCommands(&out)
var dumpInfos []string
if len(c.results) > 0 {
dumpInfo := c.results[len(c.results)-1].DumpInfo
if dumpInfo != "" {
dumpInfos = append(dumpInfos, dumpInfo)
}
}
dumpInfos = append(dumpInfos, c.extraDumps...)
for _, d := range dumpInfos {
fmt.Fprintln(&out, "--------------------------[[DUMP]]-------------------------------")
fmt.Fprintf(&out, d)
}
fmt.Fprintln(&out, "=================================================================")
return out.String()
}
func (c *KnRunResultCollector) printCommands(out io.Writer) {
for i, result := range c.results {
c.printCommand(out, result)
if i < len(c.results)-1 {
fmt.Fprintf(out, "┣━%s\n", seperatorHeavy)
}
}
}
func (c *KnRunResultCollector) printCommand(out io.Writer, result KnRunResult) {
fmt.Fprintf(out, "🦆 %s\n", result.CmdLine)
for _, l := range strings.Split(result.Stdout, "\n") {
fmt.Fprintf(out, "┃ %s\n", l)
}
if result.Stderr != "" {
errorPrefix := "🔥"
if result.ErrorExpected {
errorPrefix = "︙"
}
for _, l := range strings.Split(result.Stderr, "\n") {
fmt.Fprintf(out, "%s %s\n", errorPrefix, l)
}
}
}
// ========================================================
// Functions:
// Result of a "kn" call
type KnRunResult struct {
// Command line called
CmdLine string
// Standard output of command
Stdout string
// Standard error of command
Stderr string
// And extra dump informations in case of an unexpected error
DumpInfo string
// Error occurred during execution
Error error
// Was an error expected ?
ErrorExpected bool
}
// RunKn runs "kn" in a given namespace // RunKn runs "kn" in a given namespace
func RunKn(namespace string, args []string) KnRunResult { func RunKn(namespace string, args []string) KnRunResult {
@ -195,6 +107,8 @@ func RunKubectl(namespace string, args ...string) (string, error) {
return stdout, nil return stdout, nil
} }
// Private
func runCli(cli string, args []string) (string, string, error) { func runCli(cli string, args []string) (string, string, error) {
var stderr bytes.Buffer var stderr bytes.Buffer
var stdout bytes.Buffer var stdout bytes.Buffer

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package e2e package test
import ( import (
"flag" "flag"
@ -23,14 +23,15 @@ import (
// Flags holds the command line flags or defaults for settings in the user's environment. // Flags holds the command line flags or defaults for settings in the user's environment.
// See ClientFlags for the list of supported fields. // See ClientFlags for the list of supported fields.
var Flags = initializeFlags() var Flags = InitializeFlags()
// ClientFlags define the flags that are needed to run the e2e tests. // ClientFlags define the flags that are needed to run the e2e tests.
type ClientFlags struct { type ClientFlags struct {
DockerConfigJSON string DockerConfigJSON string
} }
func initializeFlags() *ClientFlags { // InitializeFlags initializes the client's flags
func InitializeFlags() *ClientFlags {
var f ClientFlags var f ClientFlags
dockerConfigJSON := os.Getenv("DOCKER_CONFIG_JSON") dockerConfigJSON := os.Getenv("DOCKER_CONFIG_JSON")

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package e2e package test
import ( import (
"fmt" "fmt"
@ -38,38 +38,59 @@ var serviceMutex sync.Mutex
var serviceCount int var serviceCount int
var namespaceCount int var namespaceCount int
type e2eTest struct { // KnTest type
type KnTest struct {
namespace string namespace string
kn kn kn Kn
} }
func NewE2eTest() (*e2eTest, error) { // NewIntegrationTest creates a new ItegrationTest object
ns := nextNamespace() func NewKnTest() (*KnTest, error) {
ns := NextNamespace()
err := createNamespace(ns) err := CreateNamespace(ns)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = waitForNamespaceCreated(ns) err = WaitForNamespaceCreated(ns)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &e2eTest{ return &KnTest{
namespace: ns, namespace: ns,
kn: kn{ns}, kn: Kn{ns},
}, nil }, nil
} }
func nextNamespace() string { // Teardown clean up
func (test *KnTest) Teardown() error {
return DeleteNamespace(test.namespace)
}
// Teardown clean up
func (test *KnTest) Kn() Kn {
return test.kn
}
// Namespace used by the test
func (test *KnTest) Namespace() string {
return test.namespace
}
// Public functions
// NextNamespace return the next unique namespace
func NextNamespace() string {
ns := os.Getenv("KN_E2E_NAMESPACE") ns := os.Getenv("KN_E2E_NAMESPACE")
if ns == "" { if ns == "" {
ns = "kne2etests" ns = "kne2etests"
} }
return fmt.Sprintf("%s%d", ns, getNextNamespaceId()) return fmt.Sprintf("%s%d", ns, GetNextNamespaceId())
} }
func getNextNamespaceId() int { // GetNextNamespaceId return the next unique ID for the next namespace
func GetNextNamespaceId() int {
nsMutex.Lock() nsMutex.Lock()
defer nsMutex.Unlock() defer nsMutex.Unlock()
current := namespaceCount current := namespaceCount
@ -77,7 +98,8 @@ func getNextNamespaceId() int {
return current return current
} }
func getNextServiceName(base string) string { // GetNextServiceName return the name for the next namespace
func GetNextServiceName(base string) string {
serviceMutex.Lock() serviceMutex.Lock()
defer serviceMutex.Unlock() defer serviceMutex.Unlock()
current := serviceCount current := serviceCount
@ -85,13 +107,8 @@ func getNextServiceName(base string) string {
return base + strconv.Itoa(current) return base + strconv.Itoa(current)
} }
// Teardown clean up // CreateNamespace creates and tests a namesspace creation invoking kubectl
func (test *e2eTest) Teardown() error { func CreateNamespace(namespace string) error {
return deleteNamespace(test.namespace)
}
// createNamespace creates and tests a namesspace creation invoking kubectl
func createNamespace(namespace string) error {
expectedOutputRegexp := fmt.Sprintf("namespace?.+%s.+created", namespace) expectedOutputRegexp := fmt.Sprintf("namespace?.+%s.+created", namespace)
out, err := createNamespaceWithRetry(namespace, MaxRetries) out, err := createNamespaceWithRetry(namespace, MaxRetries)
if err != nil { if err != nil {
@ -109,9 +126,9 @@ func createNamespace(namespace string) error {
return nil return nil
} }
// createNamespace deletes and tests a namesspace deletion invoking kubectl // DeleteNamespace deletes and tests a namesspace deletion invoking kubectl
func deleteNamespace(namespace string) error { func DeleteNamespace(namespace string) error {
kubectl := kubectl{namespace} kubectl := Kubectl{namespace}
out, err := kubectl.Run("delete", "namespace", namespace) out, err := kubectl.Run("delete", "namespace", namespace)
if err != nil { if err != nil {
return errors.Wrap(err, fmt.Sprintf("Cannot delete namespace %s", namespace)) return errors.Wrap(err, fmt.Sprintf("Cannot delete namespace %s", namespace))
@ -129,7 +146,7 @@ func deleteNamespace(namespace string) error {
} }
// WaitForNamespaceDeleted wait until namespace is deleted // WaitForNamespaceDeleted wait until namespace is deleted
func waitForNamespaceDeleted(namespace string) error { func WaitForNamespaceDeleted(namespace string) error {
deleted := checkNamespace(namespace, false, MaxRetries) deleted := checkNamespace(namespace, false, MaxRetries)
if !deleted { if !deleted {
return fmt.Errorf("error deleting namespace %s, timed out after %d retries", namespace, MaxRetries) return fmt.Errorf("error deleting namespace %s, timed out after %d retries", namespace, MaxRetries)
@ -138,7 +155,7 @@ func waitForNamespaceDeleted(namespace string) error {
} }
// WaitForNamespaceCreated wait until namespace is created // WaitForNamespaceCreated wait until namespace is created
func waitForNamespaceCreated(namespace string) error { func WaitForNamespaceCreated(namespace string) error {
created := checkNamespace(namespace, true, MaxRetries) created := checkNamespace(namespace, true, MaxRetries)
if !created { if !created {
return fmt.Errorf("error creating namespace %s, timed out after %d retries", namespace, MaxRetries) return fmt.Errorf("error creating namespace %s, timed out after %d retries", namespace, MaxRetries)
@ -146,11 +163,20 @@ func waitForNamespaceCreated(namespace string) error {
return nil return nil
} }
func CurrentDir(t *testing.T) string {
dir, err := os.Getwd()
if err != nil {
t.Fatal("Unable to read current dir:", err)
}
return dir
}
// Private functions // Private functions
func checkNamespace(namespace string, created bool, maxRetries int) bool { func checkNamespace(namespace string, created bool, maxRetries int) bool {
retries := 0 retries := 0
for retries < MaxRetries { for retries < MaxRetries {
output, _ := kubectl{}.Run("get", "namespace") output, _ := Kubectl{}.Run("get", "namespace")
// check for namespace deleted // check for namespace deleted
if !created && !strings.Contains(output, namespace) { if !created && !strings.Contains(output, namespace) {
@ -177,7 +203,7 @@ func createNamespaceWithRetry(namespace string, maxRetries int) (string, error)
) )
for retries < maxRetries { for retries < maxRetries {
out, err = kubectl{}.Run("create", "namespace", namespace) out, err = Kubectl{}.Run("create", "namespace", namespace)
if err == nil { if err == nil {
return out, nil return out, nil
} }
@ -195,11 +221,3 @@ func matchRegexp(matchingRegexp, actual string) (bool, error) {
} }
return matched, nil return matched, nil
} }
func currentDir(t *testing.T) string {
dir, err := os.Getwd()
if err != nil {
t.Fatal("Unable to read current dir:", err)
}
return dir
}

View File

@ -0,0 +1,137 @@
// Copyright 2020 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 implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package test
import (
"bytes"
"fmt"
"io"
"strings"
"testing"
)
// KnRunResult holds command and result artifacts of a "kn" call
type KnRunResult struct {
// Command line called
CmdLine string
// Standard output of command
Stdout string
// Standard error of command
Stderr string
// And extra dump informations in case of an unexpected error
DumpInfo string
// Error occurred during execution
Error error
// Was an error expected ?
ErrorExpected bool
}
// KnRunResultCollector collects Kn run's results
type KnRunResultCollector struct {
results []KnRunResult
extraDumps []string
t *testing.T
}
// NewKnRunResultCollector returns a new KnRunResultCollector
func NewKnRunResultCollector(t *testing.T) *KnRunResultCollector {
return &KnRunResultCollector{
results: []KnRunResult{},
t: t,
extraDumps: []string{},
}
}
// AssertError helper to assert no error on result
func (c *KnRunResultCollector) AssertNoError(result KnRunResult) {
c.results = append(c.results, result)
if result.Error != nil {
c.t.Logf("ERROR: %v", result.Stderr)
c.t.FailNow()
}
}
// AssertError helper to assert error on result
func (c *KnRunResultCollector) AssertError(result KnRunResult) {
c.results = append(c.results, result)
if result.Error == nil {
c.t.Log("ERROR: Error expected but no error happened")
c.t.FailNow()
}
}
// AddDump adds extra dump information to the collector which is printed
// out if an error occurs
func (c *KnRunResultCollector) AddDump(kind string, name string, namespace string) {
dumpInfo := extractDumpInfoWithName(kind, name, namespace)
if dumpInfo != "" {
c.extraDumps = append(c.extraDumps, dumpInfo)
}
}
// DumpIfFailed logs if collector failed
func (c *KnRunResultCollector) DumpIfFailed() {
if c.t.Failed() {
c.t.Log(c.errorDetails())
}
}
// Private
func (c *KnRunResultCollector) errorDetails() string {
var out = bytes.Buffer{}
fmt.Fprintln(&out, "=== FAIL: =======================[[ERROR]]========================")
c.printCommands(&out)
var dumpInfos []string
if len(c.results) > 0 {
dumpInfo := c.results[len(c.results)-1].DumpInfo
if dumpInfo != "" {
dumpInfos = append(dumpInfos, dumpInfo)
}
}
dumpInfos = append(dumpInfos, c.extraDumps...)
for _, d := range dumpInfos {
fmt.Fprintln(&out, "--------------------------[[DUMP]]-------------------------------")
fmt.Fprintf(&out, d)
}
fmt.Fprintln(&out, "=================================================================")
return out.String()
}
func (c *KnRunResultCollector) printCommands(out io.Writer) {
for i, result := range c.results {
c.printCommand(out, result)
if i < len(c.results)-1 {
fmt.Fprintf(out, "┣━%s\n", seperatorHeavy)
}
}
}
func (c *KnRunResultCollector) printCommand(out io.Writer, result KnRunResult) {
fmt.Fprintf(out, "🦆 %s\n", result.CmdLine)
for _, l := range strings.Split(result.Stdout, "\n") {
fmt.Fprintf(out, "┃ %s\n", l)
}
if result.Stderr != "" {
errorPrefix := "🔥"
if result.ErrorExpected {
errorPrefix = "︙"
}
for _, l := range strings.Split(result.Stderr, "\n") {
fmt.Fprintf(out, "%s %s\n", errorPrefix, l)
}
}
}

View File

@ -23,60 +23,61 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestBasicWorkflow(t *testing.T) { func TestBasicWorkflow(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
t.Log("returns no service before running tests") t.Log("returns no service before running tests")
test.serviceListEmpty(t, r) serviceListEmpty(t, it, r)
t.Log("create hello service and return no error") t.Log("create hello service and return no error")
test.serviceCreate(t, r, "hello") serviceCreate(t, it, r, "hello")
t.Log("return valid info about hello service") t.Log("return valid info about hello service")
test.serviceList(t, r, "hello") serviceList(t, it, r, "hello")
test.serviceDescribe(t, r, "hello") serviceDescribe(t, it, r, "hello")
t.Log("update hello service's configuration and return no error") t.Log("update hello service's configuration and return no error")
test.serviceUpdate(t, r, "hello", "--env", "TARGET=kn", "--port", "8888") serviceUpdate(t, it, r, "hello", "--env", "TARGET=kn", "--port", "8888")
t.Log("create another service and return no error") t.Log("create another service and return no error")
test.serviceCreate(t, r, "svc2") serviceCreate(t, it, r, "svc2")
t.Log("return a list of revisions associated with hello and svc2 services") t.Log("return a list of revisions associated with hello and svc2 services")
test.revisionListForService(t, r, "hello") revisionListForService(t, it, r, "hello")
test.revisionListForService(t, r, "svc2") revisionListForService(t, it, r, "svc2")
t.Log("describe revision from hello service") t.Log("describe revision from hello service")
test.revisionDescribe(t, r, "hello") revisionDescribe(t, it, r, "hello")
t.Log("delete hello and svc2 services and return no error") t.Log("delete hello and svc2 services and return no error")
test.serviceDelete(t, r, "hello") serviceDelete(t, it, r, "hello")
test.serviceDelete(t, r, "svc2") serviceDelete(t, it, r, "svc2")
t.Log("return no service after completing tests") t.Log("return no service after completing tests")
test.serviceListEmpty(t, r) serviceListEmpty(t, it, r)
} }
func TestWrongCommand(t *testing.T) { func TestWrongCommand(t *testing.T) {
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
out := kn{}.Run("source", "apiserver", "noverb", "--tag=0.13") out := test.Kn{}.Run("source", "apiserver", "noverb", "--tag=0.13")
assert.Check(t, util.ContainsAll(out.Stderr, "Error", "unknown subcommand", "noverb")) assert.Check(t, util.ContainsAll(out.Stderr, "Error", "unknown subcommand", "noverb"))
r.AssertError(out) r.AssertError(out)
out = kn{}.Run("rev") out = test.Kn{}.Run("rev")
assert.Check(t, util.ContainsAll(out.Stderr, "Error", "unknown command", "rev")) assert.Check(t, util.ContainsAll(out.Stderr, "Error", "unknown command", "rev"))
r.AssertError(out) r.AssertError(out)
@ -84,48 +85,48 @@ func TestWrongCommand(t *testing.T) {
// ========================================================================== // ==========================================================================
func (test *e2eTest) serviceListEmpty(t *testing.T, r *KnRunResultCollector) { func serviceListEmpty(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector) {
out := test.kn.Run("service", "list") out := it.Kn().Run("service", "list")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, "No services found.")) assert.Check(t, util.ContainsAll(out.Stdout, "No services found."))
} }
func (test *e2eTest) serviceCreate(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceCreate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "create", serviceName, "--image", KnDefaultTestImage) out := it.Kn().Run("service", "create", serviceName, "--image", test.KnDefaultTestImage)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "creating", "namespace", test.kn.namespace, "ready")) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "creating", "namespace", it.Kn().Namespace(), "ready"))
} }
func (test *e2eTest) serviceList(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceList(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "list", serviceName) out := it.Kn().Run("service", "list", serviceName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, serviceName)) assert.Check(t, util.ContainsAll(out.Stdout, serviceName))
} }
func (test *e2eTest) serviceDescribe(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceDescribe(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "describe", serviceName) out := it.Kn().Run("service", "describe", serviceName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Assert(t, util.ContainsAll(out.Stdout, serviceName, test.kn.namespace, KnDefaultTestImage)) assert.Assert(t, util.ContainsAll(out.Stdout, serviceName, it.Kn().Namespace(), test.KnDefaultTestImage))
assert.Assert(t, util.ContainsAll(out.Stdout, "Conditions", "ConfigurationsReady", "Ready", "RoutesReady")) assert.Assert(t, util.ContainsAll(out.Stdout, "Conditions", "ConfigurationsReady", "Ready", "RoutesReady"))
assert.Assert(t, util.ContainsAll(out.Stdout, "Name", "Namespace", "URL", "Age", "Revisions")) assert.Assert(t, util.ContainsAll(out.Stdout, "Name", "Namespace", "URL", "Age", "Revisions"))
} }
func (test *e2eTest) serviceUpdate(t *testing.T, r *KnRunResultCollector, serviceName string, args ...string) { func serviceUpdate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, args ...string) {
fullArgs := append([]string{}, "service", "update", serviceName) fullArgs := append([]string{}, "service", "update", serviceName)
fullArgs = append(fullArgs, args...) fullArgs = append(fullArgs, args...)
out := test.kn.Run(fullArgs...) out := it.Kn().Run(fullArgs...)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "updating", "service", serviceName, "ready")) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "updating", "service", serviceName, "ready"))
} }
func (test *e2eTest) serviceDelete(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceDelete(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "delete", serviceName) out := it.Kn().Run("service", "delete", serviceName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, "Service", serviceName, "successfully deleted in namespace", test.kn.namespace)) assert.Check(t, util.ContainsAll(out.Stdout, "Service", serviceName, "successfully deleted in namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) revisionListForService(t *testing.T, r *KnRunResultCollector, serviceName string) { func revisionListForService(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("revision", "list", "-s", serviceName) out := it.Kn().Run("revision", "list", "-s", serviceName)
r.AssertNoError(out) r.AssertNoError(out)
outputLines := strings.Split(out.Stdout, "\n") outputLines := strings.Split(out.Stdout, "\n")
// Ignore the last line because it is an empty string caused by splitting a line break // Ignore the last line because it is an empty string caused by splitting a line break
@ -136,10 +137,10 @@ func (test *e2eTest) revisionListForService(t *testing.T, r *KnRunResultCollecto
} }
} }
func (test *e2eTest) revisionDescribe(t *testing.T, r *KnRunResultCollector, serviceName string) { func revisionDescribe(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
revName := test.findRevision(t, r, serviceName) revName := findRevision(t, it, r, serviceName)
out := test.kn.Run("revision", "describe", revName) out := it.Kn().Run("revision", "describe", revName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, revName, test.kn.namespace, serviceName, "++ Ready", "TARGET=kn")) assert.Check(t, util.ContainsAll(out.Stdout, revName, it.Kn().Namespace(), serviceName, "++ Ready", "TARGET=kn"))
} }

View File

@ -22,92 +22,93 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestSourcePing(t *testing.T) { func TestSourcePing(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
t.Log("Creating a testservice") t.Log("Creating a testservice")
test.serviceCreate(t, r, "testsvc0") serviceCreate(t, it, r, "testsvc0")
t.Log("create Ping sources with a sink to a service") t.Log("create Ping sources with a sink to a service")
test.pingSourceCreate(t, r, "testpingsource0", "* * * * */1", "ping", "svc:testsvc0") pingSourceCreate(t, it, r, "testpingsource0", "* * * * */1", "ping", "svc:testsvc0")
t.Log("delete Ping sources") t.Log("delete Ping sources")
test.pingSourceDelete(t, r, "testpingsource0") pingSourceDelete(t, it, r, "testpingsource0")
t.Log("create Ping source with a missing sink service") t.Log("create Ping source with a missing sink service")
test.pingSourceCreateMissingSink(t, r, "testpingsource1", "* * * * */1", "ping", "svc:unknown") pingSourceCreateMissingSink(t, it, r, "testpingsource1", "* * * * */1", "ping", "svc:unknown")
t.Log("update Ping source sink service") t.Log("update Ping source sink service")
test.pingSourceCreate(t, r, "testpingsource2", "* * * * */1", "ping", "svc:testsvc0") pingSourceCreate(t, it, r, "testpingsource2", "* * * * */1", "ping", "svc:testsvc0")
test.serviceCreate(t, r, "testsvc1") serviceCreate(t, it, r, "testsvc1")
test.pingSourceUpdateSink(t, r, "testpingsource2", "svc:testsvc1") pingSourceUpdateSink(t, it, r, "testpingsource2", "svc:testsvc1")
jpSinkRefNameInSpec := "jsonpath={.spec.sink.ref.name}" jpSinkRefNameInSpec := "jsonpath={.spec.sink.ref.name}"
out, err := test.getResourceFieldsWithJSONPath("pingsource", "testpingsource2", jpSinkRefNameInSpec) out, err := getResourceFieldsWithJSONPath(t, it, "pingsource", "testpingsource2", jpSinkRefNameInSpec)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out, "testsvc1") assert.Equal(t, out, "testsvc1")
t.Log("verify Ping source description") t.Log("verify Ping source description")
mymsg := "This is a message from Ping." mymsg := "This is a message from Ping."
test.pingSourceCreate(t, r, "testpingsource3", "*/1 * * * *", mymsg, "svc:testsvc1") pingSourceCreate(t, it, r, "testpingsource3", "*/1 * * * *", mymsg, "svc:testsvc1")
test.verifyPingSourceDescribe(t, r, "testpingsource3", "*/1 * * * *", mymsg, "testsvc1") verifyPingSourceDescribe(t, it, r, "testpingsource3", "*/1 * * * *", mymsg, "testsvc1")
} }
func (test *e2eTest) pingSourceCreate(t *testing.T, r *KnRunResultCollector, sourceName string, schedule string, data string, sink string) { func pingSourceCreate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, schedule string, data string, sink string) {
out := test.kn.Run("source", "ping", "create", sourceName, out := it.Kn().Run("source", "ping", "create", sourceName,
"--schedule", schedule, "--data", data, "--sink", sink) "--schedule", schedule, "--data", data, "--sink", sink)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "ping", "source", sourceName, "created", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "ping", "source", sourceName, "created", "namespace", it.Kn().Namespace()))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) pingSourceDelete(t *testing.T, r *KnRunResultCollector, sourceName string) { func pingSourceDelete(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string) {
out := test.kn.Run("source", "ping", "delete", sourceName) out := it.Kn().Run("source", "ping", "delete", sourceName)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "ping", "source", sourceName, "deleted", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "ping", "source", sourceName, "deleted", "namespace", it.Kn().Namespace()))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) pingSourceCreateMissingSink(t *testing.T, r *KnRunResultCollector, sourceName string, schedule string, data string, sink string) { func pingSourceCreateMissingSink(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, schedule string, data string, sink string) {
out := test.kn.Run("source", "ping", "create", sourceName, out := it.Kn().Run("source", "ping", "create", sourceName,
"--schedule", schedule, "--data", data, "--sink", sink) "--schedule", schedule, "--data", data, "--sink", sink)
assert.Check(t, util.ContainsAll(out.Stderr, "services.serving.knative.dev", "not found")) assert.Check(t, util.ContainsAll(out.Stderr, "services.serving.knative.dev", "not found"))
r.AssertError(out) r.AssertError(out)
} }
func (test *e2eTest) pingSourceUpdateSink(t *testing.T, r *KnRunResultCollector, sourceName string, sink string) { func pingSourceUpdateSink(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, sink string) {
out := test.kn.Run("source", "ping", "update", sourceName, "--sink", sink) out := it.Kn().Run("source", "ping", "update", sourceName, "--sink", sink)
assert.Check(t, util.ContainsAll(out.Stdout, sourceName, "updated", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAll(out.Stdout, sourceName, "updated", "namespace", it.Kn().Namespace()))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) pingSourceCreateWithResources(t *testing.T, r *KnRunResultCollector, sourceName string, schedule string, data string, sink string, sa string, requestcpu string, requestmm string, limitcpu string, limitmm string) { func pingSourceCreateWithResources(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, schedule string, data string, sink string, sa string, requestcpu string, requestmm string, limitcpu string, limitmm string) {
out := test.kn.Run("source", "ping", "create", sourceName, out := it.Kn().Run("source", "ping", "create", sourceName,
"--schedule", schedule, "--data", data, "--sink", sink, "--service-account", sa, "--schedule", schedule, "--data", data, "--sink", sink, "--service-account", sa,
"--requests-cpu", requestcpu, "--requests-memory", requestmm, "--limits-cpu", limitcpu, "--limits-memory", limitmm) "--requests-cpu", requestcpu, "--requests-memory", requestmm, "--limits-cpu", limitcpu, "--limits-memory", limitmm)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "ping", "source", sourceName, "created", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "ping", "source", sourceName, "created", "namespace", it.Kn().Namespace()))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) pingSourceUpdateResources(t *testing.T, r *KnRunResultCollector, sourceName string, requestcpu string, requestmm string, limitcpu string, limitmm string) { func pingSourceUpdateResources(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, requestcpu string, requestmm string, limitcpu string, limitmm string) {
out := test.kn.Run("source", "ping", "update", sourceName, out := it.Kn().Run("source", "ping", "update", sourceName,
"--requests-cpu", requestcpu, "--requests-memory", requestmm, "--limits-cpu", limitcpu, "--limits-memory", limitmm) "--requests-cpu", requestcpu, "--requests-memory", requestmm, "--limits-cpu", limitcpu, "--limits-memory", limitmm)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, sourceName, "updated", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, sourceName, "updated", "namespace", it.Kn().Namespace()))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) verifyPingSourceDescribe(t *testing.T, r *KnRunResultCollector, sourceName string, schedule string, data string, sink string) { func verifyPingSourceDescribe(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, schedule string, data string, sink string) {
out := test.kn.Run("source", "ping", "describe", sourceName) out := it.Kn().Run("source", "ping", "describe", sourceName)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, sourceName, schedule, data, sink)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, sourceName, schedule, data, sink))
r.AssertNoError(out) r.AssertNoError(out)
} }

View File

@ -25,6 +25,7 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
@ -95,7 +96,7 @@ func TestPluginWithoutLookup(t *testing.T) {
pc, oldPath := setupPluginTestConfigWithNewPath(t) pc, oldPath := setupPluginTestConfigWithNewPath(t)
defer tearDownWithPath(pc, oldPath) defer tearDownWithPath(pc, oldPath)
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
knFlags := []string{fmt.Sprintf("--plugins-dir=%s", pc.knPluginsDir), "--lookup-plugins=false"} knFlags := []string{fmt.Sprintf("--plugins-dir=%s", pc.knPluginsDir), "--lookup-plugins=false"}
@ -114,7 +115,7 @@ func TestPluginWithoutLookup(t *testing.T) {
func TestPluginWithLookup(t *testing.T) { func TestPluginWithLookup(t *testing.T) {
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
pc := pluginTestConfig{} pc := pluginTestConfig{}
@ -132,7 +133,7 @@ func TestPluginWithLookup(t *testing.T) {
func TestListPluginInPath(t *testing.T) { func TestListPluginInPath(t *testing.T) {
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
pc, oldPath := setupPluginTestConfigWithNewPath(t) pc, oldPath := setupPluginTestConfigWithNewPath(t)
defer tearDownWithPath(pc, oldPath) defer tearDownWithPath(pc, oldPath)
@ -145,7 +146,7 @@ func TestListPluginInPath(t *testing.T) {
} }
func TestExecutePluginInPath(t *testing.T) { func TestExecutePluginInPath(t *testing.T) {
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
pc, oldPath := setupPluginTestConfigWithNewPath(t) pc, oldPath := setupPluginTestConfigWithNewPath(t)
@ -171,21 +172,21 @@ func tearDownWithPath(pc pluginTestConfig, oldPath string) {
// Private // Private
func listPlugin(t *testing.T, r *KnRunResultCollector, knFlags []string, expectedPlugins []string, unexpectedPlugins []string) { func listPlugin(t *testing.T, r *test.KnRunResultCollector, knFlags []string, expectedPlugins []string, unexpectedPlugins []string) {
knArgs := append(knFlags, "plugin", "list") knArgs := append(knFlags, "plugin", "list")
out := kn{}.Run(knArgs...) out := test.Kn{}.Run(knArgs...)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, expectedPlugins...)) assert.Check(t, util.ContainsAll(out.Stdout, expectedPlugins...))
assert.Check(t, util.ContainsNone(out.Stdout, unexpectedPlugins...)) assert.Check(t, util.ContainsNone(out.Stdout, unexpectedPlugins...))
} }
func runPlugin(t *testing.T, r *KnRunResultCollector, knFlags []string, pluginName string, args []string, expectedOutput []string) { func runPlugin(t *testing.T, r *test.KnRunResultCollector, knFlags []string, pluginName string, args []string, expectedOutput []string) {
knArgs := append([]string{}, knFlags...) knArgs := append([]string{}, knFlags...)
knArgs = append(knArgs, pluginName) knArgs = append(knArgs, pluginName)
knArgs = append(knArgs, args...) knArgs = append(knArgs, args...)
out := kn{}.Run(knArgs...) out := test.Kn{}.Run(knArgs...)
r.AssertNoError(out) r.AssertNoError(out)
for _, output := range expectedOutput { for _, output := range expectedOutput {
assert.Check(t, util.ContainsAll(out.Stdout, output)) assert.Check(t, util.ContainsAll(out.Stdout, output))

View File

@ -24,99 +24,101 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestRevision(t *testing.T) { func TestRevision(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
t.Log("create hello service and return no error") t.Log("create hello service and return no error")
test.serviceCreate(t, r, "hello") serviceCreate(t, it, r, "hello")
t.Log("describe revision from hello service with print flags") t.Log("describe revision from hello service with print flags")
revName := test.findRevision(t, r, "hello") revName := findRevision(t, it, r, "hello")
test.revisionDescribeWithPrintFlags(t, r, revName) revisionDescribeWithPrintFlags(t, it, r, revName)
t.Log("update hello service and increase revision count to 2") t.Log("update hello service and increase revision count to 2")
test.serviceUpdate(t, r, "hello", "--env", "TARGET=kn", "--port", "8888") serviceUpdate(t, it, r, "hello", "--env", "TARGET=kn", "--port", "8888")
t.Log("show a list of revisions sorted by the count of configuration generation") t.Log("show a list of revisions sorted by the count of configuration generation")
test.revisionListWithService(t, r, "hello") revisionListWithService(t, it, r, "hello")
t.Log("update hello service and increase revision count to 3") t.Log("update hello service and increase revision count to 3")
test.serviceUpdate(t, r, "hello", "--env", "TARGET=kn", "--port", "8888") serviceUpdate(t, it, r, "hello", "--env", "TARGET=kn", "--port", "8888")
t.Log("delete three revisions with one revision a nonexistent") t.Log("delete three revisions with one revision a nonexistent")
existRevision1 := test.findRevisionByGeneration(t, r, "hello", 1) existRevision1 := findRevisionByGeneration(t, it, r, "hello", 1)
existRevision2 := test.findRevisionByGeneration(t, r, "hello", 2) existRevision2 := findRevisionByGeneration(t, it, r, "hello", 2)
nonexistRevision := "hello-nonexist" nonexistRevision := "hello-nonexist"
test.revisionMultipleDelete(t, r, existRevision1, existRevision2, nonexistRevision) revisionMultipleDelete(t, it, r, existRevision1, existRevision2, nonexistRevision)
t.Log("delete latest revision from hello service and return no error") t.Log("delete latest revision from hello service and return no error")
revName = test.findRevision(t, r, "hello") revName = findRevision(t, it, r, "hello")
test.revisionDelete(t, r, revName) revisionDelete(t, it, r, revName)
t.Log("delete hello service and return no error") t.Log("delete hello service and return no error")
test.serviceDelete(t, r, "hello") serviceDelete(t, it, r, "hello")
} }
func (test *e2eTest) revisionListWithService(t *testing.T, r *KnRunResultCollector, serviceNames ...string) { func revisionListWithService(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceNames ...string) {
for _, svcName := range serviceNames { for _, svcName := range serviceNames {
confGen := test.findConfigurationGeneration(t, r, svcName) confGen := findConfigurationGeneration(t, it, r, svcName)
out := test.kn.Run("revision", "list", "-s", svcName) out := it.Kn().Run("revision", "list", "-s", svcName)
r.AssertNoError(out) r.AssertNoError(out)
outputLines := strings.Split(out.Stdout, "\n") outputLines := strings.Split(out.Stdout, "\n")
// Ignore the last line because it is an empty string caused by splitting a line break // Ignore the last line because it is an empty string caused by splitting a line break
// at the end of the output string // at the end of the output string
for _, line := range outputLines[1 : len(outputLines)-1] { for _, line := range outputLines[1 : len(outputLines)-1] {
revName := test.findRevisionByGeneration(t, r, svcName, confGen) revName := findRevisionByGeneration(t, it, r, svcName, confGen)
assert.Check(t, util.ContainsAll(line, revName, svcName, strconv.Itoa(confGen))) assert.Check(t, util.ContainsAll(line, revName, svcName, strconv.Itoa(confGen)))
confGen-- confGen--
} }
if t.Failed() { if t.Failed() {
r.AddDump("service", svcName, test.namespace) r.AddDump("service", svcName, it.Kn().Namespace())
} }
} }
} }
func (test *e2eTest) revisionDelete(t *testing.T, r *KnRunResultCollector, revName string) { func revisionDelete(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, revName string) {
out := test.kn.Run("revision", "delete", revName) out := it.Kn().Run("revision", "delete", revName)
assert.Check(t, util.ContainsAll(out.Stdout, "Revision", revName, "deleted", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAll(out.Stdout, "Revision", revName, "deleted", "namespace", it.Kn().Namespace()))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) revisionMultipleDelete(t *testing.T, r *KnRunResultCollector, existRevision1, existRevision2, nonexistRevision string) { func revisionMultipleDelete(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, existRevision1, existRevision2, nonexistRevision string) {
out := test.kn.Run("revision", "list") out := it.Kn().Run("revision", "list")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, strings.Contains(out.Stdout, existRevision1), "Required revision1 does not exist") assert.Check(t, strings.Contains(out.Stdout, existRevision1), "Required revision1 does not exist")
assert.Check(t, strings.Contains(out.Stdout, existRevision2), "Required revision2 does not exist") assert.Check(t, strings.Contains(out.Stdout, existRevision2), "Required revision2 does not exist")
out = test.kn.Run("revision", "delete", existRevision1, existRevision2, nonexistRevision) out = it.Kn().Run("revision", "delete", existRevision1, existRevision2, nonexistRevision)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, "Revision", existRevision1, "deleted", "namespace", test.kn.namespace), "Failed to get 'deleted' first revision message") assert.Check(t, util.ContainsAll(out.Stdout, "Revision", existRevision1, "deleted", "namespace", it.Kn().Namespace()), "Failed to get 'deleted' first revision message")
assert.Check(t, util.ContainsAll(out.Stdout, "Revision", existRevision2, "deleted", "namespace", test.kn.namespace), "Failed to get 'deleted' second revision message") assert.Check(t, util.ContainsAll(out.Stdout, "Revision", existRevision2, "deleted", "namespace", it.Kn().Namespace()), "Failed to get 'deleted' second revision message")
assert.Check(t, util.ContainsAll(out.Stdout, "revisions.serving.knative.dev", nonexistRevision, "not found"), "Failed to get 'not found' error") assert.Check(t, util.ContainsAll(out.Stdout, "revisions.serving.knative.dev", nonexistRevision, "not found"), "Failed to get 'not found' error")
} }
func (test *e2eTest) revisionDescribeWithPrintFlags(t *testing.T, r *KnRunResultCollector, revName string) { func revisionDescribeWithPrintFlags(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, revName string) {
out := test.kn.Run("revision", "describe", revName, "-o=name") out := it.Kn().Run("revision", "describe", revName, "-o=name")
r.AssertNoError(out) r.AssertNoError(out)
expectedName := fmt.Sprintf("revision.serving.knative.dev/%s", revName) expectedName := fmt.Sprintf("revision.serving.knative.dev/%s", revName)
assert.Equal(t, strings.TrimSpace(out.Stdout), expectedName) assert.Equal(t, strings.TrimSpace(out.Stdout), expectedName)
} }
func (test *e2eTest) findRevision(t *testing.T, r *KnRunResultCollector, serviceName string) string { func findRevision(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) string {
out := test.kn.Run("revision", "list", "-s", serviceName, "-o=jsonpath={.items[0].metadata.name}") out := it.Kn().Run("revision", "list", "-s", serviceName, "-o=jsonpath={.items[0].metadata.name}")
r.AssertNoError(out) r.AssertNoError(out)
if strings.Contains(out.Stdout, "No resources") { if strings.Contains(out.Stdout, "No resources") {
t.Errorf("Could not find revision name.") t.Errorf("Could not find revision name.")
@ -124,9 +126,9 @@ func (test *e2eTest) findRevision(t *testing.T, r *KnRunResultCollector, service
return out.Stdout return out.Stdout
} }
func (test *e2eTest) findRevisionByGeneration(t *testing.T, r *KnRunResultCollector, serviceName string, generation int) string { func findRevisionByGeneration(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, generation int) string {
maxGen := test.findConfigurationGeneration(t, r, serviceName) maxGen := findConfigurationGeneration(t, it, r, serviceName)
out := test.kn.Run("revision", "list", "-s", serviceName, out := it.Kn().Run("revision", "list", "-s", serviceName,
fmt.Sprintf("-o=jsonpath={.items[%d].metadata.name}", maxGen-generation)) fmt.Sprintf("-o=jsonpath={.items[%d].metadata.name}", maxGen-generation))
r.AssertNoError(out) r.AssertNoError(out)
if strings.Contains(out.Stdout, "No resources found.") { if strings.Contains(out.Stdout, "No resources found.") {
@ -135,8 +137,8 @@ func (test *e2eTest) findRevisionByGeneration(t *testing.T, r *KnRunResultCollec
return out.Stdout return out.Stdout
} }
func (test *e2eTest) findConfigurationGeneration(t *testing.T, r *KnRunResultCollector, serviceName string) int { func findConfigurationGeneration(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) int {
out := test.kn.Run("revision", "list", "-s", serviceName, "-o=jsonpath={.items[0].metadata.labels.serving\\.knative\\.dev/configurationGeneration}") out := it.Kn().Run("revision", "list", "-s", serviceName, "-o=jsonpath={.items[0].metadata.labels.serving\\.knative\\.dev/configurationGeneration}")
r.AssertNoError(out) r.AssertNoError(out)
if out.Stdout == "" { if out.Stdout == "" {
t.Errorf("Could not find configuration generation.") t.Errorf("Could not find configuration generation.")

View File

@ -23,75 +23,77 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestRoute(t *testing.T) { func TestRoute(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
t.Log("create hello service and return no error") t.Log("create hello service and return no error")
test.serviceCreate(t, r, "hello") serviceCreate(t, it, r, "hello")
t.Log("return a list of routes") t.Log("return a list of routes")
test.routeList(t, r) routeList(t, it, r)
t.Log("return a list of routes associated with hello service") t.Log("return a list of routes associated with hello service")
test.routeListWithArgument(t, r, "hello") routeListWithArgument(t, it, r, "hello")
t.Log("return a list of routes associated with hello service with print flags") t.Log("return a list of routes associated with hello service with print flags")
test.routeListWithPrintFlags(t, r, "hello") routeListWithPrintFlags(t, it, r, "hello")
t.Log("describe route from hello service") t.Log("describe route from hello service")
test.routeDescribe(t, r, "hello") routeDescribe(t, it, r, "hello")
t.Log("describe route from hello service with print flags") t.Log("describe route from hello service with print flags")
test.routeDescribeWithPrintFlags(t, r, "hello") routeDescribeWithPrintFlags(t, it, r, "hello")
t.Log("delete hello service and return no error") t.Log("delete hello service and return no error")
test.serviceDelete(t, r, "hello") serviceDelete(t, it, r, "hello")
} }
func (test *e2eTest) routeList(t *testing.T, r *KnRunResultCollector) { func routeList(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector) {
out := test.kn.Run("route", "list") out := it.Kn().Run("route", "list")
expectedHeaders := []string{"NAME", "URL", "READY"} expectedHeaders := []string{"NAME", "URL", "READY"}
assert.Check(t, util.ContainsAll(out.Stdout, expectedHeaders...)) assert.Check(t, util.ContainsAll(out.Stdout, expectedHeaders...))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) routeListWithArgument(t *testing.T, r *KnRunResultCollector, routeName string) { func routeListWithArgument(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, routeName string) {
out := test.kn.Run("route", "list", routeName) out := it.Kn().Run("route", "list", routeName)
assert.Check(t, util.ContainsAll(out.Stdout, routeName)) assert.Check(t, util.ContainsAll(out.Stdout, routeName))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) routeDescribe(t *testing.T, r *KnRunResultCollector, routeName string) { func routeDescribe(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, routeName string) {
out := test.kn.Run("route", "describe", routeName) out := it.Kn().Run("route", "describe", routeName)
assert.Check(t, util.ContainsAll(out.Stdout, assert.Check(t, util.ContainsAll(out.Stdout,
routeName, test.kn.namespace, "URL", "Service", "Traffic", "Targets", "Conditions")) routeName, it.Kn().Namespace(), "URL", "Service", "Traffic", "Targets", "Conditions"))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) routeDescribeWithPrintFlags(t *testing.T, r *KnRunResultCollector, routeName string) { func routeDescribeWithPrintFlags(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, routeName string) {
out := test.kn.Run("route", "describe", routeName, "-o=name") out := it.Kn().Run("route", "describe", routeName, "-o=name")
expectedName := fmt.Sprintf("route.serving.knative.dev/%s", routeName) expectedName := fmt.Sprintf("route.serving.knative.dev/%s", routeName)
assert.Equal(t, strings.TrimSpace(out.Stdout), expectedName) assert.Equal(t, strings.TrimSpace(out.Stdout), expectedName)
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) routeListWithPrintFlags(t *testing.T, r *KnRunResultCollector, names ...string) { func routeListWithPrintFlags(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, names ...string) {
out := test.kn.Run("route", "list", "-o=jsonpath={.items[*].metadata.name}") out := it.Kn().Run("route", "list", "-o=jsonpath={.items[*].metadata.name}")
assert.Check(t, util.ContainsAll(out.Stdout, names...)) assert.Check(t, util.ContainsAll(out.Stdout, names...))
r.AssertNoError(out) r.AssertNoError(out)
} }

View File

@ -23,12 +23,14 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"knative.dev/pkg/ptr" "knative.dev/pkg/ptr"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"knative.dev/client/lib/test"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
servingv1 "knative.dev/serving/pkg/apis/serving/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1"
) )
@ -36,60 +38,64 @@ type expectedServiceOption func(*servingv1.Service)
func TestServiceExportImportApply(t *testing.T) { func TestServiceExportImportApply(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
t.Log("create service with byo revision") t.Log("create service with byo revision")
test.serviceCreateWithOptions(t, r, "hello", "--revision-name", "rev1") serviceCreateWithOptions(t, it, r, "hello", "--revision-name", "rev1")
t.Log("export service and compare") t.Log("export service and compare")
test.serviceExport(t, r, "hello", getSvc(withName("hello"), withRevisionName("hello-rev1"), withAnnotations()), "-o", "json") serviceExport(t, it, r, "hello", getSvc(withName("hello"), withRevisionName("hello-rev1"), withAnnotations()), "-o", "json")
t.Log("update service - add env variable") t.Log("update service - add env variable")
test.serviceUpdateWithOptions(t, r, "hello", "--env", "key1=val1", "--revision-name", "rev2", "--no-lock-to-digest") serviceUpdateWithOptions(t, it, r, "hello", "--env", "key1=val1", "--revision-name", "rev2", "--no-lock-to-digest")
test.serviceExport(t, r, "hello", getSvc(withName("hello"), withRevisionName("hello-rev2"), withEnv("key1", "val1")), "-o", "json") serviceExport(t, it, r, "hello", getSvc(withName("hello"), withRevisionName("hello-rev2"), withEnv("key1", "val1")), "-o", "json")
test.serviceExportWithRevisions(t, r, "hello", getSvcListWithOneRevision(), "--with-revisions", "-o", "yaml") serviceExportWithRevisions(t, it, r, "hello", getSvcListWithOneRevision(), "--with-revisions", "-o", "yaml")
t.Log("update service with tag and split traffic") t.Log("update service with tag and split traffic")
test.serviceUpdateWithOptions(t, r, "hello", "--tag", "hello-rev1=candidate", "--traffic", "candidate=2%,@latest=98%") serviceUpdateWithOptions(t, it, r, "hello", "--tag", "hello-rev1=candidate", "--traffic", "candidate=2%,@latest=98%")
test.serviceExportWithRevisions(t, r, "hello", getSvcListWithTags(), "--with-revisions", "-o", "yaml") serviceExportWithRevisions(t, it, r, "hello", getSvcListWithTags(), "--with-revisions", "-o", "yaml")
t.Log("update service - untag, add env variable and traffic split") t.Log("update service - untag, add env variable and traffic split")
test.serviceUpdateWithOptions(t, r, "hello", "--untag", "candidate") serviceUpdateWithOptions(t, it, r, "hello", "--untag", "candidate")
test.serviceUpdateWithOptions(t, r, "hello", "--env", "key2=val2", "--revision-name", "rev3", "--traffic", "hello-rev1=30,hello-rev2=30,hello-rev3=40") serviceUpdateWithOptions(t, it, r, "hello", "--env", "key2=val2", "--revision-name", "rev3", "--traffic", "hello-rev1=30,hello-rev2=30,hello-rev3=40")
test.serviceExportWithRevisions(t, r, "hello", getSvcListWOTags(), "--with-revisions", "-o", "yaml") serviceExportWithRevisions(t, it, r, "hello", getSvcListWOTags(), "--with-revisions", "-o", "yaml")
} }
func (test *e2eTest) serviceExport(t *testing.T, r *KnRunResultCollector, serviceName string, expService servingv1.Service, options ...string) { // Private methods
func serviceExport(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, expService servingv1.Service, options ...string) {
command := []string{"service", "export", serviceName} command := []string{"service", "export", serviceName}
command = append(command, options...) command = append(command, options...)
out := test.kn.Run(command...) out := it.Kn().Run(command...)
validateExportedService(t, out.Stdout, expService) validateExportedService(t, it, out.Stdout, expService)
r.AssertNoError(out) r.AssertNoError(out)
} }
func validateExportedService(t *testing.T, out string, expService servingv1.Service) { func serviceExportWithRevisions(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, expServiceList servingv1.ServiceList, options ...string) {
command := []string{"service", "export", serviceName}
command = append(command, options...)
out := it.Kn().Run(command...)
validateExportedServiceList(t, it, out.Stdout, expServiceList)
r.AssertNoError(out)
}
// Private functions
func validateExportedService(t *testing.T, it *test.KnTest, out string, expService servingv1.Service) {
actSvcJSON := servingv1.Service{} actSvcJSON := servingv1.Service{}
err := json.Unmarshal([]byte(out), &actSvcJSON) err := json.Unmarshal([]byte(out), &actSvcJSON)
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, &expService, &actSvcJSON) assert.DeepEqual(t, &expService, &actSvcJSON)
} }
func (test *e2eTest) serviceExportWithRevisions(t *testing.T, r *KnRunResultCollector, serviceName string, expServiceList servingv1.ServiceList, options ...string) { func validateExportedServiceList(t *testing.T, it *test.KnTest, out string, expServiceList servingv1.ServiceList) {
command := []string{"service", "export", serviceName}
command = append(command, options...)
out := test.kn.Run(command...)
validateExportedServiceList(t, out.Stdout, expServiceList)
r.AssertNoError(out)
}
func validateExportedServiceList(t *testing.T, out string, expServiceList servingv1.ServiceList) {
actYaml := servingv1.ServiceList{} actYaml := servingv1.ServiceList{}
err := yaml.Unmarshal([]byte(out), &actYaml) err := yaml.Unmarshal([]byte(out), &actYaml)
assert.NilError(t, err) assert.NilError(t, err)
@ -108,7 +114,7 @@ func getSvc(options ...expectedServiceOption) servingv1.Service {
Containers: []corev1.Container{ Containers: []corev1.Container{
{ {
Name: "user-container", Name: "user-container",
Image: KnDefaultTestImage, Image: test.KnDefaultTestImage,
Resources: corev1.ResourceRequirements{}, Resources: corev1.ResourceRequirements{},
ReadinessProbe: &corev1.Probe{ ReadinessProbe: &corev1.Probe{
SuccessThreshold: int32(1), SuccessThreshold: int32(1),

View File

@ -26,76 +26,79 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
servingv1 "knative.dev/serving/pkg/apis/serving/v1" servingv1 "knative.dev/serving/pkg/apis/serving/v1"
) )
func TestServiceOptions(t *testing.T) { func TestServiceOptions(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
t.Log("create and validate service with concurrency options") t.Log("create and validate service with concurrency options")
defer r.DumpIfFailed() defer r.DumpIfFailed()
test.serviceCreateWithOptions(t, r, "svc1", "--concurrency-limit", "250", "--concurrency-target", "300") serviceCreateWithOptions(t, it, r, "svc1", "--concurrency-limit", "250", "--concurrency-target", "300")
test.validateServiceConcurrencyTarget(t, r, "svc1", "300") validateServiceConcurrencyTarget(t, it, r, "svc1", "300")
test.validateServiceConcurrencyLimit(t, r, "svc1", "250") validateServiceConcurrencyLimit(t, it, r, "svc1", "250")
t.Log("update and validate service with concurrency limit") t.Log("update and validate service with concurrency limit")
test.serviceUpdate(t, r, "svc1", "--concurrency-limit", "300") serviceUpdate(t, it, r, "svc1", "--concurrency-limit", "300")
test.validateServiceConcurrencyLimit(t, r, "svc1", "300") validateServiceConcurrencyLimit(t, it, r, "svc1", "300")
t.Log("update concurrency options with invalid values for service") t.Log("update concurrency options with invalid values for service")
out := test.kn.Run("service", "update", "svc1", "--concurrency-limit", "-1", "--concurrency-target", "0") out := it.Kn().Run("service", "update", "svc1", "--concurrency-limit", "-1", "--concurrency-target", "0")
r.AssertError(out) r.AssertError(out)
assert.Check(t, util.ContainsAll(out.Stderr, "invalid")) assert.Check(t, util.ContainsAll(out.Stderr, "invalid"))
t.Log("returns steady concurrency options for service") t.Log("returns steady concurrency options for service")
test.validateServiceConcurrencyLimit(t, r, "svc1", "300") validateServiceConcurrencyLimit(t, it, r, "svc1", "300")
test.validateServiceConcurrencyTarget(t, r, "svc1", "300") validateServiceConcurrencyTarget(t, it, r, "svc1", "300")
t.Log("delete service") t.Log("delete service")
test.serviceDelete(t, r, "svc1") serviceDelete(t, it, r, "svc1")
t.Log("create and validate service with min/max scale options ") t.Log("create and validate service with min/max scale options ")
test.serviceCreateWithOptions(t, r, "svc2", "--min-scale", "1", "--max-scale", "3") serviceCreateWithOptions(t, it, r, "svc2", "--min-scale", "1", "--max-scale", "3")
test.validateServiceMinScale(t, r, "svc2", "1") validateServiceMinScale(t, it, r, "svc2", "1")
test.validateServiceMaxScale(t, r, "svc2", "3") validateServiceMaxScale(t, it, r, "svc2", "3")
t.Log("update and validate service with max scale option") t.Log("update and validate service with max scale option")
test.serviceUpdate(t, r, "svc2", "--max-scale", "2") serviceUpdate(t, it, r, "svc2", "--max-scale", "2")
test.validateServiceMaxScale(t, r, "svc2", "2") validateServiceMaxScale(t, it, r, "svc2", "2")
t.Log("delete service") t.Log("delete service")
test.serviceDelete(t, r, "svc2") serviceDelete(t, it, r, "svc2")
t.Log("create, update and validate service with annotations") t.Log("create, update and validate service with annotations")
test.serviceCreateWithOptions(t, r, "svc3", "--annotation", "alpha=wolf", "--annotation", "brave=horse") serviceCreateWithOptions(t, it, r, "svc3", "--annotation", "alpha=wolf", "--annotation", "brave=horse")
test.validateServiceAnnotations(t, r, "svc3", map[string]string{"alpha": "wolf", "brave": "horse"}) validateServiceAnnotations(t, it, r, "svc3", map[string]string{"alpha": "wolf", "brave": "horse"})
test.serviceUpdate(t, r, "svc3", "--annotation", "alpha=direwolf", "--annotation", "brave-") serviceUpdate(t, it, r, "svc3", "--annotation", "alpha=direwolf", "--annotation", "brave-")
test.validateServiceAnnotations(t, r, "svc3", map[string]string{"alpha": "direwolf", "brave": ""}) validateServiceAnnotations(t, it, r, "svc3", map[string]string{"alpha": "direwolf", "brave": ""})
test.serviceDelete(t, r, "svc3") serviceDelete(t, it, r, "svc3")
t.Log("create, update and validate service with autoscale window option") t.Log("create, update and validate service with autoscale window option")
test.serviceCreateWithOptions(t, r, "svc4", "--autoscale-window", "1m") serviceCreateWithOptions(t, it, r, "svc4", "--autoscale-window", "1m")
test.validateAutoscaleWindow(t, r, "svc4", "1m") validateAutoscaleWindow(t, it, r, "svc4", "1m")
test.serviceUpdate(t, r, "svc4", "--autoscale-window", "15s") serviceUpdate(t, it, r, "svc4", "--autoscale-window", "15s")
test.validateAutoscaleWindow(t, r, "svc4", "15s") validateAutoscaleWindow(t, it, r, "svc4", "15s")
test.serviceDelete(t, r, "svc4") serviceDelete(t, it, r, "svc4")
t.Log("create, update and validate service with cmd and arg options") t.Log("create, update and validate service with cmd and arg options")
test.serviceCreateWithOptions(t, r, "svc5", "--cmd", "/go/bin/helloworld") serviceCreateWithOptions(t, it, r, "svc5", "--cmd", "/go/bin/helloworld")
test.validateContainerField(t, r, "svc5", "command", "[/go/bin/helloworld]") validateContainerField(t, it, r, "svc5", "command", "[/go/bin/helloworld]")
test.serviceUpdate(t, r, "svc5", "--arg", "myArg1", "--arg", "--myArg2") serviceUpdate(t, it, r, "svc5", "--arg", "myArg1", "--arg", "--myArg2")
test.validateContainerField(t, r, "svc5", "args", "[myArg1 --myArg2]") validateContainerField(t, it, r, "svc5", "args", "[myArg1 --myArg2]")
test.serviceUpdate(t, r, "svc5", "--arg", "myArg1") serviceUpdate(t, it, r, "svc5", "--arg", "myArg1")
test.validateContainerField(t, r, "svc5", "args", "[myArg1]") validateContainerField(t, it, r, "svc5", "args", "[myArg1]")
t.Log("create, update and validate service with user defined") t.Log("create, update and validate service with user defined")
var uid int64 = 1000 var uid int64 = 1000
@ -103,79 +106,79 @@ func TestServiceOptions(t *testing.T) {
uid, err = strconv.ParseInt(uids, 10, 64) uid, err = strconv.ParseInt(uids, 10, 64)
assert.NilError(t, err) assert.NilError(t, err)
} }
test.serviceCreateWithOptions(t, r, "svc6", "--user", strconv.FormatInt(uid, 10)) serviceCreateWithOptions(t, it, r, "svc6", "--user", strconv.FormatInt(uid, 10))
test.validateUserId(t, r, "svc6", uid) validateUserId(t, it, r, "svc6", uid)
test.serviceUpdate(t, r, "svc6", "--user", strconv.FormatInt(uid+1, 10)) serviceUpdate(t, it, r, "svc6", "--user", strconv.FormatInt(uid+1, 10))
test.validateUserId(t, r, "svc6", uid+1) validateUserId(t, it, r, "svc6", uid+1)
} }
func (test *e2eTest) serviceCreateWithOptions(t *testing.T, r *KnRunResultCollector, serviceName string, options ...string) { func serviceCreateWithOptions(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, options ...string) {
command := []string{"service", "create", serviceName, "--image", KnDefaultTestImage} command := []string{"service", "create", serviceName, "--image", test.KnDefaultTestImage}
command = append(command, options...) command = append(command, options...)
out := test.kn.Run(command...) out := it.Kn().Run(command...)
assert.Check(t, util.ContainsAll(out.Stdout, "service", serviceName, "Creating", "namespace", test.kn.namespace, "Ready")) assert.Check(t, util.ContainsAll(out.Stdout, "service", serviceName, "Creating", "namespace", it.Kn().Namespace(), "Ready"))
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) validateServiceConcurrencyLimit(t *testing.T, r *KnRunResultCollector, serviceName, concurrencyLimit string) { func validateServiceConcurrencyLimit(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName, concurrencyLimit string) {
jsonpath := "jsonpath={.items[0].spec.template.spec.containerConcurrency}" jsonpath := "jsonpath={.items[0].spec.template.spec.containerConcurrency}"
out := test.kn.Run("service", "list", serviceName, "-o", jsonpath) out := it.Kn().Run("service", "list", serviceName, "-o", jsonpath)
assert.Equal(t, out.Stdout, concurrencyLimit) assert.Equal(t, out.Stdout, concurrencyLimit)
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) validateServiceConcurrencyTarget(t *testing.T, r *KnRunResultCollector, serviceName, concurrencyTarget string) { func validateServiceConcurrencyTarget(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName, concurrencyTarget string) {
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/target}" jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/target}"
out := test.kn.Run("service", "list", serviceName, "-o", jsonpath) out := it.Kn().Run("service", "list", serviceName, "-o", jsonpath)
assert.Equal(t, out.Stdout, concurrencyTarget) assert.Equal(t, out.Stdout, concurrencyTarget)
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) validateAutoscaleWindow(t *testing.T, r *KnRunResultCollector, serviceName, window string) { func validateAutoscaleWindow(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName, window string) {
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/window}" jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/window}"
out := test.kn.Run("service", "list", serviceName, "-o", jsonpath) out := it.Kn().Run("service", "list", serviceName, "-o", jsonpath)
assert.Equal(t, out.Stdout, window) assert.Equal(t, out.Stdout, window)
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) validateServiceMinScale(t *testing.T, r *KnRunResultCollector, serviceName, minScale string) { func validateServiceMinScale(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName, minScale string) {
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/minScale}" jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/minScale}"
out := test.kn.Run("service", "list", serviceName, "-o", jsonpath) out := it.Kn().Run("service", "list", serviceName, "-o", jsonpath)
assert.Equal(t, out.Stdout, minScale) assert.Equal(t, out.Stdout, minScale)
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) validateServiceMaxScale(t *testing.T, r *KnRunResultCollector, serviceName, maxScale string) { func validateServiceMaxScale(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName, maxScale string) {
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/maxScale}" jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/maxScale}"
out := test.kn.Run("service", "list", serviceName, "-o", jsonpath) out := it.Kn().Run("service", "list", serviceName, "-o", jsonpath)
assert.Equal(t, out.Stdout, maxScale) assert.Equal(t, out.Stdout, maxScale)
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) validateServiceAnnotations(t *testing.T, r *KnRunResultCollector, serviceName string, annotations map[string]string) { func validateServiceAnnotations(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, annotations map[string]string) {
metadataAnnotationsJsonpathFormat := "jsonpath={.metadata.annotations.%s}" metadataAnnotationsJsonpathFormat := "jsonpath={.metadata.annotations.%s}"
templateAnnotationsJsonpathFormat := "jsonpath={.spec.template.metadata.annotations.%s}" templateAnnotationsJsonpathFormat := "jsonpath={.spec.template.metadata.annotations.%s}"
for k, v := range annotations { for k, v := range annotations {
out := test.kn.Run("service", "describe", serviceName, "-o", fmt.Sprintf(metadataAnnotationsJsonpathFormat, k)) out := it.Kn().Run("service", "describe", serviceName, "-o", fmt.Sprintf(metadataAnnotationsJsonpathFormat, k))
assert.Equal(t, v, out.Stdout) assert.Equal(t, v, out.Stdout)
r.AssertNoError(out) r.AssertNoError(out)
out = test.kn.Run("service", "describe", serviceName, "-o", fmt.Sprintf(templateAnnotationsJsonpathFormat, k)) out = it.Kn().Run("service", "describe", serviceName, "-o", fmt.Sprintf(templateAnnotationsJsonpathFormat, k))
assert.Equal(t, v, out.Stdout) assert.Equal(t, v, out.Stdout)
r.AssertNoError(out) r.AssertNoError(out)
} }
} }
func (test *e2eTest) validateContainerField(t *testing.T, r *KnRunResultCollector, serviceName, field, expected string) { func validateContainerField(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName, field, expected string) {
jsonpath := fmt.Sprintf("jsonpath={.items[0].spec.template.spec.containers[0].%s}", field) jsonpath := fmt.Sprintf("jsonpath={.items[0].spec.template.spec.containers[0].%s}", field)
out := test.kn.Run("service", "list", serviceName, "-o", jsonpath) out := it.Kn().Run("service", "list", serviceName, "-o", jsonpath)
assert.Equal(t, out.Stdout, expected) assert.Equal(t, out.Stdout, expected)
r.AssertNoError(out) r.AssertNoError(out)
} }
func (test *e2eTest) validateUserId(t *testing.T, r *KnRunResultCollector, serviceName string, uid int64) { func validateUserId(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, uid int64) {
out := test.kn.Run("service", "describe", serviceName, "-ojson") out := it.Kn().Run("service", "describe", serviceName, "-ojson")
data := json.NewDecoder(strings.NewReader(out.Stdout)) data := json.NewDecoder(strings.NewReader(out.Stdout))
data.UseNumber() data.UseNumber()
var service servingv1.Service var service servingv1.Service

View File

@ -23,110 +23,112 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
"knative.dev/serving/pkg/apis/serving" "knative.dev/serving/pkg/apis/serving"
) )
func TestService(t *testing.T) { func TestService(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
t.Log("create hello service, delete, and try to create duplicate and get service already exists error") t.Log("create hello service, delete, and try to create duplicate and get service already exists error")
test.serviceCreate(t, r, "hello") serviceCreate(t, it, r, "hello")
test.serviceCreatePrivate(t, r, "hello-private") serviceCreatePrivate(t, it, r, "hello-private")
test.serviceCreateDuplicate(t, r, "hello-private") serviceCreateDuplicate(t, it, r, "hello-private")
t.Log("return valid info about hello service with print flags") t.Log("return valid info about hello service with print flags")
test.serviceDescribeWithPrintFlags(t, r, "hello") serviceDescribeWithPrintFlags(t, it, r, "hello")
t.Log("delete hello service repeatedly and get an error") t.Log("delete hello service repeatedly and get an error")
test.serviceDelete(t, r, "hello") serviceDelete(t, it, r, "hello")
test.serviceDeleteNonexistent(t, r, "hello") serviceDeleteNonexistent(t, it, r, "hello")
t.Log("delete two services with a service nonexistent") t.Log("delete two services with a service nonexistent")
test.serviceCreate(t, r, "hello") serviceCreate(t, it, r, "hello")
test.serviceMultipleDelete(t, r, "hello", "bla123") serviceMultipleDelete(t, it, r, "hello", "bla123")
t.Log("create service private and make public") t.Log("create service private and make public")
test.serviceCreatePrivateUpdatePublic(t, r, "hello-private-public") serviceCreatePrivateUpdatePublic(t, it, r, "hello-private-public")
} }
func (test *e2eTest) serviceCreatePrivate(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceCreatePrivate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "create", serviceName, out := it.Kn().Run("service", "create", serviceName,
"--image", KnDefaultTestImage, "--cluster-local") "--image", test.KnDefaultTestImage, "--cluster-local")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "creating", "namespace", test.kn.namespace, "ready")) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "creating", "namespace", it.Kn().Namespace(), "ready"))
out = test.kn.Run("service", "describe", serviceName, "--verbose") out = it.Kn().Run("service", "describe", serviceName, "--verbose")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, serving.VisibilityLabelKey, serving.VisibilityClusterLocal)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, serving.VisibilityLabelKey, serving.VisibilityClusterLocal))
} }
func (test *e2eTest) serviceCreatePrivateUpdatePublic(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceCreatePrivateUpdatePublic(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "create", serviceName, out := it.Kn().Run("service", "create", serviceName,
"--image", KnDefaultTestImage, "--cluster-local") "--image", test.KnDefaultTestImage, "--cluster-local")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "creating", "namespace", test.kn.namespace, "ready")) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "creating", "namespace", it.Kn().Namespace(), "ready"))
out = test.kn.Run("service", "describe", serviceName, "--verbose") out = it.Kn().Run("service", "describe", serviceName, "--verbose")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, serving.VisibilityLabelKey, serving.VisibilityClusterLocal)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, serving.VisibilityLabelKey, serving.VisibilityClusterLocal))
out = test.kn.Run("service", "update", serviceName, out = it.Kn().Run("service", "update", serviceName,
"--image", KnDefaultTestImage, "--no-cluster-local") "--image", test.KnDefaultTestImage, "--no-cluster-local")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "updated", "namespace", test.kn.namespace, "ready")) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "service", serviceName, "updated", "namespace", it.Kn().Namespace(), "ready"))
out = test.kn.Run("service", "describe", serviceName, "--verbose") out = it.Kn().Run("service", "describe", serviceName, "--verbose")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsNone(out.Stdout, serving.VisibilityLabelKey, serving.VisibilityClusterLocal)) assert.Check(t, util.ContainsNone(out.Stdout, serving.VisibilityLabelKey, serving.VisibilityClusterLocal))
} }
func (test *e2eTest) serviceCreateDuplicate(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceCreateDuplicate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "list", serviceName) out := it.Kn().Run("service", "list", serviceName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, strings.Contains(out.Stdout, serviceName), "The service does not exist yet") assert.Check(t, strings.Contains(out.Stdout, serviceName), "The service does not exist yet")
out = test.kn.Run("service", "create", serviceName, "--image", KnDefaultTestImage) out = it.Kn().Run("service", "create", serviceName, "--image", test.KnDefaultTestImage)
r.AssertError(out) r.AssertError(out)
assert.Check(t, util.ContainsAll(out.Stderr, "the service already exists")) assert.Check(t, util.ContainsAll(out.Stderr, "the service already exists"))
} }
func (test *e2eTest) serviceDescribeWithPrintFlags(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceDescribeWithPrintFlags(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "describe", serviceName, "-o=name") out := it.Kn().Run("service", "describe", serviceName, "-o=name")
r.AssertNoError(out) r.AssertNoError(out)
expectedName := fmt.Sprintf("service.serving.knative.dev/%s", serviceName) expectedName := fmt.Sprintf("service.serving.knative.dev/%s", serviceName)
assert.Equal(t, strings.TrimSpace(out.Stdout), expectedName) assert.Equal(t, strings.TrimSpace(out.Stdout), expectedName)
} }
func (test *e2eTest) serviceDeleteNonexistent(t *testing.T, r *KnRunResultCollector, serviceName string) { func serviceDeleteNonexistent(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string) {
out := test.kn.Run("service", "list", serviceName) out := it.Kn().Run("service", "list", serviceName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, !strings.Contains(out.Stdout, serviceName), "The service exists") assert.Check(t, !strings.Contains(out.Stdout, serviceName), "The service exists")
out = test.kn.Run("service", "delete", serviceName) out = it.Kn().Run("service", "delete", serviceName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, "hello", "not found"), "Failed to get 'not found' error") assert.Check(t, util.ContainsAll(out.Stdout, "hello", "not found"), "Failed to get 'not found' error")
} }
func (test *e2eTest) serviceMultipleDelete(t *testing.T, r *KnRunResultCollector, existService, nonexistService string) { func serviceMultipleDelete(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, existService, nonexistService string) {
out := test.kn.Run("service", "list") out := it.Kn().Run("service", "list")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, strings.Contains(out.Stdout, existService), "The service ", existService, " does not exist (but is expected to exist)") assert.Check(t, strings.Contains(out.Stdout, existService), "The service ", existService, " does not exist (but is expected to exist)")
assert.Check(t, !strings.Contains(out.Stdout, nonexistService), "The service", nonexistService, " exists (but is supposed to be not)") assert.Check(t, !strings.Contains(out.Stdout, nonexistService), "The service", nonexistService, " exists (but is supposed to be not)")
out = test.kn.Run("service", "delete", existService, nonexistService) out = it.Kn().Run("service", "delete", existService, nonexistService)
r.AssertNoError(out) r.AssertNoError(out)
expectedSuccess := fmt.Sprintf(`Service '%s' successfully deleted in namespace '%s'.`, existService, test.kn.namespace) expectedSuccess := fmt.Sprintf(`Service '%s' successfully deleted in namespace '%s'.`, existService, it.Kn().Namespace())
expectedErr := fmt.Sprintf(`services.serving.knative.dev "%s" not found`, nonexistService) expectedErr := fmt.Sprintf(`services.serving.knative.dev "%s" not found`, nonexistService)
assert.Check(t, strings.Contains(out.Stdout, expectedSuccess), "Failed to get 'successfully deleted' message") assert.Check(t, strings.Contains(out.Stdout, expectedSuccess), "Failed to get 'successfully deleted' message")
assert.Check(t, strings.Contains(out.Stdout, expectedErr), "Failed to get 'not found' error") assert.Check(t, strings.Contains(out.Stdout, expectedErr), "Failed to get 'not found' error")

View File

@ -22,6 +22,8 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
@ -57,13 +59,13 @@ func (tc *sinkprefixTestConfig) teardown() {
func TestSinkPrefixConfig(t *testing.T) { func TestSinkPrefixConfig(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
tc := sinkprefixTestConfig{} tc := sinkprefixTestConfig{}
@ -71,22 +73,22 @@ func TestSinkPrefixConfig(t *testing.T) {
defer tc.teardown() defer tc.teardown()
t.Log("Creating a testservice") t.Log("Creating a testservice")
test.serviceCreate(t, r, "testsvc0") serviceCreate(t, it, r, "testsvc0")
t.Log("create Ping sources with a sink to hello:testsvc0") t.Log("create Ping sources with a sink to hello:testsvc0")
test.pingSourceCreateWithConfig(t, r, "testpingsource0", "* * * * */1", "ping", "hello:testsvc0", tc.knConfigPath) pingSourceCreateWithConfig(t, it, r, "testpingsource0", "* * * * */1", "ping", "hello:testsvc0", tc.knConfigPath)
jpSinkRefNameInSpec := "jsonpath={.spec.sink.ref.name}" jpSinkRefNameInSpec := "jsonpath={.spec.sink.ref.name}"
out, err := test.getResourceFieldsWithJSONPath("pingsource", "testpingsource0", jpSinkRefNameInSpec) out, err := getResourceFieldsWithJSONPath(t, it, "pingsource", "testpingsource0", jpSinkRefNameInSpec)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out, "testsvc0") assert.Equal(t, out, "testsvc0")
t.Log("delete Ping sources") t.Log("delete Ping sources")
test.pingSourceDelete(t, r, "testpingsource0") pingSourceDelete(t, it, r, "testpingsource0")
} }
func (test *e2eTest) pingSourceCreateWithConfig(t *testing.T, r *KnRunResultCollector, sourceName string, schedule string, data string, sink string, config string) { func pingSourceCreateWithConfig(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, schedule string, data string, sink string, config string) {
out := test.kn.Run("source", "ping", "create", sourceName, out := it.Kn().Run("source", "ping", "create", sourceName,
"--schedule", schedule, "--data", data, "--sink", sink, "--config", config) "--schedule", schedule, "--data", data, "--sink", sink, "--config", config)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "ping", "source", sourceName, "created", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "ping", "source", sourceName, "created", "namespace", it.Kn().Namespace()))
r.AssertNoError(out) r.AssertNoError(out)
} }

View File

@ -25,6 +25,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
@ -37,117 +38,116 @@ const (
func TestSourceApiServer(t *testing.T) { func TestSourceApiServer(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
err1 := test.tearDownForSourceApiServer() err1 := tearDownForSourceApiServer(t, it)
err2 := test.Teardown() err2 := it.Teardown()
assert.NilError(t, err1) assert.NilError(t, err1)
assert.NilError(t, err2) assert.NilError(t, err2)
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
test.setupForSourceApiServer(t) setupForSourceApiServer(t, it)
test.serviceCreate(t, r, "testsvc0") serviceCreate(t, it, r, "testsvc0")
t.Log("create apiserver sources with a sink to a service") t.Log("create apiserver sources with a sink to a service")
test.apiServerSourceCreate(t, r, "testapisource0", "Event:v1:true", "testsa", "svc:testsvc0") apiServerSourceCreate(t, it, r, "testapisource0", "Event:v1:true", "testsa", "svc:testsvc0")
test.apiServerSourceCreate(t, r, "testapisource1", "Event:v1", "testsa", "svc:testsvc0") apiServerSourceCreate(t, it, r, "testapisource1", "Event:v1", "testsa", "svc:testsvc0")
t.Log("list sources") t.Log("list sources")
output := test.sourceList(t, r) output := sourceList(t, it, r)
assert.Check(t, util.ContainsAll(output, "NAME", "TYPE", "RESOURCE", "SINK", "READY")) assert.Check(t, util.ContainsAll(output, "NAME", "TYPE", "RESOURCE", "SINK", "READY"))
assert.Check(t, util.ContainsAll(output, "testapisource0", "ApiServerSource", "apiserversources.sources.knative.dev", "svc:testsvc0")) assert.Check(t, util.ContainsAll(output, "testapisource0", "ApiServerSource", "apiserversources.sources.knative.dev", "svc:testsvc0"))
assert.Check(t, util.ContainsAll(output, "testapisource1", "ApiServerSource", "apiserversources.sources.knative.dev", "svc:testsvc0")) assert.Check(t, util.ContainsAll(output, "testapisource1", "ApiServerSource", "apiserversources.sources.knative.dev", "svc:testsvc0"))
t.Log("list sources in YAML format") t.Log("list sources in YAML format")
output = test.sourceList(t, r, "-oyaml") output = sourceList(t, it, r, "-oyaml")
assert.Check(t, util.ContainsAll(output, "testapisource1", "ApiServerSource", "Service", "testsvc0")) assert.Check(t, util.ContainsAll(output, "testapisource1", "ApiServerSource", "Service", "testsvc0"))
t.Log("delete apiserver sources") t.Log("delete apiserver sources")
test.apiServerSourceDelete(t, r, "testapisource0") apiServerSourceDelete(t, it, r, "testapisource0")
test.apiServerSourceDelete(t, r, "testapisource1") apiServerSourceDelete(t, it, r, "testapisource1")
t.Log("create apiserver source with a missing sink service") t.Log("create apiserver source with a missing sink service")
test.apiServerSourceCreateMissingSink(t, r, "testapisource2", "Event:v1:true", "testsa", "svc:unknown") apiServerSourceCreateMissingSink(t, it, r, "testapisource2", "Event:v1:true", "testsa", "svc:unknown")
t.Log("update apiserver source sink service") t.Log("update apiserver source sink service")
test.apiServerSourceCreate(t, r, "testapisource3", "Event:v1:true", "testsa", "svc:testsvc0") apiServerSourceCreate(t, it, r, "testapisource3", "Event:v1:true", "testsa", "svc:testsvc0")
test.serviceCreate(t, r, "testsvc1") serviceCreate(t, it, r, "testsvc1")
test.apiServerSourceUpdateSink(t, r, "testapisource3", "svc:testsvc1") apiServerSourceUpdateSink(t, it, r, "testapisource3", "svc:testsvc1")
jpSinkRefNameInSpec := "jsonpath={.spec.sink.ref.name}" jpSinkRefNameInSpec := "jsonpath={.spec.sink.ref.name}"
out, err := test.getResourceFieldsWithJSONPath("apiserversource.sources.knative.dev", "testapisource3", jpSinkRefNameInSpec) out, err := getResourceFieldsWithJSONPath(t, it, "apiserversource.sources.knative.dev", "testapisource3", jpSinkRefNameInSpec)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out, "testsvc1") assert.Equal(t, out, "testsvc1")
// TODO(navidshaikh): Verify the source's status with synchronous create/update // TODO(navidshaikh): Verify the source's status with synchronous create/update
} }
func (test *e2eTest) apiServerSourceCreate(t *testing.T, r *KnRunResultCollector, sourceName string, resources string, sa string, sink string) { func apiServerSourceCreate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, resources string, sa string, sink string) {
out := test.kn.Run("source", "apiserver", "create", sourceName, "--resource", resources, "--service-account", sa, "--sink", sink) out := it.Kn().Run("source", "apiserver", "create", sourceName, "--resource", resources, "--service-account", sa, "--sink", sink)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "apiserver", "source", sourceName, "created", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "apiserver", "source", sourceName, "created", "namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) apiServerSourceCreateMissingSink(t *testing.T, r *KnRunResultCollector, sourceName string, resources string, sa string, sink string) { func apiServerSourceCreateMissingSink(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, resources string, sa string, sink string) {
out := test.kn.Run("source", "apiserver", "create", sourceName, "--resource", resources, "--service-account", sa, "--sink", sink) out := it.Kn().Run("source", "apiserver", "create", sourceName, "--resource", resources, "--service-account", sa, "--sink", sink)
r.AssertError(out) r.AssertError(out)
assert.Check(t, util.ContainsAll(out.Stderr, "services.serving.knative.dev", "not found")) assert.Check(t, util.ContainsAll(out.Stderr, "services.serving.knative.dev", "not found"))
} }
func (test *e2eTest) apiServerSourceDelete(t *testing.T, r *KnRunResultCollector, sourceName string) { func apiServerSourceDelete(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string) {
out := test.kn.Run("source", "apiserver", "delete", sourceName) out := it.Kn().Run("source", "apiserver", "delete", sourceName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "apiserver", "source", sourceName, "deleted", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "apiserver", "source", sourceName, "deleted", "namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) setupForSourceApiServer(t *testing.T) { func setupForSourceApiServer(t *testing.T, it *test.KnTest) {
_, err := kubectl{test.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 = kubectl{}.Run("create", "clusterrole", clusterRolePrefix+test.kn.namespace, "--verb=get,list,watch", "--resource=events,namespaces") _, err = test.Kubectl{}.Run("create", "clusterrole", clusterRolePrefix+it.Kn().Namespace(), "--verb=get,list,watch", "--resource=events,namespaces")
assert.NilError(t, err) assert.NilError(t, err)
_, err = kubectl{}.Run( _, err = test.Kubectl{}.Run(
"create", "create",
"clusterrolebinding", "clusterrolebinding",
clusterRoleBindingPrefix+test.kn.namespace, clusterRoleBindingPrefix+it.Kn().Namespace(),
"--clusterrole="+clusterRolePrefix+test.kn.namespace, "--clusterrole="+clusterRolePrefix+it.Kn().Namespace(),
"--serviceaccount="+test.kn.namespace+":"+testServiceAccount) "--serviceaccount="+it.Kn().Namespace()+":"+testServiceAccount)
assert.NilError(t, err) assert.NilError(t, err)
} }
func (test *e2eTest) tearDownForSourceApiServer() error { func tearDownForSourceApiServer(t *testing.T, it *test.KnTest) error {
saCmd := []string{"delete", "serviceaccount", testServiceAccount} saCmd := []string{"delete", "serviceaccount", testServiceAccount}
_, err := kubectl{test.kn.namespace}.Run(saCmd...) _, err := test.NewKubectl(it.Kn().Namespace()).Run(saCmd...)
if err != nil { if err != nil {
return errors.Wrap(err, fmt.Sprintf("Error executing '%s'", strings.Join(saCmd, " "))) return errors.Wrap(err, fmt.Sprintf("Error executing '%s'", strings.Join(saCmd, " ")))
} }
crCmd := []string{"delete", "clusterrole", clusterRolePrefix + test.kn.namespace} crCmd := []string{"delete", "clusterrole", clusterRolePrefix + it.Kn().Namespace()}
_, err = kubectl{}.Run(crCmd...) _, err = test.Kubectl{}.Run(crCmd...)
if err != nil { if err != nil {
return errors.Wrap(err, fmt.Sprintf("Error executing '%s'", strings.Join(saCmd, " "))) return errors.Wrap(err, fmt.Sprintf("Error executing '%s'", strings.Join(saCmd, " ")))
} }
crbCmd := []string{"delete", "clusterrolebinding", clusterRoleBindingPrefix + test.kn.namespace} crbCmd := []string{"delete", "clusterrolebinding", clusterRoleBindingPrefix + it.Kn().Namespace()}
_, err = kubectl{}.Run(crbCmd...) _, err = test.Kubectl{}.Run(crbCmd...)
if err != nil { if err != nil {
return errors.Wrap(err, fmt.Sprintf("Error executing '%s'", strings.Join(saCmd, " "))) return errors.Wrap(err, fmt.Sprintf("Error executing '%s'", strings.Join(saCmd, " ")))
} }
return nil return nil
} }
func (test *e2eTest) apiServerSourceUpdateSink(t *testing.T, r *KnRunResultCollector, sourceName string, sink string) { func apiServerSourceUpdateSink(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, sourceName string, sink string) {
out := test.kn.Run("source", "apiserver", "update", sourceName, "--sink", sink) out := it.Kn().Run("source", "apiserver", "update", sourceName, "--sink", sink)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, sourceName, "updated", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAll(out.Stdout, sourceName, "updated", "namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) getResourceFieldsWithJSONPath(resource, name, jsonpath string) (string, error) { func getResourceFieldsWithJSONPath(t *testing.T, it *test.KnTest, resource, name, jsonpath string) (string, error) {
out, err := kubectl{test.kn.namespace}.Run("get", resource, name, "-o", jsonpath, "-n", test.kn.namespace) out, err := test.NewKubectl(it.Kn().Namespace()).Run("get", resource, name, "-o", jsonpath, "-n", it.Kn().Namespace())
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -21,52 +21,54 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestSourceBinding(t *testing.T) { func TestSourceBinding(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
test.serviceCreate(t, r, "testsvc0") serviceCreate(t, it, r, "testsvc0")
t.Log("create source binding") t.Log("create source binding")
test.sourceBindingCreate(t, r, "my-binding0", "Deployment:apps/v1:myapp", "svc:testsvc0") sourceBindingCreate(t, it, r, "my-binding0", "Deployment:apps/v1:myapp", "svc:testsvc0")
t.Log("delete source binding") t.Log("delete source binding")
test.sourceBindingDelete(t, r, "my-binding0") sourceBindingDelete(t, it, r, "my-binding0")
t.Log("update source binding") t.Log("update source binding")
test.sourceBindingCreate(t, r, "my-binding1", "Deployment:apps/v1:myapp", "svc:testsvc0") sourceBindingCreate(t, it, r, "my-binding1", "Deployment:apps/v1:myapp", "svc:testsvc0")
test.serviceCreate(t, r, "testsvc1") serviceCreate(t, it, r, "testsvc1")
test.sourceBindingUpdate(t, r, "my-binding1", "Deployment:apps/v1:myapp", "svc:testsvc1") sourceBindingUpdate(t, it, r, "my-binding1", "Deployment:apps/v1:myapp", "svc:testsvc1")
jpSinkRefNameInSpec := "jsonpath={.spec.sink.ref.name}" jpSinkRefNameInSpec := "jsonpath={.spec.sink.ref.name}"
out, err := test.getResourceFieldsWithJSONPath("sinkbindings.sources.knative.dev", "my-binding1", jpSinkRefNameInSpec) out, err := getResourceFieldsWithJSONPath(t, it, "sinkbindings.sources.knative.dev", "my-binding1", jpSinkRefNameInSpec)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out, "testsvc1") assert.Equal(t, out, "testsvc1")
} }
func (test *e2eTest) sourceBindingCreate(t *testing.T, r *KnRunResultCollector, bindingName string, subject string, sink string) { func sourceBindingCreate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, bindingName string, subject string, sink string) {
out := test.kn.Run("source", "binding", "create", bindingName, "--subject", subject, "--sink", sink) out := it.Kn().Run("source", "binding", "create", bindingName, "--subject", subject, "--sink", sink)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Sink", "binding", bindingName, "created", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Sink", "binding", bindingName, "created", "namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) sourceBindingDelete(t *testing.T, r *KnRunResultCollector, bindingName string) { func sourceBindingDelete(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, bindingName string) {
out := test.kn.Run("source", "binding", "delete", bindingName) out := it.Kn().Run("source", "binding", "delete", bindingName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Sink", "binding", bindingName, "deleted", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Sink", "binding", bindingName, "deleted", "namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) sourceBindingUpdate(t *testing.T, r *KnRunResultCollector, bindingName string, subject string, sink string) { func sourceBindingUpdate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, bindingName string, subject string, sink string) {
out := test.kn.Run("source", "binding", "update", bindingName, "--subject", subject, "--sink", sink) out := it.Kn().Run("source", "binding", "update", bindingName, "--subject", subject, "--sink", sink)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, bindingName, "updated", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAll(out.Stdout, bindingName, "updated", "namespace", it.Kn().Namespace()))
} }

View File

@ -22,59 +22,60 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestSourceListTypes(t *testing.T) { func TestSourceListTypes(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
t.Log("List available source types") t.Log("List available source types")
output := test.sourceListTypes(t, r) output := sourceListTypes(t, it, r)
assert.Check(t, util.ContainsAll(output, "TYPE", "NAME", "DESCRIPTION", "Ping", "ApiServer")) assert.Check(t, util.ContainsAll(output, "TYPE", "NAME", "DESCRIPTION", "Ping", "ApiServer"))
t.Log("List available source types in YAML format") t.Log("List available source types in YAML format")
output = test.sourceListTypes(t, r, "-oyaml") output = sourceListTypes(t, it, r, "-oyaml")
assert.Check(t, util.ContainsAll(output, "apiextensions.k8s.io/v1beta1", "CustomResourceDefinition", "Ping", "ApiServer")) assert.Check(t, util.ContainsAll(output, "apiextensions.k8s.io/v1beta1", "CustomResourceDefinition", "Ping", "ApiServer"))
} }
func TestSourceList(t *testing.T) { func TestSourceList(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
t.Log("List sources empty case") t.Log("List sources empty case")
output := test.sourceList(t, r) output := sourceList(t, it, r)
assert.Check(t, util.ContainsAll(output, "No", "sources", "found", "namespace")) assert.Check(t, util.ContainsAll(output, "No", "sources", "found", "namespace"))
assert.Check(t, util.ContainsNone(output, "NAME", "TYPE", "RESOURCE", "SINK", "READY")) assert.Check(t, util.ContainsNone(output, "NAME", "TYPE", "RESOURCE", "SINK", "READY"))
// non empty list case is tested in test/e2e/source_apiserver_test.go where source setup is present // non empty list case is tested in test/e2e/source_apiserver_it.go where source setup is present
} }
func (test *e2eTest) sourceListTypes(t *testing.T, r *KnRunResultCollector, args ...string) string { func sourceListTypes(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, args ...string) string {
cmd := append([]string{"source", "list-types"}, args...) cmd := append([]string{"source", "list-types"}, args...)
out := test.kn.Run(cmd...) out := it.Kn().Run(cmd...)
r.AssertNoError(out) r.AssertNoError(out)
return out.Stdout return out.Stdout
} }
func (test *e2eTest) sourceList(t *testing.T, r *KnRunResultCollector, args ...string) string { func sourceList(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, args ...string) string {
cmd := append([]string{"source", "list"}, args...) cmd := append([]string{"source", "list"}, args...)
out := test.kn.Run(cmd...) out := it.Kn().Run(cmd...)
r.AssertNoError(out) r.AssertNoError(out)
return out.Stdout return out.Stdout
} }

View File

@ -23,6 +23,8 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
@ -34,19 +36,19 @@ const (
) )
func TestTektonPipeline(t *testing.T) { func TestTektonPipeline(t *testing.T) {
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
kubectl := kubectl{test.namespace} kubectl := test.NewKubectl(it.Namespace())
basedir := currentDir(t) + "/../resources/tekton" basedir := test.CurrentDir(t) + "/../resources/tekton"
// create secret for the kn-deployer-account service account // create secret for the kn-deployer-account service account
_, err = kubectl.Run("create", "-n", test.namespace, "secret", _, err = kubectl.Run("create", "-n", it.Namespace(), "secret",
"generic", "container-registry", "generic", "container-registry",
"--from-file=.dockerconfigjson="+Flags.DockerConfigJSON, "--from-file=.dockerconfigjson="+test.Flags.DockerConfigJSON,
"--type=kubernetes.io/dockerconfigjson") "--type=kubernetes.io/dockerconfigjson")
assert.NilError(t, err) assert.NilError(t, err)
@ -71,16 +73,16 @@ func TestTektonPipeline(t *testing.T) {
err = waitForPipelineSuccess(kubectl) err = waitForPipelineSuccess(kubectl)
assert.NilError(t, err) assert.NilError(t, err)
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
const serviceName = "hello" const serviceName = "hello"
out := test.kn.Run("service", "describe", serviceName) out := it.Kn().Run("service", "describe", serviceName)
r.AssertNoError(out) r.AssertNoError(out)
assert.Assert(t, util.ContainsAll(out.Stdout, serviceName, test.kn.namespace)) assert.Assert(t, util.ContainsAll(out.Stdout, serviceName, it.Kn().Namespace()))
assert.Assert(t, util.ContainsAll(out.Stdout, "Conditions", "ConfigurationsReady", "Ready", "RoutesReady")) assert.Assert(t, util.ContainsAll(out.Stdout, "Conditions", "ConfigurationsReady", "Ready", "RoutesReady"))
} }
func waitForPipelineSuccess(k kubectl) error { func waitForPipelineSuccess(k test.Kubectl) error {
return wait.PollImmediate(Interval, Timeout, func() (bool, error) { return wait.PollImmediate(Interval, Timeout, func() (bool, error) {
out, err := k.Run("get", "pipelinerun", "-o=jsonpath='{.items[0].status.conditions[?(@.type==\"Succeeded\")].status}'") out, err := k.Run("get", "pipelinerun", "-o=jsonpath='{.items[0].status.conditions[?(@.type==\"Succeeded\")].status}'")
return strings.Contains(out, "True"), err return strings.Contains(out, "True"), err

View File

@ -24,6 +24,8 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
@ -59,7 +61,7 @@ func splitTargets(s, separator string, partsCount int) ([]string, error) {
// formatActualTargets takes the traffic targets string received after jsonpath operation and converts // formatActualTargets takes the traffic targets string received after jsonpath operation and converts
// them into []TargetFields for comparison // them into []TargetFields for comparison
func formatActualTargets(t *testing.T, actualTargets []string) (formattedTargets []TargetFields) { func formatActualTargets(t *testing.T, it *test.KnTest, actualTargets []string) (formattedTargets []TargetFields) {
for _, each := range actualTargets { for _, each := range actualTargets {
each := strings.TrimSuffix(each, targetFieldsSeparator) each := strings.TrimSuffix(each, targetFieldsSeparator)
fields, err := splitTargets(each, targetFieldsSeparator, targetFieldsLength) fields, err := splitTargets(each, targetFieldsSeparator, targetFieldsLength)
@ -76,324 +78,324 @@ func formatActualTargets(t *testing.T, actualTargets []string) (formattedTargets
// TestTrafficSplitSuite runs different e2e tests for service traffic splitting and verifies the traffic targets from service status // TestTrafficSplitSuite runs different e2e tests for service traffic splitting and verifies the traffic targets from service status
func TestTrafficSplit(t *testing.T) { func TestTrafficSplit(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
serviceBase := "echo" serviceBase := "echo"
t.Run("50:50", t.Run("50:50",
func(t *testing.T) { func(t *testing.T) {
t.Log("tag two revisions as v1 and v2 and give 50-50% share") t.Log("tag two revisions as v1 and v2 and give 50-50% share")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
test.serviceCreate(t, r, serviceName) serviceCreate(t, it, r, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v1", "--revision-name", rev1) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v1", "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2)
tflags := []string{"--tag", fmt.Sprintf("%s=v1,%s=v2", rev1, rev2), tflags := []string{"--tag", fmt.Sprintf("%s=v1,%s=v2", rev1, rev2),
"--traffic", "v1=50,v2=50"} "--traffic", "v1=50,v2=50"}
test.serviceUpdateWithOptions(t, r, serviceName, tflags...) serviceUpdateWithOptions(t, it, r, serviceName, tflags...)
// make ordered fields per tflags (tag, revision, percent, latest) // make ordered fields per tflags (tag, revision, percent, latest)
expectedTargets := []TargetFields{newTargetFields("v1", rev1, 50, false), newTargetFields("v2", rev2, 50, false)} expectedTargets := []TargetFields{newTargetFields("v1", rev1, 50, false), newTargetFields("v2", rev2, 50, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("20:80", t.Run("20:80",
func(t *testing.T) { func(t *testing.T) {
t.Log("ramp/up down a revision to 20% adjusting other traffic to accommodate") t.Log("ramp/up down a revision to 20% adjusting other traffic to accommodate")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
test.serviceCreate(t, r, serviceName) serviceCreate(t, it, r, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v1", "--revision-name", rev1) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v1", "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2)
test.serviceUpdateWithOptions(t, r, serviceName, "--traffic", fmt.Sprintf("%s=20,%s=80", rev1, rev2)) serviceUpdateWithOptions(t, it, r, serviceName, "--traffic", fmt.Sprintf("%s=20,%s=80", rev1, rev2))
expectedTargets := []TargetFields{newTargetFields("", rev1, 20, false), newTargetFields("", rev2, 80, false)} expectedTargets := []TargetFields{newTargetFields("", rev1, 20, false), newTargetFields("", rev2, 80, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("TagCandidate", t.Run("TagCandidate",
func(t *testing.T) { func(t *testing.T) {
t.Log("tag a revision as candidate, without otherwise changing any traffic split") t.Log("tag a revision as candidate, without otherwise changing any traffic split")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v1", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v1", "--revision-name", rev2)
// no traffic, append new target with tag in traffic block // no traffic, append new target with tag in traffic block
test.serviceUpdateWithOptions(t, r, serviceName, "--tag", fmt.Sprintf("%s=%s", rev1, "candidate")) serviceUpdateWithOptions(t, it, r, serviceName, "--tag", fmt.Sprintf("%s=%s", rev1, "candidate"))
expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true), newTargetFields("candidate", rev1, 0, false)} expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true), newTargetFields("candidate", rev1, 0, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("TagCandidate:2:98", t.Run("TagCandidate:2:98",
func(t *testing.T) { func(t *testing.T) {
t.Log("tag a revision as candidate, set 2% traffic adjusting other traffic to accommodate") t.Log("tag a revision as candidate, set 2% traffic adjusting other traffic to accommodate")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v1", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v1", "--revision-name", rev2)
// traffic by tag name and use % at the end // traffic by tag name and use % at the end
test.serviceUpdateWithOptions(t, r, serviceName, serviceUpdateWithOptions(t, it, r, serviceName,
"--tag", fmt.Sprintf("%s=%s", rev1, "candidate"), "--tag", fmt.Sprintf("%s=%s", rev1, "candidate"),
"--traffic", "candidate=2%,@latest=98%") "--traffic", "candidate=2%,@latest=98%")
expectedTargets := []TargetFields{newTargetFields("", rev2, 98, true), newTargetFields("candidate", rev1, 2, false)} expectedTargets := []TargetFields{newTargetFields("", rev2, 98, true), newTargetFields("candidate", rev1, 2, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("TagCurrent", t.Run("TagCurrent",
func(t *testing.T) { func(t *testing.T) {
t.Log("update tag for a revision from candidate to current, tag current is present on another revision") t.Log("update tag for a revision from candidate to current, tag current is present on another revision")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
// make available 3 revisions for service first // make available 3 revisions for service first
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2)
rev3 := fmt.Sprintf("%s-rev-3", serviceName) rev3 := fmt.Sprintf("%s-rev-3", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v3", "--revision-name", rev3) //note that this gives 100% traffic to latest revision (rev3) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v3", "--revision-name", rev3) //note that this gives 100% traffic to latest revision (rev3)
// make existing state: tag current and candidate exist in traffic block // make existing state: tag current and candidate exist in traffic block
test.serviceUpdateWithOptions(t, r, serviceName, "--tag", fmt.Sprintf("%s=current,%s=candidate", rev1, rev2)) serviceUpdateWithOptions(t, it, r, serviceName, "--tag", fmt.Sprintf("%s=current,%s=candidate", rev1, rev2))
// desired state of tags: update tag of revision (rev2) from candidate to current (which is present on rev1) // desired state of tags: update tag of revision (rev2) from candidate to current (which is present on rev1)
//untag first to update //untag first to update
test.serviceUpdateWithOptions(t, r, serviceName, serviceUpdateWithOptions(t, it, r, serviceName,
"--untag", "current,candidate", "--untag", "current,candidate",
"--tag", fmt.Sprintf("%s=current", rev2)) "--tag", fmt.Sprintf("%s=current", rev2))
// there will be 2 targets in existing block 1. @latest, 2.for revision $rev2 // there will be 2 targets in existing block 1. @latest, 2.for revision $rev2
// target for rev1 is removed as it had no traffic and we untagged it's tag current // target for rev1 is removed as it had no traffic and we untagged it's tag current
expectedTargets := []TargetFields{newTargetFields("", rev3, 100, true), newTargetFields("current", rev2, 0, false)} expectedTargets := []TargetFields{newTargetFields("", rev3, 100, true), newTargetFields("current", rev2, 0, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("TagStagingLatest", t.Run("TagStagingLatest",
func(t *testing.T) { func(t *testing.T) {
t.Log("update tag from testing to staging for @latest revision") t.Log("update tag from testing to staging for @latest revision")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
// make existing state: tag @latest as testing // make existing state: tag @latest as testing
test.serviceUpdateWithOptions(t, r, serviceName, "--tag", "@latest=testing") serviceUpdateWithOptions(t, it, r, serviceName, "--tag", "@latest=testing")
// desired state: change tag from testing to staging // desired state: change tag from testing to staging
test.serviceUpdateWithOptions(t, r, serviceName, "--untag", "testing", "--tag", "@latest=staging") serviceUpdateWithOptions(t, it, r, serviceName, "--untag", "testing", "--tag", "@latest=staging")
expectedTargets := []TargetFields{newTargetFields("staging", rev1, 100, true)} expectedTargets := []TargetFields{newTargetFields("staging", rev1, 100, true)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("TagStagingNonLatest", t.Run("TagStagingNonLatest",
func(t *testing.T) { func(t *testing.T) {
t.Log("update tag from testing to staging for a revision (non @latest)") t.Log("update tag from testing to staging for a revision (non @latest)")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2)
// make existing state: tag a revision as testing // make existing state: tag a revision as testing
test.serviceUpdateWithOptions(t, r, serviceName, "--tag", fmt.Sprintf("%s=testing", rev1)) serviceUpdateWithOptions(t, it, r, serviceName, "--tag", fmt.Sprintf("%s=testing", rev1))
// desired state: change tag from testing to staging // desired state: change tag from testing to staging
test.serviceUpdateWithOptions(t, r, serviceName, "--untag", "testing", "--tag", fmt.Sprintf("%s=staging", rev1)) serviceUpdateWithOptions(t, it, r, serviceName, "--untag", "testing", "--tag", fmt.Sprintf("%s=staging", rev1))
expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true), expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true),
newTargetFields("staging", rev1, 0, false)} newTargetFields("staging", rev1, 0, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
// test reducing number of targets from traffic blockdd // test reducing number of targets from traffic blockdd
t.Run("RemoveTag", t.Run("RemoveTag",
func(t *testing.T) { func(t *testing.T) {
t.Log("remove a revision with tag old from traffic block entirely") t.Log("remove a revision with tag old from traffic block entirely")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2)
// existing state: traffic block having a revision with tag old and some traffic // existing state: traffic block having a revision with tag old and some traffic
test.serviceUpdateWithOptions(t, r, serviceName, serviceUpdateWithOptions(t, it, r, serviceName,
"--tag", fmt.Sprintf("%s=old", rev1), "--tag", fmt.Sprintf("%s=old", rev1),
"--traffic", "old=2,@latest=98") "--traffic", "old=2,@latest=98")
// desired state: remove revision with tag old // desired state: remove revision with tag old
test.serviceUpdateWithOptions(t, r, serviceName, "--untag", "old", "--traffic", "@latest=100") serviceUpdateWithOptions(t, it, r, serviceName, "--untag", "old", "--traffic", "@latest=100")
expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true)} expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("TagStable:50:50", t.Run("TagStable:50:50",
func(t *testing.T) { func(t *testing.T) {
t.Log("tag a revision as stable and current with 50-50% traffic") t.Log("tag a revision as stable and current with 50-50% traffic")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
// existing state: traffic block having two targets // existing state: traffic block having two targets
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2") serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2")
// desired state: tag non-@latest revision with two tags and 50-50% traffic each // desired state: tag non-@latest revision with two tags and 50-50% traffic each
test.serviceUpdateWithOptions(t, r, serviceName, serviceUpdateWithOptions(t, it, r, serviceName,
"--tag", fmt.Sprintf("%s=stable,%s=current", rev1, rev1), "--tag", fmt.Sprintf("%s=stable,%s=current", rev1, rev1),
"--traffic", "stable=50%,current=50%") "--traffic", "stable=50%,current=50%")
expectedTargets := []TargetFields{newTargetFields("stable", rev1, 50, false), newTargetFields("current", rev1, 50, false)} expectedTargets := []TargetFields{newTargetFields("stable", rev1, 50, false), newTargetFields("current", rev1, 50, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("RevertToLatest", t.Run("RevertToLatest",
func(t *testing.T) { func(t *testing.T) {
t.Log("revert all traffic to latest ready revision of service") t.Log("revert all traffic to latest ready revision of service")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2)
// existing state: latest ready revision not getting any traffic // existing state: latest ready revision not getting any traffic
test.serviceUpdateWithOptions(t, r, serviceName, "--traffic", fmt.Sprintf("%s=100", rev1)) serviceUpdateWithOptions(t, it, r, serviceName, "--traffic", fmt.Sprintf("%s=100", rev1))
// desired state: revert traffic to latest ready revision // desired state: revert traffic to latest ready revision
test.serviceUpdateWithOptions(t, r, serviceName, "--traffic", "@latest=100") serviceUpdateWithOptions(t, it, r, serviceName, "--traffic", "@latest=100")
expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true)} expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("TagLatestAsCurrent", t.Run("TagLatestAsCurrent",
func(t *testing.T) { func(t *testing.T) {
t.Log("tag latest ready revision of service as current") t.Log("tag latest ready revision of service as current")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
// existing state: latest revision has no tag // existing state: latest revision has no tag
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
// desired state: tag latest ready revision as 'current' // desired state: tag latest ready revision as 'current'
test.serviceUpdateWithOptions(t, r, serviceName, "--tag", "@latest=current") serviceUpdateWithOptions(t, it, r, serviceName, "--tag", "@latest=current")
expectedTargets := []TargetFields{newTargetFields("current", rev1, 100, true)} expectedTargets := []TargetFields{newTargetFields("current", rev1, 100, true)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("UpdateTag:100:0", t.Run("UpdateTag:100:0",
func(t *testing.T) { func(t *testing.T) {
t.Log("update tag for a revision as testing and assign all the traffic to it") t.Log("update tag for a revision as testing and assign all the traffic to it")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2)
// existing state: two revision exists with traffic share and // existing state: two revision exists with traffic share and
// each revision has tag and traffic portions // each revision has tag and traffic portions
test.serviceUpdateWithOptions(t, r, serviceName, serviceUpdateWithOptions(t, it, r, serviceName,
"--tag", fmt.Sprintf("@latest=current,%s=candidate", rev1), "--tag", fmt.Sprintf("@latest=current,%s=candidate", rev1),
"--traffic", "current=90,candidate=10") "--traffic", "current=90,candidate=10")
// desired state: update tag for rev1 as testing (from candidate) with 100% traffic // desired state: update tag for rev1 as testing (from candidate) with 100% traffic
test.serviceUpdateWithOptions(t, r, serviceName, serviceUpdateWithOptions(t, it, r, serviceName,
"--untag", "candidate", "--tag", fmt.Sprintf("%s=testing", rev1), "--untag", "candidate", "--tag", fmt.Sprintf("%s=testing", rev1),
"--traffic", "testing=100") "--traffic", "testing=100")
expectedTargets := []TargetFields{newTargetFields("current", rev2, 0, true), expectedTargets := []TargetFields{newTargetFields("current", rev2, 0, true),
newTargetFields("testing", rev1, 100, false)} newTargetFields("testing", rev1, 100, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
t.Run("TagReplace", t.Run("TagReplace",
func(t *testing.T) { func(t *testing.T) {
t.Log("replace latest tag of a revision with old and give latest to another revision") t.Log("replace latest tag of a revision with old and give latest to another revision")
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
serviceName := getNextServiceName(serviceBase) serviceName := test.GetNextServiceName(serviceBase)
rev1 := fmt.Sprintf("%s-rev-1", serviceName) rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, r, serviceName, "--revision-name", rev1) serviceCreateWithOptions(t, it, r, serviceName, "--revision-name", rev1)
rev2 := fmt.Sprintf("%s-rev-2", serviceName) rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2) serviceUpdateWithOptions(t, it, r, serviceName, "--env", "TARGET=v2", "--revision-name", rev2)
// existing state: a revision exist with latest tag // existing state: a revision exist with latest tag
test.serviceUpdateWithOptions(t, r, serviceName, "--tag", fmt.Sprintf("%s=latest", rev1)) serviceUpdateWithOptions(t, it, r, serviceName, "--tag", fmt.Sprintf("%s=latest", rev1))
// desired state of revision tags: rev1=old rev2=latest // desired state of revision tags: rev1=old rev2=latest
test.serviceUpdateWithOptions(t, r, serviceName, serviceUpdateWithOptions(t, it, r, serviceName,
"--untag", "latest", "--untag", "latest",
"--tag", fmt.Sprintf("%s=old,%s=latest", rev1, rev2)) "--tag", fmt.Sprintf("%s=old,%s=latest", rev1, rev2))
@ -404,34 +406,34 @@ func TestTrafficSplit(t *testing.T) {
// In spec of traffic block (not status) either latestReadyRevision:true or revisionName can be given per target // In spec of traffic block (not status) either latestReadyRevision:true or revisionName can be given per target
newTargetFields("latest", rev2, 0, false)} newTargetFields("latest", rev2, 0, false)}
test.verifyTargets(t, r, serviceName, expectedTargets) verifyTargets(t, it, r, serviceName, expectedTargets)
test.serviceDelete(t, r, serviceName) serviceDelete(t, it, r, serviceName)
}, },
) )
} }
func (test *e2eTest) verifyTargets(t *testing.T, r *KnRunResultCollector, serviceName string, expectedTargets []TargetFields) { func verifyTargets(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, expectedTargets []TargetFields) {
out := test.serviceDescribeWithJsonPath(r, serviceName, targetsJsonPath) out := serviceDescribeWithJsonPath(t, it, r, serviceName, targetsJsonPath)
assert.Check(t, out != "") assert.Check(t, out != "")
actualTargets, err := splitTargets(out, targetsSeparator, len(expectedTargets)) actualTargets, err := splitTargets(out, targetsSeparator, len(expectedTargets))
assert.NilError(t, err) assert.NilError(t, err)
formattedActualTargets := formatActualTargets(t, actualTargets) formattedActualTargets := formatActualTargets(t, it, actualTargets)
assert.DeepEqual(t, expectedTargets, formattedActualTargets) assert.DeepEqual(t, expectedTargets, formattedActualTargets)
if t.Failed() { if t.Failed() {
r.AddDump("service", serviceName, test.namespace) r.AddDump("service", serviceName, it.Kn().Namespace())
} }
} }
func (test *e2eTest) serviceDescribeWithJsonPath(r *KnRunResultCollector, serviceName, jsonpath string) string { func serviceDescribeWithJsonPath(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName, jsonpath string) string {
out := test.kn.Run("service", "describe", serviceName, "-o", jsonpath) out := it.Kn().Run("service", "describe", serviceName, "-o", jsonpath)
r.AssertNoError(out) r.AssertNoError(out)
return out.Stdout return out.Stdout
} }
func (test *e2eTest) serviceUpdateWithOptions(t *testing.T, r *KnRunResultCollector, serviceName string, options ...string) { func serviceUpdateWithOptions(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, serviceName string, options ...string) {
command := []string{"service", "update", serviceName} command := []string{"service", "update", serviceName}
command = append(command, options...) command = append(command, options...)
out := test.kn.Run(command...) out := it.Kn().Run(command...)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Service", serviceName, "updating", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Service", serviceName, "updating", "namespace", it.Kn().Namespace()))
} }

View File

@ -21,45 +21,47 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestInjectBrokerTrigger(t *testing.T) { func TestInjectBrokerTrigger(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
assert.NilError(t, err) assert.NilError(t, err)
test.serviceCreate(t, r, "sinksvc0") serviceCreate(t, it, r, "sinksvc0")
test.serviceCreate(t, r, "sinksvc1") serviceCreate(t, it, r, "sinksvc1")
t.Log("create triggers and list them") t.Log("create triggers and list them")
test.triggerCreateWithInject(t, r, "trigger1", "sinksvc0", []string{"a=b"}) triggerCreateWithInject(t, it, r, "trigger1", "sinksvc0", []string{"a=b"})
test.triggerCreateWithInject(t, r, "trigger2", "sinksvc1", []string{"type=knative.dev.bar", "source=ping"}) triggerCreateWithInject(t, it, r, "trigger2", "sinksvc1", []string{"type=knative.dev.bar", "source=ping"})
test.verifyTriggerList(t, r, "trigger1", "trigger2") verifyTriggerList(t, it, r, "trigger1", "trigger2")
test.triggerDelete(t, r, "trigger1") triggerDelete(t, it, r, "trigger1")
test.triggerDelete(t, r, "trigger2") triggerDelete(t, it, r, "trigger2")
t.Log("create trigger with error") t.Log("create trigger with error")
out := test.kn.Run("trigger", "create", "errorTrigger", "--broker", "mybroker", "--inject-broker", out := it.Kn().Run("trigger", "create", "errorTrigger", "--broker", "mybroker", "--inject-broker",
"--sink", "svc:sinksvc0", "--filter", "a=b") "--sink", "svc:sinksvc0", "--filter", "a=b")
r.AssertError(out) r.AssertError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stderr, "broker", "name", "'default'", "--inject-broker", "flag")) assert.Check(t, util.ContainsAllIgnoreCase(out.Stderr, "broker", "name", "'default'", "--inject-broker", "flag"))
} }
func (test *e2eTest) triggerCreateWithInject(t *testing.T, r *KnRunResultCollector, name string, sinksvc string, filters []string) { func triggerCreateWithInject(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, name string, sinksvc string, filters []string) {
args := []string{"trigger", "create", name, "--broker", "default", "--inject-broker", "--sink", "svc:" + sinksvc} args := []string{"trigger", "create", name, "--broker", "default", "--inject-broker", "--sink", "svc:" + sinksvc}
for _, v := range filters { for _, v := range filters {
args = append(args, "--filter", v) args = append(args, "--filter", v)
} }
out := test.kn.Run(args...) out := it.Kn().Run(args...)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Trigger", name, "created", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Trigger", name, "created", "namespace", it.Kn().Namespace()))
} }

View File

@ -24,74 +24,79 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestBrokerTrigger(t *testing.T) { func TestBrokerTrigger(t *testing.T) {
t.Parallel() t.Parallel()
test, err := NewE2eTest() it, err := test.NewKnTest()
assert.NilError(t, err) assert.NilError(t, err)
defer func() { defer func() {
assert.NilError(t, test.Teardown()) assert.NilError(t, it.Teardown())
}() }()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
err = test.labelNamespaceForDefaultBroker(t) err = lableNamespaceForDefaultBroker(t, it)
assert.NilError(t, err) assert.NilError(t, err)
defer test.unlabelNamespaceForDefaultBroker(t) defer unlableNamespaceForDefaultBroker(t, it)
test.serviceCreate(t, r, "sinksvc0") serviceCreate(t, it, r, "sinksvc0")
test.serviceCreate(t, r, "sinksvc1") serviceCreate(t, it, r, "sinksvc1")
t.Log("create triggers and list them") t.Log("create triggers and list them")
test.triggerCreate(t, r, "trigger1", "sinksvc0", nil) triggerCreate(t, it, r, "trigger1", "sinksvc0", []string{"a=b"})
test.triggerCreate(t, r, "trigger2", "sinksvc1", []string{"type=knative.dev.bar", "source=ping"}) triggerCreate(t, it, r, "trigger2", "sinksvc1", []string{"type=knative.dev.bar", "source=ping"})
test.verifyTriggerList(t, r, "trigger1", "trigger2") verifyTriggerList(t, it, r, "trigger1", "trigger2")
test.triggerDelete(t, r, "trigger1") triggerDelete(t, it, r, "trigger1")
test.triggerDelete(t, r, "trigger2") triggerDelete(t, it, r, "trigger2")
t.Log("create a trigger and delete it") t.Log("create a trigger and delete it")
test.triggerCreate(t, r, "deltrigger", "sinksvc0", []string{"a=b"}) triggerCreate(t, it, r, "deltrigger", "sinksvc0", []string{"a=b"})
test.triggerDelete(t, r, "deltrigger") triggerDelete(t, it, r, "deltrigger")
test.verifyTriggerNotfound(t, r, "deltrigger") verifyTriggerNotfound(t, it, r, "deltrigger")
t.Log("create a trigger with filters and remove them one by one") t.Log("create a trigger with filters and remove them one by one")
test.triggerCreate(t, r, "filtertrigger", "sinksvc0", []string{"foo=bar", "source=ping"}) triggerCreate(t, it, r, "filtertrigger", "sinksvc0", []string{"foo=bar", "source=ping"})
test.verifyTriggerDescribe(t, r, "filtertrigger", "default", "sinksvc0", []string{"foo", "bar", "source", "ping"}) verifyTriggerDescribe(t, it, r, "filtertrigger", "default", "sinksvc0", []string{"foo", "bar", "source", "ping"})
test.triggerUpdate(t, r, "filtertrigger", "foo-", "sinksvc0") triggerUpdate(t, it, r, "filtertrigger", "foo-", "sinksvc0")
test.verifyTriggerDescribe(t, r, "filtertrigger", "default", "sinksvc0", []string{"source", "ping"}) verifyTriggerDescribe(t, it, r, "filtertrigger", "default", "sinksvc0", []string{"source", "ping"})
test.triggerUpdate(t, r, "filtertrigger", "source-", "sinksvc0") triggerUpdate(t, it, r, "filtertrigger", "source-", "sinksvc0")
test.verifyTriggerDescribe(t, r, "filtertrigger", "default", "sinksvc0", nil) verifyTriggerDescribe(t, it, r, "filtertrigger", "default", "sinksvc0", nil)
test.triggerDelete(t, r, "filtertrigger") triggerDelete(t, it, r, "filtertrigger")
t.Log("create a trigger, describe and update it") t.Log("create a trigger, describe and update it")
test.triggerCreate(t, r, "updtrigger", "sinksvc0", []string{"a=b"}) triggerCreate(t, it, r, "updtrigger", "sinksvc0", []string{"a=b"})
test.verifyTriggerDescribe(t, r, "updtrigger", "default", "sinksvc0", []string{"a", "b"}) verifyTriggerDescribe(t, it, r, "updtrigger", "default", "sinksvc0", []string{"a", "b"})
test.triggerUpdate(t, r, "updtrigger", "type=knative.dev.bar", "sinksvc1") triggerUpdate(t, it, r, "updtrigger", "type=knative.dev.bar", "sinksvc1")
test.verifyTriggerDescribe(t, r, "updtrigger", "default", "sinksvc1", []string{"a", "b", "type", "knative.dev.bar"}) verifyTriggerDescribe(t, it, r, "updtrigger", "default", "sinksvc1", []string{"a", "b", "type", "knative.dev.bar"})
test.triggerDelete(t, r, "updtrigger") triggerDelete(t, it, r, "updtrigger")
t.Log("create trigger with error return") t.Log("create trigger with error return")
test.triggerCreateMissingSink(t, r, "errtrigger", "notfound") triggerCreateMissingSink(t, it, r, "errtrigger", "notfound")
} }
func (test *e2eTest) unlabelNamespaceForDefaultBroker(t *testing.T) { // Private functions
_, err := kubectl{}.Run("label", "namespace", test.kn.namespace, "knative-eventing-injection-")
func unlableNamespaceForDefaultBroker(t *testing.T, it *test.KnTest) {
_, err := test.Kubectl{}.Run("label", "namespace", it.Kn().Namespace(), "knative-eventing-injection-")
if err != nil { if err != nil {
t.Fatalf("Error executing 'kubectl label namespace %s knative-eventing-injection-'. Error: %s", test.kn.namespace, err.Error()) t.Fatalf("Error executing 'kubectl label namespace %s knative-eventing-injection-'. Error: %s", it.Kn().Namespace(), err.Error())
} }
} }
func (test *e2eTest) labelNamespaceForDefaultBroker(t *testing.T) error { func lableNamespaceForDefaultBroker(t *testing.T, it *test.KnTest) error {
_, err := kubectl{}.Run("label", "namespace", test.kn.namespace, "knative-eventing-injection=enabled") _, err := test.Kubectl{}.Run("label", "namespace", it.Kn().Namespace(), "knative-eventing-injection=enabled")
if err != nil { if err != nil {
t.Fatalf("Error executing 'kubectl label namespace %s knative-eventing-injection=enabled'. Error: %s", test.kn.namespace, err.Error()) t.Fatalf("Error executing 'kubectl label namespace %s knative-eventing-injection=enabled'. Error: %s", it.Kn().Namespace(), err.Error())
} }
return wait.PollImmediate(10*time.Second, 5*time.Minute, func() (bool, error) { return wait.PollImmediate(10*time.Second, 5*time.Minute, func() (bool, error) {
out, err := kubectl{test.kn.namespace}.Run("get", "broker", "-o=jsonpath='{.items[0].status.conditions[?(@.type==\"Ready\")].status}'") out, err := test.NewKubectl(it.Kn().Namespace()).Run("get", "broker", "-o=jsonpath='{.items[0].status.conditions[?(@.type==\"Ready\")].status}'")
if err != nil { if err != nil {
return false, nil return false, nil
} else { } else {
@ -100,44 +105,44 @@ func (test *e2eTest) labelNamespaceForDefaultBroker(t *testing.T) error {
}) })
} }
func (test *e2eTest) triggerCreate(t *testing.T, r *KnRunResultCollector, name string, sinksvc string, filters []string) { func triggerCreate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, name string, sinksvc string, filters []string) {
args := []string{"trigger", "create", name, "--broker", "default", "--sink", "svc:" + sinksvc} args := []string{"trigger", "create", name, "--broker", "default", "--sink", "svc:" + sinksvc}
if len(filters) > 0 { if len(filters) > 0 {
for _, v := range filters { for _, v := range filters {
args = append(args, "--filter", v) args = append(args, "--filter", v)
} }
} }
out := test.kn.Run(args...) out := it.Kn().Run(args...)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Trigger", name, "created", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Trigger", name, "created", "namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) triggerCreateMissingSink(t *testing.T, r *KnRunResultCollector, name string, sinksvc string) { func triggerCreateMissingSink(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, name string, sinksvc string) {
out := test.kn.Run("trigger", "create", name, "--broker", "default", "--sink", "svc:"+sinksvc) out := it.Kn().Run("trigger", "create", name, "--broker", "default", "--sink", "svc:"+sinksvc)
r.AssertError(out) r.AssertError(out)
assert.Check(t, util.ContainsAll(out.Stderr, "services.serving.knative.dev", "not found")) assert.Check(t, util.ContainsAll(out.Stderr, "services.serving.knative.dev", "not found"))
} }
func (test *e2eTest) triggerDelete(t *testing.T, r *KnRunResultCollector, name string) { func triggerDelete(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, name string) {
out := test.kn.Run("trigger", "delete", name) out := it.Kn().Run("trigger", "delete", name)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Trigger", name, "deleted", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Trigger", name, "deleted", "namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) triggerUpdate(t *testing.T, r *KnRunResultCollector, name string, filter string, sinksvc string) { func triggerUpdate(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, name string, filter string, sinksvc string) {
out := test.kn.Run("trigger", "update", name, "--filter", filter, "--sink", "svc:"+sinksvc) out := it.Kn().Run("trigger", "update", name, "--filter", filter, "--sink", "svc:"+sinksvc)
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Trigger", name, "updated", "namespace", test.kn.namespace)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "Trigger", name, "updated", "namespace", it.Kn().Namespace()))
} }
func (test *e2eTest) verifyTriggerList(t *testing.T, r *KnRunResultCollector, triggers ...string) { func verifyTriggerList(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, triggers ...string) {
out := test.kn.Run("trigger", "list") out := it.Kn().Run("trigger", "list")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, triggers...)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, triggers...))
} }
func (test *e2eTest) verifyTriggerDescribe(t *testing.T, r *KnRunResultCollector, name string, broker string, sink string, filters []string) { func verifyTriggerDescribe(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, name string, broker string, sink string, filters []string) {
out := test.kn.Run("trigger", "describe", name) out := it.Kn().Run("trigger", "describe", name)
r.AssertNoError(out) r.AssertNoError(out)
if len(filters) > 0 { if len(filters) > 0 {
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, filters...)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, filters...))
@ -147,8 +152,8 @@ func (test *e2eTest) verifyTriggerDescribe(t *testing.T, r *KnRunResultCollector
assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, name, broker, sink)) assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, name, broker, sink))
} }
func (test *e2eTest) verifyTriggerNotfound(t *testing.T, r *KnRunResultCollector, name string) { func verifyTriggerNotfound(t *testing.T, it *test.KnTest, r *test.KnRunResultCollector, name string) {
out := test.kn.Run("trigger", "describe", name) out := it.Kn().Run("trigger", "describe", name)
r.AssertError(out) r.AssertError(out)
assert.Check(t, util.ContainsAll(out.Stderr, name, "not found")) assert.Check(t, util.ContainsAll(out.Stderr, name, "not found"))
} }

View File

@ -20,16 +20,18 @@ import (
"testing" "testing"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
) )
func TestVersion(t *testing.T) { func TestVersion(t *testing.T) {
t.Parallel() t.Parallel()
r := NewKnRunResultCollector(t) r := test.NewKnRunResultCollector(t)
defer r.DumpIfFailed() defer r.DumpIfFailed()
out := kn{}.Run("version") out := test.Kn{}.Run("version")
r.AssertNoError(out) r.AssertNoError(out)
assert.Check(t, util.ContainsAll(out.Stdout, "Version")) assert.Check(t, util.ContainsAll(out.Stdout, "Version"))
} }