cddf395094fcf2dba583bdf375191d85ffb7435d
[snaps.git] / snaps / openstack / tests / os_source_file_test.py
1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain 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,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 import logging
16 import pkg_resources
17 import uuid
18 import unittest
19
20 from snaps import file_utils
21 from snaps.config.project import ProjectConfig
22 from snaps.config.user import UserConfig
23 from snaps.openstack.tests import openstack_tests
24 from snaps.openstack.utils import deploy_utils, keystone_utils
25
26
27 dev_os_env_file = pkg_resources.resource_filename(
28     'snaps.openstack.tests.conf', 'os_env.yaml')
29
30
31 class OSComponentTestCase(unittest.TestCase):
32
33     def __init__(self, method_name='runTest', os_creds=None, ext_net_name=None,
34                  flavor_metadata=None, image_metadata=None,
35                  log_level=logging.DEBUG):
36         """
37         Super for test classes requiring a connection to OpenStack
38         :param method_name: default 'runTest'
39         :param os_creds: the OSCreds object, when null it searches for the file
40                          in the package snaps.openstack.tests.conf.os_env.yaml
41         :param ext_net_name: the name of the external network that is used for
42                              creating routers for floating IPs
43         :param flavor_metadata: dict() to be sent directly into the Nova client
44                                 generally used for page sizes
45         :param image_metadata: ability to override images being used in the
46                                tests (see examples/image-metadata)
47         :param log_level: the logging level of your test run (default DEBUG)
48         """
49         super(OSComponentTestCase, self).__init__(method_name)
50
51         logging.basicConfig(level=log_level)
52
53         if os_creds:
54             self.os_creds = os_creds
55         else:
56             self.os_creds = openstack_tests.get_credentials(
57                 dev_os_env_file=dev_os_env_file)
58
59         self.os_session = keystone_utils.keystone_session(self.os_creds)
60         self.ext_net_name = ext_net_name
61
62         if not self.ext_net_name and file_utils.file_exists(dev_os_env_file):
63             test_conf = file_utils.read_yaml(dev_os_env_file)
64             self.ext_net_name = test_conf.get('ext_net')
65
66         self.flavor_metadata = {}
67         if flavor_metadata:
68             self.flavor_metadata = flavor_metadata
69         else:
70             if file_utils.file_exists(dev_os_env_file):
71                 os_env_dict = file_utils.read_yaml(dev_os_env_file)
72                 flavor_metadata = os_env_dict.get('flavor_metadata')
73                 if flavor_metadata:
74                     self.flavor_metadata = {'metadata': flavor_metadata}
75         self.image_metadata = image_metadata
76
77     @staticmethod
78     def parameterize(testcase_klass, os_creds, ext_net_name,
79                      flavor_metadata=None, image_metadata=None,
80                      log_level=logging.DEBUG):
81         """ Create a suite containing all tests taken from the given
82             subclass, passing them the parameter 'param'.
83         """
84         test_loader = unittest.TestLoader()
85         test_names = test_loader.getTestCaseNames(testcase_klass)
86         suite = unittest.TestSuite()
87         for name in test_names:
88             suite.addTest(testcase_klass(
89                 name, os_creds, ext_net_name, flavor_metadata, image_metadata,
90                 log_level))
91         return suite
92
93     def __clean__(self):
94         """
95         Cleans up keystone session.
96         """
97         if self.os_session:
98             keystone_utils.close_session(self.os_session)
99
100
101 class OSIntegrationTestCase(OSComponentTestCase):
102
103     def __init__(self, method_name='runTest', os_creds=None, ext_net_name=None,
104                  use_keystone=True, flavor_metadata=None, image_metadata=None,
105                  netconf_override=None, log_level=logging.DEBUG):
106         """
107         Super for integration tests requiring a connection to OpenStack
108         :param method_name: default 'runTest'
109         :param os_creds: the OSCreds object, when null it searches for the file
110                          in the package snaps.openstack.tests.conf.os_env.yaml
111         :param ext_net_name: the name of the external network that is used for
112                              creating routers for floating IPs
113         :param use_keystone: when true, these tests will create a new
114                              user/project under which to run the test
115         :param image_metadata: dict() containing the URLs for the disk, kernel,
116                                and ramdisk images when multi-part images are
117                                required. See below for a simple example
118         image_metadata={'disk_url': '{URI}/cirros-0.3.4-x86_64-disk.img',
119                         'kernel_url': '{URI}/cirros-0.3.4-x86_64-kernel',
120                         'ramdisk_url': '{URI}/cirros-0.3.4-x86_64-initramfs'})
121         :param flavor_metadata: dict() to be sent directly into the Nova client
122                                 generally used for page sizes
123         :param netconf_override: dict() containing the configured network_type,
124                                physical_network and segmentation_id
125         :param log_level: the logging level of your test run (default DEBUG)
126         """
127         super(OSIntegrationTestCase, self).__init__(
128             method_name=method_name, os_creds=os_creds,
129             ext_net_name=ext_net_name, flavor_metadata=flavor_metadata,
130             image_metadata=image_metadata, log_level=log_level)
131         self.netconf_override = netconf_override
132         self.use_keystone = use_keystone
133         self.keystone = None
134         self.user_roles = None
135         self.proj_users = None
136
137     @staticmethod
138     def parameterize(testcase_klass, os_creds, ext_net_name,
139                      use_keystone=True, flavor_metadata=None,
140                      image_metadata=None, netconf_override=None,
141                      log_level=logging.DEBUG):
142         """
143         Create a suite containing all tests taken from the given
144         subclass, passing them the parameter 'param'.
145         """
146         test_loader = unittest.TestLoader()
147         test_names = test_loader.getTestCaseNames(testcase_klass)
148         suite = unittest.TestSuite()
149         for name in test_names:
150             suite.addTest(testcase_klass(name, os_creds, ext_net_name,
151                                          use_keystone, flavor_metadata,
152                                          image_metadata, netconf_override,
153                                          log_level))
154         return suite
155
156     """
157     Super for test classes that should be run within their own project/tenant
158     as they can run for quite some time
159     """
160     def __start__(self):
161         """
162         Creates a project and user to be leveraged by subclass test methods. If
163         implementing class uses this method, it must call __clean__() else you
164         will be left with unwanted users and tenants
165         """
166         self.project_creator = None
167         self.user_creator = None
168         self.admin_os_creds = self.os_creds
169         self.admin_os_session = self.os_session
170         self.keystone = keystone_utils.keystone_client(
171             self.admin_os_creds, self.admin_os_session)
172
173         if self.use_keystone:
174             guid = self.__class__.__name__ + '-' + str(uuid.uuid4())[:-19]
175             project_name = guid + '-proj'
176             self.project_creator = deploy_utils.create_project(
177                 self.admin_os_creds, ProjectConfig(
178                     name=project_name,
179                     domain=self.admin_os_creds.project_domain_name))
180
181             # Set by implementing class for setting the user's roles
182             roles = dict()
183             if self.user_roles and isinstance(self.user_roles, list):
184                 for user_role in self.user_roles:
185                     roles[user_role] = project_name
186
187             self.user_creator = deploy_utils.create_user(
188                 self.admin_os_creds, UserConfig(
189                     name=guid + '-user', password=guid,
190                     project_name=project_name, roles=roles,
191                     domain_name=self.admin_os_creds.user_domain_name))
192
193             self.os_creds = self.user_creator.get_os_creds(
194                 self.project_creator.project_settings.name)
195             self.os_session = keystone_utils.keystone_session(self.os_creds)
196
197             # add user to project
198             self.project_creator.assoc_user(self.user_creator.get_user())
199
200             if self.proj_users and isinstance(self.proj_users, list):
201                 for user_name in self.proj_users:
202                     user = keystone_utils.get_user(self.keystone, user_name)
203                     if user:
204                         self.project_creator.assoc_user(user)
205
206     def __clean__(self):
207         """
208         Cleans up test user and project.
209         Must be called at the end of child classes tearDown() if __start__() is
210         called during setUp() else these objects will persist after the test is
211         run
212         """
213         if self.project_creator:
214             self.project_creator.clean()
215
216         if self.user_creator:
217             self.user_creator.clean()
218
219         if self.admin_os_session:
220             keystone_utils.close_session(self.admin_os_session)
221
222         super(OSIntegrationTestCase, self).__clean__()