blob: 67499b89bc89bcd15efff675b2da29d05af8fc0f [file] [log] [blame]
Hanna Arhipova71ecc272019-08-20 14:54:22 +03001import pytest
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +03002import sys
3import os
Hanna Arhipova71ecc272019-08-20 14:54:22 +03004
5from tcp_tests import logger
6from tcp_tests import settings
Hanna Arhipova71ecc272019-08-20 14:54:22 +03007
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +03008sys.path.append(os.getcwd())
9try:
10 from tcp_tests.fixtures import config_fixtures
11 from tcp_tests.managers import underlay_ssh_manager
12 from tcp_tests.managers import saltmanager as salt_manager
13except ImportError:
14 print("ImportError: Run the application from the tcp-qa directory or "
15 "set the PYTHONPATH environment variable to directory which contains"
16 " ./tcp_tests")
17 sys.exit(1)
Hanna Arhipova71ecc272019-08-20 14:54:22 +030018LOG = logger.logger
19
20
Hanna Arhipovad35a29b2019-09-04 13:24:06 +030021def has_only_similar(values_by_nodes):
22 """
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +030023 :param values_by_nodes: dict
Hanna Arhipovad35a29b2019-09-04 13:24:06 +030024 :return: bool, True if all items in the dict have similar values
25 """
26 values = list(values_by_nodes.values())
27 return all(value == values[0] for value in values)
28
29
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +030030def get_control_plane_targets():
31 config = config_fixtures.config()
32 underlay = underlay_ssh_manager.UnderlaySSHManager(config)
33 saltmanager = salt_manager.SaltManager(config, underlay)
34
35 targets = saltmanager.run_state(
36 "I@keystone:server", 'test.ping')[0]['return'][0].keys()
37 targets += saltmanager.run_state(
38 "I@nginx:server and not I@salt:master",
39 "test.ping")[0]['return'][0].keys()
40
41 # TODO: add check for Manila existence
42 # # Commented to avoid fails during OpenStack updates.
43 # # Anyway we don't have deployments with Manila yet
44 # targets.append('share*')
45 # TODO: add check for Tenant Telemetry existence
46 targets.append('mdb*')
47 # TODO: add check for Barbican existence
48 targets.append('kmn*')
49 return targets
50
51
52@pytest.fixture
53def switch_to_proposed_pipelines(reclass_actions, salt_actions):
54 reclass_actions.add_key(
55 "parameters._param.jenkins_pipelines_branch",
56 "release/proposed/2019.2.0",
57 "cluster/*/infra/init.yml"
58 )
59 salt_actions.enforce_state("I@jenkins:client", "jenkins.client")
60
61
Hanna Arhipova71ecc272019-08-20 14:54:22 +030062class TestUpdateMcpCluster(object):
63 """
64 Following the steps in
Hanna Arhipova94a8abe2019-08-22 14:11:46 +030065 https://docs.mirantis.com/mcp/master/mcp-operations-guide/update-upgrade/minor-update.html#minor-update
Hanna Arhipova71ecc272019-08-20 14:54:22 +030066 """
67
68 @pytest.mark.grab_versions
69 @pytest.mark.parametrize("_", [settings.ENV_NAME])
70 @pytest.mark.run_mcp_update
Hanna Arhipova17b2c102019-09-06 16:44:17 +030071 def test_update_drivetrain(self, salt_actions, drivetrain_actions,
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +030072 show_step, _, switch_to_proposed_pipelines):
Hanna Arhipova71ecc272019-08-20 14:54:22 +030073 """Updating DriveTrain component to release/proposed/2019.2.0 version
74
75 Scenario:
Hanna Arhipova17b2c102019-09-06 16:44:17 +030076 1. Add workaround for PROD-32751
Hanna Arhipova71ecc272019-08-20 14:54:22 +030077 2. Run job git-mirror-downstream-mk-pipelines
78 3. Run job git-mirror-downstream-pipeline-library
79 4. If jobs are passed then start 'Deploy - upgrade MCP Drivetrain'
80
Hanna Arhipovad35a29b2019-09-04 13:24:06 +030081 Duration: ~70 min
Hanna Arhipova71ecc272019-08-20 14:54:22 +030082 """
83 salt = salt_actions
Hanna Arhipova17b2c102019-09-06 16:44:17 +030084 dt = drivetrain_actions
Hanna Arhipova71ecc272019-08-20 14:54:22 +030085
Hanna Arhipova17b2c102019-09-06 16:44:17 +030086 # #################### Add workaround for PROD-32751 #################
Hanna Arhipova71ecc272019-08-20 14:54:22 +030087 show_step(1)
88
Hanna Arhipova71ecc272019-08-20 14:54:22 +030089 # FIXME: workaround for PROD-32751
90 salt.cmd_run("cfg01*", "cd /srv/salt/reclass; git add -u && \
91 git commit --allow-empty -m 'Cluster model update'")
92
93 # ################### Downstream mk-pipelines #########################
94 show_step(2)
95 job_name = 'git-mirror-downstream-mk-pipelines'
96 job_parameters = {
97 'BRANCHES': 'release/proposed/2019.2.0'
98 }
Hanna Arhipova17b2c102019-09-06 16:44:17 +030099 update_pipelines = dt.start_job_on_cid_jenkins(
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300100 job_name=job_name,
101 job_parameters=job_parameters)
102
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300103 assert update_pipelines == 'SUCCESS'
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300104
105 # ################### Downstream pipeline-library ####################
106 show_step(3)
107 job_name = 'git-mirror-downstream-pipeline-library'
108 job_parameters = {
109 'BRANCHES': 'release/proposed/2019.2.0'
110 }
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300111 update_pipeline_library = dt.start_job_on_cid_jenkins(
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300112 job_name=job_name,
113 job_parameters=job_parameters)
114
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300115 assert update_pipeline_library == 'SUCCESS'
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300116
117 # ################### Start 'Deploy - upgrade MCP Drivetrain' job #####
118 show_step(4)
119
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300120 job_name = 'upgrade-mcp-release'
121 job_parameters = {
Hanna Arhipovad35a29b2019-09-04 13:24:06 +0300122 'GIT_REFSPEC': 'release/proposed/2019.2.0',
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300123 'MK_PIPELINES_REFSPEC': 'release/proposed/2019.2.0',
124 'TARGET_MCP_VERSION': '2019.2.0'
125 }
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300126 update_drivetrain = dt.start_job_on_cid_jenkins(
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300127 job_name=job_name,
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300128 job_parameters=job_parameters,
Hanna Arhipovad35a29b2019-09-04 13:24:06 +0300129 build_timeout=90*60)
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300130
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300131 assert update_drivetrain == 'SUCCESS'
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300132
Hanna Arhipova94a8abe2019-08-22 14:11:46 +0300133 @pytest.mark.grab_versions
134 @pytest.mark.parametrize("_", [settings.ENV_NAME])
Hanna Arhipova71ecc272019-08-20 14:54:22 +0300135 @pytest.mark.run_mcp_update
Hanna Arhipovacc3759b2019-08-28 16:01:11 +0300136 def test_update_glusterfs(self, salt_actions, reclass_actions,
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300137 drivetrain_actions, show_step, _):
Hanna Arhipovacc3759b2019-08-28 16:01:11 +0300138 """ Upgrade GlusterFS
139 Scenario:
140 1. In infra/init.yml in Reclass, add the glusterfs_version parameter
141 2. Start linux.system.repo state
142 3. Start "update-glusterfs" job
143 4. Check version for GlusterFS servers
144 5. Check version for GlusterFS clients
145
146 """
147 salt = salt_actions
148 reclass = reclass_actions
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300149 dt = drivetrain_actions
Hanna Arhipovacc3759b2019-08-28 16:01:11 +0300150
Hanna Arhipovacc3759b2019-08-28 16:01:11 +0300151 # ############## Change reclass ######################################
152 show_step(1)
153 reclass.add_key(
154 "parameters._param.linux_system_repo_mcp_glusterfs_version_number",
155 "5",
156 "cluster/*/infra/init.yml"
157 )
158 # ################# Run linux.system state ###########################
159 show_step(2)
160 salt.enforce_state("*", "linux.system.repo")
161
162 # ############## Start deploy-upgrade-galera job #####################
163 show_step(3)
Hanna Arhipovacc3759b2019-08-28 16:01:11 +0300164 job_name = 'update-glusterfs'
165
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300166 update_glusterfs = dt.start_job_on_cid_jenkins(
Hanna Arhipovacc3759b2019-08-28 16:01:11 +0300167 job_name=job_name,
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300168 build_timeout=40 * 60)
Hanna Arhipovacc3759b2019-08-28 16:01:11 +0300169
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300170 assert update_glusterfs == 'SUCCESS'
Hanna Arhipovacc3759b2019-08-28 16:01:11 +0300171
172 # ################ Check GlusterFS version for servers ##############
173 show_step(4)
174 gluster_server_versions_by_nodes = salt.cmd_run(
175 "I@glusterfs:server",
176 "glusterd --version|head -n1")[0]
177
178 assert has_only_similar(gluster_server_versions_by_nodes),\
179 gluster_server_versions_by_nodes
180
181 # ################ Check GlusterFS version for clients ##############
182 show_step(5)
183 gluster_client_versions_by_nodes = salt.cmd_run(
184 "I@glusterfs:client",
185 "glusterfs --version|head -n1")[0]
186
187 assert has_only_similar(gluster_client_versions_by_nodes), \
188 gluster_client_versions_by_nodes
189
190 @pytest.mark.grab_versions
191 @pytest.mark.parametrize("_", [settings.ENV_NAME])
192 @pytest.mark.run_mcp_update
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300193 def test_update_galera(self, salt_actions, reclass_actions,
194 drivetrain_actions, show_step, _):
Hanna Arhipova94a8abe2019-08-22 14:11:46 +0300195 """ Upgrade Galera automatically
196
197 Scenario:
198 1. Include the Galera upgrade pipeline job to DriveTrain
199 2. Apply the jenkins.client state on the Jenkins nodes
200 3. set the openstack_upgrade_enabled parameter to true
201 4. Refresh pillars
202 5. Add repositories with new Galera packages
203 6. Start job from Jenkins
204 """
205 salt = salt_actions
206 reclass = reclass_actions
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300207 dt = drivetrain_actions
Hanna Arhipova94a8abe2019-08-22 14:11:46 +0300208 # ################### Enable pipeline #################################
209 show_step(1)
210 reclass.add_class(
211 "system.jenkins.client.job.deploy.update.upgrade_galera",
212 "cluster/*/cicd/control/leader.yml")
213 show_step(2)
214 salt.enforce_state("I@jenkins:client", "jenkins.client")
215
216 # ############### Enable automatic upgrade ############################
217 show_step(3)
218 reclass.add_bool_key("parameters._param.openstack_upgrade_enabled",
219 "True",
220 "cluster/*/infra/init.yml")
221
222 show_step(4)
223 salt.enforce_state("dbs*", "saltutil.refresh_pillar")
224
225 # ############# Add repositories with new Galera packages #######
226 show_step(5)
227 salt.enforce_state("dbs*", "linux.system.repo")
228 salt.enforce_state("cfg*", "salt.master")
229
Hanna Arhipova94a8abe2019-08-22 14:11:46 +0300230 # #################### Login Jenkins on cid01 node ###################
231 show_step(6)
232
Hanna Arhipova94a8abe2019-08-22 14:11:46 +0300233 job_name = 'deploy-upgrade-galera'
234 job_parameters = {
235 'INTERACTIVE': 'false'
236 }
237
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300238 update_galera = dt.start_job_on_cid_jenkins(
Hanna Arhipova94a8abe2019-08-22 14:11:46 +0300239 job_name=job_name,
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300240 job_parameters=job_parameters,
241 build_timeout=40 * 60)
Hanna Arhipova94a8abe2019-08-22 14:11:46 +0300242
Hanna Arhipova17b2c102019-09-06 16:44:17 +0300243 assert update_galera == 'SUCCESS'
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300244
245 @pytest.fixture
246 def disable_automatic_failover_neutron_for_test(self, salt_actions):
247 """
248 On each OpenStack controller node, modify the neutron.conf file
249 Restart the neutron-server service
250 """
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300251 def comment_line(node, file_name, word):
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300252 """
253 Adds '#' before the specific line in specific file
254
255 :param node: string, salt target of node where the file locates
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300256 :param file_name: string, full path to the file
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300257 :param word: string, the begin of line which should be commented
258 :return: None
259 """
260 salt_actions.cmd_run(node,
261 "sed -i 's/^{word}/#{word}/' {file}".
262 format(word=word,
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300263 file=file_name))
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300264
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300265 def add_line(node, file_name, line):
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300266 """
267 Appends line to the end of file
268
269 :param node: string, salt target of node where the file locates
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300270 :param file_name: string, full path to the file
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300271 :param line: string, line that should be added
272 :return: None
273 """
274 salt_actions.cmd_run(node, "echo {line} >> {file}".format(
275 line=line,
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300276 file=file_name))
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300277
278 neutron_conf = '/etc/neutron/neutron.conf'
279 neutron_server = "I@neutron:server"
280 # ######## Create backup for config file #######################
281 salt_actions.cmd_run(
282 neutron_server,
283 "cp -p {file} {file}.backup".format(file=neutron_conf))
284
285 # ## Change parameters in neutron.conf'
286 comment_line(neutron_server, neutron_conf,
287 "allow_automatic_l3agent_failover",)
288 comment_line(neutron_server, neutron_conf,
289 "allow_automatic_dhcp_failover")
290 add_line(neutron_server, neutron_conf,
291 "allow_automatic_dhcp_failover = false")
292 add_line(neutron_server, neutron_conf,
293 "allow_automatic_l3agent_failover = false")
294
295 # ## Apply changed config to the neutron-server service
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300296 result = salt_actions.cmd_run(neutron_server,
297 "service neutron-server restart")
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300298 # TODO: add check that neutron-server is up and running
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300299 yield result
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300300 # ## Revert file changes
301 salt_actions.cmd_run(
302 neutron_server,
303 "cp -p {file}.backup {file}".format(file=neutron_conf))
304 salt_actions.cmd_run(neutron_server,
305 "service neutron-server restart")
306
307 @pytest.fixture
308 def disable_neutron_agents_for_test(self, salt_actions):
309 """
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300310 Disable the neutron services before the test and
311 enable it after test
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300312 """
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300313 result = salt_actions.cmd_run("I@neutron:server", """
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300314 service neutron-dhcp-agent stop && \
315 service neutron-l3-agent stop && \
316 service neutron-metadata-agent stop && \
317 service neutron-openvswitch-agent stop
318 """)
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300319 yield result
320 #
Hanna Arhipova1fcaf442019-09-06 15:30:45 +0300321 salt_actions.cmd_run("I@neutron:server", """
322 service neutron-dhcp-agent start && \
323 service neutron-l3-agent start && \
324 service neutron-metadata-agent start && \
325 service neutron-openvswitch-agent start
326 """)
327 # TODO: add check that all services are UP and running
328
329 @pytest.mark.grab_versions
330 @pytest.mark.parametrize("_", [settings.ENV_NAME])
331 @pytest.mark.run_mcp_update
332 def test_update_rabbit(self, salt_actions, reclass_actions,
333 drivetrain_actions, show_step, _,
334 disable_automatic_failover_neutron_for_test,
335 disable_neutron_agents_for_test):
336 """ Updates RabbitMQ
337 Scenario:
338 1. Include the RabbitMQ upgrade pipeline job to DriveTrain
339 2. Add repositories with new RabbitMQ packages
340 3. Start Deploy - upgrade RabbitMQ pipeline
341
342 Updating RabbitMq should be completed before the OpenStack updating
343 process starts
344 """
345 salt = salt_actions
346 reclass = reclass_actions
347 dt = drivetrain_actions
348
349 # ####### Include the RabbitMQ upgrade pipeline job to DriveTrain ####
350 show_step(1)
351 reclass.add_class(
352 "system.jenkins.client.job.deploy.update.upgrade_rabbitmq",
353 "cluster/*/cicd/control/leader.yml")
354 salt.enforce_state("I@jenkins:client", "jenkins.client")
355
356 reclass.add_bool_key("parameters._param.openstack_upgrade_enabled",
357 "True",
358 "cluster/*/infra/init.yml")
359 salt.run_state("I@rabbitmq:server", "saltutil.refresh_pillar")
360
361 # ########### Add repositories with new RabbitMQ packages ############
362 show_step(2)
363 salt.enforce_state("I@rabbitmq:server", "linux.system.repo")
364
365 # ########### Start Deploy - upgrade RabbitMQ pipeline ############
366 show_step(3)
367 job_parameters = {
368 'INTERACTIVE': 'false'
369 }
370
371 update_rabbit = dt.start_job_on_cid_jenkins(
372 job_name='deploy-upgrade-rabbitmq',
373 job_parameters=job_parameters,
374 build_timeout=40 * 60
375 )
376 assert update_rabbit == 'SUCCESS'
Hanna Arhipovad35a29b2019-09-04 13:24:06 +0300377
378 @pytest.mark.grab_versions
379 @pytest.mark.parametrize("_", [settings.ENV_NAME])
380 @pytest.mark.run_mcp_update
381 def test_update_ceph(self, salt_actions, drivetrain_actions, show_step, _):
382 """ Updates Ceph to the latest minor version
383
384 Scenario:
385 1. Add workaround for unhealth Ceph
386 2. Start ceph-upgrade job with default parameters
387 3. Check Ceph version for all nodes
388
389 https://docs.mirantis.com/mcp/master/mcp-operations-guide/update-upgrade/minor-update/ceph-update.html
390 """
391 salt = salt_actions
392 dt = drivetrain_actions
393
394 # ###################### Add workaround for unhealth Ceph ############
395 show_step(1)
396 salt.cmd_run("I@ceph:radosgw",
397 "ceph config set 'mon pg warn max object skew' 20")
398 # ###################### Start ceph-upgrade pipeline #################
399 show_step(2)
400 job_parameters = {}
401
402 update_ceph = dt.start_job_on_cid_jenkins(
403 job_name='ceph-update',
404 job_parameters=job_parameters)
405
406 assert update_ceph == 'SUCCESS'
407
408 # ########## Verify Ceph version #####################################
409 show_step(3)
410
411 ceph_version_by_nodes = salt.cmd_run(
412 "I@ceph:* and not I@ceph:monitoring and not I@ceph:backup:server",
413 "ceph version")[0]
414
415 assert has_only_similar(ceph_version_by_nodes), ceph_version_by_nodes
Hanna Arhipovaeb3a2112019-09-13 18:45:21 +0300416
417
418class TestOpenstackUpdate(object):
419
420 @pytest.mark.grab_versions
421 @pytest.mark.run_mcp_update
422 def test__pre_update__enable_pipeline_job(self,
423 reclass_actions, salt_actions,
424 show_step):
425 """ Enable pipeline in the Drivetrain
426
427 Scenario:
428 1. Add deploy.update.* classes to the reclass
429 2. Start jenkins.client salt state
430
431 """
432 salt = salt_actions
433 reclass = reclass_actions
434 show_step(1)
435 reclass.add_class("system.jenkins.client.job.deploy.update.upgrade",
436 "cluster/*/cicd/control/leader.yml")
437
438 reclass.add_class(
439 "system.jenkins.client.job.deploy.update.upgrade_ovs_gateway",
440 "cluster/*/cicd/control/leader.yml")
441
442 reclass.add_class(
443 "system.jenkins.client.job.deploy.update.upgrade_compute",
444 "cluster/*/cicd/control/leader.yml")
445
446 show_step(2)
447 r, errors = salt.enforce_state("I@jenkins:client", "jenkins.client")
448 assert errors is None
449
450 @pytest.mark.grab_versions
451 @pytest.mark.parametrize('target', get_control_plane_targets())
452 @pytest.mark.run_mcp_update
453 def test__update__control_plane(self, drivetrain_actions,
454 switch_to_proposed_pipelines, target):
455 """Start 'Deploy - upgrade control VMs' for specific node
456 """
457 job_parameters = {
458 "TARGET_SERVERS": target,
459 "INTERACTIVE": False}
460 upgrade_control_pipeline = drivetrain_actions.start_job_on_cid_jenkins(
461 job_name="deploy-upgrade-control",
462 job_parameters=job_parameters)
463
464 assert upgrade_control_pipeline == 'SUCCESS'
465
466 @pytest.mark.grab_versions
467 @pytest.mark.run_mcp_update
468 def test__update__data_plane(self, drivetrain_actions):
469 """Start 'Deploy - upgrade OVS gateway'
470 """
471 job_parameters = {
472 "INTERACTIVE": False}
473 upgrade_data_pipeline = drivetrain_actions.start_job_on_cid_jenkins(
474 job_name="deploy-upgrade-ovs-gateway",
475 job_parameters=job_parameters)
476
477 assert upgrade_data_pipeline == 'SUCCESS'