Browse Source

Merge "Add test_agent_cleanup_with_control_node_stop"

Jenkins 2 years ago
parent
commit
71f5c0ae51

+ 17
- 0
plugin_test/vapor/vapor/fixtures/nodes.py View File

@@ -24,3 +24,20 @@ def computes(os_faults_steps):
24 24
     fqdns = settings.CONTRAIL_ROLES_DISTRIBUTION[
25 25
         settings.ROLE_CONTRAIL_COMPUTE]
26 26
     return os_faults_steps.get_nodes(fqdns)
27
+
28
+
29
+@pytest.fixture
30
+def stop_service(os_faults_steps):
31
+    """Callable fixture to stop service on nodes."""
32
+    stopped = []
33
+
34
+    def _stop_service(nodes, service):
35
+        cmd = "service {} stop".format(service)
36
+        os_faults_steps.execute_cmd(nodes, cmd)
37
+        stopped.append([nodes, service])
38
+
39
+    yield _stop_service
40
+
41
+    for nodes, service in reversed(stopped):
42
+        cmd = "service {} start".format(service)
43
+        os_faults_steps.execute_cmd(nodes, cmd)

+ 9
- 2
plugin_test/vapor/vapor/fixtures/skip.py View File

@@ -27,8 +27,8 @@ class Predicates(skip.Predicates):
27 27
     def vrouter_headless_mode(self):
28 28
         """Define whether vrouter headless mode enabled."""
29 29
         os_faults_steps = self._get_fixture('os_faults_steps')
30
-        fqdns = settings.CONTRAIL_ROLES_DISTRIBUTION[settings.
31
-                                                     ROLE_CONTRAIL_COMPUTE]
30
+        fqdns = settings.CONTRAIL_ROLES_DISTRIBUTION[
31
+            settings.ROLE_CONTRAIL_COMPUTE]
32 32
         actual_nodes = os_faults_steps.get_nodes_by_cmd(
33 33
             settings.VROUTER_HEADLESS_MODE_CMD)
34 34
         return set(actual_nodes.get_fqdns()) == set(fqdns)
@@ -41,6 +41,13 @@ class Predicates(skip.Predicates):
41 41
         sriov_device_mappings = sriov.get_sriov_device_mapping(agent_steps)
42 42
         return len(sriov_device_mappings) > 0
43 43
 
44
+    @property
45
+    @_store_call
46
+    def contrail_control_nodes_count(self):
47
+        """Return contrail control nodes count."""
48
+        return len(settings.CONTRAIL_ROLES_DISTRIBUTION[
49
+            settings.ROLE_CONTRAIL_CONTROLLER])
50
+
44 51
 
45 52
 @pytest.fixture
46 53
 def predicates(request):

+ 22
- 0
plugin_test/vapor/vapor/helpers/analytic_steps.py View File

@@ -65,6 +65,28 @@ def get_vna_xmpp_connection_status(session, ip, port):
65 65
     return result
66 66
 
67 67
 
68
+def get_vna_vm_list(session, ip, port):
69
+    """Return vna vm list."""
70
+    response = session.get(
71
+        'http://{ip}:{port}/Snh_VmListReq?uuid='.format(
72
+            ip=ip, port=port))
73
+    response.raise_for_status()
74
+    tree = ET.fromstring(response.content)
75
+    avn = tree.findall('.//list/VmSandeshData/uuid')
76
+    return [x.text for x in avn]
77
+
78
+
79
+def wait_vna_vm_list(session, ip, port, matcher, timeout):
80
+    """Wait until received vm_list will satisfy the macher."""
81
+
82
+    def predicate():
83
+        list_of_vm = get_vna_vm_list(session, ip, port)
84
+
85
+        return waiter.expect_that(list_of_vm, matcher)
86
+
87
+    waiter.wait(predicate, timeout_seconds=timeout)
88
+
89
+
68 90
 def get_processes_with_wrong_state(ops, module_id,
69 91
                                    expected_state='Functional'):
70 92
     """Return ops with wrong state for module_id."""

+ 32
- 12
plugin_test/vapor/vapor/helpers/asserts.py View File

@@ -75,37 +75,57 @@ class BaseSequencesMatcher(BaseMatcher):
75 75
         return not self._get_wrong_items(item)
76 76
 
77 77
 
78
-class IsSubsetOf(BaseSequencesMatcher):
78
+class SubsetOf(BaseSequencesMatcher):
79 79
 
80
-    def _get_wrong_items(self, item):
81
-        return self._get_extra_items(item, self.sequence)
80
+    def _get_wrong_items(self, other):
81
+        return self._get_extra_items(other, self.sequence)
82 82
 
83 83
     def describe_to(self, description):
84 84
         description.append_text('a subset of ').append_text(self.sequence)
85 85
 
86 86
     def describe_mismatch(self, item, mismatch_description):
