Browse Source

Merge "Smoke and bvt tests"

Jenkins 2 years ago
parent
commit
c3447a069a

+ 4
- 0
.gitmodules View File

@@ -0,0 +1,4 @@
1
+[submodule "plugin_test/fuel-qa"]
2
+	path = plugin_test/fuel-qa
3
+	url = https://github.com/openstack/fuel-qa
4
+	branch = stable/mitaka

+ 14
- 0
plugin_test/__init__.py View File

@@ -0,0 +1,14 @@
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""

+ 1
- 0
plugin_test/fuel-qa

@@ -0,0 +1 @@
1
+Subproject commit 15681971a6ff4adc9a8fd0b567f7443a3db6ffab

+ 14
- 0
plugin_test/helpers/__init__.py View File

@@ -0,0 +1,14 @@
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""

+ 81
- 0
plugin_test/helpers/settings.py View File

@@ -0,0 +1,81 @@
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""
15
+
16
+import os
17
+
18
+from fuelweb_test.settings import get_var_as_bool
19
+from fuelweb_test.settings import iface_alias
20
+from fuelweb_test.settings import NEUTRON_SEGMENT_TYPE
21
+
22
+
23
+HALF_MIN_WAIT = 30  # 30 seconds
24
+WAIT_FOR_COMMAND = 60 * 3  # 3 minutes
25
+WAIT_FOR_LONG_DEPLOY = 60 * 180  # 180 minutes
26
+
27
+EXT_IP = '8.8.8.8'  # Google DNS ^_^
28
+PRIVATE_NET = os.environ.get('PRIVATE_NET', 'admin_internal_net')
29
+ADMIN_NET = os.environ.get('ADMIN_NET', 'admin_floating_net')
30
+DEFAULT_ROUTER_NAME = os.environ.get('DEFAULT_ROUTER_NAME', 'router04')
31
+METADATA_IP = os.environ.get('METADATA_IP', '169.254.169.254')
32
+VM_USER = 'cirros'
33
+VM_PASS = 'cubswin:)'
34
+AZ_VCENTER1 = 'vcenter'
35
+AZ_VCENTER2 = 'vcenter2'
36
+FLAVOR_NAME = 'm1.micro128'
37
+
38
+PLUGIN_NAME = os.environ.get('PLUGIN_NAME', 'nsx-t')
39
+NSXT_PLUGIN_PATH = os.environ.get('NSXT_PLUGIN_PATH')
40
+NSXT_PLUGIN_VERSION = os.environ.get('NSXT_PLUGIN_VERSION', '1.0.0')
41
+NSXT_MANAGERS_IP = os.environ.get('NSXT_MANAGERS_IP')
42
+NSXT_USER = os.environ.get('NSXT_USER')
43
+
44
+
45
+assigned_networks = {
46
+    iface_alias('eth0'): ['fuelweb_admin', 'private'],
47
+    iface_alias('eth1'): ['public'],
48
+    iface_alias('eth2'): ['storage'],
49
+    iface_alias('eth4'): ['management']
50
+}
51
+
52
+cluster_settings = {
53
+    'net_provider': 'neutron',
54
+    'assign_to_all_nodes': True,
55
+    'net_segment_type': NEUTRON_SEGMENT_TYPE
56
+}
57
+
58
+plugin_configuration = {
59
+    'insecure/value': get_var_as_bool(os.environ.get('NSXT_INSECURE'), True),
60
+    'nsx_api_managers/value': NSXT_MANAGERS_IP,
61
+    'nsx_api_user/value': NSXT_USER,
62
+    'nsx_api_password/value': os.environ.get('NSXT_PASSWORD'),
63
+    'default_overlay_tz_uuid/value': os.environ.get('NSXT_OVERLAY_TZ_UUID'),
64
+    'default_vlan_tz_uuid/value': os.environ.get('NSXT_VLAN_TZ_UUID'),
65
+    'default_tier0_router_uuid/value': os.environ.get(
66
+        'NSXT_TIER0_ROUTER_UUID'),
67
+    'default_edge_cluster_uuid/value': os.environ.get(
68
+        'NSXT_EDGE_CLUSTER_UUID'),
69
+    'uplink_profile_uuid/value': os.environ.get('NSXT_UPLINK_PROFILE_UUID'),
70
+    'controller_ip_pool_uuid/value': os.environ.get(
71
+        'NSXT_CONTROLLER_IP_POOL_UUID'),
72
+    'controller_pnics_pairs/value': os.environ.get(
73
+        'NSXT_CONTROLLER_PNICS_PAIRS'),
74
+    'compute_ip_pool_uuid/value': os.environ.get('NSXT_COMPUTE_IP_POOL_UUID'),
75
+    'compute_pnics_pairs/value': os.environ.get('NSXT_COMPUTE_PNICS_PAIRS'),
76
+    'floating_ip_range/value': os.environ.get('NSXT_FLOATING_IP_RANGE'),
77
+    'floating_net_cidr/value': os.environ.get('NSXT_FLOATING_NET_CIDR'),
78
+    'internal_net_cidr/value': os.environ.get('NSXT_INTERNAL_NET_CIDR'),
79
+    'floating_net_gw/value': os.environ.get('NSXT_FLOATING_NET_GW'),
80
+    'internal_net_dns/value': os.environ.get('NSXT_INTERNAL_NET_DNS')
81
+}

+ 54
- 0
plugin_test/helpers/tools.py View File

@@ -0,0 +1,54 @@
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""
15
+
16
+from functools import wraps
17
+
18
+from fuelweb_test import logger
19
+
20
+
21
+def find_first(seq, predicate):
22
+    """Find the first item of sequence for which predicate is performed."""
23
+    return next((x for x in seq if predicate(x)), None)
24
+
25
+
26
+class ShowPos(object):
27
+    """Print func name and its parameters for each call."""
28
+
29
+    @staticmethod
30
+    def deco(f):
31
+        """Logger decorator."""
32
+        def wrapper(*args, **kwargs):
33
+            logger.debug("Call {0}({1}, {2})".format(f.__name__, args, kwargs))
34
+            return f(*args, **kwargs)
35
+        return wrapper
36
+
37
+    def __getattribute__(self, name):
38
+        """Log by attributes."""
39
+        attr = object.__getattribute__(self, name)
40
+        if callable(attr):
41
+            return ShowPos.deco(attr)
42
+        else:
43
+            return attr
44
+
45
+
46
+def show_pos(f):
47
+    """Wrapper shows current POSition in debug output."""
48
+    @wraps(f)
49
+    def wrapper(*args, **kwargs):
50
+        logger.debug('Call {func}({args}, {kwargs})'.format(func=f.__name__,
51
+                                                            args=args,
52
+                                                            kwargs=kwargs))
53
+        return f(*args, **kwargs)
54
+    return wrapper

+ 65
- 0
plugin_test/run_tests.py View File

@@ -0,0 +1,65 @@
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""
15
+import os
16
+import re
17
+import sys
18
+
19
+from nose.plugins import Plugin
20
+from paramiko.transport import _join_lingering_threads
21
+
22
+
23
+class CloseSSHConnectionsPlugin(Plugin):
24
+    """Closes all paramiko's ssh connections after each test case.
25
+
26
+    Plugin fixes proboscis disability to run cleanup of any kind.
27
+    'afterTest' calls _join_lingering_threads function from paramiko,
28
+    which stops all threads (set the state to inactive and join for 10s)
29
+    """
30
+
31
+    name = 'closesshconnections'
32
+
33
+    def options(self, parser, env=os.environ):
34
+        super(CloseSSHConnectionsPlugin, self).options(parser, env=env)
35
+
36
+    def configure(self, options, conf):
37
+        super(CloseSSHConnectionsPlugin, self).configure(options, conf)
38
+        self.enabled = True
39
+
40
+    def afterTest(self, *args, **kwargs):
41
+        _join_lingering_threads()
42
+
43
+
44
+def import_tests():
45
+    from tests import test_plugin_nsxt  # noqa
46
+
47
+
48
+def run_tests():
49
+    from proboscis import TestProgram  # noqa
50
+    import_tests()
51
+
52
+    # Run Proboscis and exit.
53
+    TestProgram(addplugins=[CloseSSHConnectionsPlugin()]).run_and_exit()
54
+
55
+
56
+if __name__ == '__main__':
57
+    sys.path.append(sys.path[0] + "/fuel-qa")
58
+    import_tests()
59
+    from fuelweb_test.helpers.patching import map_test
60
+    if any(re.search(r'--group=patching_master_tests', arg)
61
+           for arg in sys.argv):
62
+        map_test('master')
63
+    elif any(re.search(r'--group=patching.*', arg) for arg in sys.argv):
64
+        map_test('environment')
65
+    run_tests()

