Merge "Add compass onos and odl_l2 scenario"
[functest.git] / testcases / functest_utils.py
1 #!/usr/bin/env python
2 #
3 # jose.lausuch@ericsson.com
4 # valentin.boucher@orange.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 json
12 import os
13 import os.path
14 import re
15 import requests
16 import shutil
17 import socket
18 import subprocess
19 import sys
20 import urllib2
21 from git import Repo
22
23
24 # ----------------------------------------------------------
25 #
26 #               OPENSTACK UTILS
27 #
28 # -----------------------------------------------------------
29
30
31 #*********************************************
32 #   CREDENTIALS
33 #*********************************************
34 def check_credentials():
35     """
36     Check if the OpenStack credentials (openrc) are sourced
37     """
38     env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME']
39     return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
40
41
42 def get_credentials(service):
43     """Returns a creds dictionary filled with the following keys:
44     * username
45     * password/api_key (depending on the service)
46     * tenant_name/project_id (depending on the service)
47     * auth_url
48     :param service: a string indicating the name of the service
49                     requesting the credentials.
50     """
51     creds = {}
52     # Unfortunately, each of the OpenStack client will request slightly
53     # different entries in their credentials dict.
54     if service.lower() in ("nova", "cinder"):
55         password = "api_key"
56         tenant = "project_id"
57     else:
58         password = "password"
59         tenant = "tenant_name"
60
61     # The most common way to pass these info to the script is to do it through
62     # environment variables.
63     creds.update({
64         "username": os.environ.get('OS_USERNAME', "admin"),
65         password: os.environ.get("OS_PASSWORD", 'admin'),
66         "auth_url": os.environ.get("OS_AUTH_URL",
67                                    "http://192.168.20.71:5000/v2.0"),
68         tenant: os.environ.get("OS_TENANT_NAME", "admin"),
69     })
70     return creds
71
72
73 #*********************************************
74 #   NOVA
75 #*********************************************
76 def get_instances(nova_client):
77     try:
78         instances = nova_client.servers.list(search_opts={'all_tenants': 1})
79         return instances
80     except Exception, e:
81         print "Error [get_instances(nova_client)]:", e
82         return None
83
84
85 def get_instance_status(nova_client, instance):
86     try:
87         instance = nova_client.servers.get(instance.id)
88         return instance.status
89     except Exception, e:
90         #print "Error [get_instance_status(nova_client, '%s')]:" % \
91         #    str(instance), e
92         return None
93
94
95 def get_instance_by_name(nova_client, instance_name):
96     try:
97         instance = nova_client.servers.find(name=instance_name)
98         return instance
99     except Exception, e:
100         print "Error [get_instance_by_name(nova_client, '%s')]:" % \
101             instance_name, e
102         return None
103
104
105 def get_flavor_id(nova_client, flavor_name):
106     flavors = nova_client.flavors.list(detailed=True)
107     id = ''
108     for f in flavors:
109         if f.name == flavor_name:
110             id = f.id
111             break
112     return id
113
114
115 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
116     flavors = nova_client.flavors.list(detailed=True)
117     id = ''
118     for f in flavors:
119         if min_ram <= f.ram and f.ram <= max_ram:
120             id = f.id
121             break
122     return id
123
124
125 def get_floating_ips(nova_client):
126     try:
127         floating_ips = nova_client.floating_ips.list()
128         return floating_ips
129     except Exception, e:
130         print "Error [get_floating_ips(nova_client)]:", e
131         return None
132
133
134 def create_flavor(nova_client, flavor_name, ram, disk, vcpus):
135     try:
136         flavor = nova_client.flavors.create(flavor_name, ram, vcpus, disk)
137     except Exception, e:
138         print "Error [create_flavor(nova_client, '%s', '%s', '%s', "\
139             "'%s')]:" % (flavor_name, ram, disk, vcpus), e
140         return None
141     return flavor.id
142
143
144 def create_floating_ip(neutron_client):
145     extnet_id = get_external_net_id(neutron_client)
146     props = {'floating_network_id': extnet_id}
147     try:
148         ip_json = neutron_client.create_floatingip({'floatingip': props})
149         floating_ip = ip_json['floatingip']['floating_ip_address']
150     except Exception, e:
151         print "Error [create_floating_ip(neutron_client)]:", e
152         return None
153     return floating_ip
154
155
156 def add_floating_ip(nova_client, server_id, floatingip_id):
157     try:
158         nova_client.servers.add_floating_ip(server_id, floatingip_id)
159         return True
160     except Exception, e:
161         print "Error [add_floating_ip(nova_client, '%s', '%s')]:" % \
162             (server_id, floatingip_id), e
163         return False
164
165
166 def delete_instance(nova_client, instance_id):
167     try:
168         nova_client.servers.force_delete(instance_id)
169         return True
170     except Exception, e:
171         print "Error [delete_instance(nova_client, '%s')]:" % instance_id, e
172         return False
173
174
175 def delete_floating_ip(nova_client, floatingip_id):
176     try:
177         nova_client.floating_ips.delete(floatingip_id)
178         return True
179     except Exception, e:
180         print "Error [delete_floating_ip(nova_client, '%s')]:" % floatingip_id, e
181         return False
182
183
184 #*********************************************
185 #   NEUTRON
186 #*********************************************
187 def get_network_list(neutron_client):
188     network_list = neutron_client.list_networks()['networks']
189     if len(network_list) == 0:
190         return None
191     else:
192         return network_list
193
194
195 def get_router_list(neutron_client):
196     router_list = neutron_client.list_routers()['routers']
197     if len(router_list) == 0:
198         return None
199     else:
200         return router_list
201
202
203 def get_port_list(neutron_client):
204     port_list = neutron_client.list_ports()['ports']
205     if len(port_list) == 0:
206         return None
207     else:
208         return port_list
209
210
211 def get_network_id(neutron_client, network_name):
212     networks = neutron_client.list_networks()['networks']
213     id = ''
214     for n in networks:
215         if n['name'] == network_name:
216             id = n['id']
217             break
218     return id
219
220
221 def get_private_net(neutron_client):
222     # Checks if there is an existing shared private network
223     networks = neutron_client.list_networks()['networks']
224     if len(networks) == 0:
225         return None
226     for net in networks:
227         if (net['router:external'] is False) and (net['shared'] is True):
228             return net
229     return None
230
231
232 def get_external_net(neutron_client):
233     for network in neutron_client.list_networks()['networks']:
234         if network['router:external']:
235             return network['name']
236     return False
237
238
239 def get_external_net_id(neutron_client):
240     for network in neutron_client.list_networks()['networks']:
241         if network['router:external']:
242             return network['id']
243     return False
244
245
246 def check_neutron_net(neutron_client, net_name):
247     for network in neutron_client.list_networks()['networks']:
248         if network['name'] == net_name:
249             for subnet in network['subnets']:
250                 return True
251     return False
252
253
254 def create_neutron_net(neutron_client, name):
255     json_body = {'network': {'name': name,
256                              'admin_state_up': True}}
257     try:
258         network = neutron_client.create_network(body=json_body)
259         network_dict = network['network']
260         return network_dict['id']
261     except Exception, e:
262         print "Error [create_neutron_net(neutron_client, '%s')]:" % name, e
263         return False
264
265
266 def create_neutron_subnet(neutron_client, name, cidr, net_id):
267     json_body = {'subnets': [{'name': name, 'cidr': cidr,
268                               'ip_version': 4, 'network_id': net_id}]}
269     try:
270         subnet = neutron_client.create_subnet(body=json_body)
271         return subnet['subnets'][0]['id']
272     except Exception, e:
273         print "Error [create_neutron_subnet(neutron_client, '%s', '%s', "\
274             "'%s')]:" % (name, cidr, net_id), e
275         return False
276
277
278 def create_neutron_router(neutron_client, name):
279     json_body = {'router': {'name': name, 'admin_state_up': True}}
280     try:
281         router = neutron_client.create_router(json_body)
282         return router['router']['id']
283     except Exception, e:
284         print "Error [create_neutron_router(neutron_client, '%s')]:" % name, e
285         return False
286
287
288 def create_neutron_port(neutron_client, name, network_id, ip):
289     json_body = {'port': {
290                  'admin_state_up': True,
291                  'name': name,
292                  'network_id': network_id,
293                  'fixed_ips': [{"ip_address": ip}]
294                  }}
295     try:
296         port = neutron_client.create_port(body=json_body)
297         return port['port']['id']
298     except Exception, e:
299         print "Error [create_neutron_port(neutron_client, '%s', '%s', "\
300             "'%s')]:" % (name, network_id, ip), e
301         return False
302
303
304 def update_neutron_net(neutron_client, network_id, shared=False):
305     json_body = {'network': {'shared': shared}}
306     try:
307         neutron_client.update_network(network_id, body=json_body)
308         return True
309     except Exception, e:
310         print "Error [update_neutron_net(neutron_client, '%s', '%s')]:" % \
311             (network_id, str(shared)), e
312         return False
313
314
315 def update_neutron_port(neutron_client, port_id, device_owner):
316     json_body = {'port': {
317                  'device_owner': device_owner,
318                  }}
319     try:
320         port = neutron_client.update_port(port=port_id,
321                                           body=json_body)
322         return port['port']['id']
323     except Exception, e:
324         print "Error [update_neutron_port(neutron_client, '%s', '%s')]:" % \
325             (port_id, device_owner), e
326         return False
327
328
329 def add_interface_router(neutron_client, router_id, subnet_id):
330     json_body = {"subnet_id": subnet_id}
331     try:
332         neutron_client.add_interface_router(router=router_id, body=json_body)
333         return True
334     except Exception, e:
335         print "Error [add_interface_router(neutron_client, '%s', '%s')]:" % \
336             (router_id, subnet_id), e
337         return False
338
339
340 def add_gateway_router(neutron_client, router_id):
341     ext_net_id = get_external_net_id(neutron_client)
342     router_dict = {'network_id': ext_net_id}
343     try:
344         neutron_client.add_gateway_router(router_id, router_dict)
345         return True
346     except Exception, e:
347         print "Error [add_gateway_router(neutron_client, '%s')]:" % router_id, e
348         return False
349
350
351 def delete_neutron_net(neutron_client, network_id):
352     try:
353         neutron_client.delete_network(network_id)
354         return True
355     except Exception, e:
356         print "Error [delete_neutron_net(neutron_client, '%s')]:" % network_id, e
357         return False
358
359
360 def delete_neutron_subnet(neutron_client, subnet_id):
361     try:
362         neutron_client.delete_subnet(subnet_id)
363         return True
364     except Exception, e:
365         print "Error [delete_neutron_subnet(neutron_client, '%s')]:" % subnet_id, e
366         return False
367
368
369 def delete_neutron_router(neutron_client, router_id):
370     json_body = {'router': {'id': router_id}}
371     try:
372         neutron_client.delete_router(router=router_id)
373         return True
374     except Exception, e:
375         print "Error [delete_neutron_router(neutron_client, '%s')]:" % \
376             router_id, e
377         return False
378
379
380 def delete_neutron_port(neutron_client, port_id):
381     try:
382         neutron_client.delete_port(port_id)
383         return True
384     except Exception, e:
385         print "Error [delete_neutron_port(neutron_client, '%s')]:" % port_id, e
386         return False
387
388
389 def remove_interface_router(neutron_client, router_id, subnet_id):
390     json_body = {"subnet_id": subnet_id}
391     try:
392         neutron_client.remove_interface_router(router=router_id,
393                                                body=json_body)
394         return True
395     except Exception, e:
396         print "Error [remove_interface_router(neutron_client, '%s', '%s')]:" % \
397             (router_id, subnet_id), e
398         return False
399
400
401 def remove_gateway_router(neutron_client, router_id):
402     try:
403         neutron_client.remove_gateway_router(router_id)
404         return True
405     except Exception, e:
406         print "Error [remove_gateway_router(neutron_client, '%s')]:" % router_id, e
407         return False
408
409
410 #*********************************************
411 #   SEC GROUPS
412 #*********************************************
413 def get_security_groups(neutron_client):
414     try:
415         security_groups = neutron_client.list_security_groups()[
416             'security_groups']
417         return security_groups
418     except Exception, e:
419         print "Error [get_security_groups(neutron_client)]:", e
420         return None
421
422
423 def create_security_group(neutron_client, sg_name, sg_description):
424     json_body = {'security_group': {'name': sg_name,
425                                     'description': sg_description}}
426     try:
427         secgroup = neutron_client.create_security_group(json_body)
428         return secgroup['security_group']
429     except Exception, e:
430         print "Error [create_security_group(neutron_client, '%s', '%s')]:" % \
431             (sg_name, sg_description), e
432         return False
433
434
435 def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
436                          port_range_min=None, port_range_max=None):
437     if port_range_min is None and port_range_max is None:
438         json_body = {'security_group_rule': {'direction': direction,
439                                              'security_group_id': sg_id,
440                                              'protocol': protocol}}
441     elif port_range_min is not None and port_range_max is not None:
442         json_body = {'security_group_rule': {'direction': direction,
443                                              'security_group_id': sg_id,
444                                              'port_range_min': port_range_min,
445                                              'port_range_max': port_range_max,
446                                              'protocol': protocol}}
447     else:
448         print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\
449               "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction, \
450                                              port_range_min, port_range_max, protocol),\
451               " Invalid values for port_range_min, port_range_max"
452         return False
453     try:
454         neutron_client.create_security_group_rule(json_body)
455         return True
456     except Exception, e:
457         print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\
458             "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction,
459                                            port_range_min, port_range_max,
460                                            protocol), e
461         return False
462
463
464 def add_secgroup_to_instance(nova_client, instance_id, secgroup_id):
465     try:
466         nova_client.servers.add_security_group(instance_id, secgroup_id)
467         return True
468     except Exception, e:
469         print "Error [add_secgroup_to_instance(nova_client, '%s', '%s')]: " % \
470             (instance_id, secgroup_id), e
471         return False
472
473
474 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
475     json_body = {"quota": {
476         "security_group": sg_quota,
477         "security_group_rule": sg_rule_quota
478     }}
479
480     try:
481         quota = neutron_client.update_quota(tenant_id=tenant_id,
482                                             body=json_body)
483         return True
484     except Exception, e:
485         print "Error [update_sg_quota(neutron_client, '%s', '%s', "\
486             "'%s')]:" % (tenant_id, sg_quota, sg_rule_quota), e
487         return False
488
489
490 def delete_security_group(neutron_client, secgroup_id):
491     try:
492         neutron_client.delete_security_group(secgroup_id)
493         return True
494     except Exception, e:
495         print "Error [delete_security_group(neutron_client, '%s')]:" % secgroup_id, e
496         return False
497
498
499 #*********************************************
500 #   GLANCE
501 #*********************************************
502 def get_images(nova_client):
503     try:
504         images = nova_client.images.list()
505         return images
506     except Exception, e:
507         print "Error [get_images]:", e
508         return None
509
510
511 def get_image_id(glance_client, image_name):
512     images = glance_client.images.list()
513     id = ''
514     for i in images:
515         if i.name == image_name:
516             id = i.id
517             break
518     return id
519
520
521 def create_glance_image(glance_client, image_name, file_path, public=True):
522     if not os.path.isfile(file_path):
523         print "Error: file " + file_path + " does not exist."
524         return False
525     try:
526         with open(file_path) as fimage:
527             image = glance_client.images.create(name=image_name,
528                                                 is_public=public,
529                                                 disk_format="qcow2",
530                                                 container_format="bare",
531                                                 data=fimage)
532         return image.id
533     except Exception, e:
534         print "Error [create_glance_image(glance_client, '%s', '%s', "\
535             "'%s')]:" % (image_name, file_path, str(public)), e
536         return False
537
538
539 def delete_glance_image(nova_client, image_id):
540     try:
541         nova_client.images.delete(image_id)
542         return True
543     except Exception, e:
544         print "Error [delete_glance_image(nova_client, '%s')]:" % image_id, e
545         return False
546
547
548 #*********************************************
549 #   CINDER
550 #*********************************************
551 def get_volumes(cinder_client):
552     try:
553         volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
554         return volumes
555     except Exception, e:
556         print "Error [get_volumes(cinder_client)]:", e
557         return None
558
559
560 def list_volume_types(cinder_client, public=True, private=True):
561     try:
562         volume_types = cinder_client.volume_types.list()
563         if not public:
564             volume_types = [vt for vt in volume_types if not vt.is_public]
565         if not private:
566             volume_types = [vt for vt in volume_types if vt.is_public]
567         return volume_types
568     except Exception, e:
569         print "Error [list_volume_types(cinder_client)]:", e
570         return None
571
572
573 def create_volume_type(cinder_client, name):
574     try:
575         volume_type = cinder_client.volume_types.create(name)
576         return volume_type
577     except Exception, e:
578         print "Error [create_volume_type(cinder_client, '%s')]:" % name, e
579         return None
580
581
582 def update_cinder_quota(cinder_client, tenant_id, vols_quota,
583                         snapshots_quota, gigabytes_quota):
584     quotas_values = {"volumes": vols_quota,
585                      "snapshots": snapshots_quota,
586                      "gigabytes": gigabytes_quota}
587
588     try:
589         quotas_default = cinder_client.quotas.update(tenant_id,
590                                                      **quotas_values)
591         return True
592     except Exception, e:
593         print "Error [update_cinder_quota(cinder_client, '%s', '%s', '%s'" \
594             "'%s')]:" % (tenant_id, vols_quota, snapshots_quota, gigabytes_quota), e
595         return False
596
597
598 def delete_volume(cinder_client, volume_id, forced=False):
599     try:
600         if forced:
601             try:
602                 cinder_client.volumes.detach(volume_id)
603             except:
604                 print "Error:", sys.exc_info()[0]
605             cinder_client.volumes.force_delete(volume_id)
606         else:
607             cinder_client.volumes.delete(volume_id)
608         return True
609     except Exception, e:
610         print "Error [delete_volume(cinder_client, '%s', '%s')]:" % \
611             (volume_id, str(forced)), e
612         return False
613
614
615 def delete_volume_type(cinder_client, volume_type):
616     try:
617         cinder_client.volume_types.delete(volume_type)
618         return True
619     except Exception, e:
620         print "Error [delete_volume_type(cinder_client, '%s')]:" % volume_type, e
621         return False
622
623
624 #*********************************************
625 #   KEYSTONE
626 #*********************************************
627 def get_tenants(keystone_client):
628     try:
629         tenants = keystone_client.tenants.list()
630         return tenants
631     except Exception, e:
632         print "Error [get_tenants(keystone_client)]:", e
633         return None
634
635
636 def get_users(keystone_client):
637     try:
638         users = keystone_client.users.list()
639         return users
640     except Exception, e:
641         print "Error [get_users(keystone_client)]:", e
642         return None
643
644
645 def get_tenant_id(keystone_client, tenant_name):
646     tenants = keystone_client.tenants.list()
647     id = ''
648     for t in tenants:
649         if t.name == tenant_name:
650             id = t.id
651             break
652     return id
653
654
655 def get_user_id(keystone_client, user_name):
656     users = keystone_client.users.list()
657     id = ''
658     for u in users:
659         if u.name == user_name:
660             id = u.id
661             break
662     return id
663
664
665 def get_role_id(keystone_client, role_name):
666     roles = keystone_client.roles.list()
667     id = ''
668     for r in roles:
669         if r.name == role_name:
670             id = r.id
671             break
672     return id
673
674
675 def create_tenant(keystone_client, tenant_name, tenant_description):
676     try:
677         tenant = keystone_client.tenants.create(tenant_name,
678                                                 tenant_description,
679                                                 enabled=True)
680         return tenant.id
681     except Exception, e:
682         print "Error [create_tenant(cinder_client, '%s', '%s')]:" % \
683             (tenant_name, tenant_description), e
684         return False
685
686
687 def create_user(keystone_client, user_name, user_password,
688                 user_email, tenant_id):
689     try:
690         user = keystone_client.users.create(user_name, user_password,
691                                             user_email, tenant_id,
692                                             enabled=True)
693         return user.id
694     except Exception, e:
695         print "Error [create_user(keystone_client, '%s', '%s', '%s'" \
696             "'%s')]:" % (user_name, user_password, user_email, tenant_id), e
697         return False
698
699
700 def add_role_user(keystone_client, user_id, role_id, tenant_id):
701     try:
702         keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
703         return True
704     except Exception, e:
705         print "Error [add_role_user(keystone_client, '%s', '%s'" \
706             "'%s')]:" % (user_id, role_id, tenant_id), e
707         return False
708
709
710 def delete_tenant(keystone_client, tenant_id):
711     try:
712         tenant = keystone_client.tenants.delete(tenant_id)
713         return True
714     except Exception, e:
715         print "Error [delete_tenant(keystone_client, '%s')]:" % tenant_id, e
716         return False
717
718
719 def delete_user(keystone_client, user_id):
720     try:
721         tenant = keystone_client.users.delete(user_id)
722         return True
723     except Exception, e:
724         print "Error [delete_user(keystone_client, '%s')]:" % user_id, e
725         return False
726
727
728
729
730
731
732
733 # ----------------------------------------------------------
734 #
735 #               INTERNET UTILS
736 #
737 # -----------------------------------------------------------
738 def check_internet_connectivity(url='http://www.opnfv.org/'):
739     """
740     Check if there is access to the internet
741     """
742     try:
743         urllib2.urlopen(url, timeout=5)
744         return True
745     except urllib2.URLError:
746         return False
747
748
749 def download_url(url, dest_path):
750     """
751     Download a file to a destination path given a URL
752     """
753     name = url.rsplit('/')[-1]
754     dest = dest_path + "/" + name
755     try:
756         response = urllib2.urlopen(url)
757     except (urllib2.HTTPError, urllib2.URLError):
758         return False
759
760     with open(dest, 'wb') as f:
761         shutil.copyfileobj(response, f)
762     return True
763
764
765
766
767 # ----------------------------------------------------------
768 #
769 #               CI UTILS
770 #
771 # -----------------------------------------------------------
772 def get_git_branch(repo_path):
773     """
774     Get git branch name
775     """
776     repo = Repo(repo_path)
777     branch = repo.active_branch
778     return branch.name
779
780
781 def get_installer_type(logger=None):
782     """
783     Get installer type (fuel, apex, joid, compass)
784     """
785     try:
786         installer = os.environ['INSTALLER_TYPE']
787     except KeyError:
788         if logger:
789             logger.error("Impossible to retrieve the installer type")
790         installer = "Unknown_installer"
791
792     return installer
793
794
795 def get_scenario(logger=None):
796     """
797     Get scenario
798     """
799     try:
800         scenario = os.environ['DEPLOY_SCENARIO']
801     except KeyError:
802         if logger:
803             logger.error("Impossible to retrieve the scenario")
804         scenario = "Unknown_scenario"
805
806     return scenario
807
808
809 def get_pod_name(logger=None):
810     """
811     Get PoD Name from env variable NODE_NAME
812     """
813     try:
814         return os.environ['NODE_NAME']
815     except KeyError:
816         if logger:
817             logger.error(
818                 "Unable to retrieve the POD name from environment.Using pod name 'unknown-pod'")
819         return "unknown-pod"
820
821
822 def push_results_to_db(db_url, project, case_name, logger, pod_name,
823                        version, payload):
824     """
825     POST results to the Result target DB
826     """
827     url = db_url + "/results"
828     installer = get_installer_type(logger)
829     params = {"project_name": project, "case_name": case_name,
830               "pod_name": pod_name, "installer": installer,
831               "version": version, "details": payload}
832
833     headers = {'Content-Type': 'application/json'}
834     try:
835         r = requests.post(url, data=json.dumps(params), headers=headers)
836         if logger:
837             logger.debug(r)
838         return True
839     except Exception, e:
840         print "Error [push_results_to_db('%s', '%s', '%s', '%s', '%s', '%s')]:" \
841             % (db_url, project, case_name, pod_name, version, payload), e
842         return False
843
844
845 def get_resolvconf_ns():
846     """
847     Get nameservers from current resolv.conf
848     """
849     nameservers = []
850     rconf = open("/etc/resolv.conf", "r")
851     line = rconf.readline()
852     while line:
853         ip = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b", line)
854         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
855         if ip:
856             result = sock.connect_ex((ip.group(), 53))
857             if result == 0:
858                 nameservers.append(ip.group())
859         line = rconf.readline()
860     return nameservers
861
862
863 def getTestEnv(test, functest_yaml):
864     """
865     Get the config of the testcase based on functest_config.yaml
866       2 options
867         - test = test project e.g; ovno
868         - test = testcase e.g. functest/odl
869        look for the / to see if it is a test project or a testcase
870     """
871     try:
872         TEST_ENV = functest_yaml.get("test-dependencies")
873
874         if test.find("/") < 0:
875             config_test = TEST_ENV[test]
876         else:
877             test_split = test.split("/")
878             testproject = test_split[0]
879             testcase = test_split[1]
880             config_test = TEST_ENV[testproject][testcase]
881     except KeyError:
882         # if not defined in dependencies => no dependencies
883         config_test = ""
884     except Exception, e:
885         print "Error [getTestEnv]:", e
886
887     return config_test
888
889
890 def get_ci_envvars():
891     """
892     Get the CI env variables
893     """
894     ci_env_var = {
895         "installer": os.environ.get('INSTALLER_TYPE'),
896         "scenario": os.environ.get('DEPLOY_SCENARIO')}
897     return ci_env_var
898
899
900 def isTestRunnable(test, functest_yaml):
901     """
902     Return True if the test is runnable in the current scenario
903     """
904     # By default we assume that all the tests are always runnable...
905     is_runnable = True
906     # Retrieve CI environment
907     ci_env = get_ci_envvars()
908     # Retrieve test environement from config file
909     test_env = getTestEnv(test, functest_yaml)
910
911     # if test_env not empty => dependencies to be checked
912     if test_env is not None and len(test_env) > 0:
913         # possible criteria = ["installer", "scenario"]
914         # consider test criteria from config file
915         # compare towards CI env through CI en variable
916         for criteria in test_env:
917             if re.search(test_env[criteria], ci_env[criteria]) is None:
918                 # print "Test "+ test + " cannot be run on the environment"
919                 is_runnable = False
920     return is_runnable
921
922
923 def generateTestcaseList(functest_yaml):
924     """
925     Generate a test file with the runnable test according to
926     the current scenario
927     """
928     test_list = ""
929     # get testcases
930     testcase_list = functest_yaml.get("test-dependencies")
931     projects = testcase_list.keys()
932
933     for project in projects:
934         testcases = testcase_list[project]
935         # 1 or 2 levels for testcases project[/case]l
936         # if only project name without controller or scenario
937         # => shall be runnable on any controller/scenario
938         if testcases is None:
939             test_list += project + " "
940         else:
941             for testcase in testcases:
942                 if testcase == "installer" or testcase == "scenario":
943                     # project (1 level)
944                     if isTestRunnable(project, functest_yaml):
945                         test_list += project + " "
946                 else:
947                     # project/testcase (2 levels)
948                     thetest = project + "/" + testcase
949                     if isTestRunnable(thetest, functest_yaml):
950                         test_list += testcase + " "
951
952     # sort the list to execute the test in the right order
953     test_order_list = functest_yaml.get("test_exec_priority")
954     test_sorted_list = ""
955     for test in test_order_list:
956         if test_order_list[test] in test_list:
957             test_sorted_list += test_order_list[test] + " "
958
959     # create a file that could be consumed by run-test.sh
960     # this method is used only for CI
961     # so it can be run only in container
962     # reuse default conf directory to store the list of runnable tests
963     file = open("/home/opnfv/functest/conf/testcase-list.txt", 'w')
964     file.write(test_sorted_list)
965     file.close()
966
967     return test_sorted_list
968
969
970 def execute_command(cmd, logger=None, exit_on_error=True):
971     """
972     Execute Linux command
973         prints stdout to a file and depending on if there
974         is a logger defined, it will print it or not.
975     """
976     if logger:
977         logger.debug('Executing command : {}'.format(cmd))
978     output_file = "output.txt"
979     f = open(output_file, 'w+')
980     p = subprocess.call(cmd, shell=True, stdout=f, stderr=subprocess.STDOUT)
981     f.close()
982     f = open(output_file, 'r')
983     result = f.read()
984     if result != "" and logger:
985         logger.debug(result)
986     if p == 0:
987         return True
988     else:
989         if logger:
990             logger.error("Error when executing command %s" % cmd)
991         if exit_on_error:
992             exit(-1)
993         return False