Merge "Add support for Promise test cases"
[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 args = parser.parse_args()
44
45 """ logging configuration """
46 logger = logging.getLogger('vIMS')
47 logger.setLevel(logging.DEBUG)
48
49 ch = logging.StreamHandler()
50 if args.debug:
51     ch.setLevel(logging.DEBUG)
52 else:
53     ch.setLevel(logging.INFO)
54 formatter = logging.Formatter(
55     '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
56 ch.setFormatter(formatter)
57 logger.addHandler(ch)
58
59 REPO_PATH = os.environ['repos_dir'] + '/functest/'
60 if not os.path.exists(REPO_PATH):
61     logger.error("Functest repository directory not found '%s'" % REPO_PATH)
62     exit(-1)
63 sys.path.append(REPO_PATH + "testcases/")
64 import functest_utils
65
66 with open("/home/opnfv/functest/conf/config_functest.yaml") as f:
67     functest_yaml = yaml.safe_load(f)
68 f.close()
69
70 # Cloudify parameters
71 VIMS_DIR = REPO_PATH + \
72     functest_yaml.get("general").get("directories").get("dir_vIMS")
73 VIMS_DATA_DIR = functest_yaml.get("general").get(
74     "directories").get("dir_vIMS_data") + "/"
75 VIMS_TEST_DIR = functest_yaml.get("general").get(
76     "directories").get("dir_repo_vims_test") + "/"
77 TEST_DB = functest_yaml.get("results").get("test_db_url")
78
79 TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name")
80 TENANT_DESCRIPTION = functest_yaml.get("vIMS").get(
81     "general").get("tenant_description")
82 IMAGES = functest_yaml.get("vIMS").get("general").get("images")
83
84 CFY_MANAGER_BLUEPRINT = functest_yaml.get(
85     "vIMS").get("cloudify").get("blueprint")
86 CFY_MANAGER_REQUIERMENTS = functest_yaml.get(
87     "vIMS").get("cloudify").get("requierments")
88 CFY_INPUTS = functest_yaml.get("vIMS").get("cloudify").get("inputs")
89
90 CW_BLUEPRINT = functest_yaml.get("vIMS").get("clearwater").get("blueprint")
91 CW_DEPLOYMENT_NAME = functest_yaml.get("vIMS").get(
92     "clearwater").get("deployment-name")
93 CW_INPUTS = functest_yaml.get("vIMS").get("clearwater").get("inputs")
94 CW_REQUIERMENTS = functest_yaml.get("vIMS").get(
95     "clearwater").get("requierments")
96
97 CFY_DEPLOYMENT_DURATION = 0
98 CW_DEPLOYMENT_DURATION = 0
99
100
101 def download_and_add_image_on_glance(glance, image_name, image_url):
102     dest_path = VIMS_DATA_DIR + "tmp/"
103     if not os.path.exists(dest_path):
104         os.makedirs(dest_path)
105     file_name = image_url.rsplit('/')[-1]
106     if not functest_utils.download_url(image_url, dest_path):
107         logger.error("Failed to download image %s" % file_name)
108         return False
109
110     image = functest_utils.create_glance_image(
111         glance, image_name, dest_path + file_name)
112     if not image:
113         logger.error("Failed to upload image on glance")
114         return False
115
116     return image
117
118
119 def test_clearwater():
120
121     time.sleep(180)
122
123     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
124     script += "cd " + VIMS_DATA_DIR + "; "
125     script += "cfy deployments outputs -d " + CW_DEPLOYMENT_NAME + \
126         " | grep Value: | sed \"s/ *Value: //g\";"
127     cmd = "/bin/bash -c '" + script + "'"
128
129     try:
130         logger.debug("Trying to get clearwater nameserver IP ... ")
131         dns_ip = os.popen(cmd).read()
132         dns_ip = dns_ip.splitlines()[0]
133     except:
134         logger.error("Unable to retrieve the IP of the DNS server !")
135
136     start_time_ts = time.time()
137     end_time_ts = start_time_ts
138     logger.info("vIMS functional test Start Time:'%s'" % (
139         datetime.datetime.fromtimestamp(start_time_ts).strftime(
140             '%Y-%m-%d %H:%M:%S')))
141     nameservers = functest_utils.get_resolvconf_ns()
142     resolvconf = ""
143     for ns in nameservers:
144         resolvconf += "\nnameserver " + ns
145
146     if dns_ip != "":
147         script = 'echo -e "nameserver ' + dns_ip + resolvconf + '" > /etc/resolv.conf; '
148         script += 'source /etc/profile.d/rvm.sh; '
149         script += 'cd ' + VIMS_TEST_DIR + '; '
150         script += 'rake test[' + \
151             CW_INPUTS["public_domain"] + '] SIGNUP_CODE="secret"'
152
153         cmd = "/bin/bash -c '" + script + "'"
154         output_file = "output.txt"
155         f = open(output_file, 'w+')
156         p = subprocess.call(cmd, shell=True, stdout=f,
157                             stderr=subprocess.STDOUT)
158         f.close()
159         end_time_ts = time.time()
160         duration = round(end_time_ts - start_time_ts, 1)
161         logger.info("vIMS functional test duration:'%s'" % duration)
162         f = open(output_file, 'r')
163         result = f.read()
164         if result != "" and logger:
165             logger.debug(result)
166
167         vims_test_result = ""
168         try:
169             logger.debug("Trying to load test results")
170             with open(VIMS_TEST_DIR + "temp.json") as f:
171                 vims_test_result = json.load(f)
172             f.close()
173         except:
174             logger.error("Unable to retrieve test results")
175
176         if vims_test_result != "":
177             if args.report:
178                 logger.debug("Push result into DB")
179                 logger.debug("Pushing results to DB....")
180                 scenario = functest_utils.get_scenario(logger)
181                 functest_utils.push_results_to_db(db_url=TEST_DB, case_name="vIMS",
182                                                   logger=logger, pod_name=functest_utils.get_pod_name(logger),
183                                                   version=scenario,
184                                                   payload={'orchestrator': {'duration': CFY_DEPLOYMENT_DURATION,
185                                                                             'result': ""},
186                                                            'vIMS': {'duration': CW_DEPLOYMENT_DURATION,
187                                                                     'result': ""},
188                                                            'sig_test': {'duration': duration,
189                                                                         'result': vims_test_result}})
190         try:
191             os.remove(VIMS_TEST_DIR + "temp.json")
192         except:
193             logger.error("Deleting file failed")
194
195
196 def main():
197
198     ################ GENERAL INITIALISATION ################
199
200     if not os.path.exists(VIMS_DATA_DIR):
201         os.makedirs(VIMS_DATA_DIR)
202
203     ks_creds = functest_utils.get_credentials("keystone")
204     nv_creds = functest_utils.get_credentials("nova")
205     nt_creds = functest_utils.get_credentials("neutron")
206
207     logger.info("Prepare OpenStack plateform (create tenant and user)")
208     keystone = ksclient.Client(**ks_creds)
209
210     user_id = functest_utils.get_user_id(keystone, ks_creds['username'])
211     if user_id == '':
212         logger.error("Error : Failed to get id of %s user" %
213                      ks_creds['username'])
214         exit(-1)
215
216     tenant_id = functest_utils.create_tenant(
217         keystone, TENANT_NAME, TENANT_DESCRIPTION)
218     if tenant_id == '':
219         logger.error("Error : Failed to create %s tenant" % TENANT_NAME)
220         exit(-1)
221
222     roles_name = ["admin", "Admin"]
223     role_id = ''
224     for role_name in roles_name:
225         if role_id == '':
226             role_id = functest_utils.get_role_id(keystone, role_name)
227
228     if role_id == '':
229         logger.error("Error : Failed to get id for %s role" % role_name)
230
231     if not functest_utils.add_role_user(keystone, user_id, role_id, tenant_id):
232         logger.error("Error : Failed to add %s on tenant" %
233                      ks_creds['username'])
234
235     user_id = functest_utils.create_user(
236         keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
237     if user_id == '':
238         logger.error("Error : Failed to create %s user" % TENANT_NAME)
239
240     logger.info("Update OpenStack creds informations")
241     ks_creds.update({
242         "username": TENANT_NAME,
243         "password": TENANT_NAME,
244         "tenant_name": TENANT_NAME,
245     })
246
247     nt_creds.update({
248         "tenant_name": TENANT_NAME,
249     })
250
251     nv_creds.update({
252         "project_id": TENANT_NAME,
253     })
254
255     logger.info("Upload some OS images if it doesn't exist")
256     glance_endpoint = keystone.service_catalog.url_for(service_type='image',
257                                                        endpoint_type='publicURL')
258     glance = glclient.Client(1, glance_endpoint, token=keystone.auth_token)
259
260     for img in IMAGES.keys():
261         image_name = IMAGES[img]['image_name']
262         image_url = IMAGES[img]['image_url']
263
264         image_id = functest_utils.get_image_id(glance, image_name)
265
266         if image_id == '':
267             logger.info("""%s image doesn't exist on glance repository.
268                             Try downloading this image and upload on glance !""" % image_name)
269             image_id = download_and_add_image_on_glance(
270                 glance, image_name, image_url)
271
272         if image_id == '':
273             logger.error(
274                 "Error : Failed to find or upload required OS image for this deployment")
275             exit(-1)
276
277     nova = nvclient.Client("2", **nv_creds)
278
279     logger.info("Update security group quota for this tenant")
280     neutron = ntclient.Client(**nt_creds)
281     if not functest_utils.update_sg_quota(neutron, tenant_id, 50, 100):
282         logger.error(
283             "Failed to update security group quota for tenant %s" % TENANT_NAME)
284         exit(-1)
285
286     logger.info("Update cinder quota for this tenant")
287     from cinderclient import client as cinderclient
288
289     creds_cinder = functest_utils.get_credentials("cinder")
290     cinder_client = cinderclient.Client('1', creds_cinder['username'],
291                                         creds_cinder['api_key'],
292                                         creds_cinder['project_id'],
293                                         creds_cinder['auth_url'],
294                                         service_type="volume")
295     if not functest_utils.update_cinder_quota(cinder_client, tenant_id, 20, 10, 150):
296         logger.error("Failed to update cinder quota for tenant %s" %
297                      TENANT_NAME)
298         exit(-1)
299
300     ################ CLOUDIFY INITIALISATION ################
301
302     cfy = orchestrator(VIMS_DATA_DIR, CFY_INPUTS, logger)
303
304     cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
305                         'password'], tenant_name=ks_creds['tenant_name'], auth_url=ks_creds['auth_url'])
306
307     logger.info("Collect flavor id for cloudify manager server")
308     nova = nvclient.Client("2", **nv_creds)
309
310     flavor_name = "m1.medium"
311     flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
312     for requirement in CFY_MANAGER_REQUIERMENTS:
313         if requirement == 'ram_min':
314             flavor_id = functest_utils.get_flavor_id_by_ram_range(
315                 nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 8196)
316
317     if flavor_id == '':
318         logger.error(
319             "Failed to find %s flavor. Try with ram range default requirement !" % flavor_name)
320         flavor_id = functest_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
321
322     if flavor_id == '':
323         logger.error(
324             "Failed to find required flavor for this deployment" % flavor_name)
325         exit(-1)
326
327     cfy.set_flavor_id(flavor_id)
328
329     image_name = "centos_7"
330     image_id = functest_utils.get_image_id(glance, image_name)
331     for requirement in CFY_MANAGER_REQUIERMENTS:
332         if requirement == 'os_image':
333             image_id = functest_utils.get_image_id(
334                 glance, CFY_MANAGER_REQUIERMENTS['os_image'])
335
336     if image_id == '':
337         logger.error(
338             "Error : Failed to find required OS image for cloudify manager")
339         exit(-1)
340
341     cfy.set_image_id(image_id)
342
343     ext_net = functest_utils.get_external_net(neutron)
344     if not ext_net:
345         logger.error("Failed to get external network")
346         exit(-1)
347
348     cfy.set_external_network_name(ext_net)
349
350     ns = functest_utils.get_resolvconf_ns()
351     if ns:
352         cfy.set_nameservers(ns)
353
354     logger.info("Prepare virtualenv for cloudify-cli")
355     cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
356     functest_utils.execute_command(cmd, logger)
357     cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
358     functest_utils.execute_command(cmd, logger)
359
360     cfy.download_manager_blueprint(
361         CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
362
363     ################ CLOUDIFY DEPLOYMENT ################
364     start_time_ts = time.time()
365     end_time_ts = start_time_ts
366     logger.info("Cloudify deployment Start Time:'%s'" % (
367         datetime.datetime.fromtimestamp(start_time_ts).strftime(
368             '%Y-%m-%d %H:%M:%S')))
369
370     cfy.deploy_manager()
371
372     global CFY_DEPLOYMENT_DURATION
373     end_time_ts = time.time()
374     CFY_DEPLOYMENT_DURATION = round(end_time_ts - start_time_ts, 1)
375     logger.info("Cloudify deployment duration:'%s'" % CFY_DEPLOYMENT_DURATION)
376
377     ################ CLEARWATER INITIALISATION ################
378
379     cw = clearwater(CW_INPUTS, cfy, logger)
380
381     logger.info("Collect flavor id for all clearwater vm")
382     nova = nvclient.Client("2", **nv_creds)
383
384     flavor_name = "m1.small"
385     flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
386     for requirement in CW_REQUIERMENTS:
387         if requirement == 'ram_min':
388             flavor_id = functest_utils.get_flavor_id_by_ram_range(
389                 nova, CW_REQUIERMENTS['ram_min'], 8196)
390
391     if flavor_id == '':
392         logger.error(
393             "Failed to find %s flavor. Try with ram range default requirement !" % flavor_name)
394         flavor_id = functest_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
395
396     if flavor_id == '':
397         logger.error(
398             "Failed to find required flavor for this deployment" % flavor_name)
399         exit(-1)
400
401     cw.set_flavor_id(flavor_id)
402
403     image_name = "ubuntu_14.04"
404     image_id = functest_utils.get_image_id(glance, image_name)
405     for requirement in CW_REQUIERMENTS:
406         if requirement == 'os_image':
407             image_id = functest_utils.get_image_id(
408                 glance, CW_REQUIERMENTS['os_image'])
409
410     if image_id == '':
411         logger.error(
412             "Error : Failed to find required OS image for cloudify manager")
413         exit(-1)
414
415     cw.set_image_id(image_id)
416
417     ext_net = functest_utils.get_external_net(neutron)
418     if not ext_net:
419         logger.error("Failed to get external network")
420         exit(-1)
421
422     cw.set_external_network_name(ext_net)
423
424     ################ CLEARWATER DEPLOYMENT ################
425
426     start_time_ts = time.time()
427     end_time_ts = start_time_ts
428     logger.info("vIMS VNF deployment Start Time:'%s'" % (
429         datetime.datetime.fromtimestamp(start_time_ts).strftime(
430             '%Y-%m-%d %H:%M:%S')))
431
432     cw.deploy_vnf(CW_BLUEPRINT)
433
434     global CW_DEPLOYMENT_DURATION
435     end_time_ts = time.time()
436     CW_DEPLOYMENT_DURATION = round(end_time_ts - start_time_ts, 1)
437     logger.info("vIMS VNF deployment duration:'%s'" % CW_DEPLOYMENT_DURATION)
438
439     ################ CLEARWATER TEST ################
440
441     test_clearwater()
442
443     ########### CLEARWATER UNDEPLOYMENT ############
444
445     cw.undeploy_vnf()
446
447     ############ CLOUDIFY UNDEPLOYMENT #############
448
449     cfy.undeploy_manager()
450
451     ############### GENERAL CLEANUP ################
452
453     ks_creds = functest_utils.get_credentials("keystone")
454
455     keystone = ksclient.Client(**ks_creds)
456
457     logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
458     tenant_id = functest_utils.get_tenant_id(
459         keystone, CFY_INPUTS['keystone_tenant_name'])
460     if tenant_id == '':
461         logger.error("Error : Failed to get id of %s tenant" %
462                      CFY_INPUTS['keystone_tenant_name'])
463     else:
464         if not functest_utils.delete_tenant(keystone, tenant_id):
465             logger.error("Error : Failed to remove %s tenant" %
466                          CFY_INPUTS['keystone_tenant_name'])
467
468     logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
469     user_id = functest_utils.get_user_id(
470         keystone, CFY_INPUTS['keystone_username'])
471     if user_id == '':
472         logger.error("Error : Failed to get id of %s user" %
473                      CFY_INPUTS['keystone_username'])
474     else:
475         if not functest_utils.delete_user(keystone, user_id):
476             logger.error("Error : Failed to remove %s user" %
477                          CFY_INPUTS['keystone_username'])
478
479
480 if __name__ == '__main__':
481     main()