+ 209
- 0
plugin_test/test_templates/default.yaml View File

@@ -0,0 +1,209 @@
1
+---
2
+template:
3
+ devops_settings:
4
+    aliases:
5
+
6
+      dynamic_address_pool:
7
+       - &pool_default !os_env POOL_DEFAULT, 10.109.0.0/16:24
8
+
9
+      default_interface_model:
10
+       - &interface_model !os_env INTERFACE_MODEL, e1000
11
+
12
+      rack-01-slave-interfaces: &rack-01-slave-interfaces
13
+       - label: eth0
14
+         l2_network_device: admin      # Libvirt bridge name. It is *NOT* Nailgun networks
15
+         interface_model: *interface_model
16
+       - label: eth1
17
+         l2_network_device: public
18
+         interface_model: *interface_model
19
+       - label: eth2
20
+         l2_network_device: management
21
+         interface_model: *interface_model
22
+       - label: eth3
23
+         l2_network_device: private
24
+         interface_model: *interface_model
25
+       - label: eth4
26
+         l2_network_device: storage
27
+         interface_model: *interface_model
28
+
29
+      rack-01-slave-network_config: &rack-01-slave-network_config
30
+        eth0:
31
+          networks:
32
+           - fuelweb_admin
33
+        eth1:
34
+          networks:
35
+           - public
36
+        eth2:
37
+          networks:
38
+           - management
39
+        eth3:
40
+          networks:
41
+           - private
42
+        eth4:
43
+          networks:
44
+           - storage
45
+
46
+      rack-01-slave-node-params: &rack-01-slave-node-params
47
+        vcpu: !os_env SLAVE_NODE_CPU, 4
48
+        memory: !os_env SLAVE_NODE_MEMORY, 8192
49
+        boot:
50
+          - network
51
+          - hd
52
+        volumes:
53
+         - name: system
54
+           capacity: !os_env NODE_VOLUME_SIZE, 55
55
+           format: qcow2
56
+         - name: cinder
57
+           capacity: !os_env NODE_VOLUME_SIZE, 55
58
+           format: qcow2
59
+         - name: swift
60
+           capacity: !os_env NODE_VOLUME_SIZE, 55
61
+           format: qcow2
62
+        interfaces: *rack-01-slave-interfaces
63
+        network_config: *rack-01-slave-network_config
64
+
65
+      rack-02-slave-node-params: &rack-02-slave-node-params
66
+        vcpu: !os_env SLAVE_NODE_CPU, 2
67
+        memory: !os_env SLAVE_NODE_MEMORY, 3072
68
+        boot:
69
+          - network
70
+          - hd
71
+        volumes:
72
+         - name: system
73
+           capacity: !os_env NODE_VOLUME_SIZE, 55
74
+           format: qcow2
75
+         - name: cinder
76
+           capacity: !os_env NODE_VOLUME_SIZE, 55
77
+           format: qcow2
78
+         - name: swift
79
+           capacity: !os_env NODE_VOLUME_SIZE, 55
80
+           format: qcow2
81
+        interfaces: *rack-01-slave-interfaces
82
+        network_config: *rack-01-slave-network_config
83
+
84
+
85
+    env_name: !os_env ENV_NAME
86
+
87
+    address_pools:
88
+    # Network pools used by the environment
89
+      fuelweb_admin-pool01:
90
+        net: *pool_default
91
+        params:
92
+          tag: 0
93
+      public-pool01:
94
+        net: *pool_default
95
+        params:
96
+          tag: 0
97
+      storage-pool01:
98
+        net: *pool_default
99
+        params:
100
+          tag: 101
101
+      management-pool01:
102
+        net: *pool_default
103
+        params:
104
+          tag: 102
105
+      private-pool01:
106
+        net: *pool_default
107
+        params:
108
+          tag: 103
109
+
110
+    groups:
111
+     - name: cat
112
+       driver:
113
+         name: devops.driver.libvirt.libvirt_driver
114
+         params:
115
+           connection_string: !os_env CONNECTION_STRING, qemu:///system
116
+           storage_pool_name: !os_env STORAGE_POOL_NAME, default
117
+           stp: True
118
+           hpet: False
119
+           use_host_cpu: !os_env DRIVER_USE_HOST_CPU, true
120
+
121
+       network_pools:  # Address pools for OpenStack networks.
122
+         # Actual names should be used for keys
123
+         # (the same as in Nailgun, for example)
124
+
125
+         fuelweb_admin: fuelweb_admin-pool01
126
+         public: public-pool01
127
+         storage: storage-pool01
128
+         management: management-pool01
129
+         private: private-pool01
130
+
131
+       l2_network_devices:  # Libvirt bridges. It is *NOT* Nailgun networks
132
+         admin:
133
+           address_pool: fuelweb_admin-pool01
134
+           dhcp: false
135
+           forward:
136
+             mode: nat
137
+
138
+         public:
139
+           address_pool: public-pool01
140
+           dhcp: false
141
+           forward:
142
+             mode: nat
143
+
144
+         storage:
145
+           address_pool: storage-pool01
146
+           dhcp: false
147
+
148
+         management:
149
+           address_pool: management-pool01
150
+           dhcp: false
151
+
152
+         private:
153
+           address_pool: private-pool01
154
+           dhcp: false
155
+
156
+       nodes:
157
+        - name: admin        # Custom name of VM for Fuel admin node
158
+          role: fuel_master  # Fixed role for Fuel master node properties
159
+          params:
160
+            vcpu: !os_env ADMIN_NODE_CPU, 2
161
+            memory: !os_env ADMIN_NODE_MEMORY, 8192
162
+            boot:
163
+              - hd
164
+              - cdrom  # for boot from usb - without 'cdrom'
165
+            volumes:
166
+             - name: system
167
+               capacity: !os_env ADMIN_NODE_VOLUME_SIZE, 80
168
+               format: qcow2
169
+             - name: iso
170
+               source_image: !os_env ISO_PATH    # if 'source_image' set, then volume capacity is calculated from it's size
171
+               format: raw
172
+               device: cdrom   # for boot from usb - 'disk'
173
+               bus: ide        # for boot from usb - 'usb'
174
+            interfaces:
175
+             - label: eth0
176
+               l2_network_device: admin    # Libvirt bridge name. It is *NOT* a Nailgun network
177
+               interface_model: *interface_model
178
+            network_config:
179
+              eth0:
180
+                networks:
181
+                 - fuelweb_admin
182
+
183
+        - name: slave-01
184
+          role: fuel_slave
185
+          params: *rack-01-slave-node-params
186
+        - name: slave-02
187
+          role: fuel_slave
188
+          params: *rack-01-slave-node-params
189
+        - name: slave-03
190
+          role: fuel_slave
191
+          params: *rack-01-slave-node-params
192
+        - name: slave-04
193
+          role: fuel_slave
194
+          params: *rack-02-slave-node-params
195
+        - name: slave-05
196
+          role: fuel_slave
197
+          params: *rack-02-slave-node-params
198
+        - name: slave-06
199
+          role: fuel_slave
200
+          params: *rack-02-slave-node-params
201
+        - name: slave-07
202
+          role: fuel_slave
203
+          params: *rack-02-slave-node-params
204
+        - name: slave-08
205
+          role: fuel_slave
206
+          params: *rack-02-slave-node-params
207
+        - name: slave-09
208
+          role: fuel_slave
209
+          params: *rack-02-slave-node-params

+ 14
- 0
plugin_test/tests/__init__.py View File

@@ -0,0 +1,14 @@
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""

+ 98
- 0
plugin_test/tests/base_plugin_test.py View File

