Change default order of tests
[functest.git] / testcases / vIMS / CI / vIMS.py
1 #!/usr/bin/python
2 # coding: utf8
3 #######################################################################
4 #
5 #   Copyright (c) 2015 Orange
6 #   valentin.boucher@orange.com
7 #
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 ########################################################################
13
14 import os, time, subprocess, logging, argparse, yaml, pprint, sys, shutil, json, datetime
15 from git import Repo
16 import keystoneclient.v2_0.client as ksclient
17 import glanceclient.client as glclient
18 import novaclient.client as nvclient
19 from neutronclient.v2_0 import client as ntclient
20
21 import urllib
22 pp = pprint.PrettyPrinter(indent=4)
23
24
25 parser = argparse.ArgumentParser()
26 parser.add_argument("repo_path", help="Path to the repository")
27 parser.add_argument("-d", "--debug", help="Debug mode",  action="store_true")
28 args = parser.parse_args()
29
30 sys.path.append(args.repo_path + "testcases/")
31
32 import functest_utils
33
34 """ logging configuration """
35 logger = logging.getLogger('vIMS')
36 logger.setLevel(logging.DEBUG)
37
38 ch = logging.StreamHandler()
39 if args.debug:
40     ch.setLevel(logging.DEBUG)
41 else:
42     ch.setLevel(logging.INFO)
43 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
44 ch.setFormatter(formatter)
45 logger.addHandler(ch)
46
47
48 # with open(args.repo_path+"config_functest.yaml") as f:
49 with open(args.repo_path + "testcases/config_functest.yaml") as f:
50     functest_yaml = yaml.safe_load(f)
51 f.close()
52
53 # Cloudify parameters
54 REPO_PATH = args.repo_path
55 VIMS_DIR = REPO_PATH + functest_yaml.get("general").get("directories").get("dir_vIMS")
56 VIMS_DATA_DIR = functest_yaml.get("general").get("directories").get("dir_vIMS_data")+"/"
57 VIMS_TEST_DIR = functest_yaml.get("general").get("directories").get("dir_repo_vims_test")+"/"
58 TEST_DB = functest_yaml.get("results").get("test_db_url")
59
60 TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name")
61 TENANT_DESCRIPTION = functest_yaml.get("vIMS").get("general").get("tenant_description")
62 BASE_IMAGE_URL = functest_yaml.get("vIMS").get("general").get("base_image_url")
63 BASE_IMAGE_NAME = functest_yaml.get("vIMS").get("general").get("base_image_name")
64 GLANCE_IMAGE_NAME = functest_yaml.get("vIMS").get("cloudify").get("inputs").get("image_id")
65
66 CFY_MANAGER_BLUEPRINT = functest_yaml.get("vIMS").get("cloudify").get("blueprint")
67 CFY_INPUTS =  functest_yaml.get("vIMS").get("cloudify").get("inputs")
68 CFY_INPUTS_PATH =  functest_yaml.get("vIMS").get("cloudify").get("inputs_path")
69
70 CW_BLUEPRINT = functest_yaml.get("vIMS").get("clearwater").get("blueprint")
71 CW_DEPLOYMENT_NAME = functest_yaml.get("vIMS").get("clearwater").get("deployment-name")
72 CW_INPUTS =  functest_yaml.get("vIMS").get("clearwater").get("inputs")
73 CW_DOMAIN_NAME =  functest_yaml.get("vIMS").get("clearwater").get("inputs").get("public_domain")
74
75 CFY_DEPLOYMENT_DURATION = 0
76 CW_DEPLOYMENT_DURATION = 0
77
78
79 def pMsg(value):
80     """pretty printing"""
81     pp.pprint(value)
82
83 def download_and_add_image_on_glance(glance, image_name, image_url):
84     dest_path = VIMS_DATA_DIR + "tmp/"
85     if not os.path.exists(dest_path):
86         os.makedirs(dest_path)
87     file_name = image_url.rsplit('/')[-1]
88     if not functest_utils.download_url(image_url, dest_path):
89         logger.error("Failed to download image %s" %file_name)
90         return False
91
92     image = functest_utils.create_glance_image(glance, image_name, dest_path + file_name)
93     if not image:
94         logger.error("Failed to upload image on glance")
95         return False
96
97     return image
98
99 def download_blueprints(blueprint_url, branch, dest_path):
100     if os.path.exists(dest_path):
101         shutil.rmtree(dest_path)
102     try:
103         Repo.clone_from(blueprint_url, dest_path, branch=branch)
104         return True
105     except:
106         return False
107
108 def initialize_deployments():
109     if not os.path.exists(VIMS_DATA_DIR):
110         os.makedirs(VIMS_DATA_DIR)
111
112     ks_creds = functest_utils.get_credentials("keystone")
113     nv_creds = functest_utils.get_credentials("nova")
114     nt_creds = functest_utils.get_credentials("neutron")
115
116     logger.info("Prepare OpenStack plateform (create tenant and user)")
117     keystone = ksclient.Client(**ks_creds)
118
119     user_id = functest_utils.get_user_id(keystone, ks_creds['username'])
120     if user_id == '':
121         logger.error("Error : Failed to get id of %s user" %ks_creds['username'])
122         exit(-1)
123
124     tenant_id = functest_utils.create_tenant(keystone, TENANT_NAME, TENANT_DESCRIPTION)
125     if tenant_id == '':
126         logger.error("Error : Failed to create %s tenant" %TENANT_NAME)
127         exit(-1)
128
129     role_name = "admin"
130     role_id = functest_utils.get_role_id(keystone, role_name)
131     if role_id == '':
132         logger.error("Error : Failed to get id for %s role" %role_name)
133
134     if not functest_utils.add_role_user(keystone, user_id, role_id, tenant_id):
135         logger.error("Error : Failed to add %s on tenant" %ks_creds['username'])
136
137     user_id = functest_utils.create_user(keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
138     if user_id == '':
139         logger.error("Error : Failed to create %s user" %TENANT_NAME)
140
141     logger.info("Update OpenStack creds informations")
142     ks_creds.update({
143         "username": TENANT_NAME,
144         "password": TENANT_NAME,
145         "tenant_name": TENANT_NAME,
146         })
147
148     nt_creds.update({
149         "tenant_name": TENANT_NAME,
150         })
151
152     nv_creds.update({
153         "project_id": TENANT_NAME,
154         })
155
156     logger.info("Upload ubuntu image if it doesn't exist")
157     glance_endpoint = keystone.service_catalog.url_for(service_type='image',
158                                                    endpoint_type='publicURL')
159     glance = glclient.Client(1, glance_endpoint, token=keystone.auth_token)
160
161     image_id = functest_utils.get_image_id(glance, BASE_IMAGE_NAME)
162     if image_id == '':
163         logger.info("""%s image doesn't exist on glance repository.
164                         Try downloading this image and upload on glance !""" %BASE_IMAGE_NAME)
165         image_id = download_and_add_image_on_glance(glance, BASE_IMAGE_NAME, BASE_IMAGE_URL)
166
167     if image_id == '':
168         logger.error("Error : Failed to find or upload required OS image for this deployment" %flavor_name)
169         exit(-1)
170
171     logger.info("Collect flavor id for cloudify and clearwater VMs")
172     nova = nvclient.Client("2", **nv_creds)
173
174     flavor_name = "m1.small"
175     flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
176     if flavor_id == '':
177         logger.error("Failed to find %s flavor. Try with ram range requirement !" %flavor_name)
178         flavor_id = get_flavor_id_by_ram_range(nova, 1792, 2048)
179
180     if flavor_id == '':
181         logger.error("Failed to find required flavor for this deployment" %flavor_name)
182         exit(-1)
183
184     logger.info("Update security group quota for this tenant")
185     neutron = ntclient.Client(**nt_creds)
186     if not functest_utils.update_sg_quota(neutron, tenant_id, 50, 100):
187         logger.error("Failed to update security group quota for tenant %s" %TENANT_NAME)
188         exit(-1)
189
190     ext_net = functest_utils.get_external_net(neutron)
191     if not ext_net:
192         logger.error("Failed to get external network")
193         exit(-1)
194
195     logger.info("Update inputs informations")
196     CFY_INPUTS['image_id'] = image_id
197     CFY_INPUTS['flavor_id'] = flavor_id
198     CFY_INPUTS['external_network_name'] = ext_net
199
200     CW_INPUTS['image_id'] = image_id
201     CW_INPUTS['flavor_id'] = flavor_id
202     CW_INPUTS['external_network_name'] = ext_net
203
204     CFY_INPUTS['keystone_username'] = ks_creds['username']
205     CFY_INPUTS['keystone_password'] = ks_creds['password']
206     CFY_INPUTS['keystone_url'] = ks_creds['auth_url']
207     CFY_INPUTS['keystone_tenant_name'] = ks_creds['tenant_name']
208
209     logger.info("Prepare virtualenv for cloudify-cli")
210     cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
211     functest_utils.execute_command(cmd,logger)
212     cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
213     functest_utils.execute_command(cmd,logger)
214
215 def cleanup_deployments():
216     ks_creds = functest_utils.get_credentials("keystone")
217
218     keystone = ksclient.Client(**ks_creds)
219
220     logger.info("Removing %s tenant .." %CFY_INPUTS['keystone_tenant_name'])
221     tenant_id = functest_utils.get_tenant_id(keystone, CFY_INPUTS['keystone_tenant_name'])
222     if tenant_id == '':
223         logger.error("Error : Failed to get id of %s tenant" %CFY_INPUTS['keystone_tenant_name'])
224     else:
225         if not functest_utils.delete_tenant(keystone, tenant_id):
226             logger.error("Error : Failed to remove %s tenant" %CFY_INPUTS['keystone_tenant_name'])
227
228     logger.info("Removing %s user .." %CFY_INPUTS['keystone_username'])
229     user_id = functest_utils.get_user_id(keystone, CFY_INPUTS['keystone_username'])
230     if user_id == '':
231         logger.error("Error : Failed to get id of %s user" %CFY_INPUTS['keystone_username'])
232     else:
233         if not functest_utils.delete_user(keystone, user_id):
234             logger.error("Error : Failed to remove %s user" %CFY_INPUTS['keystone_username'])
235
236 def deploy_cloudify_manager():
237
238     logger.info("Downloading the cloudify manager server blueprint")
239     download_result = download_blueprints(CFY_MANAGER_BLUEPRINT['url'],
240                                                         CFY_MANAGER_BLUEPRINT['branch'],
241                                                         VIMS_DATA_DIR + 'cloudify-manager-blueprint/')
242
243     if not download_result:
244         logger.error("Failed to download manager blueprint")
245         exit(-1)
246
247     logger.info("Writing the inputs file")
248     with open( VIMS_DATA_DIR + 'cloudify-manager-blueprint/' + CFY_INPUTS_PATH, "w") as f:
249         f.write(yaml.dump(CFY_INPUTS, default_style='"') )
250     f.close()
251
252     start_time_ts = time.time()
253     end_time_ts = start_time_ts
254     logger.info("Cloudify deployment Start Time:'%s'" % (
255         datetime.datetime.fromtimestamp(start_time_ts).strftime(
256             '%Y-%m-%d %H:%M:%S')))
257
258     logger.info("Launching the cloudify-manager deployment")
259     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
260     script += "cd " + VIMS_DATA_DIR + "; "
261     script += "cfy init -r; "
262     script += "cd cloudify-manager-blueprint/openstack; "
263     script += "cfy local create-requirements -o requirements.txt -p openstack-manager-blueprint.yaml; "
264     script += "pip install -r requirements.txt; "
265     script += "cfy bootstrap --install-plugins -p openstack-manager-blueprint.yaml -i inputs.yaml; "
266     cmd = "/bin/bash -c '" + script + "'"
267     functest_utils.execute_command(cmd, logger)
268
269     logger.info("Cloudify-manager server is UP !")
270
271     global CFY_DEPLOYMENT_DURATION
272     end_time_ts = time.time()
273     CFY_DEPLOYMENT_DURATION = round(end_time_ts - start_time_ts, 1)
274     logger.info("Cloudify deployment duration:'%s'" %CFY_DEPLOYMENT_DURATION)
275
276 def undeploy_cloudify_manager():
277
278     logger.info("Launching the cloudify-manager undeployment")
279     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
280     script += "cd " + VIMS_DATA_DIR + "; "
281     script += "cfy teardown -f; "
282     cmd = "/bin/bash -c '" + script + "'"
283     functest_utils.execute_command(cmd, logger)
284
285     logger.info("Cloudify-manager server has been successfully removed!")
286
287 def deploy_clearwater():
288
289     logger.info("Downloading the {0} blueprint".format(CW_BLUEPRINT['file_name']))
290     download_result = download_blueprints(CW_BLUEPRINT['url'], CW_BLUEPRINT['branch'],
291                                               VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder'])
292
293     if not download_result:
294         logger.error("Failed to download blueprint {0}".format(CW_BLUEPRINT['file_name']))
295         exit(-1)
296
297     logger.info("Writing the inputs file")
298     with open(VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder'] + "/inputs.yaml", "w") as f:
299         f.write(yaml.dump(CW_INPUTS, default_style='"') )
300     f.close()
301
302     time.sleep(30)
303
304     start_time_ts = time.time()
305     end_time_ts = start_time_ts
306     logger.info("vIMS VNF deployment Start Time:'%s'" % (
307         datetime.datetime.fromtimestamp(start_time_ts).strftime(
308             '%Y-%m-%d %H:%M:%S')))
309
310     logger.info("Launching the {0} deployment".format(CW_BLUEPRINT['name']))
311     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
312     script += "cd " + VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder'] + "; "
313     script += "cfy blueprints upload -b " + CW_BLUEPRINT['name'] + " -p openstack-blueprint.yaml; "
314     script += "cfy deployments create -b " + CW_BLUEPRINT['name'] + " -d " + CW_DEPLOYMENT_NAME + " --inputs inputs.yaml; "
315     script += "cfy executions start -w install -d " + CW_DEPLOYMENT_NAME + " --timeout 1800; "
316
317     cmd = "/bin/bash -c '" + script + "'"
318     functest_utils.execute_command(cmd, logger)
319
320     logger.info("Clearwater vIMS is UP !")
321
322     global CW_DEPLOYMENT_DURATION
323     end_time_ts = time.time()
324     CW_DEPLOYMENT_DURATION = round(end_time_ts - start_time_ts, 1)
325     logger.info("vIMS VNF deployment duration:'%s'" %CW_DEPLOYMENT_DURATION)
326
327 def undeploy_clearwater():
328
329     logger.info("Launching the {0} undeployment".format(CW_BLUEPRINT['name']))
330     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
331     script += "cd " + VIMS_DATA_DIR + "; "
332     script += "cfy executions start -w uninstall -d " + CW_DEPLOYMENT_NAME + " --timeout 1800 ; "
333     script += "cfy deployments delete -d " + CW_DEPLOYMENT_NAME + "; "
334
335     cmd = "/bin/bash -c '" + script + "'"
336     functest_utils.execute_command(cmd, logger)
337
338 def test_clearwater():
339
340     time.sleep(120)
341
342     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
343     script += "cd " + VIMS_DATA_DIR + "; "
344     script += "cfy deployments outputs -d " + CW_DEPLOYMENT_NAME + " | grep Value: | sed \"s/ *Value: //g\";"
345     cmd = "/bin/bash -c '" + script + "'"
346
347     try:
348         logger.debug("Trying to get clearwater nameserver IP ... ")
349         dns_ip = os.popen(cmd).read()
350         dns_ip = dns_ip.splitlines()[0]
351     except:
352         logger.error("Unable to retrieve the IP of the DNS server !")
353
354     start_time_ts = time.time()
355     end_time_ts = start_time_ts
356     logger.info("vIMS functional test Start Time:'%s'" % (
357         datetime.datetime.fromtimestamp(start_time_ts).strftime(
358             '%Y-%m-%d %H:%M:%S')))
359
360     if dns_ip != "":
361         script = 'echo -e "nameserver ' + dns_ip + '\nnameserver 8.8.8.8\nnameserver 8.8.4.4" > /etc/resolv.conf; '
362         script += 'source /etc/profile.d/rvm.sh; '
363         script += 'cd ' + VIMS_TEST_DIR + '; '
364         script += 'rake test[' + CW_INPUTS["public_domain"] + '] SIGNUP_CODE="secret"'
365
366         cmd = "/bin/bash -c '" + script + "'"
367         output_file = "output.txt"
368         f = open(output_file, 'w+')
369         p = subprocess.call(cmd, shell=True, stdout=f, stderr=subprocess.STDOUT)
370         f.close()
371         end_time_ts = time.time()
372         duration = round(end_time_ts - start_time_ts, 1)
373         logger.info("vIMS functional test duration:'%s'" %duration)
374         f = open(output_file, 'r')
375         result = f.read()
376         if result != "" and logger:
377             logger.debug(result)
378
379         vims_test_result=""
380         try:
381             logger.debug("Trying to load test results")
382             with open(VIMS_TEST_DIR + "temp.json") as f:
383                 vims_test_result = json.load(f)
384             f.close()
385         except:
386             logger.error("Unable to retrieve test results")
387
388         if vims_test_result != "":
389             git_version = functest_utils.get_git_branch(args.repo_path)
390             functest_utils.push_results_to_db(db_url=TEST_DB, case_name="vIMS",
391                         logger=logger, pod_name="opnfv-jump-2", git_version=git_version,
392                         payload={'orchestrator_deployment_duration': CFY_DEPLOYMENT_DURATION,
393                         'VNF_deployment_duration': CW_DEPLOYMENT_DURATION,
394                         'functional_test': {'duration': duration,
395                         'result': vims_test_result}})
396         try:
397             os.remove(VIMS_TEST_DIR + "temp.json")
398         except:
399             logger.error("Deleting file failed")
400
401 def main():
402     initialize_deployments()
403     deploy_cloudify_manager()
404     deploy_clearwater()
405
406     test_clearwater()
407
408     undeploy_clearwater()
409     undeploy_cloudify_manager()
410     cleanup_deployments()
411
412 if __name__ == '__main__':
413     main()