mirror of https://github.com/knative/client.git
* (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:
parent
521a0b423d
commit
df78b8b40c
|
|
@ -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
1
go.mod
|
|
@ -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
2
go.sum
|
|
@ -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=
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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")
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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.")
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue