1.1.37
by James Page
Import upstream version 2014.1~b3 |
1 |
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
2 |
# not use this file except in compliance with the License. You may obtain
|
|
3 |
# a copy of the License at
|
|
4 |
#
|
|
5 |
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6 |
#
|
|
7 |
# Unless required by applicable law or agreed to in writing, software
|
|
8 |
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
9 |
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
10 |
# License for the specific language governing permissions and limitations
|
|
11 |
# under the License.
|
|
12 |
||
13 |
||
14 |
from django.core.urlresolvers import reverse |
|
15 |
from django import http |
|
16 |
from mox import IsA # noqa |
|
17 |
||
18 |
from openstack_dashboard import api |
|
19 |
from openstack_dashboard.dashboards.admin.aggregates import constants |
|
20 |
from openstack_dashboard.dashboards.admin.aggregates import workflows |
|
21 |
from openstack_dashboard.test import helpers as test |
|
22 |
||
23 |
||
24 |
class BaseAggregateWorkflowTests(test.BaseAdminViewTests): |
|
25 |
||
26 |
def _get_create_workflow_data(self, aggregate, hosts=None): |
|
27 |
aggregate_info = {"name": aggregate.name, |
|
28 |
"availability_zone": aggregate.availability_zone} |
|
29 |
||
30 |
if hosts: |
|
31 |
compute_hosts = [] |
|
32 |
for host in hosts: |
|
33 |
if host.service == 'compute': |
|
34 |
compute_hosts.append(host) |
|
35 |
||
36 |
host_field_name = 'add_host_to_aggregate_role_member' |
|
37 |
aggregate_info[host_field_name] = \ |
|
38 |
[h.host_name for h in compute_hosts] |
|
39 |
||
40 |
return aggregate_info |
|
41 |
||
42 |
def _get_manage_workflow_data(self, aggregate, hosts=None, ): |
|
43 |
aggregate_info = {"id": aggregate.id} |
|
44 |
||
45 |
if hosts: |
|
46 |
compute_hosts = [] |
|
47 |
for host in hosts: |
|
48 |
if host.service == 'compute': |
|
49 |
compute_hosts.append(host) |
|
50 |
||
51 |
host_field_name = 'add_host_to_aggregate_role_member' |
|
52 |
aggregate_info[host_field_name] = \ |
|
53 |
[h.host_name for h in compute_hosts] |
|
54 |
||
55 |
return aggregate_info |
|
56 |
||
57 |
||
58 |
class CreateAggregateWorkflowTests(BaseAggregateWorkflowTests): |
|
59 |
||
60 |
@test.create_stubs({api.nova: ('host_list', ), }) |
|
61 |
def test_workflow_get(self): |
|
62 |
||
63 |
api.nova.host_list(IsA(http.HttpRequest)).AndReturn(self.hosts.list()) |
|
64 |
self.mox.ReplayAll() |
|
65 |
||
66 |
url = reverse(constants.AGGREGATES_CREATE_URL) |
|
67 |
res = self.client.get(url) |
|
68 |
workflow = res.context['workflow'] |
|
69 |
||
70 |
self.assertTemplateUsed(res, constants.AGGREGATES_CREATE_VIEW_TEMPLATE) |
|
71 |
self.assertEqual(workflow.name, workflows.CreateAggregateWorkflow.name) |
|
72 |
self.assertQuerysetEqual(workflow.steps, |
|
73 |
['<SetAggregateInfoStep: set_aggregate_info>', |
|
74 |
'<AddHostsToAggregateStep: add_host_to_aggregate>']) |
|
75 |
||
76 |
@test.create_stubs({api.nova: ('host_list', 'aggregate_details_list', |
|
77 |
'aggregate_create'), }) |
|
78 |
def test_create_aggregate(self): |
|
79 |
||
80 |
aggregate = self.aggregates.first() |
|
81 |
||
82 |
api.nova.host_list(IsA(http.HttpRequest)).AndReturn(self.hosts.list()) |
|
83 |
api.nova.aggregate_details_list(IsA(http.HttpRequest)).AndReturn([]) |
|
84 |
||
85 |
workflow_data = self._get_create_workflow_data(aggregate) |
|
86 |
api.nova.aggregate_create(IsA(http.HttpRequest), |
|
87 |
name=workflow_data['name'], |
|
88 |
availability_zone= |
|
89 |
workflow_data['availability_zone'])\ |
|
90 |
.AndReturn(aggregate) |
|
91 |
||
92 |
self.mox.ReplayAll() |
|
93 |
||
94 |
url = reverse(constants.AGGREGATES_CREATE_URL) |
|
95 |
res = self.client.post(url, workflow_data) |
|
96 |
||
97 |
self.assertNoFormErrors(res) |
|
98 |
self.assertRedirectsNoFollow(res, |
|
99 |
reverse(constants.AGGREGATES_INDEX_URL)) |
|
100 |
||
101 |
@test.create_stubs({api.nova: ('host_list', |
|
102 |
'aggregate_details_list', |
|
103 |
'aggregate_create', |
|
104 |
'add_host_to_aggregate'), }) |
|
105 |
def test_create_aggregate_with_hosts(self): |
|
106 |
aggregate = self.aggregates.first() |
|
107 |
hosts = self.hosts.list() |
|
108 |
||
109 |
api.nova.host_list(IsA(http.HttpRequest)).AndReturn(self.hosts.list()) |
|
110 |
api.nova.aggregate_details_list(IsA(http.HttpRequest)).AndReturn([]) |
|
111 |
||
112 |
workflow_data = self._get_create_workflow_data(aggregate, hosts) |
|
113 |
api.nova.aggregate_create(IsA(http.HttpRequest), |
|
114 |
name=workflow_data['name'], |
|
115 |
availability_zone= |
|
116 |
workflow_data['availability_zone'])\ |
|
117 |
.AndReturn(aggregate) |
|
118 |
||
119 |
compute_hosts = [] |
|
120 |
for host in hosts: |
|
121 |
if host.service == 'compute': |
|
122 |
compute_hosts.append(host) |
|
123 |
||
124 |
for host in compute_hosts: |
|
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
125 |
api.nova.add_host_to_aggregate( |
126 |
IsA(http.HttpRequest), |
|
127 |
aggregate.id, host.host_name).InAnyOrder() |
|
1.1.37
by James Page
Import upstream version 2014.1~b3 |
128 |
|
129 |
self.mox.ReplayAll() |
|
130 |
||
131 |
url = reverse(constants.AGGREGATES_CREATE_URL) |
|
132 |
res = self.client.post(url, workflow_data) |
|
133 |
||
134 |
self.assertNoFormErrors(res) |
|
135 |
self.assertRedirectsNoFollow(res, |
|
136 |
reverse(constants.AGGREGATES_INDEX_URL)) |
|
137 |
||
138 |
@test.create_stubs({api.nova: ('host_list', 'aggregate_details_list', ), }) |
|
139 |
def test_host_list_nova_compute(self): |
|
140 |
||
141 |
hosts = self.hosts.list() |
|
142 |
compute_hosts = [] |
|
143 |
||
144 |
for host in hosts: |
|
145 |
if host.service == 'compute': |
|
146 |
compute_hosts.append(host) |
|
147 |
||
148 |
api.nova.host_list(IsA(http.HttpRequest)).AndReturn(self.hosts.list()) |
|
149 |
||
150 |
self.mox.ReplayAll() |
|
151 |
||
152 |
url = reverse(constants.AGGREGATES_CREATE_URL) |
|
153 |
res = self.client.get(url) |
|
154 |
workflow = res.context['workflow'] |
|
155 |
step = workflow.get_step("add_host_to_aggregate") |
|
156 |
field_name = step.get_member_field_name('member') |
|
157 |
self.assertEqual(len(step.action.fields[field_name].choices), |
|
158 |
len(compute_hosts)) |
|
159 |
||
160 |
||
161 |
class AggregatesViewTests(test.BaseAdminViewTests): |
|
162 |
||
163 |
@test.create_stubs({api.nova: ('aggregate_details_list', |
|
164 |
'availability_zone_list',), }) |
|
165 |
def test_index(self): |
|
166 |
api.nova.aggregate_details_list(IsA(http.HttpRequest)) \ |
|
167 |
.AndReturn(self.aggregates.list()) |
|
168 |
api.nova.availability_zone_list(IsA(http.HttpRequest), detailed=True) \ |
|
169 |
.AndReturn(self.availability_zones.list()) |
|
170 |
self.mox.ReplayAll() |
|
171 |
||
172 |
res = self.client.get(reverse(constants.AGGREGATES_INDEX_URL)) |
|
173 |
self.assertTemplateUsed(res, constants.AGGREGATES_INDEX_VIEW_TEMPLATE) |
|
174 |
self.assertItemsEqual(res.context['host_aggregates_table'].data, |
|
175 |
self.aggregates.list()) |
|
176 |
self.assertItemsEqual(res.context['availability_zones_table'].data, |
|
177 |
self.availability_zones.list()) |
|
178 |
||
179 |
@test.create_stubs({api.nova: ('aggregate_update', 'aggregate_get',), }) |
|
180 |
def _test_generic_update_aggregate(self, form_data, aggregate, |
|
181 |
error_count=0, |
|
182 |
expected_error_message=None): |
|
183 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id))\ |
|
184 |
.AndReturn(aggregate) |
|
185 |
if not expected_error_message: |
|
186 |
az = form_data['availability_zone'] |
|
187 |
aggregate_data = {'name': form_data['name'], |
|
188 |
'availability_zone': az} |
|
189 |
api.nova.aggregate_update(IsA(http.HttpRequest), str(aggregate.id), |
|
190 |
aggregate_data) |
|
191 |
self.mox.ReplayAll() |
|
192 |
||
193 |
res = self.client.post(reverse(constants.AGGREGATES_UPDATE_URL, |
|
194 |
args=[aggregate.id]), |
|
195 |
form_data) |
|
196 |
||
197 |
if not expected_error_message: |
|
198 |
self.assertNoFormErrors(res) |
|
199 |
self.assertRedirectsNoFollow(res, |
|
200 |
reverse(constants.AGGREGATES_INDEX_URL)) |
|
201 |
else: |
|
202 |
self.assertFormErrors(res, error_count, expected_error_message) |
|
203 |
||
204 |
def test_update_aggregate(self): |
|
205 |
aggregate = self.aggregates.first() |
|
206 |
form_data = {'id': aggregate.id, |
|
207 |
'name': 'my_new_name', |
|
208 |
'availability_zone': 'my_new_zone'} |
|
209 |
||
210 |
self._test_generic_update_aggregate(form_data, aggregate) |
|
211 |
||
212 |
def test_update_aggregate_fails_missing_fields(self): |
|
213 |
aggregate = self.aggregates.first() |
|
214 |
form_data = {'id': aggregate.id} |
|
215 |
||
216 |
self._test_generic_update_aggregate(form_data, aggregate, 1, |
|
217 |
u'This field is required') |
|
218 |
||
219 |
||
220 |
class ManageHostsTests(test.BaseAdminViewTests): |
|
221 |
||
1.1.38
by James Page
Import upstream version 2014.1~rc1 |
222 |
@test.create_stubs({api.nova: ('aggregate_get', 'host_list')}) |
1.1.37
by James Page
Import upstream version 2014.1~b3 |
223 |
def test_manage_hosts(self): |
224 |
aggregate = self.aggregates.first() |
|
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
225 |
|
1.1.38
by James Page
Import upstream version 2014.1~rc1 |
226 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
227 |
.AndReturn(aggregate) |
|
228 |
api.nova.host_list(IsA(http.HttpRequest)) \ |
|
229 |
.AndReturn(self.hosts.list()) |
|
230 |
self.mox.ReplayAll() |
|
231 |
||
1.1.37
by James Page
Import upstream version 2014.1~b3 |
232 |
res = self.client.get(reverse(constants.AGGREGATES_MANAGE_HOSTS_URL, |
233 |
args=[aggregate.id])) |
|
234 |
self.assertEqual(res.status_code, 200) |
|
235 |
self.assertTemplateUsed(res, |
|
236 |
constants.AGGREGATES_MANAGE_HOSTS_TEMPLATE) |
|
237 |
||
238 |
@test.create_stubs({api.nova: ('aggregate_get', 'add_host_to_aggregate', |
|
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
239 |
'remove_host_from_aggregate', |
1.1.37
by James Page
Import upstream version 2014.1~b3 |
240 |
'host_list')}) |
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
241 |
def test_manage_hosts_update_add_remove_not_empty_aggregate(self): |
1.1.37
by James Page
Import upstream version 2014.1~b3 |
242 |
aggregate = self.aggregates.first() |
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
243 |
aggregate.hosts = ['host1', 'host2'] |
244 |
host = self.hosts.list()[0] |
|
1.1.37
by James Page
Import upstream version 2014.1~b3 |
245 |
form_data = {'manageaggregatehostsaction_role_member': |
246 |
[host.host_name]} |
|
247 |
||
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
248 |
api.nova.remove_host_from_aggregate(IsA(http.HttpRequest), |
249 |
str(aggregate.id), |
|
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
250 |
'host2').InAnyOrder() |
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
251 |
api.nova.remove_host_from_aggregate(IsA(http.HttpRequest), |
252 |
str(aggregate.id), |
|
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
253 |
'host1').InAnyOrder() |
1.1.37
by James Page
Import upstream version 2014.1~b3 |
254 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
255 |
.AndReturn(aggregate) |
|
256 |
api.nova.host_list(IsA(http.HttpRequest)) \ |
|
257 |
.AndReturn(self.hosts.list()) |
|
258 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
|
259 |
.AndReturn(aggregate) |
|
260 |
api.nova.add_host_to_aggregate(IsA(http.HttpRequest), |
|
261 |
str(aggregate.id), host.host_name) |
|
262 |
self.mox.ReplayAll() |
|
263 |
||
264 |
res = self.client.post(reverse(constants.AGGREGATES_MANAGE_HOSTS_URL, |
|
265 |
args=[aggregate.id]), |
|
266 |
form_data) |
|
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
267 |
self.assertNoFormErrors(res) |
268 |
self.assertRedirectsNoFollow(res, |
|
269 |
reverse(constants.AGGREGATES_INDEX_URL)) |
|
270 |
||
271 |
@test.create_stubs({api.nova: ('aggregate_get', 'add_host_to_aggregate', |
|
272 |
'remove_host_from_aggregate', |
|
273 |
'host_list')}) |
|
274 |
def test_manage_hosts_update_add_not_empty_aggregate_should_fail(self): |
|
275 |
aggregate = self.aggregates.first() |
|
276 |
aggregate.hosts = ['devstack001'] |
|
277 |
host1 = self.hosts.list()[0] |
|
278 |
host3 = self.hosts.list()[2] |
|
279 |
form_data = {'manageaggregatehostsaction_role_member': |
|
280 |
[host1.host_name, host3.host_name]} |
|
281 |
||
282 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
|
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
283 |
.InAnyOrder().AndReturn(aggregate) |
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
284 |
api.nova.host_list(IsA(http.HttpRequest)) \ |
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
285 |
.InAnyOrder().AndReturn(self.hosts.list()) |
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
286 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
287 |
.InAnyOrder().AndReturn(aggregate) |
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
288 |
api.nova.add_host_to_aggregate(IsA(http.HttpRequest), |
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
289 |
str(aggregate.id), host3.host_name) \ |
290 |
.InAnyOrder().AndRaise(self.exceptions.nova) |
|
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
291 |
self.mox.ReplayAll() |
292 |
||
293 |
res = self.client.post(reverse(constants.AGGREGATES_MANAGE_HOSTS_URL, |
|
294 |
args=[aggregate.id]), |
|
295 |
form_data) |
|
296 |
self.assertNoFormErrors(res) |
|
297 |
self.assertMessageCount(error=2) |
|
298 |
self.assertRedirectsNoFollow(res, |
|
299 |
reverse(constants.AGGREGATES_INDEX_URL)) |
|
300 |
||
301 |
@test.create_stubs({api.nova: ('aggregate_get', 'add_host_to_aggregate', |
|
302 |
'remove_host_from_aggregate', |
|
303 |
'host_list')}) |
|
304 |
def test_manage_hosts_update_clean_not_empty_aggregate_should_fail(self): |
|
305 |
aggregate = self.aggregates.first() |
|
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
306 |
aggregate.hosts = ['host2'] |
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
307 |
form_data = {'manageaggregatehostsaction_role_member': |
308 |
[]}
|
|
309 |
||
310 |
api.nova.remove_host_from_aggregate(IsA(http.HttpRequest), |
|
311 |
str(aggregate.id), |
|
312 |
'host2')\ |
|
313 |
.AndRaise(self.exceptions.nova) |
|
314 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
|
315 |
.AndReturn(aggregate) |
|
316 |
api.nova.host_list(IsA(http.HttpRequest)) \ |
|
317 |
.AndReturn(self.hosts.list()) |
|
318 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
|
319 |
.AndReturn(aggregate) |
|
320 |
self.mox.ReplayAll() |
|
321 |
||
322 |
res = self.client.post(reverse(constants.AGGREGATES_MANAGE_HOSTS_URL, |
|
323 |
args=[aggregate.id]), |
|
324 |
form_data) |
|
325 |
self.assertNoFormErrors(res) |
|
326 |
self.assertMessageCount(error=2) |
|
327 |
self.assertRedirectsNoFollow(res, |
|
328 |
reverse(constants.AGGREGATES_INDEX_URL)) |
|
329 |
||
330 |
@test.create_stubs({api.nova: ('aggregate_get', 'add_host_to_aggregate', |
|
331 |
'remove_host_from_aggregate', |
|
332 |
'host_list')}) |
|
333 |
def _test_manage_hosts_update(self, |
|
334 |
host, |
|
335 |
aggregate, |
|
336 |
form_data, |
|
337 |
addAggregate=False, |
|
338 |
cleanAggregates=False): |
|
339 |
if cleanAggregates: |
|
340 |
api.nova.remove_host_from_aggregate(IsA(http.HttpRequest), |
|
341 |
str(aggregate.id), |
|
1.1.42
by Chuck Short
Import upstream version 2014.2~b2 |
342 |
'host3').InAnyOrder() |
343 |
api.nova.remove_host_from_aggregate(IsA(http.HttpRequest), |
|
344 |
str(aggregate.id), |
|
345 |
'host2').InAnyOrder() |
|
346 |
api.nova.remove_host_from_aggregate(IsA(http.HttpRequest), |
|
347 |
str(aggregate.id), |
|
348 |
'host1').InAnyOrder() |
|
1.1.39
by Chuck Short
Import upstream version 2014.1~rc2 |
349 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
350 |
.AndReturn(aggregate) |
|
351 |
api.nova.host_list(IsA(http.HttpRequest)) \ |
|
352 |
.AndReturn(self.hosts.list()) |
|
353 |
api.nova.aggregate_get(IsA(http.HttpRequest), str(aggregate.id)) \ |
|
354 |
.AndReturn(aggregate) |
|
355 |
if addAggregate: |
|
356 |
api.nova.add_host_to_aggregate(IsA(http.HttpRequest), |
|
357 |
str(aggregate.id), |
|
358 |
host.host_name) |
|
359 |
self.mox.ReplayAll() |
|
360 |
||
361 |
res = self.client.post(reverse(constants.AGGREGATES_MANAGE_HOSTS_URL, |
|
362 |
args=[aggregate.id]), |
|
363 |
form_data) |
|
364 |
self.assertNoFormErrors(res) |
|
365 |
self.assertRedirectsNoFollow(res, |
|
366 |
reverse(constants.AGGREGATES_INDEX_URL)) |
|
367 |
||
368 |
def test_manage_hosts_update_nothing_not_empty_aggregate(self): |
|
369 |
aggregate = self.aggregates.first() |
|
370 |
host = self.hosts.list()[0] |
|
371 |
aggregate.hosts = [host.host_name] |
|
372 |
form_data = {'manageaggregatehostsaction_role_member': |
|
373 |
[host.host_name]} |
|
374 |
self._test_manage_hosts_update(host, |
|
375 |
aggregate, |
|
376 |
form_data, |
|
377 |
addAggregate=False) |
|
378 |
||
379 |
def test_manage_hosts_update_nothing_empty_aggregate(self): |
|
380 |
aggregate = self.aggregates.first() |
|
381 |
aggregate.hosts = [] |
|
382 |
form_data = {'manageaggregatehostsaction_role_member': |
|
383 |
[]}
|
|
384 |
self._test_manage_hosts_update(None, |
|
385 |
aggregate, |
|
386 |
form_data, |
|
387 |
addAggregate=False) |
|
388 |
||
389 |
def test_manage_hosts_update_add_empty_aggregate(self): |
|
390 |
aggregate = self.aggregates.first() |
|
391 |
aggregate.hosts = [] |
|
392 |
host = self.hosts.list()[0] |
|
393 |
form_data = {'manageaggregatehostsaction_role_member': |
|
394 |
[host.host_name]} |
|
395 |
self._test_manage_hosts_update(host, |
|
396 |
aggregate, |
|
397 |
form_data, |
|
398 |
addAggregate=True) |
|
399 |
||
400 |
def test_manage_hosts_update_add_not_empty_aggregate(self): |
|
401 |
aggregate = self.aggregates.first() |
|
402 |
aggregate.hosts = ['devstack001'] |
|
403 |
host1 = self.hosts.list()[0] |
|
404 |
host3 = self.hosts.list()[2] |
|
405 |
form_data = {'manageaggregatehostsaction_role_member': |
|
406 |
[host1.host_name, host3.host_name]} |
|
407 |
self._test_manage_hosts_update(host3, |
|
408 |
aggregate, |
|
409 |
form_data, |
|
410 |
addAggregate=True) |
|
411 |
||
412 |
def test_manage_hosts_update_clean_not_empty_aggregate(self): |
|
413 |
aggregate = self.aggregates.first() |
|
414 |
aggregate.hosts = ['host1', 'host2', 'host3'] |
|
415 |
form_data = {'manageaggregatehostsaction_role_member': |
|
416 |
[]}
|
|
417 |
self._test_manage_hosts_update(None, |
|
418 |
aggregate, |
|
419 |
form_data, |
|
420 |
addAggregate=False, |
|
421 |
cleanAggregates=True) |