1
by Casey Marshall
Source distribution of launchpad.net/juju-core created 20140327105939 |
1 |
// Copyright 2013 Canonical Ltd.
|
2 |
// Licensed under the AGPLv3, see LICENCE file for details.
|
|
3 |
||
4 |
package provisioner_test |
|
5 |
||
6 |
import ( |
|
7 |
stdtesting "testing" |
|
8 |
||
9 |
jc "github.com/juju/testing/checkers" |
|
10 |
gc "launchpad.net/gocheck" |
|
11 |
||
12 |
"launchpad.net/juju-core/constraints"
|
|
13 |
"launchpad.net/juju-core/errors"
|
|
14 |
"launchpad.net/juju-core/instance"
|
|
15 |
"launchpad.net/juju-core/juju/testing"
|
|
16 |
"launchpad.net/juju-core/state"
|
|
17 |
"launchpad.net/juju-core/state/api"
|
|
18 |
"launchpad.net/juju-core/state/api/params"
|
|
19 |
"launchpad.net/juju-core/state/api/provisioner"
|
|
20 |
apitesting "launchpad.net/juju-core/state/api/testing" |
|
21 |
statetesting "launchpad.net/juju-core/state/testing" |
|
22 |
coretesting "launchpad.net/juju-core/testing" |
|
23 |
"launchpad.net/juju-core/tools"
|
|
24 |
"launchpad.net/juju-core/utils"
|
|
25 |
"launchpad.net/juju-core/version"
|
|
26 |
)
|
|
27 |
||
28 |
func TestAll(t *stdtesting.T) { |
|
29 |
coretesting.MgoTestPackage(t) |
|
30 |
}
|
|
31 |
||
32 |
type provisionerSuite struct { |
|
33 |
testing.JujuConnSuite |
|
34 |
*apitesting.EnvironWatcherTests |
|
35 |
*apitesting.APIAddresserTests |
|
36 |
||
37 |
st *api.State |
|
38 |
machine *state.Machine |
|
39 |
||
40 |
provisioner *provisioner.State |
|
41 |
}
|
|
42 |
||
43 |
var _ = gc.Suite(&provisionerSuite{}) |
|
44 |
||
45 |
func (s *provisionerSuite) SetUpTest(c *gc.C) { |
|
46 |
s.JujuConnSuite.SetUpTest(c) |
|
47 |
||
48 |
var err error |
|
49 |
s.machine, err = s.State.AddMachine("quantal", state.JobManageEnviron) |
|
50 |
c.Assert(err, gc.IsNil) |
|
51 |
password, err := utils.RandomPassword() |
|
52 |
c.Assert(err, gc.IsNil) |
|
53 |
err = s.machine.SetPassword(password) |
|
54 |
c.Assert(err, gc.IsNil) |
|
55 |
err = s.machine.SetProvisioned("i-manager", "fake_nonce", nil) |
|
56 |
c.Assert(err, gc.IsNil) |
|
57 |
s.st = s.OpenAPIAsMachine(c, s.machine.Tag(), password, "fake_nonce") |
|
58 |
c.Assert(s.st, gc.NotNil) |
|
59 |
err = s.machine.SetAddresses(instance.NewAddresses([]string{"0.1.2.3"})) |
|
60 |
c.Assert(err, gc.IsNil) |
|
61 |
||
62 |
// Create the provisioner API facade.
|
|
63 |
s.provisioner = s.st.Provisioner() |
|
64 |
c.Assert(s.provisioner, gc.NotNil) |
|
65 |
||
66 |
s.EnvironWatcherTests = apitesting.NewEnvironWatcherTests(s.provisioner, s.BackingState, apitesting.HasSecrets) |
|
67 |
s.APIAddresserTests = apitesting.NewAPIAddresserTests(s.provisioner, s.BackingState) |
|
68 |
}
|
|
69 |
||
70 |
func (s *provisionerSuite) TestMachineTagAndId(c *gc.C) { |
|
71 |
apiMachine, err := s.provisioner.Machine("machine-42") |
|
72 |
c.Assert(err, gc.ErrorMatches, "machine 42 not found") |
|
73 |
c.Assert(err, jc.Satisfies, params.IsCodeNotFound) |
|
74 |
c.Assert(apiMachine, gc.IsNil) |
|
75 |
||
76 |
apiMachine, err = s.provisioner.Machine(s.machine.Tag()) |
|
77 |
c.Assert(err, gc.IsNil) |
|
78 |
c.Assert(apiMachine.Tag(), gc.Equals, s.machine.Tag()) |
|
79 |
c.Assert(apiMachine.Id(), gc.Equals, s.machine.Id()) |
|
80 |
}
|
|
81 |
||
82 |
func (s *provisionerSuite) TestGetSetStatus(c *gc.C) { |
|
83 |
apiMachine, err := s.provisioner.Machine(s.machine.Tag()) |
|
84 |
c.Assert(err, gc.IsNil) |
|
85 |
||
86 |
status, info, err := apiMachine.Status() |
|
87 |
c.Assert(err, gc.IsNil) |
|
88 |
c.Assert(status, gc.Equals, params.StatusPending) |
|
89 |
c.Assert(info, gc.Equals, "") |
|
90 |
||
91 |
err = apiMachine.SetStatus(params.StatusStarted, "blah", nil) |
|
92 |
c.Assert(err, gc.IsNil) |
|
93 |
||
94 |
status, info, err = apiMachine.Status() |
|
95 |
c.Assert(err, gc.IsNil) |
|
96 |
c.Assert(status, gc.Equals, params.StatusStarted) |
|
97 |
c.Assert(info, gc.Equals, "blah") |
|
98 |
_, _, data, err := s.machine.Status() |
|
99 |
c.Assert(err, gc.IsNil) |
|
100 |
c.Assert(data, gc.HasLen, 0) |
|
101 |
}
|
|
102 |
||
103 |
func (s *provisionerSuite) TestGetSetStatusWithData(c *gc.C) { |
|
104 |
apiMachine, err := s.provisioner.Machine(s.machine.Tag()) |
|
105 |
c.Assert(err, gc.IsNil) |
|
106 |
||
107 |
err = apiMachine.SetStatus(params.StatusError, "blah", params.StatusData{"foo": "bar"}) |
|
108 |
c.Assert(err, gc.IsNil) |
|
109 |
||
110 |
status, info, err := apiMachine.Status() |
|
111 |
c.Assert(err, gc.IsNil) |
|
112 |
c.Assert(status, gc.Equals, params.StatusError) |
|
113 |
c.Assert(info, gc.Equals, "blah") |
|
114 |
_, _, data, err := s.machine.Status() |
|
115 |
c.Assert(err, gc.IsNil) |
|
116 |
c.Assert(data, gc.DeepEquals, params.StatusData{"foo": "bar"}) |
|
117 |
}
|
|
118 |
||
119 |
func (s *provisionerSuite) TestMachinesWithTransientErrors(c *gc.C) { |
|
120 |
machine, err := s.State.AddMachine("quantal", state.JobHostUnits) |
|
121 |
c.Assert(err, gc.IsNil) |
|
122 |
err = machine.SetStatus(params.StatusError, "blah", params.StatusData{"transient": true}) |
|
123 |
c.Assert(err, gc.IsNil) |
|
124 |
machines, info, err := s.provisioner.MachinesWithTransientErrors() |
|
125 |
c.Assert(err, gc.IsNil) |
|
126 |
c.Assert(machines, gc.HasLen, 1) |
|
127 |
c.Assert(machines[0].Id(), gc.Equals, "1") |
|
128 |
c.Assert(info, gc.HasLen, 1) |
|
129 |
c.Assert(info[0], gc.DeepEquals, params.StatusResult{ |
|
130 |
Id: "1", |
|
131 |
Life: "alive", |
|
132 |
Status: "error", |
|
133 |
Info: "blah", |
|
134 |
Data: params.StatusData{"transient": true}, |
|
135 |
})
|
|
136 |
}
|
|
137 |
||
138 |
func (s *provisionerSuite) TestEnsureDeadAndRemove(c *gc.C) { |
|
139 |
// Create a fresh machine to test the complete scenario.
|
|
140 |
otherMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) |
|
141 |
c.Assert(err, gc.IsNil) |
|
142 |
c.Assert(otherMachine.Life(), gc.Equals, state.Alive) |
|
143 |
||
144 |
apiMachine, err := s.provisioner.Machine(otherMachine.Tag()) |
|
145 |
c.Assert(err, gc.IsNil) |
|
146 |
||
147 |
err = apiMachine.Remove() |
|
148 |
c.Assert(err, gc.ErrorMatches, `cannot remove entity "machine-1": still alive`) |
|
149 |
err = apiMachine.EnsureDead() |
|
150 |
c.Assert(err, gc.IsNil) |
|
151 |
||
152 |
err = otherMachine.Refresh() |
|
153 |
c.Assert(err, gc.IsNil) |
|
154 |
c.Assert(otherMachine.Life(), gc.Equals, state.Dead) |
|
155 |
||
156 |
err = apiMachine.EnsureDead() |
|
157 |
c.Assert(err, gc.IsNil) |
|
158 |
err = otherMachine.Refresh() |
|
159 |
c.Assert(err, gc.IsNil) |
|
160 |
c.Assert(otherMachine.Life(), gc.Equals, state.Dead) |
|
161 |
||
162 |
err = apiMachine.Remove() |
|
163 |
c.Assert(err, gc.IsNil) |
|
164 |
err = otherMachine.Refresh() |
|
165 |
c.Assert(err, jc.Satisfies, errors.IsNotFoundError) |
|
166 |
||
167 |
err = apiMachine.EnsureDead() |
|
168 |
c.Assert(err, gc.ErrorMatches, "machine 1 not found") |
|
169 |
c.Assert(err, jc.Satisfies, params.IsCodeNotFound) |
|
170 |
||
171 |
// Now try to EnsureDead machine 0 - should fail.
|
|
172 |
apiMachine, err = s.provisioner.Machine(s.machine.Tag()) |
|
173 |
c.Assert(err, gc.IsNil) |
|
174 |
err = apiMachine.EnsureDead() |
|
175 |
c.Assert(err, gc.ErrorMatches, "machine 0 is required by the environment") |
|
176 |
}
|
|
177 |
||
178 |
func (s *provisionerSuite) TestRefreshAndLife(c *gc.C) { |
|
179 |
// Create a fresh machine to test the complete scenario.
|
|
180 |
otherMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) |
|
181 |
c.Assert(err, gc.IsNil) |
|
182 |
c.Assert(otherMachine.Life(), gc.Equals, state.Alive) |
|
183 |
||
184 |
apiMachine, err := s.provisioner.Machine(otherMachine.Tag()) |
|
185 |
c.Assert(err, gc.IsNil) |
|
186 |
c.Assert(apiMachine.Life(), gc.Equals, params.Alive) |
|
187 |
||
188 |
err = apiMachine.EnsureDead() |
|
189 |
c.Assert(err, gc.IsNil) |
|
190 |
c.Assert(apiMachine.Life(), gc.Equals, params.Alive) |
|
191 |
||
192 |
err = apiMachine.Refresh() |
|
193 |
c.Assert(err, gc.IsNil) |
|
194 |
c.Assert(apiMachine.Life(), gc.Equals, params.Dead) |
|
195 |
}
|
|
196 |
||
197 |
func (s *provisionerSuite) TestSetProvisionedAndInstanceId(c *gc.C) { |
|
198 |
// Create a fresh machine, since machine 0 is already provisioned.
|
|
199 |
notProvisionedMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) |
|
200 |
c.Assert(err, gc.IsNil) |
|
201 |
||
202 |
apiMachine, err := s.provisioner.Machine(notProvisionedMachine.Tag()) |
|
203 |
c.Assert(err, gc.IsNil) |
|
204 |
||
205 |
instanceId, err := apiMachine.InstanceId() |
|
206 |
c.Assert(err, jc.Satisfies, params.IsCodeNotProvisioned) |
|
207 |
c.Assert(err, gc.ErrorMatches, "machine 1 is not provisioned") |
|
208 |
c.Assert(instanceId, gc.Equals, instance.Id("")) |
|
209 |
||
210 |
hwChars := instance.MustParseHardware("cpu-cores=123", "mem=4G") |
|
211 |
err = apiMachine.SetProvisioned("i-will", "fake_nonce", &hwChars) |
|
212 |
c.Assert(err, gc.IsNil) |
|
213 |
||
214 |
instanceId, err = apiMachine.InstanceId() |
|
215 |
c.Assert(err, gc.IsNil) |
|
216 |
c.Assert(instanceId, gc.Equals, instance.Id("i-will")) |
|
217 |
||
218 |
// Try it again - should fail.
|
|
219 |
err = apiMachine.SetProvisioned("i-wont", "fake", nil) |
|
220 |
c.Assert(err, gc.ErrorMatches, `cannot set instance data for machine "1": already set`) |
|
221 |
||
222 |
// Now try to get machine 0's instance id.
|
|
223 |
apiMachine, err = s.provisioner.Machine(s.machine.Tag()) |
|
224 |
c.Assert(err, gc.IsNil) |
|
225 |
instanceId, err = apiMachine.InstanceId() |
|
226 |
c.Assert(err, gc.IsNil) |
|
227 |
c.Assert(instanceId, gc.Equals, instance.Id("i-manager")) |
|
228 |
}
|
|
229 |
||
230 |
func (s *provisionerSuite) TestSeries(c *gc.C) { |
|
231 |
// Create a fresh machine with different series.
|
|
232 |
foobarMachine, err := s.State.AddMachine("foobar", state.JobHostUnits) |
|
233 |
c.Assert(err, gc.IsNil) |
|
234 |
||
235 |
apiMachine, err := s.provisioner.Machine(foobarMachine.Tag()) |
|
236 |
c.Assert(err, gc.IsNil) |
|
237 |
series, err := apiMachine.Series() |
|
238 |
c.Assert(err, gc.IsNil) |
|
239 |
c.Assert(series, gc.Equals, "foobar") |
|
240 |
||
241 |
// Now try machine 0.
|
|
242 |
apiMachine, err = s.provisioner.Machine(s.machine.Tag()) |
|
243 |
c.Assert(err, gc.IsNil) |
|
244 |
series, err = apiMachine.Series() |
|
245 |
c.Assert(err, gc.IsNil) |
|
246 |
c.Assert(series, gc.Equals, "quantal") |
|
247 |
}
|
|
248 |
||
249 |
func (s *provisionerSuite) TestConstraints(c *gc.C) { |
|
250 |
// Create a fresh machine with some constraints.
|
|
251 |
template := state.MachineTemplate{ |
|
252 |
Series: "quantal", |
|
253 |
Jobs: []state.MachineJob{state.JobHostUnits}, |
|
254 |
Constraints: constraints.MustParse("cpu-cores=12", "mem=8G"), |
|
255 |
}
|
|
256 |
consMachine, err := s.State.AddOneMachine(template) |
|
257 |
c.Assert(err, gc.IsNil) |
|
258 |
||
259 |
apiMachine, err := s.provisioner.Machine(consMachine.Tag()) |
|
260 |
c.Assert(err, gc.IsNil) |
|
261 |
cons, err := apiMachine.Constraints() |
|
262 |
c.Assert(err, gc.IsNil) |
|
263 |
c.Assert(cons, gc.DeepEquals, template.Constraints) |
|
264 |
||
265 |
// Now try machine 0.
|
|
266 |
apiMachine, err = s.provisioner.Machine(s.machine.Tag()) |
|
267 |
c.Assert(err, gc.IsNil) |
|
268 |
cons, err = apiMachine.Constraints() |
|
269 |
c.Assert(err, gc.IsNil) |
|
270 |
c.Assert(cons, gc.DeepEquals, constraints.Value{}) |
|
271 |
}
|
|
272 |
||
273 |
func (s *provisionerSuite) TestWatchContainers(c *gc.C) { |
|
274 |
apiMachine, err := s.provisioner.Machine(s.machine.Tag()) |
|
275 |
c.Assert(err, gc.IsNil) |
|
276 |
||
277 |
// Add one LXC container.
|
|
278 |
template := state.MachineTemplate{ |
|
279 |
Series: "quantal", |
|
280 |
Jobs: []state.MachineJob{state.JobHostUnits}, |
|
281 |
}
|
|
282 |
container, err := s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) |
|
283 |
c.Assert(err, gc.IsNil) |
|
284 |
||
285 |
w, err := apiMachine.WatchContainers(instance.LXC) |
|
286 |
c.Assert(err, gc.IsNil) |
|
287 |
defer statetesting.AssertStop(c, w) |
|
288 |
wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) |
|
289 |
||
290 |
// Initial event.
|
|
291 |
wc.AssertChange(container.Id()) |
|
292 |
||
293 |
// Change something other than the containers and make sure it's
|
|
294 |
// not detected.
|
|
295 |
err = apiMachine.SetStatus(params.StatusStarted, "not really", nil) |
|
296 |
c.Assert(err, gc.IsNil) |
|
297 |
wc.AssertNoChange() |
|
298 |
||
299 |
// Add a KVM container and make sure it's not detected.
|
|
300 |
container, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.KVM) |
|
301 |
c.Assert(err, gc.IsNil) |
|
302 |
wc.AssertNoChange() |
|
303 |
||
304 |
// Add another LXC container and make sure it's detected.
|
|
305 |
container, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) |
|
306 |
c.Assert(err, gc.IsNil) |
|
307 |
wc.AssertChange(container.Id()) |
|
308 |
||
309 |
statetesting.AssertStop(c, w) |
|
310 |
wc.AssertClosed() |
|
311 |
}
|
|
312 |
||
313 |
func (s *provisionerSuite) TestWatchContainersAcceptsSupportedContainers(c *gc.C) { |
|
314 |
apiMachine, err := s.provisioner.Machine(s.machine.Tag()) |
|
315 |
c.Assert(err, gc.IsNil) |
|
316 |
||
317 |
for _, ctype := range instance.ContainerTypes { |
|
318 |
w, err := apiMachine.WatchContainers(ctype) |
|
319 |
c.Assert(w, gc.NotNil) |
|
320 |
c.Assert(err, gc.IsNil) |
|
321 |
}
|
|
322 |
}
|
|
323 |
||
324 |
func (s *provisionerSuite) TestWatchContainersErrors(c *gc.C) { |
|
325 |
apiMachine, err := s.provisioner.Machine(s.machine.Tag()) |
|
326 |
c.Assert(err, gc.IsNil) |
|
327 |
||
328 |
_, err = apiMachine.WatchContainers(instance.NONE) |
|
329 |
c.Assert(err, gc.ErrorMatches, `unsupported container type "none"`) |
|
330 |
||
331 |
_, err = apiMachine.WatchContainers("") |
|
332 |
c.Assert(err, gc.ErrorMatches, "container type must be specified") |
|
333 |
}
|
|
334 |
||
335 |
func (s *provisionerSuite) TestWatchEnvironMachines(c *gc.C) { |
|
336 |
w, err := s.provisioner.WatchEnvironMachines() |
|
337 |
c.Assert(err, gc.IsNil) |
|
338 |
defer statetesting.AssertStop(c, w) |
|
339 |
wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) |
|
340 |
||
341 |
// Initial event.
|
|
342 |
wc.AssertChange(s.machine.Id()) |
|
343 |
||
344 |
// Add another 2 machines make sure they are detected.
|
|
345 |
otherMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) |
|
346 |
c.Assert(err, gc.IsNil) |
|
347 |
otherMachine, err = s.State.AddMachine("quantal", state.JobHostUnits) |
|
348 |
c.Assert(err, gc.IsNil) |
|
349 |
wc.AssertChange("1", "2") |
|
350 |
||
351 |
// Change the lifecycle of last machine.
|
|
352 |
err = otherMachine.EnsureDead() |
|
353 |
c.Assert(err, gc.IsNil) |
|
354 |
wc.AssertChange("2") |
|
355 |
||
356 |
// Add a container and make sure it's not detected.
|
|
357 |
template := state.MachineTemplate{ |
|
358 |
Series: "quantal", |
|
359 |
Jobs: []state.MachineJob{state.JobHostUnits}, |
|
360 |
}
|
|
361 |
_, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) |
|
362 |
c.Assert(err, gc.IsNil) |
|
363 |
wc.AssertNoChange() |
|
364 |
||
365 |
statetesting.AssertStop(c, w) |
|
366 |
wc.AssertClosed() |
|
367 |
}
|
|
368 |
||
369 |
func (s *provisionerSuite) TestStateAddresses(c *gc.C) { |
|
370 |
err := s.machine.SetAddresses([]instance.Address{ |
|
371 |
instance.NewAddress("0.1.2.3"), |
|
372 |
})
|
|
373 |
c.Assert(err, gc.IsNil) |
|
374 |
||
375 |
stateAddresses, err := s.State.Addresses() |
|
376 |
c.Assert(err, gc.IsNil) |
|
377 |
||
378 |
addresses, err := s.provisioner.StateAddresses() |
|
379 |
c.Assert(err, gc.IsNil) |
|
380 |
c.Assert(addresses, gc.DeepEquals, stateAddresses) |
|
381 |
}
|
|
382 |
||
383 |
func (s *provisionerSuite) TestContainerConfig(c *gc.C) { |
|
384 |
result, err := s.provisioner.ContainerConfig() |
|
385 |
c.Assert(err, gc.IsNil) |
|
386 |
c.Assert(result.ProviderType, gc.Equals, "dummy") |
|
387 |
c.Assert(result.AuthorizedKeys, gc.Equals, coretesting.FakeAuthKeys) |
|
388 |
c.Assert(result.SSLHostnameVerification, jc.IsTrue) |
|
389 |
}
|
|
390 |
||
391 |
func (s *provisionerSuite) TestToolsWrongMachine(c *gc.C) { |
|
392 |
tools, err := s.provisioner.Tools("42") |
|
393 |
c.Assert(err, gc.ErrorMatches, "permission denied") |
|
394 |
c.Assert(err, jc.Satisfies, params.IsCodeUnauthorized) |
|
395 |
c.Assert(tools, gc.IsNil) |
|
396 |
}
|
|
397 |
||
398 |
func (s *provisionerSuite) TestTools(c *gc.C) { |
|
399 |
cur := version.Current |
|
400 |
curTools := &tools.Tools{Version: cur, URL: ""} |
|
401 |
curTools.Version.Minor++ |
|
402 |
s.machine.SetAgentVersion(cur) |
|
403 |
// Provisioner.Tools returns the *desired* set of tools, not the
|
|
404 |
// currently running set. We want to be upgraded to cur.Version
|
|
405 |
stateTools, err := s.provisioner.Tools(s.machine.Tag()) |
|
406 |
c.Assert(err, gc.IsNil) |
|
407 |
c.Assert(stateTools.Version, gc.Equals, cur) |
|
408 |
c.Assert(stateTools.URL, gc.Not(gc.Equals), "") |
|
409 |
}
|
|
410 |
||
411 |
func (s *provisionerSuite) TestSetSupportedContainers(c *gc.C) { |
|
412 |
apiMachine, err := s.provisioner.Machine(s.machine.Tag()) |
|
413 |
c.Assert(err, gc.IsNil) |
|
414 |
err = apiMachine.SetSupportedContainers(instance.LXC, instance.KVM) |
|
415 |
c.Assert(err, gc.IsNil) |
|
416 |
||
417 |
err = s.machine.Refresh() |
|
418 |
c.Assert(err, gc.IsNil) |
|
419 |
containers, ok := s.machine.SupportedContainers() |
|
420 |
c.Assert(ok, jc.IsTrue) |
|
421 |
c.Assert(containers, gc.DeepEquals, []instance.ContainerType{instance.LXC, instance.KVM}) |
|
422 |
}
|
|
423 |
||
424 |
func (s *provisionerSuite) TestSupportsNoContainers(c *gc.C) { |
|
425 |
apiMachine, err := s.provisioner.Machine(s.machine.Tag()) |
|
426 |
c.Assert(err, gc.IsNil) |
|
427 |
err = apiMachine.SupportsNoContainers() |
|
428 |
c.Assert(err, gc.IsNil) |
|
429 |
||
430 |
err = s.machine.Refresh() |
|
431 |
c.Assert(err, gc.IsNil) |
|
432 |
containers, ok := s.machine.SupportedContainers() |
|
433 |
c.Assert(ok, jc.IsTrue) |
|
434 |
c.Assert(containers, gc.DeepEquals, []instance.ContainerType{}) |
|
435 |
}
|