Update node command tests to the new golden

Also remove some superfluous tests that are now covered by a strict golden.Assert

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-08-16 12:42:19 -04:00
parent 75f7bfedf8
commit 0e2bf7420a
13 changed files with 86 additions and 140 deletions

View File

@ -1,7 +1,6 @@
package node package node
import ( import (
"bytes"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"testing" "testing"
@ -13,7 +12,7 @@ import (
// Import builders to get the builder function as package function // Import builders to get the builder function as package function
. "github.com/docker/cli/cli/internal/test/builders" . "github.com/docker/cli/cli/internal/test/builders"
"github.com/docker/docker/pkg/testutil" "github.com/docker/docker/pkg/testutil"
"github.com/docker/docker/pkg/testutil/golden" "github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -67,12 +66,11 @@ func TestNodeInspectErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newInspectCommand( cmd := newInspectCommand(
test.NewFakeCliWithOutput(&fakeClient{ test.NewFakeCli(&fakeClient{
nodeInspectFunc: tc.nodeInspectFunc, nodeInspectFunc: tc.nodeInspectFunc,
infoFunc: tc.infoFunc, infoFunc: tc.infoFunc,
}, buf)) }))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
for key, value := range tc.flags { for key, value := range tc.flags {
cmd.Flags().Set(key, value) cmd.Flags().Set(key, value)
@ -109,16 +107,13 @@ func TestNodeInspectPretty(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{
cmd := newInspectCommand( nodeInspectFunc: tc.nodeInspectFunc,
test.NewFakeCliWithOutput(&fakeClient{ })
nodeInspectFunc: tc.nodeInspectFunc, cmd := newInspectCommand(cli)
}, buf))
cmd.SetArgs([]string{"nodeID"}) cmd.SetArgs([]string{"nodeID"})
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
actual := buf.String() golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-inspect-pretty.%s.golden", tc.name))
expected := golden.Get(t, []byte(actual), fmt.Sprintf("node-inspect-pretty.%s.golden", tc.name))
testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected))
} }
} }

View File