@@ -0,0 +1,98 @@
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""
15
+
16
+import os
17
+
18
+from proboscis.asserts import assert_true
19
+
20
+from fuelweb_test import logger
21
+from fuelweb_test.helpers import utils
22
+from fuelweb_test.helpers.utils import pretty_log
23
+from fuelweb_test.tests.base_test_case import TestBasic
24
+from helpers import settings
25
+
26
+
27
+class TestNSXtBase(TestBasic):
28
+    """Base class for NSX-T plugin tests"""
29
+
30
+    def __init__(self):
31
+        super(TestNSXtBase, self).__init__()
32
+        self.default = settings
33
+
34
+    def install_nsxt_plugin(self):
35
+        """Download and install NSX-T plugin on master node.
36
+
37
+        :return: None
38
+        """
39
+        master_ip = self.ssh_manager.admin_ip
40
+        utils.upload_tarball(ip=master_ip,
41
+                             tar_path=self.default.NSXT_PLUGIN_PATH,
42
+                             tar_target='/var')
43
+
44
+        utils.install_plugin_check_code(
45
+            ip=master_ip,
46
+            plugin=os.path.basename(self.default.NSXT_PLUGIN_PATH))
47
+
48
+    def enable_plugin(self, cluster_id, settings=None):
49
+        """Enable NSX-T plugin on cluster.
50
+
51
+        :param cluster_id: cluster id
52
+        :param settings: settings in dict format
53
+        :return: None
54
+        """
55
+        msg = "Plugin couldn't be enabled. Check plugin version. Test aborted"
56
+        settings = settings if settings else {}
57
+        checker = self.fuel_web.check_plugin_exists(cluster_id,
58
+                                                    self.default.PLUGIN_NAME)
59
+        assert_true(checker, msg)
60
+        logger.info('Configure cluster with '
61
+                    'following parameters: \n{}'.format(pretty_log(settings)))
62
+        self.fuel_web.update_plugin_settings(
63
+            cluster_id,
64
+            self.default.PLUGIN_NAME,
65
+            self.default.NSXT_PLUGIN_VERSION,
66
+            dict(self.default.plugin_configuration, **settings))
67
+
68
+    def reconfigure_cluster_interfaces(self, cluster_id):
69
+        # clear network mapping enp0s6 for all deployed nodes
70
+        nodes = self.fuel_web.client.list_cluster_nodes(cluster_id)
71
+        for node in nodes:
72
+            self.fuel_web.update_node_networks(node['id'],
73
+                                               settings.assigned_networks)
74
+
75
+    def delete_nsxt_plugin(self, failover=False):
76
+        """Delete NSX-T plugin
77
+
78
+        :param failover: True if we expect that plugin won't be deleted
79
+        :return:
80
+        """
81
+        plugin_name = self.default.PLUGIN_NAME
82
+        plugin_vers = self.default.NSXT_PLUGIN_VERSION
83
+        tmp = "Plugin '{0}' {1} removed"
84
+        msg = tmp.format(plugin_name, 'was' if failover else "wasn't")
85
+        cmd = 'fuel plugins --remove {0}=={1}'.format(plugin_name, plugin_vers)
86
+
87
+        self.ssh_manager.check_call(
88
+            ip=self.ssh_manager.admin_ip,
89
+            command=cmd,
90
+            expected=[1 if failover else 0],
91
+            raise_on_err=not failover
92
+        )
93
+
94
+        output = self.ssh_manager.check_call(
95
+            ip=self.ssh_manager.admin_ip,
96
+            command='fuel2 plugins list -f value -c name'
97
+        ).stdout[-1].split(' ')
98
+        assert_true(plugin_name in output != failover, msg)

+ 204
- 0
plugin_test/tests/test_plugin_nsxt.py View File

@@ -0,0 +1,204 @@
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""
15
+
16
+from proboscis import test
17
+from proboscis.asserts import assert_true
18
+
19
+from fuelweb_test.helpers.decorators import log_snapshot_after_test
20
+from fuelweb_test.settings import DEPLOYMENT_MODE
21
+from fuelweb_test.tests.base_test_case import SetupEnvironment
22
+from tests.base_plugin_test import TestNSXtBase
23
+
24
+
25
+@test(groups=["plugins", "nsxt_plugin", 'nsxt_smoke_scenarios'])
26
+class TestNSXtSmoke(TestNSXtBase):
27
+    """Tests from test plan that have been marked as 'Automated'."""
28
+
29
+    @test(depends_on=[SetupEnvironment.prepare_slaves_1],
30
+          groups=["nsxt_install", 'nsxt_smoke'])
31
+    @log_snapshot_after_test
32
+    def nsxt_install(self):
33
+        """Check that plugin can be installed.
34
+
35
+        Scenario:
36
+            1. Connect to the Fuel master node via ssh.
37
+            2. Upload NSX-T plugin.
38
+            3. Install NSX-T plugin.
39
+            4. Run command 'fuel plugins'.
40
+            5. Check name, version and package version of plugin.
41
+
42
+        Duration 30 min
43
+
44
+        """
45
+        self.env.revert_snapshot('ready_with_1_slaves')
46
+
47
+        self.show_step(1)
48
+        self.show_step(2)
49
+        self.show_step(3)
50
+        self.install_nsxt_plugin()
51
+
52
+        self.show_step(4)
53
+        output = self.ssh_manager.execute_on_remote(
54
+            ip=self.ssh_manager.admin_ip, cmd='fuel plugins list'
55
+        )['stdout'].pop().split(' ')
56
+
57
+        self.show_step(5)
58
+        msg = "Plugin '{0}' is not installed.".format(self.default.PLUGIN_NAME)
59
+        # check name
60
+        assert_true(self.default.PLUGIN_NAME in output, msg)
61
+        # check version
62
+        assert_true(self.default.NSXT_PLUGIN_VERSION in output, msg)
63
+
64
+        self.env.make_snapshot("nsxt_install", is_make=True)
65
+
66
+    @test(depends_on=[nsxt_install],
67
+          groups=["nsxt_uninstall", 'nsxt_smoke'])
68
+    @log_snapshot_after_test
69
+    def nsxt_uninstall(self):
70
+        """Check that NSX-T plugin can be removed.
71
+
72
+        Scenario:
73
+            1. Revert to snapshot nsxt_install
74
+            2. Remove NSX-T plugin.
75
+            3. Run command 'fuel plugins' to ensure the NSX-T plugin has
76
+               been removed.
77
+
78
+        Duration: 5 min
79
+        """
80
+        self.show_step(1)
81
+        self.env.revert_snapshot("nsxt_install")
82
+
83
+        self.show_step(2)
84
+        cmd = 'fuel plugins --remove {0}=={1}'.format(
85
+            self.default.PLUGIN_NAME, self.default.NSXT_PLUGIN_VERSION)
86
+
87
+        self.ssh_manager.execute_on_remote(
88
+            ip=self.ssh_manager.admin_ip,
89
+            cmd=cmd,
90
+            err_msg='Can not remove plugin.')
91
+
92
+        self.show_step(3)
93
+        self.delete_nsxt_plugin()
94
+
95
+    @test(depends_on=[nsxt_install],
96
+          groups=['nsxt_kvm_smoke', 'nsxt_smoke'])
97
+    @log_snapshot_after_test
98
+    def nsxt_kvm_smoke(self):
99
+        """Deploy a cluster with NSXt Plugin.
100
+
101
+        Scenario:
102
+            1. Upload the plugin to master node.
103
+            2. Create cluster.
104
+            3. Provision one controller node.
105
+            4. Configure NSXt for that cluster.
106
+            5. Deploy cluster with plugin.
107
+            6. Run 'smoke' OSTF.
108
+
109
+        Duration 90 min
110
+
111
+        """
112
+        self.show_step(1)
113
+        self.env.revert_snapshot('nsxt_install')
114
+
115
+        self.show_step(2)
116
+        cluster_id = self.fuel_web.create_cluster(
117
+            name=self.__class__.__name__,
118
+            mode=DEPLOYMENT_MODE,
119
+            settings=self.default.cluster_settings,
120
+            configure_ssl=False)
121
+
122
+        self.show_step(3)
123
+        self.fuel_web.update_nodes(cluster_id, {'slave-01': ['controller']})
124
+
125
+        self.reconfigure_cluster_interfaces(cluster_id)
126
+
127
+        self.show_step(4)
128
+        self.enable_plugin(cluster_id)
129
+
130
+        self.show_step(5)
131
+        self.fuel_web.deploy_cluster_wait(cluster_id)
132
+
133
+        self.show_step(6)
134
+        self.fuel_web.run_ostf(cluster_id=cluster_id, test_sets=['smoke'])
135
+
136
+
137
+@test(groups=["plugins", "nsxt_plugin", 'nsxt_bvt_scenarios'])
138
+class TestNSXtBVT(TestNSXtBase):
139
+    """NSX-t BVT scenarios"""
140
+
141
+    @test(depends_on=[SetupEnvironment.prepare_slaves_9],
142
+          groups=["nsxt_bvt"])
143
+    @log_snapshot_after_test
144
+    def nsxt_bvt(self):
145
+        """Deploy cluster with plugin and vmware datastore backend.
146
+
147
+        Scenario:
148
+            1. Upload plugins to the master node.
149
+            2. Create cluster with vcenter.
150
+            3. Add 3 node with controller role, 3 ceph,
151
+               compute-vmware + cinder-vmware, compute.
152
+            4. Configure vcenter.
153
+            5. Configure NSXt for that cluster.
154
+            6. Deploy cluster.
155
+            7. Run OSTF.
156
+
157
+        Duration 3 hours
158
+
159
+        """
160
+        self.env.revert_snapshot("ready_with_9_slaves")
161
+
162
+        self.show_step(1)
163
+        self.install_nsxt_plugin()
164
+
165
+        self.show_step(2)
166
+        settings = self.default.cluster_settings
167
+        settings["images_ceph"] = True
168
+
169
+        cluster_id = self.fuel_web.create_cluster(
170
+            name=self.__class__.__name__,
171
+            mode=DEPLOYMENT_MODE,
172
+            settings=settings,
173
+            configure_ssl=False)
174
+
175
+        self.show_step(3)
176
+        self.fuel_web.update_nodes(
177
+            cluster_id,
178
+            {'slave-01': ['controller'],
179
+             'slave-02': ['controller'],
180
+             'slave-03': ['controller'],
181
+             'slave-04': ['ceph-osd'],
182
+             'slave-05': ['ceph-osd'],
183
+             'slave-06': ['ceph-osd'],
184
+             'slave-07': ['compute-vmware', 'cinder-vmware'],
185
+             'slave-08': ['compute']}
186
+        )
187
+
188
+        self.reconfigure_cluster_interfaces(cluster_id)
189
+
190
+        self.show_step(4)
191
+        target_node_2 = \
192
+            self.fuel_web.get_nailgun_node_by_name('slave-07')['hostname']
193
+        self.fuel_web.vcenter_configure(cluster_id,
194
+                                        multiclusters=True,
195
+                                        target_node_2=target_node_2)
196
+        self.show_step(5)
197
+        self.enable_plugin(cluster_id)
198
+
199
+        self.show_step(6)
200
+        self.fuel_web.deploy_cluster_wait(cluster_id)
201
+
202
+        self.show_step(7)
203
+        self.fuel_web.run_ostf(
204
+            cluster_id=cluster_id, test_sets=['smoke', 'sanity', 'ha'])

