blob: 8600d5daebbc24a93ceaa2a889f6c5d9c982d055 [file] [log] [blame]
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04001#!/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
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -040025import datetime
26import gi
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040027import json
28import logging
29import os
30import pytest
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040031import requests
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -040032import shlex
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040033import subprocess
34import time
35import uuid
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040036
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040037gi.require_version('RwBaseYang', '1.0')
38gi.require_version('RwCloudYang', '1.0')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040039gi.require_version('RwlogMgmtYang', '1.0')
40gi.require_version('RwNsmYang', '1.0')
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -040041gi.require_version('ProjectNsdYang', '1.0')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040042gi.require_version('RwResourceMgrYang', '1.0')
43gi.require_version('RwConmanYang', '1.0')
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -040044gi.require_version('RwProjectVnfdYang', '1.0')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040045
46from gi.repository import (
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -040047 ProjectNsdYang as NsdYang,
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040048 NsrYang,
49 RwBaseYang,
50 RwCloudYang,
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040051 RwlogMgmtYang,
52 RwNsmYang,
53 RwNsrYang,
54 RwResourceMgrYang,
55 RwConmanYang,
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -040056 RwProjectVnfdYang as RwVnfdYang,
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040057 VldYang,
58 )
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -040059gi.require_version('RwKeyspec', '1.0')
60from gi.repository.RwKeyspec import quoted_key
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040061
62logging.basicConfig(level=logging.DEBUG)
63
64
65RW_PING_PONG_PKG_INSTALL_DIR = os.path.join(
66 os.environ["RIFT_ROOT"],
67 "images"
68 )
69
70class PackageError(Exception):
71 pass
72
73
74def raise_package_error():
75 raise PackageError("Could not find ns packages")
76
77
78@pytest.fixture(scope='module')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040079def rwlog_mgmt_proxy(request, mgmt_session):
80 return mgmt_session.proxy(RwlogMgmtYang)
81
82
83@pytest.fixture(scope='module')
84def resource_mgr_proxy(request, mgmt_session):
85 return mgmt_session.proxy(RwResourceMgrYang)
86
87
88@pytest.fixture(scope='module')
89def cloud_proxy(request, mgmt_session):
90 return mgmt_session.proxy(RwCloudYang)
91
92
93@pytest.fixture(scope='module')
94def vnfd_proxy(request, mgmt_session):
95 return mgmt_session.proxy(RwVnfdYang)
96
97
98@pytest.fixture(scope='module')
99def vld_proxy(request, mgmt_session):
100 return mgmt_session.proxy(VldYang)
101
102
103@pytest.fixture(scope='module')
104def nsd_proxy(request, mgmt_session):
105 return mgmt_session.proxy(NsdYang)
106
107
108@pytest.fixture(scope='module')
109def nsr_proxy(request, mgmt_session):
110 return mgmt_session.proxy(NsrYang)
111
112
113@pytest.fixture(scope='module')
114def rwnsr_proxy(request, mgmt_session):
115 return mgmt_session.proxy(RwNsrYang)
116
117
118@pytest.fixture(scope='module')
119def base_proxy(request, mgmt_session):
120 return mgmt_session.proxy(RwBaseYang)
121
122
123@pytest.fixture(scope='module')
124def so_proxy(request, mgmt_session):
125 return mgmt_session.proxy(RwConmanYang)
126
127
128@pytest.fixture(scope='module')
129def nsm_proxy(request, mgmt_session):
130 return mgmt_session.proxy(RwNsmYang)
131
132
133@pytest.fixture(scope='session')
134def 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')
146def 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')
158def 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
169def create_nsr_from_nsd_id(nsd_id):
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400170 nsr = RwNsrYang.YangData_RwProject_Project_NsInstanceConfig_Nsr()
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400171 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
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400179 param = NsrYang.YangData_RwProject_Project_NsInstanceConfig_Nsr_InputParameter()
180 param.xpath = '/rw-project:project/project-nsd:nsd-catalog/project-nsd:nsd/project-nsd:vendor'
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400181 param.value = "rift-o-matic"
182
183 nsr.input_parameter.append(param)
184
185 return nsr
186
187
188def 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
202class DescriptorOnboardError(Exception):
203 pass
204
205
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400206def wait_unboard_transaction_finished(logger, transaction_id, timeout_secs=600, host="127.0.0.1", project="default"):
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400207 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(
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400212 'http://{host}:8008/api/operational/project/{proj}/create-jobs/job/{t_id}'.format(
213 host=host, proj=project, t_id=transaction_id
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400214 )
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
233class 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):
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400249 cloud_account = RwCloudYang.YangData_RwProject_Project_CloudAccounts_CloudAccountList()
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400250 # 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
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400267 catalog = vnfd_proxy.get_config('/rw-project:project[rw-project:name="default"]/vnfd-catalog')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400268 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
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400278 catalog = vnfd_proxy.get_config('/rw-project:project[rw-project:name="default"]/vnfd-catalog')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400279 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
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400288 catalog = nsd_proxy.get_config('/rw-project:project[rw-project:name="default"]/nsd-catalog')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400289 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):
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400295 catalog = nsd_proxy.get_config('/rw-project:project[rw-project:name="default"]/nsd-catalog')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400296 nsd = catalog.nsd[0]
297
298 nsr = create_nsr_from_nsd_id(nsd.id)
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400299 rwnsr_proxy.merge_config('/rw-project:project[rw-project:name="default"]/ns-instance-config', nsr)
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400300
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400301 nsr_opdata = rwnsr_proxy.get('/rw-project:project[rw-project:name="default"]/ns-instance-opdata')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400302 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):
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400381 # nsr_configs = nsr_proxy.get_config('/rw-project:project[rw-project:name="default"]/ns-instance-config')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -0400382 # nsr = nsr_configs.nsr[0]
383 # nsr_id = nsr.id
384
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -0400385 # nsr_configs = nsr_proxy.delete_config("/ns-instance-config/nsr[id={}]".format(quoted_key(nsr_id)))