blob: 021adaf57a68b3bba1832dc6d8905228e317d717 [file] [log] [blame]
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +03001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13import functools
14
15from tempest import clients
16from tempest.common.utils import data_utils
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000017from tempest import config
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030018from tempest import exceptions as exc
19from tempest import test
20
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000021CONF = config.CONF
22
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030023
24def creates(resource):
25 """Decorator that adds resources to the appropriate cleanup list."""
26
27 def decorator(f):
28 @functools.wraps(f)
29 def wrapper(cls, *args, **kwargs):
30 result = f(cls, *args, **kwargs)
31 body = result[resource]
32
33 if 'uuid' in body:
34 cls.created_objects[resource].add(body['uuid'])
35
36 return result
37 return wrapper
38 return decorator
39
40
41class BaseBaremetalTest(test.BaseTestCase):
42 """Base class for Baremetal API tests."""
43
44 @classmethod
45 def setUpClass(cls):
46 super(BaseBaremetalTest, cls).setUpClass()
47
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000048 if not CONF.service_available.ironic:
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030049 skip_msg = ('%s skipped as Ironic is not available' % cls.__name__)
50 raise cls.skipException(skip_msg)
51
52 mgr = clients.AdminManager()
53 cls.client = mgr.baremetal_client
54
55 cls.created_objects = {'chassis': set(),
56 'port': set(),
57 'node': set()}
58
59 @classmethod
60 def tearDownClass(cls):
61 """Ensure that all created objects get destroyed."""
62
63 try:
64 for resource, uuids in cls.created_objects.iteritems():
65 delete_method = getattr(cls.client, 'delete_%s' % resource)
66 for u in uuids:
67 delete_method(u, ignore_errors=exc.NotFound)
68 finally:
69 super(BaseBaremetalTest, cls).tearDownClass()
70
71 @classmethod
72 @creates('chassis')
73 def create_chassis(cls, description=None, expect_errors=False):
74 """
75 Wrapper utility for creating test chassis.
76
77 :param description: A description of the chassis. if not supplied,
78 a random value will be generated.
79 :return: Created chassis.
80
81 """
82 description = description or data_utils.rand_name('test-chassis-')
83 resp, body = cls.client.create_chassis(description=description)
84
85 return {'chassis': body, 'response': resp}
86
87 @classmethod
88 @creates('node')
89 def create_node(cls, chassis_id, cpu_arch='x86', cpu_num=8, storage=1024,
90 memory=4096, driver='fake'):
91 """
92 Wrapper utility for creating test baremetal nodes.
93
94 :param cpu_arch: CPU architecture of the node. Default: x86.
95 :param cpu_num: Number of CPUs. Default: 8.
96 :param storage: Disk size. Default: 1024.
97 :param memory: Available RAM. Default: 4096.
98 :return: Created node.
99
100 """
101 resp, body = cls.client.create_node(chassis_id, cpu_arch=cpu_arch,
102 cpu_num=cpu_num, storage=storage,
103 memory=memory, driver=driver)
104
105 return {'node': body, 'response': resp}
106
107 @classmethod
108 @creates('port')
Sergey Nikitin0d43eb52014-02-03 14:50:02 +0400109 def create_port(cls, node_id, address, extra=None, uuid=None):
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300110 """
111 Wrapper utility for creating test ports.
112
Sergey Nikitin0d43eb52014-02-03 14:50:02 +0400113 :param address: MAC address of the port.
114 :param extra: Meta data of the port. If not supplied, an empty
115 dictionary will be created.
116 :param uuid: UUID of the port.
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300117 :return: Created port.
118
119 """
Sergey Nikitin0d43eb52014-02-03 14:50:02 +0400120 extra = extra or {}
121 resp, body = cls.client.create_port(address=address, node_id=node_id,
122 extra=extra, uuid=uuid)
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300123
124 return {'port': body, 'response': resp}
125
126 @classmethod
127 def delete_chassis(cls, chassis_id):
128 """
129 Deletes a chassis having the specified UUID.
130
131 :param uuid: The unique identifier of the chassis.
132 :return: Server response.
133
134 """
135
136 resp, body = cls.client.delete_chassis(chassis_id)
137
138 if chassis_id in cls.created_objects['chassis']:
139 cls.created_objects['chassis'].remove(chassis_id)
140
141 return resp
142
143 @classmethod
144 def delete_node(cls, node_id):
145 """
146 Deletes a node having the specified UUID.
147
148 :param uuid: The unique identifier of the node.
149 :return: Server response.
150
151 """
152
153 resp, body = cls.client.delete_node(node_id)
154
155 if node_id in cls.created_objects['node']:
156 cls.created_objects['node'].remove(node_id)
157
158 return resp
159
160 @classmethod
161 def delete_port(cls, port_id):
162 """
163 Deletes a port having the specified UUID.
164
165 :param uuid: The unique identifier of the port.
166 :return: Server response.
167
168 """
169
170 resp, body = cls.client.delete_port(port_id)
171
172 if port_id in cls.created_objects['port']:
173 cls.created_objects['port'].remove(port_id)
174
175 return resp
Sergey Nikitin0d43eb52014-02-03 14:50:02 +0400176
177 def validate_self_link(self, resource, uuid, link):
178 """Check whether the given self link formatted correctly."""
179 expected_link = "{base}/{pref}/{res}/{uuid}".format(
180 base=self.client.base_url,
181 pref=self.client.uri_prefix,
182 res=resource,
183 uuid=uuid)
184 self.assertEqual(expected_link, link)