@ -1,7 +1,6 @@
package node package node
import ( import (
"bytes"
"io/ioutil" "io/ioutil"
"testing" "testing"
@ -9,8 +8,7 @@ import (
"github.com/docker/cli/cli/internal/test" "github.com/docker/cli/cli/internal/test"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/pkg/testutil" "github.com/gotestyourself/gotestyourself/golden"
"github.com/docker/docker/pkg/testutil/golden"
"github.com/pkg/errors" "github.com/pkg/errors"
// Import builders to get the builder function as package function // Import builders to get the builder function as package function
. "github.com/docker/cli/cli/internal/test/builders" . "github.com/docker/cli/cli/internal/test/builders"
@ -58,9 +56,9 @@ func TestNodeList(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
nodeListFunc: func() ([]swarm.Node, error) { nodeListFunc: func() ([]swarm.Node, error) {
return []swarm.Node{ return []swarm.Node{
*Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())), *Node(NodeID("nodeID1"), Hostname("node-2-foo"), Manager(Leader())),
*Node(NodeID("nodeID2"), Hostname("nodeHostname2"), Manager()), *Node(NodeID("nodeID2"), Hostname("node-10-foo"), Manager()),
*Node(NodeID("nodeID3"), Hostname("nodeHostname3")), *Node(NodeID("nodeID3"), Hostname("node-1-foo")),
}, nil }, nil
}, },
infoFunc: func() (types.Info, error) { infoFunc: func() (types.Info, error) {
@ -74,39 +72,25 @@ func TestNodeList(t *testing.T) {
cmd := newListCommand(cli) cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
out := cli.OutBuffer().String() golden.Assert(t, cli.OutBuffer().String(), "node-list-sort.golden")
assert.Contains(t, out, `nodeID1 * nodeHostname1 Ready Active Leader`)
assert.Contains(t, out, `nodeID2 nodeHostname2 Ready Active Reachable`)
assert.Contains(t, out, `nodeID3 nodeHostname3 Ready Active`)
} }
func TestNodeListQuietShouldOnlyPrintIDs(t *testing.T) { func TestNodeListQuietShouldOnlyPrintIDs(t *testing.T) {
buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{
cli := test.NewFakeCliWithOutput(&fakeClient{
nodeListFunc: func() ([]swarm.Node, error) { nodeListFunc: func() ([]swarm.Node, error) {
return []swarm.Node{ return []swarm.Node{
*Node(), *Node(NodeID("nodeID1")),
}, nil }, nil
}, },
}, buf) })
cmd := newListCommand(cli) cmd := newListCommand(cli)
cmd.Flags().Set("quiet", "true") cmd.Flags().Set("quiet", "true")
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
assert.Contains(t, buf.String(), "nodeID") assert.Equal(t, cli.OutBuffer().String(), "nodeID1\n")
} }
// Test case for #24090 func TestNodeListDefaultFormatFromConfig(t *testing.T) {
func TestNodeListContainsHostname(t *testing.T) { cli := test.NewFakeCli(&fakeClient{
buf := new(bytes.Buffer)
cli := test.NewFakeCliWithOutput(&fakeClient{}, buf)
cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.Contains(t, buf.String(), "HOSTNAME")
}
func TestNodeListDefaultFormat(t *testing.T) {
buf := new(bytes.Buffer)
cli := test.NewFakeCliWithOutput(&fakeClient{
nodeListFunc: func() ([]swarm.Node, error) { nodeListFunc: func() ([]swarm.Node, error) {
return []swarm.Node{ return []swarm.Node{
*Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())), *Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())),
@ -121,20 +105,17 @@ func TestNodeListDefaultFormat(t *testing.T) {
}, },
}, nil }, nil
}, },
}, buf) })
cli.SetConfigFile(&configfile.ConfigFile{ cli.SetConfigFile(&configfile.ConfigFile{
NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}", NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}",
}) })
cmd := newListCommand(cli) cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
assert.Contains(t, buf.String(), `nodeID1: nodeHostname1 Ready/Leader`) golden.Assert(t, cli.OutBuffer().String(), "node-list-format-from-config.golden")
assert.Contains(t, buf.String(), `nodeID2: nodeHostname2 Ready/Reachable`)
assert.Contains(t, buf.String(), `nodeID3: nodeHostname3 Ready`)
} }
func TestNodeListFormat(t *testing.T) { func TestNodeListFormat(t *testing.T) {
buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{
cli := test.NewFakeCliWithOutput(&fakeClient{
nodeListFunc: func() ([]swarm.Node, error) { nodeListFunc: func() ([]swarm.Node, error) {
return []swarm.Node{ return []swarm.Node{
*Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())), *Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())),
@ -148,32 +129,12 @@ func TestNodeListFormat(t *testing.T) {
}, },
}, nil }, nil
}, },
}, buf) })
cli.SetConfigFile(&configfile.ConfigFile{ cli.SetConfigFile(&configfile.ConfigFile{
NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}", NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}",
}) })
cmd := newListCommand(cli) cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{.Hostname}}: {{.ManagerStatus}}") cmd.Flags().Set("format", "{{.Hostname}}: {{.ManagerStatus}}")
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
assert.Contains(t, buf.String(), `nodeHostname1: Leader`) golden.Assert(t, cli.OutBuffer().String(), "node-list-format-flag.golden")
assert.Contains(t, buf.String(), `nodeHostname2: Reachable`)
}
func TestNodeListOrder(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
nodeListFunc: func() ([]swarm.Node, error) {
return []swarm.Node{
*Node(Hostname("node-2-foo"), Manager(Leader())),
*Node(Hostname("node-10-foo"), Manager()),
*Node(Hostname("node-1-foo")),
}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{.Hostname}}: {{.ManagerStatus}}")
assert.NoError(t, cmd.Execute())
actual := cli.OutBuffer().String()
expected := golden.Get(t, []byte(actual), "node-list-sort.golden")
testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected))
} }

View File

@ -1,7 +1,6 @@
package node package node
import ( import (
"bytes"
"io/ioutil" "io/ioutil"
"testing" "testing"
@ -40,12 +39,11 @@ func TestNodePromoteErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newPromoteCommand( cmd := newPromoteCommand(
test.NewFakeCliWithOutput(&fakeClient{ test.NewFakeCli(&fakeClient{
nodeInspectFunc: tc.nodeInspectFunc, nodeInspectFunc: tc.nodeInspectFunc,
nodeUpdateFunc: tc.nodeUpdateFunc, nodeUpdateFunc: tc.nodeUpdateFunc,
}, buf)) }))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard) cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
@ -53,9 +51,8 @@ func TestNodePromoteErrors(t *testing.T) {
} }
func TestNodePromoteNoChange(t *testing.T) { func TestNodePromoteNoChange(t *testing.T) {
buf := new(bytes.Buffer)
cmd := newPromoteCommand( cmd := newPromoteCommand(
test.NewFakeCliWithOutput(&fakeClient{ test.NewFakeCli(&fakeClient{
nodeInspectFunc: func() (swarm.Node, []byte, error) { nodeInspectFunc: func() (swarm.Node, []byte, error) {
return *Node(Manager()), []byte{}, nil return *Node(Manager()), []byte{}, nil
}, },
@ -65,15 +62,14 @@ func TestNodePromoteNoChange(t *testing.T) {
} }
return nil return nil
}, },
}, buf)) }))
cmd.SetArgs([]string{"nodeID"}) cmd.SetArgs([]string{"nodeID"})
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
} }
func TestNodePromoteMultipleNode(t *testing.T) { func TestNodePromoteMultipleNode(t *testing.T) {
buf := new(bytes.Buffer)
cmd := newPromoteCommand( cmd := newPromoteCommand(
test.NewFakeCliWithOutput(&fakeClient{ test.NewFakeCli(&fakeClient{
nodeInspectFunc: func() (swarm.Node, []byte, error) { nodeInspectFunc: func() (swarm.Node, []byte, error) {
return *Node(), []byte{}, nil return *Node(), []byte{}, nil
}, },
@ -83,7 +79,7 @@ func TestNodePromoteMultipleNode(t *testing.T) {
} }
return nil return nil
}, },
}, buf)) }))
cmd.SetArgs([]string{"nodeID1", "nodeID2"}) cmd.SetArgs([]string{"nodeID1", "nodeID2"})
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
} }

