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
33 pp = pprint.PrettyPrinter(indent=4)
36 parser = argparse.ArgumentParser()
37 parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
38 parser.add_argument("-r", "--report",
39 help="Create json result file",
41 parser.add_argument("-n", "--noclean",
42 help="Don't clean the created resources for this test.",
44 args = parser.parse_args()
46 """ logging configuration """
47 logger = ft_logger.Logger("vIMS").getLogger()
51 VIMS_DIR = ft_utils.FUNCTEST_REPO + '/' + \
52 ft_utils.get_functest_config('general.directories.dir_vIMS')
55 ft_utils.get_functest_config('general.directories.dir_vIMS_data') + \
58 ft_utils.get_functest_config('general.directories.dir_repo_vims_test') + \
61 ft_utils.get_functest_config('results.test_db_url')
64 ft_utils.get_functest_config('vIMS.general.tenant_name')
65 TENANT_DESCRIPTION = \
66 ft_utils.get_functest_config('vIMS.general.tenant_description')
68 ft_utils.get_functest_config('vIMS.general.images')
70 CFY_MANAGER_BLUEPRINT = \
71 ft_utils.get_functest_config('vIMS.cloudify.blueprint')
72 CFY_MANAGER_REQUIERMENTS = \
73 ft_utils.get_functest_config('vIMS.cloudify.requierments')
74 CFY_INPUTS = ft_utils.get_functest_config('vIMS.cloudify.inputs')
77 ft_utils.get_functest_config('vIMS.clearwater.blueprint')
78 CW_DEPLOYMENT_NAME = \
79 ft_utils.get_functest_config('vIMS.clearwater.deployment-name')
81 ft_utils.get_functest_config('vIMS.clearwater.inputs')
83 ft_utils.get_functest_config('vIMS.clearwater.requierments')
85 CFY_DEPLOYMENT_DURATION = 0
86 CW_DEPLOYMENT_DURATION = 0
88 TESTCASE_START_TIME = time.time()
89 RESULTS = {'orchestrator': {'duration': 0, 'result': ''},
90 'vIMS': {'duration': 0, 'result': ''},
91 'sig_test': {'duration': 0, 'result': ''}}
94 def download_and_add_image_on_glance(glance, image_name, image_url):
95 dest_path = VIMS_DATA_DIR + "tmp/"
96 if not os.path.exists(dest_path):
97 os.makedirs(dest_path)
98 file_name = image_url.rsplit('/')[-1]
99 if not ft_utils.download_url(image_url, dest_path):
100 logger.error("Failed to download image %s" % file_name)
103 image = os_utils.create_glance_image(
104 glance, image_name, dest_path + file_name)
106 logger.error("Failed to upload image on glance")
112 def step_failure(step_name, error_msg):
113 logger.error(error_msg)
114 set_result(step_name, 0, error_msg)
116 # in case of failure starting and stoping time are not correct
117 stop_time = time.time()
118 if step_name == "sig_test":
120 ft_utils.push_results_to_db("functest",
129 def set_result(step_name, duration=0, result=""):
130 RESULTS[step_name] = {'duration': duration, 'result': result}
133 def test_clearwater():
134 script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
135 script += "cd " + VIMS_DATA_DIR + "; "
136 script += "cfy status | grep -Eo \"([0-9]{1,3}\.){3}[0-9]{1,3}\""
137 cmd = "/bin/bash -c '" + script + "'"
140 logger.debug("Trying to get clearwater manager IP ... ")
141 mgr_ip = os.popen(cmd).read()
142 mgr_ip = mgr_ip.splitlines()[0]
144 step_failure("sig_test", "Unable to retrieve the IP of the "
145 "cloudify manager server !")
147 api_url = "http://" + mgr_ip + "/api/v2"
148 dep_outputs = requests.get(api_url + "/deployments/" +
149 CW_DEPLOYMENT_NAME + "/outputs")
150 dns_ip = dep_outputs.json()['outputs']['dns_ip']
151 ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
153 ellis_url = "http://" + ellis_ip + "/"
154 url = ellis_url + "accounts"
156 params = {"password": "functest",
157 "full_name": "opnfv functest user",
158 "email": "functest@opnfv.fr",
159 "signup_code": "secret"}
161 rq = requests.post(url, data=params)
163 while rq.status_code != 201 and i > 0:
164 rq = requests.post(url, data=params)
168 if rq.status_code == 201:
169 url = ellis_url + "session"
170 rq = requests.post(url, data=params)
173 url = ellis_url + "accounts/" + params['email'] + "/numbers"
175 rq = requests.post(url, cookies=cookies)
177 while rq.status_code != 200 and i > 0:
178 rq = requests.post(url, cookies=cookies)
182 if rq.status_code != 200:
183 step_failure("sig_test", "Unable to create a number: %s"
184 % rq.json()['reason'])
186 start_time_ts = time.time()
187 end_time_ts = start_time_ts
188 logger.info("vIMS functional test Start Time:'%s'" % (
189 datetime.datetime.fromtimestamp(start_time_ts).strftime(
190 '%Y-%m-%d %H:%M:%S')))
191 nameservers = ft_utils.get_resolvconf_ns()
193 for ns in nameservers:
194 resolvconf += "\nnameserver " + ns
197 script = ('echo -e "nameserver ' + dns_ip + resolvconf +
198 '" > /etc/resolv.conf; ')
199 script += 'source /etc/profile.d/rvm.sh; '
200 script += 'cd ' + VIMS_TEST_DIR + '; '
201 script += ('rake test[' + CW_INPUTS["public_domain"] +
202 '] SIGNUP_CODE="secret"')
204 cmd = "/bin/bash -c '" + script + "'"
205 output_file = "output.txt"
206 f = open(output_file, 'w+')
207 subprocess.call(cmd, shell=True, stdout=f,
208 stderr=subprocess.STDOUT)
210 end_time_ts = time.time()
211 duration = round(end_time_ts - start_time_ts, 1)
212 logger.info("vIMS functional test duration:'%s'" % duration)
213 f = open(output_file, 'r')
215 if result != "" and logger:
218 vims_test_result = ""
220 logger.debug("Trying to load test results")
221 with open(VIMS_TEST_DIR + "temp.json") as f:
222 vims_test_result = json.load(f)
225 logger.error("Unable to retrieve test results")
227 set_result("sig_test", duration, vims_test_result)
229 # success criteria for vIMS (for Brahmaputra)
230 # - orchestrator deployed
232 # TODO use test criteria defined in config file
235 if (RESULTS['orchestrator']['duration'] > 0 and
236 RESULTS['vIMS']['duration'] > 0):
239 logger.error("Unable to set test status")
241 ft_utils.push_results_to_db("functest",
249 os.remove(VIMS_TEST_DIR + "temp.json")
251 logger.error("Deleting file failed")
256 # ############### GENERAL INITIALISATION ################
258 if not os.path.exists(VIMS_DATA_DIR):
259 os.makedirs(VIMS_DATA_DIR)
261 ks_creds = os_utils.get_credentials("keystone")
262 nv_creds = os_utils.get_credentials("nova")
263 nt_creds = os_utils.get_credentials("neutron")
265 logger.info("Prepare OpenStack plateform (create tenant and user)")
266 keystone = ksclient.Client(**ks_creds)
268 user_id = os_utils.get_user_id(keystone, ks_creds['username'])
270 step_failure("init", "Error : Failed to get id of " +
271 ks_creds['username'])
273 tenant_id = os_utils.create_tenant(
274 keystone, TENANT_NAME, TENANT_DESCRIPTION)
276 step_failure("init", "Error : Failed to create " +
277 TENANT_NAME + " tenant")
279 roles_name = ["admin", "Admin"]
281 for role_name in roles_name:
283 role_id = os_utils.get_role_id(keystone, role_name)
286 logger.error("Error : Failed to get id for %s role" % role_name)
288 if not os_utils.add_role_user(keystone, user_id, role_id, tenant_id):
289 logger.error("Error : Failed to add %s on tenant" %
290 ks_creds['username'])
292 user_id = os_utils.create_user(
293 keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
295 logger.error("Error : Failed to create %s user" % TENANT_NAME)
297 logger.info("Update OpenStack creds informations")
299 "username": TENANT_NAME,
300 "password": TENANT_NAME,
301 "tenant_name": TENANT_NAME,
305 "tenant_name": TENANT_NAME,
309 "project_id": TENANT_NAME,
312 logger.info("Upload some OS images if it doesn't exist")
313 glance = os_utils.get_glance_client()
315 for img in IMAGES.keys():
316 image_name = IMAGES[img]['image_name']
317 image_url = IMAGES[img]['image_url']
319 image_id = os_utils.get_image_id(glance, image_name)
322 logger.info("""%s image doesn't exist on glance repository. Try
323 downloading this image and upload on glance !""" % image_name)
324 image_id = download_and_add_image_on_glance(
325 glance, image_name, image_url)
330 "Error : Failed to find or upload required OS "
331 "image for this deployment")
333 nova = nvclient.Client("2", **nv_creds)
335 logger.info("Update security group quota for this tenant")
336 neutron = ntclient.Client(**nt_creds)
337 if not os_utils.update_sg_quota(neutron, tenant_id, 50, 100):
340 "Failed to update security group quota for tenant " + TENANT_NAME)
342 # ############### CLOUDIFY INITIALISATION ################
343 public_auth_url = keystone.service_catalog.url_for(
344 service_type='identity', endpoint_type='publicURL')
346 cfy = orchestrator(VIMS_DATA_DIR, CFY_INPUTS)
348 cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
349 'password'], tenant_name=ks_creds['tenant_name'],
350 auth_url=public_auth_url)
352 logger.info("Collect flavor id for cloudify manager server")
353 nova = nvclient.Client("2", **nv_creds)
355 flavor_name = "m1.large"
356 flavor_id = os_utils.get_flavor_id(nova, flavor_name)
357 for requirement in CFY_MANAGER_REQUIERMENTS:
358 if requirement == 'ram_min':
359 flavor_id = os_utils.get_flavor_id_by_ram_range(
360 nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 10000)
364 "Failed to find %s flavor. "
365 "Try with ram range default requirement !" % flavor_name)
366 flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
369 step_failure("orchestrator",
370 "Failed to find required flavor for this deployment")
372 cfy.set_flavor_id(flavor_id)
374 image_name = "centos_7"
375 image_id = os_utils.get_image_id(glance, image_name)
376 for requirement in CFY_MANAGER_REQUIERMENTS:
377 if requirement == 'os_image':
378 image_id = os_utils.get_image_id(
379 glance, CFY_MANAGER_REQUIERMENTS['os_image'])
384 "Error : Failed to find required OS image for cloudify manager")
386 cfy.set_image_id(image_id)
388 ext_net = os_utils.get_external_net(neutron)
390 step_failure("orchestrator", "Failed to get external network")
392 cfy.set_external_network_name(ext_net)
394 ns = ft_utils.get_resolvconf_ns()
396 cfy.set_nameservers(ns)
398 if 'compute' in nova.client.services_url:
399 cfy.set_nova_url(nova.client.services_url['compute'])
400 if neutron.httpclient.endpoint_url is not None:
401 cfy.set_neutron_url(neutron.httpclient.endpoint_url)
403 logger.info("Prepare virtualenv for cloudify-cli")
404 cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
405 ft_utils.execute_command(cmd)
407 cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
408 ft_utils.execute_command(cmd)
410 cfy.download_manager_blueprint(
411 CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
413 # ############### CLOUDIFY DEPLOYMENT ################
414 start_time_ts = time.time()
415 end_time_ts = start_time_ts
416 logger.info("Cloudify deployment Start Time:'%s'" % (
417 datetime.datetime.fromtimestamp(start_time_ts).strftime(
418 '%Y-%m-%d %H:%M:%S')))
420 error = cfy.deploy_manager()
422 step_failure("orchestrator", error)
424 end_time_ts = time.time()
425 duration = round(end_time_ts - start_time_ts, 1)
426 logger.info("Cloudify deployment duration:'%s'" % duration)
427 set_result("orchestrator", duration, "")
429 # ############### CLEARWATER INITIALISATION ################
431 cw = clearwater(CW_INPUTS, cfy, logger)
433 logger.info("Collect flavor id for all clearwater vm")
434 nova = nvclient.Client("2", **nv_creds)
436 flavor_name = "m1.small"
437 flavor_id = os_utils.get_flavor_id(nova, flavor_name)
438 for requirement in CW_REQUIERMENTS:
439 if requirement == 'ram_min' and flavor_id == '':
440 flavor_id = os_utils.get_flavor_id_by_ram_range(
441 nova, CW_REQUIERMENTS['ram_min'], 4500)
445 "Failed to find %s flavor. Try with ram range "
446 "default requirement !" % flavor_name)
447 flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
451 "vIMS", "Failed to find required flavor for this deployment")
453 cw.set_flavor_id(flavor_id)
455 image_name = "ubuntu_14.04"
456 image_id = os_utils.get_image_id(glance, image_name)
457 for requirement in CW_REQUIERMENTS:
458 if requirement == 'os_image':
459 image_id = os_utils.get_image_id(
460 glance, CW_REQUIERMENTS['os_image'])
465 "Error : Failed to find required OS image for cloudify manager")
467 cw.set_image_id(image_id)
469 ext_net = os_utils.get_external_net(neutron)
471 step_failure("vIMS", "Failed to get external network")
473 cw.set_external_network_name(ext_net)
475 # ############### CLEARWATER DEPLOYMENT ################
477 start_time_ts = time.time()
478 end_time_ts = start_time_ts
479 logger.info("vIMS VNF deployment Start Time:'%s'" % (
480 datetime.datetime.fromtimestamp(start_time_ts).strftime(
481 '%Y-%m-%d %H:%M:%S')))
483 error = cw.deploy_vnf(CW_BLUEPRINT)
485 step_failure("vIMS", error)
487 end_time_ts = time.time()
488 duration = round(end_time_ts - start_time_ts, 1)
489 logger.info("vIMS VNF deployment duration:'%s'" % duration)
490 set_result("vIMS", duration, "")
492 # ############### CLEARWATER TEST ################
496 # ########## CLEARWATER UNDEPLOYMENT ############
500 # ########### CLOUDIFY UNDEPLOYMENT #############
502 cfy.undeploy_manager()
504 # ############## GENERAL CLEANUP ################
508 ks_creds = os_utils.get_credentials("keystone")
510 keystone = ksclient.Client(**ks_creds)
512 logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
513 tenant_id = os_utils.get_tenant_id(
514 keystone, CFY_INPUTS['keystone_tenant_name'])
516 logger.error("Error : Failed to get id of %s tenant" %
517 CFY_INPUTS['keystone_tenant_name'])
519 if not os_utils.delete_tenant(keystone, tenant_id):
520 logger.error("Error : Failed to remove %s tenant" %
521 CFY_INPUTS['keystone_tenant_name'])
523 logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
524 user_id = os_utils.get_user_id(
525 keystone, CFY_INPUTS['keystone_username'])
527 logger.error("Error : Failed to get id of %s user" %
528 CFY_INPUTS['keystone_username'])
530 if not os_utils.delete_user(keystone, user_id):
531 logger.error("Error : Failed to remove %s user" %
532 CFY_INPUTS['keystone_username'])
535 if __name__ == '__main__':