3 #######################################################################
5 # Copyright (c) 2015 Orange
6 # valentin.boucher@orange.com
8 # All rights reserved. This program and the accompanying materials
9 # are made available under the terms of the Apache License, Version 2.0
10 # which accompanies this distribution, and is available at
11 # http://www.apache.org/licenses/LICENSE-2.0
12 ########################################################################
22 import keystoneclient.v2_0.client as ksclient
23 import novaclient.client as nvclient
25 from neutronclient.v2_0 import client as ntclient
27 import functest.utils.functest_logger as ft_logger
28 import functest.utils.functest_utils as ft_utils
29 import functest.utils.openstack_utils as os_utils
30 from clearwater import Clearwater
31 from orchestrator import Orchestrator
32 import functest.utils.functest_constants as ft_constants
34 pp = pprint.PrettyPrinter(indent=4)
37 parser = argparse.ArgumentParser()
38 parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
39 parser.add_argument("-r", "--report",
40 help="Create json result file",
42 parser.add_argument("-n", "--noclean",
43 help="Don't clean the created resources for this test.",
45 args = parser.parse_args()
47 """ logging configuration """
48 logger = ft_logger.Logger("vIMS").getLogger()
52 VIMS_DIR = os.path.join(ft_constants.FUNCTEST_TEST_DIR, 'vnf/ims/')
53 VIMS_DATA_DIR = ft_constants.VIMS_DATA_DIR
54 VIMS_TEST_DIR = ft_constants.VIMS_TEST_DIR
55 VIMS_TENANT_NAME = ft_constants.VIMS_TENANT_NAME
56 VIMS_TENANT_DESCRIPTION = ft_constants.VIMS_TENANT_DESCRIPTION
57 VIMS_IMAGES = ft_constants.VIMS_IMAGES
59 CFY_MANAGER_BLUEPRINT = ft_constants.CFY_MANAGER_BLUEPRINT
60 CFY_MANAGER_REQUIERMENTS = ft_constants.CFY_MANAGER_REQUIERMENTS
61 CFY_INPUTS = ft_constants.CFY_INPUTS
63 CW_BLUEPRINT = ft_constants.CW_BLUEPRINT
64 CW_DEPLOYMENT_NAME = ft_constants.CW_DEPLOYMENT_NAME
65 CW_INPUTS = ft_constants.CW_INPUTS
66 CW_REQUIERMENTS = ft_constants.CW_REQUIERMENTS
68 CFY_DEPLOYMENT_DURATION = 0
69 CW_DEPLOYMENT_DURATION = 0
71 TESTCASE_START_TIME = time.time()
72 RESULTS = {'orchestrator': {'duration': 0, 'result': ''},
73 'vIMS': {'duration': 0, 'result': ''},
74 'sig_test': {'duration': 0, 'result': ''}}
77 def download_and_add_image_on_glance(glance, image_name, image_url):
78 dest_path = os.path.join(VIMS_DATA_DIR, "tmp/")
79 if not os.path.exists(dest_path):
80 os.makedirs(dest_path)
81 file_name = image_url.rsplit('/')[-1]
82 if not ft_utils.download_url(image_url, dest_path):
83 logger.error("Failed to download image %s" % file_name)
86 image = os_utils.create_glance_image(
87 glance, image_name, dest_path + file_name)
89 logger.error("Failed to upload image on glance")
95 def step_failure(step_name, error_msg):
96 logger.error(error_msg)
97 set_result(step_name, 0, error_msg)
99 # in case of failure starting and stoping time are not correct
100 stop_time = time.time()
101 if step_name == "sig_test":
103 ft_utils.push_results_to_db("functest",
112 def set_result(step_name, duration=0, result=""):
113 RESULTS[step_name] = {'duration': duration, 'result': result}
116 def test_clearwater():
117 script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
118 script += "cd " + VIMS_DATA_DIR + "; "
119 script += "cfy status | grep -Eo \"([0-9]{1,3}\.){3}[0-9]{1,3}\""
120 cmd = "/bin/bash -c '" + script + "'"
123 logger.debug("Trying to get clearwater manager IP ... ")
124 mgr_ip = os.popen(cmd).read()
125 mgr_ip = mgr_ip.splitlines()[0]
127 step_failure("sig_test", "Unable to retrieve the IP of the "
128 "cloudify manager server !")
130 api_url = "http://" + mgr_ip + "/api/v2"
131 dep_outputs = requests.get(api_url + "/deployments/" +
132 CW_DEPLOYMENT_NAME + "/outputs")
133 dns_ip = dep_outputs.json()['outputs']['dns_ip']
134 ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
136 ellis_url = "http://" + ellis_ip + "/"
137 url = ellis_url + "accounts"
139 params = {"password": "functest",
140 "full_name": "opnfv functest user",
141 "email": "functest@opnfv.fr",
142 "signup_code": "secret"}
144 rq = requests.post(url, data=params)
146 while rq.status_code != 201 and i > 0:
147 rq = requests.post(url, data=params)
151 if rq.status_code == 201:
152 url = ellis_url + "session"
153 rq = requests.post(url, data=params)
156 url = ellis_url + "accounts/" + params['email'] + "/numbers"
158 rq = requests.post(url, cookies=cookies)
160 while rq.status_code != 200 and i > 0:
161 rq = requests.post(url, cookies=cookies)
165 if rq.status_code != 200:
166 step_failure("sig_test", "Unable to create a number: %s"
167 % rq.json()['reason'])
169 start_time_ts = time.time()
170 end_time_ts = start_time_ts
171 logger.info("vIMS functional test Start Time:'%s'" % (
172 datetime.datetime.fromtimestamp(start_time_ts).strftime(
173 '%Y-%m-%d %H:%M:%S')))
174 nameservers = ft_utils.get_resolvconf_ns()
176 for ns in nameservers:
177 resolvconf += "\nnameserver " + ns
180 script = ('echo -e "nameserver ' + dns_ip + resolvconf +
181 '" > /etc/resolv.conf; ')
182 script += 'source /etc/profile.d/rvm.sh; '
183 script += 'cd ' + VIMS_TEST_DIR + '; '
184 script += ('rake test[' + CW_INPUTS["public_domain"] +
185 '] SIGNUP_CODE="secret"')
187 cmd = "/bin/bash -c '" + script + "'"
188 output_file = "output.txt"
189 f = open(output_file, 'w+')
190 subprocess.call(cmd, shell=True, stdout=f,
191 stderr=subprocess.STDOUT)
193 end_time_ts = time.time()
194 duration = round(end_time_ts - start_time_ts, 1)
195 logger.info("vIMS functional test duration:'%s'" % duration)
196 f = open(output_file, 'r')
198 if result != "" and logger:
201 vims_test_result = ""
202 tempFile = os.path.join(VIMS_TEST_DIR, "temp.json")
204 logger.debug("Trying to load test results")
205 with open(tempFile) as f:
206 vims_test_result = json.load(f)
209 logger.error("Unable to retrieve test results")
211 set_result("sig_test", duration, vims_test_result)
213 # success criteria for vIMS (for Brahmaputra)
214 # - orchestrator deployed
216 # TODO use test criteria defined in config file
219 if (RESULTS['orchestrator']['duration'] > 0 and
220 RESULTS['vIMS']['duration'] > 0):
223 logger.error("Unable to set test status")
225 ft_utils.push_results_to_db("functest",
235 logger.error("Deleting file failed")
240 # ############### GENERAL INITIALISATION ################
242 if not os.path.exists(VIMS_DATA_DIR):
243 os.makedirs(VIMS_DATA_DIR)
245 ks_creds = os_utils.get_credentials("keystone")
246 nv_creds = os_utils.get_credentials("nova")
247 nt_creds = os_utils.get_credentials("neutron")
249 logger.info("Prepare OpenStack plateform (create tenant and user)")
250 keystone = ksclient.Client(**ks_creds)
252 user_id = os_utils.get_user_id(keystone, ks_creds['username'])
254 step_failure("init", "Error : Failed to get id of " +
255 ks_creds['username'])
257 tenant_id = os_utils.create_tenant(
258 keystone, VIMS_TENANT_NAME, VIMS_TENANT_DESCRIPTION)
260 step_failure("init", "Error : Failed to create " +
261 VIMS_TENANT_NAME + " tenant")
263 roles_name = ["admin", "Admin"]
265 for role_name in roles_name:
267 role_id = os_utils.get_role_id(keystone, role_name)
270 logger.error("Error : Failed to get id for %s role" % role_name)
272 if not os_utils.add_role_user(keystone, user_id, role_id, tenant_id):
273 logger.error("Error : Failed to add %s on tenant" %
274 ks_creds['username'])
276 user_id = os_utils.create_user(
277 keystone, VIMS_TENANT_NAME, VIMS_TENANT_NAME, None, tenant_id)
279 logger.error("Error : Failed to create %s user" % VIMS_TENANT_NAME)
281 logger.info("Update OpenStack creds informations")
283 "username": VIMS_TENANT_NAME,
284 "password": VIMS_TENANT_NAME,
285 "tenant_name": VIMS_TENANT_NAME,
289 "tenant_name": VIMS_TENANT_NAME,
293 "project_id": VIMS_TENANT_NAME,
296 logger.info("Upload some OS images if it doesn't exist")
297 glance = os_utils.get_glance_client()
299 for img in VIMS_IMAGES.keys():
300 image_name = VIMS_IMAGES[img]['image_name']
301 image_url = VIMS_IMAGES[img]['image_url']
303 image_id = os_utils.get_image_id(glance, image_name)
306 logger.info("""%s image doesn't exist on glance repository. Try
307 downloading this image and upload on glance !""" % image_name)
308 image_id = download_and_add_image_on_glance(
309 glance, image_name, image_url)
314 "Error : Failed to find or upload required OS "
315 "image for this deployment")
317 nova = nvclient.Client("2", **nv_creds)
319 logger.info("Update security group quota for this tenant")
320 neutron = ntclient.Client(**nt_creds)
321 if not os_utils.update_sg_quota(neutron, tenant_id, 50, 100):
324 "Failed to update security group quota for tenant " +
327 # ############### CLOUDIFY INITIALISATION ################
328 public_auth_url = keystone.service_catalog.url_for(
329 service_type='identity', endpoint_type='publicURL')
331 cfy = Orchestrator(VIMS_DATA_DIR, CFY_INPUTS)
333 cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
334 'password'], tenant_name=ks_creds['tenant_name'],
335 auth_url=public_auth_url)
337 logger.info("Collect flavor id for cloudify manager server")
338 nova = nvclient.Client("2", **nv_creds)
340 flavor_name = "m1.large"
341 flavor_id = os_utils.get_flavor_id(nova, flavor_name)
342 for requirement in CFY_MANAGER_REQUIERMENTS:
343 if requirement == 'ram_min':
344 flavor_id = os_utils.get_flavor_id_by_ram_range(
345 nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 10000)
349 "Failed to find %s flavor. "
350 "Try with ram range default requirement !" % flavor_name)
351 flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
354 step_failure("orchestrator",
355 "Failed to find required flavor for this deployment")
357 cfy.set_flavor_id(flavor_id)
359 image_name = "centos_7"
360 image_id = os_utils.get_image_id(glance, image_name)
361 for requirement in CFY_MANAGER_REQUIERMENTS:
362 if requirement == 'os_image':
363 image_id = os_utils.get_image_id(
364 glance, CFY_MANAGER_REQUIERMENTS['os_image'])
369 "Error : Failed to find required OS image for cloudify manager")
371 cfy.set_image_id(image_id)
373 ext_net = os_utils.get_external_net(neutron)
375 step_failure("orchestrator", "Failed to get external network")
377 cfy.set_external_network_name(ext_net)
379 ns = ft_utils.get_resolvconf_ns()
381 cfy.set_nameservers(ns)
383 if 'compute' in nova.client.services_url:
384 cfy.set_nova_url(nova.client.services_url['compute'])
385 if neutron.httpclient.endpoint_url is not None:
386 cfy.set_neutron_url(neutron.httpclient.endpoint_url)
388 logger.info("Prepare virtualenv for cloudify-cli")
389 cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
390 ft_utils.execute_command(cmd)
392 cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
393 ft_utils.execute_command(cmd)
395 cfy.download_manager_blueprint(
396 CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
398 # ############### CLOUDIFY DEPLOYMENT ################
399 start_time_ts = time.time()
400 end_time_ts = start_time_ts
401 logger.info("Cloudify deployment Start Time:'%s'" % (
402 datetime.datetime.fromtimestamp(start_time_ts).strftime(
403 '%Y-%m-%d %H:%M:%S')))
405 error = cfy.deploy_manager()
407 step_failure("orchestrator", error)
409 end_time_ts = time.time()
410 duration = round(end_time_ts - start_time_ts, 1)
411 logger.info("Cloudify deployment duration:'%s'" % duration)
412 set_result("orchestrator", duration, "")
414 # ############### CLEARWATER INITIALISATION ################
416 cw = Clearwater(CW_INPUTS, cfy, logger)
418 logger.info("Collect flavor id for all clearwater vm")
419 nova = nvclient.Client("2", **nv_creds)
421 flavor_name = "m1.small"
422 flavor_id = os_utils.get_flavor_id(nova, flavor_name)
423 for requirement in CW_REQUIERMENTS:
424 if requirement == 'ram_min' and flavor_id == '':
425 flavor_id = os_utils.get_flavor_id_by_ram_range(
426 nova, CW_REQUIERMENTS['ram_min'], 4500)
430 "Failed to find %s flavor. Try with ram range "
431 "default requirement !" % flavor_name)
432 flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
436 "vIMS", "Failed to find required flavor for this deployment")
438 cw.set_flavor_id(flavor_id)
440 image_name = "ubuntu_14.04"
441 image_id = os_utils.get_image_id(glance, image_name)
442 for requirement in CW_REQUIERMENTS:
443 if requirement == 'os_image':
444 image_id = os_utils.get_image_id(
445 glance, CW_REQUIERMENTS['os_image'])
450 "Error : Failed to find required OS image for cloudify manager")
452 cw.set_image_id(image_id)
454 ext_net = os_utils.get_external_net(neutron)
456 step_failure("vIMS", "Failed to get external network")
458 cw.set_external_network_name(ext_net)
460 # ############### CLEARWATER DEPLOYMENT ################
462 start_time_ts = time.time()
463 end_time_ts = start_time_ts
464 logger.info("vIMS VNF deployment Start Time:'%s'" % (
465 datetime.datetime.fromtimestamp(start_time_ts).strftime(
466 '%Y-%m-%d %H:%M:%S')))
468 error = cw.deploy_vnf(CW_BLUEPRINT)
470 step_failure("vIMS", error)
472 end_time_ts = time.time()
473 duration = round(end_time_ts - start_time_ts, 1)
474 logger.info("vIMS VNF deployment duration:'%s'" % duration)
475 set_result("vIMS", duration, "")
477 # ############### CLEARWATER TEST ################
481 # ########## CLEARWATER UNDEPLOYMENT ############
485 # ########### CLOUDIFY UNDEPLOYMENT #############
487 cfy.undeploy_manager()
489 # ############## GENERAL CLEANUP ################
493 ks_creds = os_utils.get_credentials("keystone")
495 keystone = ksclient.Client(**ks_creds)
497 logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
498 tenant_id = os_utils.get_tenant_id(
499 keystone, CFY_INPUTS['keystone_tenant_name'])
501 logger.error("Error : Failed to get id of %s tenant" %
502 CFY_INPUTS['keystone_tenant_name'])
504 if not os_utils.delete_tenant(keystone, tenant_id):
505 logger.error("Error : Failed to remove %s tenant" %
506 CFY_INPUTS['keystone_tenant_name'])
508 logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
509 user_id = os_utils.get_user_id(
510 keystone, CFY_INPUTS['keystone_username'])
512 logger.error("Error : Failed to get id of %s user" %
513 CFY_INPUTS['keystone_username'])
515 if not os_utils.delete_user(keystone, user_id):
516 logger.error("Error : Failed to remove %s user" %
517 CFY_INPUTS['keystone_username'])
520 if __name__ == '__main__':