View File

@ -1,7 +1,6 @@
package node package node
import ( import (
"bytes"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"testing" "testing"
@ -13,8 +12,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
// Import builders to get the builder function as package function // Import builders to get the builder function as package function
. "github.com/docker/cli/cli/internal/test/builders" . "github.com/docker/cli/cli/internal/test/builders"
"github.com/docker/docker/pkg/testutil" "github.com/gotestyourself/gotestyourself/golden"
"github.com/docker/docker/pkg/testutil/golden"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -50,14 +48,13 @@ func TestNodePsErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{
cmd := newPsCommand( infoFunc: tc.infoFunc,
test.NewFakeCliWithOutput(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc,
infoFunc: tc.infoFunc, taskInspectFunc: tc.taskInspectFunc,
nodeInspectFunc: tc.nodeInspectFunc, taskListFunc: tc.taskListFunc,
taskInspectFunc: tc.taskInspectFunc, })
taskListFunc: tc.taskListFunc, cmd := newPsCommand(cli)
}, buf))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
for key, value := range tc.flags { for key, value := range tc.flags {
cmd.Flags().Set(key, value) cmd.Flags().Set(key, value)
@ -114,21 +111,18 @@ func TestNodePs(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{
cmd := newPsCommand( infoFunc: tc.infoFunc,
test.NewFakeCliWithOutput(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc,
infoFunc: tc.infoFunc, taskInspectFunc: tc.taskInspectFunc,
nodeInspectFunc: tc.nodeInspectFunc, taskListFunc: tc.taskListFunc,
taskInspectFunc: tc.taskInspectFunc, })
taskListFunc: tc.taskListFunc, cmd := newPsCommand(cli)
}, buf))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
for key, value := range tc.flags { for key, value := range tc.flags {
cmd.Flags().Set(key, value) cmd.Flags().Set(key, value)
} }
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
actual := buf.String() golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-ps.%s.golden", tc.name))
expected := golden.Get(t, []byte(actual), fmt.Sprintf("node-ps.%s.golden", tc.name))
testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected))
} }
} }

View File

@ -1,7 +1,6 @@
package node package node
import ( import (
"bytes"
"io/ioutil" "io/ioutil"
"testing" "testing"
@ -29,11 +28,10 @@ func TestNodeRemoveErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
buf := new(bytes.Buffer)
cmd := newRemoveCommand( cmd := newRemoveCommand(
test.NewFakeCliWithOutput(&fakeClient{ test.NewFakeCli(&fakeClient{
nodeRemoveFunc: tc.nodeRemoveFunc, nodeRemoveFunc: tc.nodeRemoveFunc,
}, buf)) }))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard) cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
@ -41,8 +39,7 @@ func TestNodeRemoveErrors(t *testing.T) {
} }
func TestNodeRemoveMultiple(t *testing.T) { func TestNodeRemoveMultiple(t *testing.T) {
buf := new(bytes.Buffer) cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}))
cmd := newRemoveCommand(test.NewFakeCliWithOutput(&fakeClient{}, buf))
cmd.SetArgs([]string{"nodeID1", "nodeID2"}) cmd.SetArgs([]string{"nodeID1", "nodeID2"})
assert.NoError(t, cmd.Execute()) assert.NoError(t, cmd.Execute())
} }

View File