87
-        super(IsSubsetOf, self).describe_mismatch(item, mismatch_description)
87
+        super(SubsetOf, self).describe_mismatch(item, mismatch_description)
88 88
         mismatch_description.append_text(' with unexpected items ') \
89 89
             .append_description_of(self._get_wrong_items(item))
90 90
 
91 91
 
92
-class IsSupersetOf(BaseSequencesMatcher):
92
+class SupersetOf(BaseSequencesMatcher):
93 93
 
94
-    def _get_wrong_items(self, item):
95
-        return self._get_extra_items(self.sequence, item)
94
+    def _get_wrong_items(self, other):
95
+        return self._get_extra_items(self.sequence, other)
96 96
 
97 97
     def describe_to(self, description):
98 98
         description.append_text('a superset of ').append_text(self.sequence)
99 99
 
100 100
     def describe_mismatch(self, item, mismatch_description):
101
-        super(IsSupersetOf, self).describe_mismatch(item, mismatch_description)
101
+        super(SupersetOf, self).describe_mismatch(item, mismatch_description)
102 102
         mismatch_description.append_text(' without expected items ') \
103 103
             .append_description_of(self._get_wrong_items(item))
104 104
 
105 105
 
106
-def is_subset_of(sequence):
107
-    return IsSubsetOf(sequence)
106
+class IntersectsWith(BaseSequencesMatcher):
107
+
108
+    def _matches(self, other):
109
+        for item in self.sequence:
110
+            if item in other:
111
+                return True
112
+        return False
113
+
114
+    def describe_to(self, description):
115
+        description.append_text(
116
+            'a sequence which intersect with ').append_text(self.sequence)
117
+
118
+
119
+def subset_of(other):
120
+    """Matches if sequence is subset of `other`."""
121
+    return SubsetOf(other)
122
+
123
+
124
+def superset_of(other):
125
+    """Matches if sequence is superset of `other`."""
126
+    return SupersetOf(other)
108 127
 
109 128
 
110
-def is_superset_of(sequence):
111
-    return IsSupersetOf(sequence)
129
+def intersects_with(other):
130
+    """Matches if sequence has intersections with `other`."""
131
+    return IntersectsWith(other)

+ 6
- 0
plugin_test/vapor/vapor/settings.py View File

@@ -47,6 +47,12 @@ PING_SUCCESS_TIMEOUT = 60 * 2
47 47
 # Security group apply timeout
48 48
 SECURITY_GROUP_APPLY_TIMEOUT = 20
49 49
 
50
+# Time to wait for contrail agent cleanup after stopping control node
51
+CONTRAIL_AGENT_CLEANUP_TIMEOUT = 20 * 60
52
+
53
+# Time to wait for contrail agent vna vm list to contain server uuid
54
+CONTRAIL_AGENT_VNA_VM_LIST_TIMEOUT = 3 * 60
55
+
50 56
 ROLE_CONTRAIL_CONTROLLER = 'contrail-controller'
51 57
 ROLE_CONTRAIL_ANALYTICS = 'contrail-analytics'
52 58
 ROLE_CONTRAIL_DB = 'contrail-db'

+ 2
- 2
plugin_test/vapor/vapor/tests/test_analytics.py View File

@@ -7,7 +7,7 @@ from six.moves import filter
7 7
 
8 8
 from vapor.helpers import analytic_steps
9 9
 from vapor.helpers import asserts
10
-from vapor.helpers.asserts import is_superset_of
10
+from vapor.helpers.asserts import superset_of
11 11
 from vapor import settings
12 12
 
13 13
 
@@ -242,7 +242,7 @@ def test_uve_module_states(client_contrail_analytics, os_faults_steps, role,
242 242
                 'NodeStatus.process_info[].process_name', data)
243 243
             process_list = [x.split(':')[0] for x in process_list]
244 244
             collector.check(process_list,
245
-                            is_superset_of(expected_process_list),
245
+                            superset_of(expected_process_list),
246 246
                             'Processes are absent on {}'.format(node))
247 247
             wrong_processes = analytic_steps.get_process_info_with_wrong_state(
248 248
                 data)

+ 91
- 0
plugin_test/vapor/vapor/tests/test_destructive.py View File

@@ -15,6 +15,8 @@ import pytest
15 15
 from stepler import config as stepler_config
16 16
 
17 17
 from vapor import settings
18
+from vapor.helpers.asserts import intersects_with
19
+from vapor.helpers import analytic_steps
18 20
 
19 21
 pytestmark = pytest.mark.destructive
20 22
 
