blob: e581b86779be75d2592abf214dfac9cac2b91f39 [file] [log] [blame]
Artem Panchenko0594cd72017-06-12 13:25:26 +03001# Copyright 2017 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# a 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
15import pytest
Vladimir Jigulinee1faa52018-06-25 13:00:51 +040016import time
Artem Panchenko0594cd72017-06-12 13:25:26 +030017
18from tcp_tests.helpers import ext
Victor Ryzhenkin8ff3c3f2018-01-17 19:37:05 +040019from tcp_tests.helpers import utils
Artem Panchenko0594cd72017-06-12 13:25:26 +030020from tcp_tests import logger
21from tcp_tests.managers import k8smanager
22
23LOG = logger.logger
24
25
26@pytest.fixture(scope='function')
Dennis Dmitrievee5ef232018-08-31 13:53:18 +030027def k8s_actions(config, underlay_actions, salt_actions):
Artem Panchenko0594cd72017-06-12 13:25:26 +030028 """Fixture that provides various actions for K8S
29
30 :param config: fixture provides oslo.config
31 :param underlay: fixture provides underlay manager
32 :param salt_deployed: fixture provides salt manager
33 :rtype: K8SManager
34
35 For use in tests or fixtures to deploy a custom K8S
36 """
Dennis Dmitrievee5ef232018-08-31 13:53:18 +030037 return k8smanager.K8SManager(config, underlay_actions, salt_actions)
Artem Panchenko0594cd72017-06-12 13:25:26 +030038
39
40@pytest.mark.revert_snapshot(ext.SNAPSHOT.k8s_deployed)
41@pytest.fixture(scope='function')
42def k8s_deployed(revert_snapshot, request, config, hardware, underlay,
Dennis Dmitrievea48cf52018-07-18 18:04:39 +030043 core_deployed, salt_deployed, k8s_actions):
Artem Panchenko0594cd72017-06-12 13:25:26 +030044 """Fixture to get or install k8s on environment
45
46 :param revert_snapshot: fixture that reverts snapshot that is specified
47 in test with @pytest.mark.revert_snapshot(<name>)
48 :param request: fixture provides pytest data
49 :param config: fixture provides oslo.config
50 :param hardware: fixture provides enviromnet manager
51 :param underlay: fixture provides underlay manager
Dennis Dmitrievea48cf52018-07-18 18:04:39 +030052 :param core_deployed: fixture provides CoreManager
Artem Panchenko0594cd72017-06-12 13:25:26 +030053 :param k8s_actions: fixture provides K8SManager instance
54 :rtype: K8SManager
55
56 If config.k8s.k8s_installed is not set, this fixture assumes
57 that the k8s services were not installed, and do the following:
58 - install k8s services
59 - make snapshot with name 'k8s_deployed'
60 - return K8SManager instance
61
62 If config.k8s.k8s_installed was set, this fixture assumes that
63 the k8s services were already installed, and do the following:
64 - return K8SManager instance
65
66 If you want to revert 'k8s_deployed' snapshot, please use mark:
67 @pytest.mark.revert_snapshot("k8s_deployed")
68 """
69
70 # Deploy Kubernetes cluster
71 if not config.k8s.k8s_installed:
Vladimir Jigulinfbe2e5c2018-08-28 21:43:57 +040072 # Workaround for dhclient not killed on non-dhcp interfaces
73 # see https://mirantis.jira.com/browse/PROD-22473
74 tgt = 'I@kubernetes:pool'
75 LOG.warning('Killing dhclient on every non-dhcp interface '
76 'on nodes with target={}'.format(tgt))
77 interfaces_pillar = k8s_actions._salt.get_pillar(
78 tgt=tgt, pillar='linux:network:interface')[0]
79
80 for node_name, interfaces in interfaces_pillar.items():
81 for iface_name, iface in interfaces.items():
82 iface_name = iface.get('name', iface_name)
83 default_proto = 'static' if 'address' in iface else 'dhcp'
84 if iface.get('proto', default_proto) != 'dhcp':
85 LOG.warning('Trying to kill dhclient for iface {0} '
86 'on node {1}'.format(iface_name, node_name))
87 underlay.check_call(
88 cmd='pkill -f "dhclient.*{}"'.format(iface_name),
89 node_name=node_name, raise_on_err=False)
90
91 LOG.warning('Restarting keepalived service on controllers...')
92 k8s_actions._salt.local(tgt='ctl*', fun='cmd.run',
93 args='systemctl restart keepalived.service')
94 # give some time to keepalived to enter in MASTER state
95 time.sleep(3)
96 # --- end of workaround
97
98 # install k8s
Artem Panchenko0594cd72017-06-12 13:25:26 +030099 steps_path = config.k8s_deploy.k8s_steps_path
100 commands = underlay.read_template(steps_path)
101 k8s_actions.install(commands)
Vladimir Jigulinfbe2e5c2018-08-28 21:43:57 +0400102
Artem Panchenko0594cd72017-06-12 13:25:26 +0300103 hardware.create_snapshot(ext.SNAPSHOT.k8s_deployed)
Dennis Dmitrievb8115f52017-12-15 13:09:56 +0200104 salt_deployed.sync_time()
Artem Panchenko0594cd72017-06-12 13:25:26 +0300105
Artem Panchenko501e67e2017-06-14 14:59:18 +0300106 return k8s_actions
Victor Ryzhenkin8ff3c3f2018-01-17 19:37:05 +0400107
108
Dennis Dmitriev63f9c952018-01-25 02:07:00 +0200109@pytest.fixture(scope='function')
Dennis Dmitrievee5ef232018-08-31 13:53:18 +0300110def k8s_logs(request, func_name, k8s_actions):
Victor Ryzhenkincf26c932018-03-29 20:08:21 +0400111 """Finalizer to extract conformance logs
Victor Ryzhenkin8ff3c3f2018-01-17 19:37:05 +0400112
Victor Ryzhenkincf26c932018-03-29 20:08:21 +0400113 Usage:
114 @pytest.mark.grab_k8s_result(name=['file1', 'file2'])
115 ^^^^^
116 This mark says tcp-qa to download files that counted in array as
117 parameter 'name'. Files should be located at ctl01. Files will be
118 downloaded to the host, where your test runs.
119
120 @pytest.mark.extract(container_system='docker', extract_from='conformance',
121 files_to_extract=['report'])
122 ^^^^^
123 This mark says tcp-qa to copy files from container. Docker or k8s system
124 supported.
125 container_system param says function what strategy should be
126 used.
127 extract_from param says what container should be used to copy. Note
128 that we are using grep to determine container ID, so if you have multiple
129 container with same substring to copy you may encounter unexpected issues.
130 files_to_extract param - this is array with paths of files/dirs to copy.
131
132 @pytest.mark.merge_xunit(path='/root/report',
133 output='/root/conformance_result.xml')
134 ^^^^^
135 This mark will help you to merge xunit results in case if you have
136 multiple reports because of multiple threads.
137 path param says where xml results stored
138 output param says where result will be saved
139 """
140
141 grab_k8s_result = request.keywords.get('grab_k8s_results', None)
142 extract = request.keywords.get('extract', None)
143 merge_xunit = request.keywords.get('merge_xunit', None)
Victor Ryzhenkin8ff3c3f2018-01-17 19:37:05 +0400144
145 def test_fin():
146 if hasattr(request.node, 'rep_call') and \
147 (request.node.rep_call.passed or request.node.rep_call.failed)\
Victor Ryzhenkincf26c932018-03-29 20:08:21 +0400148 and grab_k8s_result:
149 files = utils.extract_name_from_mark(grab_k8s_result) \
Victor Ryzhenkin87a31422018-03-16 22:25:27 +0400150 or "{}".format(func_name)
Victor Ryzhenkincf26c932018-03-29 20:08:21 +0400151 if extract:
152 container_system = utils.extract_name_from_mark(
153 extract, 'container_system')
154 extract_from = utils.extract_name_from_mark(
155 extract, 'extract_from')
156 files_to_extract = utils.extract_name_from_mark(
157 extract, 'files_to_extract')
158 for path in files_to_extract:
Dennis Dmitrievee5ef232018-08-31 13:53:18 +0300159 k8s_actions.extract_file_to_node(
Victor Ryzhenkincf26c932018-03-29 20:08:21 +0400160 system=container_system, container=extract_from,
161 file_path=path)
162 else:
Dennis Dmitrievee5ef232018-08-31 13:53:18 +0300163 k8s_actions.extract_file_to_node()
Victor Ryzhenkincf26c932018-03-29 20:08:21 +0400164 if merge_xunit:
165 path = utils.extract_name_from_mark(merge_xunit, 'path')
166 output = utils.extract_name_from_mark(merge_xunit, 'output')
Dennis Dmitrievee5ef232018-08-31 13:53:18 +0300167 k8s_actions.combine_xunit(path, output)
168 k8s_actions.download_k8s_logs(files)
Victor Ryzhenkin87a31422018-03-16 22:25:27 +0400169
170 request.addfinalizer(test_fin)
171
172
173@pytest.fixture(scope='function')
Vladimir Jigulin0c8dd5a2018-08-28 05:08:35 +0400174def k8s_cncf_log_helper(request, func_name, underlay, k8s_deployed):
Victor Ryzhenkin87a31422018-03-16 22:25:27 +0400175 """Finalizer to prepare cncf tar.gz and save results from archive"""
176
177 cncf_publisher = request.keywords.get('cncf_publisher', None)
178
179 def test_fin():
180 if hasattr(request.node, 'rep_call') and \
181 (request.node.rep_call.passed or request.node.rep_call.failed)\
182 and cncf_publisher:
183 files = utils.extract_name_from_mark(cncf_publisher) \
184 or "{}".format(func_name)
185 k8s_deployed.extract_file_to_node(
186 system='k8s', file_path='tmp/sonobuoy',
Vladimir Jigulin0c8dd5a2018-08-28 05:08:35 +0400187 pod_name='sonobuoy', pod_namespace='heptio-sonobuoy'
Victor Ryzhenkin87a31422018-03-16 22:25:27 +0400188 )
189 k8s_deployed.manage_cncf_archive()
190 k8s_deployed.download_k8s_logs(files)
191
Victor Ryzhenkin8ff3c3f2018-01-17 19:37:05 +0400192 request.addfinalizer(test_fin)
Vladimir Jigulin62bcf462018-05-28 18:17:01 +0400193
194
195@pytest.fixture(scope='function')
196def k8s_chain_update_log_helper(request, config, k8s_deployed):
197 def test_fin():
198 if hasattr(request.node, 'rep_call') and \
199 (request.node.rep_call.passed or request.node.rep_call.failed):
200
201 chain_versions = config.k8s.k8s_update_chain.split(" ")
202 for version in chain_versions:
203 container_name = "k8s-conformance:{}".format(version)
204 tmp_report_dir = "/root/report_{}".format(version)
Vladimir Jigulin96bdcb02018-06-08 08:28:26 +0400205 report_path = "report_{}.xml".format(version)
Vladimir Jigulin62bcf462018-05-28 18:17:01 +0400206 conformance_log_path = "k8s_conformance_{}.log".format(version)
207
208 k8s_deployed.extract_file_to_node(
209 system='docker', container=container_name,
210 out_dir=tmp_report_dir, file_path='report'
211 )
Vladimir Jigulin96bdcb02018-06-08 08:28:26 +0400212 k8s_deployed.combine_xunit(tmp_report_dir,
213 '/root/{}'.format(report_path))
Vladimir Jigulin62bcf462018-05-28 18:17:01 +0400214
215 k8s_deployed.download_k8s_logs(
216 [report_path, conformance_log_path])
217
218 request.addfinalizer(test_fin)