Merge ~newell-jensen/maas:lp1548402 into maas:master
- Git
- lp:~newell-jensen/maas
- lp1548402
- Merge into master
Proposed by
Newell Jensen
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Newell Jensen | ||||
Approved revision: | 9a16d511e3f3ed9b56fd2890e85fceed1c711b61 | ||||
Merge reported by: | MAAS Lander | ||||
Merged at revision: | not available | ||||
Proposed branch: | ~newell-jensen/maas:lp1548402 | ||||
Merge into: | maas:master | ||||
Diff against target: |
352 lines (+108/-11) 5 files modified
src/maasserver/api/machines.py (+7/-0) src/maasserver/api/tests/test_machine.py (+34/-1) src/maasserver/node_action.py (+7/-0) src/maasserver/tests/test_node_action.py (+58/-10) src/maasserver/websockets/handlers/tests/test_machine.py (+2/-0) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andres Rodriguez (community) | Approve | ||
Review via email: mp+327766@code.launchpad.net |
Commit message
LP: #1548402 - Handle errors in preseeds
Ensure that MAAS prevents starting the deployment of a machine if the preseeds fail to render.
Description of the change
To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote : | # |
LANDING
-b lp1548402 lp:~newell-jensen/maas into -b master lp:~maas-committers/maas
STATUS: FAILED BUILD
LOG: http://
~newell-jensen/maas:lp1548402
updated
- 9a16d51... by Newell Jensen
-
Add fix for failing test in websocket handler machine_test
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/src/maasserver/api/machines.py b/src/maasserver/api/machines.py | |||
2 | index 58d9dfd..dfca107 100644 | |||
3 | --- a/src/maasserver/api/machines.py | |||
4 | +++ b/src/maasserver/api/machines.py | |||
5 | @@ -443,6 +443,13 @@ class MachineHandler(NodeHandler, OwnerDataMixin, PowerMixin): | |||
6 | 443 | form.save() | 443 | form.save() |
7 | 444 | else: | 444 | else: |
8 | 445 | raise MAASAPIValidationError(form.errors) | 445 | raise MAASAPIValidationError(form.errors) |
9 | 446 | # Check that the curtin preseeds renders correctly. | ||
10 | 447 | try: | ||
11 | 448 | get_curtin_merged_config(machine) | ||
12 | 449 | except Exception as e: | ||
13 | 450 | raise MAASAPIBadRequest( | ||
14 | 451 | "Failed to render preseed: %s" % e) | ||
15 | 452 | |||
16 | 446 | return self.power_on(request, system_id) | 453 | return self.power_on(request, system_id) |
17 | 447 | 454 | ||
18 | 448 | @operation(idempotent=False) | 455 | @operation(idempotent=False) |
19 | diff --git a/src/maasserver/api/tests/test_machine.py b/src/maasserver/api/tests/test_machine.py | |||
20 | index 4f9fa5d..9d4abf0 100644 | |||
21 | --- a/src/maasserver/api/tests/test_machine.py | |||
22 | +++ b/src/maasserver/api/tests/test_machine.py | |||
23 | @@ -1,4 +1,4 @@ | |||
25 | 1 | # Copyright 2015-2016 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2015-2017 Canonical Ltd. This software is licensed under the |
26 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
27 | 3 | 3 | ||
28 | 4 | """Tests for the Machine API.""" | 4 | """Tests for the Machine API.""" |
29 | @@ -326,6 +326,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
30 | 326 | 326 | ||
31 | 327 | def test_POST_deploy_sets_osystem_and_distro_series(self): | 327 | def test_POST_deploy_sets_osystem_and_distro_series(self): |
32 | 328 | self.patch(node_module.Node, "_start") | 328 | self.patch(node_module.Node, "_start") |
33 | 329 | self.patch(machines_module, "get_curtin_merged_config") | ||
34 | 329 | machine = factory.make_Node( | 330 | machine = factory.make_Node( |
35 | 330 | owner=self.user, interface=True, | 331 | owner=self.user, interface=True, |
36 | 331 | power_type='manual', | 332 | power_type='manual', |
37 | @@ -367,6 +368,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
38 | 367 | 368 | ||
39 | 368 | def test_POST_deploy_sets_license_key(self): | 369 | def test_POST_deploy_sets_license_key(self): |
40 | 369 | self.patch(node_module.Node, "_start") | 370 | self.patch(node_module.Node, "_start") |
41 | 371 | self.patch(machines_module, "get_curtin_merged_config") | ||
42 | 370 | machine = factory.make_Node( | 372 | machine = factory.make_Node( |
43 | 371 | owner=self.user, interface=True, | 373 | owner=self.user, interface=True, |
44 | 372 | power_type='manual', | 374 | power_type='manual', |
45 | @@ -415,6 +417,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
46 | 415 | 417 | ||
47 | 416 | def test_POST_deploy_sets_default_distro_series(self): | 418 | def test_POST_deploy_sets_default_distro_series(self): |
48 | 417 | self.patch(node_module.Node, "_start") | 419 | self.patch(node_module.Node, "_start") |
49 | 420 | self.patch(machines_module, "get_curtin_merged_config") | ||
50 | 418 | machine = factory.make_Node( | 421 | machine = factory.make_Node( |
51 | 419 | owner=self.user, interface=True, | 422 | owner=self.user, interface=True, |
52 | 420 | power_type='manual', | 423 | power_type='manual', |
53 | @@ -432,6 +435,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
54 | 432 | 435 | ||
55 | 433 | def test_POST_deploy_works_if_series_already_set(self): | 436 | def test_POST_deploy_works_if_series_already_set(self): |
56 | 434 | self.patch(node_module.Node, "_start") | 437 | self.patch(node_module.Node, "_start") |
57 | 438 | self.patch(machines_module, "get_curtin_merged_config") | ||
58 | 435 | osystem = Config.objects.get_config('default_osystem') | 439 | osystem = Config.objects.get_config('default_osystem') |
59 | 436 | distro_series = Config.objects.get_config('default_distro_series') | 440 | distro_series = Config.objects.get_config('default_distro_series') |
60 | 437 | make_usable_osystem( | 441 | make_usable_osystem( |
61 | @@ -467,6 +471,26 @@ class TestMachineAPI(APITestCase.ForUser): | |||
62 | 467 | ), | 471 | ), |
63 | 468 | (response.status_code, json_load_bytes(response.content))) | 472 | (response.status_code, json_load_bytes(response.content))) |
64 | 469 | 473 | ||
65 | 474 | def test_POST_deploy_fails_when_preseed_not_rendered(self): | ||
66 | 475 | mock_get_curtin_merged_config = self.patch( | ||
67 | 476 | machines_module, "get_curtin_merged_config") | ||
68 | 477 | mock_get_curtin_merged_config.side_effect = Exception('error') | ||
69 | 478 | osystem = Config.objects.get_config('default_osystem') | ||
70 | 479 | distro_series = Config.objects.get_config('default_distro_series') | ||
71 | 480 | make_usable_osystem( | ||
72 | 481 | self, osystem_name=osystem, releases=[distro_series]) | ||
73 | 482 | machine = factory.make_Node( | ||
74 | 483 | owner=self.user, interface=True, | ||
75 | 484 | status=NODE_STATUS.ALLOCATED, | ||
76 | 485 | power_type='manual', | ||
77 | 486 | distro_series=distro_series, | ||
78 | 487 | osystem=osystem, | ||
79 | 488 | architecture=make_usable_architecture(self)) | ||
80 | 489 | response = self.client.post( | ||
81 | 490 | self.get_machine_uri(machine), {'op': 'deploy'}) | ||
82 | 491 | self.assertEqual(http.client.BAD_REQUEST, response.status_code) | ||
83 | 492 | self.assertEqual(b"Failed to render preseed: error", response.content) | ||
84 | 493 | |||
85 | 470 | def test_POST_deploy_validates_hwe_kernel_with_default_distro_series(self): | 494 | def test_POST_deploy_validates_hwe_kernel_with_default_distro_series(self): |
86 | 471 | architecture = make_usable_architecture(self, subarch_name="generic") | 495 | architecture = make_usable_architecture(self, subarch_name="generic") |
87 | 472 | machine = factory.make_Node( | 496 | machine = factory.make_Node( |
88 | @@ -495,6 +519,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
89 | 495 | 519 | ||
90 | 496 | def test_POST_deploy_may_be_repeated(self): | 520 | def test_POST_deploy_may_be_repeated(self): |
91 | 497 | self.patch(node_module.Node, "_start") | 521 | self.patch(node_module.Node, "_start") |
92 | 522 | self.patch(machines_module, "get_curtin_merged_config") | ||
93 | 498 | machine = factory.make_Node( | 523 | machine = factory.make_Node( |
94 | 499 | owner=self.user, interface=True, | 524 | owner=self.user, interface=True, |
95 | 500 | power_type='manual', | 525 | power_type='manual', |
96 | @@ -515,6 +540,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
97 | 515 | node_module.RackControllerManager, "filter_by_url_accessible" | 540 | node_module.RackControllerManager, "filter_by_url_accessible" |
98 | 516 | ).return_value = [rack_controller] | 541 | ).return_value = [rack_controller] |
99 | 517 | self.patch(node_module.Node, "_power_control_node") | 542 | self.patch(node_module.Node, "_power_control_node") |
100 | 543 | self.patch(machines_module, "get_curtin_merged_config") | ||
101 | 518 | machine = factory.make_Node( | 544 | machine = factory.make_Node( |
102 | 519 | owner=self.user, interface=True, | 545 | owner=self.user, interface=True, |
103 | 520 | power_type='virsh', architecture=make_usable_architecture(self), | 546 | power_type='virsh', architecture=make_usable_architecture(self), |
104 | @@ -536,6 +562,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
105 | 536 | 562 | ||
106 | 537 | def test_POST_deploy_passes_comment(self): | 563 | def test_POST_deploy_passes_comment(self): |
107 | 538 | self.patch(node_module.Node, "_start") | 564 | self.patch(node_module.Node, "_start") |
108 | 565 | self.patch(machines_module, "get_curtin_merged_config") | ||
109 | 539 | rack_controller = factory.make_RackController() | 566 | rack_controller = factory.make_RackController() |
110 | 540 | machine = factory.make_Node( | 567 | machine = factory.make_Node( |
111 | 541 | owner=self.user, interface=True, | 568 | owner=self.user, interface=True, |
112 | @@ -565,6 +592,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
113 | 565 | osystem = make_usable_osystem(self) | 592 | osystem = make_usable_osystem(self) |
114 | 566 | distro_series = osystem['default_release'] | 593 | distro_series = osystem['default_release'] |
115 | 567 | machine_start = self.patch(node_module.Machine, 'start') | 594 | machine_start = self.patch(node_module.Machine, 'start') |
116 | 595 | self.patch(machines_module, "get_curtin_merged_config") | ||
117 | 568 | machine_start.return_value = False | 596 | machine_start.return_value = False |
118 | 569 | self.client.post( | 597 | self.client.post( |
119 | 570 | self.get_machine_uri(machine), { | 598 | self.get_machine_uri(machine), { |
120 | @@ -578,6 +606,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
121 | 578 | def test_POST_deploy_doesnt_reset_power_options_bug_1569102(self): | 606 | def test_POST_deploy_doesnt_reset_power_options_bug_1569102(self): |
122 | 579 | self.become_admin() | 607 | self.become_admin() |
123 | 580 | self.patch(node_module.Node, "_start") | 608 | self.patch(node_module.Node, "_start") |
124 | 609 | self.patch(machines_module, "get_curtin_merged_config") | ||
125 | 581 | rack_controller = factory.make_RackController() | 610 | rack_controller = factory.make_RackController() |
126 | 582 | machine = factory.make_Node( | 611 | machine = factory.make_Node( |
127 | 583 | owner=self.user, interface=True, | 612 | owner=self.user, interface=True, |
128 | @@ -600,6 +629,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
129 | 600 | 629 | ||
130 | 601 | def test_POST_deploy_allocates_ready_machines(self): | 630 | def test_POST_deploy_allocates_ready_machines(self): |
131 | 602 | self.patch(node_module.Node, "_start") | 631 | self.patch(node_module.Node, "_start") |
132 | 632 | self.patch(machines_module, "get_curtin_merged_config") | ||
133 | 603 | machine = factory.make_Node( | 633 | machine = factory.make_Node( |
134 | 604 | status=NODE_STATUS.READY, interface=True, | 634 | status=NODE_STATUS.READY, interface=True, |
135 | 605 | power_type='manual', | 635 | power_type='manual', |
136 | @@ -631,6 +661,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
137 | 631 | 661 | ||
138 | 632 | def test_POST_deploy_passes_agent_name(self): | 662 | def test_POST_deploy_passes_agent_name(self): |
139 | 633 | self.patch(node_module.Node, "_start") | 663 | self.patch(node_module.Node, "_start") |
140 | 664 | self.patch(machines_module, "get_curtin_merged_config") | ||
141 | 634 | machine = factory.make_Node( | 665 | machine = factory.make_Node( |
142 | 635 | status=NODE_STATUS.READY, interface=True, | 666 | status=NODE_STATUS.READY, interface=True, |
143 | 636 | power_type='manual', | 667 | power_type='manual', |
144 | @@ -650,6 +681,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
145 | 650 | 681 | ||
146 | 651 | def test_POST_deploy_passes_comment_on_acquire(self): | 682 | def test_POST_deploy_passes_comment_on_acquire(self): |
147 | 652 | self.patch(node_module.Node, "_start") | 683 | self.patch(node_module.Node, "_start") |
148 | 684 | self.patch(machines_module, "get_curtin_merged_config") | ||
149 | 653 | machine_method = self.patch(node_module.Machine, 'acquire') | 685 | machine_method = self.patch(node_module.Machine, 'acquire') |
150 | 654 | machine = factory.make_Node( | 686 | machine = factory.make_Node( |
151 | 655 | status=NODE_STATUS.READY, owner=self.user, interface=True, | 687 | status=NODE_STATUS.READY, owner=self.user, interface=True, |
152 | @@ -673,6 +705,7 @@ class TestMachineAPI(APITestCase.ForUser): | |||
153 | 673 | 705 | ||
154 | 674 | def test_POST_deploy_passes_bridge_settings(self): | 706 | def test_POST_deploy_passes_bridge_settings(self): |
155 | 675 | self.patch(node_module.Node, "_start") | 707 | self.patch(node_module.Node, "_start") |
156 | 708 | self.patch(machines_module, "get_curtin_merged_config") | ||
157 | 676 | machine_method = self.patch(node_module.Machine, 'acquire') | 709 | machine_method = self.patch(node_module.Machine, 'acquire') |
158 | 677 | machine = factory.make_Node( | 710 | machine = factory.make_Node( |
159 | 678 | status=NODE_STATUS.READY, owner=self.user, interface=True, | 711 | status=NODE_STATUS.READY, owner=self.user, interface=True, |
160 | diff --git a/src/maasserver/node_action.py b/src/maasserver/node_action.py | |||
161 | index fc48bb0..564abd5 100644 | |||
162 | --- a/src/maasserver/node_action.py | |||
163 | +++ b/src/maasserver/node_action.py | |||
164 | @@ -44,6 +44,7 @@ from maasserver.node_status import ( | |||
165 | 44 | is_failed_status, | 44 | is_failed_status, |
166 | 45 | NON_MONITORED_STATUSES, | 45 | NON_MONITORED_STATUSES, |
167 | 46 | ) | 46 | ) |
168 | 47 | from maasserver.preseed import get_curtin_config | ||
169 | 47 | from maasserver.utils.orm import post_commit_do | 48 | from maasserver.utils.orm import post_commit_do |
170 | 48 | from maasserver.utils.osystems import ( | 49 | from maasserver.utils.osystems import ( |
171 | 49 | validate_hwe_kernel, | 50 | validate_hwe_kernel, |
172 | @@ -346,6 +347,12 @@ class Deploy(NodeAction): | |||
173 | 346 | raise NodeActionError(e) | 347 | raise NodeActionError(e) |
174 | 347 | 348 | ||
175 | 348 | try: | 349 | try: |
176 | 350 | get_curtin_config(self.node) | ||
177 | 351 | except Exception as e: | ||
178 | 352 | raise NodeActionError( | ||
179 | 353 | "Failed to retrieve curtin config: %s" % e) | ||
180 | 354 | |||
181 | 355 | try: | ||
182 | 349 | self.node.start(self.user) | 356 | self.node.start(self.user) |
183 | 350 | except StaticIPAddressExhaustion: | 357 | except StaticIPAddressExhaustion: |
184 | 351 | raise NodeActionError( | 358 | raise NodeActionError( |
185 | diff --git a/src/maasserver/tests/test_node_action.py b/src/maasserver/tests/test_node_action.py | |||
186 | index 4f0c0bd..bad38a2 100644 | |||
187 | --- a/src/maasserver/tests/test_node_action.py | |||
188 | +++ b/src/maasserver/tests/test_node_action.py | |||
189 | @@ -49,6 +49,7 @@ from maasserver.node_action import ( | |||
190 | 49 | SetZone, | 49 | SetZone, |
191 | 50 | Test, | 50 | Test, |
192 | 51 | ) | 51 | ) |
193 | 52 | import maasserver.node_action as node_action_module | ||
194 | 52 | from maasserver.node_status import ( | 53 | from maasserver.node_status import ( |
195 | 53 | MONITORED_STATUSES, | 54 | MONITORED_STATUSES, |
196 | 54 | NODE_TESTING_RESET_READY_TRANSITIONS, | 55 | NODE_TESTING_RESET_READY_TRANSITIONS, |
197 | @@ -499,10 +500,27 @@ class TestDeployAction(MAASServerTestCase): | |||
198 | 499 | node = factory.make_Node( | 500 | node = factory.make_Node( |
199 | 500 | interface=True, status=NODE_STATUS.ALLOCATED, | 501 | interface=True, status=NODE_STATUS.ALLOCATED, |
200 | 501 | power_type='manual', owner=user) | 502 | power_type='manual', owner=user) |
202 | 502 | node_start = self.patch(node, 'start') | 503 | mock_get_curtin_config = self.patch( |
203 | 504 | node_action_module, 'get_curtin_config') | ||
204 | 505 | mock_node_start = self.patch(node, 'start') | ||
205 | 503 | Deploy(node, user).execute() | 506 | Deploy(node, user).execute() |
208 | 504 | self.assertThat( | 507 | self.expectThat( |
209 | 505 | node_start, MockCalledOnceWith(user)) | 508 | mock_get_curtin_config, MockCalledOnceWith(node)) |
210 | 509 | self.expectThat( | ||
211 | 510 | mock_node_start, MockCalledOnceWith(user)) | ||
212 | 511 | |||
213 | 512 | def test_Deploy_raises_NodeActionError_for_no_curtin_config(self): | ||
214 | 513 | user = factory.make_User() | ||
215 | 514 | node = factory.make_Node( | ||
216 | 515 | interface=True, status=NODE_STATUS.ALLOCATED, | ||
217 | 516 | power_type='manual', owner=user) | ||
218 | 517 | mock_get_curtin_config = self.patch( | ||
219 | 518 | node_action_module, 'get_curtin_config') | ||
220 | 519 | mock_get_curtin_config.side_effect = NodeActionError('error') | ||
221 | 520 | error = self.assertRaises( | ||
222 | 521 | NodeActionError, Deploy(node, user).execute) | ||
223 | 522 | self.assertEqual( | ||
224 | 523 | "Failed to retrieve curtin config: error", str(error)) | ||
225 | 506 | 524 | ||
226 | 507 | def test_Deploy_raises_NodeActionError_for_invalid_os(self): | 525 | def test_Deploy_raises_NodeActionError_for_invalid_os(self): |
227 | 508 | user = factory.make_User() | 526 | user = factory.make_User() |
228 | @@ -527,7 +545,9 @@ class TestDeployAction(MAASServerTestCase): | |||
229 | 527 | node = factory.make_Node( | 545 | node = factory.make_Node( |
230 | 528 | interface=True, status=NODE_STATUS.ALLOCATED, | 546 | interface=True, status=NODE_STATUS.ALLOCATED, |
231 | 529 | power_type='manual', owner=user) | 547 | power_type='manual', owner=user) |
233 | 530 | self.patch(node, 'start') | 548 | mock_get_curtin_config = self.patch( |
234 | 549 | node_action_module, 'get_curtin_config') | ||
235 | 550 | mock_node_start = self.patch(node, 'start') | ||
236 | 531 | osystem = make_usable_osystem(self) | 551 | osystem = make_usable_osystem(self) |
237 | 532 | os_name = osystem["name"] | 552 | os_name = osystem["name"] |
238 | 533 | release_name = osystem["releases"][0]["name"] | 553 | release_name = osystem["releases"][0]["name"] |
239 | @@ -536,6 +556,10 @@ class TestDeployAction(MAASServerTestCase): | |||
240 | 536 | "distro_series": release_name | 556 | "distro_series": release_name |
241 | 537 | } | 557 | } |
242 | 538 | Deploy(node, user).execute(**extra) | 558 | Deploy(node, user).execute(**extra) |
243 | 559 | self.expectThat( | ||
244 | 560 | mock_get_curtin_config, MockCalledOnceWith(node)) | ||
245 | 561 | self.expectThat( | ||
246 | 562 | mock_node_start, MockCalledOnceWith(user)) | ||
247 | 539 | self.expectThat(node.osystem, Equals(os_name)) | 563 | self.expectThat(node.osystem, Equals(os_name)) |
248 | 540 | self.expectThat( | 564 | self.expectThat( |
249 | 541 | node.distro_series, Equals(release_name)) | 565 | node.distro_series, Equals(release_name)) |
250 | @@ -545,7 +569,9 @@ class TestDeployAction(MAASServerTestCase): | |||
251 | 545 | node = factory.make_Node( | 569 | node = factory.make_Node( |
252 | 546 | interface=True, status=NODE_STATUS.ALLOCATED, | 570 | interface=True, status=NODE_STATUS.ALLOCATED, |
253 | 547 | power_type='manual', owner=user) | 571 | power_type='manual', owner=user) |
255 | 548 | self.patch(node, 'start') | 572 | mock_get_curtin_config = self.patch( |
256 | 573 | node_action_module, 'get_curtin_config') | ||
257 | 574 | mock_node_start = self.patch(node, 'start') | ||
258 | 549 | osystem = make_usable_osystem(self) | 575 | osystem = make_usable_osystem(self) |
259 | 550 | os_name = osystem["name"] | 576 | os_name = osystem["name"] |
260 | 551 | release_name = osystem["releases"][0]["name"] | 577 | release_name = osystem["releases"][0]["name"] |
261 | @@ -554,6 +580,10 @@ class TestDeployAction(MAASServerTestCase): | |||
262 | 554 | "distro_series": release_name + '*' | 580 | "distro_series": release_name + '*' |
263 | 555 | } | 581 | } |
264 | 556 | Deploy(node, user).execute(**extra) | 582 | Deploy(node, user).execute(**extra) |
265 | 583 | self.expectThat( | ||
266 | 584 | mock_get_curtin_config, MockCalledOnceWith(node)) | ||
267 | 585 | self.expectThat( | ||
268 | 586 | mock_node_start, MockCalledOnceWith(user)) | ||
269 | 557 | self.expectThat(node.osystem, Equals(os_name)) | 587 | self.expectThat(node.osystem, Equals(os_name)) |
270 | 558 | self.expectThat( | 588 | self.expectThat( |
271 | 559 | node.distro_series, Equals(release_name)) | 589 | node.distro_series, Equals(release_name)) |
272 | @@ -563,12 +593,18 @@ class TestDeployAction(MAASServerTestCase): | |||
273 | 563 | node = factory.make_Node( | 593 | node = factory.make_Node( |
274 | 564 | interface=True, status=NODE_STATUS.ALLOCATED, | 594 | interface=True, status=NODE_STATUS.ALLOCATED, |
275 | 565 | power_type='manual', owner=user) | 595 | power_type='manual', owner=user) |
277 | 566 | self.patch(node, 'start') | 596 | mock_get_curtin_config = self.patch( |
278 | 597 | node_action_module, 'get_curtin_config') | ||
279 | 598 | mock_node_start = self.patch(node, 'start') | ||
280 | 567 | osystem = make_osystem_with_releases(self) | 599 | osystem = make_osystem_with_releases(self) |
281 | 568 | extra = { | 600 | extra = { |
282 | 569 | "distro_series": osystem["releases"][0]["name"], | 601 | "distro_series": osystem["releases"][0]["name"], |
283 | 570 | } | 602 | } |
284 | 571 | Deploy(node, user).execute(**extra) | 603 | Deploy(node, user).execute(**extra) |
285 | 604 | self.expectThat( | ||
286 | 605 | mock_get_curtin_config, MockCalledOnceWith(node)) | ||
287 | 606 | self.expectThat( | ||
288 | 607 | mock_node_start, MockCalledOnceWith(user)) | ||
289 | 572 | self.expectThat(node.osystem, Equals("")) | 608 | self.expectThat(node.osystem, Equals("")) |
290 | 573 | self.expectThat(node.distro_series, Equals("")) | 609 | self.expectThat(node.distro_series, Equals("")) |
291 | 574 | 610 | ||
292 | @@ -577,24 +613,36 @@ class TestDeployAction(MAASServerTestCase): | |||
293 | 577 | node = factory.make_Node( | 613 | node = factory.make_Node( |
294 | 578 | interface=True, status=NODE_STATUS.ALLOCATED, | 614 | interface=True, status=NODE_STATUS.ALLOCATED, |
295 | 579 | power_type='manual', owner=user) | 615 | power_type='manual', owner=user) |
297 | 580 | self.patch(node, 'start') | 616 | mock_get_curtin_config = self.patch( |
298 | 617 | node_action_module, 'get_curtin_config') | ||
299 | 618 | mock_node_start = self.patch(node, 'start') | ||
300 | 581 | osystem = make_osystem_with_releases(self) | 619 | osystem = make_osystem_with_releases(self) |
301 | 582 | extra = { | 620 | extra = { |
302 | 583 | "osystem": osystem["name"], | 621 | "osystem": osystem["name"], |
303 | 584 | } | 622 | } |
304 | 585 | Deploy(node, user).execute(**extra) | 623 | Deploy(node, user).execute(**extra) |
305 | 624 | self.expectThat( | ||
306 | 625 | mock_get_curtin_config, MockCalledOnceWith(node)) | ||
307 | 626 | self.expectThat( | ||
308 | 627 | mock_node_start, MockCalledOnceWith(user)) | ||
309 | 586 | self.expectThat(node.osystem, Equals("")) | 628 | self.expectThat(node.osystem, Equals("")) |
310 | 587 | self.expectThat(node.distro_series, Equals("")) | 629 | self.expectThat(node.distro_series, Equals("")) |
311 | 588 | 630 | ||
312 | 589 | def test_Deploy_allocates_node_if_node_not_already_allocated(self): | 631 | def test_Deploy_allocates_node_if_node_not_already_allocated(self): |
313 | 590 | user = factory.make_User() | 632 | user = factory.make_User() |
314 | 591 | node = factory.make_Node(status=NODE_STATUS.READY, with_boot_disk=True) | 633 | node = factory.make_Node(status=NODE_STATUS.READY, with_boot_disk=True) |
316 | 592 | self.patch(node, 'start') | 634 | mock_get_curtin_config = self.patch( |
317 | 635 | node_action_module, 'get_curtin_config') | ||
318 | 636 | mock_node_start = self.patch(node, 'start') | ||
319 | 593 | action = Deploy(node, user) | 637 | action = Deploy(node, user) |
320 | 594 | action.execute() | 638 | action.execute() |
321 | 595 | 639 | ||
324 | 596 | self.assertEqual(user, node.owner) | 640 | self.expectThat( |
325 | 597 | self.assertEqual(NODE_STATUS.ALLOCATED, node.status) | 641 | mock_get_curtin_config, MockCalledOnceWith(node)) |
326 | 642 | self.expectThat( | ||
327 | 643 | mock_node_start, MockCalledOnceWith(user)) | ||
328 | 644 | self.expectThat(user, Equals(node.owner)) | ||
329 | 645 | self.expectThat(NODE_STATUS.ALLOCATED, Equals(node.status)) | ||
330 | 598 | 646 | ||
331 | 599 | 647 | ||
332 | 600 | class TestDeployActionTransactional(MAASTransactionServerTestCase): | 648 | class TestDeployActionTransactional(MAASTransactionServerTestCase): |
333 | diff --git a/src/maasserver/websockets/handlers/tests/test_machine.py b/src/maasserver/websockets/handlers/tests/test_machine.py | |||
334 | index 80ab253..0732ba1 100644 | |||
335 | --- a/src/maasserver/websockets/handlers/tests/test_machine.py | |||
336 | +++ b/src/maasserver/websockets/handlers/tests/test_machine.py | |||
337 | @@ -56,6 +56,7 @@ from maasserver.models.partition import ( | |||
338 | 56 | PARTITION_ALIGNMENT_SIZE, | 56 | PARTITION_ALIGNMENT_SIZE, |
339 | 57 | ) | 57 | ) |
340 | 58 | from maasserver.node_action import compile_node_actions | 58 | from maasserver.node_action import compile_node_actions |
341 | 59 | import maasserver.node_action as node_action_module | ||
342 | 59 | from maasserver.testing.architecture import make_usable_architecture | 60 | from maasserver.testing.architecture import make_usable_architecture |
343 | 60 | from maasserver.testing.factory import factory | 61 | from maasserver.testing.factory import factory |
344 | 61 | from maasserver.testing.osystems import make_usable_osystem | 62 | from maasserver.testing.osystems import make_usable_osystem |
345 | @@ -2059,6 +2060,7 @@ class TestMachineHandler(MAASServerTestCase): | |||
346 | 2059 | self.patch(Machine, 'on_network').return_value = True | 2060 | self.patch(Machine, 'on_network').return_value = True |
347 | 2060 | node = factory.make_Node(status=NODE_STATUS.ALLOCATED, owner=user) | 2061 | node = factory.make_Node(status=NODE_STATUS.ALLOCATED, owner=user) |
348 | 2061 | self.patch(Machine, "_start").return_value = None | 2062 | self.patch(Machine, "_start").return_value = None |
349 | 2063 | self.patch(node_action_module, 'get_curtin_config') | ||
350 | 2062 | osystem = make_usable_osystem(self) | 2064 | osystem = make_usable_osystem(self) |
351 | 2063 | handler = MachineHandler(user, {}) | 2065 | handler = MachineHandler(user, {}) |
352 | 2064 | handler.action({ | 2066 | handler.action({ |
lgtm!