blob: ab7e5f3bdd5dc22e7e461b254b9a2ff13baa0d67 [file] [log] [blame]
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +00001import pytest
2import json
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +03003import utils
Hanna Arhipova56eab942019-05-06 20:14:18 +03004import logging
Hanna Arhipova2d538412021-08-17 10:44:41 +03005import itertools
6from functools import lru_cache
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +03007
Hanna Arhipova2d538412021-08-17 10:44:41 +03008
9@lru_cache(maxsize=32)
10def targeted_minions(target):
11 """
12 Returns nodes associated with salt target
13 :param target: str, salt target in COMPOUND notation like I@nova:server
14 More here https://docs.saltproject.io/en/latest/topics/targeting/compound.html
15 :return: list of nodes or []
16 """
17 salt_client = pytest.local_salt_client
18 return list(salt_client.test_ping(
19 tgt=target,
20 expr_form='compound'))
21
22
23def is_deb_in_exception(inconsistency_rule, package_name, node_hostname):
24 for salt_target, excluded_packages in inconsistency_rule.items():
25 if package_name in excluded_packages \
26 and node_hostname in targeted_minions(salt_target):
Ekaterina Chernovab4806752019-07-26 16:02:18 +030027 return True
28 return False
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000029
Hanna Arhipova2d538412021-08-17 10:44:41 +030030
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -050031@pytest.mark.full
Oleksii Zhurbad0ae87f2018-03-26 13:36:25 -050032def test_check_package_versions(local_salt_client, nodes_in_group):
Ekaterina Chernovab4806752019-07-26 16:02:18 +030033 """Validate package has same versions on all the nodes.
34 Steps:
35 1) Collect packages for nodes_in_group
36 "salt -C '<group_of_nodes>' cmd.run 'lowpkg.list_pkgs'"
37 2) Exclude nodes without packages and exceptions
Ekaterina Chernova7ea97152019-07-29 17:09:12 +030038 3) Go through each package and save it with version from each node to the
Ekaterina Chernovab4806752019-07-26 16:02:18 +030039 list. Mark 'No version' if package is not found.
Hanna Arhipova2d538412021-08-17 10:44:41 +030040 If package name in the exception list or in inconsistency_rule,
41 ignore it.
Hanna Arhipova035dea42021-08-19 12:24:08 +030042 4) Compare items in that list - they should be equal and match the
43 amount of nodes
Ekaterina Chernovab4806752019-07-26 16:02:18 +030044
45 """
Hanna Arhipova2d538412021-08-17 10:44:41 +030046 salt = local_salt_client
47 # defines packages specific to the nodes
48 inconsistency_rule = {
49 "I@backupninja:server": [
50 "rsync", "sysstat", "xz-utils"],
51 "I@elasticsearch:server": [
52 "python-elasticsearch"],
53 # PROD-30833
54 "I@octavia:manager:controller_worker:loadbalancer_topology:SINGLE": [
55 "netfilter-persistent",
56 "gunicorn",
57 "octavia-worker",
58 "octavia-health-manager",
Hanna Arhipovaae2e05b2021-08-18 10:47:39 +030059 "octavia-housekeeping",
Hanna Arhipovafb3bc582021-09-22 14:30:52 +030060 "python-castellan",
Hanna Arhipovaae2e05b2021-08-18 10:47:39 +030061 'python-automaton',
62 'python-setproctitle',
63 'python-glanceclient',
64 'libnss3-nssdb',
65 'python-json-pointer',
66 'debootstrap',
67 'python-cotyledon',
68 'librbd1',
69 'qemu-block-extra:amd64',
70 'python-diskimage-builder',
71 'liburcu4:amd64',
72 'python-networkx',
73 'librados2',
74 'kpartx',
75 'python-taskflow',
76 'libnss3:amd64',
77 'libibverbs1',
78 'python-itsdangerous',
79 'liblttng-ust0:amd64',
80 'python-wsme',
81 'python-werkzeug',
82 'liblttng-ust-ctl2:amd64',
83 'python-gunicorn',
84 'python-octavia',
85 'python-warlock',
86 'python-barbicanclient',
87 'iptables-persistent',
88 'python-psycopg2',
89 'octavia-common',
90 'python-flask',
91 'libpq5:amd64',
92 'python-dib-utils',
93 'python-jsonpatch',
94 'libnspr4:amd64',
95 'qemu-utils',
96 'python-pyasn1-modules',
97 'libonig2:amd64',
98 'jq',
99 'libaio1:amd64',
100 'python-kazoo',
101 'python-ipaddr',
102 'libiscsi2:amd64']
Hanna Arhipova035dea42021-08-19 12:24:08 +0300103 }
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200104 exclude_packages = utils.get_configuration().get("skipped_packages", [])
Hanna Arhipova2d538412021-08-17 10:44:41 +0300105
106 group_name, nodes = nodes_in_group
107 packages_versions_by_nodes = salt.cmd(tgt="L@"+','.join(nodes),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500108 fun='lowpkg.list_pkgs',
109 expr_form='compound')
Oleksii Zhurbadad1acc2018-03-26 14:09:38 -0500110 # Let's exclude cid01 and dbs01 nodes from this check
Hanna Arhipova2d538412021-08-17 10:44:41 +0300111 exclude_nodes = targeted_minions("I@galera:master or I@gerrit:client")
Oleksii Zhurba599801a2019-06-04 17:26:51 -0500112
Hanna Arhipova2d538412021-08-17 10:44:41 +0300113 total_nodes = [i
114 for i in nodes
115 if i not in exclude_nodes]
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500116 if len(total_nodes) < 2:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000117 pytest.skip("Nothing to compare - only 1 node")
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000118
Hanna Arhipova2d538412021-08-17 10:44:41 +0300119 packages_with_different_versions = dict()
120 packages_names = set(itertools.chain.from_iterable(
121 [packages_versions_by_nodes[node].keys()
122 for node in total_nodes])
123 )
124
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200125 for deb in packages_names:
126 if deb in exclude_packages:
127 continue
Ekaterina Chernovab4806752019-07-26 16:02:18 +0300128
Hanna Arhipova2d538412021-08-17 10:44:41 +0300129 node_and_version = [
130 (node, packages_versions_by_nodes[node].get(deb, "No package"))
131 for node in total_nodes
132 if not is_deb_in_exception(inconsistency_rule, deb, node)
133 ]
134
135 if set([version for node, version in node_and_version]).__len__() > 1:
136 packages_with_different_versions[deb] = [
Hanna Arhipova035dea42021-08-19 12:24:08 +0300137 "{}: {}".format(node, version)
Hanna Arhipova2d538412021-08-17 10:44:41 +0300138 for node, version in node_and_version]
139
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200140 assert len(packages_with_different_versions) == 0, (
141 "Non-uniform package versions are installed on '{}' group of nodes:\n"
142 "{}".format(
Hanna Arhipova2d538412021-08-17 10:44:41 +0300143 group_name, json.dumps(packages_with_different_versions, indent=4))
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200144 )
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000145
146
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500147@pytest.mark.full
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300148def test_packages_are_latest(local_salt_client, nodes_in_group):
149 config = utils.get_configuration()
150 skip = config.get("test_packages")["skip_test"]
Ievgeniia Zadorozhna0c306fd2019-11-12 16:03:51 +0300151 if skip.lower() == 'true':
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300152 pytest.skip("Test for the latest packages is disabled")
153 skipped_pkg = config.get("test_packages")["skipped_packages"]
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200154 group, nodes = nodes_in_group
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300155 info_salt = local_salt_client.cmd(
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200156 tgt='L@' + ','.join(nodes),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500157 param='apt list --upgradable 2>/dev/null | grep -v Listing',
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300158 expr_form='compound')
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200159 for node in nodes:
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300160 result = []
161 if info_salt[node]:
162 upg_list = info_salt[node].split('\n')
163 for i in upg_list:
164 if i.split('/')[0] not in skipped_pkg:
165 result.append(i)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200166 assert not result, (
167 "Packages are not of latest version on '{}' node:\n{}".format(
168 node, "\n".join(result))
169 )
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300170
171
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500172@pytest.mark.full
Oleksii Zhurbad0ae87f2018-03-26 13:36:25 -0500173def test_check_module_versions(local_salt_client, nodes_in_group):
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300174 # defines modules specific to the nodes
175 inconsistency_rule = {
176 "I@elasticsearch:server": ["elasticsearch"],
Taras Khlivnyak83959eb2022-02-15 14:21:42 +0200177 # PROD-30833, PROD-36718
Hanna Arhipovaae2e05b2021-08-18 10:47:39 +0300178 "I@octavia:manager:controller_worker:loadbalancer_topology:SINGLE": [
179 'octavia',
180 'setproctitle',
181 'automaton',
182 'warlock',
183 'python-glanceclient',
184 'taskflow',
185 'diskimage-builder',
186 'pyasn1-modules',
187 'python-barbicanclient',
188 'WSME',
189 'jsonpatch',
190 'cotyledon',
191 'dib-utils',
192 'itsdangerous',
193 'kazoo',
194 'psycopg2',
195 'Flask',
196 'networkx',
197 'Werkzeug',
198 'jsonpointer',
199 'gunicorn',
Hanna Arhipovafb3bc582021-09-22 14:30:52 +0300200 'ipaddr',
Taras Khlivnyak83959eb2022-02-15 14:21:42 +0200201 'castellan',
202 'python-pyasn1',
203 'python3-pyasn1'
Hanna Arhipovafb3bc582021-09-22 14:30:52 +0300204 ]
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300205 }
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200206 exclude_modules = utils.get_configuration().get("skipped_modules", [])
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200207 group, nodes = nodes_in_group
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300208
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000209 pre_check = local_salt_client.cmd(
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300210 tgt="L@{nodes}".format(nodes=','.join(nodes)),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500211 param='dpkg -l | grep "python-pip "',
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500212 expr_form='compound')
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300213 exclude_nodes = targeted_minions("I@galera:master or I@gerrit:client")
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300214 if list(pre_check.values()).count('') > 0:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000215 pytest.skip("pip is not installed on one or more nodes")
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500216
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300217 total_nodes = [node
218 for node in nodes
219 if node not in exclude_nodes]
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500220 if len(total_nodes) < 2:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000221 pytest.skip("Nothing to compare - only 1 node")
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200222 list_of_pip_packages = local_salt_client.cmd(
223 tgt="L@"+','.join(nodes),
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300224 fun='pip.list', expr_form='compound')
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000225
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300226 modules_with_different_versions = dict()
227 packages_names = set(itertools.chain.from_iterable(
228 list_of_pip_packages.values()
229 ))
Oleksii Zhurbaa32d92f2018-03-29 16:22:35 -0500230
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300231 for package in packages_names:
232 if package in exclude_modules:
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200233 continue
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300234 node_and_version = [
235 (node, list_of_pip_packages[node].get(package, "No module"))
236 for node in total_nodes
237 if not is_deb_in_exception(inconsistency_rule, package, node)
238 ]
239
240 if set([version for node, version in node_and_version]).__len__() > 1:
241 modules_with_different_versions[package] = [
Hanna Arhipova035dea42021-08-19 12:24:08 +0300242 "{}: {}".format(node, version)
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300243 for node, version in node_and_version
244 ]
245
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200246 assert len(modules_with_different_versions) == 0, (
247 "Non-uniform pip modules are installed on '{}' group of nodes:\n"
248 "{}".format(
249 group, json.dumps(modules_with_different_versions, indent=4))
250 )
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200251
252
253@pytest.mark.full
254def test_restricted_updates_repo(local_salt_client):
255 restricted_repo_enabled = local_salt_client.pillar_get(
256 tgt="I@salt:master",
Hanna Arhipova1d87dbe2021-02-16 19:26:27 +0200257 param='_param:updates_mirantis_login',
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200258 expr_form='compound')
259 if not restricted_repo_enabled:
Hanna Arhipova2d538412021-08-17 10:44:41 +0300260 pytest.skip("This env doesn't require the restricted ubuntu repo")
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200261
262 repos_by_nodes=local_salt_client.cmd(
263 tgt="*",
264 param="apt-cache policy |grep updates.mirantis.com"
Hanna Arhipova035dea42021-08-19 12:24:08 +0300265 )
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200266
Hanna Arhipova1d87dbe2021-02-16 19:26:27 +0200267 assert all(list(repos_by_nodes.values())), \
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200268 "Next nodes don't have updates.mirantis.com in sources.list: {}".\
269 format({node for node, repo
270 in repos_by_nodes.items()
Hanna Arhipova035dea42021-08-19 12:24:08 +0300271 if not repo})