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