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 ########################################################################
24 import keystoneclient.v2_0.client as ksclient
25 import novaclient.client as nvclient
26 from neutronclient.v2_0 import client as ntclient
28 from clearwater import clearwater
29 from orchestrator import orchestrator
31 import functest.utils.functest_logger as ft_logger
32 import functest.utils.functest_utils as functest_utils
33 import functest.utils.openstack_utils as os_utils
36 pp = pprint.PrettyPrinter(indent=4)
39 parser = argparse.ArgumentParser()
40 parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
41 parser.add_argument("-r", "--report",
42 help="Create json result file",
44 parser.add_argument("-n", "--noclean",
45 help="Don't clean the created resources for this test.",
47 args = parser.parse_args()
49 """ logging configuration """
50 logger = ft_logger.Logger("vIMS").getLogger()
52 REPO_PATH = os.environ['repos_dir'] + '/functest/'
53 if not os.path.exists(REPO_PATH):
54 logger.error("Functest repository directory not found '%s'" % REPO_PATH)
57 with open(os.environ["CONFIG_FUNCTEST_YAML"]) as f:
58 functest_yaml = yaml.safe_load(f)
62 VIMS_DIR = (REPO_PATH +
63 functest_yaml.get("general").get("directories").get("dir_vIMS"))
64 VIMS_DATA_DIR = functest_yaml.get("general").get(
65 "directories").get("dir_vIMS_data") + "/"
66 VIMS_TEST_DIR = functest_yaml.get("general").get(
67 "directories").get("dir_repo_vims_test") + "/"
68 DB_URL = functest_yaml.get("results").get("test_db_url")
70 TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name")
71 TENANT_DESCRIPTION = functest_yaml.get("vIMS").get(
72 "general").get("tenant_description")
73 IMAGES = functest_yaml.get("vIMS").get("general").get("images")
75 CFY_MANAGER_BLUEPRINT = functest_yaml.get(
76 "vIMS").get("cloudify").get("blueprint")
77 CFY_MANAGER_REQUIERMENTS = functest_yaml.get(
78 "vIMS").get("cloudify").get("requierments")
79 CFY_INPUTS = functest_yaml.get("vIMS").get("cloudify").get("inputs")
81 CW_BLUEPRINT = functest_yaml.get("vIMS").get("clearwater").get("blueprint")
82 CW_DEPLOYMENT_NAME = functest_yaml.get("vIMS").get(
83 "clearwater").get("deployment-name")
84 CW_INPUTS = functest_yaml.get("vIMS").get("clearwater").get("inputs")
85 CW_REQUIERMENTS = functest_yaml.get("vIMS").get(
86 "clearwater").get("requierments")
88 CFY_DEPLOYMENT_DURATION = 0
89 CW_DEPLOYMENT_DURATION = 0
91 TESTCASE_START_TIME = time.time()
92 RESULTS = {'orchestrator': {'duration': 0, 'result': ''},
93 'vIMS': {'duration': 0, 'result': ''},
94 'sig_test': {'duration': 0, 'result': ''}}
97 def download_and_add_image_on_glance(glance, image_name, image_url):
98 dest_path = VIMS_DATA_DIR + "tmp/"
99 if not os.path.exists(dest_path):
100 os.makedirs(dest_path)
101 file_name = image_url.rsplit('/')[-1]
102 if not functest_utils.download_url(image_url, dest_path):
103 logger.error("Failed to download image %s" % file_name)
106 image = os_utils.create_glance_image(
107 glance, image_name, dest_path + file_name)
109 logger.error("Failed to upload image on glance")
115 def step_failure(step_name, error_msg):
116 logger.error(error_msg)
117 set_result(step_name, 0, error_msg)
119 # in case of failure starting and stoping time are not correct
120 stop_time = time.time()
121 if step_name == "sig_test":
123 functest_utils.push_results_to_db("functest",
133 def set_result(step_name, duration=0, result=""):
134 RESULTS[step_name] = {'duration': duration, 'result': result}
137 def test_clearwater():
138 script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
139 script += "cd " + VIMS_DATA_DIR + "; "
140 script += "cfy status | grep -Eo \"([0-9]{1,3}\.){3}[0-9]{1,3}\""
141 cmd = "/bin/bash -c '" + script + "'"
144 logger.debug("Trying to get clearwater manager IP ... ")
145 mgr_ip = os.popen(cmd).read()
146 mgr_ip = mgr_ip.splitlines()[0]
148 step_failure("sig_test", "Unable to retrieve the IP of the "
149 "cloudify manager server !")
151 api_url = "http://" + mgr_ip + "/api/v2"
152 dep_outputs = requests.get(api_url + "/deployments/" +
153 CW_DEPLOYMENT_NAME + "/outputs")
154 dns_ip = dep_outputs.json()['outputs']['dns_ip']
155 ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
157 ellis_url = "http://" + ellis_ip + "/"
158 url = ellis_url + "accounts"
160 params = {"password": "functest",
161 "full_name": "opnfv functest user",
162 "email": "functest@opnfv.fr",
163 "signup_code": "secret"}
165 rq = requests.post(url, data=params)
167 while rq.status_code != 201 and i > 0:
168 rq = requests.post(url, data=params)
172 if rq.status_code == 201:
173 url = ellis_url + "session"
174 rq = requests.post(url, data=params)
177 url = ellis_url + "accounts/" + params['email'] + "/numbers"
179 rq = requests.post(url, cookies=cookies)
181 while rq.status_code != 200 and i > 0:
182 rq = requests.post(url, cookies=cookies)
186 if rq.status_code != 200:
187 step_failure("sig_test", "Unable to create a number: %s"
188 % rq.json()['reason'])
190 start_time_ts = time.time()
191 end_time_ts = start_time_ts
192 logger.info("vIMS functional test Start Time:'%s'" % (
193 datetime.datetime.fromtimestamp(start_time_ts).strftime(
194 '%Y-%m-%d %H:%M:%S')))
195 nameservers = functest_utils.get_resolvconf_ns()
197 for ns in nameservers:
198 resolvconf += "\nnameserver " + ns
201 script = ('echo -e "nameserver ' + dns_ip + resolvconf +
202 '" > /etc/resolv.conf; ')
203 script += 'source /etc/profile.d/rvm.sh; '
204 script += 'cd ' + VIMS_TEST_DIR + '; '
205 script += ('rake test[' + CW_INPUTS["public_domain"] +
206 '] SIGNUP_CODE="secret"')
208 cmd = "/bin/bash -c '" + script + "'"
209 output_file = "output.txt"
210 f = open(output_file, 'w+')
211 subprocess.call(cmd, shell=True, stdout=f,
212 stderr=subprocess.STDOUT)
214 end_time_ts = time.time()
215 duration = round(end_time_ts - start_time_ts, 1)
216 logger.info("vIMS functional test duration:'%s'" % duration)
217 f = open(output_file, 'r')
219 if result != "" and logger:
222 vims_test_result = ""
224 logger.debug("Trying to load test results")
225 with open(VIMS_TEST_DIR + "temp.json") as f:
226 vims_test_result = json.load(f)
229 logger.error("Unable to retrieve test results")
231 set_result("sig_test", duration, vims_test_result)
233 # success criteria for vIMS (for Brahmaputra)
234 # - orchestrator deployed
236 # TODO use test criteria defined in config file
239 if (RESULTS['orchestrator']['duration'] > 0 and
240 RESULTS['vIMS']['duration'] > 0):
243 logger.error("Unable to set test status")
245 functest_utils.push_results_to_db("functest",
254 os.remove(VIMS_TEST_DIR + "temp.json")
256 logger.error("Deleting file failed")
261 # ############### GENERAL INITIALISATION ################
263 if not os.path.exists(VIMS_DATA_DIR):
264 os.makedirs(VIMS_DATA_DIR)
266 ks_creds = os_utils.get_credentials("keystone")
267 nv_creds = os_utils.get_credentials("nova")
268 nt_creds = os_utils.get_credentials("neutron")
270 logger.info("Prepare OpenStack plateform (create tenant and user)")
271 keystone = ksclient.Client(**ks_creds)
273 user_id = os_utils.get_user_id(keystone, ks_creds['username'])
275 step_failure("init", "Error : Failed to get id of " +
276 ks_creds['username'])
278 tenant_id = os_utils.create_tenant(
279 keystone, TENANT_NAME, TENANT_DESCRIPTION)
281 step_failure("init", "Error : Failed to create " +
282 TENANT_NAME + " tenant")
284 roles_name = ["admin", "Admin"]
286 for role_name in roles_name:
288 role_id = os_utils.get_role_id(keystone, role_name)
291 logger.error("Error : Failed to get id for %s role" % role_name)
293 if not os_utils.add_role_user(keystone, user_id, role_id, tenant_id):
294 logger.error("Error : Failed to add %s on tenant" %
295 ks_creds['username'])
297 user_id = os_utils.create_user(
298 keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
300 logger.error("Error : Failed to create %s user" % TENANT_NAME)
302 logger.info("Update OpenStack creds informations")
304 "username": TENANT_NAME,
305 "password": TENANT_NAME,
306 "tenant_name": TENANT_NAME,
310 "tenant_name": TENANT_NAME,
314 "project_id": TENANT_NAME,
317 logger.info("Upload some OS images if it doesn't exist")
318 glance = os_utils.get_glance_client()
320 for img in IMAGES.keys():
321 image_name = IMAGES[img]['image_name']
322 image_url = IMAGES[img]['image_url']
324 image_id = os_utils.get_image_id(glance, image_name)
327 logger.info("""%s image doesn't exist on glance repository. Try
328 downloading this image and upload on glance !""" % image_name)
329 image_id = download_and_add_image_on_glance(
330 glance, image_name, image_url)
335 "Error : Failed to find or upload required OS "
336 "image for this deployment")
338 nova = nvclient.Client("2", **nv_creds)
340 logger.info("Update security group quota for this tenant")
341 neutron = ntclient.Client(**nt_creds)
342 if not os_utils.update_sg_quota(neutron, tenant_id, 50, 100):
345 "Failed to update security group quota for tenant " + TENANT_NAME)
347 # ############### CLOUDIFY INITIALISATION ################
348 public_auth_url = keystone.service_catalog.url_for(
349 service_type='identity', endpoint_type='publicURL')
351 cfy = orchestrator(VIMS_DATA_DIR, CFY_INPUTS, logger)
353 cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
354 'password'], tenant_name=ks_creds['tenant_name'],
355 auth_url=public_auth_url)
357 logger.info("Collect flavor id for cloudify manager server")
358 nova = nvclient.Client("2", **nv_creds)
360 flavor_name = "m1.large"
361 flavor_id = os_utils.get_flavor_id(nova, flavor_name)
362 for requirement in CFY_MANAGER_REQUIERMENTS:
363 if requirement == 'ram_min':
364 flavor_id = os_utils.get_flavor_id_by_ram_range(
365 nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 10000)
369 "Failed to find %s flavor. "
370 "Try with ram range default requirement !" % flavor_name)
371 flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
374 step_failure("orchestrator",
375 "Failed to find required flavor for this deployment")
377 cfy.set_flavor_id(flavor_id)
379 image_name = "centos_7"
380 image_id = os_utils.get_image_id(glance, image_name)
381 for requirement in CFY_MANAGER_REQUIERMENTS:
382 if requirement == 'os_image':
383 image_id = os_utils.get_image_id(
384 glance, CFY_MANAGER_REQUIERMENTS['os_image'])
389 "Error : Failed to find required OS image for cloudify manager")
391 cfy.set_image_id(image_id)
393 ext_net = os_utils.get_external_net(neutron)
395 step_failure("orchestrator", "Failed to get external network")
397 cfy.set_external_network_name(ext_net)
399 ns = functest_utils.get_resolvconf_ns()
401 cfy.set_nameservers(ns)
403 if 'compute' in nova.client.services_url:
404 cfy.set_nova_url(nova.client.services_url['compute'])
405 if neutron.httpclient.endpoint_url is not None:
406 cfy.set_neutron_url(neutron.httpclient.endpoint_url)
408 logger.info("Prepare virtualenv for cloudify-cli")
409 cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
410 functest_utils.execute_command(cmd, logger)
412 cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
413 functest_utils.execute_command(cmd, logger)
415 cfy.download_manager_blueprint(
416 CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
418 # ############### CLOUDIFY DEPLOYMENT ################
419 start_time_ts = time.time()
420 end_time_ts = start_time_ts
421 logger.info("Cloudify deployment Start Time:'%s'" % (
422 datetime.datetime.fromtimestamp(start_time_ts).strftime(
423 '%Y-%m-%d %H:%M:%S')))
425 error = cfy.deploy_manager()
427 step_failure("orchestrator", error)
429 end_time_ts = time.time()
430 duration = round(end_time_ts - start_time_ts, 1)
431 logger.info("Cloudify deployment duration:'%s'" % duration)
432 set_result("orchestrator", duration, "")
434 # ############### CLEARWATER INITIALISATION ################
436 cw = clearwater(CW_INPUTS, cfy, logger)
438 logger.info("Collect flavor id for all clearwater vm")
439 nova = nvclient.Client("2", **nv_creds)
441 flavor_name = "m1.small"
442 flavor_id = os_utils.get_flavor_id(nova, flavor_name)
443 for requirement in CW_REQUIERMENTS:
444 if requirement == 'ram_min' and flavor_id == '':
445 flavor_id = os_utils.get_flavor_id_by_ram_range(
446 nova, CW_REQUIERMENTS['ram_min'], 4500)
450 "Failed to find %s flavor. Try with ram range "
451 "default requirement !" % flavor_name)
452 flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
456 "vIMS", "Failed to find required flavor for this deployment")
458 cw.set_flavor_id(flavor_id)
460 image_name = "ubuntu_14.04"
461 image_id = os_utils.get_image_id(glance, image_name)
462 for requirement in CW_REQUIERMENTS:
463 if requirement == 'os_image':
464 image_id = os_utils.get_image_id(
465 glance, CW_REQUIERMENTS['os_image'])
470 "Error : Failed to find required OS image for cloudify manager")
472 cw.set_image_id(image_id)
474 ext_net = os_utils.get_external_net(neutron)
476 step_failure("vIMS", "Failed to get external network")
478 cw.set_external_network_name(ext_net)
480 # ############### CLEARWATER DEPLOYMENT ################
482 start_time_ts = time.time()
483 end_time_ts = start_time_ts
484 logger.info("vIMS VNF deployment Start Time:'%s'" % (
485 datetime.datetime.fromtimestamp(start_time_ts).strftime(
486 '%Y-%m-%d %H:%M:%S')))
488 error = cw.deploy_vnf(CW_BLUEPRINT)
490 step_failure("vIMS", error)
492 end_time_ts = time.time()
493 duration = round(end_time_ts - start_time_ts, 1)
494 logger.info("vIMS VNF deployment duration:'%s'" % duration)
495 set_result("vIMS", duration, "")
497 # ############### CLEARWATER TEST ################
501 # ########## CLEARWATER UNDEPLOYMENT ############
505 # ########### CLOUDIFY UNDEPLOYMENT #############
507 cfy.undeploy_manager()
509 # ############## GENERAL CLEANUP ################
513 ks_creds = os_utils.get_credentials("keystone")
515 keystone = ksclient.Client(**ks_creds)
517 logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
518 tenant_id = os_utils.get_tenant_id(
519 keystone, CFY_INPUTS['keystone_tenant_name'])
521 logger.error("Error : Failed to get id of %s tenant" %
522 CFY_INPUTS['keystone_tenant_name'])
524 if not os_utils.delete_tenant(keystone, tenant_id):
525 logger.error("Error : Failed to remove %s tenant" %
526 CFY_INPUTS['keystone_tenant_name'])
528 logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
529 user_id = os_utils.get_user_id(
530 keystone, CFY_INPUTS['keystone_username'])
532 logger.error("Error : Failed to get id of %s user" %
533 CFY_INPUTS['keystone_username'])
535 if not os_utils.delete_user(keystone, user_id):
536 logger.error("Error : Failed to remove %s user" %
537 CFY_INPUTS['keystone_username'])
540 if __name__ == '__main__':