Merge lp:~devcamcar/django-nova/improve_unittests into lp:django-nova

Proposed by Devin Carlen
Status: Merged
Approved by: Devin Carlen
Approved revision: no longer in the source branch.
Merged at revision: 11
Proposed branch: lp:~devcamcar/django-nova/improve_unittests
Merge into: lp:django-nova
Diff against target: 885 lines (+490/-54)
17 files modified
buildout.cfg (+1/-1)
setup.py (+1/-1)
src/django_nova/forms.py (+3/-3)
src/django_nova/manager.py (+11/-1)
src/django_nova/models.py (+5/-0)
src/django_nova/shortcuts.py (+3/-2)
src/django_nova/tests/__init__.py (+1/-0)
src/django_nova/tests/urls.py (+32/-0)
src/django_nova/tests/view_tests/__init__.py (+3/-0)
src/django_nova/tests/view_tests/base.py (+51/-0)
src/django_nova/tests/view_tests/image_tests.py (+210/-0)
src/django_nova/tests/view_tests/instance_tests.py (+45/-0)
src/django_nova/tests/view_tests/keypair_tests.py (+71/-0)
src/django_nova/testsettings.py (+17/-3)
src/django_nova/views/images.py (+20/-27)
src/django_nova/views/instances.py (+11/-11)
src/django_nova/views/keypairs.py (+5/-5)
To merge this branch: bzr merge lp:~devcamcar/django-nova/improve_unittests
Reviewer Review Type Date Requested Status
Devin Carlen Approve
Review via email: mp+47481@code.launchpad.net

Description of the change

Results of refactoring view tests and adding mox. Still in progress but merging in what's there to date.

To post a comment you must log in.
Revision history for this message
Devin Carlen (devcamcar) wrote :

approve

review: Approve
11. By Devin Carlen

