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 ########################################################################
26 import keystoneclient.v2_0.client as ksclient
27 import glanceclient.client as glclient
28 import novaclient.client as nvclient
29 from neutronclient.v2_0 import client as ntclient
31 from orchestrator import *
32 from clearwater import *
35 pp = pprint.PrettyPrinter(indent=4)
38 parser = argparse.ArgumentParser()
39 parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
40 parser.add_argument("-r", "--report",
41 help="Create json result file",
43 parser.add_argument("-n", "--noclean",
44 help="Don't clean the created resources for this test.",
46 args = parser.parse_args()
48 """ logging configuration """
49 logger = logging.getLogger('vIMS')
50 logger.setLevel(logging.INFO)
52 ch = logging.StreamHandler()
54 ch.setLevel(logging.DEBUG)
56 ch.setLevel(logging.INFO)
57 formatter = logging.Formatter(
58 '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
59 ch.setFormatter(formatter)
62 REPO_PATH = os.environ['repos_dir'] + '/functest/'
63 if not os.path.exists(REPO_PATH):
64 logger.error("Functest repository directory not found '%s'" % REPO_PATH)
66 sys.path.append(REPO_PATH + "testcases/")
69 with open("/home/opnfv/functest/conf/config_functest.yaml") as f:
70 functest_yaml = yaml.safe_load(f)
74 VIMS_DIR = REPO_PATH + \
75 functest_yaml.get("general").get("directories").get("dir_vIMS")
76 VIMS_DATA_DIR = functest_yaml.get("general").get(
77 "directories").get("dir_vIMS_data") + "/"
78 VIMS_TEST_DIR = functest_yaml.get("general").get(
79 "directories").get("dir_repo_vims_test") + "/"
80 DB_URL = functest_yaml.get("results").get("test_db_url")
82 TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name")
83 TENANT_DESCRIPTION = functest_yaml.get("vIMS").get(
84 "general").get("tenant_description")
85 IMAGES = functest_yaml.get("vIMS").get("general").get("images")
87 CFY_MANAGER_BLUEPRINT = functest_yaml.get(
88 "vIMS").get("cloudify").get("blueprint")
89 CFY_MANAGER_REQUIERMENTS = functest_yaml.get(
90 "vIMS").get("cloudify").get("requierments")
91 CFY_INPUTS = functest_yaml.get("vIMS").get("cloudify").get("inputs")
93 CW_BLUEPRINT = functest_yaml.get("vIMS").get("clearwater").get("blueprint")
94 CW_DEPLOYMENT_NAME = functest_yaml.get("vIMS").get(
95 "clearwater").get("deployment-name")
96 CW_INPUTS = functest_yaml.get("vIMS").get("clearwater").get("inputs")
97 CW_REQUIERMENTS = functest_yaml.get("vIMS").get(
98 "clearwater").get("requierments")
100 CFY_DEPLOYMENT_DURATION = 0
101 CW_DEPLOYMENT_DURATION = 0
103 RESULTS = {'orchestrator': {'duration': 0, 'result': ''},
104 'vIMS': {'duration': 0, 'result': ''},
105 'sig_test': {'duration': 0, 'result': ''}}
108 def download_and_add_image_on_glance(glance, image_name, image_url):
109 dest_path = VIMS_DATA_DIR + "tmp/"
110 if not os.path.exists(dest_path):
111 os.makedirs(dest_path)
112 file_name = image_url.rsplit('/')[-1]
113 if not functest_utils.download_url(image_url, dest_path):
114 logger.error("Failed to download image %s" % file_name)
117 image = functest_utils.create_glance_image(
118 glance, image_name, dest_path + file_name)
120 logger.error("Failed to upload image on glance")
126 def step_failure(step_name, error_msg):
127 logger.error(error_msg)
128 set_result(step_name, 0, error_msg)
135 logger.debug("Pushing results to DB....")
137 scenario = functest_utils.get_scenario(logger)
138 pod_name = functest_utils.get_pod_name(logger)
139 build_tag = functest_utils.get_build_tag(logger)
141 functest_utils.push_results_to_db(db_url=DB_URL,
144 logger=logger, pod_name=pod_name,
150 def set_result(step_name, duration=0, result=""):
151 RESULTS[step_name] = {'duration': duration, 'result': result}
154 def test_clearwater():
158 script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
159 script += "cd " + VIMS_DATA_DIR + "; "
160 script += "cfy deployments outputs -d " + CW_DEPLOYMENT_NAME + \
161 " | grep Value: | sed \"s/ *Value: //g\";"
162 cmd = "/bin/bash -c '" + script + "'"
165 logger.debug("Trying to get clearwater nameserver IP ... ")
166 dns_ip = os.popen(cmd).read()
167 dns_ip = dns_ip.splitlines()[0]
169 logger.error("Unable to retrieve the IP of the DNS server !")
171 start_time_ts = time.time()
172 end_time_ts = start_time_ts
173 logger.info("vIMS functional test Start Time:'%s'" % (
174 datetime.datetime.fromtimestamp(start_time_ts).strftime(
175 '%Y-%m-%d %H:%M:%S')))
176 nameservers = functest_utils.get_resolvconf_ns()
178 for ns in nameservers:
179 resolvconf += "\nnameserver " + ns
182 script = 'echo -e "nameserver ' + dns_ip + resolvconf + '" > /etc/resolv.conf; '
183 script += 'source /etc/profile.d/rvm.sh; '
184 script += 'cd ' + VIMS_TEST_DIR + '; '
185 script += 'rake test[' + \
186 CW_INPUTS["public_domain"] + '] SIGNUP_CODE="secret"'
188 cmd = "/bin/bash -c '" + script + "'"
189 output_file = "output.txt"
190 f = open(output_file, 'w+')
191 p = subprocess.call(cmd, shell=True, stdout=f,
192 stderr=subprocess.STDOUT)
194 end_time_ts = time.time()
195 duration = round(end_time_ts - start_time_ts, 1)
196 logger.info("vIMS functional test duration:'%s'" % duration)
197 f = open(output_file, 'r')
199 if result != "" and logger:
202 vims_test_result = ""
204 logger.debug("Trying to load test results")
205 with open(VIMS_TEST_DIR + "temp.json") 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)
215 os.remove(VIMS_TEST_DIR + "temp.json")
217 logger.error("Deleting file failed")
222 ################ GENERAL INITIALISATION ################
224 if not os.path.exists(VIMS_DATA_DIR):
225 os.makedirs(VIMS_DATA_DIR)
227 ks_creds = functest_utils.get_credentials("keystone")
228 nv_creds = functest_utils.get_credentials("nova")
229 nt_creds = functest_utils.get_credentials("neutron")
231 logger.info("Prepare OpenStack plateform (create tenant and user)")
232 keystone = ksclient.Client(**ks_creds)
234 user_id = functest_utils.get_user_id(keystone, ks_creds['username'])
236 step_failure("init", "Error : Failed to get id of " +
237 ks_creds['username'])
239 tenant_id = functest_utils.create_tenant(
240 keystone, TENANT_NAME, TENANT_DESCRIPTION)
242 step_failure("init", "Error : Failed to create " +
243 TENANT_NAME + " tenant")
245 roles_name = ["admin", "Admin"]
247 for role_name in roles_name:
249 role_id = functest_utils.get_role_id(keystone, role_name)
252 logger.error("Error : Failed to get id for %s role" % role_name)
254 if not functest_utils.add_role_user(keystone, user_id, role_id, tenant_id):
255 logger.error("Error : Failed to add %s on tenant" %
256 ks_creds['username'])
258 user_id = functest_utils.create_user(
259 keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
261 logger.error("Error : Failed to create %s user" % TENANT_NAME)
263 logger.info("Update OpenStack creds informations")
265 "username": TENANT_NAME,
266 "password": TENANT_NAME,
267 "tenant_name": TENANT_NAME,
271 "tenant_name": TENANT_NAME,
275 "project_id": TENANT_NAME,
278 logger.info("Upload some OS images if it doesn't exist")
279 glance_endpoint = keystone.service_catalog.url_for(service_type='image',
280 endpoint_type='publicURL')
281 glance = glclient.Client(1, glance_endpoint, token=keystone.auth_token)
283 for img in IMAGES.keys():
284 image_name = IMAGES[img]['image_name']
285 image_url = IMAGES[img]['image_url']
287 image_id = functest_utils.get_image_id(glance, image_name)
290 logger.info("""%s image doesn't exist on glance repository.
291 Try downloading this image and upload on glance !""" % image_name)
292 image_id = download_and_add_image_on_glance(
293 glance, image_name, image_url)
297 "init", "Error : Failed to find or upload required OS image for this deployment")
299 nova = nvclient.Client("2", **nv_creds)
301 logger.info("Update security group quota for this tenant")
302 neutron = ntclient.Client(**nt_creds)
303 if not functest_utils.update_sg_quota(neutron, tenant_id, 50, 100):
305 "init", "Failed to update security group quota for tenant " + TENANT_NAME)
307 logger.info("Update cinder quota for this tenant")
308 from cinderclient import client as cinderclient
310 creds_cinder = functest_utils.get_credentials("cinder")
311 cinder_client = cinderclient.Client('1', creds_cinder['username'],
312 creds_cinder['api_key'],
313 creds_cinder['project_id'],
314 creds_cinder['auth_url'],
315 service_type="volume")
316 if not functest_utils.update_cinder_quota(cinder_client, tenant_id, 20, 10, 150):
318 "init", "Failed to update cinder quota for tenant " + TENANT_NAME)
320 ################ CLOUDIFY INITIALISATION ################
322 cfy = orchestrator(VIMS_DATA_DIR, CFY_INPUTS, logger)
324 cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
325 'password'], tenant_name=ks_creds['tenant_name'], auth_url=ks_creds['auth_url'])
327 logger.info("Collect flavor id for cloudify manager server")
328 nova = nvclient.Client("2", **nv_creds)
330 flavor_name = "m1.medium"
331 flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
332 for requirement in CFY_MANAGER_REQUIERMENTS:
333 if requirement == 'ram_min':
334 flavor_id = functest_utils.get_flavor_id_by_ram_range(
335 nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 8196)
339 "Failed to find %s flavor. Try with ram range default requirement !" % flavor_name)
340 flavor_id = functest_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
343 step_failure("orchestrator",
344 "Failed to find required flavor for this deployment")
346 cfy.set_flavor_id(flavor_id)
348 image_name = "centos_7"
349 image_id = functest_utils.get_image_id(glance, image_name)
350 for requirement in CFY_MANAGER_REQUIERMENTS:
351 if requirement == 'os_image':
352 image_id = functest_utils.get_image_id(
353 glance, CFY_MANAGER_REQUIERMENTS['os_image'])
357 "orchestrator", "Error : Failed to find required OS image for cloudify manager")
359 cfy.set_image_id(image_id)
361 ext_net = functest_utils.get_external_net(neutron)
363 step_failure("orchestrator", "Failed to get external network")
365 cfy.set_external_network_name(ext_net)
367 ns = functest_utils.get_resolvconf_ns()
369 cfy.set_nameservers(ns)
371 logger.info("Prepare virtualenv for cloudify-cli")
372 cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
373 functest_utils.execute_command(cmd, logger)
375 cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
376 functest_utils.execute_command(cmd, logger)
378 cfy.download_manager_blueprint(
379 CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
381 ################ CLOUDIFY DEPLOYMENT ################
382 start_time_ts = time.time()
383 end_time_ts = start_time_ts
384 logger.info("Cloudify deployment Start Time:'%s'" % (
385 datetime.datetime.fromtimestamp(start_time_ts).strftime(
386 '%Y-%m-%d %H:%M:%S')))
388 error = cfy.deploy_manager()
390 step_failure("orchestrator", error)
392 end_time_ts = time.time()
393 duration = round(end_time_ts - start_time_ts, 1)
394 logger.info("Cloudify deployment duration:'%s'" % duration)
395 set_result("orchestrator", duration, "")
397 ################ CLEARWATER INITIALISATION ################
399 cw = clearwater(CW_INPUTS, cfy, logger)
401 logger.info("Collect flavor id for all clearwater vm")
402 nova = nvclient.Client("2", **nv_creds)
404 flavor_name = "m1.small"
405 flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
406 for requirement in CW_REQUIERMENTS:
407 if requirement == 'ram_min':
408 flavor_id = functest_utils.get_flavor_id_by_ram_range(
409 nova, CW_REQUIERMENTS['ram_min'], 8196)
413 "Failed to find %s flavor. Try with ram range default requirement !" % flavor_name)
414 flavor_id = functest_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
418 "vIMS", "Failed to find required flavor for this deployment")
420 cw.set_flavor_id(flavor_id)
422 image_name = "ubuntu_14.04"
423 image_id = functest_utils.get_image_id(glance, image_name)
424 for requirement in CW_REQUIERMENTS:
425 if requirement == 'os_image':
426 image_id = functest_utils.get_image_id(
427 glance, CW_REQUIERMENTS['os_image'])
431 "vIMS", "Error : Failed to find required OS image for cloudify manager")
433 cw.set_image_id(image_id)
435 ext_net = functest_utils.get_external_net(neutron)
437 step_failure("vIMS", "Failed to get external network")
439 cw.set_external_network_name(ext_net)
441 ################ CLEARWATER DEPLOYMENT ################
443 start_time_ts = time.time()
444 end_time_ts = start_time_ts
445 logger.info("vIMS VNF deployment Start Time:'%s'" % (
446 datetime.datetime.fromtimestamp(start_time_ts).strftime(
447 '%Y-%m-%d %H:%M:%S')))
449 error = cw.deploy_vnf(CW_BLUEPRINT)
451 step_failure("vIMS", error)
453 end_time_ts = time.time()
454 duration = round(end_time_ts - start_time_ts, 1)
455 logger.info("vIMS VNF deployment duration:'%s'" % duration)
456 set_result("vIMS", duration, "")
458 ################ CLEARWATER TEST ################
462 ########### CLEARWATER UNDEPLOYMENT ############
466 ############ CLOUDIFY UNDEPLOYMENT #############
468 cfy.undeploy_manager()
470 ############### GENERAL CLEANUP ################
474 ks_creds = functest_utils.get_credentials("keystone")
476 keystone = ksclient.Client(**ks_creds)
478 logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
479 tenant_id = functest_utils.get_tenant_id(
480 keystone, CFY_INPUTS['keystone_tenant_name'])
482 logger.error("Error : Failed to get id of %s tenant" %
483 CFY_INPUTS['keystone_tenant_name'])
485 if not functest_utils.delete_tenant(keystone, tenant_id):
486 logger.error("Error : Failed to remove %s tenant" %
487 CFY_INPUTS['keystone_tenant_name'])
489 logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
490 user_id = functest_utils.get_user_id(
491 keystone, CFY_INPUTS['keystone_username'])
493 logger.error("Error : Failed to get id of %s user" %
494 CFY_INPUTS['keystone_username'])
496 if not functest_utils.delete_user(keystone, user_id):
497 logger.error("Error : Failed to remove %s user" %
498 CFY_INPUTS['keystone_username'])
501 if __name__ == '__main__':