From 24b6c8a4a425aaf20cc49e3e8e3d3870c1e7c1a1 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 13 May 2019 16:22:02 +0100 Subject: [PATCH] context: produce consistent output on `context create`. Refactor `RunCreate` slightly so that all three paths always produce the same output, namely the name of the new context of `stdout` (for scripting) and the success log message on `stderr`. Validate by extending the existing unit tests to always check the output is as expected. Signed-off-by: Ian Campbell --- cli/command/context/create.go | 22 +++++++++++++--------- cli/command/context/create_test.go | 21 +++++++++++++++++++++ internal/test/cli.go | 5 +++++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/cli/command/context/create.go b/cli/command/context/create.go index 73d8c29f1848..9d5865a70a7d 100644 --- a/cli/command/context/create.go +++ b/cli/command/context/create.go @@ -78,13 +78,19 @@ func RunCreate(cli command.Cli, o *CreateOptions) error { if err != nil { return errors.Wrap(err, "unable to parse default-stack-orchestrator") } - if o.From == "" && o.Docker == nil && o.Kubernetes == nil { - return createFromExistingContext(s, cli.CurrentContext(), stackOrchestrator, o) - } - if o.From != "" { - return createFromExistingContext(s, o.From, stackOrchestrator, o) - } - return createNewContext(o, stackOrchestrator, cli, s) + switch { + case o.From == "" && o.Docker == nil && o.Kubernetes == nil: + err = createFromExistingContext(s, cli.CurrentContext(), stackOrchestrator, o) + case o.From != "": + err = createFromExistingContext(s, o.From, stackOrchestrator, o) + default: + err = createNewContext(o, stackOrchestrator, cli, s) + } + if err == nil { + fmt.Fprintln(cli.Out(), o.Name) + fmt.Fprintf(cli.Err(), "Successfully created context %q\n", o.Name) + } + return err } func createNewContext(o *CreateOptions, stackOrchestrator command.Orchestrator, cli command.Cli, s store.Writer) error { @@ -127,8 +133,6 @@ func createNewContext(o *CreateOptions, stackOrchestrator command.Orchestrator, if err := s.ResetTLSMaterial(o.Name, &contextTLSData); err != nil { return err } - fmt.Fprintln(cli.Out(), o.Name) - fmt.Fprintf(cli.Err(), "Successfully created context %q\n", o.Name) return nil } diff --git a/cli/command/context/create_test.go b/cli/command/context/create_test.go index dba73c5b64dd..c1c931ef28a8 100644 --- a/cli/command/context/create_test.go +++ b/cli/command/context/create_test.go @@ -1,6 +1,7 @@ package context import ( + "fmt" "io/ioutil" "os" "testing" @@ -154,6 +155,8 @@ func TestCreateOrchestratorEmpty(t *testing.T) { Docker: map[string]string{}, }) assert.NilError(t, err) + assert.Equal(t, "test\n", cli.OutBuffer().String()) + assert.Equal(t, "Successfully created context \"test\"\n", cli.ErrBuffer().String()) } func validateTestKubeEndpoint(t *testing.T, s store.Reader, name string) { @@ -189,6 +192,8 @@ func TestCreateOrchestratorAllKubernetesEndpointFromCurrent(t *testing.T) { cli, cleanup := makeFakeCli(t) defer cleanup() createTestContextWithKube(t, cli) + assert.Equal(t, "test\n", cli.OutBuffer().String()) + assert.Equal(t, "Successfully created context \"test\"\n", cli.ErrBuffer().String()) validateTestKubeEndpoint(t, cli.ContextStore(), "test") } @@ -225,6 +230,7 @@ func TestCreateFromContext(t *testing.T) { defer cleanup() revert := env.Patch(t, "KUBECONFIG", "./testdata/test-kubeconfig") defer revert() + cli.ResetOutputBuffers() assert.NilError(t, RunCreate(cli, &CreateOptions{ Name: "original", Description: "original description", @@ -236,6 +242,10 @@ func TestCreateFromContext(t *testing.T) { }, DefaultStackOrchestrator: "swarm", })) + assert.Equal(t, "original\n", cli.OutBuffer().String()) + assert.Equal(t, "Successfully created context \"original\"\n", cli.ErrBuffer().String()) + + cli.ResetOutputBuffers() assert.NilError(t, RunCreate(cli, &CreateOptions{ Name: "dummy", Description: "dummy description", @@ -247,11 +257,14 @@ func TestCreateFromContext(t *testing.T) { }, DefaultStackOrchestrator: "swarm", })) + assert.Equal(t, "dummy\n", cli.OutBuffer().String()) + assert.Equal(t, "Successfully created context \"dummy\"\n", cli.ErrBuffer().String()) cli.SetCurrentContext("dummy") for _, c := range cases { t.Run(c.name, func(t *testing.T) { + cli.ResetOutputBuffers() err := RunCreate(cli, &CreateOptions{ From: "original", Name: c.name, @@ -261,6 +274,8 @@ func TestCreateFromContext(t *testing.T) { Kubernetes: c.kubernetes, }) assert.NilError(t, err) + assert.Equal(t, c.name+"\n", cli.OutBuffer().String()) + assert.Equal(t, fmt.Sprintf("Successfully created context %q\n", c.name), cli.ErrBuffer().String()) newContext, err := cli.ContextStore().GetMetadata(c.name) assert.NilError(t, err) newContextTyped, err := command.GetDockerContext(newContext) @@ -308,6 +323,7 @@ func TestCreateFromCurrent(t *testing.T) { defer cleanup() revert := env.Patch(t, "KUBECONFIG", "./testdata/test-kubeconfig") defer revert() + cli.ResetOutputBuffers() assert.NilError(t, RunCreate(cli, &CreateOptions{ Name: "original", Description: "original description", @@ -319,17 +335,22 @@ func TestCreateFromCurrent(t *testing.T) { }, DefaultStackOrchestrator: "swarm", })) + assert.Equal(t, "original\n", cli.OutBuffer().String()) + assert.Equal(t, "Successfully created context \"original\"\n", cli.ErrBuffer().String()) cli.SetCurrentContext("original") for _, c := range cases { t.Run(c.name, func(t *testing.T) { + cli.ResetOutputBuffers() err := RunCreate(cli, &CreateOptions{ Name: c.name, Description: c.description, DefaultStackOrchestrator: c.orchestrator, }) assert.NilError(t, err) + assert.Equal(t, c.name+"\n", cli.OutBuffer().String()) + assert.Equal(t, fmt.Sprintf("Successfully created context %q\n", c.name), cli.ErrBuffer().String()) newContext, err := cli.ContextStore().GetMetadata(c.name) assert.NilError(t, err) newContextTyped, err := command.GetDockerContext(newContext) diff --git a/internal/test/cli.go b/internal/test/cli.go index 2321ca4d6beb..a5ffdf8b4617 100644 --- a/internal/test/cli.go +++ b/internal/test/cli.go @@ -169,6 +169,11 @@ func (c *FakeCli) ErrBuffer() *bytes.Buffer { return c.err } +func (c *FakeCli) ResetOutputBuffers() { + c.outBuffer.Reset() + c.err.Reset() +} + // SetNotaryClient sets the internal getter for retrieving a NotaryClient func (c *FakeCli) SetNotaryClient(notaryClientFunc NotaryClientFuncType) { c.notaryClientFunc = notaryClientFunc