Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
Signed-off-by: Patrik Cyvoct <pcyvoct@scaleway.com>
  • Loading branch information
Sh4d1 committed Apr 24, 2020
1 parent c554ff6 commit c9e9a93
Show file tree
Hide file tree
Showing 22 changed files with 436 additions and 173 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
This command will run the correct command in order to log you in on the namespace with the chosen program.
This command will run the correct command in order to log you in on the registry with the chosen program.
You will need to have the chosen binary installed on your system and in your PATH.

USAGE:
scw registry namespace login <namespace> [arg=value ...]
scw registry login [arg=value ...]

ARGS:
namespace Namespace name or ID to log in to
[program=docker] Program used to log in to the namespace (docker | podman)
[region] Region to target. If none is passed will use default region from the config

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
This command will run the correct command in order to log you out of the namespace with the chosen program.
This command will run the correct command in order to log you out of the registry with the chosen program.
You will need to have the chosen binary installed on your system and in your PATH.

USAGE:
scw registry namespace logout <namespace> [arg=value ...]
scw registry logout [arg=value ...]

ARGS:
namespace Namespace name or ID to log out of
[program=docker] Program used to log in to the namespace (docker | podman)
[region] Region to target. If none is passed will use default region from the config

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ AVAILABLE COMMANDS:
create Create a new namespace
update Update an existing namespace
delete Delete an existing namespace
login Login to a namespace
logout Logout of a namespace

FLAGS:
-h, --help help for namespace
Expand Down
2 changes: 2 additions & 0 deletions cmd/scw/testdata/test-all-usage-registry-usage.stderr.golden
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ AVAILABLE COMMANDS:
namespace A namespace is for images what a folder is for files
image An image represents a container image
tag A tag represents a container tag of an image
login Login to a registry
logout Logout of a registry

FLAGS:
-h, --help help for registry
Expand Down
30 changes: 20 additions & 10 deletions internal/core/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ type BootstrapConfig struct {
// OverrideEnv overrides environment variables returned by core.ExtractEnv function.
// This is useful for tests as it allows overriding env without relying on global state.
OverrideEnv map[string]string

// OverrideExecCommmand contains programs that will be overriden during the test.
// This is useful when commands include external commands
OverrideExecCommand map[string]ExecCmd
}