Merged lp:~devcamcar/django-nova/improve_unittests

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'buildout.cfg'
--- buildout.cfg 2011-01-12 20:02:06 +0000
+++ buildout.cfg 2011-01-25 23:54:53 +0000
@@ -10,7 +10,7 @@
1010
11[django]11[django]
12recipe = djangorecipe12recipe = djangorecipe
13version = 1.2.313version = 1.2.4
14project = django_nova14project = django_nova
15projectegg = django_nova15projectegg = django_nova
16settings = testsettings16settings = testsettings
1717
=== modified file 'setup.py'
--- setup.py 2011-01-12 20:02:06 +0000
+++ setup.py 2011-01-25 23:54:53 +0000
@@ -15,7 +15,7 @@
15 author_email = 'devin.carlen@gmail.com',15 author_email = 'devin.carlen@gmail.com',
16 packages = find_packages('src'),16 packages = find_packages('src'),
17 package_dir = {'': 'src'},17 package_dir = {'': 'src'},
18 install_requires = ['setuptools'],18 install_requires = ['setuptools', 'boto==1.9b', 'mox>=0.5.0'],
19 classifiers = [19 classifiers = [
20 'Development Status :: 4 - Beta',20 'Development Status :: 4 - Beta',
21 'Framework :: Django',21 'Framework :: Django',
2222
=== modified file 'src/django_nova/forms.py'
--- src/django_nova/forms.py 2011-01-16 03:46:33 +0000
+++ src/django_nova/forms.py 2011-01-25 23:54:53 +0000
@@ -49,13 +49,13 @@
4949
50def get_instance_choices(project):50def get_instance_choices(project):
51 choices = [(i.id, i.id) for i in project.get_instances()]51 choices = [(i.id, i.id) for i in project.get_instances()]
52 if len(choices) == 0:52 if not len(choices):
53 choices = [('', 'none available')]53 choices = [('', 'none available')]
54 return choices54 return choices
5555
56def get_key_pair_choices(project):56def get_key_pair_choices(project):
57 choices = [(k.name, k.name) for k in project.get_key_pairs()]57 choices = [(k.name, k.name) for k in project.get_key_pairs()]
58 if len(choices) == 0:58 if not len(choices):
59 choices = [('', 'none available')]59 choices = [('', 'none available')]
60 return choices60 return choices
6161
@@ -68,7 +68,7 @@
68def get_available_volume_choices(project):68def get_available_volume_choices(project):
69 choices = [(v.id, '%s %s - %dGB' % (v.id, v.displayName, v.size)) for v in \69 choices = [(v.id, '%s %s - %dGB' % (v.id, v.displayName, v.size)) for v in \
70 project.get_volumes() if v.status != "in-use"]70 project.get_volumes() if v.status != "in-use"]
71 if len(choices) == 0:71 if not len(choices):
72 choices = [('', 'none available')]72 choices = [('', 'none available')]
73 return choices73 return choices
7474
7575
=== modified file 'src/django_nova/manager.py'
--- src/django_nova/manager.py 2011-01-15 09:27:24 +0000
+++ src/django_nova/manager.py 2011-01-25 23:54:53 +0000
@@ -87,6 +87,16 @@
87 return conn.get_object('UpdateImage', params, boto.ec2.image.Image)87 return conn.get_object('UpdateImage', params, boto.ec2.image.Image)
8888
89 @wrap_nova_error89 @wrap_nova_error
90 def modify_image_attribute(self, image_id, attribute=None, operation=None,
91 groups='all'):
92 conn = self.get_nova_connection()
93 return conn.modify_image_attribute(image_id,
94 attribute='launchPermission',
95 operation='remove',
96 groups='all',)
97
98
99 @wrap_nova_error
90 def run_instances(self, image_id, **kwargs):100 def run_instances(self, image_id, **kwargs):
91 """101 """
92 Runs instances of the specified image id.102 Runs instances of the specified image id.
@@ -201,7 +211,7 @@
201 """211 """
202 Indicates whether a security group with the specified name exists in this project.212 Indicates whether a security group with the specified name exists in this project.
203 """213 """
204 return self.get_security_group(name) != None214 return self.get_security_group(name) is not None
205215
206 @wrap_nova_error216 @wrap_nova_error
207 def create_security_group(self, name, description):217 def create_security_group(self, name, description):
208218
=== modified file 'src/django_nova/models.py'
--- src/django_nova/models.py 2011-01-12 20:02:06 +0000
+++ src/django_nova/models.py 2011-01-25 23:54:53 +0000
@@ -107,6 +107,11 @@
107 """107 """
108 Creates a Nova User when a new Django User is created.108 Creates a Nova User when a new Django User is created.
109 """109 """
110
111 # NOTE(devcamcar): If running unit tests, don't use a real endpoint.
112 if settings.NOVA_DEFAULT_ENDPOINT == 'none':
113 return
114
110 if created:115 if created:
111 nova = get_nova_admin_connection()116 nova = get_nova_admin_connection()
112 if not nova.has_user(instance.username):117 if not nova.has_user(instance.username):
113118
=== modified file 'src/django_nova/shortcuts.py'
--- src/django_nova/shortcuts.py 2011-01-17 06:58:19 +0000
+++ src/django_nova/shortcuts.py 2011-01-25 23:54:53 +0000
@@ -15,6 +15,7 @@
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations16# License for the specific language governing permissions and limitations
17# under the License.17# under the License.
18
18"""19"""
19Helper methods for commonly used operations.20Helper methods for commonly used operations.
20"""21"""
@@ -115,13 +116,13 @@
115 user_has_modify_permissions = False116 user_has_modify_permissions = False
116117
117 # checks global roles, if user is a sysadmin they can modify image attribtues.118 # checks global roles, if user is a sysadmin they can modify image attribtues.
118 if user_has_modify_permissions == False:119 if not user_has_modify_permissions:
119 for role in nova.get_user_roles(username):120 for role in nova.get_user_roles(username):
120 if role.role == "sysadmin":121 if role.role == "sysadmin":
121 user_has_modify_permissions = True122 user_has_modify_permissions = True
122123
123 # checks project roles, if user is a sysadmin they can modify image attribtues.124 # checks project roles, if user is a sysadmin they can modify image attribtues.
124 if user_has_modify_permissions == False:125 if not user_has_modify_permissions:
125 for role in nova.get_user_roles(username, project_name):126 for role in nova.get_user_roles(username, project_name):
126 if role.role == "sysadmin":127 if role.role == "sysadmin":
127 user_has_modify_permissions = True128 user_has_modify_permissions = True
128129
=== added directory 'src/django_nova/tests'
=== added file 'src/django_nova/tests/__init__.py'
--- src/django_nova/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/__init__.py 2011-01-25 23:54:53 +0000
@@ -0,0 +1,1 @@
1from view_tests import *
0\ No newline at end of file2\ No newline at end of file
13
=== added directory 'src/django_nova/tests/templates'
=== added file 'src/django_nova/tests/templates/base-sidebar.html'
=== added file 'src/django_nova/tests/urls.py'
--- src/django_nova/tests/urls.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/urls.py 2011-01-25 23:54:53 +0000
@@ -0,0 +1,32 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2010 United States Government as represented by the
4# Administrator of the National Aeronautics and Space Administration.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
19"""
20URL patterns for testing django-nova views.
21"""
22
23from django.conf.urls.defaults import *
24from django.conf.urls.defaults import *
25
26
27urlpatterns = patterns('',
28 url(r'^projects/', include('django_nova.urls.project')),
29 url(r'^region/', include('django_nova.urls.region')),
30 url(r'^admin/projects/', include('django_nova.urls.admin_project')),
31 url(r'^admin/roles/', include('django_nova.urls.admin_roles')),
32)
0\ No newline at end of file33\ No newline at end of file
134
=== added directory 'src/django_nova/tests/view_tests'
=== added file 'src/django_nova/tests/view_tests/__init__.py'
--- src/django_nova/tests/view_tests/__init__.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/view_tests/__init__.py 2011-01-25 23:54:53 +0000
@@ -0,0 +1,3 @@
1from keypair_tests import *
2from image_tests import *
3from instance_tests import *
0\ No newline at end of file4\ No newline at end of file
15
=== added file 'src/django_nova/tests/view_tests/base.py'
--- src/django_nova/tests/view_tests/base.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/view_tests/base.py 2011-01-25 23:54:53 +0000
@@ -0,0 +1,51 @@
1import mox
2
3from django import test
4from django.conf import settings
5from django.contrib.auth import models as auth_models
6from django_nova import adminclient
7from django_nova import manager
8from django_nova import shortcuts
9
10
11TEST_PROJECT = 'test'
12TEST_USER = 'test'
13TEST_REGION = 'test'
14
15
16class BaseProjectViewTests(test.TestCase):
17 def setUp(self):
18 project = adminclient.ProjectInfo()
19 project.projectname = TEST_PROJECT
20 project.projectManagerId = TEST_USER
21
22 self.mox = mox.Mox()
23 self.user = auth_models.User.objects.create_user(TEST_USER,
24 'test@test.com',
25 password='test')
26 login = self.client.login(username=TEST_USER, password='test')
27 self.failUnless(login, 'Unable to login')
28
29 self.region = adminclient.RegionInfo(name=TEST_REGION,
30 endpoint='http://test:8773/')
31 self.project = manager.ProjectManager(self.user.username,
32 project,
33 self.region)
34 self.mox.StubOutWithMock(shortcuts, 'get_project_or_404')
35 shortcuts.get_project_or_404(mox.IgnoreArg(),
36 'test').AndReturn(self.project)
37
38 def tearDown(self):
39 self.mox.UnsetStubs()
40
41 def assertRedirectsNoFollow(self, response, expected_url):
42 self.assertEqual(response._headers['location'],
43 ('Location', settings.TESTSERVER + expected_url))
44 self.assertEqual(response.status_code, 302)
45
46 def create_key_pair_choices(self, key_names):
47 return [(k, k) for k in key_names]
48
49 def create_instance_type_choices(self):
50 return [('m1.medium', 'm1.medium'),
51 ('m1.large', 'm1.large')]
052
=== added file 'src/django_nova/tests/view_tests/image_tests.py'
--- src/django_nova/tests/view_tests/image_tests.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/view_tests/image_tests.py 2011-01-25 23:54:53 +0000
@@ -0,0 +1,210 @@
1import boto.ec2.image
2import boto.ec2.instance
3import mox
4
5from django.core.urlresolvers import reverse
6from django_nova import forms
7from django_nova import shortcuts
8from django_nova.tests.view_tests.base import BaseProjectViewTests, TEST_PROJECT
9
10
11TEST_IMAGE_ID = 'ami_test'
12TEST_INSTANCE_ID = 'i-abcdefg'
13TEST_KEY = 'foo'
14
15
16class ImageViewTests(BaseProjectViewTests):
17 def setUp(self):
18 self.ami = boto.ec2.image.Image()
19 self.ami.id = TEST_IMAGE_ID
20 setattr(self.ami, 'displayName', TEST_IMAGE_ID)
21 setattr(self.ami, 'description', TEST_IMAGE_ID)
22 super(ImageViewTests, self).setUp()
23
24 def test_index(self):
25 self.mox.StubOutWithMock(self.project, 'get_images')
26 self.mox.StubOutWithMock(forms, 'get_key_pair_choices')
27 self.mox.StubOutWithMock(forms, 'get_instance_type_choices')
28
29 self.project.get_images().AndReturn([])
30 forms.get_key_pair_choices(self.project).AndReturn([])
31 forms.get_instance_type_choices().AndReturn([])
32
33 self.mox.ReplayAll()
34
35 res = self.client.get(reverse('nova_images', args=[TEST_PROJECT]))
36 self.assertEqual(res.status_code, 200)
37 self.assertTemplateUsed(res, 'django_nova/images/index.html')
38 self.assertEqual(len(res.context['image_lists']), 3)
39
40 self.mox.VerifyAll()
41
42 def test_launch_form(self):
43 self.mox.StubOutWithMock(self.project, 'get_image')
44 self.mox.StubOutWithMock(forms, 'get_key_pair_choices')
45 self.mox.StubOutWithMock(forms, 'get_instance_type_choices')
46
47 self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
48 forms.get_key_pair_choices(self.project).AndReturn([])
49 forms.get_instance_type_choices().AndReturn([])
50
51 self.mox.ReplayAll()
52
53 args = [TEST_PROJECT, TEST_IMAGE_ID]
54 res = self.client.get(reverse('nova_images_launch', args=args))
55 self.assertEqual(res.status_code, 200)
56 self.assertTemplateUsed(res, 'django_nova/images/launch.html')
57 self.assertEqual(res.context['ami'].id, TEST_IMAGE_ID)
58
59 self.mox.VerifyAll()
60
61 def test_launch(self):
62 instance = boto.ec2.instance.Instance()
63 instance.id = TEST_INSTANCE_ID
64 instance.image_id = TEST_IMAGE_ID
65 reservation = boto.ec2.instance.Reservation()
66 reservation.instances = [instance]
67
68 self.mox.StubOutWithMock(forms, 'get_key_pair_choices')
69 self.mox.StubOutWithMock(forms, 'get_instance_type_choices')
70 self.mox.StubOutWithMock(self.project, 'run_instances')
71
72 forms.get_key_pair_choices(self.project).AndReturn(
73 self.create_key_pair_choices([TEST_KEY]))
74 forms.get_instance_type_choices().AndReturn(
75 self.create_instance_type_choices())
76 self.project.run_instances(TEST_IMAGE_ID,
77 addressing_type=mox.IgnoreArg(),
78 key_name=TEST_KEY,
79 user_data='',
80 instance_type='m1.medium',
81 min_count='1',
82 max_count='1').AndReturn(reservation)
83 self.mox.ReplayAll()
84
85 url = reverse('nova_images_launch', args=[TEST_PROJECT, TEST_IMAGE_ID])
86 data = {'key_name': TEST_KEY,
87 'count': '1',
88 'size': 'm1.medium',
89 'user_data': ''}
90 res = self.client.post(url, data)
91 self.assertRedirectsNoFollow(res, reverse('nova_instances',
92 args=[TEST_PROJECT]))
93 self.mox.VerifyAll()
94
95 def test_detail(self):
96 self.mox.StubOutWithMock(self.project, 'get_images')
97 self.mox.StubOutWithMock(self.project, 'get_image')
98 self.mox.StubOutWithMock(shortcuts, 'get_user_image_permissions')
99 self.mox.StubOutWithMock(forms, 'get_key_pair_choices')
100 self.mox.StubOutWithMock(forms, 'get_instance_type_choices')
101
102 self.project.get_images().AndReturn([self.ami])
103 self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
104 shortcuts.get_user_image_permissions(mox.IgnoreArg(),
105 TEST_PROJECT).AndReturn(True)
106 forms.get_key_pair_choices(self.project).AndReturn(
107 self.create_key_pair_choices([TEST_KEY]))
108 forms.get_instance_type_choices().AndReturn(
109 self.create_instance_type_choices())
110
111 self.mox.ReplayAll()
112
113 res = self.client.get(reverse('nova_images_detail',
114 args=[TEST_PROJECT, TEST_IMAGE_ID]))
115 self.assertEqual(res.status_code, 200)
116 self.assertTemplateUsed(res, 'django_nova/images/index.html')
117 self.assertEqual(res.context['ami'].id, TEST_IMAGE_ID)
118
119 self.mox.VerifyAll()
120
121 def test_remove_form(self):
122 self.mox.StubOutWithMock(self.project, 'get_image')
123 self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
124 self.mox.ReplayAll()
125
126 res = self.client.get(reverse('nova_images_remove',
127 args=[TEST_PROJECT, TEST_IMAGE_ID]))
128 self.assertEqual(res.status_code, 200)
129 self.assertTemplateUsed(res, 'django_nova/images/detail_list.html')
130 self.assertEqual(res.context['ami'].id, TEST_IMAGE_ID)
131
132 self.mox.VerifyAll()
133
134 def test_remove(self):
135 self.mox.StubOutWithMock(self.project, 'deregister_image')
136 self.project.deregister_image(TEST_IMAGE_ID).AndReturn(True)
137 self.mox.ReplayAll()
138
139 res = self.client.post(reverse('nova_images_remove',
140 args=[TEST_PROJECT, TEST_IMAGE_ID]))
141 self.assertRedirectsNoFollow(res, reverse('nova_images',
142 args=[TEST_PROJECT]))
143
144 self.mox.VerifyAll()
145
146 def test_make_public(self):
147 self.mox.StubOutWithMock(self.project, 'get_image')
148 self.mox.StubOutWithMock(self.project, 'modify_image_attribute')
149
150 self.ami.is_public = False
151 self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
152 self.project.modify_image_attribute(TEST_IMAGE_ID,
153 attribute='launchPermission',
154 operation='add').AndReturn(True)
155 self.mox.ReplayAll()
156
157 res = self.client.post(reverse('nova_images_privacy',
158 args=[TEST_PROJECT, TEST_IMAGE_ID]))
159 self.assertRedirectsNoFollow(res, reverse('nova_images_detail',
160 args=[TEST_PROJECT, TEST_IMAGE_ID]))
161 self.mox.VerifyAll()
162
163 def test_make_private(self):
164 self.mox.StubOutWithMock(self.project, 'get_image')
165 self.mox.StubOutWithMock(self.project, 'modify_image_attribute')
166
167 self.ami.is_public = True
168 self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
169 self.project.modify_image_attribute(TEST_IMAGE_ID,
170 attribute='launchPermission',
171 operation='remove').AndReturn(True)
172 self.mox.ReplayAll()
173
174 args = [TEST_PROJECT, TEST_IMAGE_ID]
175 res = self.client.post(reverse('nova_images_privacy', args=args))
176 self.assertRedirectsNoFollow(res, reverse('nova_images_detail',
177 args=args))
178 self.mox.VerifyAll()
179
180 def test_update_form(self):
181 self.mox.StubOutWithMock(self.project, 'get_image')
182 self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
183 self.mox.ReplayAll()
184
185 args = [TEST_PROJECT, TEST_IMAGE_ID]
186 res = self.client.get(reverse('nova_images_update', args=args))
187 self.assertEqual(res.status_code, 200)
188 self.assertTemplateUsed(res, 'django_nova/images/edit.html')
189 self.assertEqual(res.context['ami'].id, TEST_IMAGE_ID)
190
191 self.mox.VerifyAll()
192
193 def test_update(self):
194 self.mox.StubOutWithMock(self.project, 'get_image')
195 self.mox.StubOutWithMock(self.project, 'update_image')
196
197 self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
198 self.project.update_image(TEST_IMAGE_ID, 'test', 'test').AndReturn(True)
199
200 self.mox.ReplayAll()
201
202 args = [TEST_PROJECT, TEST_IMAGE_ID]
203 data = {'nickname': 'test',
204 'description': 'test'}
205 url = reverse('nova_images_update', args=args)
206 res = self.client.post(url, data)
207 expected_url = reverse('nova_images_detail', args=args)
208 self.assertRedirectsNoFollow(res, expected_url)
209
210 self.mox.VerifyAll()
0211
=== added file 'src/django_nova/tests/view_tests/instance_tests.py'
--- src/django_nova/tests/view_tests/instance_tests.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/view_tests/instance_tests.py 2011-01-25 23:54:53 +0000
@@ -0,0 +1,45 @@
1import boto.ec2.instance
2import mox
3
4from django.core.urlresolvers import reverse
5from django_nova.tests.view_tests.base import BaseProjectViewTests, TEST_PROJECT
6
7
8TEST_INSTANCE_ID = 'i-abcdefgh'
9
10
11class InstanceViewTests(BaseProjectViewTests):
12 def test_index(self):
13 self.mox.StubOutWithMock(self.project, 'get_instances')
14 self.project.get_instances().AndReturn([])
15
16 self.mox.ReplayAll()
17
18 res = self.client.get(reverse('nova_instances', args=[TEST_PROJECT]))
19 self.assertEqual(res.status_code, 200)
20 self.assertTemplateUsed(res, 'django_nova/instances/index.html')
21 self.assertEqual(len(res.context['instances']), 0)
22
23 self.mox.VerifyAll()
24
25 def test_detail(self):
26 instance = boto.ec2.instance.Instance()
27 instance.id = TEST_INSTANCE_ID
28 instance.displayName = instance.id
29 instance.displayDescription = instance.id
30
31 self.mox.StubOutWithMock(self.project, 'get_instance')
32 self.project.get_instance(instance.id).AndReturn(instance)
33 self.mox.StubOutWithMock(self.project, 'get_instances')
34 self.project.get_instances().AndReturn([instance])
35
36 self.mox.ReplayAll()
37
38 res = self.client.get(reverse('nova_instances_detail',
39 args=[TEST_PROJECT, TEST_INSTANCE_ID]))
40 self.assertEqual(res.status_code, 200)
41 self.assertTemplateUsed(res, 'django_nova/instances/index.html')
42 self.assertEqual(res.context['selected_instance'].id, instance.id)
43
44 self.mox.VerifyAll()
45
046
=== added file 'src/django_nova/tests/view_tests/keypair_tests.py'
--- src/django_nova/tests/view_tests/keypair_tests.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/view_tests/keypair_tests.py 2011-01-25 23:54:53 +0000
@@ -0,0 +1,71 @@
1import boto.ec2.keypair
2import mox
3
4from django.core.urlresolvers import reverse
5from django_nova.tests.view_tests.base import BaseProjectViewTests, TEST_PROJECT
6
7
8TEST_KEY = 'test_key'
9
10
11class KeyPairViewTests(BaseProjectViewTests):
12 def test_index(self):
13 self.mox.StubOutWithMock(self.project, 'get_key_pairs')
14 self.project.get_key_pairs().AndReturn([])
15
16 self.mox.ReplayAll()
17
18 response = self.client.get(reverse('nova_keypairs',
19 args=[TEST_PROJECT]))
20 self.assertEqual(response.status_code, 200)
21 self.assertTemplateUsed(response, 'django_nova/keypairs/index.html')
22 self.assertEqual(len(response.context['keypairs']), 0)
23
24 self.mox.VerifyAll()
25
26 def test_add_keypair(self):
27 key = boto.ec2.keypair.KeyPair()
28 key.name = TEST_KEY
29
30 self.mox.StubOutWithMock(self.project, 'create_key_pair')
31 self.project.create_key_pair(key.name).AndReturn(key)
32 self.mox.StubOutWithMock(self.project, 'has_key_pair')
33 self.project.has_key_pair(key.name).AndReturn(False)
34
35 self.mox.ReplayAll()
36
37 url = reverse('nova_keypairs_add', args=[TEST_PROJECT])
38 data = {'js': '0', 'name': key.name}
39 res = self.client.post(url,
40 data)
41 self.assertEqual(res.status_code, 200)
42 self.assertEqual(res['Content-Type'], 'application/binary')
43
44 self.mox.VerifyAll()
45
46 def test_delete_keypair(self):
47 self.mox.StubOutWithMock(self.project, 'delete_key_pair')
48 self.project.delete_key_pair(TEST_KEY).AndReturn(None)
49
50 self.mox.ReplayAll()
51
52 data = {'key_name': TEST_KEY}
53 url = reverse('nova_keypairs_delete', args=[TEST_PROJECT])
54 res = self.client.post(url, data)
55 self.assertRedirectsNoFollow(res, reverse('nova_keypairs',
56 args=[TEST_PROJECT]))
57
58 self.mox.VerifyAll()
59
60 def test_download_keypair(self):
61 material = 'abcdefgh'
62 session = self.client.session
63 session['key.%s' % TEST_KEY] = material
64 session.save()
65
66 res = self.client.get(reverse('nova_keypairs_download',
67 args=['test', TEST_KEY]))
68 self.assertEqual(res.status_code, 200)
69 self.assertEqual(res['Content-Type'], 'application/binary')
70 self.assertContains(res, material)
71
072
=== modified file 'src/django_nova/testsettings.py'
--- src/django_nova/testsettings.py 2011-01-12 20:02:06 +0000
+++ src/django_nova/testsettings.py 2011-01-25 23:54:53 +0000
@@ -1,5 +1,19 @@
1import os
2
3ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
4DEBUG = True
5TESTSERVER = 'http://testserver'
1DATABASE_ENGINE = 'sqlite3'6DATABASE_ENGINE = 'sqlite3'
2DATABASE_NAME = '/tmp/django-nova.db'7DATABASE_NAME = '/tmp/django-nova.db'
3INSTALLED_APPS = ['django_nova']8INSTALLED_APPS = ['django.contrib.auth',
4ROOT_URLCONF = ['django_nova.urls']9 'django.contrib.contenttypes',
510 'django.contrib.sessions',
11 'django_nova']
12ROOT_URLCONF = 'django_nova.tests.urls'
13TEMPLATE_DIRS = (
14 os.path.join(ROOT_PATH, 'tests', 'templates')
15)
16NOVA_DEFAULT_ENDPOINT = 'none'
17NOVA_DEFAULT_REGION = 'test'
18NOVA_ACCESS_KEY = 'test'
19NOVA_SECRET_KEY = 'test'
620
=== modified file 'src/django_nova/views/images.py'
--- src/django_nova/views/images.py 2011-01-24 23:17:58 +0000
+++ src/django_nova/views/images.py 2011-01-25 23:54:53 +0000
@@ -30,8 +30,8 @@
30from django.shortcuts import redirect, render_to_response30from django.shortcuts import redirect, render_to_response
31from django_nova import exceptions31from django_nova import exceptions
32from django_nova import forms32from django_nova import forms
33from django_nova import shortcuts
33from django_nova.exceptions import handle_nova_error34from django_nova.exceptions import handle_nova_error
34from django_nova.shortcuts import get_project_or_404, get_user_image_permissions
3535
3636
37def _image_lists(images, project_id):37def _image_lists(images, project_id):
@@ -52,7 +52,7 @@
52@login_required52@login_required
53@handle_nova_error53@handle_nova_error
54def index(request, project_id):54def index(request, project_id):
55 project = get_project_or_404(request, project_id)55 project = shortcuts.get_project_or_404(request, project_id)
56 images = project.get_images()56 images = project.get_images()
5757
58 return render_to_response('django_nova/images/index.html', {58 return render_to_response('django_nova/images/index.html', {
@@ -66,7 +66,7 @@
66@login_required66@login_required
67@handle_nova_error67@handle_nova_error
68def launch(request, project_id, image_id):68def launch(request, project_id, image_id):
69 project = get_project_or_404(request, project_id)69 project = shortcuts.get_project_or_404(request, project_id)
7070
71 if request.method == 'POST':71 if request.method == 'POST':
72 form = forms.LaunchInstanceForm(project, request.POST)72 form = forms.LaunchInstanceForm(project, request.POST)
@@ -107,14 +107,15 @@
107@login_required107@login_required
108@handle_nova_error108@handle_nova_error
109def detail(request, project_id, image_id):109def detail(request, project_id, image_id):
110 project = get_project_or_404(request, project_id)110 project = shortcuts.get_project_or_404(request, project_id)
111 images = project.get_images()111 images = project.get_images()
112112
113 ami = project.get_image(image_id)113 ami = project.get_image(image_id)
114 can_modify = shortcuts.get_user_image_permissions(request.user.username,
115 project_id)
114116
115 if not ami:117 if not ami:
116 raise http.Http404()118 raise http.Http404()
117
118 return render_to_response('django_nova/images/index.html', {119 return render_to_response('django_nova/images/index.html', {
119 'form': forms.LaunchInstanceForm(project),120 'form': forms.LaunchInstanceForm(project),
120 'update_form': forms.UpdateImageForm(ami),121 'update_form': forms.UpdateImageForm(ami),
@@ -123,14 +124,14 @@
123 'images': images,124 'images': images,
124 'image_lists': _image_lists(images, project_id),125 'image_lists': _image_lists(images, project_id),
125 'ami': ami,126 'ami': ami,
126 'can_modify': get_user_image_permissions(request.user.username, project_id),127 'can_modify': can_modify,
127 }, context_instance = template.RequestContext(request))128 }, context_instance = template.RequestContext(request))
128129
129130
130@login_required131@login_required
131@handle_nova_error132@handle_nova_error
132def remove(request, project_id, image_id):133def remove(request, project_id, image_id):
133 project = get_project_or_404(request, project_id)134 project = shortcuts.get_project_or_404(request, project_id)
134135
135 if request.method == 'POST':136 if request.method == 'POST':
136 try:137 try:
@@ -159,34 +160,27 @@
159@login_required160@login_required
160@handle_nova_error161@handle_nova_error
161def privacy(request, project_id, image_id):162def privacy(request, project_id, image_id):
162 project = get_project_or_404(request, project_id)163 project = shortcuts.get_project_or_404(request, project_id)
163 conn = project.get_nova_connection()
164164
165 if request.method == 'POST':165 if request.method == 'POST':
166 ami = project.get_image(image_id)166 ami = project.get_image(image_id)
167167
168 if ami.is_public:168 if ami.is_public:
169 # TODO(devcamcar): create a wrapper in manager.ProjectManager
170 # for modifying image attributes.
171 try:169 try:
172 conn.modify_image_attribute(image_id,170 project.modify_image_attribute(image_id,
173 attribute='launchPermission',171 attribute='launchPermission',
174 operation='remove',172 operation='remove')
175 groups='all',)173 except exceptions.NovaApiError, e:
176 except boto.exception.EC2ResponseError, e:
177 messages.error(request,174 messages.error(request,
178 'Unable to make image private: %s - %s' %175 'Unable to make image private: %s' % e.message)
179 (e.code, e.message,))
180 else:176 else:
181 try:177 try:
182 conn.modify_image_attribute(image_id,178 project.modify_image_attribute(image_id,
183 attribute='launchPermission',179 attribute='launchPermission',
184 operation='add',180 operation='add')
185 groups='all')181 except exceptions.NovaApiError, e:
186 except boto.exception.EC2ResponseError, e:
187 messages.error(request,182 messages.error(request,
188 'Unable to make image public: %s - %s' %183 'Unable to make image public: %s' % e.message)
189 (e.code, e.message,))
190184
191 return redirect('nova_images_detail', project_id, image_id)185 return redirect('nova_images_detail', project_id, image_id)
192186
@@ -194,7 +188,7 @@
194@login_required188@login_required
195@handle_nova_error189@handle_nova_error
196def update(request, project_id, image_id):190def update(request, project_id, image_id):
197 project = get_project_or_404(request, project_id)191 project = shortcuts.get_project_or_404(request, project_id)
198 ami = project.get_image(image_id)192 ami = project.get_image(image_id)
199193
200 if request.method == 'POST':194 if request.method == 'POST':
@@ -221,7 +215,6 @@
221 'form': form,215 'form': form,
222 'region': project.region,216 'region': project.region,
223 'project': project,217 'project': project,
224 'project_list': project_list,
225 'ami': ami,218 'ami': ami,
226 }, context_instance = template.RequestContext(request))219 }, context_instance = template.RequestContext(request))
227 else:220 else:
228221
=== modified file 'src/django_nova/views/instances.py'
--- src/django_nova/views/instances.py 2011-01-18 23:07:26 +0000
+++ src/django_nova/views/instances.py 2011-01-25 23:54:53 +0000
@@ -27,14 +27,14 @@
27from django.shortcuts import redirect, render_to_response27from django.shortcuts import redirect, render_to_response
28from django_nova import exceptions28from django_nova import exceptions
29from django_nova import forms as nova_forms29from django_nova import forms as nova_forms
30from django_nova import shortcuts
30from django_nova.exceptions import handle_nova_error31from django_nova.exceptions import handle_nova_error
31from django_nova.shortcuts import get_project_or_404
3232
3333
34@login_required34@login_required
35@handle_nova_error35@handle_nova_error
36def index(request, project_id):36def index(request, project_id):
37 project = get_project_or_404(request, project_id)37 project = shortcuts.get_project_or_404(request, project_id)
38 instances = sorted(project.get_instances(), key=lambda k: k.public_dns_name)38 instances = sorted(project.get_instances(), key=lambda k: k.public_dns_name)
3939
40 return render_to_response('django_nova/instances/index.html', {40 return render_to_response('django_nova/instances/index.html', {
@@ -48,7 +48,7 @@
48@login_required48@login_required
49@handle_nova_error49@handle_nova_error
50def detail(request, project_id, instance_id):50def detail(request, project_id, instance_id):
51 project = get_project_or_404(request, project_id)51 project = shortcuts.get_project_or_404(request, project_id)
52 instance = project.get_instance(instance_id)52 instance = project.get_instance(instance_id)
53 instances = sorted(project.get_instances(), key=lambda k: k.public_dns_name)53 instances = sorted(project.get_instances(), key=lambda k: k.public_dns_name)
5454
@@ -68,7 +68,7 @@
68@login_required68@login_required
69@handle_nova_error69@handle_nova_error
70def performance(request, project_id, instance_id):70def performance(request, project_id, instance_id):
71 project = get_project_or_404(request, project_id)71 project = shortcuts.get_project_or_404(request, project_id)
72 instance = project.get_instance(instance_id)72 instance = project.get_instance(instance_id)
7373
74 if not instance:74 if not instance:
@@ -88,7 +88,7 @@
88 if not request.user.is_authenticated():88 if not request.user.is_authenticated():
89 return http.HttpResponseForbidden()89 return http.HttpResponseForbidden()
9090
91 project = get_project_or_404(request, project_id)91 project = shortcuts.get_project_or_404(request, project_id)
92 instances = sorted(project.get_instances(), key=lambda k: k.public_dns_name)92 instances = sorted(project.get_instances(), key=lambda k: k.public_dns_name)
9393
94 return render_to_response('django_nova/instances/_instances_list.html', {94 return render_to_response('django_nova/instances/_instances_list.html', {
@@ -103,7 +103,7 @@
103 if not request.user.is_authenticated():103 if not request.user.is_authenticated():
104 return http.HttpResponseForbidden()104 return http.HttpResponseForbidden()
105105
106 project = get_project_or_404(request, project_id)106 project = shortcuts.get_project_or_404(request, project_id)
107 instance = project.get_instance(instance_id)107 instance = project.get_instance(instance_id)
108 instances = sorted(project.get_instances(), key=lambda k: k.public_dns_name)108 instances = sorted(project.get_instances(), key=lambda k: k.public_dns_name)
109109
@@ -117,7 +117,7 @@
117@login_required117@login_required
118@handle_nova_error118@handle_nova_error
119def terminate(request, project_id):119def terminate(request, project_id):
120 project = get_project_or_404(request, project_id)120 project = shortcuts.get_project_or_404(request, project_id)
121121
122 if request.method == 'POST':122 if request.method == 'POST':
123 instance_id = request.POST['instance_id']123 instance_id = request.POST['instance_id']
@@ -138,7 +138,7 @@
138@login_required138@login_required
139@handle_nova_error139@handle_nova_error
140def console(request, project_id, instance_id):140def console(request, project_id, instance_id):
141 project = get_project_or_404(request, project_id)141 project = shortcuts.get_project_or_404(request, project_id)
142 conn = project.get_nova_connection()142 conn = project.get_nova_connection()
143 console = conn.get_console_output(instance_id)143 console = conn.get_console_output(instance_id)
144 response = http.HttpResponse(mimetype='text/plain')144 response = http.HttpResponse(mimetype='text/plain')
@@ -151,7 +151,7 @@
151@login_required151@login_required
152@handle_nova_error152@handle_nova_error
153def graph(request, project_id, instance_id, graph_name):153def graph(request, project_id, instance_id, graph_name):
154 project = get_project_or_404(request, project_id)154 project = shortcuts.get_project_or_404(request, project_id)
155 graph = project.get_instance_graph(instance_id, graph_name)155 graph = project.get_instance_graph(instance_id, graph_name)
156156
157 if graph is None:157 if graph is None:
@@ -166,10 +166,10 @@
166@login_required166@login_required
167@handle_nova_error167@handle_nova_error
168def update(request, project_id, instance_id):168def update(request, project_id, instance_id):
169 project = get_project_or_404(request, project_id)169 project = shortcuts.get_project_or_404(request, project_id)
170 instance = project.get_instance(instance_id)170 instance = project.get_instance(instance_id)
171171
172 if instance is None:172 if not instance:
173 raise http.Http404()173 raise http.Http404()
174174
175 if request.method == 'POST':175 if request.method == 'POST':
176176
=== modified file 'src/django_nova/views/keypairs.py'
--- src/django_nova/views/keypairs.py 2011-01-18 23:07:26 +0000
+++ src/django_nova/views/keypairs.py 2011-01-25 23:54:53 +0000
@@ -27,14 +27,14 @@
27from django.shortcuts import redirect, render_to_response27from django.shortcuts import redirect, render_to_response
28from django_nova import exceptions28from django_nova import exceptions
29from django_nova import forms29from django_nova import forms
30from django_nova import shortcuts
30from django_nova.exceptions import handle_nova_error31from django_nova.exceptions import handle_nova_error
31from django_nova.shortcuts import get_project_or_404
3232
3333
34@login_required34@login_required
35@handle_nova_error35@handle_nova_error
36def index(request, project_id, download_key=None):36def index(request, project_id, download_key=None):
37 project = get_project_or_404(request, project_id)37 project = shortcuts.get_project_or_404(request, project_id)
38 keypairs = project.get_key_pairs()38 keypairs = project.get_key_pairs()
3939
40 return render_to_response('django_nova/keypairs/index.html', {40 return render_to_response('django_nova/keypairs/index.html', {
@@ -48,7 +48,7 @@
48@login_required48@login_required
49@handle_nova_error49@handle_nova_error
50def add(request, project_id):50def add(request, project_id):
51 project = get_project_or_404(request, project_id)51 project = shortcuts.get_project_or_404(request, project_id)
5252
53 if request.method == 'POST':53 if request.method == 'POST':
54 form = forms.CreateKeyPairForm(project, request.POST)54 form = forms.CreateKeyPairForm(project, request.POST)
@@ -87,7 +87,7 @@
87@login_required87@login_required
88@handle_nova_error88@handle_nova_error
89def delete(request, project_id):89def delete(request, project_id):
90 project = get_project_or_404(request, project_id)90 project = shortcuts.get_project_or_404(request, project_id)
9191
92 if request.method == 'POST':92 if request.method == 'POST':
93 key_name = request.POST['key_name']93 key_name = request.POST['key_name']
@@ -108,7 +108,7 @@
108@handle_nova_error108@handle_nova_error
109def download(request, project_id, key_name):109def download(request, project_id, key_name):
110 # Ensure the project exists.110 # Ensure the project exists.
111 get_project_or_404(request, project_id)111 shortcuts.get_project_or_404(request, project_id)
112112
113 try:113 try:
114 material = request.session.pop('key.%s' % key_name)114 material = request.session.pop('key.%s' % key_name)

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: