Skip to content

Commit

Permalink
(refactor) address the e2e extract / refactor of issue #763 (#765)
Browse files Browse the repository at this point in the history
* (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
  • Loading branch information
maximilien authored Apr 1, 2020
1 parent 521a0b4 commit df78b8b
Show file tree
Hide file tree
Showing 25 changed files with 805 additions and 693 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
[cols="1,10,3", options="header", width="100%"]
|===
| | Description | PR

|===

| 🐣
| Refactor `e2e` common code into `lib/test/integration`
| https://github.com/knative/client/pull/765[#765]

## v0.13.1 (2020-03-25)

[cols="1,10,3", options="header", width="100%"]
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/spf13/viper v1.4.0
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
gomodules.xyz/jsonpatch/v2 v2.1.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gotest.tools v2.2.0+incompatible
k8s.io/api v0.17.0
k8s.io/apimachinery v0.17.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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 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-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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
Expand Down
2 changes: 1 addition & 1 deletion hack/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

set -o pipefail

source_dirs="cmd pkg test"
source_dirs="cmd pkg test lib"

# Store for later
if [ -z "$1" ]; then
Expand Down
142 changes: 28 additions & 114 deletions test/e2e/cli.go → lib/test/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,153 +12,65 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package e2e
package test

import (
"bytes"
"fmt"
"io"
"os/exec"
"strings"
"testing"

"github.com/pkg/errors"
)

type kn struct {
namespace string
}

const (
seperatorHeavy = "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
seperatorLight = "╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍"
)

// Run the 'kn' CLI with args and opts
func (k kn) Run(args ...string) KnRunResult {
return RunKn(k.namespace, args)
}

// Helper methods for calling out to the test cluster
type kubectl struct {
// Kn type
type Kn struct {
namespace string
}

// Run the 'kubectl' CLI with args and opts
func (k kubectl) Run(args ...string) (string, error) {
return RunKubectl(k.namespace, args...)
}

// Collector for results
type KnRunResultCollector struct {
results []KnRunResult
extraDumps []string
t *testing.T
}

func NewKnRunResultCollector(t *testing.T) *KnRunResultCollector {
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()
}
// New Kn object
func NewKn() Kn {
return Kn{}
}

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()
}
// Run the 'kn' CLI with args
func (k Kn) Run(args ...string) KnRunResult {
return RunKn(k.namespace, args)
}

// 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)
}
// Namespace that this Kn instance uses
func (k Kn) Namespace() string {
return k.namespace
}

func (c *KnRunResultCollector) DumpIfFailed() {
if c.t.Failed() {
c.t.Log(c.errorDetails())
}
// Kubectl type
type Kubectl struct {
namespace string
}

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)
// New Kubectl object
func NewKubectl(namespace string) Kubectl {
return Kubectl{
namespace: namespace,
}

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)
}
}
// Run the 'kubectl' CLI with args
func (k Kubectl) Run(args ...string) (string, error) {
return RunKubectl(k.namespace, args...)
}

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)
}
}
// Namespace that this Kubectl instance uses
func (k Kubectl) Namespace() string {
return k.namespace
}

// ========================================================
// 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
}
// Public functions

// RunKn runs "kn" in a given namespace
func RunKn(namespace string, args []string) KnRunResult {
Expand Down Expand Up @@ -195,6 +107,8 @@ func RunKubectl(namespace string, args ...string) (string, error) {
return stdout, nil
}

// Private

func runCli(cli string, args []string) (string, string, error) {
var stderr bytes.Buffer
var stdout bytes.Buffer
Expand Down
7 changes: 4 additions & 3 deletions test/e2e/e2e_flags.go → lib/test/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e
package test

import (
"flag"
Expand All @@ -23,14 +23,15 @@ import (

// Flags holds the command line flags or defaults for settings in the user's environment.
// 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.
type ClientFlags struct {
DockerConfigJSON string
}

func initializeFlags() *ClientFlags {
// InitializeFlags initializes the client's flags
func InitializeFlags() *ClientFlags {
var f ClientFlags

dockerConfigJSON := os.Getenv("DOCKER_CONFIG_JSON")
Expand Down
Loading

0 comments on commit df78b8b

Please sign in to comment.