1 # Copyright (C) 2010 Oregon State University et al.
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 from datetime
import datetime
21 from django
.conf
import settings
22 from django
.contrib
.auth
.models
import User
, Group
23 from django
.test
import TestCase
24 from django
.test
.client
import Client
25 from django_test_tools
.users
import UserTestMixin
26 from django_test_tools
.views
import ViewTestMixin
27 from ganeti
.models
import SSHKey
, Profile
29 from object_permissions
import *
31 from ganeti
.tests
.rapi_proxy
import RapiProxy
, INFO
, NODES
, NODES_BULK
, JOB_RUNNING
, JOB
32 from ganeti
import models
33 Cluster
= models
.Cluster
34 VirtualMachine
= models
.VirtualMachine
40 __all__
= ('TestClusterViews', 'TestClusterModel')
43 global user
, user1
, group
, cluster_admin
, superuser
47 class TestClusterModel(TestCase
):
51 models
.client
.GanetiRapiClient
= RapiProxy
54 Profile
.objects
.all().delete()
55 User
.objects
.all().delete()
56 Quota
.objects
.all().delete()
57 VirtualMachine
.objects
.all().delete()
58 Node
.objects
.all().delete()
59 Cluster
.objects
.all().delete()
61 def test_trivial(self
):
63 Test creating a Cluster Object
69 test saving a cluster object
72 * object is saved and queryable
77 self
.assert_(cluster
.hash)
79 cluster
= Cluster(hostname
='foo.fake.hostname', slug
='different')
81 self
.assert_(cluster
.hash)
83 def test_parse_info(self
):
85 Test parsing values from cached info
88 * mtime and ctime are parsed
89 * ram, virtual_cpus, and disksize are parsed
91 cluster
= Cluster(hostname
='foo.fake.hostname')
95 self
.assertEqual(cluster
.ctime
, datetime
.fromtimestamp(1270685309.818239))
96 self
.assertEqual(cluster
.mtime
, datetime
.fromtimestamp(1283552454.2998919))
98 def test_get_quota(self
):
100 Tests cluster.get_quota() method
103 * if no user is passed, return default quota values
104 * if user has quota, return values from Quota
105 * if user doesn't have quota, return default cluster values
107 default_quota
= {'default':1, 'ram':1, 'virtual_cpus':None, 'disk':3}
108 user_quota
= {'default':0, 'ram':4, 'virtual_cpus':5, 'disk':None}
110 cluster
= Cluster(hostname
='foo.fake.hostname')
111 cluster
.__dict
__.update(default_quota
)
113 user
= User(username
='tester')
117 self
.assertEqual(default_quota
, cluster
.get_quota())
119 # user without quota, defaults to default
120 self
.assertEqual(default_quota
, cluster
.get_quota(user
.get_profile()))
122 # user with custom quota
123 quota
= Quota(cluster
=cluster
, user
=user
.get_profile())
124 quota
.__dict
__.update(user_quota
)
126 self
.assertEqual(user_quota
, cluster
.get_quota(user
.get_profile()))
128 def test_set_quota(self
):
130 Tests cluster.set_quota()
133 * passing values with no quota, creates a new quota object
134 * passing values with an existing quota, updates it.
135 * passing a None with an existing quota deletes it
136 * passing a None with no quota, does nothing
138 default_quota
= {'default':1,'ram':1, 'virtual_cpus':None, 'disk':3}
139 user_quota
= {'default':0, 'ram':4, 'virtual_cpus':5, 'disk':None}
140 user_quota2
= {'default':0, 'ram':7, 'virtual_cpus':8, 'disk':9}
142 cluster
= Cluster(hostname
='foo.fake.hostname')
143 cluster
.__dict
__.update(default_quota
)
145 user
= User(username
='tester')
149 cluster
.set_quota(user
.get_profile(), user_quota
)
150 query
= Quota
.objects
.filter(cluster
=cluster
, user
=user
.get_profile())
151 self
.assert_(query
.exists())
152 self
.assertEqual(user_quota
, cluster
.get_quota(user
.get_profile()))
154 # update quota with new values
155 cluster
.set_quota(user
.get_profile(), user_quota2
)
156 query
= Quota
.objects
.filter(cluster
=cluster
, user
=user
.get_profile())
157 self
.assertEqual(1, query
.count())
158 self
.assertEqual(user_quota2
, cluster
.get_quota(user
.get_profile()))
161 cluster
.set_quota(user
.get_profile(), None)
162 query
= Quota
.objects
.filter(cluster
=cluster
, user
=user
.get_profile())
163 self
.assertFalse(query
.exists())
164 self
.assertEqual(default_quota
, cluster
.get_quota(user
.get_profile()))
166 def test_sync_virtual_machines(self
):
168 Tests synchronizing cached virtuals machines (stored in db) with info
169 the ganeti cluster is storing
172 * VMs no longer in ganeti are deleted
173 * VMs missing from the database are added
175 cluster
= Cluster(hostname
='ganeti.osuosl.test')
177 vm_missing
= 'gimager.osuosl.bak'
178 vm_current
= VirtualMachine(cluster
=cluster
, hostname
='gimager2.osuosl.bak')
179 vm_removed
= VirtualMachine(cluster
=cluster
, hostname
='does.not.exist.org')
183 cluster
.sync_virtual_machines()
184 self
.assert_(VirtualMachine
.objects
.get(cluster
=cluster
, hostname
=vm_missing
), 'missing vm was not created')
185 self
.assert_(VirtualMachine
.objects
.get(cluster
=cluster
, hostname
=vm_current
.hostname
), 'previously existing vm was not created')
186 self
.assert_(VirtualMachine
.objects
.filter(cluster
=cluster
, hostname
=vm_removed
.hostname
), 'vm not present in ganeti was not removed from db, even though remove flag was false')
188 cluster
.sync_virtual_machines(True)
189 self
.assertFalse(VirtualMachine
.objects
.filter(cluster
=cluster
, hostname
=vm_removed
.hostname
), 'vm not present in ganeti was not removed from db')
191 def test_sync_nodes(self
):
193 Tests synchronizing cached Nodes (stored in db) with info
194 the ganeti cluster is storing
197 * Node no longer in ganeti are deleted
198 * Nodes missing from the database are added
200 cluster
= Cluster
.objects
.create(hostname
='ganeti.osuosl.test')
201 node_missing
= 'gtest1.osuosl.bak'
202 node_current
= Node
.objects
.create(cluster
=cluster
, hostname
='gtest2.osuosl.bak')
203 node_removed
= Node
.objects
.create(cluster
=cluster
, hostname
='does.not.exist.org')
206 self
.assert_(Node
.objects
.get(cluster
=cluster
, hostname
=node_missing
), 'missing node was not created')
207 self
.assert_(Node
.objects
.get(cluster
=cluster
, hostname
=node_current
.hostname
), 'previously existing node was not created')
208 self
.assert_(Node
.objects
.filter(cluster
=cluster
, hostname
=node_removed
.hostname
), 'node not present in ganeti was not removed from db, even though remove flag was false')
210 cluster
.sync_nodes(True)
211 self
.assertFalse(Node
.objects
.filter(cluster
=cluster
, hostname
=node_removed
.hostname
), 'node not present in ganeti was not removed from db')
214 def test_missing_in_database(self
):
216 Tests missing_in_ganeti property
218 cluster
= Cluster(hostname
='ganeti.osuosl.test')
220 vm_current
= VirtualMachine(cluster
=cluster
, hostname
='gimager2.osuosl.bak')
221 vm_removed
= VirtualMachine(cluster
=cluster
, hostname
='does.not.exist.org')
225 self
.assertEqual([u
'gimager.osuosl.bak'], cluster
.missing_in_db
)
227 def test_missing_in_ganeti(self
):
229 Tests missing_in_ganeti property
231 cluster
= Cluster(hostname
='ganeti.osuosl.test')
233 vm_current
= VirtualMachine(cluster
=cluster
, hostname
='gimager2.osuosl.bak')
234 vm_removed
= VirtualMachine(cluster
=cluster
, hostname
='does.not.exist.org')
238 self
.assertEqual([u
'does.not.exist.org'], cluster
.missing_in_ganeti
)
240 def test_available_ram(self
):
242 Tests that the available_ram property returns the correct values
244 c
= Cluster
.objects
.create(hostname
='ganeti.osuosl.test')
245 c2
= Cluster
.objects
.create(hostname
='ganeti2.osuosl.test', slug
='argh')
246 node
= Node
.objects
.create(cluster
=c
, hostname
='node.osuosl.test')
247 node1
= Node
.objects
.create(cluster
=c2
, hostname
='node1.osuosl.test')
249 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='foo', ram
=123, status
='running')
250 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='bar', ram
=456, status
='running')
251 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='xoo', ram
=789, status
='admin_down')
252 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='xar', ram
=234, status
='stopped')
253 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='boo', status
='running')
254 VirtualMachine
.objects
.create(cluster
=c2
, primary_node
=node1
, hostname
='gar', ram
=888, status
='running')
255 VirtualMachine
.objects
.create(cluster
=c2
, primary_node
=node1
, hostname
='yoo', ram
=999, status
='admin_down')
257 # test with no nodes, should result in zeros since nodes info isn't cached yet
258 ram
= c
.available_ram
259 self
.assertEqual(0, ram
['free'])
260 self
.assertEqual(0, ram
['total'])
262 # force refresh of nodes and rerun test for real values
265 ram
= c
.available_ram
266 self
.assertEqual(9999, ram
['total'])
267 self
.assertEqual(9420, ram
['free'])
270 def test_available_disk(self
):
272 Tests that the available_disk property returns the correct values
274 c
= Cluster
.objects
.create(hostname
='ganeti.osuosl.test')
275 c2
= Cluster
.objects
.create(hostname
='ganeti2.osuosl.test', slug
='argh')
276 node
= Node
.objects
.create(cluster
=c
, hostname
='node.osuosl.test')
277 node1
= Node
.objects
.create(cluster
=c2
, hostname
='node1.osuosl.test')
279 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='foo', disk_size
=123, status
='running')
280 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
,hostname
='bar', disk_size
=456, status
='running')
281 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='xoo', disk_size
=789, status
='admin_down')
282 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='xar', disk_size
=234, status
='stopped')
283 VirtualMachine
.objects
.create(cluster
=c
, primary_node
=node
, hostname
='boo', status
='running')
284 VirtualMachine
.objects
.create(cluster
=c2
, primary_node
=node1
, hostname
='gar', disk_size
=888, status
='running')
285 VirtualMachine
.objects
.create(cluster
=c2
, primary_node
=node1
, hostname
='yoo', disk_size
=999, status
='admin_down')
287 # test with no nodes, should result in zeros since nodes info isn't cached yet
288 disk
= c
.available_disk
289 self
.assertEqual(0, disk
['free'])
290 self
.assertEqual(0, disk
['total'])
292 # force refresh of nodes and rerun test for real values
295 disk
= c
.available_disk
296 self
.assertEqual(6666, disk
['total'])
297 self
.assertEqual(5064, disk
['free'])
299 def test_redistribute_config(self
):
301 Test Cluster.redistribute_config()
305 * cache is disabled while job is running
306 * cache is reenabled when job is finished
308 cluster
= Cluster
.objects
.create(hostname
='ganeti.osuosl.test')
309 cluster
.rapi
.GetJobStatus
.response
= JOB_RUNNING
311 # redistribute_config enables ignore_cache flag
312 job_id
= cluster
.redistribute_config().id
313 self
.assert_(Job
.objects
.filter(id=job_id
).exists())
314 cluster
= Cluster
.objects
.get(id=cluster
.id)
315 self
.assert_(cluster
.ignore_cache
)
316 self
.assert_(cluster
.last_job_id
)
317 self
.assert_(Job
.objects
.filter(id=job_id
).values()[0]['ignore_cache'])
319 # finished job resets ignore_cache flag
320 cluster
.rapi
.GetJobStatus
.response
= JOB
321 cluster
= Cluster
.objects
.get(id=cluster
.id)
322 self
.assertFalse(cluster
.ignore_cache
)
323 self
.assertFalse(cluster
.last_job_id
)
324 self
.assertFalse(Job
.objects
.filter(id=job_id
).values()[0]['ignore_cache'])
325 self
.assert_(Job
.objects
.get(id=job_id
).finished
)
328 class TestClusterViews(TestCase
, ViewTestMixin
, UserTestMixin
):
332 models
.client
.GanetiRapiClient
= RapiProxy
334 User(id=1, username
='anonymous').save()
335 settings
.ANONYMOUS_USER_ID
=1
337 user
= User(id=2, username
='tester0')
338 user
.set_password('secret')
340 user1
= User(id=3, username
='tester1')
341 user1
.set_password('secret')
344 group
= Group(name
='testing_group')
347 cluster
= Cluster(hostname
='test.osuosl.test', slug
='OSL_TEST')
350 self
.create_standard_users(globals())
351 self
.create_users(['cluster_admin'], globals())
352 cluster_admin
.grant('admin', cluster
)
356 dict_
['user1'] = user1
357 dict_
['group'] = group
358 dict_
['cluster'] = cluster
359 dict_
['c'] = Client()
362 VirtualMachine
.objects
.all().delete()
363 Quota
.objects
.all().delete()
364 Cluster
.objects
.all().delete()
365 Group
.objects
.all().delete()
366 User
.objects
.all().delete()
368 def validate_get(self
, url
, args
, template
):
370 response
= c
.get(url
% args
, follow
=True)
371 self
.assertEqual(200, response
.status_code
)
372 self
.assertTemplateUsed(response
, 'registration/login.html')
375 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
376 response
= c
.get(url
% args
)
377 self
.assertEqual(403, response
.status_code
)
380 response
= c
.get(url
% "DOES_NOT_EXIST")
381 self
.assertEqual(404, response
.status_code
)
383 # authorized user (perm)
384 grant(user
, 'admin', cluster
)
385 response
= c
.get(url
% args
)
386 self
.assertEqual(200, response
.status_code
)
387 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
388 self
.assertTemplateUsed(response
, template
)
390 # authorized user (superuser)
391 user
.revoke('admin', cluster
)
392 user
.is_superuser
= True
394 response
= c
.get(url
% args
)
395 self
.assertEqual(200, response
.status_code
)
396 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
397 self
.assertTemplateUsed(response
, template
)
399 def validate_get_configurable(self
, url
, args
, template
=False,
400 mimetype
=False, status
=False, perms
=[]):
402 More configurable version of validate_get.
403 Additional arguments (only if set) affects only authorized user test.
405 @template: used template
406 @mimetype: returned mimetype
407 @status: returned Http status code
408 @perms: set of perms granted on authorized user
410 @return response content
413 response
= c
.get(url
% args
, follow
=True)
414 self
.assertEqual(200, response
.status_code
)
415 self
.assertTemplateUsed(response
, 'registration/login.html')
418 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
419 response
= c
.get(url
% args
)
420 self
.assertEqual(403, response
.status_code
)
424 response
= c
.get(url
% "DOES_NOT_EXIST")
425 self
.assertEqual(404, response
.status_code
)
429 # authorized user (perm)
432 grant(user
, perm
, cluster
)
433 response
= c
.get(url
% args
)
435 self
.assertEqual(status
, response
.status_code
)
437 self
.assertEqual(mimetype
, response
['content-type'])
439 self
.assertTemplateUsed(response
, template
)
441 result
.append(response
)
443 # authorized user (superuser)
444 user
.revoke_all(cluster
)
445 user
.is_superuser
= True
447 response
= c
.get(url
% args
)
449 self
.assertEqual(200, response
.status_code
)
451 self
.assertEqual(mimetype
, response
['content-type'])
453 self
.assertTemplateUsed(response
, template
)
455 result
.append(response
)
459 def test_view_list(self
):
461 Tests displaying the list of clusters
465 # create extra user and tests
466 user2
= User(id=4, username
='tester2', is_superuser
=True)
467 user2
.set_password('secret')
469 cluster1
= Cluster(hostname
='cluster1', slug
='cluster1')
470 cluster2
= Cluster(hostname
='cluster2', slug
='cluster2')
471 cluster3
= Cluster(hostname
='cluster3', slug
='cluster3')
477 user1
.grant('admin', cluster
)
478 user1
.grant('create_vm', cluster1
)
481 response
= c
.get(url
, follow
=True)
482 self
.assertEqual(200, response
.status_code
)
483 self
.assertTemplateUsed(response
, 'registration/login.html')
486 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
487 response
= c
.get(url
)
488 self
.assertEqual(200, response
.status_code
)
489 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
490 self
.assertTemplateUsed(response
, 'cluster/list.html')
491 clusters
= response
.context
['cluster_list']
492 self
.assertFalse(clusters
)
494 # authorized permissions
495 self
.assert_(c
.login(username
=user1
.username
, password
='secret'))
496 response
= c
.get(url
)
497 self
.assertEqual(200, response
.status_code
)
498 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
499 self
.assertTemplateUsed(response
, 'cluster/list.html')
500 clusters
= response
.context
['cluster_list']
501 self
.assert_(cluster
in clusters
)
502 self
.assert_(cluster1
not in clusters
)
503 self
.assertEqual(1, len(clusters
))
505 # authorized (superuser)
506 self
.assert_(c
.login(username
=user2
.username
, password
='secret'))
507 response
= c
.get(url
)
508 self
.assertEqual(200, response
.status_code
)
509 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
510 self
.assertTemplateUsed(response
, 'cluster/list.html')
511 clusters
= response
.context
['cluster_list']
512 self
.assert_(cluster
in clusters
)
513 self
.assert_(cluster1
in clusters
)
514 self
.assert_(cluster2
in clusters
)
515 self
.assert_(cluster3
in clusters
)
516 self
.assertEqual(4, len(clusters
))
518 def test_view_add(self
):
520 Tests adding a new cluster
522 url
= '/cluster/add/'
525 response
= c
.get(url
, follow
=True)
526 self
.assertEqual(200, response
.status_code
)
527 self
.assertTemplateUsed(response
, 'registration/login.html')
530 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
531 response
= c
.get(url
)
532 self
.assertEqual(403, response
.status_code
)
535 user
.is_superuser
= True
537 response
= c
.get(url
)
538 self
.assertEqual(200, response
.status_code
)
539 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
540 self
.assertTemplateUsed(response
, 'cluster/edit.html')
542 data
= dict(hostname
='new-host3.hostname',
545 description
='testing editing clusters',
553 # test required fields
554 required
= ['hostname', 'port']
555 for property in required
:
558 response
= c
.post(url
, data_
)
559 self
.assertEqual(200, response
.status_code
)
560 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
561 self
.assertTemplateUsed(response
, 'cluster/edit.html')
564 non_required
= ['slug','description','virtual_cpus','disk','ram']
565 for property in non_required
:
568 response
= c
.post(url
, data_
, follow
=True)
569 self
.assertEqual(200, response
.status_code
)
570 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
571 self
.assertTemplateUsed(response
, 'cluster/detail.html')
572 cluster
= response
.context
['cluster']
573 for k
, v
in data_
.items():
574 self
.assertEqual(v
, getattr(cluster
, k
))
575 Cluster
.objects
.all().delete()
579 response
= c
.post(url
, data
, follow
=True)
580 self
.assertEqual(200, response
.status_code
)
581 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
582 self
.assertTemplateUsed(response
, 'cluster/detail.html')
583 cluster
= response
.context
['cluster']
584 for k
, v
in data_
.items():
585 self
.assertEqual(v
, getattr(cluster
, k
))
586 Cluster
.objects
.all().delete()
588 # success without username or password
590 del data_
['username']
591 del data_
['password']
592 response
= c
.post(url
, data_
, follow
=True)
593 self
.assertEqual(200, response
.status_code
)
594 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
595 self
.assertTemplateUsed(response
, 'cluster/detail.html')
596 cluster
= response
.context
['cluster']
597 for k
, v
in data_
.items():
598 self
.assertEqual(v
, getattr(cluster
, k
))
599 Cluster
.objects
.all().delete()
601 #test username/password/confirm_password relationships
602 relation
= ['username', 'password']
603 for property in relation
:
606 response
= c
.post(url
, data_
, follow
=True)
607 self
.assertEqual(200, response
.status_code
)
608 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
609 self
.assertTemplateUsed(response
, 'cluster/edit.html')
612 response
= c
.post(url
, data
)
613 for property in ['hostname','slug']:
615 data_
[property] = 'different'
616 response
= c
.post(url
, data_
)
617 self
.assertEqual(200, response
.status_code
)
618 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
619 self
.assertTemplateUsed(response
, 'cluster/edit.html')
621 def test_view_edit(self
):
623 Tests editing a cluster
625 cluster
= globals()['cluster']
626 url
= '/cluster/%s/edit/' % cluster
.slug
629 response
= c
.get(url
, follow
=True)
630 self
.assertEqual(200, response
.status_code
)
631 self
.assertTemplateUsed(response
, 'registration/login.html')
634 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
635 response
= c
.get(url
)
636 self
.assertEqual(403, response
.status_code
)
638 # authorized (permission)
639 user
.grant('admin', cluster
)
640 response
= c
.get(url
)
641 self
.assertEqual(200, response
.status_code
)
642 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
643 self
.assertTemplateUsed(response
, 'cluster/edit.html')
644 self
.assertEqual(cluster
, response
.context
['cluster'])
645 user
.revoke('admin', cluster
)
648 user
.is_superuser
= True
650 response
= c
.get(url
)
651 self
.assertEqual(200, response
.status_code
)
652 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
653 self
.assertTemplateUsed(response
, 'cluster/edit.html')
654 self
.assertEqual(None, cluster
.info
)
656 data
= dict(hostname
='new-host-1.hostname',
659 description
='testing editing clusters',
662 confirm_password
= 'secret',
670 response
= c
.post(url
, data
, follow
=True)
671 self
.assertEqual(200, response
.status_code
)
672 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
673 self
.assertTemplateUsed(response
, 'cluster/detail.html')
674 cluster
= response
.context
['cluster']
675 self
.assertNotEqual(None, cluster
.info
)
676 del data_
['confirm_password']
677 for k
, v
in data_
.items():
678 self
.assertEqual(v
, getattr(cluster
, k
))
680 def test_view_delete_anonymous(self
):
682 Random people shouldn't be able to delete clusters.
685 cluster
= Cluster(hostname
='test.cluster.bak', slug
='cluster1')
687 url
= '/cluster/%s/edit/' % cluster
.slug
689 response
= c
.delete(url
, follow
=True)
690 self
.assertEqual(200, response
.status_code
)
691 self
.assertTemplateUsed(response
, 'registration/login.html')
693 def test_view_delete_unauthorized(self
):
695 Unauthorized people shouldn't be able to delete clusters.
698 cluster
= Cluster(hostname
='test.cluster.bak', slug
='cluster1')
700 url
= '/cluster/%s/edit/' % cluster
.slug
702 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
703 response
= c
.delete(url
)
704 self
.assertEqual(403, response
.status_code
)
706 def test_view_delete_authorized(self
):
708 Users with admin on the cluster should be able to delete the cluster.
711 cluster
= Cluster(hostname
='test.cluster.bak', slug
='cluster1')
713 url
= '/cluster/%s/edit/' % cluster
.slug
715 user
.grant('admin', cluster
)
716 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
717 response
= c
.delete(url
, follow
=True)
718 self
.assertEqual(200, response
.status_code
)
719 self
.assertEquals('application/json', response
['content-type'])
720 self
.assertEquals('1', response
.content
)
721 self
.assertFalse(Cluster
.objects
.all().filter(id=cluster
.id).exists())
723 def test_view_delete_superuser(self
):
725 Superusers can delete clusters.
728 cluster
= Cluster(hostname
='test.cluster.bak', slug
='cluster1')
730 url
= '/cluster/%s/edit/' % cluster
.slug
732 user
.is_superuser
= True
734 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
735 response
= c
.delete(url
, follow
=True)
736 self
.assertEqual(200, response
.status_code
)
737 self
.assertEquals('application/json', response
['content-type'])
738 self
.assertEquals('1', response
.content
)
739 self
.assertFalse(Cluster
.objects
.all().filter(id=cluster
.id).exists())
741 def test_view_detail(self
):
743 Tests displaying detailed view for a Cluster
749 response
= c
.get(url
% args
, follow
=True)
750 self
.assertEqual(200, response
.status_code
)
751 self
.assertTemplateUsed(response
, 'registration/login.html')
754 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
755 response
= c
.get(url
% args
)
756 self
.assertEqual(403, response
.status_code
)
759 response
= c
.get(url
% "DoesNotExist")
760 self
.assertEqual(404, response
.status_code
)
762 # authorized (permission)
763 grant(user
, 'admin', cluster
)
764 response
= c
.get(url
% args
)
765 self
.assertEqual(200, response
.status_code
)
766 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
767 self
.assertTemplateUsed(response
, 'cluster/detail.html')
769 # authorized (superuser)
770 user
.revoke('admin', cluster
)
771 user
.is_superuser
= True
773 response
= c
.get(url
% args
)
774 self
.assertEqual(200, response
.status_code
)
775 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
776 self
.assertTemplateUsed(response
, 'cluster/detail.html')
778 def test_view_users(self
):
780 Tests view for cluster users:
783 * lack of permissions returns 403
784 * nonexistent cluster returns 404
786 url
= "/cluster/%s/users/"
788 self
.validate_get(url
, args
, 'cluster/users.html')
790 def test_view_virtual_machines(self
):
792 Tests view for cluster users:
795 * lack of permissions returns 403
796 * nonexistent cluster returns 404
798 url
= "/cluster/%s/virtual_machines/"
800 self
.validate_get(url
, args
, 'virtual_machine/table.html')
802 def test_view_nodes(self
):
804 Tests view for cluster users:
807 * lack of permissions returns 403
808 * nonexistent cluster returns 404
810 url
= "/cluster/%s/nodes/"
812 cluster
.rapi
.GetNodes
.response
= NODES_BULK
813 self
.validate_get(url
, args
, 'node/table.html')
814 cluster
.rapi
.GetNodes
.response
= NODES
816 def test_view_add_permissions(self
):
818 Test adding permissions to a new User or Group
820 url
= '/cluster/%s/permissions/'
824 response
= c
.get(url
% args
, follow
=True)
825 self
.assertEqual(200, response
.status_code
)
826 self
.assertTemplateUsed(response
, 'registration/login.html')
829 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
830 response
= c
.get(url
% args
)
831 self
.assertEqual(403, response
.status_code
)
834 response
= c
.get(url
% "DOES_NOT_EXIST")
835 self
.assertEqual(404, response
.status_code
)
837 # valid GET authorized user (perm)
838 grant(user
, 'admin', cluster
)
839 response
= c
.get(url
% args
)
840 self
.assertEqual(200, response
.status_code
)
841 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
842 self
.assertTemplateUsed(response
, 'object_permissions/permissions/form.html')
844 # valid GET authorized user (superuser)
845 user
.revoke('admin', cluster
)
846 user
.is_superuser
= True
848 response
= c
.get(url
% args
)
849 self
.assertEqual(200, response
.status_code
)
850 self
.assertTemplateUsed(response
, 'object_permissions/permissions/form.html')
853 data
= {'permissions':['admin'], 'obj':cluster
.pk
}
854 response
= c
.post(url
% args
, data
)
855 self
.assertEqual(200, response
.status_code
)
856 self
.assertEquals('application/json', response
['content-type'])
857 self
.assertNotEqual('0', response
.content
)
859 # both user and group
860 data
= {'permissions':['admin'], 'group':group
.id, 'user':user1
.id, 'cluster':cluster
.pk
}
861 response
= c
.post(url
% args
, data
)
862 self
.assertEqual(200, response
.status_code
)
863 self
.assertEquals('application/json', response
['content-type'])
864 self
.assertNotEqual('0', response
.content
)
866 # no permissions specified - user
867 data
= {'permissions':[], 'user':user1
.id, 'obj':cluster
.pk
}
868 response
= c
.post(url
% args
, data
)
869 self
.assertEqual(200, response
.status_code
)
870 self
.assertEquals('application/json', response
['content-type'])
871 self
.assertNotEqual('0', response
.content
)
873 # no permissions specified - group
874 data
= {'permissions':[], 'group':group
.id, 'obj':cluster
.pk
}
875 response
= c
.post(url
% args
, data
)
876 self
.assertEqual(200, response
.status_code
)
877 self
.assertEquals('application/json', response
['content-type'])
879 # valid POST user has permissions
880 user1
.grant('create_vm', cluster
)
881 data
= {'permissions':['admin'], 'user':user1
.id, 'obj':cluster
.pk
}
882 response
= c
.post(url
% args
, data
)
883 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
884 self
.assertTemplateUsed(response
, 'cluster/user_row.html')
885 self
.assert_(user1
.has_perm('admin', cluster
))
886 self
.assertFalse(user1
.has_perm('create_vm', cluster
))
888 # valid POST group has permissions
889 group
.grant('create_vm', cluster
)
890 data
= {'permissions':['admin'], 'group':group
.id, 'obj':cluster
.pk
}
891 response
= c
.post(url
% args
, data
)
892 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
893 self
.assertTemplateUsed(response
, 'cluster/group_row.html')
894 self
.assertEqual(['admin'], group
.get_perms(cluster
))
896 def test_view_object_log(self
):
898 Tests view for cluster object log:
902 * cluster specific log actions can be rendered properly
904 url
= "/cluster/%s/object_log/"
905 args
= (cluster
.slug
,)
906 self
.assert_standard_fails(url
, args
)
907 self
.assert_200(url
, args
, users
=[superuser
, cluster_admin
])
909 def test_view_user_permissions(self
):
911 Tests updating users permissions
914 * anonymous user returns 403
915 * lack of permissions returns 403
916 * nonexistent cluster returns 404
917 * invalid user returns 404
918 * invalid group returns 404
919 * missing user and group returns error as json
920 * GET returns html for form
921 * If user/group has permissions no html is returned
922 * If user/group has no permissions a json response of -1 is returned
924 args
= (cluster
.slug
, user1
.id)
925 args_post
= cluster
.slug
926 url
= "/cluster/%s/permissions/user/%s"
927 url_post
= "/cluster/%s/permissions/"
930 response
= c
.get(url
% args
, follow
=True)
931 self
.assertEqual(200, response
.status_code
)
932 self
.assertTemplateUsed(response
, 'registration/login.html')
935 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
936 response
= c
.get(url
% args
)
937 self
.assertEqual(403, response
.status_code
)
940 response
= c
.get(url
% ("DOES_NOT_EXIST", user1
.id))
941 self
.assertEqual(404, response
.status_code
)
943 # valid GET authorized user (perm)
944 grant(user
, 'admin', cluster
)
945 response
= c
.get(url
% args
)
946 self
.assertEqual(200, response
.status_code
)
947 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
948 self
.assertTemplateUsed(response
, 'object_permissions/permissions/form.html')
950 # valid GET authorized user (superuser)
951 user
.revoke('admin', cluster
)
952 user
.is_superuser
= True
954 response
= c
.get(url
% args
)
955 self
.assertEqual(200, response
.status_code
)
956 self
.assertTemplateUsed(response
, 'object_permissions/permissions/form.html')
959 response
= c
.get(url
% (cluster
.slug
, -1))
960 self
.assertEqual(404, response
.status_code
)
962 # invalid user (POST)
963 user1
.grant('create_vm', cluster
)
964 data
= {'permissions':['admin'], 'user':-1, 'obj':cluster
.pk
}
965 response
= c
.post(url_post
% args_post
, data
)
966 self
.assertEquals('application/json', response
['content-type'])
967 self
.assertNotEqual('0', response
.content
)
970 user1
.grant('create_vm', cluster
)
971 data
= {'permissions':['admin'], 'obj':cluster
.pk
}
972 response
= c
.post(url_post
% args_post
, data
)
973 self
.assertEquals('application/json', response
['content-type'])
974 self
.assertNotEqual('0', response
.content
)
976 # valid POST user has permissions
977 user1
.grant('create_vm', cluster
)
978 data
= {'permissions':['admin'], 'user':user1
.id, 'obj':cluster
.pk
}
979 response
= c
.post(url_post
% args_post
, data
)
980 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
981 self
.assertTemplateUsed(response
, 'cluster/user_row.html')
982 self
.assert_(user1
.has_perm('admin', cluster
))
983 self
.assertFalse(user1
.has_perm('create_vm', cluster
))
985 # add quota to the user
986 user_quota
= {'default':0, 'ram':51, 'virtual_cpus':10, 'disk':3000}
987 quota
= Quota(cluster
=cluster
, user
=user1
.get_profile())
988 quota
.__dict
__.update(user_quota
)
990 self
.assertEqual(user_quota
, cluster
.get_quota(user1
.get_profile()))
992 # valid POST user has no permissions left
993 data
= {'permissions':[], 'user':user1
.id, 'obj':cluster
.pk
}
994 response
= c
.post(url_post
% args_post
, data
)
995 self
.assertEqual(200, response
.status_code
)
996 self
.assertEquals('application/json', response
['content-type'])
997 self
.assertEqual([], get_user_perms(user
, cluster
))
998 self
.assertEqual('"user_3"', response
.content
)
1000 # quota should be deleted (and showing default)
1001 self
.assertEqual(1, cluster
.get_quota(user1
.get_profile())['default'])
1002 self
.assertFalse(user1
.get_profile().quotas
.all().exists())
1004 # no permissions specified - user with no quota
1005 user1
.grant('create_vm', cluster
)
1006 cluster
.set_quota(user1
.get_profile(), None)
1007 data
= {'permissions':[], 'user':user1
.id, 'obj':cluster
.pk
}
1008 response
= c
.post(url
% args
, data
)
1009 self
.assertEqual(200, response
.status_code
)
1010 self
.assertEquals('application/json', response
['content-type'])
1011 self
.assertNotEqual('0', response
.content
)
1013 # quota should be deleted (and showing default)
1014 self
.assertEqual(1, cluster
.get_quota(user1
.get_profile())['default'])
1015 self
.assertFalse(user1
.get_profile().quotas
.all().exists())
1017 def test_view_group_permissions(self
):
1019 Test editing Group permissions on a Cluster
1021 args
= (cluster
.slug
, group
.id)
1022 args_post
= cluster
.slug
1023 url
= "/cluster/%s/permissions/group/%s"
1024 url_post
= "/cluster/%s/permissions/"
1027 response
= c
.get(url
% args
, follow
=True)
1028 self
.assertEqual(200, response
.status_code
)
1029 self
.assertTemplateUsed(response
, 'registration/login.html')
1032 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
1033 response
= c
.get(url
% args
)
1034 self
.assertEqual(403, response
.status_code
)
1036 # nonexisent cluster
1037 response
= c
.get(url
% ("DOES_NOT_EXIST", group
.id))
1038 self
.assertEqual(404, response
.status_code
)
1040 # valid GET authorized user (perm)
1041 grant(user
, 'admin', cluster
)
1042 response
= c
.get(url
% args
)
1043 self
.assertEqual(200, response
.status_code
)
1044 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
1045 self
.assertTemplateUsed(response
, 'object_permissions/permissions/form.html')
1047 # valid GET authorized user (superuser)
1048 user
.revoke('admin', cluster
)
1049 user
.is_superuser
= True
1051 response
= c
.get(url
% args
)
1052 self
.assertEqual(200, response
.status_code
)
1053 self
.assertTemplateUsed(response
, 'object_permissions/permissions/form.html')
1056 response
= c
.get(url
% (cluster
.slug
, 0))
1057 self
.assertEqual(404, response
.status_code
)
1059 # invalid group (POST)
1060 data
= {'permissions':['admin'], 'group':-1, 'obj':cluster
.pk
}
1061 response
= c
.post(url_post
% args_post
, data
)
1062 self
.assertEquals('application/json', response
['content-type'])
1063 self
.assertNotEqual('0', response
.content
)
1066 data
= {'permissions':['admin'], 'obj':cluster
.pk
}
1067 response
= c
.post(url_post
% args_post
, data
)
1068 self
.assertEquals('application/json', response
['content-type'])
1069 self
.assertNotEqual('0', response
.content
)
1071 # valid POST group has permissions
1072 group
.grant('create_vm', cluster
)
1073 data
= {'permissions':['admin'], 'group':group
.id, 'obj':cluster
.pk
}
1074 response
= c
.post(url_post
% args_post
, data
)
1075 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
1076 self
.assertTemplateUsed(response
, 'cluster/group_row.html')
1077 self
.assertEqual(['admin'], group
.get_perms(cluster
))
1079 # add quota to the group
1080 user_quota
= {'default':0, 'ram':51, 'virtual_cpus':10, 'disk':3000}
1081 quota
= Quota(cluster
=cluster
, user
=group
.organization
)
1082 quota
.__dict
__.update(user_quota
)
1084 self
.assertEqual(user_quota
, cluster
.get_quota(group
.organization
))
1086 # valid POST group has no permissions left
1087 data
= {'permissions':[], 'group':group
.id, 'obj':cluster
.pk
}
1088 response
= c
.post(url_post
% args_post
, data
)
1089 self
.assertEqual(200, response
.status_code
)
1090 self
.assertEquals('application/json', response
['content-type'])
1091 self
.assertEqual([], group
.get_perms(cluster
))
1092 self
.assertEqual('"group_%s"'%group
.id, response
.content
)
1094 # quota should be deleted (and showing default)
1095 self
.assertEqual(1, cluster
.get_quota(group
.organization
)['default'])
1096 self
.assertFalse(group
.organization
.quotas
.all().exists())
1098 # no permissions specified - user with no quota
1099 group
.grant('create_vm', cluster
)
1100 cluster
.set_quota(group
.organization
, None)
1101 data
= {'permissions':[], 'group':group
.id, 'obj':cluster
.pk
}
1102 response
= c
.post(url
% args
, data
)
1103 self
.assertEqual(200, response
.status_code
)
1104 self
.assertEquals('application/json', response
['content-type'])
1105 self
.assertNotEqual('0', response
.content
)
1107 # quota should be deleted (and showing default)
1108 self
.assertEqual(1, cluster
.get_quota(group
.organization
)['default'])
1109 self
.assertFalse(group
.organization
.quotas
.all().exists())
1111 def validate_quota(self
, cluster_user
, template
):
1113 Generic tests for validating quota views
1116 * lack of permissions returns 403
1117 * nonexistent cluster returns 404
1118 * invalid user returns 404
1119 * missing user returns error as json
1120 * GET returns html for form
1121 * successful POST returns html for user row
1122 * successful DELETE removes user quota
1124 default_quota
= {'default':1, 'ram':1, 'virtual_cpus':None, 'disk':3}
1125 user_quota
= {'default':0, 'ram':4, 'virtual_cpus':5, 'disk':None}
1126 user_unlimited
= {'default':0, 'ram':None, 'virtual_cpus':None, 'disk':None}
1127 cluster
.__dict
__.update(default_quota
)
1130 args
= (cluster
.slug
, cluster_user
.id)
1131 args_post
= cluster
.slug
1132 url
= '/cluster/%s/quota/%s'
1133 url_post
= '/cluster/%s/quota/'
1136 response
= c
.get(url
% args
, follow
=True)
1137 self
.assertEqual(200, response
.status_code
)
1138 self
.assertTemplateUsed(response
, 'registration/login.html')
1141 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
1142 response
= c
.get(url
% args
)
1143 self
.assertEqual(403, response
.status_code
)
1145 # nonexisent cluster
1146 response
= c
.get("/cluster/%s/user/quota/?user=%s" % ("DOES_NOT_EXIST", user1
.id))
1147 self
.assertEqual(404, response
.status_code
)
1149 # valid GET authorized user (perm)
1150 grant(user
, 'admin', cluster
)
1151 response
= c
.get(url
% args
)
1152 self
.assertEqual(200, response
.status_code
)
1153 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
1154 self
.assertTemplateUsed(response
, 'cluster/quota.html')
1156 # valid GET authorized user (superuser)
1157 user
.revoke('admin', cluster
)
1158 user
.is_superuser
= True
1160 response
= c
.get(url
% args
)
1161 self
.assertEqual(200, response
.status_code
)
1162 self
.assertTemplateUsed(response
, 'cluster/quota.html')
1165 response
= c
.get(url
% (cluster
.slug
, 0))
1166 self
.assertEqual(404, response
.status_code
)
1169 response
= c
.get(url_post
% args_post
)
1170 self
.assertEqual(404, response
.status_code
)
1173 data
= {'ram':'', 'virtual_cpus':'', 'disk':''}
1174 response
= c
.post(url_post
% args_post
, data
)
1175 self
.assertEqual(200, response
.status_code
)
1176 self
.assertEquals('application/json', response
['content-type'])
1178 # valid POST - setting unlimited values (nones)
1179 data
= {'user':cluster_user
.id, 'ram':'', 'virtual_cpus':'', 'disk':''}
1180 response
= c
.post(url_post
% args_post
, data
)
1181 self
.assertEqual(200, response
.status_code
)
1182 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
1183 self
.assertTemplateUsed(response
, template
)
1184 self
.assertEqual(user_unlimited
, cluster
.get_quota(cluster_user
))
1185 query
= Quota
.objects
.filter(cluster
=cluster
, user
=cluster_user
)
1186 self
.assert_(query
.exists())
1188 # valid POST - setting values
1189 data
= {'user':cluster_user
.id, 'ram':4, 'virtual_cpus':5, 'disk':''}
1190 response
= c
.post(url_post
% args_post
, data
)
1191 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
1192 self
.assertTemplateUsed(response
, template
)
1193 self
.assertEqual(user_quota
, cluster
.get_quota(cluster_user
))
1194 self
.assert_(query
.exists())
1196 # valid POST - same as default values (should delete)
1197 data
= {'user':cluster_user
.id, 'ram':1, 'disk':3}
1198 response
= c
.post(url_post
% args_post
, data
)
1199 self
.assertEqual(200, response
.status_code
)
1200 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
1201 self
.assertTemplateUsed(response
, template
)
1202 self
.assertEqual(default_quota
, cluster
.get_quota(cluster_user
))
1203 self
.assertFalse(query
.exists())
1205 # valid POST - same as default values (should do nothing)
1206 data
= {'user':cluster_user
.id, 'ram':1, 'disk':3}
1207 response
= c
.post(url_post
% args_post
, data
)
1208 self
.assertEqual(200, response
.status_code
)
1209 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
1210 self
.assertTemplateUsed(response
, template
)
1211 self
.assertEqual(default_quota
, cluster
.get_quota(cluster_user
))
1212 self
.assertFalse(query
.exists())
1214 # valid POST - setting implicit unlimited (values are excluded)
1215 data
= {'user':cluster_user
.id}
1216 response
= c
.post(url_post
% args_post
, data
)
1217 self
.assertEqual(200, response
.status_code
)
1218 self
.assertEquals('text/html; charset=utf-8', response
['content-type'])
1219 self
.assertTemplateUsed(response
, template
)
1220 self
.assertEqual(user_unlimited
, cluster
.get_quota(cluster_user
))
1221 self
.assert_(query
.exists())
1223 # valid DELETE - returns to default values
1224 data
= {'user':cluster_user
.id, 'delete':True}
1225 response
= c
.post(url_post
% args_post
, data
)
1226 self
.assertEqual(200, response
.status_code
)
1227 self
.assertTemplateUsed(response
, template
)
1228 self
.assertEqual(default_quota
, cluster
.get_quota(cluster_user
))
1229 self
.assertFalse(query
.exists())
1231 def test_view_user_quota(self
):
1233 Tests updating users quota
1235 self
.validate_quota(user1
.get_profile(), template
='cluster/user_row.html')
1237 def test_view_group_quota(self
):
1239 Tests updating a Group's quota
1241 self
.validate_quota(group
.organization
, template
='cluster/group_row.html')
1243 def test_sync_virtual_machines_in_edit_view(self
):
1245 Test if sync_virtual_machines is run after editing a cluster
1248 #configuring stuff needed to test edit view
1249 user
.is_superuser
= True
1251 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
1252 cluster
.virtual_machines
.all().delete()
1253 url
= '/cluster/%s/edit/' % cluster
.slug
1255 data
= dict(hostname
='new-host-1.hostname',
1258 description
='testing editing clusters',
1260 password
= 'secret',
1266 # run view once to create cluster
1267 c
.post(url
, data
, follow
=True)
1269 # ensure there are VMs ready for sync
1270 cluster
.virtual_machines
.all().delete()
1272 #run view_edit again..
1273 c
.post(url
, data
, follow
=True)
1275 # assert that no VMs were created
1276 self
.assertFalse(cluster
.virtual_machines
.all().exists())
1278 def test_view_ssh_keys(self
):
1280 Test getting SSH keys belonging to users, who have admin permission on
1283 vm
= VirtualMachine
.objects
.create(cluster
=cluster
, hostname
='vm1.osuosl.bak')
1286 SSHKey
.objects
.create(key
="ssh-rsa test test@test", user
=user
)
1287 SSHKey
.objects
.create(key
="ssh-dsa test asd@asd", user
=user
)
1288 SSHKey
.objects
.create(key
="ssh-dsa test foo@bar", user
=user1
)
1291 import settings
, json
1292 key
= settings
.WEB_MGR_API_KEY
1294 url
= '/cluster/%s/keys/%s/'
1295 args
= (cluster
.slug
, key
)
1297 self
.assert_standard_fails(url
, args
, login_required
=False, authorized
=False)
1299 # cluster without users who have admin perms
1300 response
= c
.get(url
% args
)
1301 self
.assertEqual(200, response
.status_code
)
1302 self
.assertEquals("application/json", response
["content-type"])
1303 self
.assertEqual(len(json
.loads(response
.content
)), 0 )
1304 self
.assertNotContains(response
, "test@test")
1305 self
.assertNotContains(response
, "asd@asd")
1307 # vm with users who have admin perms
1308 # grant admin permission to first user
1309 user
.grant("admin", vm
)
1310 user1
.grant("admin", cluster
)
1312 response
= c
.get(url
% args
)
1313 self
.assertEqual(200, response
.status_code
)
1314 self
.assertEquals("application/json", response
["content-type"])
1315 self
.assertEqual(len(json
.loads(response
.content
)), 3 )
1316 self
.assertContains(response
, "test@test", count
=1)
1317 self
.assertContains(response
, "asd@asd", count
=1)
1318 self
.assertContains(response
, "foo@bar", count
=1)
1320 def test_view_redistribute_config(self
):
1322 Tests cluster's config redistribution
1324 cluster
= globals()['cluster']
1325 url
= '/cluster/%s/redistribute-config/' % cluster
.slug
1328 response
= c
.get(url
, follow
=True)
1329 self
.assertEqual(200, response
.status_code
)
1330 self
.assertTemplateUsed(response
, 'registration/login.html')
1333 self
.assert_(c
.login(username
=user
.username
, password
='secret'))
1334 response
= c
.delete(url
)
1335 self
.assertEqual(403, response
.status_code
)
1337 # authorized (permission)
1338 user
.grant('admin', cluster
)
1339 response
= c
.post(url
)
1340 self
.assertEqual(200, response
.status_code
)
1341 self
.assertEquals('application/json', response
['content-type'])
1342 self
.assert_('status' in response
.content
)
1343 self
.assert_(Cluster
.objects
.filter(id=cluster
.id).exists())
1344 user
.revoke('admin', cluster
)
1350 user
.is_superuser
= True
1352 response
= c
.post(url
)
1353 self
.assertEqual(200, response
.status_code
)
1354 self
.assertEquals('application/json', response
['content-type'])
1355 self
.assert_('status' in response
.content
)
1356 self
.assert_(Cluster
.objects
.filter(id=cluster
.id).exists())