Added first draft config_functest.py.
[functest.git] / testcases / config_functest.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2015 Ericsson
4 # jose.lausuch@ericsson.com
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10
11 import re, json, os, urllib2, argparse, logging, shutil
12
13 actions = ['start', 'check', 'clean']
14
15 """ global variables """
16 functest_dir = os.environ['HOME'] + '/.functest/'
17 #image_url = 'http://mirror.us.leaseweb.net/ubuntu-releases/14.04.2/ubuntu-14.04.2-server-amd64.iso'
18 image_url = 'http://download.cirros-cloud.net/0.3.0/cirros-0.3.0-i386-disk.img'
19 image_disk_format = 'raw'
20 image_name = image_url.rsplit('/')[-1]
21 image_path = functest_dir + image_name
22
23 parser = argparse.ArgumentParser()
24 parser.add_argument("action", help="Possible actions are: '{d[0]}|{d[1]}|{d[2]}' ".format(d=actions))
25 parser.add_argument("-d", "--debug", help="Debug mode",  action="store_true")
26 args = parser.parse_args()
27
28
29 """ logging configuration """
30 logger = logging.getLogger('config_functest')
31 logger.setLevel(logging.DEBUG)
32
33 ch = logging.StreamHandler()
34 if args.debug:
35     ch.setLevel(logging.DEBUG)
36 else:
37     ch.setLevel(logging.INFO)
38
39 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
40 ch.setFormatter(formatter)
41 logger.addHandler(ch)
42
43
44
45 def config_functest_start():
46     """
47     Start the functest environment installation
48     """
49     if config_functest_check():
50         logger.info("Functest environment already installed in %s. Nothing to do." %functest_dir)
51         exit(0)
52     elif not check_internet_connectivity():
53         logger.error("There is no Internet connectivity. Please check the network configuration.")
54         exit(-1)
55     elif not check_credentials():
56         logger.error("Please source the openrc credentials and run the script again.")
57         #TODO: source the credentials in this script
58         exit(-1)
59     elif not check_rally():
60         logger.error("Rally is not installed. Please follow the instructions to prepare the Rally environment.")
61         exit(-1)
62     else:
63         logger.info("Starting installationg of functest environment in %s" %functest_dir)
64         os.makedirs(functest_dir)
65         if not os.path.exists(functest_dir):
66             logger.error("There has been a problem why creating the environment directory")
67             exit(-1)
68
69         logger.info("Donwloading test scripts and scenarios...")
70         download_tests()
71
72         logger.info("Donwloading image...")
73         download_url_with_progress(image_url, functest_dir)
74
75         logger.info("Creating Glance image: %s ..." %image_name)
76         create_glance_image(image_path,image_name,image_disk_format)
77         exit(0)
78
79
80
81 def config_functest_check():
82     """
83     Check if the functest environment is installed
84     """
85     logger.info("Checking current functest configuration...")
86     if not os.path.exists(functest_dir):
87         logger.info("Functest environment directory not found")
88         return False
89     else:
90         logger.info("Functest environment directory found in %s" %functest_dir)
91         #TODO: more verifications here
92         return True
93
94
95
96 def config_functest_clean():
97     """
98     Clean the existing functest environment
99     """
100     if not config_functest_check():
101         logger.info("There is no functest environment installed. Nothing to clean.")
102         return 0
103     else:
104         while True:
105             print("Are you sure? [y|n]")
106             answer = raw_input("")
107             if answer == "y":
108                 logger.info("Removing current functest environment...")
109                 shutil.rmtree(functest_dir,ignore_errors=True)
110                 exit(0)
111             elif answer == "n":
112                 exit(0)
113             else:
114                 print("Invalid option.")
115
116
117
118
119 def check_rally():
120     """
121     Check if Rally is installed and properly configured
122     """
123     if os.path.exists(os.environ['HOME']+"/.rally/"):
124         #TODO: do a more consistent check, for example running the comand rally deployment check
125         return True
126     else:
127         return False
128
129
130 def check_credentials():
131     """
132     Check if the OpenStack credentials (openrc) are sourced
133     """
134     #TODO: there must be a short way to do this, doing if os.environ["something"] == "" throws an error
135     try:
136        os.environ['OS_AUTH_URL']
137     except KeyError:
138         return False
139     try:
140        os.environ['OS_USERNAME']
141     except KeyError:
142         return False
143     try:
144        os.environ['OS_PASSWORD']
145     except KeyError:
146         return False
147     try:
148        os.environ['OS_TENANT_NAME']
149     except KeyError:
150         return False
151     try:
152        os.environ['OS_REGION_NAME']
153     except KeyError:
154         return False
155     return True
156
157
158 def download_tests():
159     vPing_dir = functest_dir + "vPing/"
160     odl_dir = functest_dir + "ODL/"
161     bench_tests_dir = functest_dir + "scenarios/"
162
163     os.makedirs(vPing_dir)
164     os.makedirs(odl_dir)
165     os.makedirs(bench_tests_dir)
166
167     logger.info("Downloading vPing test...")
168     vPing_url = 'https://git.opnfv.org/cgit/functest/plain/testcases/vPing/CI/libraries/vPing.py'
169     download_url(vPing_url,vPing_dir)
170
171     logger.info("Downloading Rally bench tests...")
172     rally_bench_base_url = 'https://git.opnfv.org/cgit/functest/plain/testcases/VIM/OpenStack/CI/suites/'
173     bench_tests = ['authenticate', 'cinder', 'glance', 'heat', 'keystone', 'neutron', 'nova', 'quotas', 'requests', 'tempest', 'vm']
174     for i in bench_tests:
175         rally_bench_url = rally_bench_base_url + "opnfv-" + i + ".json"
176         logger.debug("Downloading %s" %rally_bench_url)
177         download_url(rally_bench_url,bench_tests_dir)
178
179     logger.info("Downloading OLD tests...")
180     odl_base_url = 'https://git.opnfv.org/cgit/functest/plain/testcases/Controllers/ODL/CI/'
181     odl_tests = ['start_tests.sh', 'test_list.txt']
182     for i in odl_tests:
183         odl_url = odl_base_url + i
184         logger.debug("Downloading %s" %odl_url)
185         download_url(odl_url,odl_dir)
186     #TODO: complete
187
188
189
190 def create_glance_image(path,name,disk_format):
191     """
192     Create a glance image given the absolute path of the image, its name and the disk format
193     """
194     cmd = "glance image-create --name "+name+" --is-public true --disk-format "+disk_format+" --container-format bare --file "+path
195     execute_command(cmd)
196
197
198 def download_url(url, dest_path):
199     """
200     Download a file to a destination path given a URL
201     """
202     name = url.rsplit('/')[-1]
203     dest = dest_path + name
204     try:
205         response = urllib2.urlopen(url)
206     except (urllib2.HTTPError, urllib2.URLError):
207         logger.error("Error in fetching %s" %url)
208         return False
209
210     with open(dest, 'wb') as f:
211         f.write(response.read())
212     return True
213
214
215 def download_url_with_progress(url, dest_path):
216     """
217     Download a file to a destination path given a URL showing the progress
218     """
219     name = url.rsplit('/')[-1]
220     dest = dest_path + name
221     try:
222         response = urllib2.urlopen(url)
223     except (urllib2.HTTPError, urllib2.URLError):
224         logger.error("Error in fetching %s" %url)
225         return False
226
227     f = open(dest, 'wb')
228     meta = response.info()
229     file_size = int(meta.getheaders("Content-Length")[0])
230     logger.info("Downloading: %s Bytes: %s" %(dest, file_size))
231
232     file_size_dl = 0
233     block_sz = 8192
234     while True:
235         buffer = response.read(block_sz)
236         if not buffer:
237             break
238
239         file_size_dl += len(buffer)
240         f.write(buffer)
241         status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
242         status = status + chr(8)*(len(status)+1)
243         print status,
244
245     f.close()
246     print("\n")
247
248
249 def check_internet_connectivity(url='http://www.google.com/'):
250     """
251     Check if there is access to the internet
252     """
253     try:
254         urllib2.urlopen(url, timeout=5)
255         return True
256     except urllib.request.URLError:
257         return False
258
259 def execute_command(cmd):
260     """
261     Execute Linux command
262     """
263     logger.debug('Executing command : {}'.format(cmd))
264     p = os.popen(cmd,"r")
265     print (p.read())
266
267
268
269 def main():
270     if not (args.action in actions):
271         logger.error('argument not valid')
272         exit(-1)
273
274     if args.action == "start":
275         config_functest_start()
276
277     if args.action == "check":
278         config_functest_check()
279
280     if args.action == "clean":
281         config_functest_clean()
282
283 if __name__ == '__main__':
284     main()
285