@ -1,10 +1,10 @@
ID: nodeID ID: nodeID
Name: defaultNodeName Name: defaultNodeName
Hostname: defaultNodeHostname Hostname: defaultNodeHostname
Joined at: 2009-11-10 23:00:00 +0000 utc Joined at: 2009-11-10 23:00:00 +0000 utc
Status: Status:
State: Ready State: Ready
Availability: Active Availability: Active
Address: 127.0.0.1 Address: 127.0.0.1
Manager Status: Manager Status:
Address: 127.0.0.1 Address: 127.0.0.1
@ -15,11 +15,10 @@ Platform:
Architecture: x86_64 Architecture: x86_64
Resources: Resources:
CPUs: 0 CPUs: 0
Memory: 20 MiB Memory: 20MiB
Plugins: Plugins:
Network: bridge, overlay Network: bridge, overlay
Volume: local Volume: local
Engine Version: 1.13.0 Engine Version: 1.13.0
Engine Labels: Engine Labels:
- engine = label - engine=label

View File

@ -1,10 +1,10 @@
ID: nodeID ID: nodeID
Name: defaultNodeName Name: defaultNodeName
Hostname: defaultNodeHostname Hostname: defaultNodeHostname
Joined at: 2009-11-10 23:00:00 +0000 utc Joined at: 2009-11-10 23:00:00 +0000 utc
Status: Status:
State: Ready State: Ready
Availability: Active Availability: Active
Address: 127.0.0.1 Address: 127.0.0.1
Manager Status: Manager Status:
Address: 127.0.0.1 Address: 127.0.0.1
@ -15,11 +15,10 @@ Platform:
Architecture: x86_64 Architecture: x86_64
Resources: Resources:
CPUs: 0 CPUs: 0
Memory: 20 MiB Memory: 20MiB
Plugins: Plugins:
Network: bridge, overlay Network: bridge, overlay
Volume: local Volume: local
Engine Version: 1.13.0 Engine Version: 1.13.0
Engine Labels: Engine Labels:
- engine = label - engine=label

View File

@ -1,23 +1,22 @@
ID: nodeID ID: nodeID
Name: defaultNodeName Name: defaultNodeName
Labels: Labels:
- lbl1 = value1 - lbl1=value1
Hostname: defaultNodeHostname Hostname: defaultNodeHostname
Joined at: 2009-11-10 23:00:00 +0000 utc Joined at: 2009-11-10 23:00:00 +0000 utc
Status: Status:
State: Ready State: Ready
Availability: Active Availability: Active
Address: 127.0.0.1 Address: 127.0.0.1
Platform: Platform:
Operating System: linux Operating System: linux
Architecture: x86_64 Architecture: x86_64
Resources: Resources:
CPUs: 0 CPUs: 0
Memory: 20 MiB Memory: 20MiB
Plugins: Plugins:
Network: bridge, overlay Network: bridge, overlay
Volume: local Volume: local
Engine Version: 1.13.0 Engine Version: 1.13.0
Engine Labels: Engine Labels:
- engine = label - engine=label

View File

@ -0,0 +1,2 @@
nodeHostname1: Leader
nodeHostname2: Reachable

View File

@ -0,0 +1,3 @@
nodeID1: nodeHostname1 Ready/Leader
nodeID2: nodeHostname2 Ready/Reachable
nodeID3: nodeHostname3 Ready/

View File

@ -1,3 +1,4 @@
node-1-foo: ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
node-2-foo: Leader nodeID3 node-1-foo Ready Active
node-10-foo: Reachable nodeID1 * node-2-foo Ready Active Leader
nodeID2 node-10-foo Ready Active Reachable

View File

@ -1,2 +1,2 @@
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
taskID rl02d5gwz6chzu7il5fhtb8be.1 myimage:mytag defaultNodeName Ready Ready 2 hours ago *:80->80/tcp taskID rl02d5gwz6chzu7il5fhtb8be.1 myimage:mytag defaultNodeName Ready Ready 2 hours ago *:80->80/tcp

View File

@ -1,4 +1,4 @@
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
taskID1 failure.1 myimage:mytag defaultNodeName Ready Ready 2 hours ago "a task error" taskID1 failure.1 myimage:mytag defaultNodeName Ready Ready 2 hours ago "a task error"
taskID2 \_ failure.1 myimage:mytag defaultNodeName Ready Ready 3 hours ago "a task error" taskID2 \_ failure.1 myimage:mytag defaultNodeName Ready Ready 3 hours ago "a task error"
taskID3 \_ failure.1 myimage:mytag defaultNodeName Ready Ready 4 hours ago "a task error" taskID3 \_ failure.1 myimage:mytag defaultNodeName Ready Ready 4 hours ago "a task error"