update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b second try
[osm/SO.git] / rwlaunchpad / test / pytest / lp_test.py
1 #!/usr/bin/env python
2 """
3 #
4 # Copyright 2016 RIFT.IO Inc
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18
19 @file lp_test.py
20 @author Austin Cormier (Austin.Cormier@riftio.com)
21 @date 10/15/2015
22 @brief Launchpad Module Test
23 """
24
25 import datetime
26 import gi
27 import json
28 import logging
29 import os
30 import pytest
31 import requests
32 import shlex
33 import subprocess
34 import time
35 import uuid
36
37 gi.require_version('RwBaseYang', '1.0')
38 gi.require_version('RwCloudYang', '1.0')
39 gi.require_version('RwlogMgmtYang', '1.0')
40 gi.require_version('RwNsmYang', '1.0')
41 gi.require_version('ProjectNsdYang', '1.0')
42 gi.require_version('RwResourceMgrYang', '1.0')
43 gi.require_version('RwConmanYang', '1.0')
44 gi.require_version('RwProjectVnfdYang', '1.0')
45
46 from gi.repository import (
47 ProjectNsdYang as NsdYang,
48 NsrYang,
49 RwBaseYang,
50 RwCloudYang,
51 RwlogMgmtYang,
52 RwNsmYang,
53 RwNsrYang,
54 RwResourceMgrYang,
55 RwConmanYang,
56 RwProjectVnfdYang as RwVnfdYang,
57 VldYang,
58 )
59 gi.require_version('RwKeyspec', '1.0')
60 from gi.repository.RwKeyspec import quoted_key
61
62 logging.basicConfig(level=logging.DEBUG)
63
64
65 RW_PING_PONG_PKG_INSTALL_DIR = os.path.join(
66 os.environ["RIFT_ROOT"],
67 "images"
68 )
69
70 class PackageError(Exception):
71 pass
72
73
74 def raise_package_error():
75 raise PackageError("Could not find ns packages")
76
77
78 @pytest.fixture(scope='module')
79 def rwlog_mgmt_proxy(request, mgmt_session):
80 return mgmt_session.proxy(RwlogMgmtYang)
81
82
83 @pytest.fixture(scope='module')
84 def resource_mgr_proxy(request, mgmt_session):
85 return mgmt_session.proxy(RwResourceMgrYang)
86
87
88 @pytest.fixture(scope='module')
89 def cloud_proxy(request, mgmt_session):
90 return mgmt_session.proxy(RwCloudYang)
91
92
93 @pytest.fixture(scope='module')
94 def vnfd_proxy(request, mgmt_session):
95 return mgmt_session.proxy(RwVnfdYang)
96
97
98 @pytest.fixture(scope='module')
99 def vld_proxy(request, mgmt_session):
100 return mgmt_session.proxy(VldYang)
101
102
103 @pytest.fixture(scope='module')
104 def nsd_proxy(request, mgmt_session):
105 return mgmt_session.proxy(NsdYang)
106
107
108 @pytest.fixture(scope='module')
109 def nsr_proxy(request, mgmt_session):
110 return mgmt_session.proxy(NsrYang)
111
112
113 @pytest.fixture(scope='module')
114 def rwnsr_proxy(request, mgmt_session):
115 return mgmt_session.proxy(RwNsrYang)
116
117
118 @pytest.fixture(scope='module')
119 def base_proxy(request, mgmt_session):
120 return mgmt_session.proxy(RwBaseYang)
121
122
123 @pytest.fixture(scope='module')
124 def so_proxy(request, mgmt_session):
125 return mgmt_session.proxy(RwConmanYang)
126
127
128 @pytest.fixture(scope='module')
129 def nsm_proxy(request, mgmt_session):
130 return mgmt_session.proxy(RwNsmYang)
131
132
133 @pytest.fixture(scope='session')
134 def ping_vnfd_package_file():
135 ping_pkg_file = os.path.join(
136 RW_PING_PONG_PKG_INSTALL_DIR,
137 "ping_vnfd_with_image.tar.gz",
138 )
139 if not os.path.exists(ping_pkg_file):
140 raise_package_error()
141
142 return ping_pkg_file
143
144
145 @pytest.fixture(scope='session')
146 def pong_vnfd_package_file():
147 pong_pkg_file = os.path.join(
148 RW_PING_PONG_PKG_INSTALL_DIR,
149 "pong_vnfd_with_image.tar.gz",
150 )
151 if not os.path.exists(pong_pkg_file):
152 raise_package_error()
153
154 return pong_pkg_file
155
156
157 @pytest.fixture(scope='session')
158 def ping_pong_nsd_package_file():
159 ping_pong_pkg_file = os.path.join(
160 RW_PING_PONG_PKG_INSTALL_DIR,
161 "ping_pong_nsd.tar.gz",
162 )
163 if not os.path.exists(ping_pong_pkg_file):
164 raise_package_error()
165
166 return ping_pong_pkg_file
167
168
169 def create_nsr_from_nsd_id(nsd_id):
170 nsr = RwNsrYang.YangData_RwProject_Project_NsInstanceConfig_Nsr()
171 nsr.id = str(uuid.uuid4())
172 nsr.name = "pingpong_{}".format(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
173 nsr.short_name = "nsr_short_name"
174 nsr.description = "This is a description"
175 nsr.nsd_ref = nsd_id
176 nsr.admin_status = "ENABLED"
177 nsr.cloud_account = "openstack"
178
179 param = NsrYang.YangData_RwProject_Project_NsInstanceConfig_Nsr_InputParameter()
180 param.xpath = '/rw-project:project/project-nsd:nsd-catalog/project-nsd:nsd/project-nsd:vendor'
181 param.value = "rift-o-matic"
182
183 nsr.input_parameter.append(param)
184
185 return nsr
186
187
188 def upload_descriptor(logger, descriptor_file, host="127.0.0.1"):
189 curl_cmd = 'curl -F "descriptor=@{file}" http://{host}:4567/api/upload'.format(
190 file=descriptor_file,
191 host=host,
192 )
193 logger.debug("Uploading descriptor %s using cmd: %s", descriptor_file, curl_cmd)
194 stdout = subprocess.check_output(shlex.split(curl_cmd), universal_newlines=True)
195
196 json_out = json.loads(stdout)
197 transaction_id = json_out["transaction_id"]
198
199 return transaction_id
200
201
202 class DescriptorOnboardError(Exception):
203 pass
204
205
206 def wait_unboard_transaction_finished(logger, transaction_id, timeout_secs=600, host="127.0.0.1", project="default"):
207 logger.info("Waiting for onboard trans_id %s to complete",
208 transaction_id)
209 start_time = time.time()
210 while (time.time() - start_time) < timeout_secs:
211 r = requests.get(
212 'http://{host}:8008/api/operational/project/{proj}/create-jobs/job/{t_id}'.format(
213 host=host, proj=project, t_id=transaction_id
214 )
215 )
216 state = r.json()
217 if state["status"] == "pending":
218 time.sleep(1)
219 continue
220
221 elif state["status"] == "success":
222 logger.info("Descriptor onboard was successful")
223 return
224
225 else:
226 raise DescriptorOnboardError(state)
227
228 if state["status"] != "success":
229 raise DescriptorOnboardError(state)
230
231
232 @pytest.mark.incremental
233 class TestLaunchpadStartStop(object):
234 def test_configure_logging(self, rwlog_mgmt_proxy):
235 logging = RwlogMgmtYang.Logging.from_dict({
236 "console": {
237 "on": True,
238 "filter": {
239 "category": [{
240 "name": "rw-generic",
241 "severity": "error"
242 }],
243 }
244 }
245 })
246 rwlog_mgmt_proxy.merge_config("/rwlog-mgmt:logging", logging)
247
248 def test_configure_cloud_account(self, cloud_proxy, logger):
249 cloud_account = RwCloudYang.YangData_RwProject_Project_CloudAccounts_CloudAccountList()
250 # cloud_account.name = "cloudsim_proxy"
251 # cloud_account.account_type = "cloudsim_proxy"
252 cloud_account.name = "openstack"
253 cloud_account.account_type = "openstack"
254 cloud_account.openstack.key = 'pluto'
255 cloud_account.openstack.secret = 'mypasswd'
256 cloud_account.openstack.auth_url = 'http://10.96.4.2:5000/v3/'
257 cloud_account.openstack.tenant = 'mano1'
258 cloud_account.openstack.mgmt_network = 'private1'
259
260 cloud_proxy.merge_config("/rw-cloud:cloud/account", cloud_account)
261
262 def test_onboard_ping_vnfd(self, logger, vnfd_proxy, ping_vnfd_package_file):
263 logger.info("Onboarding ping_vnfd package: %s", ping_vnfd_package_file)
264 trans_id = upload_descriptor(logger, ping_vnfd_package_file)
265 wait_unboard_transaction_finished(logger, trans_id)
266
267 catalog = vnfd_proxy.get_config('/rw-project:project[rw-project:name="default"]/vnfd-catalog')
268 vnfds = catalog.vnfd
269 assert len(vnfds) == 1, "There should only be a single vnfd"
270 vnfd = vnfds[0]
271 assert vnfd.name == "ping_vnfd"
272
273 def test_onboard_pong_vnfd(self, logger, vnfd_proxy, pong_vnfd_package_file):
274 logger.info("Onboarding pong_vnfd package: %s", pong_vnfd_package_file)
275 trans_id = upload_descriptor(logger, pong_vnfd_package_file)
276 wait_unboard_transaction_finished(logger, trans_id)
277
278 catalog = vnfd_proxy.get_config('/rw-project:project[rw-project:name="default"]/vnfd-catalog')
279 vnfds = catalog.vnfd
280 assert len(vnfds) == 2, "There should be two vnfds"
281 assert "pong_vnfd" in [vnfds[0].name, vnfds[1].name]
282
283 def test_onboard_ping_pong_nsd(self, logger, nsd_proxy, ping_pong_nsd_package_file):
284 logger.info("Onboarding ping_pong_nsd package: %s", ping_pong_nsd_package_file)
285 trans_id = upload_descriptor(logger, ping_pong_nsd_package_file)
286 wait_unboard_transaction_finished(logger, trans_id)
287
288 catalog = nsd_proxy.get_config('/rw-project:project[rw-project:name="default"]/nsd-catalog')
289 nsds = catalog.nsd
290 assert len(nsds) == 1, "There should only be a single nsd"
291 nsd = nsds[0]
292 assert nsd.name == "ping_pong_nsd"
293
294 def test_instantiate_ping_pong_nsr(self, logger, nsd_proxy, nsr_proxy, rwnsr_proxy, base_proxy):
295 catalog = nsd_proxy.get_config('/rw-project:project[rw-project:name="default"]/nsd-catalog')
296 nsd = catalog.nsd[0]
297
298 nsr = create_nsr_from_nsd_id(nsd.id)
299 rwnsr_proxy.merge_config('/rw-project:project[rw-project:name="default"]/ns-instance-config', nsr)
300
301 nsr_opdata = rwnsr_proxy.get('/rw-project:project[rw-project:name="default"]/ns-instance-opdata')
302 nsrs = nsr_opdata.nsr
303 assert len(nsrs) == 1
304 assert nsrs[0].ns_instance_config_ref == nsr.id
305
306 # logger.info("Waiting up to 30 seconds for ping and pong components to show "
307 # "up in show tasklet info")
308
309 # start_time = time.time()
310 # while (time.time() - start_time) < 30:
311 # vcs_info = base_proxy.get('/vcs/info')
312 # components = vcs_info.components.component_info
313
314 # def find_component_by_name(name):
315 # for component in components:
316 # if name in component.component_name:
317 # return component
318
319 # logger.warning("Did not find %s component name in show tasklet info",
320 # name)
321
322 # return None
323
324 # """
325 # ping_cluster_component = find_component_by_name(
326 # "rw_ping_vnfd:rwping_cluster"
327 # )
328 # if ping_cluster_component is None:
329 # continue
330
331 # pong_cluster_component = find_component_by_name(
332 # "rw_pong_vnfd:rwpong_cluster"
333 # )
334 # if pong_cluster_component is None:
335 # continue
336 # """
337
338 # ping_vm_component = find_component_by_name(
339 # "rw_ping_vnfd:rwping_vm"
340 # )
341 # if ping_vm_component is None:
342 # continue
343
344 # pong_vm_component = find_component_by_name(
345 # "rw_pong_vnfd:rwpong_vm"
346 # )
347 # if pong_vm_component is None:
348 # continue
349
350 # ping_proc_component = find_component_by_name(
351 # "rw_ping_vnfd:rwping_proc"
352 # )
353 # if ping_proc_component is None:
354 # continue
355
356 # pong_proc_component = find_component_by_name(
357 # "rw_pong_vnfd:rwpong_proc"
358 # )
359 # if pong_proc_component is None:
360 # continue
361
362 # ping_tasklet_component = find_component_by_name(
363 # "rw_ping_vnfd:rwping_tasklet"
364 # )
365 # if ping_tasklet_component is None:
366 # continue
367
368 # pong_tasklet_component = find_component_by_name(
369 # "rw_pong_vnfd:rwpong_tasklet"
370 # )
371 # if pong_tasklet_component is None:
372 # continue
373
374 # logger.info("TEST SUCCESSFUL: All ping and pong components were found in show tasklet info")
375 # break
376
377 # else:
378 # assert False, "Did not find all ping and pong component in time"
379
380 #def test_terminate_ping_pong_ns(self, logger, nsd_proxy, nsr_proxy, rwnsr_proxy, base_proxy):
381 # nsr_configs = nsr_proxy.get_config('/rw-project:project[rw-project:name="default"]/ns-instance-config')
382 # nsr = nsr_configs.nsr[0]
383 # nsr_id = nsr.id
384
385 # nsr_configs = nsr_proxy.delete_config("/ns-instance-config/nsr[id={}]".format(quoted_key(nsr_id)))