1# Copyright (c) 2015 Hewlett-Packard Development Company, L.P. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15""" 16test_flavor 17---------------------------------- 18 19Functional tests for `shade` flavor resource. 20""" 21 22from openstack.cloud.exc import OpenStackCloudException 23from openstack.tests.functional import base 24 25 26class TestFlavor(base.BaseFunctionalTest): 27 28 def setUp(self): 29 super(TestFlavor, self).setUp() 30 31 # Generate a random name for flavors in this test 32 self.new_item_name = self.getUniqueString('flavor') 33 34 self.addCleanup(self._cleanup_flavors) 35 36 def _cleanup_flavors(self): 37 exception_list = list() 38 for f in self.operator_cloud.list_flavors(get_extra=False): 39 if f['name'].startswith(self.new_item_name): 40 try: 41 self.operator_cloud.delete_flavor(f['id']) 42 except Exception as e: 43 # We were unable to delete a flavor, let's try with next 44 exception_list.append(str(e)) 45 continue 46 if exception_list: 47 # Raise an error: we must make users aware that something went 48 # wrong 49 raise OpenStackCloudException('\n'.join(exception_list)) 50 51 def test_create_flavor(self): 52 flavor_name = self.new_item_name + '_create' 53 flavor_kwargs = dict( 54 name=flavor_name, ram=1024, vcpus=2, disk=10, ephemeral=5, 55 swap=100, rxtx_factor=1.5, is_public=True 56 ) 57 58 flavor = self.operator_cloud.create_flavor(**flavor_kwargs) 59 60 self.assertIsNotNone(flavor['id']) 61 62 # When properly normalized, we should always get an extra_specs 63 # and expect empty dict on create. 64 self.assertIn('extra_specs', flavor) 65 self.assertEqual({}, flavor['extra_specs']) 66 67 # We should also always have ephemeral and public attributes 68 self.assertIn('ephemeral', flavor) 69 self.assertEqual(5, flavor['ephemeral']) 70 self.assertIn('is_public', flavor) 71 self.assertTrue(flavor['is_public']) 72 73 for key in flavor_kwargs.keys(): 74 self.assertIn(key, flavor) 75 for key, value in flavor_kwargs.items(): 76 self.assertEqual(value, flavor[key]) 77 78 def test_list_flavors(self): 79 pub_flavor_name = self.new_item_name + '_public' 80 priv_flavor_name = self.new_item_name + '_private' 81 public_kwargs = dict( 82 name=pub_flavor_name, ram=1024, vcpus=2, disk=10, is_public=True 83 ) 84 private_kwargs = dict( 85 name=priv_flavor_name, ram=1024, vcpus=2, disk=10, is_public=False 86 ) 87 88 # Create a public and private flavor. We expect both to be listed 89 # for an operator. 90 self.operator_cloud.create_flavor(**public_kwargs) 91 self.operator_cloud.create_flavor(**private_kwargs) 92 93 flavors = self.operator_cloud.list_flavors(get_extra=False) 94 95 # Flavor list will include the standard devstack flavors. We just want 96 # to make sure both of the flavors we just created are present. 97 found = [] 98 for f in flavors: 99 # extra_specs should be added within list_flavors() 100 self.assertIn('extra_specs', f) 101 if f['name'] in (pub_flavor_name, priv_flavor_name): 102 found.append(f) 103 self.assertEqual(2, len(found)) 104 105 def test_flavor_access(self): 106 priv_flavor_name = self.new_item_name + '_private' 107 private_kwargs = dict( 108 name=priv_flavor_name, ram=1024, vcpus=2, disk=10, is_public=False 109 ) 110 new_flavor = self.operator_cloud.create_flavor(**private_kwargs) 111 112 # Validate the 'demo' user cannot see the new flavor 113 flavors = self.user_cloud.search_flavors(priv_flavor_name) 114 self.assertEqual(0, len(flavors)) 115 116 # We need the tenant ID for the 'demo' user 117 project = self.operator_cloud.get_project('demo') 118 self.assertIsNotNone(project) 119 120 # Now give 'demo' access 121 self.operator_cloud.add_flavor_access(new_flavor['id'], project['id']) 122 123 # Now see if the 'demo' user has access to it 124 flavors = self.user_cloud.search_flavors(priv_flavor_name) 125 self.assertEqual(1, len(flavors)) 126 self.assertEqual(priv_flavor_name, flavors[0]['name']) 127 128 # Now see if the 'demo' user has access to it without needing 129 # the demo_cloud access. 130 acls = self.operator_cloud.list_flavor_access(new_flavor['id']) 131 self.assertEqual(1, len(acls)) 132 self.assertEqual(project['id'], acls[0]['project_id']) 133 134 # Now revoke the access and make sure we can't find it 135 self.operator_cloud.remove_flavor_access(new_flavor['id'], 136 project['id']) 137 flavors = self.user_cloud.search_flavors(priv_flavor_name) 138 self.assertEqual(0, len(flavors)) 139 140 def test_set_unset_flavor_specs(self): 141 """ 142 Test setting and unsetting flavor extra specs 143 """ 144 flavor_name = self.new_item_name + '_spec_test' 145 kwargs = dict( 146 name=flavor_name, ram=1024, vcpus=2, disk=10 147 ) 148 new_flavor = self.operator_cloud.create_flavor(**kwargs) 149 150 # Expect no extra_specs 151 self.assertEqual({}, new_flavor['extra_specs']) 152 153 # Now set them 154 extra_specs = {'foo': 'aaa', 'bar': 'bbb'} 155 self.operator_cloud.set_flavor_specs(new_flavor['id'], extra_specs) 156 mod_flavor = self.operator_cloud.get_flavor( 157 new_flavor['id'], get_extra=True) 158 159 # Verify extra_specs were set 160 self.assertIn('extra_specs', mod_flavor) 161 self.assertEqual(extra_specs, mod_flavor['extra_specs']) 162 163 # Unset the 'foo' value 164 self.operator_cloud.unset_flavor_specs(mod_flavor['id'], ['foo']) 165 mod_flavor = self.operator_cloud.get_flavor_by_id( 166 new_flavor['id'], get_extra=True) 167 168 # Verify 'foo' is unset and 'bar' is still set 169 self.assertEqual({'bar': 'bbb'}, mod_flavor['extra_specs']) 170