1package command
2
3import (
4	"fmt"
5	"testing"
6
7	"github.com/hashicorp/nomad/command/agent"
8	"github.com/hashicorp/nomad/nomad/mock"
9	"github.com/hashicorp/nomad/nomad/structs"
10	"github.com/hashicorp/nomad/testutil"
11	"github.com/mitchellh/cli"
12	"github.com/posener/complete"
13	"github.com/stretchr/testify/assert"
14)
15
16func TestStatusCommand_Run_JobStatus(t *testing.T) {
17	assert := assert.New(t)
18	t.Parallel()
19
20	srv, _, url := testServer(t, true, nil)
21	defer srv.Shutdown()
22
23	ui := new(cli.MockUi)
24	cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
25
26	// Create a fake job
27	state := srv.Agent.Server().State()
28	j := mock.Job()
29	assert.Nil(state.UpsertJob(1000, j))
30
31	// Query to check the job status
32	if code := cmd.Run([]string{"-address=" + url, j.ID}); code != 0 {
33		t.Fatalf("expected exit 0, got: %d", code)
34	}
35
36	out := ui.OutputWriter.String()
37	assert.Contains(out, j.ID)
38
39	ui.OutputWriter.Reset()
40}
41
42func TestStatusCommand_Run_JobStatus_MultiMatch(t *testing.T) {
43	assert := assert.New(t)
44	t.Parallel()
45
46	srv, _, url := testServer(t, true, nil)
47	defer srv.Shutdown()
48
49	ui := new(cli.MockUi)
50	cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
51
52	// Create two fake jobs sharing a prefix
53	state := srv.Agent.Server().State()
54	j := mock.Job()
55	j2 := mock.Job()
56	j2.ID = fmt.Sprintf("%s-more", j.ID)
57	assert.Nil(state.UpsertJob(1000, j))
58	assert.Nil(state.UpsertJob(1001, j2))
59
60	// Query to check the job status
61	if code := cmd.Run([]string{"-address=" + url, j.ID}); code != 0 {
62		t.Fatalf("expected exit 0, got: %d", code)
63	}
64
65	out := ui.OutputWriter.String()
66	assert.Contains(out, j.ID)
67
68	ui.OutputWriter.Reset()
69}
70
71func TestStatusCommand_Run_EvalStatus(t *testing.T) {
72	assert := assert.New(t)
73	t.Parallel()
74
75	srv, _, url := testServer(t, true, nil)
76	defer srv.Shutdown()
77
78	ui := new(cli.MockUi)
79	cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
80
81	// Create a fake eval
82	state := srv.Agent.Server().State()
83	eval := mock.Eval()
84	assert.Nil(state.UpsertEvals(1000, []*structs.Evaluation{eval}))
85
86	// Query to check the eval status
87	if code := cmd.Run([]string{"-address=" + url, eval.ID}); code != 0 {
88		t.Fatalf("expected exit 0, got: %d", code)
89	}
90
91	out := ui.OutputWriter.String()
92	assert.Contains(out, eval.ID[:shortId])
93
94	ui.OutputWriter.Reset()
95}
96
97func TestStatusCommand_Run_NodeStatus(t *testing.T) {
98	assert := assert.New(t)
99	t.Parallel()
100
101	// Start in dev mode so we get a node registration
102	srv, client, url := testServer(t, true, func(c *agent.Config) {
103		c.NodeName = "mynode"
104	})
105	defer srv.Shutdown()
106
107	ui := new(cli.MockUi)
108	cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
109
110	// Wait for a node to appear
111	var nodeID string
112	testutil.WaitForResult(func() (bool, error) {
113		nodes, _, err := client.Nodes().List(nil)
114		if err != nil {
115			return false, err
116		}
117		if len(nodes) == 0 {
118			return false, fmt.Errorf("missing node")
119		}
120		nodeID = nodes[0].ID
121		return true, nil
122	}, func(err error) {
123		t.Fatalf("err: %s", err)
124	})
125
126	// Query to check the node status
127	if code := cmd.Run([]string{"-address=" + url, nodeID}); code != 0 {
128		t.Fatalf("expected exit 0, got: %d", code)
129	}
130
131	out := ui.OutputWriter.String()
132	assert.Contains(out, "mynode")
133
134	ui.OutputWriter.Reset()
135}
136
137func TestStatusCommand_Run_AllocStatus(t *testing.T) {
138	assert := assert.New(t)
139	t.Parallel()
140
141	srv, _, url := testServer(t, true, nil)
142	defer srv.Shutdown()
143
144	ui := new(cli.MockUi)
145	cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
146
147	// Create a fake alloc
148	state := srv.Agent.Server().State()
149	alloc := mock.Alloc()
150	assert.Nil(state.UpsertAllocs(1000, []*structs.Allocation{alloc}))
151
152	if code := cmd.Run([]string{"-address=" + url, alloc.ID}); code != 0 {
153		t.Fatalf("expected exit 0, got: %d", code)
154	}
155
156	out := ui.OutputWriter.String()
157	assert.Contains(out, alloc.ID[:shortId])
158
159	ui.OutputWriter.Reset()
160}
161
162func TestStatusCommand_Run_DeploymentStatus(t *testing.T) {
163	assert := assert.New(t)
164	t.Parallel()
165
166	srv, _, url := testServer(t, true, nil)
167	defer srv.Shutdown()
168
169	ui := new(cli.MockUi)
170	cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
171
172	// Create a fake deployment
173	state := srv.Agent.Server().State()
174	deployment := mock.Deployment()
175	assert.Nil(state.UpsertDeployment(1000, deployment))
176
177	// Query to check the deployment status
178	if code := cmd.Run([]string{"-address=" + url, deployment.ID}); code != 0 {
179		t.Fatalf("expected exit 0, got: %d", code)
180	}
181
182	out := ui.OutputWriter.String()
183	assert.Contains(out, deployment.ID[:shortId])
184
185	ui.OutputWriter.Reset()
186}
187
188func TestStatusCommand_Run_NoPrefix(t *testing.T) {
189	assert := assert.New(t)
190	t.Parallel()
191
192	srv, _, url := testServer(t, true, nil)
193	defer srv.Shutdown()
194
195	ui := new(cli.MockUi)
196	cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
197
198	// Create a fake job
199	state := srv.Agent.Server().State()
200	job := mock.Job()
201	assert.Nil(state.UpsertJob(1000, job))
202
203	// Query to check status
204	if code := cmd.Run([]string{"-address=" + url}); code != 0 {
205		t.Fatalf("expected exit 0, got: %d", code)
206	}
207
208	out := ui.OutputWriter.String()
209	assert.Contains(out, job.ID)
210
211	ui.OutputWriter.Reset()
212}
213
214func TestStatusCommand_AutocompleteArgs(t *testing.T) {
215	assert := assert.New(t)
216	t.Parallel()
217
218	srv, _, url := testServer(t, true, nil)
219	defer srv.Shutdown()
220
221	ui := new(cli.MockUi)
222	cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
223
224	// Create a fake job
225	state := srv.Agent.Server().State()
226	job := mock.Job()
227	assert.Nil(state.UpsertJob(1000, job))
228
229	prefix := job.ID[:len(job.ID)-5]
230	args := complete.Args{Last: prefix}
231	predictor := cmd.AutocompleteArgs()
232
233	res := predictor.Predict(args)
234	assert.Contains(res, job.ID)
235}
236