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