Merge ~bjornt/maas:bug-1772906-fix-pod-update-api into maas:master
- Git
- lp:~bjornt/maas
- bug-1772906-fix-pod-update-api
- Merge into master
Status: | Merged |
---|---|
Approved by: | Björn Tillenius |
Approved revision: | f1a1cdfde86f33481b60e7ef2dd9b92cf37a4018 |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~bjornt/maas:bug-1772906-fix-pod-update-api |
Merge into: | maas:master |
Diff against target: |
343 lines (+64/-119) 6 files modified
src/maasserver/api/tests/test_pods.py (+20/-0) src/maasserver/forms/pods.py (+5/-1) src/maasserver/forms/tests/test_pods.py (+23/-12) src/maasserver/models/tests/test_bmc.py (+2/-2) src/maasserver/testing/factory.py (+4/-1) src/maasserver/websockets/handlers/tests/test_pod.py (+10/-103) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
MAAS Lander | Needs Fixing | ||
Alberto Donato (community) | Approve | ||
Review via email:
|
Commit message
LP: #1772906 - Pods can't be updated via the API without passing power_address
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
LANDING
-b bug-1772906-fix-pod-update-api lp:~bjornt/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED BUILD
LOG: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
LANDING
-b bug-1772906-fix-pod-update-api lp:~bjornt/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED BUILD
LOG: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
LANDING
-b bug-1772906-fix-pod-update-api lp:~bjornt/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED BUILD
LOG: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b bug-1772906-fix-pod-update-api lp:~bjornt/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED
LOG: http://
COMMIT: aa1df742fc57ac9
- f1a1cdf... by Björn Tillenius
-
Fix test failure.
Preview Diff
1 | diff --git a/src/maasserver/api/tests/test_pods.py b/src/maasserver/api/tests/test_pods.py | |||
2 | index fed3570..863df22 100644 | |||
3 | --- a/src/maasserver/api/tests/test_pods.py | |||
4 | +++ b/src/maasserver/api/tests/test_pods.py | |||
5 | @@ -276,6 +276,26 @@ class TestPodAPI(APITestCase.ForUser, PodMixin): | |||
6 | 276 | self.assertEqual(new_name, parsed_output['name']) | 276 | self.assertEqual(new_name, parsed_output['name']) |
7 | 277 | self.assertEqual(discovered_pod.cores, parsed_output['total']['cores']) | 277 | self.assertEqual(discovered_pod.cores, parsed_output['total']['cores']) |
8 | 278 | 278 | ||
9 | 279 | def test_PUT_update_minimal(self): | ||
10 | 280 | self.become_admin() | ||
11 | 281 | pod_info = self.make_pod_info() | ||
12 | 282 | power_parameters = { | ||
13 | 283 | 'power_address': pod_info['power_address'], | ||
14 | 284 | 'power_pass': pod_info['power_pass'], | ||
15 | 285 | } | ||
16 | 286 | pod = factory.make_Pod( | ||
17 | 287 | pod_type=pod_info['type'], parameters=power_parameters) | ||
18 | 288 | new_name = factory.make_name('pool') | ||
19 | 289 | self.fake_pod_discovery() | ||
20 | 290 | response = self.client.put(get_pod_uri(pod), { | ||
21 | 291 | 'name': new_name, | ||
22 | 292 | }) | ||
23 | 293 | self.assertEqual( | ||
24 | 294 | http.client.OK, response.status_code, response.content) | ||
25 | 295 | pod.refresh_from_db() | ||
26 | 296 | self.assertEqual(new_name, pod.name) | ||
27 | 297 | self.assertEqual(power_parameters, pod.power_parameters) | ||
28 | 298 | |||
29 | 279 | def test_refresh_requires_admin(self): | 299 | def test_refresh_requires_admin(self): |
30 | 280 | pod = factory.make_Pod() | 300 | pod = factory.make_Pod() |
31 | 281 | response = self.client.post(get_pod_uri(pod), { | 301 | response = self.client.post(get_pod_uri(pod), { |
32 | diff --git a/src/maasserver/forms/pods.py b/src/maasserver/forms/pods.py | |||
33 | index 654f5f6..89e3b2b 100644 | |||
34 | --- a/src/maasserver/forms/pods.py | |||
35 | +++ b/src/maasserver/forms/pods.py | |||
36 | @@ -165,10 +165,14 @@ class PodForm(MAASModelForm): | |||
37 | 165 | # selected type for the pod. | 165 | # selected type for the pod. |
38 | 166 | if len(self.errors) == 0: | 166 | if len(self.errors) == 0: |
39 | 167 | driver_fields = get_driver_parameters_from_json( | 167 | driver_fields = get_driver_parameters_from_json( |
41 | 168 | self.drivers_orig, None, scope=SETTING_SCOPE.BMC) | 168 | self.drivers_orig, scope=SETTING_SCOPE.BMC) |
42 | 169 | self.param_fields = ( | 169 | self.param_fields = ( |
43 | 170 | driver_fields[self.cleaned_data['type']].field_dict) | 170 | driver_fields[self.cleaned_data['type']].field_dict) |
44 | 171 | self.fields.update(self.param_fields) | 171 | self.fields.update(self.param_fields) |
45 | 172 | if not self.is_new: | ||
46 | 173 | for key, value in self.instance.power_parameters.items(): | ||
47 | 174 | if key not in self.data: | ||
48 | 175 | self.data[key] = value | ||
49 | 172 | super(PodForm, self)._clean_fields() | 176 | super(PodForm, self)._clean_fields() |
50 | 173 | 177 | ||
51 | 174 | def clean(self): | 178 | def clean(self): |
52 | diff --git a/src/maasserver/forms/tests/test_pods.py b/src/maasserver/forms/tests/test_pods.py | |||
53 | index 64bfae4..a567f31 100644 | |||
54 | --- a/src/maasserver/forms/tests/test_pods.py | |||
55 | +++ b/src/maasserver/forms/tests/test_pods.py | |||
56 | @@ -85,7 +85,7 @@ def make_pod_with_hints(): | |||
57 | 85 | pod = factory.make_Pod( | 85 | pod = factory.make_Pod( |
58 | 86 | architectures=architectures, cores=random.randint(8, 16), | 86 | architectures=architectures, cores=random.randint(8, 16), |
59 | 87 | memory=random.randint(4096, 8192), | 87 | memory=random.randint(4096, 8192), |
61 | 88 | cpu_speed=random.randint(2000, 3000)) | 88 | cpu_speed=random.randint(2000, 3000), parameters={}) |
62 | 89 | for _ in range(3): | 89 | for _ in range(3): |
63 | 90 | pool = factory.make_PodStoragePool(pod) | 90 | pool = factory.make_PodStoragePool(pod) |
64 | 91 | pod.default_storage_pool = pool | 91 | pod.default_storage_pool = pool |
65 | @@ -369,18 +369,22 @@ class TestPodForm(MAASTransactionServerTestCase): | |||
66 | 369 | 369 | ||
67 | 370 | def test_updates_existing_pod_minimal(self): | 370 | def test_updates_existing_pod_minimal(self): |
68 | 371 | self.fake_pod_discovery() | 371 | self.fake_pod_discovery() |
69 | 372 | pod_info = self.make_pod_info() | ||
70 | 373 | zone = factory.make_Zone() | 372 | zone = factory.make_Zone() |
71 | 374 | pool = factory.make_ResourcePool() | 373 | pool = factory.make_ResourcePool() |
72 | 375 | cpu_over_commit = random.randint(0, 10) | 374 | cpu_over_commit = random.randint(0, 10) |
73 | 376 | memory_over_commit = random.randint(0, 10) | 375 | memory_over_commit = random.randint(0, 10) |
74 | 376 | power_parameters = { | ||
75 | 377 | 'power_address': 'qemu+ssh://1.2.3.4/system', | ||
76 | 378 | 'power_pass': 'pass', | ||
77 | 379 | } | ||
78 | 377 | orig_pod = factory.make_Pod( | 380 | orig_pod = factory.make_Pod( |
80 | 378 | pod_type=pod_info['type'], zone=zone, default_pool=pool, | 381 | pod_type='virsh', zone=zone, default_pool=pool, |
81 | 379 | cpu_over_commit_ratio=cpu_over_commit, | 382 | cpu_over_commit_ratio=cpu_over_commit, |
83 | 380 | memory_over_commit_ratio=memory_over_commit) | 383 | memory_over_commit_ratio=memory_over_commit, |
84 | 384 | parameters=power_parameters) | ||
85 | 381 | new_name = factory.make_name("pod") | 385 | new_name = factory.make_name("pod") |
88 | 382 | pod_info['name'] = new_name | 386 | form = PodForm( |
89 | 383 | form = PodForm(data=pod_info, request=self.request, instance=orig_pod) | 387 | data={'name': new_name}, request=self.request, instance=orig_pod) |
90 | 384 | self.assertTrue(form.is_valid(), form._errors) | 388 | self.assertTrue(form.is_valid(), form._errors) |
91 | 385 | pod = form.save() | 389 | pod = form.save() |
92 | 386 | self.assertEqual(new_name, pod.name) | 390 | self.assertEqual(new_name, pod.name) |
93 | @@ -388,6 +392,8 @@ class TestPodForm(MAASTransactionServerTestCase): | |||
94 | 388 | self.assertEqual(pool, pod.default_pool) | 392 | self.assertEqual(pool, pod.default_pool) |
95 | 389 | self.assertEqual(cpu_over_commit, pod.cpu_over_commit_ratio) | 393 | self.assertEqual(cpu_over_commit, pod.cpu_over_commit_ratio) |
96 | 390 | self.assertEqual(memory_over_commit, pod.memory_over_commit_ratio) | 394 | self.assertEqual(memory_over_commit, pod.memory_over_commit_ratio) |
97 | 395 | self.assertEqual(memory_over_commit, pod.memory_over_commit_ratio) | ||
98 | 396 | self.assertEqual(power_parameters, pod.power_parameters) | ||
99 | 391 | 397 | ||
100 | 392 | def test_updates_existing_pod(self): | 398 | def test_updates_existing_pod(self): |
101 | 393 | discovered_pod, discovered_racks, failed_racks = ( | 399 | discovered_pod, discovered_racks, failed_racks = ( |
102 | @@ -533,7 +539,10 @@ class TestPodForm(MAASTransactionServerTestCase): | |||
103 | 533 | self.fake_pod_discovery()) | 539 | self.fake_pod_discovery()) |
104 | 534 | zone = factory.make_Zone() | 540 | zone = factory.make_Zone() |
105 | 535 | pod_info = self.make_pod_info() | 541 | pod_info = self.make_pod_info() |
107 | 536 | orig_pod = factory.make_Pod(zone=zone, pod_type=pod_info['type']) | 542 | power_parameters = {'power_address': pod_info['power_address']} |
108 | 543 | orig_pod = factory.make_Pod( | ||
109 | 544 | zone=zone, pod_type=pod_info['type'], | ||
110 | 545 | parameters=power_parameters) | ||
111 | 537 | form = PodForm(data=pod_info, request=self.request, instance=orig_pod) | 546 | form = PodForm(data=pod_info, request=self.request, instance=orig_pod) |
112 | 538 | pod = form.discover_and_sync_pod() | 547 | pod = form.discover_and_sync_pod() |
113 | 539 | self.assertThat(pod, MatchesStructure( | 548 | self.assertThat(pod, MatchesStructure( |
114 | @@ -546,8 +555,8 @@ class TestPodForm(MAASTransactionServerTestCase): | |||
115 | 546 | cpu_speed=Equals(discovered_pod.cpu_speed), | 555 | cpu_speed=Equals(discovered_pod.cpu_speed), |
116 | 547 | zone=Equals(zone), | 556 | zone=Equals(zone), |
117 | 548 | power_type=Equals(pod_info['type']), | 557 | power_type=Equals(pod_info['type']), |
120 | 549 | power_parameters=Equals({}), | 558 | power_parameters=Equals(power_parameters), |
121 | 550 | ip_address=Is(None), | 559 | ip_address=MatchesStructure(ip=Equals(pod_info['ip_address'])), |
122 | 551 | )) | 560 | )) |
123 | 552 | routable_racks = [ | 561 | routable_racks = [ |
124 | 553 | relation.rack_controller | 562 | relation.rack_controller |
125 | @@ -571,8 +580,10 @@ class TestPodForm(MAASTransactionServerTestCase): | |||
126 | 571 | pods_module.discover_pod.return_value) | 580 | pods_module.discover_pod.return_value) |
127 | 572 | zone = yield deferToDatabase(factory.make_Zone) | 581 | zone = yield deferToDatabase(factory.make_Zone) |
128 | 573 | pod_info = yield deferToDatabase(self.make_pod_info) | 582 | pod_info = yield deferToDatabase(self.make_pod_info) |
129 | 583 | power_parameters = {'power_address': pod_info['power_address']} | ||
130 | 574 | orig_pod = yield deferToDatabase( | 584 | orig_pod = yield deferToDatabase( |
132 | 575 | factory.make_Pod, zone=zone, pod_type=pod_info['type']) | 585 | factory.make_Pod, zone=zone, pod_type=pod_info['type'], |
133 | 586 | parameters=power_parameters) | ||
134 | 576 | form = yield deferToDatabase( | 587 | form = yield deferToDatabase( |
135 | 577 | PodForm, data=pod_info, request=self.request, instance=orig_pod) | 588 | PodForm, data=pod_info, request=self.request, instance=orig_pod) |
136 | 578 | pod = yield form.discover_and_sync_pod() | 589 | pod = yield form.discover_and_sync_pod() |
137 | @@ -586,8 +597,8 @@ class TestPodForm(MAASTransactionServerTestCase): | |||
138 | 586 | cpu_speed=Equals(discovered_pod.cpu_speed), | 597 | cpu_speed=Equals(discovered_pod.cpu_speed), |
139 | 587 | zone=Equals(zone), | 598 | zone=Equals(zone), |
140 | 588 | power_type=Equals(pod_info['type']), | 599 | power_type=Equals(pod_info['type']), |
143 | 589 | power_parameters=Equals({}), | 600 | power_parameters=Equals(power_parameters), |
144 | 590 | ip_address=Is(None), | 601 | ip_address=MatchesStructure(ip=Equals(pod_info['ip_address'])), |
145 | 591 | )) | 602 | )) |
146 | 592 | 603 | ||
147 | 593 | def validate_rack_routes(): | 604 | def validate_rack_routes(): |
148 | diff --git a/src/maasserver/models/tests/test_bmc.py b/src/maasserver/models/tests/test_bmc.py | |||
149 | index 9bc3cfb..84db146 100644 | |||
150 | --- a/src/maasserver/models/tests/test_bmc.py | |||
151 | +++ b/src/maasserver/models/tests/test_bmc.py | |||
152 | @@ -1509,8 +1509,8 @@ class TestPodDelete(MAASTransactionServerTestCase): | |||
153 | 1509 | yield pod.async_delete() | 1509 | yield pod.async_delete() |
154 | 1510 | self.assertThat( | 1510 | self.assertThat( |
155 | 1511 | client, MockCalledOnceWith( | 1511 | client, MockCalledOnceWith( |
158 | 1512 | DecomposeMachine, type=pod.power_type, context={}, | 1512 | DecomposeMachine, type=pod.power_type, |
159 | 1513 | pod_id=pod.id, name=pod.name)) | 1513 | context=pod.power_parameters, pod_id=pod.id, name=pod.name)) |
160 | 1514 | decomposable_machine = yield deferToDatabase( | 1514 | decomposable_machine = yield deferToDatabase( |
161 | 1515 | reload_object, decomposable_machine) | 1515 | reload_object, decomposable_machine) |
162 | 1516 | delete_machine = yield deferToDatabase(reload_object, delete_machine) | 1516 | delete_machine = yield deferToDatabase(reload_object, delete_machine) |
163 | diff --git a/src/maasserver/testing/factory.py b/src/maasserver/testing/factory.py | |||
164 | index 0204588..e5bd2b7 100644 | |||
165 | --- a/src/maasserver/testing/factory.py | |||
166 | +++ b/src/maasserver/testing/factory.py | |||
167 | @@ -610,7 +610,10 @@ class Factory(maastesting.factory.Factory): | |||
168 | 610 | if pod_type is None: | 610 | if pod_type is None: |
169 | 611 | pod_type = 'virsh' | 611 | pod_type = 'virsh' |
170 | 612 | if parameters is None: | 612 | if parameters is None: |
172 | 613 | parameters = {} | 613 | parameters = { |
173 | 614 | 'power_address': 'qemu+ssh://{}/system'.format( | ||
174 | 615 | self.make_ip_address()) | ||
175 | 616 | } | ||
176 | 614 | pod = Pod( | 617 | pod = Pod( |
177 | 615 | power_type=pod_type, power_parameters=parameters, | 618 | power_type=pod_type, power_parameters=parameters, |
178 | 616 | ip_address=ip_address, **kwargs) | 619 | ip_address=ip_address, **kwargs) |
179 | diff --git a/src/maasserver/websockets/handlers/tests/test_pod.py b/src/maasserver/websockets/handlers/tests/test_pod.py | |||
180 | index 7539a5a..d3a4621 100644 | |||
181 | --- a/src/maasserver/websockets/handlers/tests/test_pod.py | |||
182 | +++ b/src/maasserver/websockets/handlers/tests/test_pod.py | |||
183 | @@ -9,14 +9,12 @@ import random | |||
184 | 9 | from unittest.mock import MagicMock | 9 | from unittest.mock import MagicMock |
185 | 10 | 10 | ||
186 | 11 | from crochet import wait_for | 11 | from crochet import wait_for |
187 | 12 | from maasserver.enum import NODE_TYPE | ||
188 | 13 | from maasserver.forms import pods | 12 | from maasserver.forms import pods |
189 | 14 | from maasserver.forms.pods import PodForm | 13 | from maasserver.forms.pods import PodForm |
190 | 15 | from maasserver.testing.factory import factory | 14 | from maasserver.testing.factory import factory |
191 | 16 | from maasserver.testing.testcase import MAASTransactionServerTestCase | 15 | from maasserver.testing.testcase import MAASTransactionServerTestCase |
192 | 17 | from maasserver.utils.orm import reload_object | 16 | from maasserver.utils.orm import reload_object |
193 | 18 | from maasserver.utils.threads import deferToDatabase | 17 | from maasserver.utils.threads import deferToDatabase |
194 | 19 | from maasserver.websockets.base import dehydrate_datetime | ||
195 | 20 | from maasserver.websockets.handlers.pod import ( | 18 | from maasserver.websockets.handlers.pod import ( |
196 | 21 | ComposeMachineForm, | 19 | ComposeMachineForm, |
197 | 22 | PodHandler, | 20 | PodHandler, |
198 | @@ -113,116 +111,22 @@ class TestPodHandler(MAASTransactionServerTestCase): | |||
199 | 113 | cpu_speed=random.randint(1000, 3000), local_storage=0) | 111 | cpu_speed=random.randint(1000, 3000), local_storage=0) |
200 | 114 | return composed_machine, pod_hints | 112 | return composed_machine, pod_hints |
201 | 115 | 113 | ||
202 | 116 | def dehydrate_storage_pool(self, pool): | ||
203 | 117 | used = pool.get_used_storage() | ||
204 | 118 | return { | ||
205 | 119 | 'id': pool.pool_id, | ||
206 | 120 | 'name': pool.name, | ||
207 | 121 | 'type': pool.pool_type, | ||
208 | 122 | 'path': pool.path, | ||
209 | 123 | 'total': pool.storage, | ||
210 | 124 | 'used': used, | ||
211 | 125 | 'available': pool.storage - used, | ||
212 | 126 | } | ||
213 | 127 | |||
214 | 128 | def dehydrate_pod(self, pod, admin=True, for_list=True): | ||
215 | 129 | data = { | ||
216 | 130 | "id": pod.id, | ||
217 | 131 | "name": pod.name, | ||
218 | 132 | "cpu_speed": pod.cpu_speed, | ||
219 | 133 | "type": pod.power_type, | ||
220 | 134 | "ip_address": pod.ip_address, | ||
221 | 135 | "updated": dehydrate_datetime(pod.updated), | ||
222 | 136 | "created": dehydrate_datetime(pod.created), | ||
223 | 137 | "composed_machines_count": pod.node_set.filter( | ||
224 | 138 | node_type=NODE_TYPE.MACHINE).count(), | ||
225 | 139 | "total": { | ||
226 | 140 | "cores": pod.cores, | ||
227 | 141 | "memory": pod.memory, | ||
228 | 142 | 'memory_gb': '%.1f' % (pod.memory / 1024.0), | ||
229 | 143 | "local_storage": pod.local_storage, | ||
230 | 144 | 'local_storage_gb': '%.1f' % (pod.local_storage / (1024 ** 3)), | ||
231 | 145 | }, | ||
232 | 146 | "used": { | ||
233 | 147 | "cores": pod.get_used_cores(), | ||
234 | 148 | "memory": pod.get_used_memory(), | ||
235 | 149 | 'memory_gb': '%.1f' % (pod.get_used_memory() / 1024.0), | ||
236 | 150 | "local_storage": pod.get_used_local_storage(), | ||
237 | 151 | 'local_storage_gb': '%.1f' % ( | ||
238 | 152 | pod.get_used_local_storage() / (1024 ** 3)), | ||
239 | 153 | }, | ||
240 | 154 | "available": { | ||
241 | 155 | "cores": pod.cores - pod.get_used_cores(), | ||
242 | 156 | "memory": pod.memory - pod.get_used_memory(), | ||
243 | 157 | 'memory_gb': '%.1f' % ( | ||
244 | 158 | (pod.memory - pod.get_used_memory()) / 1024.0), | ||
245 | 159 | "local_storage": ( | ||
246 | 160 | pod.local_storage - pod.get_used_local_storage()), | ||
247 | 161 | 'local_storage_gb': '%.1f' % ( | ||
248 | 162 | (pod.local_storage - pod.get_used_local_storage()) / ( | ||
249 | 163 | (1024 ** 3))), | ||
250 | 164 | }, | ||
251 | 165 | "default_pool": pod.default_pool.id, | ||
252 | 166 | "capabilities": pod.capabilities, | ||
253 | 167 | "architectures": pod.architectures, | ||
254 | 168 | "hints": { | ||
255 | 169 | 'cores': pod.hints.cores, | ||
256 | 170 | 'cpu_speed': pod.hints.cpu_speed, | ||
257 | 171 | 'memory': pod.hints.memory, | ||
258 | 172 | 'memory_gb': '%.1f' % (pod.hints.memory / 1024.0), | ||
259 | 173 | 'local_storage': pod.hints.local_storage, | ||
260 | 174 | 'local_storage_gb': '%.1f' % ( | ||
261 | 175 | pod.hints.local_storage / (1024 ** 3)), | ||
262 | 176 | 'local_disks': pod.hints.local_disks, | ||
263 | 177 | 'iscsi_storage': pod.hints.iscsi_storage, | ||
264 | 178 | 'iscsi_storage_gb': '%.1f' % ( | ||
265 | 179 | pod.hints.iscsi_storage / (1024 ** 3)), | ||
266 | 180 | }, | ||
267 | 181 | "tags": pod.tags, | ||
268 | 182 | "zone": pod.zone.id, | ||
269 | 183 | "cpu_over_commit_ratio": pod.cpu_over_commit_ratio, | ||
270 | 184 | "memory_over_commit_ratio": pod.memory_over_commit_ratio | ||
271 | 185 | } | ||
272 | 186 | if Capabilities.FIXED_LOCAL_STORAGE in pod.capabilities: | ||
273 | 187 | data['total']['local_disks'] = pod.local_disks | ||
274 | 188 | data['used']['local_disks'] = pod.get_used_local_disks() | ||
275 | 189 | data['available']['local_disks'] = ( | ||
276 | 190 | pod.local_disks - pod.get_used_local_disks()) | ||
277 | 191 | if Capabilities.ISCSI_STORAGE in pod.capabilities: | ||
278 | 192 | data['total']['iscsi_storage'] = pod.iscsi_storage | ||
279 | 193 | data['total']['iscsi_storage_gb'] = '%.1f' % ( | ||
280 | 194 | pod.iscsi_storage / (1024 ** 3)) | ||
281 | 195 | data['used']['iscsi_storage'] = pod.get_used_iscsi_storage() | ||
282 | 196 | data['used']['iscsi_storage_gb'] = '%.1f' % ( | ||
283 | 197 | pod.get_used_iscsi_storage() / (1024 ** 3)) | ||
284 | 198 | data['available']['iscsi_storage'] = ( | ||
285 | 199 | pod.iscsi_storage - pod.get_used_iscsi_storage()) | ||
286 | 200 | data['available']['iscsi_storage_gb'] = '%.1f' % ( | ||
287 | 201 | (pod.iscsi_storage - pod.get_used_iscsi_storage()) / ( | ||
288 | 202 | 1024 ** 3)) | ||
289 | 203 | if admin: | ||
290 | 204 | data.update(pod.power_parameters) | ||
291 | 205 | if not for_list and pod.storage_pools.all(): | ||
292 | 206 | data["storage_pools"] = [ | ||
293 | 207 | self.dehydrate_storage_pool(pool) | ||
294 | 208 | for pool in pod.storage_pools.all() | ||
295 | 209 | ] | ||
296 | 210 | data["default_storage_pool"] = pod.default_storage_pool.pool_id | ||
297 | 211 | return data | ||
298 | 212 | |||
299 | 213 | def test_get(self): | 114 | def test_get(self): |
300 | 214 | admin = factory.make_admin() | 115 | admin = factory.make_admin() |
301 | 215 | handler = PodHandler(admin, {}) | 116 | handler = PodHandler(admin, {}) |
302 | 216 | pod = self.make_pod_with_hints() | 117 | pod = self.make_pod_with_hints() |
304 | 217 | expected_data = self.dehydrate_pod(pod, for_list=False) | 118 | expected_data = handler.full_dehydrate(pod) |
305 | 218 | result = handler.get({"id": pod.id}) | 119 | result = handler.get({"id": pod.id}) |
306 | 120 | self.assertItemsEqual(expected_data.keys(), result.keys()) | ||
307 | 121 | for key in expected_data: | ||
308 | 122 | self.assertEqual(expected_data[key], result[key], key) | ||
309 | 219 | self.assertThat(result, Equals(expected_data)) | 123 | self.assertThat(result, Equals(expected_data)) |
310 | 220 | 124 | ||
311 | 221 | def test_get_as_standard_user(self): | 125 | def test_get_as_standard_user(self): |
312 | 222 | user = factory.make_User() | 126 | user = factory.make_User() |
313 | 223 | handler = PodHandler(user, {}) | 127 | handler = PodHandler(user, {}) |
314 | 224 | pod = self.make_pod_with_hints() | 128 | pod = self.make_pod_with_hints() |
316 | 225 | expected_data = self.dehydrate_pod(pod, admin=False, for_list=False) | 129 | expected_data = handler.full_dehydrate(pod) |
317 | 226 | result = handler.get({"id": pod.id}) | 130 | result = handler.get({"id": pod.id}) |
318 | 227 | self.assertThat(result, Equals(expected_data)) | 131 | self.assertThat(result, Equals(expected_data)) |
319 | 228 | 132 | ||
320 | @@ -230,7 +134,7 @@ class TestPodHandler(MAASTransactionServerTestCase): | |||
321 | 230 | admin = factory.make_admin() | 134 | admin = factory.make_admin() |
322 | 231 | handler = PodHandler(admin, {}) | 135 | handler = PodHandler(admin, {}) |
323 | 232 | pod = self.make_pod_with_hints() | 136 | pod = self.make_pod_with_hints() |
325 | 233 | expected_data = [self.dehydrate_pod(pod, for_list=True)] | 137 | expected_data = [handler.full_dehydrate(pod, for_list=True)] |
326 | 234 | result = handler.list({"id": pod.id}) | 138 | result = handler.list({"id": pod.id}) |
327 | 235 | self.assertThat(result, Equals(expected_data)) | 139 | self.assertThat(result, Equals(expected_data)) |
328 | 236 | 140 | ||
329 | @@ -244,10 +148,13 @@ class TestPodHandler(MAASTransactionServerTestCase): | |||
330 | 244 | PodForm, 'discover_and_sync_pod') | 148 | PodForm, 'discover_and_sync_pod') |
331 | 245 | mock_discover_and_sync_pod.return_value = succeed(pod) | 149 | mock_discover_and_sync_pod.return_value = succeed(pod) |
332 | 246 | expected_data = yield deferToDatabase( | 150 | expected_data = yield deferToDatabase( |
334 | 247 | self.dehydrate_pod, pod, for_list=False) | 151 | handler.full_dehydrate, pod, for_list=False) |
335 | 248 | observed_data = yield handler.refresh({"id": pod.id}) | 152 | observed_data = yield handler.refresh({"id": pod.id}) |
336 | 249 | self.assertThat( | 153 | self.assertThat( |
337 | 250 | mock_discover_and_sync_pod, MockCalledOnceWith()) | 154 | mock_discover_and_sync_pod, MockCalledOnceWith()) |
338 | 155 | self.assertItemsEqual(expected_data.keys(), observed_data.keys()) | ||
339 | 156 | for key in expected_data: | ||
340 | 157 | self.assertEqual(expected_data[key], observed_data[key], key) | ||
341 | 251 | self.assertEqual(expected_data, observed_data) | 158 | self.assertEqual(expected_data, observed_data) |
342 | 252 | 159 | ||
343 | 253 | @wait_for_reactor | 160 | @wait_for_reactor |
+1