// Bootstrap is the main entry point. It is directly called from main.
Expand All @@ -57,23 +61,29 @@ func Bootstrap(config *BootstrapConfig) (exitCode int, result interface{}, err e
// Meta store globally available variables like SDK client.
// Meta is injected in a context object that will be passed to all commands.
meta := &meta{
BinaryName: config.Args[0],
BuildInfo: config.BuildInfo,
stdout: config.Stdout,
stderr: config.Stderr,
Client: config.Client,
Commands: config.Commands,
Printer: globalPrinter,
OverrideEnv: config.OverrideEnv,
result: nil, // result is later injected by cobra_utils.go/cobraRun()
command: nil, // command is later injected by cobra_utils.go/cobraRun()
BinaryName: config.Args[0],
BuildInfo: config.BuildInfo,
stdout: config.Stdout,
stderr: config.Stderr,
Client: config.Client,
Commands: config.Commands,
Printer: globalPrinter,
OverrideEnv: config.OverrideEnv,
OverrideExecCommand: config.OverrideExecCommand,
result: nil, // result is later injected by cobra_utils.go/cobraRun()
command: nil, // command is later injected by cobra_utils.go/cobraRun()
}

// We make sure OverrideEnv is never nil in meta.
if meta.OverrideEnv == nil {
meta.OverrideEnv = map[string]string{}
}

// We make sure OverrideExecCommand is never nil in meta.
if meta.OverrideExecCommand == nil {
meta.OverrideExecCommand = map[string]ExecCmd{}
}

// Send Matomo telemetry when exiting the bootstrap
start := time.Now()
defer func() {
Expand Down
29 changes: 24 additions & 5 deletions internal/core/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"io"
"os"
"os/exec"

"github.com/scaleway/scaleway-cli/internal/printer"
"github.com/scaleway/scaleway-sdk-go/scw"
Expand All @@ -17,11 +18,12 @@ type meta struct {
DebugModeFlag bool
PrinterTypeFlag printer.Type

BuildInfo *BuildInfo
Client *scw.Client
Printer printer.Printer
Commands *Commands
OverrideEnv map[string]string
BuildInfo *BuildInfo
Client *scw.Client
Printer printer.Printer
Commands *Commands
OverrideEnv map[string]string
OverrideExecCommand map[string]ExecCmd

command *Command
stdout io.Writer
Expand Down Expand Up @@ -99,3 +101,20 @@ func ExtractUserHomeDir(ctx context.Context) string {
func ExtractBinaryName(ctx context.Context) string {
return extractMeta(ctx).BinaryName
}

func ExtractAndExecCommand(ctx context.Context, function string, args ...string) Cmd {
meta := extractMeta(ctx)
var cmd Cmd
if f, exist := meta.OverrideExecCommand[function]; exist {
cmd = f(function, os.Stdin, meta.stdout, meta.stderr, args...)
} else {
realCmd := exec.Command(function, args...)
realCmd.Stdout = meta.stdout
realCmd.Stderr = meta.stderr
cmd = &RealCmd{
realCmd,
}
}

return cmd
}
21 changes: 21 additions & 0 deletions internal/core/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package core

import (
"io"
"os/exec"
)

type ExecCmd func(name string, stdin io.Reader, stdout io.Writer, stderr io.Writer, args ...string) Cmd

type Cmd interface {
Run() error
SetStdin(io.Reader)
}

type RealCmd struct {
*exec.Cmd
}

func (rc *RealCmd) SetStdin(r io.Reader) {
rc.Stdin = r
}
119 changes: 69 additions & 50 deletions internal/core/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ type CheckFuncCtx struct {

// OverrideEnv passed in the TestConfig
OverrideEnv map[string]string

// OverrideExecCommand passed in the TestConfig
OverrideExecCommand map[string]ExecCmd
}

// TestCheck is a function that perform assertion on a CheckFuncCtx
Expand All @@ -67,20 +70,22 @@ type BeforeFunc func(ctx *BeforeFuncCtx) error
type AfterFunc func(ctx *AfterFuncCtx) error

type BeforeFuncCtx struct {
T *testing.T
Client *scw.Client
ExecuteCmd func(args []string) interface{}
Meta map[string]interface{}
OverrideEnv map[string]string
T *testing.T
Client *scw.Client
ExecuteCmd func(args []string) interface{}
Meta map[string]interface{}
OverrideEnv map[string]string
OverrideExecCommand map[string]ExecCmd
}

type AfterFuncCtx struct {
T *testing.T
Client *scw.Client
ExecuteCmd func(args []string) interface{}
Meta map[string]interface{}
CmdResult interface{}
OverrideEnv map[string]string
T *testing.T
Client *scw.Client
ExecuteCmd func(args []string) interface{}
Meta map[string]interface{}
CmdResult interface{}
OverrideEnv map[string]string
OverrideExecCommand map[string]ExecCmd
}

// TestConfig contain configuration that can be used with the Test function
Expand Down Expand Up @@ -130,6 +135,9 @@ type TestConfig struct {

// Custom client to use for test, if none are provided will create one automatically
Client *scw.Client

// OverrideExecCommand contains programs that will be overriden during the test.
OverrideExecCommand map[string]ExecCmd
}

// getTestFilePath returns a valid filename path based on the go test name and suffix. (Take care of non fs friendly char)
Expand Down Expand Up @@ -158,6 +166,7 @@ func createTestClient(t *testing.T, testConfig *TestConfig) (client *scw.Client,
scw.WithEnv(),
scw.WithUserAgent("cli-e2e-test"),
scw.WithDefaultOrganizationID("11111111-1111-1111-1111-111111111111"),
scw.WithAuth("SCWXXXXXXXXXXXXXXXXX", "11111111-1111-1111-1111-111111111111"),
}

// If client is NOT an E2E client we init http recorder and load configuration.
Expand Down Expand Up @@ -222,9 +231,14 @@ func Test(config *TestConfig) func(t *testing.T) {

meta := map[string]interface{}{}

overideEnv := config.OverrideEnv
if overideEnv == nil {
overideEnv = map[string]string{}
overrideEnv := config.OverrideEnv
if overrideEnv == nil {
overrideEnv = map[string]string{}
}

overrideExecCommand := config.OverrideExecCommand
if overrideExecCommand == nil {
overrideExecCommand = map[string]ExecCmd{}
}

if config.TmpHomeDir {
Expand All @@ -234,22 +248,23 @@ func Test(config *TestConfig) func(t *testing.T) {
err = os.RemoveAll(dir)
assert.NoError(t, err)
}()
overideEnv["HOME"] = dir
overrideEnv["HOME"] = dir
}

executeCmd := func(args []string) interface{} {
stdoutBuffer := &bytes.Buffer{}
stderrBuffer := &bytes.Buffer{}
logger.Debugf("command: %s", args)
_, result, err := Bootstrap(&BootstrapConfig{
Args: args,
Commands: config.Commands,
BuildInfo: &config.BuildInfo,
Stdout: stdoutBuffer,
Stderr: stderrBuffer,
Client: client,
DisableTelemetry: true,
OverrideEnv: overideEnv,
Args: args,
Commands: config.Commands,
BuildInfo: &config.BuildInfo,
Stdout: stdoutBuffer,
Stderr: stderrBuffer,
Client: client,
DisableTelemetry: true,
OverrideEnv: overrideEnv,
OverrideExecCommand: overrideExecCommand,
})
require.NoError(t, err, "stdout: %s\nstderr: %s", stdoutBuffer.String(), stderrBuffer.String())

Expand All @@ -259,11 +274,12 @@ func Test(config *TestConfig) func(t *testing.T) {
// Run config.BeforeFunc
if config.BeforeFunc != nil {
require.NoError(t, config.BeforeFunc(&BeforeFuncCtx{
T: t,
Client: client,
ExecuteCmd: executeCmd,
Meta: meta,
OverrideEnv: overideEnv,
T: t,
Client: client,
ExecuteCmd: executeCmd,
Meta: meta,
OverrideEnv: overrideEnv,
OverrideExecCommand: overrideExecCommand,
}))
}

Expand All @@ -280,38 +296,41 @@ func Test(config *TestConfig) func(t *testing.T) {
stderr := &bytes.Buffer{}
logger.Debugf("command: %s", args)
exitCode, result, err = Bootstrap(&BootstrapConfig{
Args: args,
Commands: config.Commands,
BuildInfo: &config.BuildInfo,
Stdout: stdout,
Stderr: stderr,
Client: client,
DisableTelemetry: true,
OverrideEnv: overideEnv,
Args: args,
Commands: config.Commands,
BuildInfo: &config.BuildInfo,
Stdout: stdout,
Stderr: stderr,
Client: client,
DisableTelemetry: true,
OverrideEnv: overrideEnv,
OverrideExecCommand: overrideExecCommand,
})

meta["CmdResult"] = result
config.Check(t, &CheckFuncCtx{
ExitCode: exitCode,
Stdout: stdout.Bytes(),
Stderr: stderr.Bytes(),
Meta: meta,
Result: result,
Err: err,
Client: client,
OverrideEnv: overideEnv,
ExitCode: exitCode,
Stdout: stdout.Bytes(),
Stderr: stderr.Bytes(),
Meta: meta,
Result: result,
Err: err,
Client: client,
OverrideEnv: overrideEnv,
OverrideExecCommand: overrideExecCommand,
})
}

// Run config.AfterFunc
if config.AfterFunc != nil {
require.NoError(t, config.AfterFunc(&AfterFuncCtx{
T: t,
Client: client,
ExecuteCmd: executeCmd,
Meta: meta,
CmdResult: result,
OverrideEnv: overideEnv,
T: t,
Client: client,
ExecuteCmd: executeCmd,
Meta: meta,
CmdResult: result,
OverrideEnv: overrideEnv,
OverrideExecCommand: overrideExecCommand,
}))
}
}
Expand Down
Loading

0 comments on commit c9e9a93

Please sign in to comment.