@@ -139,3 +141,92 @@ def test_connectivity_after_contrail_services_restart(
139 141
     # Verify network creation
140 142
     network = request.getfixturevalue('contrail_network')
141 143
     assert_that(network.uuid, is_not(None))
144
+
145
+
146
+def test_agent_cleanup_with_control_node_stop(
147
+        session, nodes_ips, contrail_services_http_introspect_ports,
148
+        cirros_image, flavor, security_group, network, subnet, public_network,
149
+        create_floating_ip, stop_service, port_steps, server_steps,
150
+        os_faults_steps):
151
+    """Stop all the control node and verify the cleanup process in agent.
152
+
153
+    Steps:
154
+        #. Create network, subnet
155
+        #. Create 2 servers
156
+        #. Add floating IP addresses to servers
157
+        #. Check ping to servers' floating ips
158
+        #. Get servers' ids from contrail_vrouter_agent
159
+        #. Get contrail control nodes connected to this contrail_vrouter_agent
160
+        #. Stop `contrail-control` service on found nodes
161
+        #. Check that servers' ids list from contrail_vrouter_agent is not
162
+            contain servers ids after some time
163
+        #. Start `contrail-control` service on found nodes
164
+        #. Check that servers' ids list from contrail_vrouter_agent is contain
165
+            servers ids after some time
166
+        #. Check ping to servers' floating ips
167
+    """
168
+    # Create servers
169
+    servers = server_steps.create_servers(
170
+        count=2,
171
+        image=cirros_image,
172
+        flavor=flavor,
173
+        security_groups=[security_group],
174
+        networks=[network],
175
+        username=stepler_config.CIRROS_USERNAME,
176
+        password=stepler_config.CIRROS_PASSWORD)
177
+
178
+    # Create Floating IP
179
+    for server in servers:
180
+        server_port = port_steps.get_port(
181
+            device_owner=stepler_config.PORT_DEVICE_OWNER_SERVER,
182
+            device_id=server.id)
183
+
184
+        floating_ip = create_floating_ip(public_network, port=server_port)
185
+        server_steps.check_server_ip(
186
+            server,
187
+            floating_ip['floating_ip_address'],
188
+            timeout=settings.FLOATING_IP_BIND_TIMEOUT)
189
+
190
+    for server in servers:
191
+        server_steps.check_ping_to_server_floating(
192
+            server, timeout=stepler_config.PING_CALL_TIMEOUT)
193
+
194
+    servers_ids = [s.id for s in servers]
195
+    compute_fqdn = getattr(servers[0],
196
+                           settings.SERVER_ATTR_HYPERVISOR_HOSTNAME)
197
+    agent_ip = nodes_ips[compute_fqdn][0]
198
+    agent_port = contrail_services_http_introspect_ports[
199
+        'contrail-vrouter-agent']['port']
200
+
201
+    analytic_steps.wait_vna_vm_list(
202
+        session, agent_ip, agent_port,
203
+        intersects_with(servers_ids),
204
+        settings.CONTRAIL_AGENT_VNA_VM_LIST_TIMEOUT)
205
+
206
+    # Collecting control nodes
207
+    controllers_fqdns = []
208
+    for entry in analytic_steps.get_vna_xmpp_connection_status(
209
+            session, agent_ip, agent_port):
210
+        ip = entry['controller_ip']
211
+        fqdn = next(fqnd for fqnd, ips in nodes_ips.items() if ip in ips)
212
+        controllers_fqdns.append(fqdn)
213
+    controller_nodes = os_faults_steps.get_nodes(fqdns=controllers_fqdns)
214
+
215
+    # Stop contrail-control service
216
+    stop_service(controller_nodes, 'contrail-control')
217
+
218
+    analytic_steps.wait_vna_vm_list(session, agent_ip, agent_port,
219
+                                    is_not(intersects_with(servers_ids)),
220
+                                    settings.CONTRAIL_AGENT_CLEANUP_TIMEOUT)
221
+
222
+    os_faults_steps.execute_cmd(controller_nodes,
223
+                                'service contrail-control start')
224
+
225
+    analytic_steps.wait_vna_vm_list(
226
+        session, agent_ip, agent_port,
227
+        intersects_with(servers_ids),
228
+        settings.CONTRAIL_AGENT_VNA_VM_LIST_TIMEOUT)
229
+
230
+    for server in servers:
231
+        server_steps.check_ping_to_server_floating(
232
+            server, timeout=stepler_config.PING_CALL_TIMEOUT)

+ 2
- 2
plugin_test/vapor/vapor/tests/test_smoke.py View File

@@ -19,7 +19,7 @@ from stepler.third_party import utils
19 19
 
20 20
 from vapor.helpers import contrail_status
21 21
 from vapor.helpers import asserts
22
-from vapor.helpers.asserts import is_superset_of
22
+from vapor.helpers.asserts import superset_of
23 23
 from vapor import settings
24 24
 
25 25
 
@@ -38,7 +38,7 @@ def test_contrail_service_distribution(os_faults_steps, role):
38 38
             if node not in nodes:
39 39
                 continue
40 40
             services = [x.service for x in services]
41
-            collector.check(services, is_superset_of(expected_services))
41
+            collector.check(services, superset_of(expected_services))
42 42
 
43 43
 
44 44
 def test_ifmap_service(os_faults_steps):

Loading…
Cancel
Save