Add jenkins build tag for result api
[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
15 import time
16 import subprocess
17 import logging
18 import argparse
19 import yaml
20 import pprint
21 import sys
22 import shutil
23 import json
24 import datetime
25 from git import Repo
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
30
31 from orchestrator import *
32 from clearwater import *
33
34 import urllib
35 pp = pprint.PrettyPrinter(indent=4)
36
37
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",
42                     action="store_true")
43 parser.add_argument("-n", "--noclean",
44                     help="Don't clean the created resources for this test.",
45                     action="store_true")
46 args = parser.parse_args()
47
48 """ logging configuration """
49 logger = logging.getLogger('vIMS')
50 logger.setLevel(logging.INFO)
51
52 ch = logging.StreamHandler()
53 if args.debug:
54     ch.setLevel(logging.DEBUG)
55 else:
56     ch.setLevel(logging.INFO)
57 formatter = logging.Formatter(
58     '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
59 ch.setFormatter(formatter)
60 logger.addHandler(ch)
61
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)
65     exit(-1)
66 sys.path.append(REPO_PATH + "testcases/")
67 import functest_utils
68
69 with open("/home/opnfv/functest/conf/config_functest.yaml") as f:
70     functest_yaml = yaml.safe_load(f)
71 f.close()
72
73 # Cloudify parameters
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")
81
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")
86
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")
92
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")
99
100 CFY_DEPLOYMENT_DURATION = 0
101 CW_DEPLOYMENT_DURATION = 0
102
103 RESULTS = {'orchestrator': {'duration': 0, 'result': ''},
104            'vIMS': {'duration': 0, 'result': ''},
105            'sig_test': {'duration': 0, 'result': ''}}
106
107
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)
115         return False
116
117     image = functest_utils.create_glance_image(
118         glance, image_name, dest_path + file_name)
119     if not image:
120         logger.error("Failed to upload image on glance")
121         return False
122
123     return image
124
125
126 def step_failure(step_name, error_msg):
127     logger.error(error_msg)
128     set_result(step_name, 0, error_msg)
129     push_results()
130     exit(-1)
131
132
133 def push_results():
134     if args.report:
135         logger.debug("Pushing results to DB....")
136
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)
140
141         functest_utils.push_results_to_db(db_url=DB_URL,
142                                           project="functest",
143                                           case_name="vIMS",
144                                           logger=logger, pod_name=pod_name,
145                                           version=scenario,
146                                           build_tag=build_tag,
147                                           payload=RESULTS)
148
149
150 def set_result(step_name, duration=0, result=""):
151     RESULTS[step_name] = {'duration': duration, 'result': result}
152
153
154 def test_clearwater():
155
156     time.sleep(180)
157
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 + "'"
163
164     try:
165         logger.debug("Trying to get clearwater nameserver IP ... ")
166         dns_ip = os.popen(cmd).read()
167         dns_ip = dns_ip.splitlines()[0]
168     except:
169         logger.error("Unable to retrieve the IP of the DNS server !")
170
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()
177     resolvconf = ""
178     for ns in nameservers:
179         resolvconf += "\nnameserver " + ns
180
181     if dns_ip != "":
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"'
187
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)
193         f.close()
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')
198         result = f.read()
199         if result != "" and logger:
200             logger.debug(result)
201
202         vims_test_result = ""
203         try:
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)
207             f.close()
208         except:
209             logger.error("Unable to retrieve test results")
210
211         set_result("sig_test", duration, vims_test_result)
212         push_results()
213
214         try:
215             os.remove(VIMS_TEST_DIR + "temp.json")
216         except:
217             logger.error("Deleting file failed")
218
219
220 def main():
221
222     ################ GENERAL INITIALISATION ################
223
224     if not os.path.exists(VIMS_DATA_DIR):
225         os.makedirs(VIMS_DATA_DIR)
226
227     ks_creds = functest_utils.get_credentials("keystone")
228     nv_creds = functest_utils.get_credentials("nova")
229     nt_creds = functest_utils.get_credentials("neutron")
230
231     logger.info("Prepare OpenStack plateform (create tenant and user)")
232     keystone = ksclient.Client(**ks_creds)
233
234     user_id = functest_utils.get_user_id(keystone, ks_creds['username'])
235     if user_id == '':
236         step_failure("init", "Error : Failed to get id of " +
237                      ks_creds['username'])
238
239     tenant_id = functest_utils.create_tenant(
240         keystone, TENANT_NAME, TENANT_DESCRIPTION)
241     if tenant_id == '':
242         step_failure("init", "Error : Failed to create " +
243                      TENANT_NAME + " tenant")
244
245     roles_name = ["admin", "Admin"]
246     role_id = ''
247     for role_name in roles_name:
248         if role_id == '':
249             role_id = functest_utils.get_role_id(keystone, role_name)
250
251     if role_id == '':
252         logger.error("Error : Failed to get id for %s role" % role_name)
253
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'])
257
258     user_id = functest_utils.create_user(
259         keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
260     if user_id == '':
261         logger.error("Error : Failed to create %s user" % TENANT_NAME)
262
263     logger.info("Update OpenStack creds informations")
264     ks_creds.update({
265         "username": TENANT_NAME,
266         "password": TENANT_NAME,
267         "tenant_name": TENANT_NAME,
268     })
269
270     nt_creds.update({
271         "tenant_name": TENANT_NAME,
272     })
273
274     nv_creds.update({
275         "project_id": TENANT_NAME,
276     })
277
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)
282
283     for img in IMAGES.keys():
284         image_name = IMAGES[img]['image_name']
285         image_url = IMAGES[img]['image_url']
286
287         image_id = functest_utils.get_image_id(glance, image_name)
288
289         if image_id == '':
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)
294
295         if image_id == '':
296             step_failure(
297                 "init", "Error : Failed to find or upload required OS image for this deployment")
298
299     nova = nvclient.Client("2", **nv_creds)
300
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):
304         step_failure(
305             "init", "Failed to update security group quota for tenant " + TENANT_NAME)
306
307     logger.info("Update cinder quota for this tenant")
308     from cinderclient import client as cinderclient
309
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):
317         step_failure(
318             "init", "Failed to update cinder quota for tenant " + TENANT_NAME)
319
320     ################ CLOUDIFY INITIALISATION ################
321
322     cfy = orchestrator(VIMS_DATA_DIR, CFY_INPUTS, logger)
323
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'])
326
327     logger.info("Collect flavor id for cloudify manager server")
328     nova = nvclient.Client("2", **nv_creds)
329
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)
336
337     if flavor_id == '':
338         logger.error(
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)
341
342     if flavor_id == '':
343         step_failure("orchestrator",
344                      "Failed to find required flavor for this deployment")
345
346     cfy.set_flavor_id(flavor_id)
347
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'])
354
355     if image_id == '':
356         step_failure(
357             "orchestrator", "Error : Failed to find required OS image for cloudify manager")
358
359     cfy.set_image_id(image_id)
360
361     ext_net = functest_utils.get_external_net(neutron)
362     if not ext_net:
363         step_failure("orchestrator", "Failed to get external network")
364
365     cfy.set_external_network_name(ext_net)
366
367     ns = functest_utils.get_resolvconf_ns()
368     if ns:
369         cfy.set_nameservers(ns)
370
371     logger.info("Prepare virtualenv for cloudify-cli")
372     cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
373     functest_utils.execute_command(cmd, logger)
374     time.sleep(3)
375     cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
376     functest_utils.execute_command(cmd, logger)
377
378     cfy.download_manager_blueprint(
379         CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
380
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')))
387
388     error = cfy.deploy_manager()
389     if error:
390         step_failure("orchestrator", error)
391
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, "")
396
397     ################ CLEARWATER INITIALISATION ################
398
399     cw = clearwater(CW_INPUTS, cfy, logger)
400
401     logger.info("Collect flavor id for all clearwater vm")
402     nova = nvclient.Client("2", **nv_creds)
403
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)
410
411     if flavor_id == '':
412         logger.error(
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)
415
416     if flavor_id == '':
417         step_failure(
418             "vIMS", "Failed to find required flavor for this deployment")
419
420     cw.set_flavor_id(flavor_id)
421
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'])
428
429     if image_id == '':
430         step_failure(
431             "vIMS", "Error : Failed to find required OS image for cloudify manager")
432
433     cw.set_image_id(image_id)
434
435     ext_net = functest_utils.get_external_net(neutron)
436     if not ext_net:
437         step_failure("vIMS", "Failed to get external network")
438
439     cw.set_external_network_name(ext_net)
440
441     ################ CLEARWATER DEPLOYMENT ################
442
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')))
448
449     error = cw.deploy_vnf(CW_BLUEPRINT)
450     if error:
451         step_failure("vIMS", error)
452
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, "")
457
458     ################ CLEARWATER TEST ################
459
460     test_clearwater()
461
462     ########### CLEARWATER UNDEPLOYMENT ############
463
464     cw.undeploy_vnf()
465
466     ############ CLOUDIFY UNDEPLOYMENT #############
467
468     cfy.undeploy_manager()
469
470     ############### GENERAL CLEANUP ################
471     if args.noclean:
472         exit(0)
473
474     ks_creds = functest_utils.get_credentials("keystone")
475
476     keystone = ksclient.Client(**ks_creds)
477
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'])
481     if tenant_id == '':
482         logger.error("Error : Failed to get id of %s tenant" %
483                      CFY_INPUTS['keystone_tenant_name'])
484     else:
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'])
488
489     logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
490     user_id = functest_utils.get_user_id(
491         keystone, CFY_INPUTS['keystone_username'])
492     if user_id == '':
493         logger.error("Error : Failed to get id of %s user" %
494                      CFY_INPUTS['keystone_username'])
495     else:
496         if not functest_utils.delete_user(keystone, user_id):
497             logger.error("Error : Failed to remove %s user" %
498                          CFY_INPUTS['keystone_username'])
499
500
501 if __name__ == '__main__':
502     main()