Merge lp:~gmb/maas/use-node.start-instead-of-start_nodes-bug-1330765 into lp:~maas-committers/maas/trunk
- use-node.start-instead-of-start_nodes-bug-1330765
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Graham Binns | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 3277 | ||||
Proposed branch: | lp:~gmb/maas/use-node.start-instead-of-start_nodes-bug-1330765 | ||||
Merge into: | lp:~maas-committers/maas/trunk | ||||
Diff against target: |
497 lines (+106/-121) 5 files modified
src/maasserver/api/nodes.py (+8/-9) src/maasserver/models/node.py (+10/-8) src/maasserver/models/tests/test_node.py (+67/-82) src/maasserver/node_action.py (+1/-1) src/maasserver/tests/test_node_action.py (+20/-21) |
||||
To merge this branch: | bzr merge lp:~gmb/maas/use-node.start-instead-of-start_nodes-bug-1330765 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Julian Edwards (community) | Approve | ||
Review via email: mp+238758@code.launchpad.net |
Commit message
Convert Node.objects.
I've accounted for all the callsites except those in the tests for start_nodes, which I'll remove in a separate branch.
Description of the change
Graham Binns (gmb) wrote : | # |
On 21 October 2014 08:45, Julian Edwards <email address hidden> wrote:
> Review: Approve
>
> Smashing!
>
> Diff comments:
>
>> === modified file 'src/maasserver
>> --- src/maasserver/
>> +++ src/maasserver/
>> @@ -285,12 +285,14 @@
>> user_data = request.
>> series = request.
>> license_key = request.
>> +
>> + node = Node.objects.
>> + system_
>> + perm=NODE_
>> +
>> if user_data is not None:
>> user_data = b64decode(
>> if series is not None or license_key is not None:
>> - node = Node.objects.
>> - system_
>> - perm=NODE_
>> Form = get_node_
>> form = Form(instance=node)
>> if series is not None:
>> @@ -301,19 +303,16 @@
>> form.save()
>> else:
>> raise ValidationError
>> +
>> try:
>> - nodes = Node.objects.
>> - [system_id], request.user, user_data=
>> + node.start(
>> except StaticIPAddress
>> # The API response should contain error text with the
>> # system_id in it, as that is the primary API key to a node.
>> raise StaticIPAddress
>> "%s: Unable to allocate static IP due to address"
>> " exhaustion." % system_id)
>> - if len(nodes) == 0:
>> - raise PermissionDenied(
>> - "You are not allowed to start up this node.")
>> - return nodes[0]
>> + return node
>>
>> @operation(
>> def release(self, request, system_id):
>>
>> === modified file 'src/maasserver
>> --- src/maasserver/
>> +++ src/maasserver/
>> @@ -969,11 +969,7 @@
>> self.save()
>> transaction.
>> try:
>> - # We don't check for which nodes we've started here, because
>> - # it's possible we can't start the node - its power type may not
>> - # allow us to do that.
>> - Node.objects.
>> - [self.system_id], user, user_data=
>> + self.start(user, user_data=
>> except Exception as ex:
>> maaslog.error(
>> "%s: Unable to start node: %s",
>> @@ -1287,8 +1283,7 @@
>> self.save()
>> transaction.
>> try:
>> - Node.objects.
>> - [self.system_id], user, user_data=
>> + self.start(user, user_data=
>> except E...
Preview Diff
1 | === modified file 'src/maasserver/api/nodes.py' |
2 | --- src/maasserver/api/nodes.py 2014-10-17 16:54:22 +0000 |
3 | +++ src/maasserver/api/nodes.py 2014-10-21 08:28:19 +0000 |
4 | @@ -285,12 +285,14 @@ |
5 | user_data = request.POST.get('user_data', None) |
6 | series = request.POST.get('distro_series', None) |
7 | license_key = request.POST.get('license_key', None) |
8 | + |
9 | + node = Node.objects.get_node_or_404( |
10 | + system_id=system_id, user=request.user, |
11 | + perm=NODE_PERMISSION.EDIT) |
12 | + |
13 | if user_data is not None: |
14 | user_data = b64decode(user_data) |
15 | if series is not None or license_key is not None: |
16 | - node = Node.objects.get_node_or_404( |
17 | - system_id=system_id, user=request.user, |
18 | - perm=NODE_PERMISSION.EDIT) |
19 | Form = get_node_edit_form(request.user) |
20 | form = Form(instance=node) |
21 | if series is not None: |
22 | @@ -301,19 +303,16 @@ |
23 | form.save() |
24 | else: |
25 | raise ValidationError(form.errors) |
26 | + |
27 | try: |
28 | - nodes = Node.objects.start_nodes( |
29 | - [system_id], request.user, user_data=user_data) |
30 | + node.start(request.user, user_data=user_data) |
31 | except StaticIPAddressExhaustion: |
32 | # The API response should contain error text with the |
33 | # system_id in it, as that is the primary API key to a node. |
34 | raise StaticIPAddressExhaustion( |
35 | "%s: Unable to allocate static IP due to address" |
36 | " exhaustion." % system_id) |
37 | - if len(nodes) == 0: |
38 | - raise PermissionDenied( |
39 | - "You are not allowed to start up this node.") |
40 | - return nodes[0] |
41 | + return node |
42 | |
43 | @operation(idempotent=False) |
44 | def release(self, request, system_id): |
45 | |
46 | === modified file 'src/maasserver/models/node.py' |
47 | --- src/maasserver/models/node.py 2014-10-21 00:02:35 +0000 |
48 | +++ src/maasserver/models/node.py 2014-10-21 08:28:19 +0000 |
49 | @@ -969,11 +969,7 @@ |
50 | self.save() |
51 | transaction.commit() |
52 | try: |
53 | - # We don't check for which nodes we've started here, because |
54 | - # it's possible we can't start the node - its power type may not |
55 | - # allow us to do that. |
56 | - Node.objects.start_nodes( |
57 | - [self.system_id], user, user_data=commissioning_user_data) |
58 | + self.start(user, user_data=commissioning_user_data) |
59 | except Exception as ex: |
60 | maaslog.error( |
61 | "%s: Unable to start node: %s", |
62 | @@ -1287,8 +1283,7 @@ |
63 | self.save() |
64 | transaction.commit() |
65 | try: |
66 | - Node.objects.start_nodes( |
67 | - [self.system_id], user, user_data=disk_erase_user_data) |
68 | + self.start(user, user_data=disk_erase_user_data) |
69 | except Exception as ex: |
70 | maaslog.error( |
71 | "%s: Unable to start node: %s", |
72 | @@ -1583,6 +1578,13 @@ |
73 | from metadataserver.models import NodeUserData |
74 | from maasserver.dns.config import change_dns_zones |
75 | |
76 | + if not by_user.has_perm(NODE_PERMISSION.EDIT, self): |
77 | + # You can't stop a node you don't own unless you're an |
78 | + # admin, so we return early. This is consistent with the |
79 | + # behaviour of NodeManager.stop_nodes(); it may be better to |
80 | + # raise an error here. |
81 | + return |
82 | + |
83 | # Record the user data for the node. Note that we do this |
84 | # whether or not we can actually send power commands to the |
85 | # node; the user may choose to start it manually. |
86 | @@ -1634,7 +1636,7 @@ |
87 | :raises MultipleFailures: When there are failures originating |
88 | from the RPC power action. |
89 | """ |
90 | - if by_user != self.owner and not by_user.is_superuser: |
91 | + if not by_user.has_perm(NODE_PERMISSION.EDIT, self): |
92 | # You can't stop a node you don't own unless you're an |
93 | # admin, so we return early. This is consistent with the |
94 | # behaviour of NodeManager.stop_nodes(); it may be better to |
95 | |
96 | === modified file 'src/maasserver/models/tests/test_node.py' |
97 | --- src/maasserver/models/tests/test_node.py 2014-10-21 01:15:29 +0000 |
98 | +++ src/maasserver/models/tests/test_node.py 2014-10-21 08:28:19 +0000 |
99 | @@ -740,13 +740,13 @@ |
100 | owner = factory.make_User() |
101 | node = factory.make_Node( |
102 | status=NODE_STATUS.ALLOCATED, owner=owner, agent_name=agent_name) |
103 | - start_nodes = self.patch(Node.objects, "start_nodes") |
104 | + node_start = self.patch(node, 'start') |
105 | node.start_disk_erasing(owner) |
106 | - self.assertEqual( |
107 | - (owner, NODE_STATUS.DISK_ERASING, agent_name), |
108 | - (node.owner, node.status, node.agent_name)) |
109 | - self.assertThat(start_nodes, MockCalledOnceWith( |
110 | - [node.system_id], owner, user_data=ANY)) |
111 | + self.expectThat(node.owner, Equals(owner)) |
112 | + self.expectThat(node.status, Equals(NODE_STATUS.DISK_ERASING)) |
113 | + self.expectThat(node.agent_name, Equals(agent_name)) |
114 | + self.assertThat( |
115 | + node_start, MockCalledOnceWith(owner, user_data=ANY)) |
116 | |
117 | def test_abort_disk_erasing_changes_state_and_stops_node(self): |
118 | agent_name = factory.make_name('agent-name') |
119 | @@ -769,53 +769,35 @@ |
120 | # Failures encountered in one call to start_disk_erasing() won't |
121 | # affect subsequent calls. |
122 | admin = factory.make_admin() |
123 | - nodes = [ |
124 | - factory.make_Node( |
125 | - status=NODE_STATUS.ALLOCATED, power_type="virsh") |
126 | - for _ in range(3) |
127 | - ] |
128 | + node = factory.make_Node(status=NODE_STATUS.ALLOCATED) |
129 | generate_user_data = self.patch(disk_erasing, 'generate_user_data') |
130 | - start_nodes = self.patch(Node.objects, 'start_nodes') |
131 | - start_nodes.side_effect = [ |
132 | - None, |
133 | - MultipleFailures( |
134 | - Failure(NoConnectionsAvailable())), |
135 | - None, |
136 | - ] |
137 | + node_start = self.patch(node, 'start') |
138 | + node_start.side_effect = MultipleFailures( |
139 | + Failure(NoConnectionsAvailable())), |
140 | |
141 | with transaction.atomic(): |
142 | - for node in nodes: |
143 | - try: |
144 | - node.start_disk_erasing(admin) |
145 | - except RPC_EXCEPTIONS: |
146 | - # Suppress all the expected errors coming out of |
147 | - # start_disk_erasing() because they're tested |
148 | - # eleswhere. |
149 | - pass |
150 | + try: |
151 | + node.start_disk_erasing(admin) |
152 | + except RPC_EXCEPTIONS: |
153 | + # Suppress all the expected errors coming out of |
154 | + # start_disk_erasing() because they're tested |
155 | + # eleswhere. |
156 | + pass |
157 | |
158 | - expected_calls = ( |
159 | - call( |
160 | - [node.system_id], admin, |
161 | - user_data=generate_user_data.return_value) |
162 | - for node in nodes) |
163 | self.assertThat( |
164 | - start_nodes, MockCallsMatch(*expected_calls)) |
165 | - self.assertEqual( |
166 | - [ |
167 | - NODE_STATUS.DISK_ERASING, |
168 | - NODE_STATUS.FAILED_DISK_ERASING, |
169 | - NODE_STATUS.DISK_ERASING, |
170 | - ], |
171 | - [node.status for node in nodes]) |
172 | + node_start, MockCalledOnceWith( |
173 | + admin, user_data=generate_user_data.return_value)) |
174 | + self.assertEqual(NODE_STATUS.FAILED_DISK_ERASING, node.status) |
175 | |
176 | def test_start_disk_erasing_logs_and_raises_errors_in_starting(self): |
177 | admin = factory.make_admin() |
178 | node = factory.make_Node(status=NODE_STATUS.ALLOCATED) |
179 | maaslog = self.patch(node_module, 'maaslog') |
180 | - exception = NoConnectionsAvailable(factory.make_name()) |
181 | - self.patch(Node.objects, 'start_nodes').side_effect = exception |
182 | + exception_type = factory.make_exception_type() |
183 | + exception = exception_type(factory.make_name()) |
184 | + self.patch(node, 'start').side_effect = exception |
185 | self.assertRaises( |
186 | - NoConnectionsAvailable, node.start_disk_erasing, admin) |
187 | + exception_type, node.start_disk_erasing, admin) |
188 | self.assertEqual(NODE_STATUS.FAILED_DISK_ERASING, node.status) |
189 | self.assertThat( |
190 | maaslog.error, MockCalledOnceWith( |
191 | @@ -1337,8 +1319,7 @@ |
192 | def test_start_commissioning_changes_status_and_starts_node(self): |
193 | node = factory.make_Node( |
194 | status=NODE_STATUS.NEW, power_type='ether_wake') |
195 | - start_nodes = self.patch(Node.objects, "start_nodes") |
196 | - start_nodes.return_value = [node] |
197 | + node_start = self.patch(node, 'start') |
198 | factory.make_MACAddress(node=node) |
199 | admin = factory.make_admin() |
200 | node.start_commissioning(admin) |
201 | @@ -1347,21 +1328,20 @@ |
202 | 'status': NODE_STATUS.COMMISSIONING, |
203 | } |
204 | self.assertAttributes(node, expected_attrs) |
205 | - self.assertThat(start_nodes, MockCalledOnceWith( |
206 | - [node.system_id], admin, user_data=ANY)) |
207 | + self.assertThat(node_start, MockCalledOnceWith( |
208 | + admin, user_data=ANY)) |
209 | |
210 | def test_start_commissioning_sets_user_data(self): |
211 | - start_nodes = self.patch(Node.objects, "start_nodes") |
212 | - |
213 | node = factory.make_Node(status=NODE_STATUS.NEW) |
214 | + node_start = self.patch(node, 'start') |
215 | user_data = factory.make_string().encode('ascii') |
216 | generate_user_data = self.patch( |
217 | commissioning, 'generate_user_data') |
218 | generate_user_data.return_value = user_data |
219 | admin = factory.make_admin() |
220 | node.start_commissioning(admin) |
221 | - self.assertThat(start_nodes, MockCalledOnceWith( |
222 | - [node.system_id], admin, user_data=user_data)) |
223 | + self.assertThat(node_start, MockCalledOnceWith( |
224 | + admin, user_data=user_data)) |
225 | |
226 | def test_start_commissioning_clears_node_commissioning_results(self): |
227 | node = factory.make_Node(status=NODE_STATUS.NEW) |
228 | @@ -1391,49 +1371,32 @@ |
229 | # start the node, it will revert the node to its previous |
230 | # status. |
231 | admin = factory.make_admin() |
232 | - nodes = [ |
233 | - factory.make_Node(status=NODE_STATUS.NEW, power_type="ether_wake") |
234 | - for _ in range(3) |
235 | - ] |
236 | + node = factory.make_Node(status=NODE_STATUS.NEW) |
237 | generate_user_data = self.patch(commissioning, 'generate_user_data') |
238 | - start_nodes = self.patch(Node.objects, 'start_nodes') |
239 | - start_nodes.side_effect = [ |
240 | - None, |
241 | - MultipleFailures( |
242 | - Failure(NoConnectionsAvailable())), |
243 | - None, |
244 | - ] |
245 | + node_start = self.patch(node, 'start') |
246 | + node_start.side_effect = MultipleFailures( |
247 | + Failure(NoConnectionsAvailable())) |
248 | |
249 | with transaction.atomic(): |
250 | - for node in nodes: |
251 | - try: |
252 | - node.start_commissioning(admin) |
253 | - except RPC_EXCEPTIONS: |
254 | - # Suppress all expected errors; we test for them |
255 | - # elsewhere. |
256 | - pass |
257 | + try: |
258 | + node.start_commissioning(admin) |
259 | + except RPC_EXCEPTIONS: |
260 | + # Suppress all expected errors; we test for them |
261 | + # elsewhere. |
262 | + pass |
263 | |
264 | - expected_calls = ( |
265 | - call( |
266 | - [node.system_id], admin, |
267 | - user_data=generate_user_data.return_value) |
268 | - for node in nodes) |
269 | self.assertThat( |
270 | - start_nodes, MockCallsMatch(*expected_calls)) |
271 | - self.assertEqual( |
272 | - [ |
273 | - NODE_STATUS.COMMISSIONING, |
274 | - NODE_STATUS.NEW, |
275 | - NODE_STATUS.COMMISSIONING |
276 | - ], |
277 | - [node.status for node in nodes]) |
278 | + node_start, |
279 | + MockCalledOnceWith( |
280 | + admin, user_data=generate_user_data.return_value)) |
281 | + self.assertEqual(NODE_STATUS.NEW, node.status) |
282 | |
283 | def test_start_commissioning_logs_and_raises_errors_in_starting(self): |
284 | admin = factory.make_admin() |
285 | node = factory.make_Node(status=NODE_STATUS.NEW) |
286 | maaslog = self.patch(node_module, 'maaslog') |
287 | exception = NoConnectionsAvailable(factory.make_name()) |
288 | - self.patch(Node.objects, 'start_nodes').side_effect = exception |
289 | + self.patch(node, 'start').side_effect = exception |
290 | self.assertRaises( |
291 | NoConnectionsAvailable, node.start_commissioning, admin) |
292 | self.assertEqual(NODE_STATUS.NEW, node.status) |
293 | @@ -2833,6 +2796,28 @@ |
294 | node.start(user) |
295 | self.assertThat(power_on_nodes, MockNotCalled()) |
296 | |
297 | + def test__does_not_start_nodes_the_user_cannot_edit(self): |
298 | + power_on_nodes = self.patch_autospec(node_module, "power_on_nodes") |
299 | + owner = factory.make_User() |
300 | + node = self.make_acquired_node_with_mac(owner) |
301 | + |
302 | + user = factory.make_User() |
303 | + node.start(user) |
304 | + self.assertThat(power_on_nodes, MockNotCalled()) |
305 | + |
306 | + def test__allows_admin_to_start_any_node(self): |
307 | + wait_for_power_commands = self.patch_autospec( |
308 | + node_module, 'wait_for_power_commands') |
309 | + power_on_nodes = self.patch_autospec(node_module, "power_on_nodes") |
310 | + owner = factory.make_User() |
311 | + node = self.make_acquired_node_with_mac(owner) |
312 | + |
313 | + admin = factory.make_admin() |
314 | + node.start(admin) |
315 | + |
316 | + self.expectThat(power_on_nodes, MockCalledOnceWith(ANY)) |
317 | + self.expectThat(wait_for_power_commands, MockCalledOnceWith(ANY)) |
318 | + |
319 | |
320 | class TestNode_Stop(MAASServerTestCase): |
321 | """Tests for Node.stop().""" |
322 | |
323 | === modified file 'src/maasserver/node_action.py' |
324 | --- src/maasserver/node_action.py 2014-10-17 16:54:22 +0000 |
325 | +++ src/maasserver/node_action.py 2014-10-21 08:28:19 +0000 |
326 | @@ -345,7 +345,7 @@ |
327 | self.node.acquire(self.user, token=None) |
328 | |
329 | try: |
330 | - Node.objects.start_nodes([self.node.system_id], self.user) |
331 | + self.node.start(self.user) |
332 | except StaticIPAddressExhaustion: |
333 | raise NodeActionError( |
334 | "%s: Failed to start, static IP addresses are exhausted." |
335 | |
336 | === modified file 'src/maasserver/tests/test_node_action.py' |
337 | --- src/maasserver/tests/test_node_action.py 2014-10-20 20:40:50 +0000 |
338 | +++ src/maasserver/tests/test_node_action.py 2014-10-21 08:28:19 +0000 |
339 | @@ -230,17 +230,16 @@ |
340 | ) |
341 | |
342 | def test_Commission_starts_commissioning(self): |
343 | - start_nodes = self.patch(Node.objects, "start_nodes") |
344 | node = factory.make_Node( |
345 | mac=True, status=self.status, |
346 | power_type='ether_wake') |
347 | + node_start = self.patch(node, 'start') |
348 | admin = factory.make_admin() |
349 | action = Commission(node, admin) |
350 | action.execute() |
351 | self.assertEqual(NODE_STATUS.COMMISSIONING, node.status) |
352 | self.assertThat( |
353 | - start_nodes, MockCalledOnceWith( |
354 | - [node.system_id], admin, user_data=ANY)) |
355 | + node_start, MockCalledOnceWith(admin, user_data=ANY)) |
356 | |
357 | |
358 | class TestAbortCommissioningNodeAction(MAASServerTestCase): |
359 | @@ -314,14 +313,14 @@ |
360 | self.assertIn("SSH key", inhibition) |
361 | |
362 | def test_StartNode_starts_node(self): |
363 | - start_nodes = self.patch(Node.objects, "start_nodes") |
364 | user = factory.make_User() |
365 | node = factory.make_Node( |
366 | mac=True, status=NODE_STATUS.ALLOCATED, |
367 | power_type='ether_wake', owner=user) |
368 | + node_start = self.patch(node, 'start') |
369 | StartNode(node, user).execute() |
370 | self.assertThat( |
371 | - start_nodes, MockCalledOnceWith([node.system_id], user)) |
372 | + node_start, MockCalledOnceWith(user)) |
373 | |
374 | def test_StartNode_returns_error_when_no_more_static_IPs(self): |
375 | user = factory.make_User() |
376 | @@ -351,9 +350,9 @@ |
377 | self.assertFalse(StartNode(node, user).is_permitted()) |
378 | |
379 | def test_StartNode_allocates_node_if_node_not_already_allocated(self): |
380 | - self.patch(Node.objects, "start_nodes") |
381 | user = factory.make_User() |
382 | node = factory.make_Node(status=NODE_STATUS.READY) |
383 | + self.patch(node, 'start') |
384 | action = StartNode(node, user) |
385 | action.execute() |
386 | |
387 | @@ -361,16 +360,16 @@ |
388 | self.assertEqual(NODE_STATUS.ALLOCATED, node.status) |
389 | |
390 | def test_StartNode_label_shows_allocate_if_unallocated(self): |
391 | - self.patch(Node.objects, "start_nodes") |
392 | user = factory.make_User() |
393 | node = factory.make_Node(status=NODE_STATUS.READY) |
394 | + self.patch(node, 'start') |
395 | action = StartNode(node, user) |
396 | self.assertEqual("Acquire and start node", action.display) |
397 | |
398 | def test_StartNode_label_hides_allocate_if_allocated(self): |
399 | - self.patch(Node.objects, "start_nodes") |
400 | user = factory.make_User() |
401 | node = factory.make_Node(status=NODE_STATUS.READY) |
402 | + self.patch(node, 'start') |
403 | node.acquire(user) |
404 | action = StartNode(node, user) |
405 | self.assertEqual("Start node", action.display) |
406 | @@ -384,17 +383,17 @@ |
407 | self.assertEqual("Start node", action.display) |
408 | |
409 | def test_StartNode_does_not_reallocate_when_run_by_non_owner(self): |
410 | - self.patch(Node.objects, "start_nodes") |
411 | user = factory.make_User() |
412 | admin = factory.make_admin() |
413 | node = factory.make_Node(status=NODE_STATUS.READY) |
414 | + self.patch(node, 'start') |
415 | node.acquire(user) |
416 | action = StartNode(node, admin) |
417 | |
418 | # This action.execute() will not fail because the non-owner is |
419 | # an admin, so they can start the node. Even if they weren't an |
420 | - # admin, the node still wouldn't start; |
421 | - # NodeManager.start_nodes() would ignore it. |
422 | + # admin, the node still wouldn't start; Node.start() would |
423 | + # ignore it. |
424 | action.execute() |
425 | self.assertEqual(user, node.owner) |
426 | self.assertEqual(NODE_STATUS.ALLOCATED, node.status) |
427 | @@ -571,9 +570,9 @@ |
428 | exception = self.exception_class(factory.make_name("exception")) |
429 | return exception |
430 | |
431 | - def patch_rpc_methods(self): |
432 | + def patch_rpc_methods(self, node): |
433 | exception = self.make_exception() |
434 | - self.patch(Node.objects, "start_nodes").side_effect = ( |
435 | + self.patch(node, 'start').side_effect = ( |
436 | exception) |
437 | self.patch(Node.objects, "stop_nodes").side_effect = ( |
438 | exception) |
439 | @@ -586,17 +585,17 @@ |
440 | |
441 | def test_Commission_handles_rpc_errors(self): |
442 | action = self.make_action(Commission, NODE_STATUS.READY) |
443 | - self.patch_rpc_methods() |
444 | + self.patch_rpc_methods(action.node) |
445 | exception = self.assertRaises(NodeActionError, action.execute) |
446 | self.assertEqual( |
447 | get_error_message_for_exception( |
448 | - Node.objects.start_nodes.side_effect), |
449 | + action.node.start.side_effect), |
450 | unicode(exception)) |
451 | |
452 | def test_AbortCommissioning_handles_rpc_errors(self): |
453 | action = self.make_action( |
454 | AbortCommissioning, NODE_STATUS.COMMISSIONING) |
455 | - self.patch_rpc_methods() |
456 | + self.patch_rpc_methods(action.node) |
457 | exception = self.assertRaises(NodeActionError, action.execute) |
458 | self.assertEqual( |
459 | get_error_message_for_exception( |
460 | @@ -606,7 +605,7 @@ |
461 | def test_AbortOperation_handles_rpc_errors(self): |
462 | action = self.make_action( |
463 | AbortOperation, NODE_STATUS.DISK_ERASING) |
464 | - self.patch_rpc_methods() |
465 | + self.patch_rpc_methods(action.node) |
466 | exception = self.assertRaises(NodeActionError, action.execute) |
467 | self.assertEqual( |
468 | get_error_message_for_exception( |
469 | @@ -615,16 +614,16 @@ |
470 | |
471 | def test_StartNode_handles_rpc_errors(self): |
472 | action = self.make_action(StartNode, NODE_STATUS.READY) |
473 | - self.patch_rpc_methods() |
474 | + self.patch_rpc_methods(action.node) |
475 | exception = self.assertRaises(NodeActionError, action.execute) |
476 | self.assertEqual( |
477 | get_error_message_for_exception( |
478 | - Node.objects.start_nodes.side_effect), |
479 | + action.node.start.side_effect), |
480 | unicode(exception)) |
481 | |
482 | def test_StopNode_handles_rpc_errors(self): |
483 | action = self.make_action(StopNode, NODE_STATUS.DEPLOYED) |
484 | - self.patch_rpc_methods() |
485 | + self.patch_rpc_methods(action.node) |
486 | exception = self.assertRaises(NodeActionError, action.execute) |
487 | self.assertEqual( |
488 | get_error_message_for_exception( |
489 | @@ -633,7 +632,7 @@ |
490 | |
491 | def test_ReleaseNode_handles_rpc_errors(self): |
492 | action = self.make_action(ReleaseNode, NODE_STATUS.ALLOCATED) |
493 | - self.patch_rpc_methods() |
494 | + self.patch_rpc_methods(action.node) |
495 | exception = self.assertRaises(NodeActionError, action.execute) |
496 | self.assertEqual( |
497 | get_error_message_for_exception( |
Smashing!