Merge "Add reporting results for Danube 3.0"
[functest.git] / functest / opnfv_tests / openstack / vping / vping_base.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. and others.
2 #
3 # This program and the accompanying materials
4 # are made available under the terms of the Apache License, Version 2.0
5 # which accompanies this distribution, and is available at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8
9 from datetime import datetime
10 import logging
11 import os
12 import time
13 import uuid
14
15 from functest.core import testcase
16 from functest.utils import functest_utils
17 from functest.utils.constants import CONST
18
19 from snaps.openstack import create_flavor
20 from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor
21 from snaps.openstack.create_network import NetworkSettings, SubnetSettings
22 from snaps.openstack.tests import openstack_tests
23 from snaps.openstack.utils import deploy_utils
24
25
26 class VPingBase(testcase.TestCase):
27
28     """
29     Base class for vPing tests that check connectivity between two VMs shared
30     internal network.
31     This class is responsible for creating the image, internal network.
32     """
33
34     def __init__(self, **kwargs):
35         super(VPingBase, self).__init__(**kwargs)
36
37         # This line is here simply for pep8 as the 'os' package import appears
38         # to be required for mock and the unit tests will fail without it
39         os.environ
40
41         self.logger = logging.getLogger(__name__)
42
43         if 'os_creds' in kwargs:
44             self.os_creds = kwargs['os_creds']
45         else:
46             creds_override = None
47             if hasattr(CONST, 'snaps_os_creds_override'):
48                 creds_override = CONST.__getattribute__(
49                     'snaps_os_creds_override')
50
51             self.os_creds = openstack_tests.get_credentials(
52                 os_env_file=CONST.__getattribute__('openstack_creds'),
53                 overrides=creds_override)
54
55         self.creators = list()
56         self.image_creator = None
57         self.network_creator = None
58         self.vm1_creator = None
59         self.vm2_creator = None
60
61         # Shared metadata
62         self.guid = ''
63         if CONST.__getattribute__('vping_unique_names'):
64             self.guid = '-' + str(uuid.uuid4())
65
66         self.vm1_name = CONST.__getattribute__('vping_vm_name_1') + self.guid
67         self.vm2_name = CONST.__getattribute__('vping_vm_name_2') + self.guid
68
69         self.vm_boot_timeout = CONST.__getattribute__('vping_vm_boot_timeout')
70         self.vm_delete_timeout = CONST.__getattribute__(
71             'vping_vm_delete_timeout')
72         self.vm_ssh_connect_timeout = CONST.vping_vm_ssh_connect_timeout
73         self.ping_timeout = CONST.__getattribute__('vping_ping_timeout')
74         self.flavor_name = 'vping-flavor' + self.guid
75
76         # Move this configuration option up for all tests to leverage
77         if hasattr(CONST, 'snaps_images_cirros'):
78             self.cirros_image_config = CONST.__getattribute__(
79                 'snaps_images_cirros')
80         else:
81             self.cirros_image_config = None
82
83     def run(self):
84         """
85         Begins the test execution which should originate from the subclass
86         """
87         self.logger.info('Begin virtual environment setup')
88
89         self.start_time = time.time()
90         self.logger.info("vPing Start Time:'%s'" % (
91             datetime.fromtimestamp(self.start_time).strftime(
92                 '%Y-%m-%d %H:%M:%S')))
93
94         image_base_name = '{}-{}'.format(
95             CONST.__getattribute__('vping_image_name'),
96             str(self.guid))
97         os_image_settings = openstack_tests.cirros_image_settings(
98             image_base_name, image_metadata=self.cirros_image_config)
99         self.logger.info("Creating image with name: '%s'" % image_base_name)
100
101         self.image_creator = deploy_utils.create_image(
102             self.os_creds, os_image_settings)
103         self.creators.append(self.image_creator)
104
105         private_net_name = CONST.__getattribute__(
106             'vping_private_net_name') + self.guid
107         private_subnet_name = CONST.__getattribute__(
108             'vping_private_subnet_name') + self.guid
109         private_subnet_cidr = CONST.__getattribute__(
110             'vping_private_subnet_cidr')
111
112         vping_network_type = None
113         vping_physical_network = None
114         vping_segmentation_id = None
115
116         if (hasattr(CONST, 'network_type')):
117             vping_network_type = CONST.__getattribute__(
118                 'vping_network_type')
119         if (hasattr(CONST, 'physical_network')):
120             vping_physical_network = CONST.__getattribute__(
121                 'vping_physical_network')
122         if (hasattr(CONST, 'segmentation_id')):
123             vping_segmentation_id = CONST.__getattribute__(
124                 'vping_segmentation_id')
125
126         self.logger.info(
127             "Creating network with name: '%s'" % private_net_name)
128         self.network_creator = deploy_utils.create_network(
129             self.os_creds,
130             NetworkSettings(
131                 name=private_net_name,
132                 network_type=vping_network_type,
133                 physical_network=vping_physical_network,
134                 segmentation_id=vping_segmentation_id,
135                 subnet_settings=[SubnetSettings(
136                     name=private_subnet_name,
137                     cidr=private_subnet_cidr)]))
138         self.creators.append(self.network_creator)
139
140         self.logger.info(
141             "Creating flavor with name: '%s'" % self.flavor_name)
142         scenario = functest_utils.get_scenario()
143         flavor_metadata = None
144         if 'ovs' in scenario or 'fdio' in scenario:
145             flavor_metadata = create_flavor.MEM_PAGE_SIZE_LARGE
146         flavor_creator = OpenStackFlavor(
147             self.os_creds,
148             FlavorSettings(name=self.flavor_name, ram=512, disk=1, vcpus=1,
149                            metadata=flavor_metadata))
150         flavor_creator.create()
151         self.creators.append(flavor_creator)
152
153     def _execute(self):
154         """
155         Method called by subclasses after environment has been setup
156         :return: the exit code
157         """
158         self.logger.info('Begin test execution')
159
160         test_ip = self.vm1_creator.get_port_ip(
161             self.vm1_creator.instance_settings.port_settings[0].name)
162
163         if self.vm1_creator.vm_active(
164                 block=True) and self.vm2_creator.vm_active(block=True):
165             result = self._do_vping(self.vm2_creator, test_ip)
166         else:
167             raise Exception('VMs never became active')
168
169         if result == testcase.TestCase.EX_RUN_ERROR:
170             return testcase.TestCase.EX_RUN_ERROR
171
172         self.stop_time = time.time()
173         self.result = 100
174         return testcase.TestCase.EX_OK
175
176     def _cleanup(self):
177         """
178         Cleanup all OpenStack objects. Should be called on completion
179         :return:
180         """
181         if CONST.__getattribute__('vping_cleanup_objects'):
182             for creator in reversed(self.creators):
183                 try:
184                     creator.clean()
185                 except Exception as e:
186                     self.logger.error('Unexpected error cleaning - %s', e)
187
188     def _do_vping(self, vm_creator, test_ip):
189         """
190         Method to be implemented by subclasses
191         Begins the real test after the OpenStack environment has been setup
192         :param vm_creator: the SNAPS VM instance creator object
193         :param test_ip: the IP to which the VM needs to issue the ping
194         :return: T/F
195         """
196         raise NotImplementedError('vping execution is not implemented')