func TestNodeRemoveErrors(t *testing.T) { testCases := []struct { args []string nodeRemoveFunc func() error expectedError string }{ { expectedError: "requires at least 1 argument", }, { args: []string{"nodeID"}, nodeRemoveFunc: func() error { return fmt.Errorf("error removing the node") }, expectedError: "error removing the node", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newRemoveCommand( test.NewFakeCli(&fakeClient{ nodeRemoveFunc: tc.nodeRemoveFunc, }, buf)) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestSwarmLeaveErrors(t *testing.T) { testCases := []struct { name string args []string swarmLeaveFunc func() error expectedError string }{ { name: "too-many-args", args: []string{"foo"}, expectedError: "accepts no argument(s)", }, { name: "leave-failed", swarmLeaveFunc: func() error { return fmt.Errorf("error leaving the swarm") }, expectedError: "error leaving the swarm", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newLeaveCommand( test.NewFakeCli(&fakeClient{ swarmLeaveFunc: tc.swarmLeaveFunc, }, buf)) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestSwarmLeave(t *testing.T) { buf := new(bytes.Buffer) cmd := newLeaveCommand( test.NewFakeCli(&fakeClient{}, buf)) assert.NilError(t, cmd.Execute()) assert.Equal(t, strings.TrimSpace(buf.String()), "Node left the swarm.") }
func TestNodeUpdateErrors(t *testing.T) { testCases := []struct { args []string flags map[string]string nodeInspectFunc func() (swarm.Node, []byte, error) nodeUpdateFunc func(nodeID string, version swarm.Version, node swarm.NodeSpec) error expectedError string }{ { expectedError: "requires exactly 1 argument", }, { args: []string{"node1", "node2"}, expectedError: "requires exactly 1 argument", }, { args: []string{"nodeID"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node") }, expectedError: "error inspecting the node", }, { args: []string{"nodeID"}, nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error { return fmt.Errorf("error updating the node") }, expectedError: "error updating the node", }, { args: []string{"nodeID"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(NodeLabels(map[string]string{ "key": "value", })), []byte{}, nil }, flags: map[string]string{ "label-rm": "notpresent", }, expectedError: "key notpresent doesn't exist in node's labels", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newUpdateCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, nodeUpdateFunc: tc.nodeUpdateFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestNodeListQuietShouldOnlyPrintIDs(t *testing.T) { buf := new(bytes.Buffer) cmd := newListCommand( test.NewFakeCli(&fakeClient{ nodeListFunc: func() ([]swarm.Node, error) { return []swarm.Node{ *Node(), }, nil }, }, buf)) cmd.Flags().Set("quiet", "true") assert.NilError(t, cmd.Execute()) assert.Contains(t, buf.String(), "nodeID") }
func TestNodePsErrors(t *testing.T) { testCases := []struct { args []string flags map[string]string infoFunc func() (types.Info, error) nodeInspectFunc func() (swarm.Node, []byte, error) taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error) taskInspectFunc func(taskID string) (swarm.Task, []byte, error) expectedError string }{ { infoFunc: func() (types.Info, error) { return types.Info{}, fmt.Errorf("error asking for node info") }, expectedError: "error asking for node info", }, { args: []string{"nodeID"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node") }, expectedError: "error inspecting the node", }, { args: []string{"nodeID"}, taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{}, fmt.Errorf("error returning the task list") }, expectedError: "error returning the task list", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newPsCommand( test.NewFakeCli(&fakeClient{ infoFunc: tc.infoFunc, nodeInspectFunc: tc.nodeInspectFunc, taskInspectFunc: tc.taskInspectFunc, taskListFunc: tc.taskListFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestSwarmInit(t *testing.T) { testCases := []struct { name string flags map[string]string swarmInitFunc func() (string, error) swarmInspectFunc func() (swarm.Swarm, error) swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error) nodeInspectFunc func() (swarm.Node, []byte, error) }{ { name: "init", swarmInitFunc: func() (string, error) { return "nodeID", nil }, }, { name: "init-autolock", flags: map[string]string{ flagAutolock: "true", }, swarmInitFunc: func() (string, error) { return "nodeID", nil }, swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{ UnlockKey: "unlock-key", }, nil }, }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInitCommand( test.NewFakeCli(&fakeClient{ swarmInitFunc: tc.swarmInitFunc, swarmInspectFunc: tc.swarmInspectFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, nodeInspectFunc: tc.nodeInspectFunc, }, buf)) for key, value := range tc.flags { cmd.Flags().Set(key, value) } assert.NilError(t, cmd.Execute()) actual := buf.String() expected := golden.Get(t, []byte(actual), fmt.Sprintf("init-%s.golden", tc.name)) assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected)) } }
func TestSwarmJoinErrors(t *testing.T) { testCases := []struct { name string args []string swarmJoinFunc func() error infoFunc func() (types.Info, error) expectedError string }{ { name: "not-enough-args", expectedError: "requires exactly 1 argument", }, { name: "too-many-args", args: []string{"remote1", "remote2"}, expectedError: "requires exactly 1 argument", }, { name: "join-failed", args: []string{"remote"}, swarmJoinFunc: func() error { return fmt.Errorf("error joining the swarm") }, expectedError: "error joining the swarm", }, { name: "join-failed-on-init", args: []string{"remote"}, infoFunc: func() (types.Info, error) { return types.Info{}, fmt.Errorf("error asking for node info") }, expectedError: "error asking for node info", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newJoinCommand( test.NewFakeCli(&fakeClient{ swarmJoinFunc: tc.swarmJoinFunc, infoFunc: tc.infoFunc, }, buf)) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestNodeDemoteMultipleNode(t *testing.T) { buf := new(bytes.Buffer) cmd := newDemoteCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager()), []byte{}, nil }, nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error { if node.Role != swarm.NodeRoleWorker { return fmt.Errorf("expected role worker, got %s", node.Role) } return nil }, }, buf)) cmd.SetArgs([]string{"nodeID1", "nodeID2"}) assert.NilError(t, cmd.Execute()) }
func TestSwarmJoin(t *testing.T) { testCases := []struct { name string infoFunc func() (types.Info, error) expected string }{ { name: "join-as-manager", infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ ControlAvailable: true, }, }, nil }, expected: "This node joined a swarm as a manager.", }, { name: "join-as-worker", infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ ControlAvailable: false, }, }, nil }, expected: "This node joined a swarm as a worker.", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newJoinCommand( test.NewFakeCli(&fakeClient{ infoFunc: tc.infoFunc, }, buf)) cmd.SetArgs([]string{"remote"}) assert.NilError(t, cmd.Execute()) assert.Equal(t, strings.TrimSpace(buf.String()), tc.expected) } }
func TestNodeInspectPretty(t *testing.T) { testCases := []struct { name string nodeInspectFunc func() (swarm.Node, []byte, error) }{ { name: "simple", nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(NodeLabels(map[string]string{ "lbl1": "value1", })), []byte{}, nil }, }, { name: "manager", nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager()), []byte{}, nil }, }, { name: "manager-leader", nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager(Leader())), []byte{}, nil }, }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInspectCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, }, buf)) cmd.SetArgs([]string{"nodeID"}) cmd.Flags().Set("pretty", "true") assert.NilError(t, cmd.Execute()) actual := buf.String() expected := golden.Get(t, []byte(actual), fmt.Sprintf("node-inspect-pretty.%s.golden", tc.name)) assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected)) } }
func TestSwarmUnlock(t *testing.T) { input := "unlockKey" buf := new(bytes.Buffer) dockerCli := test.NewFakeCli(&fakeClient{ infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ LocalNodeState: swarm.LocalNodeStateLocked, }, }, nil }, swarmUnlockFunc: func(req swarm.UnlockRequest) error { if req.UnlockKey != input { return fmt.Errorf("Invalid unlock key") } return nil }, }, buf) dockerCli.SetIn(ioutil.NopCloser(strings.NewReader(input))) cmd := newUnlockCommand(dockerCli) assert.NilError(t, cmd.Execute()) }
func TestNodeListErrorOnAPIFailure(t *testing.T) { testCases := []struct { nodeListFunc func() ([]swarm.Node, error) infoFunc func() (types.Info, error) expectedError string }{ { nodeListFunc: func() ([]swarm.Node, error) { return []swarm.Node{}, fmt.Errorf("error listing nodes") }, expectedError: "error listing nodes", }, { nodeListFunc: func() ([]swarm.Node, error) { return []swarm.Node{ { ID: "nodeID", }, }, nil }, infoFunc: func() (types.Info, error) { return types.Info{}, fmt.Errorf("error asking for node info") }, expectedError: "error asking for node info", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newListCommand( test.NewFakeCli(&fakeClient{ nodeListFunc: tc.nodeListFunc, infoFunc: tc.infoFunc, }, buf)) cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestNodeDemoteErrors(t *testing.T) { testCases := []struct { args []string nodeInspectFunc func() (swarm.Node, []byte, error) nodeUpdateFunc func(nodeID string, version swarm.Version, node swarm.NodeSpec) error expectedError string }{ { expectedError: "requires at least 1 argument", }, { args: []string{"nodeID"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node") }, expectedError: "error inspecting the node", }, { args: []string{"nodeID"}, nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error { return fmt.Errorf("error updating the node") }, expectedError: "error updating the node", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newDemoteCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, nodeUpdateFunc: tc.nodeUpdateFunc, }, buf)) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestNodeList(t *testing.T) { buf := new(bytes.Buffer) cmd := newListCommand( test.NewFakeCli(&fakeClient{ nodeListFunc: func() ([]swarm.Node, error) { return []swarm.Node{ *Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())), *Node(NodeID("nodeID2"), Hostname("nodeHostname2"), Manager()), *Node(NodeID("nodeID3"), Hostname("nodeHostname3")), }, nil }, infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ NodeID: "nodeID1", }, }, nil }, }, buf)) assert.NilError(t, cmd.Execute()) assert.Contains(t, buf.String(), `nodeID1 * nodeHostname1 Ready Active Leader`) assert.Contains(t, buf.String(), `nodeID2 nodeHostname2 Ready Active Reachable`) assert.Contains(t, buf.String(), `nodeID3 nodeHostname3 Ready Active`) }
// Test case for #24090 func TestNodeListContainsHostname(t *testing.T) { buf := new(bytes.Buffer) cmd := newListCommand(test.NewFakeCli(&fakeClient{}, buf)) assert.NilError(t, cmd.Execute()) assert.Contains(t, buf.String(), "HOSTNAME") }
func TestSwarmUnlockErrors(t *testing.T) { testCases := []struct { name string args []string input string swarmUnlockFunc func(req swarm.UnlockRequest) error infoFunc func() (types.Info, error) expectedError string }{ { name: "too-many-args", args: []string{"foo"}, expectedError: "accepts no argument(s)", }, { name: "is-not-part-of-a-swarm", infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ LocalNodeState: swarm.LocalNodeStateInactive, }, }, nil }, expectedError: "This node is not part of a swarm", }, { name: "is-not-locked", infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ LocalNodeState: swarm.LocalNodeStateActive, }, }, nil }, expectedError: "Error: swarm is not locked", }, { name: "unlockrequest-failed", infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ LocalNodeState: swarm.LocalNodeStateLocked, }, }, nil }, swarmUnlockFunc: func(req swarm.UnlockRequest) error { return fmt.Errorf("error unlocking the swarm") }, expectedError: "error unlocking the swarm", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newUnlockCommand( test.NewFakeCli(&fakeClient{ infoFunc: tc.infoFunc, swarmUnlockFunc: tc.swarmUnlockFunc, }, buf)) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestSwarmJoinTokenErrors(t *testing.T) { testCases := []struct { name string args []string flags map[string]string infoFunc func() (types.Info, error) swarmInspectFunc func() (swarm.Swarm, error) swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error nodeInspectFunc func() (swarm.Node, []byte, error) expectedError string }{ { name: "not-enough-args", expectedError: "requires exactly 1 argument", }, { name: "too-many-args", args: []string{"worker", "manager"}, expectedError: "requires exactly 1 argument", }, { name: "invalid-args", args: []string{"foo"}, expectedError: "unknown role foo", }, { name: "swarm-inspect-failed", args: []string{"worker"}, swarmInspectFunc: func() (swarm.Swarm, error) { return swarm.Swarm{}, fmt.Errorf("error inspecting the swarm") }, expectedError: "error inspecting the swarm", }, { name: "swarm-inspect-rotate-failed", args: []string{"worker"}, flags: map[string]string{ flagRotate: "true", }, swarmInspectFunc: func() (swarm.Swarm, error) { return swarm.Swarm{}, fmt.Errorf("error inspecting the swarm") }, expectedError: "error inspecting the swarm", }, { name: "swarm-update-failed", args: []string{"worker"}, flags: map[string]string{ flagRotate: "true", }, swarmUpdateFunc: func(swarm swarm.Spec, flags swarm.UpdateFlags) error { return fmt.Errorf("error updating the swarm") }, expectedError: "error updating the swarm", }, { name: "node-inspect-failed", args: []string{"worker"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting node") }, expectedError: "error inspecting node", }, { name: "info-failed", args: []string{"worker"}, infoFunc: func() (types.Info, error) { return types.Info{}, fmt.Errorf("error asking for node info") }, expectedError: "error asking for node info", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newJoinTokenCommand( test.NewFakeCli(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc, infoFunc: tc.infoFunc, nodeInspectFunc: tc.nodeInspectFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestNodeInspectErrors(t *testing.T) { testCases := []struct { args []string flags map[string]string nodeInspectFunc func() (swarm.Node, []byte, error) infoFunc func() (types.Info, error) expectedError string }{ { expectedError: "requires at least 1 argument", }, { args: []string{"self"}, infoFunc: func() (types.Info, error) { return types.Info{}, fmt.Errorf("error asking for node info") }, expectedError: "error asking for node info", }, { args: []string{"nodeID"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node") }, infoFunc: func() (types.Info, error) { return types.Info{}, fmt.Errorf("error asking for node info") }, expectedError: "error inspecting the node", }, { args: []string{"self"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node") }, infoFunc: func() (types.Info, error) { return types.Info{}, nil }, expectedError: "error inspecting the node", }, { args: []string{"self"}, flags: map[string]string{ "pretty": "true", }, infoFunc: func() (types.Info, error) { return types.Info{}, fmt.Errorf("error asking for node info") }, expectedError: "error asking for node info", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInspectCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, infoFunc: tc.infoFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestSwarmUnlockKey(t *testing.T) { testCases := []struct { name string args []string flags map[string]string swarmInspectFunc func() (swarm.Swarm, error) swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error) }{ { name: "unlock-key", swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{ UnlockKey: "unlock-key", }, nil }, }, { name: "unlock-key-quiet", flags: map[string]string{ flagQuiet: "true", }, swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{ UnlockKey: "unlock-key", }, nil }, }, { name: "unlock-key-rotate", flags: map[string]string{ flagRotate: "true", }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(Autolock()), nil }, swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{ UnlockKey: "unlock-key", }, nil }, }, { name: "unlock-key-rotate-quiet", flags: map[string]string{ flagQuiet: "true", flagRotate: "true", }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(Autolock()), nil }, swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{ UnlockKey: "unlock-key", }, nil }, }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newUnlockKeyCommand( test.NewFakeCli(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } assert.NilError(t, cmd.Execute()) actual := buf.String() expected := golden.Get(t, []byte(actual), fmt.Sprintf("unlockkeys-%s.golden", tc.name)) assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected)) } }
func TestSwarmInitErrorOnAPIFailure(t *testing.T) { testCases := []struct { name string flags map[string]string swarmInitFunc func() (string, error) swarmInspectFunc func() (swarm.Swarm, error) swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error) nodeInspectFunc func() (swarm.Node, []byte, error) expectedError string }{ { name: "init-failed", swarmInitFunc: func() (string, error) { return "", fmt.Errorf("error initializing the swarm") }, expectedError: "error initializing the swarm", }, { name: "init-faild-with-ip-choice", swarmInitFunc: func() (string, error) { return "", fmt.Errorf("could not choose an IP address to advertise") }, expectedError: "could not choose an IP address to advertise - specify one with --advertise-addr", }, { name: "swarm-inspect-after-init-failed", swarmInspectFunc: func() (swarm.Swarm, error) { return swarm.Swarm{}, fmt.Errorf("error inspecting the swarm") }, expectedError: "error inspecting the swarm", }, { name: "node-inspect-after-init-failed", nodeInspectFunc: func() (swarm.Node, []byte, error) { return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node") }, expectedError: "error inspecting the node", }, { name: "swarm-get-unlock-key-after-init-failed", flags: map[string]string{ flagAutolock: "true", }, swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{}, fmt.Errorf("error getting swarm unlock key") }, expectedError: "could not fetch unlock key: error getting swarm unlock key", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInitCommand( test.NewFakeCli(&fakeClient{ swarmInitFunc: tc.swarmInitFunc, swarmInspectFunc: tc.swarmInspectFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, nodeInspectFunc: tc.nodeInspectFunc, }, buf)) for key, value := range tc.flags { cmd.Flags().Set(key, value) } cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestSwarmUpdate(t *testing.T) { testCases := []struct { name string args []string flags map[string]string swarmInspectFunc func() (swarm.Swarm, error) swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error) }{ { name: "noargs", }, { name: "all-flags-quiet", flags: map[string]string{ flagTaskHistoryLimit: "10", flagDispatcherHeartbeat: "10s", flagCertExpiry: "20s", flagExternalCA: "protocol=cfssl,url=https://example.com.", flagMaxSnapshots: "10", flagSnapshotInterval: "100", flagAutolock: "true", flagQuiet: "true", }, swarmUpdateFunc: func(swarm swarm.Spec, flags swarm.UpdateFlags) error { if *swarm.Orchestration.TaskHistoryRetentionLimit != 10 { return fmt.Errorf("historyLimit not correctly set") } heartbeatDuration, err := time.ParseDuration("10s") if err != nil { return err } if swarm.Dispatcher.HeartbeatPeriod != heartbeatDuration { return fmt.Errorf("heartbeatPeriodLimit not correctly set") } certExpiryDuration, err := time.ParseDuration("20s") if err != nil { return err } if swarm.CAConfig.NodeCertExpiry != certExpiryDuration { return fmt.Errorf("certExpiry not correctly set") } if len(swarm.CAConfig.ExternalCAs) != 1 { return fmt.Errorf("externalCA not correctly set") } if *swarm.Raft.KeepOldSnapshots != 10 { return fmt.Errorf("keepOldSnapshots not correctly set") } if swarm.Raft.SnapshotInterval != 100 { return fmt.Errorf("snapshotInterval not correctly set") } if !swarm.EncryptionConfig.AutoLockManagers { return fmt.Errorf("autolock not correctly set") } return nil }, }, { name: "autolock-unlock-key", flags: map[string]string{ flagTaskHistoryLimit: "10", flagAutolock: "true", }, swarmUpdateFunc: func(swarm swarm.Spec, flags swarm.UpdateFlags) error { if *swarm.Orchestration.TaskHistoryRetentionLimit != 10 { return fmt.Errorf("historyLimit not correctly set") } return nil }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(), nil }, swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{ UnlockKey: "unlock-key", }, nil }, }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newUpdateCommand( test.NewFakeCli(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } cmd.SetOutput(buf) assert.NilError(t, cmd.Execute()) actual := buf.String() expected := golden.Get(t, []byte(actual), fmt.Sprintf("update-%s.golden", tc.name)) assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected)) } }
func TestSwarmUpdateErrors(t *testing.T) { testCases := []struct { name string args []string flags map[string]string swarmInspectFunc func() (swarm.Swarm, error) swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error) expectedError string }{ { name: "too-many-args", args: []string{"foo"}, expectedError: "accepts no argument(s)", }, { name: "swarm-inspect-error", flags: map[string]string{ flagTaskHistoryLimit: "10", }, swarmInspectFunc: func() (swarm.Swarm, error) { return swarm.Swarm{}, fmt.Errorf("error inspecting the swarm") }, expectedError: "error inspecting the swarm", }, { name: "swarm-update-error", flags: map[string]string{ flagTaskHistoryLimit: "10", }, swarmUpdateFunc: func(swarm swarm.Spec, flags swarm.UpdateFlags) error { return fmt.Errorf("error updating the swarm") }, expectedError: "error updating the swarm", }, { name: "swarm-unlockkey-error", flags: map[string]string{ flagAutolock: "true", }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(), nil }, swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{}, fmt.Errorf("error getting unlock key") }, expectedError: "error getting unlock key", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newUpdateCommand( test.NewFakeCli(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }
func TestNodePs(t *testing.T) { testCases := []struct { name string args []string flags map[string]string infoFunc func() (types.Info, error) nodeInspectFunc func() (swarm.Node, []byte, error) taskListFunc func(options types.TaskListOptions) ([]swarm.Task, error) taskInspectFunc func(taskID string) (swarm.Task, []byte, error) }{ { name: "simple", args: []string{"nodeID"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(), []byte{}, nil }, taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{ *Task(WithStatus(Timestamp(time.Now().Add(-2*time.Hour)), PortStatus([]swarm.PortConfig{ { TargetPort: 80, PublishedPort: 80, Protocol: "tcp", }, }))), }, nil }, }, { name: "with-errors", args: []string{"nodeID"}, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(), []byte{}, nil }, taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{ *Task(TaskID("taskID1"), ServiceID("failure"), WithStatus(Timestamp(time.Now().Add(-2*time.Hour)), StatusErr("a task error"))), *Task(TaskID("taskID2"), ServiceID("failure"), WithStatus(Timestamp(time.Now().Add(-3*time.Hour)), StatusErr("a task error"))), *Task(TaskID("taskID3"), ServiceID("failure"), WithStatus(Timestamp(time.Now().Add(-4*time.Hour)), StatusErr("a task error"))), }, nil }, }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newPsCommand( test.NewFakeCli(&fakeClient{ infoFunc: tc.infoFunc, nodeInspectFunc: tc.nodeInspectFunc, taskInspectFunc: tc.taskInspectFunc, taskListFunc: tc.taskListFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } assert.NilError(t, cmd.Execute()) actual := buf.String() expected := golden.Get(t, []byte(actual), fmt.Sprintf("node-ps.%s.golden", tc.name)) assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected)) } }
func TestNodeUpdate(t *testing.T) { testCases := []struct { args []string flags map[string]string nodeInspectFunc func() (swarm.Node, []byte, error) nodeUpdateFunc func(nodeID string, version swarm.Version, node swarm.NodeSpec) error }{ { args: []string{"nodeID"}, flags: map[string]string{ "role": "manager", }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(), []byte{}, nil }, nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error { if node.Role != swarm.NodeRoleManager { return fmt.Errorf("expected role manager, got %s", node.Role) } return nil }, }, { args: []string{"nodeID"}, flags: map[string]string{ "availability": "drain", }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(), []byte{}, nil }, nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error { if node.Availability != swarm.NodeAvailabilityDrain { return fmt.Errorf("expected drain availability, got %s", node.Availability) } return nil }, }, { args: []string{"nodeID"}, flags: map[string]string{ "label-add": "lbl", }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(), []byte{}, nil }, nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error { if _, present := node.Annotations.Labels["lbl"]; !present { return fmt.Errorf("expected 'lbl' label, got %v", node.Annotations.Labels) } return nil }, }, { args: []string{"nodeID"}, flags: map[string]string{ "label-add": "key=value", }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(), []byte{}, nil }, nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error { if value, present := node.Annotations.Labels["key"]; !present || value != "value" { return fmt.Errorf("expected 'key' label to be 'value', got %v", node.Annotations.Labels) } return nil }, }, { args: []string{"nodeID"}, flags: map[string]string{ "label-rm": "key", }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(NodeLabels(map[string]string{ "key": "value", })), []byte{}, nil }, nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error { if len(node.Annotations.Labels) > 0 { return fmt.Errorf("expected no labels, got %v", node.Annotations.Labels) } return nil }, }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newUpdateCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, nodeUpdateFunc: tc.nodeUpdateFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } assert.NilError(t, cmd.Execute()) } }
func TestSwarmJoinToken(t *testing.T) { testCases := []struct { name string args []string flags map[string]string infoFunc func() (types.Info, error) swarmInspectFunc func() (swarm.Swarm, error) nodeInspectFunc func() (swarm.Node, []byte, error) }{ { name: "worker", args: []string{"worker"}, infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ NodeID: "nodeID", }, }, nil }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager()), []byte{}, nil }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(), nil }, }, { name: "manager", args: []string{"manager"}, infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ NodeID: "nodeID", }, }, nil }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager()), []byte{}, nil }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(), nil }, }, { name: "manager-rotate", args: []string{"manager"}, flags: map[string]string{ flagRotate: "true", }, infoFunc: func() (types.Info, error) { return types.Info{ Swarm: swarm.Info{ NodeID: "nodeID", }, }, nil }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager()), []byte{}, nil }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(), nil }, }, { name: "worker-quiet", args: []string{"worker"}, flags: map[string]string{ flagQuiet: "true", }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager()), []byte{}, nil }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(), nil }, }, { name: "manager-quiet", args: []string{"manager"}, flags: map[string]string{ flagQuiet: "true", }, nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager()), []byte{}, nil }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(), nil }, }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newJoinTokenCommand( test.NewFakeCli(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, infoFunc: tc.infoFunc, nodeInspectFunc: tc.nodeInspectFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } assert.NilError(t, cmd.Execute()) actual := buf.String() expected := golden.Get(t, []byte(actual), fmt.Sprintf("jointoken-%s.golden", tc.name)) assert.EqualNormalizedString(t, assert.RemoveSpace, actual, string(expected)) } }
func TestNodeRemoveMultiple(t *testing.T) { buf := new(bytes.Buffer) cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}, buf)) cmd.SetArgs([]string{"nodeID1", "nodeID2"}) assert.NilError(t, cmd.Execute()) }
func TestSwarmUnlockKeyErrors(t *testing.T) { testCases := []struct { name string args []string flags map[string]string swarmInspectFunc func() (swarm.Swarm, error) swarmUpdateFunc func(swarm swarm.Spec, flags swarm.UpdateFlags) error swarmGetUnlockKeyFunc func() (types.SwarmUnlockKeyResponse, error) expectedError string }{ { name: "too-many-args", args: []string{"foo"}, expectedError: "accepts no argument(s)", }, { name: "swarm-inspect-rotate-failed", flags: map[string]string{ flagRotate: "true", }, swarmInspectFunc: func() (swarm.Swarm, error) { return swarm.Swarm{}, fmt.Errorf("error inspecting the swarm") }, expectedError: "error inspecting the swarm", }, { name: "swarm-rotate-no-autolock-failed", flags: map[string]string{ flagRotate: "true", }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(), nil }, expectedError: "cannot rotate because autolock is not turned on", }, { name: "swarm-update-failed", flags: map[string]string{ flagRotate: "true", }, swarmInspectFunc: func() (swarm.Swarm, error) { return *Swarm(Autolock()), nil }, swarmUpdateFunc: func(swarm swarm.Spec, flags swarm.UpdateFlags) error { return fmt.Errorf("error updating the swarm") }, expectedError: "error updating the swarm", }, { name: "swarm-get-unlock-key-failed", swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{}, fmt.Errorf("error getting unlock key") }, expectedError: "error getting unlock key", }, { name: "swarm-no-unlock-key-failed", swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) { return types.SwarmUnlockKeyResponse{ UnlockKey: "", }, nil }, expectedError: "no unlock key is set", }, } for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newUnlockKeyCommand( test.NewFakeCli(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, }, buf)) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } cmd.SetOutput(ioutil.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } }