~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

Viewing changes to nova/tests/api/openstack/compute/contrib/test_flavor_access.py

  • Committer: Package Import Robot
  • Author(s): Adam Gandelman, Adam Gandelman, Chuck Short
  • Date: 2012-08-27 15:37:18 UTC
  • mfrom: (1.1.60)
  • Revision ID: package-import@ubuntu.com-20120827153718-lj8er44eqqz1gsrj
Tags: 2012.2~rc1~20120827.15815-0ubuntu1
[ Adam Gandelman ]
* New upstream release.

[ Chuck Short ]
* debian/patches/0001-Update-tools-hacking-for-pep8-1.2-and-
  beyond.patch: Dropped we dont run pep8 tests anymore.
* debian/control: Drop pep8 build depends
* debian/*.upstart.in: Make sure we transition correctly from runlevel
  1 to 2. (LP: #820694)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2012 OpenStack LLC.
 
2
# All Rights Reserved.
 
3
#
 
4
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
5
#    not use this file except in compliance with the License. You may obtain
 
6
#    a copy of the License at
 
7
#
 
8
#         http://www.apache.org/licenses/LICENSE-2.0
 
9
#
 
10
#    Unless required by applicable law or agreed to in writing, software
 
11
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
12
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
13
#    License for the specific language governing permissions and limitations
 
14
#    under the License.
 
15
 
 
16
import datetime
 
17
 
 
18
from lxml import etree
 
19
from webob import exc
 
20
 
 
21
from nova.api.openstack.compute.contrib import flavor_access
 
22
from nova.api.openstack.compute import flavors
 
23
from nova.compute import instance_types
 
24
from nova import context
 
25
from nova import exception
 
26
from nova import test
 
27
from nova.tests.api.openstack import fakes
 
28
 
 
29
 
 
30
def generate_instance_type(flavorid, ispublic):
 
31
    return {
 
32
        'id': flavorid,
 
33
        'flavorid': str(flavorid),
 
34
        'root_gb': 1,
 
35
        'ephemeral_gb': 1,
 
36
        'name': u'test',
 
37
        'deleted': False,
 
38
        'created_at': datetime.datetime(2012, 1, 1, 1, 1, 1, 1),
 
39
        'updated_at': None,
 
40
        'memory_mb': 512,
 
41
        'vcpus': 1,
 
42
        'swap': 512,
 
43
        'rxtx_factor': 1.0,
 
44
        'extra_specs': {},
 
45
        'deleted_at': None,
 
46
        'vcpu_weight': None,
 
47
        'is_public': bool(ispublic)
 
48
    }
 
49
 
 
50
 
 
51
INSTANCE_TYPES = {
 
52
        '0': generate_instance_type(0, True),
 
53
        '1': generate_instance_type(1, True),
 
54
        '2': generate_instance_type(2, False),
 
55
        '3': generate_instance_type(3, False)}
 
56
 
 
57
 
 
58
ACCESS_LIST = [{'flavor_id': '2', 'project_id': 'proj2'},
 
59
               {'flavor_id': '2', 'project_id': 'proj3'},
 
60
               {'flavor_id': '3', 'project_id': 'proj3'}]
 
61
 
 
62
 
 
63
def fake_get_instance_type_access_by_flavor_id(flavorid):
 
64
    res = []
 
65
    for access in ACCESS_LIST:
 
66
        if access['flavor_id'] == flavorid:
 
67
            res.append(access)
 
68
    return res
 
69
 
 
70
 
 
71
def fake_get_instance_type_by_flavor_id(flavorid):
 
72
    return INSTANCE_TYPES[flavorid]
 
73
 
 
74
 
 
75
def _has_flavor_access(flavorid, projectid):
 
76
    for access in ACCESS_LIST:
 
77
        if access['flavor_id'] == flavorid and \
 
78
           access['project_id'] == projectid:
 
79
                return True
 
80
    return False
 
81
 
 
82
 
 
83
def fake_get_all_types(context, inactive=0, filters=None):
 
84
    if filters == None or filters['is_public'] == None:
 
85
        return INSTANCE_TYPES
 
86
 
 
87
    res = {}
 
88
    for k, v in INSTANCE_TYPES.iteritems():
 
89
        if filters['is_public'] and _has_flavor_access(k, context.project_id):
 
90
            res.update({k: v})
 
91
            continue
 
92
        if v['is_public'] == filters['is_public']:
 
93
            res.update({k: v})
 
94
 
 
95
    return res
 
96
 
 
97
 
 
98
class FakeRequest(object):
 
99
    environ = {"nova.context": context.get_admin_context()}
 
100
 
 
101
 
 
102
class FlavorAccessTest(test.TestCase):
 
103
    def setUp(self):
 
104
        super(FlavorAccessTest, self).setUp()
 
105
        self.flavor_controller = flavors.Controller()
 
106
        self.flavor_access_controller = flavor_access.FlavorAccessController()
 
107
        self.flavor_action_controller = flavor_access.FlavorActionController()
 
108
        self.req = FakeRequest()
 
109
        self.context = self.req.environ['nova.context']
 
110
        self.stubs.Set(instance_types, 'get_instance_type_by_flavor_id',
 
111
                       fake_get_instance_type_by_flavor_id)
 
112
        self.stubs.Set(instance_types, 'get_all_types', fake_get_all_types)
 
113
        self.stubs.Set(instance_types, 'get_instance_type_access_by_flavor_id',
 
114
                       fake_get_instance_type_access_by_flavor_id)
 
115
 
 
116
    def _verify_flavor_list(self, result, expected):
 
117
        # result already sorted by flavor_id
 
118
        self.assertEqual(len(result), len(expected))
 
119
 
 
120
        for d1, d2 in zip(result, expected):
 
121
            self.assertEqual(d1['id'], d2['id'])
 
122
 
 
123
    def test_list_flavor_access_public(self):
 
124
        # query os-flavor-access on public flavor should return 404
 
125
        req = fakes.HTTPRequest.blank('/v2/fake/flavors/os-flavor-access',
 
126
                                      use_admin_context=True)
 
127
        self.assertRaises(exc.HTTPNotFound,
 
128
                          self.flavor_access_controller.index,
 
129
                          self.req, '1')
 
130
 
 
131
    def test_list_flavor_access_private(self):
 
132
        expected = {'flavor_access': [
 
133
            {'flavor_id': '2', 'tenant_id': 'proj2'},
 
134
            {'flavor_id': '2', 'tenant_id': 'proj3'}]}
 
135
        result = self.flavor_access_controller.index(self.req, '2')
 
136
        self.assertEqual(result, expected)
 
137
 
 
138
    def test_list_flavor_with_admin_default_proj1(self):
 
139
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
 
140
        req = fakes.HTTPRequest.blank('/v2/fake/flavors',
 
141
                                      use_admin_context=True)
 
142
        req.environ['nova.context'].project_id = 'proj1'
 
143
        result = self.flavor_controller.index(req)
 
144
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
145
 
 
146
    def test_list_flavor_with_admin_default_proj2(self):
 
147
        expected = {'flavors': [{'id': '0'}, {'id': '1'}, {'id': '2'}]}
 
148
        req = fakes.HTTPRequest.blank('/v2/fake/flavors',
 
149
                                      use_admin_context=True)
 
150
        req.environ['nova.context'].project_id = 'proj2'
 
151
        result = self.flavor_controller.index(req)
 
152
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
153
 
 
154
    def test_list_flavor_with_admin_ispublic_true(self):
 
155
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
 
156
        req = fakes.HTTPRequest.blank('/v2/fake/flavors?is_public=true',
 
157
                                      use_admin_context=True)
 
158
        result = self.flavor_controller.index(req)
 
159
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
160
 
 
161
    def test_list_flavor_with_admin_ispublic_false(self):
 
162
        expected = {'flavors': [{'id': '2'}, {'id': '3'}]}
 
163
        req = fakes.HTTPRequest.blank('/v2/fake/flavors?is_public=false',
 
164
                                      use_admin_context=True)
 
165
        result = self.flavor_controller.index(req)
 
166
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
167
 
 
168
    def test_list_flavor_with_admin_ispublic_false_proj2(self):
 
169
        expected = {'flavors': [{'id': '2'}, {'id': '3'}]}
 
170
        req = fakes.HTTPRequest.blank('/v2/fake/flavors?is_public=false',
 
171
                                      use_admin_context=True)
 
172
        req.environ['nova.context'].project_id = 'proj2'
 
173
        result = self.flavor_controller.index(req)
 
174
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
175
 
 
176
    def test_list_flavor_with_admin_ispublic_none(self):
 
177
        expected = {'flavors': [{'id': '0'}, {'id': '1'}, {'id': '2'},
 
178
                                {'id': '3'}]}
 
179
        req = fakes.HTTPRequest.blank('/v2/fake/flavors?is_public=none',
 
180
                                      use_admin_context=True)
 
181
        result = self.flavor_controller.index(req)
 
182
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
183
 
 
184
    def test_list_flavor_with_no_admin_default(self):
 
185
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
 
186
        req = fakes.HTTPRequest.blank('/v2/fake/flavors',
 
187
                                      use_admin_context=False)
 
188
        result = self.flavor_controller.index(req)
 
189
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
190
 
 
191
    def test_list_flavor_with_no_admin_ispublic_true(self):
 
192
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
 
193
        req = fakes.HTTPRequest.blank('/v2/fake/flavors?is_public=true',
 
194
                                      use_admin_context=False)
 
195
        result = self.flavor_controller.index(req)
 
196
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
197
 
 
198
    def test_list_flavor_with_no_admin_ispublic_false(self):
 
199
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
 
200
        req = fakes.HTTPRequest.blank('/v2/fake/flavors?is_public=false',
 
201
                                      use_admin_context=False)
 
202
        result = self.flavor_controller.index(req)
 
203
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
204
 
 
205
    def test_list_flavor_with_no_admin_ispublic_none(self):
 
206
        expected = {'flavors': [{'id': '0'}, {'id': '1'}]}
 
207
        req = fakes.HTTPRequest.blank('/v2/fake/flavors?is_public=none',
 
208
                                      use_admin_context=False)
 
209
        result = self.flavor_controller.index(req)
 
210
        self._verify_flavor_list(result['flavors'], expected['flavors'])
 
211
 
 
212
    def test_add_tenant_access(self):
 
213
        def stub_add_instance_type_access(flavorid, projectid, ctxt=None):
 
214
            self.assertEqual('3', flavorid, "flavorid")
 
215
            self.assertEqual("proj2", projectid, "projectid")
 
216
        self.stubs.Set(instance_types, 'add_instance_type_access',
 
217
                       stub_add_instance_type_access)
 
218
        expected = {'flavor_access':
 
219
            [{'flavor_id': '3', 'tenant_id': 'proj3'}]}
 
220
        body = {'addTenantAccess': {'tenant': 'proj2'}}
 
221
        req = fakes.HTTPRequest.blank('/v2/fake/flavors/2/action',
 
222
                                      use_admin_context=True)
 
223
        result = self.flavor_action_controller.\
 
224
            _addTenantAccess(req, '3', body)
 
225
        self.assertEqual(result, expected)
 
226
 
 
227
    def test_add_tenant_access_with_already_added_access(self):
 
228
        def stub_add_instance_type_access(flavorid, projectid, ctxt=None):
 
229
            raise exception.FlavorAccessExists()
 
230
        self.stubs.Set(instance_types, 'add_instance_type_access',
 
231
                       stub_add_instance_type_access)
 
232
        body = {'addTenantAccess': {'tenant': 'proj2'}}
 
233
        req = fakes.HTTPRequest.blank('/v2/fake/flavors/2/action',
 
234
                                      use_admin_context=True)
 
235
        self.assertRaises(exc.HTTPConflict,
 
236
                          self.flavor_action_controller._addTenantAccess,
 
237
                          self.req, '3', body)
 
238
 
 
239
    def test_remove_tenant_access_with_bad_access(self):
 
240
        def stub_remove_instance_type_access(flavorid, projectid, ctxt=None):
 
241
            self.assertEqual('3', flavorid, "flavorid")
 
242
            self.assertEqual("proj2", projectid, "projectid")
 
243
        expected = {'flavor_access': [
 
244
            {'flavor_id': '3', 'tenant_id': 'proj3'}]}
 
245
        self.stubs.Set(instance_types, 'remove_instance_type_access',
 
246
                       stub_remove_instance_type_access)
 
247
        body = {'removeTenantAccess': {'tenant': 'proj2'}}
 
248
        req = fakes.HTTPRequest.blank('/v2/fake/flavors/2/action',
 
249
                                      use_admin_context=True)
 
250
        result = self.flavor_action_controller.\
 
251
            _addTenantAccess(req, '3', body)
 
252
        self.assertEqual(result, expected)
 
253
 
 
254
    def test_remove_tenant_access_with_bad_access(self):
 
255
        def stub_remove_instance_type_access(flavorid, projectid, ctxt=None):
 
256
            raise exception.FlavorAccessNotFound()
 
257
        self.stubs.Set(instance_types, 'remove_instance_type_access',
 
258
                       stub_remove_instance_type_access)
 
259
        body = {'removeTenantAccess': {'tenant': 'proj2'}}
 
260
        req = fakes.HTTPRequest.blank('/v2/fake/flavors/2/action',
 
261
                                      use_admin_context=True)
 
262
        self.assertRaises(exc.HTTPNotFound,
 
263
                          self.flavor_action_controller._removeTenantAccess,
 
264
                          self.req, '3', body)
 
265
 
 
266
 
 
267
class FlavorAccessSerializerTest(test.TestCase):
 
268
    def test_xml_declaration(self):
 
269
        access_list = [{'flavor_id': '2', 'tenant_id': 'proj2'}]
 
270
        serializer = flavor_access.FlavorAccessTemplate()
 
271
        output = serializer.serialize(access_list)
 
272
        has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
 
273
        self.assertTrue(has_dec)
 
274
 
 
275
    def test_serializer_empty(self):
 
276
        access_list = []
 
277
 
 
278
        serializer = flavor_access.FlavorAccessTemplate()
 
279
        text = serializer.serialize(access_list)
 
280
        tree = etree.fromstring(text)
 
281
        self.assertEqual(len(tree), 0)
 
282
 
 
283
    def test_serializer(self):
 
284
        access_list = [{'flavor_id': '2', 'tenant_id': 'proj2'},
 
285
                       {'flavor_id': '2', 'tenant_id': 'proj3'}]
 
286
 
 
287
        serializer = flavor_access.FlavorAccessTemplate()
 
288
        text = serializer.serialize(access_list)
 
289
        tree = etree.fromstring(text)
 
290
 
 
291
        self.assertEqual('flavor_access', tree.tag)
 
292
        self.assertEqual(len(access_list), len(tree))
 
293
 
 
294
        for i in range(len(access_list)):
 
295
            self.assertEqual('access', tree[i].tag)
 
296
            self.assertEqual(access_list[i]['flavor_id'],
 
297
                             tree[i].get('flavor_id'))
 
298
            self.assertEqual(access_list[i]['tenant_id'],
 
299
                             tree[i].get('tenant_id'))