+ 660
- 0
plugin_test/utils/jenkins/system_tests.sh View File

@@ -0,0 +1,660 @@
1
+#!/bin/sh
2
+PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
3
+
4
+INVALIDOPTS_ERR=100
5
+NOJOBNAME_ERR=101
6
+NOISOPATH_ERR=102
7
+NOTASKNAME_ERR=103
8
+NOWORKSPACE_ERR=104
9
+NOISOFOUND_ERR=107
10
+CDWORKSPACE_ERR=110
11
+ISODOWNLOAD_ERR=111
12
+INVALIDTASK_ERR=112
13
+
14
+# Defaults
15
+
16
+export REBOOT_TIMEOUT=${REBOOT_TIMEOUT:-5000}
17
+export ALWAYS_CREATE_DIAGNOSTIC_SNAPSHOT=${ALWAYS_CREATE_DIAGNOSTIC_SNAPSHOT:-true}
18
+
19
+ShowHelp() {
20
+cat << EOF
21
+System Tests Script
22
+
23
+It can perform several actions depending on Jenkins JOB_NAME it's ran from
24
+or it can take names from exported environment variables or command line options
25
+if you do need to override them.
26
+
27
+-w (dir)    - Path to workspace where fuelweb git repository was checked out.
28
+              Uses Jenkins' WORKSPACE if not set
29
+-e (name)   - Directly specify environment name used in tests
30
+              Uses ENV_NAME variable is set.
31
+-j (name)   - Name of this job. Determines ISO name, Task name and used by tests.
32
+              Uses Jenkins' JOB_NAME if not set
33
+-v          - Do not use virtual environment
34
+-V (dir)    - Path to python virtual environment
35
+-i (file)   - Full path to ISO file to build or use for tests.
36
+              Made from iso dir and name if not set.
37
+-t (name)   - Name of task this script should perform. Should be one of defined ones.
38
+              Taken from Jenkins' job's suffix if not set.
39
+-o (str)    - Allows you any extra command line option to run test job if you
40
+              want to use some parameters.
41
+-a (str)    - Allows you to path NOSE_ATTR to the test job if you want
42
+              to use some parameters.
43
+-A (str)    - Allows you to path  NOSE_EVAL_ATTR if you want to enter attributes
44
+              as python expressions.
45
+-m (name)   - Use this mirror to build ISO from.
46
+              Uses 'srt' if not set.
47
+-U          - ISO URL for tests.
48
+              Null by default.
49
+-r (yes/no) - Should built ISO file be placed with build number tag and
50
+              symlinked to the last build or just copied over the last file.
51
+-b (num)    - Allows you to override Jenkins' build number if you need to.
52
+-l (dir)    - Path to logs directory. Can be set by LOGS_DIR evironment variable.
53
+              Uses WORKSPACE/logs if not set.
54
+-d          - Dry run mode. Only show what would be done and do nothing.
55
+              Useful for debugging.
56
+-k          - Keep previously created test environment before tests run
57
+-K          - Keep test environment after tests are finished
58
+-h          - Show this help page
59
+
60
+Most variables uses guesses from Jenkins' job name but can be overriden
61
+by exported variable before script is run or by one of command line options.
62
+
63
+You can override following variables using export VARNAME="value" before running this script
64
+WORKSPACE  - path to directory where Fuelweb repository was checked out by Jenkins or manually
65
+JOB_NAME   - name of Jenkins job that determines which task should be done and ISO file name.
66
+
67
+If task name is "iso" it will make iso file
68
+Other defined names will run Nose tests using previously built ISO file.
69
+
70
+ISO file name is taken from job name prefix
71
+Task name is taken from job name suffix
72
+Separator is one dot '.'
73
+
74
+For example if JOB_NAME is:
75
+mytest.somestring.iso
76
+ISO name: mytest.iso
77
+Task name: iso
78
+If ran with such JOB_NAME iso file with name mytest.iso will be created
79
+
80
+If JOB_NAME is:
81
+mytest.somestring.node
82
+ISO name: mytest.iso
83
+Task name: node
84
+If script was run with this JOB_NAME node tests will be using ISO file mytest.iso.
85
+
86
+First you should run mytest.somestring.iso job to create mytest.iso.
87
+Then you can ran mytest.somestring.node job to start tests using mytest.iso and other tests too.
88
+EOF
89
+}
90
+
91
+GlobalVariables() {
92
+  # where built iso's should be placed
93
+  # use hardcoded default if not set before by export
94
+  ISO_DIR="${ISO_DIR:=/var/www/fuelweb-iso}"
95
+
96
+  # name of iso file
97
+  # taken from jenkins job prefix
98
+  # if not set before by variable export
99
+  if [ -z "${ISO_NAME}" ]; then
100
+    ISO_NAME="${JOB_NAME%.*}.iso"
101
+  fi
102
+
103
+  # full path where iso file should be placed
104
+  # make from iso name and path to iso shared directory
105
+  # if was not overriden by options or export
106
+  if [ -z "${ISO_PATH}" ]; then
107
+    ISO_PATH="${ISO_DIR}/${ISO_NAME}"
108
+  fi
109
+
110
+  # what task should be ran
111
+  # it's taken from jenkins job name suffix if not set by options
112
+  if [ -z "${TASK_NAME}" ]; then
113
+    TASK_NAME="${JOB_NAME##*.}"
114
+  fi
115
+
116
+  # do we want to keep iso's for each build or just copy over single file
117
+  ROTATE_ISO="${ROTATE_ISO:=yes}"
118
+
119
+  # choose mirror to build iso from. Default is 'srt' for Saratov's mirror
120
+  # you can change mirror by exporting USE_MIRROR variable before running this script
121
+  USE_MIRROR="${USE_MIRROR:=srt}"
122
+
123
+  # only show what commands would be executed but do nothing
124
+  # this feature is useful if you want to debug this script's behaviour
125
+  DRY_RUN="${DRY_RUN:=no}"
126
+
127
+  VENV="${VENV:=yes}"
128
+}
129
+
130
+GetoptsVariables() {
131
+  while getopts ":w:j:i:t:o:a:A:m:U:r:b:V:l:dkKe:v:h" opt; do
132
+    case $opt in
133
+      w)
134
+        WORKSPACE="${OPTARG}"
135
+        ;;
136
+      j)
137
+        JOB_NAME="${OPTARG}"
138
+        ;;
139
+      i)
140
+        ISO_PATH="${OPTARG}"
141
+        ;;
142
+      t)
143
+        TASK_NAME="${OPTARG}"
144
+        ;;
145
+      o)
146
+        TEST_OPTIONS="${TEST_OPTIONS} ${OPTARG}"
147
+        ;;
148
+      a)
149
+        NOSE_ATTR="${OPTARG}"
150
+        ;;
151
+      A)
152
+        NOSE_EVAL_ATTR="${OPTARG}"
153
+        ;;
154
+      m)
155
+        USE_MIRROR="${OPTARG}"
156
+        ;;
157
+      U)
158
+        ISO_URL="${OPTARG}"
159
+        ;;
160
+      r)
161
+        ROTATE_ISO="${OPTARG}"
162
+        ;;
163
+      V)
164
+        VENV_PATH="${OPTARG}"
165
+        ;;
166
+      l)
167
+        LOGS_DIR="${OPTARG}"
168
+        ;;
169
+      k)
170
+        KEEP_BEFORE="yes"
171
+        ;;
172
+      K)
173
+        KEEP_AFTER="yes"
174
+        ;;
175
+      e)
176
+        ENV_NAME="${OPTARG}"
177
+        ;;
178
+      d)
179
+        DRY_RUN="yes"
180
+        ;;
181
+      v)
182
+        VENV="no"
183
+        ;;
184
+      h)
185
+        ShowHelp
186
+        exit 0
187
+        ;;
188
+      \?)
189
+        echo "Invalid option: -$OPTARG"
190
+        ShowHelp
191
+        exit $INVALIDOPTS_ERR
192
+        ;;
193
+      :)
194
+        echo "Option -$OPTARG requires an argument."
195
+        ShowHelp
196
+        exit $INVALIDOPTS_ERR
197
+        ;;
198
+    esac
199
+  done
200
+}
201
+
202
+CheckVariables() {
203
+
204
+  if [ -z "${JOB_NAME}" ]; then
205
+    echo "Error! JOB_NAME is not set!"
206
+    exit $NOJOBNAME_ERR
207
+  fi
208
+  if [ -z "${ISO_PATH}" ]; then
209
+    echo "Error! ISO_PATH is not set!"
210
+    exit $NOISOPATH_ERR
211
+  fi
212
+  if [ -z "${TASK_NAME}" ]; then
213
+    echo "Error! TASK_NAME is not set!"
214
+    exit $NOTASKNAME_ERR
215
+  fi
216
+  if [ -z "${WORKSPACE}" ]; then
217
+    echo "Error! WORKSPACE is not set!"
218
+    exit $NOWORKSPACE_ERR
219
+  fi
220
+
221
+  if [ -z "${POOL_PUBLIC}" ]; then
222
+    export POOL_PUBLIC='172.16.0.0/24:24'
223
+  fi
224
+  if [ -z "${POOL_MANAGEMENT}" ]; then
225
+    export POOL_MANAGEMENT='172.16.1.0/24:24'
226
+  fi
227
+  if [ -z "${POOL_PRIVATE}" ]; then
228
+    export POOL_PRIVATE='192.168.0.0/24:24'
229
+  fi
230
+
231
+  # vCenter variables
232
+  if [ -z "${DISABLE_SSL}" ]; then
233
+    export DISABLE_SSL="true"
234
+  fi
235
+  if [ -z "${VCENTER_USE}" ]; then
236
+    export VCENTER_USE="true"
237
+  fi
238
+  if [ -z "${VCENTER_IP}" ]; then
239
+    export VCENTER_IP="172.16.0.254"
240
+  fi
241
+  if [ -z "${VCENTER_USERNAME}" ]; then
242
+    export VCENTER_USERNAME="administrator@vsphere.local"
243
+  fi
244
+  if [ -z "${VCENTER_PASSWORD}" ]; then
245
+    echo "Error! VCENTER_PASSWORD is not set!"
246
+    exit 1
247
+  fi
248
+  if [ -z "${VC_DATACENTER}" ]; then
249
+    export VC_DATACENTER="Datacenter"
250
+  fi
251
+  if [ -z "${VC_DATASTORE}" ]; then
252
+    export VC_DATASTORE="nfs"
253
+  fi
254
+  if [ -z "${VCENTER_IMAGE_DIR}" ]; then
255
+    export VCENTER_IMAGE_DIR="/openstack_glance"
256
+  fi
257
+  if [ -z "${WORKSTATION_NODES}" ]; then
258
+    export WORKSTATION_NODES="esxi1 esxi2 esxi3 vcenter trusty nsx-edge"
259
+  fi
260
+  if [ -z "${WORKSTATION_IFS}" ]; then
261
+    export WORKSTATION_IFS="vmnet1 vmnet2 vmnet5"
262
+  fi
263
+  if [ -z "${VCENTER_CLUSTERS}" ]; then
264
+    export VCENTER_CLUSTERS="Cluster1,Cluster2"
265
+  fi
266
+  if [ -z "${WORKSTATION_SNAPSHOT}" ]; then
267
+    echo "Error! WORKSTATION_SNAPSHOT is not set!"
268
+    exit 1
269
+  fi
270
+  if [ -z "${WORKSTATION_USERNAME}" ]; then
271
+    echo "Error! WORKSTATION_USERNAME is not set!"
272
+    exit 1
273
+  fi
274
+  if [ -z "${WORKSTATION_PASSWORD}" ]; then
275
+    echo "Error! WORKSTATION_PASSWORD is not set!"
276
+    exit 1
277
+  fi
278
+
279
+  # NSXt variables
280
+  if [ -z "${NSXT_PLUGIN_PATH}" ]; then
281
+    echo "Error! NSXT_PLUGIN_PATH is not set!"
282
+    exit 1
283
+  fi
284
+  if [ -z "${NEUTRON_SEGMENT_TYPE}" ]; then
285
+    export NEUTRON_SEGMENT_TYPE="tun"
286
+  fi
287
+  if [ -z "${NSXT_INSECURE}" ]; then
288
+    export NSXT_INSECURE='true'
289
+  fi
290
+  if [ -z "${NSXT_MANAGERS_IP}" ]; then
291
+    export NSXT_MANAGERS_IP="172.16.0.249"
292
+  fi
293
+  if [ -z "${NSXT_USER}" ]; then
294
+    export NSXT_USER='admin'
295
+  fi
296
+  if [ -z "${NSXT_PASSWORD}" ]; then
297
+    echo "Error! NSXT_PASSWORD is not set!"
298
+    exit 1
299
+  fi
300
+  if [ -z "${NSXT_OVERLAY_TZ_UUID}" ]; then
301
+    export NSXT_OVERLAY_TZ_UUID='0eeb1b85-c826-403d-8762-6a9c23a4f132'
302
+  fi
303
+  if [ -z "${NSXT_VLAN_TZ_UUID}" ]; then
304
+    export NSXT_VLAN_TZ_UUID='8efe20d2-e71a-4d6e-acdd-f78a2ec2e90c'
305
+  fi
306
+  if [ -z "${NSXT_TIER0_ROUTER_UUID}" ]; then
307
+    export NSXT_TIER0_ROUTER_UUID='606acd01-c5f8-40ea-ae20-9a91eb7ebcb4'
308
+  fi
309
+  if [ -z "${NSXT_EDGE_CLUSTER_UUID}" ]; then
310
+    export NSXT_EDGE_CLUSTER_UUID='c53d602a-4010-47cc-a8b1-4ef11d0a3edd'
311
+  fi
312
+  if [ -z "${NSXT_UPLINK_PROFILE_UUID}" ]; then
313
+    export NSXT_UPLINK_PROFILE_UUID='99864272-b34f-46a5-89c8-5657fa7042ea'
314
+  fi
315
+  if [ -z "${NSXT_CONTROLLER_IP_POOL_UUID}" ]; then
316
+    export NSXT_CONTROLLER_IP_POOL_UUID='2e06fcb2-7c5b-4515-a7a9-98809c7b863a'
317
+  fi
318
+  if [ -z "${NSXT_CONTROLLER_PNICS_PAIRS}" ]; then
319
+    export NSXT_CONTROLLER_PNICS_PAIRS='enp0s6:uplink'
320
+  fi
321
+  if [ -z "${NSXT_COMPUTE_IP_POOL_UUID}" ]; then
322
+    export NSXT_COMPUTE_IP_POOL_UUID='2e06fcb2-7c5b-4515-a7a9-98809c7b863a'
323
+  fi
324
+  if [ -z "${NSXT_COMPUTE_PNICS_PAIRS}" ]; then
325
+    export NSXT_COMPUTE_PNICS_PAIRS='enp0s6:uplink'
326
+  fi
327
+
328
+  if [ -z "${NSXT_FLOATING_IP_RANGE}" ]; then
329
+    export NSXT_FLOATING_IP_RANGE='172.16.212.2-172.16.212.40'
330
+  fi
331
+  if [ -z "${NSXT_FLOATING_NET_CIDR}" ]; then
332
+    export NSXT_FLOATING_NET_CIDR='172.16.212.0/24'
333
+  fi
334
+  if [ -z "${NSXT_ROUTING_NET_CIDR}" ]; then
335
+    export NSXT_ROUTING_NET_CIDR='172.16.214.0/30'
336
+  fi
337
+  if [ -z "${NSXT_FLOATING_NET_GW}" ]; then
338
+    export NSXT_FLOATING_NET_GW='172.16.212.1'
339
+  fi
340
+  if [ -z "${NSXT_INTERNAL_NET_CIDR}" ]; then
341
+    export NSXT_INTERNAL_NET_CIDR='192.168.251.0/24'
342
+  fi
343
+  if [ -z "${NSXT_INTERNAL_NET_DNS}" ]; then
344
+    export NSXT_INTERNAL_NET_DNS='8.8.8.8'
345
+  fi
346
+
347
+  if [ ! -f "${DEVOPS_SETTINGS_TEMPLATE}" ]; then
348
+    if [ -z "${NODE_VOLUME_SIZE}" ]; then
349
+      export NODE_VOLUME_SIZE=350
350
+    fi
351
+    if [ -z "${ADMIN_NODE_MEMORY}" ]; then
352
+      export ADMIN_NODE_MEMORY=4096
353
+    fi
354
+    if [ -z "${ADMIN_NODE_CPU}" ]; then
355
+      export ADMIN_NODE_CPU=4
356
+    fi
357
+    if [ -z "${SLAVE_NODE_MEMORY}" ]; then
358
+      export SLAVE_NODE_MEMORY=4096
359
+    fi
360
+    if [ -z "${SLAVE_NODE_CPU}" ]; then
361
+      export SLAVE_NODE_CPU=4
362
+    fi
363
+  fi
364
+}
365
+
366
+CdWorkSpace() {
367
+    # chdir into workspace or fail if could not
368
+    if [ "${DRY_RUN}" != "yes" ]; then
369
+        cd "${WORKSPACE}"
370
+        ec=$?
371
+
372
+        if [ "${ec}" -gt "0" ]; then
373
+            echo "Error! Cannot cd to WORKSPACE!"
374
+            exit $CDWORKSPACE_ERR
375
+        fi
376
+    else
377
+        echo cd "${WORKSPACE}"
378
+    fi
379
+}
380
+
381
+RunTest() {
382
+    # Run test selected by task name
383
+
384
+    # check if iso file exists
385
+    if [ ! -f "${ISO_PATH}" ]; then
386
+        if [ -z "${ISO_URL}" -a "${DRY_RUN}" != "yes" ]; then
387
+            echo "Error! File ${ISO_PATH} not found and no ISO_URL (-U key) for downloading!"
388
+            exit $NOISOFOUND_ERR
389
+        else
390
+            if [ "${DRY_RUN}" = "yes" ]; then
391
+                echo wget -c ${ISO_URL} -O ${ISO_PATH}
392
+            else
393
+                echo "No ${ISO_PATH} found. Trying to download file."
394
+                wget -c ${ISO_URL} -O ${ISO_PATH}
395
+                rc=$?
396
+                if [ $rc -ne 0 ]; then
397
+                    echo "Failed to fetch ISO from ${ISO_URL}"
398
+                    exit $ISODOWNLOAD_ERR
399
+                fi
400
+            fi
401
+        fi
402
+    fi
403
+
404
+    if [ -z "${VENV_PATH}" ]; then
405
+        VENV_PATH="/home/jenkins/venv-nailgun-tests"
406
+    fi
407
+
408
+    # run python virtualenv
409
+    if [ "${VENV}" = "yes" ]; then
410
+        if [ "${DRY_RUN}" = "yes" ]; then
411
+            echo . $VENV_PATH/bin/activate
412
+        else
413
+            . $VENV_PATH/bin/activate
414
+        fi
415
+    fi
416
+
417
+    if [ "${ENV_NAME}" = "" ]; then
418
+      ENV_NAME="${JOB_NAME}_system_test"
419
+    fi
420
+
421
+    if [ "${LOGS_DIR}" = "" ]; then
422
+      LOGS_DIR="${WORKSPACE}/logs"
423
+    fi
424
+
425
+    if [ ! -f "$LOGS_DIR" ]; then
426
+      mkdir -p $LOGS_DIR
427
+    fi
428
+
429
+    export ENV_NAME
430
+    export LOGS_DIR
431
+    export ISO_PATH
432
+
433
+    if [ "${KEEP_BEFORE}" != "yes" ]; then
434
+      # remove previous environment
435
+      if [ "${DRY_RUN}" = "yes" ]; then
436
+        echo dos.py erase "${ENV_NAME}"
437
+      else
438
+        if dos.py list | grep -q "^${ENV_NAME}\$" ; then
439
+          dos.py erase "${ENV_NAME}"
440
+        fi
441
+      fi
442
+    fi
443
+
444
+    # gather additional option for this nose test run
445
+    OPTS=""
446
+    if [ -n "${NOSE_ATTR}" ]; then
447
+        OPTS="${OPTS} -a ${NOSE_ATTR}"
448
+    fi
449
+    if [ -n "${NOSE_EVAL_ATTR}" ]; then
450
+        OPTS="${OPTS} -A ${NOSE_EVAL_ATTR}"
451
+    fi
452
+    if [ -n "${TEST_OPTIONS}" ]; then
453
+        OPTS="${OPTS} ${TEST_OPTIONS}"
454
+    fi
455
+
456
+    clean_old_bridges
457
+
458
+    # run python test set to create environments, deploy and test product
459
+    if [ "${DRY_RUN}" = "yes" ]; then
460
+        echo export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}${WORKSPACE}"
461
+        echo python plugin_test/run_tests.py -q --nologcapture --with-xunit ${OPTS}
462
+    else
463
+        export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}${WORKSPACE}"
464
+        echo ${PYTHONPATH}
465
+        python plugin_test/run_tests.py -q --nologcapture --with-xunit ${OPTS} &
466
+
467
+    fi
468
+
469
+    SYSTEST_PID=$!
470
+
471
+    if ! ps -p $SYSTEST_PID > /dev/null
472
+    then
473
+	  echo System tests exited prematurely, aborting
474
+	  exit 1
475
+    fi
476
+
477
+    while [ "$(virsh net-list | grep -c $ENV_NAME)" -ne 5 ];do sleep 10
478
+	  if ! ps -p $SYSTEST_PID > /dev/null
479
+	  then
480
+	    echo System tests exited prematurely, aborting
481
+	    exit 1
482
+	  fi
483
+      done
484
+      sleep 10
485
+
486
+
487
+    # Configre vcenter nodes and interfaces
488
+    setup_net $ENV_NAME
489
+    clean_iptables
490
+    setup_stt $ENV_NAME
491
+    setup_external_net
492
+
493
+    revert_ws "$WORKSTATION_NODES" || { echo "killing $SYSTEST_PID and its childs" && pkill --parent $SYSTEST_PID && kill $SYSTEST_PID && exit 1; }
494
+
495
+    echo waiting for system tests to finish
496
+    wait $SYSTEST_PID
497
+
498
+    export RES=$?
499
+    echo ENVIRONMENT NAME is $ENV_NAME
500
+    virsh net-dumpxml ${ENV_NAME}_admin | grep -P "(\d+\.){3}" -o | awk '{print "Fuel master node IP: "$0"2"}'
501
+
502
+    if [ "${KEEP_AFTER}" != "yes" ]; then
503
+      # remove environment after tests
504
+      if [ "${DRY_RUN}" = "yes" ]; then
505
+        echo dos.py destroy "${ENV_NAME}"
506
+      else
507
+        dos.py destroy "${ENV_NAME}"
508
+      fi
509
+    fi
510
+
511
+    exit "${RES}"
512
+}
513
+
514
+RouteTasks() {
515
+  # this selector defines task names that are recognised by this script
516
+  # and runs corresponding jobs for them
517
+  # running any jobs should exit this script
518
+
519
+  case "${TASK_NAME}" in
520
+  test)
521
+    RunTest
522
+    ;;
523
+  *)
524
+    echo "Unknown task: ${TASK_NAME}!"
525
+    exit $INVALIDTASK_ERR
526
+    ;;
527
+  esac
528
+  exit 0
529
+}
530
+
531
+add_interface_to_bridge() {
532
+  env=$1
533
+  net_name=$2
534
+  nic=$3
535
+  ip=$4
536
+
537
+  for net in $(virsh net-list |grep ${env}_${net_name} |awk '{print $1}');do
538
+    bridge=$(virsh net-info $net |grep -i bridge |awk '{print $2}')
539
+    setup_bridge $bridge $nic $ip && echo $net_name bridge $bridge ready
540
+  done
541
+}
542
+
543
+setup_bridge() {
544
+  bridge=$1
545
+  nic=$2
546
+  ip=$3
547
+
548
+  sudo /sbin/brctl stp $bridge off
549
+  sudo /sbin/brctl addif $bridge $nic
550
+  # set if with existing ip down
551
+  for itf in $(sudo ip -o addr show to $ip | cut -d' ' -f2); do
552
+      echo deleting $ip from $itf
553
+      sudo ip addr del dev $itf $ip
554
+  done
555
+  echo adding $ip to $bridge
556
+  sudo /sbin/ip addr add $ip dev $bridge
557
+  echo $nic added to $bridge
558
+  sudo /sbin/ip link set dev $bridge up
559
+  if sudo /sbin/iptables-save |grep $bridge | grep -i reject| grep -q FORWARD; then
560
+    sudo /sbin/iptables -D FORWARD -o $bridge -j REJECT --reject-with icmp-port-unreachable
561
+    sudo /sbin/iptables -D FORWARD -i $bridge -j REJECT --reject-with icmp-port-unreachable
562
+  fi
563
+}
564
+
565
+clean_old_bridges() {
566
+  for intf in $WORKSTATION_IFS; do
567
+    for br in $(/sbin/brctl show | grep -v "bridge name" | cut -f1 -d'	'); do
568
+      /sbin/brctl show $br| grep -q $intf && sudo /sbin/brctl delif $br $intf \
569
+        && sudo /sbin/ip link set dev $br down && echo $intf deleted from $br
570
+    done
571
+  done
572
+}
573
+
574
+clean_iptables() {
575
+  sudo /sbin/iptables -F
576
+  sudo /sbin/iptables -t nat -F
577
+  sudo /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
578
+}
579
+
580
+revert_ws() {
581
+  for i in $1
582
+  do
583
+    vmrun -T ws-shared -h https://localhost:443/sdk -u $WORKSTATION_USERNAME -p $WORKSTATION_PASSWORD listRegisteredVM | grep -q $i || { echo "VM $i does not exist"; continue; }
584
+    echo vmrun: reverting $i to $WORKSTATION_SNAPSHOT
585
+    vmrun -T ws-shared -h https://localhost:443/sdk -u $WORKSTATION_USERNAME -p $WORKSTATION_PASSWORD revertToSnapshot "[standard] $i/$i.vmx" $WORKSTATION_SNAPSHOT || { echo "Error: revert of $i failed";  return 1; }
586
+  done
587
+
588
+  for i in $1
589
+  do
590
+    echo vmrun: starting $i
591
+    vmrun -T ws-shared -h https://localhost:443/sdk -u $WORKSTATION_USERNAME -p $WORKSTATION_PASSWORD start "[standard] $i/$i.vmx" || { echo "Error: $i failed to start";  return 1; }
592
+  done
593
+}
594
+
595
+setup_net() {
596
+  env=$1
597
+  add_interface_to_bridge $env public vmnet1 172.16.0.1/24
598
+}
599
+
600
+setup_stt() {
601
+  set -e
602
+  env=$1
603
+  net_name='private'
604
+  nic='vmnet2'
605
+
606
+  for net in $(virsh net-list |grep ${env}_${net_name} | awk '{print $1}');do
607
+    bridge=$(virsh net-info $net | grep -i bridge | awk '{print $2}')
608
+  done
609
+  sudo /sbin/brctl stp $bridge off
610
+  sudo /sbin/brctl addif $bridge $nic
611
+  echo $nic added to $bridge
612
+  sudo /sbin/ip link set dev $bridge up
613
+  if sudo /sbin/iptables-save | grep $bridge | grep -i reject| grep -q FORWARD; then
614
+    sudo /sbin/iptables -D FORWARD -o $bridge -j REJECT --reject-with icmp-port-unreachable
615
+    sudo /sbin/iptables -D FORWARD -i $bridge -j REJECT --reject-with icmp-port-unreachable
616
+  fi
617
+
618
+  echo "Stt added to $net_name bridge $bridge"
619
+}
620
+
621
+setup_external_net() {
622
+  nic='vmnet5'
623
+
624
+  ip=${NSXT_ROUTING_NET_CIDR%\.*}.1
625
+  gw_ip=${NSXT_ROUTING_NET_CIDR%\.*}.2
626
+  mask=${NSXT_ROUTING_NET_CIDR##*\/}
627
+
628
+  #set if with existing ip down
629
+  for itf in $(sudo ip -o addr show to $ip | cut -d' ' -f2); do
630
+      echo deleting $ip from $itf
631
+      sudo ip addr del $ip/$mask dev $itf
632
+  done
633
+
634
+  for itf in $(sudo ip -o ro show to ${NSXT_FLOATING_NET_CIDR} | cut -d' ' -f5); do
635
+      echo deleting route to ${NSXT_FLOATING_NET_CIDR} dev $itf
636
+      sudo ip ro del ${NSXT_FLOATING_NET_CIDR} dev $itf
637
+  done
638
+
639
+  set -e
640
+  sudo /sbin/ip addr add ${ip}/${mask} dev $nic
641
+  sudo /sbin/ip ro add ${NSXT_FLOATING_NET_CIDR} via ${gw_ip}
642
+  echo "Routing net added to $nic"
643
+}
644
+
645
+# MAIN
646
+
647
+# first we want to get variable from command line options
648
+GetoptsVariables "${@}"
649
+
650
+# then we define global variables and there defaults when needed
651
+GlobalVariables
652
+
653
+# check do we have all critical variables set
654
+CheckVariables
655
+
656
+# first we chdir into our working directory unless we dry run
657
+CdWorkSpace
658
+
659
+# finally we can choose what to do according to TASK_NAME
660
+RouteTasks

+ 58
- 60
spec/conf.py View File

@@ -1,29 +1,27 @@
1
-# -*- coding: utf-8 -*-
2
-#
3
-# Fuel NSXv plugin documentation build configuration file, created by
4
-# sphinx-quickstart on Fri Aug 14 12:14:29 2015.
5
-#
6
-# This file is execfile()d with the current directory set to its
7
-# containing dir.
8
-#
9
-# Note that not all possible configuration values are present in this
10
-# autogenerated file.
11
-#
12
-# All configuration values have a default; values that are commented out
13
-# serve to show the default.
1
+"""Copyright 2016 Mirantis, Inc.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+not use this file except in compliance with the License. You may obtain
5
+copy of the License at
6
+
7
+http://www.apache.org/licenses/LICENSE-2.0
14 8
 
15
-import sys
16
-import os
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+License for the specific language governing permissions and limitations
13
+under the License.
14
+"""
17 15
 
18 16
 # If extensions (or modules to document with autodoc) are in another directory,
19 17
 # add these directories to sys.path here. If the directory is relative to the
20 18
 # documentation root, use os.path.abspath to make it absolute, like shown here.
21
-#sys.path.insert(0, os.path.abspath('.'))
19
+# sys.path.insert(0, os.path.abspath('.'))
22 20
 
23 21
 # -- General configuration ------------------------------------------------
24 22
 
25 23
 # If your documentation needs a minimal Sphinx version, state it here.
26
-#needs_sphinx = '1.0'
24
+# needs_sphinx = '1.0'
27 25
 
28 26
 # Add any Sphinx extension module names here, as strings. They can be
29 27
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@@ -37,7 +35,7 @@ templates_path = ['_templates']
37 35
 source_suffix = '.rst'
38 36
 
39 37
 # The encoding of source files.
40
-#source_encoding = 'utf-8-sig'
38
+# source_encoding = 'utf-8-sig'
41 39
 
42 40
 # The master toctree document.
43 41
 master_doc = 'index'
@@ -57,13 +55,13 @@ release = '1.0.0'
57 55
 
58 56
 # The language for content autogenerated by Sphinx. Refer to documentation
59 57
 # for a list of supported languages.
60
-#language = None
58
+# language = None
61 59
 
62 60
 # There are two options for replacing |today|: either, you set today to some
63 61
 # non-false value, then it is used:
64
-#today = ''
62
+# today = ''
65 63
 # Else, today_fmt is used as the format for a strftime call.
66
-#today_fmt = '%B %d, %Y'
64
+# today_fmt = '%B %d, %Y'
67 65
 
68 66
 # List of patterns, relative to source directory, that match files and
69 67
 # directories to ignore when looking for source files.
@@ -71,27 +69,27 @@ exclude_patterns = ['_build']
71 69
 
72 70
 # The reST default role (used for this markup: `text`) to use for all
73 71
 # documents.
74
-#default_role = None
72
+# default_role = None
75 73
 
76 74
 # If true, '()' will be appended to :func: etc. cross-reference text.
77
-#add_function_parentheses = True
75
+# add_function_parentheses = True
78 76
 
79 77
 # If true, the current module name will be prepended to all description
80 78
 # unit titles (such as .. function::).
81
-#add_module_names = True
79
+# add_module_names = True
82 80
 
83 81
 # If true, sectionauthor and moduleauthor directives will be shown in the
84 82
 # output. They are ignored by default.
85
-#show_authors = False
83
+# show_authors = False
86 84
 
87 85
 # The name of the Pygments (syntax highlighting) style to use.
88 86
 pygments_style = 'sphinx'
89 87
 
90 88
 # A list of ignored prefixes for module index sorting.
91
-#modindex_common_prefix = []
89
+# modindex_common_prefix = []
92 90
 
93 91
 # If true, keep warnings as "system message" paragraphs in the built documents.
94
-#keep_warnings = False
92
+# keep_warnings = False
95 93
 
96 94
 
97 95
 # -- Options for HTML output ----------------------------------------------
@@ -103,26 +101,26 @@ html_theme = 'default'
103 101
 # Theme options are theme-specific and customize the look and feel of a theme
104 102
 # further.  For a list of options available for each theme, see the
105 103
 # documentation.
106
-#html_theme_options = {}
104
+# html_theme_options = {}
107 105
 
108 106
 # Add any paths that contain custom themes here, relative to this directory.
109
-#html_theme_path = []
107
+# html_theme_path = []
110 108
 
111 109
 # The name for this set of Sphinx documents.  If None, it defaults to
112 110
 # "<project> v<release> documentation".
113
-#html_title = None
111
+# html_title = None
114 112
 
115 113
 # A shorter title for the navigation bar.  Default is the same as html_title.
116
-#html_short_title = None
114
+# html_short_title = None
117 115
 
118 116
 # The name of an image file (relative to this directory) to place at the top
119 117
 # of the sidebar.
120
-#html_logo = None
118
+# html_logo = None
121 119
 
122 120
 # The name of an image file (within the static path) to use as favicon of the
123 121
 # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
124 122
 # pixels large.
125
-#html_favicon = None
123
+# html_favicon = None
126 124
 
127 125
 # Add any paths that contain custom static files (such as style sheets) here,
128 126
 # relative to this directory. They are copied after the builtin static files,
@@ -132,48 +130,48 @@ html_static_path = ['_static']
132 130
 # Add any extra paths that contain custom files (such as robots.txt or
133 131
 # .htaccess) here, relative to this directory. These files are copied
134 132
 # directly to the root of the documentation.
135
-#html_extra_path = []
133
+# html_extra_path = []
136 134
 
137 135
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
138 136
 # using the given strftime format.
139
-#html_last_updated_fmt = '%b %d, %Y'
137
+# html_last_updated_fmt = '%b %d, %Y'
140 138
 
141 139
 # If true, SmartyPants will be used to convert quotes and dashes to
142 140
 # typographically correct entities.
143
-#html_use_smartypants = True
141
+# html_use_smartypants = True
144 142
 
145 143
 # Custom sidebar templates, maps document names to template names.
146
-#html_sidebars = {}
144
+# html_sidebars = {}
147 145
 
148 146
 # Additional templates that should be rendered to pages, maps page names to
149 147
 # template names.
150
-#html_additional_pages = {}
148
+# html_additional_pages = {}
151 149
 
152 150
 # If false, no module index is generated.
153
-#html_domain_indices = True
151
+# html_domain_indices = True
154 152
 
155 153
 # If false, no index is generated.
156
-#html_use_index = True
154
+# html_use_index = True
157 155
 
158 156
 # If true, the index is split into individual pages for each letter.
159
-#html_split_index = False
157
+# html_split_index = False
160 158
 
161 159
 # If true, links to the reST sources are added to the pages.
162
-#html_show_sourcelink = True
160
+# html_show_sourcelink = True
163 161
 
164 162
 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
165
-#html_show_sphinx = True
163
+# html_show_sphinx = True
166 164
 
167 165
 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
168
-#html_show_copyright = True
166
+# html_show_copyright = True
169 167
 
170 168
 # If true, an OpenSearch description file will be output, and all pages will
171 169
 # contain a <link> tag referring to it.  The value of this option must be the
172 170
 # base URL from which the finished HTML is served.
173
-#html_use_opensearch = ''
171
+# html_use_opensearch = ''
174 172
 
175 173
 # This is the file name suffix for HTML files (e.g. ".xhtml").
176
-#html_file_suffix = None
174
+# html_file_suffix = None
177 175
 
178 176
 # Output file base name for HTML help builder.
179 177
 htmlhelp_basename = 'FuelNSXTplugindoc'
@@ -183,13 +181,13 @@ htmlhelp_basename = 'FuelNSXTplugindoc'
183 181
 
184 182
 latex_elements = {
185 183
 # The paper size ('letterpaper' or 'a4paper').
186
-#'papersize': 'letterpaper',
184
+# 'papersize': 'letterpaper',
187 185
 
188 186
 # The font size ('10pt', '11pt' or '12pt').
189
-#'pointsize': '10pt',
187
+# 'pointsize': '10pt',
190 188
 
191 189
 # Additional stuff for the LaTeX preamble.
192
-#'preamble': '',
190
+# 'preamble': '',
193 191
 }
194 192
 
195 193
 # Grouping the document tree into LaTeX files. List of tuples
@@ -202,23 +200,23 @@ latex_documents = [
202 200
 
203 201
 # The name of an image file (relative to this directory) to place at the top of
204 202
 # the title page.
205
-#latex_logo = None
203
+# latex_logo = None
206 204
 
207 205
 # For "manual" documents, if this is true, then toplevel headings are parts,
208 206
 # not chapters.
209
-#latex_use_parts = False
207
+# latex_use_parts = False
210 208
 
211 209
 # If true, show page references after internal links.
212
-#latex_show_pagerefs = False
210
+# latex_show_pagerefs = False
213 211
 
214 212
 # If true, show URL addresses after external links.
215
-#latex_show_urls = False
213
+# latex_show_urls = False
216 214
 
217 215
 # Documents to append as an appendix to all manuals.
218
-#latex_appendices = []
216
+# latex_appendices = []
219 217
 
220 218
 # If false, no module index is generated.
221
-#latex_domain_indices = True
219
+# latex_domain_indices = True
222 220
 
223 221
 
224 222
 # -- Options for manual page output ---------------------------------------
@@ -231,7 +229,7 @@ man_pages = [
231 229
 ]
232 230
 
233 231
 # If true, show URL addresses after external links.
234
-#man_show_urls = False
232
+# man_show_urls = False
235 233
 
236 234
 
237 235
 # -- Options for Texinfo output -------------------------------------------
@@ -246,13 +244,13 @@ texinfo_documents = [
246 244
 ]
247 245
 
248 246
 # Documents to append as an appendix to all manuals.
249
-#texinfo_appendices = []
247
+# texinfo_appendices = []
250 248
 
251 249
 # If false, no module index is generated.
252
-#texinfo_domain_indices = True
250
+# texinfo_domain_indices = True
253 251
 
254 252
 # How to display URL addresses: 'footnote', 'no', or 'inline'.
255
-#texinfo_show_urls = 'footnote'
253
+# texinfo_show_urls = 'footnote'
256 254
 
257 255
 # If true, do not generate a @detailmenu in the "Top" node's menu.
258
-#texinfo_no_detailmenu = False
256
+# texinfo_no_detailmenu = False

Loading…
Cancel
Save