blob: fa59a893c2216cb845534c30cc9544fac47ce2c3 [file] [log] [blame]
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +03001import git
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +04002import jenkins
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -05003import json
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +03004import logging
5import os
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -05006import pytest
Mikhail Kraynov351e8412018-10-04 18:27:44 +04007import time
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +03008import utils
9from builtins import range
10from ldap3 import (
11 Connection,
12 Server,
13 Reader,
14 LDIF,
15 MODIFY_ADD,
16 MODIFY_DELETE,
17 SUBTREE,
18 ALL_ATTRIBUTES)
19from ldap3.core.exceptions import LDAPException
Mikhail Kraynov351e8412018-10-04 18:27:44 +040020from pygerrit2 import GerritRestAPI, HTTPBasicAuth
21from requests import HTTPError
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +030022from xml.dom import minidom
Ievgeniia Zadorozhna4f470442020-01-09 13:22:14 +020023from collections import defaultdict
Hanna Arhipovae792be52019-02-13 13:28:11 +020024
Hanna Arhipova91dc8152019-07-04 12:43:16 +030025
Mikhail Kraynov351e8412018-10-04 18:27:44 +040026def join_to_gerrit(local_salt_client, gerrit_user, gerrit_password):
Hanna Arhipova91dc8152019-07-04 12:43:16 +030027 # Workaround for issue in test_drivetrain.join_to_jenkins https://github.com/kennethreitz/requests/issues/3829
28 os.environ["PYTHONHTTPSVERIFY"] = "0"
29
30 pytest.gerrit_port = local_salt_client.pillar_get(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050031 tgt='I@gerrit:client and not I@salt:master',
32 param='_param:haproxy_gerrit_bind_port',
33 expr_form='compound')
Hanna Arhipova91dc8152019-07-04 12:43:16 +030034 pytest.gerrit_address = local_salt_client.pillar_get(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050035 tgt='I@gerrit:client and not I@salt:master',
36 param='_param:haproxy_gerrit_bind_host',
37 expr_form='compound')
Hanna Arhipova91dc8152019-07-04 12:43:16 +030038
39 pytest.gerrit_protocol = local_salt_client.pillar_get(
40 tgt='I@gerrit:client and not I@salt:master',
41 param="gerrit:client:server:protocol",
42 expr_form='compound')
43
44 gerrit_url = '{protocol}://{address}:{port}'.format(
45 protocol=pytest.gerrit_protocol,
46 address=pytest.gerrit_address,
47 port=pytest.gerrit_port)
Mikhail Kraynov351e8412018-10-04 18:27:44 +040048 auth = HTTPBasicAuth(gerrit_user, gerrit_password)
Hanna Arhipova91dc8152019-07-04 12:43:16 +030049 rest = GerritRestAPI(url=gerrit_url, auth=auth)
Mikhail Kraynov351e8412018-10-04 18:27:44 +040050 return rest
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -050051
Hanna Arhipovae792be52019-02-13 13:28:11 +020052
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +040053def join_to_jenkins(local_salt_client, jenkins_user, jenkins_password):
Hanna Arhipova91dc8152019-07-04 12:43:16 +030054
55 pytest.jenkins_port = local_salt_client.pillar_get(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050056 tgt='I@jenkins:client and not I@salt:master',
57 param='_param:haproxy_jenkins_bind_port',
58 expr_form='compound')
Hanna Arhipova91dc8152019-07-04 12:43:16 +030059 pytest.jenkins_address = local_salt_client.pillar_get(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050060 tgt='I@jenkins:client and not I@salt:master',
61 param='_param:haproxy_jenkins_bind_host',
62 expr_form='compound')
Hanna Arhipova91dc8152019-07-04 12:43:16 +030063 pytest.jenkins_protocol = local_salt_client.pillar_get(
64 tgt='I@gerrit:client and not I@salt:master',
65 param="_param:jenkins_master_protocol",
66 expr_form='compound')
67
68 jenkins_url = '{protocol}://{address}:{port}'.format(
69 protocol=pytest.jenkins_protocol,
70 address=pytest.jenkins_address,
71 port=pytest.jenkins_port)
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +040072 server = jenkins.Jenkins(jenkins_url, username=jenkins_user, password=jenkins_password)
73 return server
74
Hanna Arhipovae792be52019-02-13 13:28:11 +020075
Mikhail Kraynov351e8412018-10-04 18:27:44 +040076def get_password(local_salt_client,service):
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050077 password = local_salt_client.pillar_get(
78 tgt=service,
79 param='_param:openldap_admin_password')
Mikhail Kraynov351e8412018-10-04 18:27:44 +040080 return password
81
Hanna Arhipovae792be52019-02-13 13:28:11 +020082
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -050083@pytest.mark.full
Hanna Arhipovab7e866c2019-04-10 13:49:56 +030084def test_drivetrain_gerrit(local_salt_client, check_cicd):
Hanna Arhipova91dc8152019-07-04 12:43:16 +030085
86 gerrit_password = get_password(local_salt_client, 'gerrit:client')
Mikhail Kraynov351e8412018-10-04 18:27:44 +040087 gerrit_error = ''
88 current_date = time.strftime("%Y%m%d-%H.%M.%S", time.localtime())
89 test_proj_name = "test-dt-{0}".format(current_date)
Hanna Arhipova91dc8152019-07-04 12:43:16 +030090
Mikhail Kraynov351e8412018-10-04 18:27:44 +040091 try:
Hanna Arhipova91dc8152019-07-04 12:43:16 +030092 # Connecting to gerrit and check connection
93 server = join_to_gerrit(local_salt_client, 'admin', gerrit_password)
Mikhail Kraynov351e8412018-10-04 18:27:44 +040094 gerrit_check = server.get("/changes/?q=owner:self%20status:open")
Hanna Arhipova91dc8152019-07-04 12:43:16 +030095 # Check deleteproject plugin and skip test if the plugin is not installed
Mikhail Kraynov351e8412018-10-04 18:27:44 +040096 gerrit_plugins = server.get("/plugins/?all")
97 if 'deleteproject' not in gerrit_plugins:
98 pytest.skip("Delete-project plugin is not installed")
Hanna Arhipova91dc8152019-07-04 12:43:16 +030099 # Create test project and add description
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400100 server.put("/projects/"+test_proj_name)
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300101 server.put("/projects/"+test_proj_name+"/description",
102 json={"description": "Test DriveTrain project", "commit_message": "Update the project description"})
Hanna Arhipova56eab942019-05-06 20:14:18 +0300103 except HTTPError as e:
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400104 gerrit_error = e
105 try:
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300106 # Create test folder and init git
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400107 repo_dir = os.path.join(os.getcwd(),test_proj_name)
108 file_name = os.path.join(repo_dir, current_date)
109 repo = git.Repo.init(repo_dir)
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300110 # Add remote url for this git repo
111 origin = repo.create_remote('origin', '{http}://admin:{password}@{address}:{port}/{project}.git'.format(
112 project=test_proj_name,
113 password=gerrit_password,
114 http=pytest.gerrit_protocol,
115 address=pytest.gerrit_address,
116 port=pytest.gerrit_port))
117 # Add commit-msg hook to automatically add Change-Id to our commit
118 os.system("curl -Lo {repo}/.git/hooks/commit-msg '{http}://admin:{password}@{address}:{port}/tools/hooks/commit-msg' > /dev/null 2>&1".format(
119 repo=repo_dir,
120 password=gerrit_password,
121 address=pytest.gerrit_address,
122 http=pytest.gerrit_protocol,
123 port=pytest.gerrit_port))
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400124 os.system("chmod u+x {0}/.git/hooks/commit-msg".format(repo_dir))
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300125 # Create a test file
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400126 f = open(file_name, 'w+')
127 f.write("This is a test file for DriveTrain test")
128 f.close()
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300129 # Add file to git and commit it to Gerrit for review
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400130 repo.index.add([file_name])
131 repo.index.commit("This is a test commit for DriveTrain test")
132 repo.git.push("origin", "HEAD:refs/for/master")
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300133 # Get change id from Gerrit. Set Code-Review +2 and submit this change
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400134 changes = server.get("/changes/?q=project:{0}".format(test_proj_name))
135 last_change = changes[0].get('change_id')
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300136 server.post("/changes/{0}/revisions/1/review".format(last_change), json={"message": "All is good","labels":{"Code-Review":"+2"}})
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400137 server.post("/changes/{0}/submit".format(last_change))
Hanna Arhipova56eab942019-05-06 20:14:18 +0300138 except HTTPError as e:
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400139 gerrit_error = e
140 finally:
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300141 # Delete test project
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400142 server.post("/projects/"+test_proj_name+"/deleteproject~delete")
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200143 assert gerrit_error == '', (
144 'There is an error during Gerrit operations:\n{}'.format(gerrit_error))
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400145
Hanna Arhipovae792be52019-02-13 13:28:11 +0200146
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500147@pytest.mark.full
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300148@pytest.mark.skip
149# Temporary skipped, ldap3 package add\search user is not working
Hanna Arhipovab7e866c2019-04-10 13:49:56 +0300150def test_drivetrain_openldap(local_salt_client, check_cicd):
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300151 """
152 1. Create a test user 'DT_test_user' in openldap
153 2. Add the user to admin group
154 3. Login using the user to Jenkins
155 4. Check that no error occurred
156 5. Add the user to devops group in Gerrit and then login to Gerrit
157 using test_user credentials.
158 6 Start job in jenkins from this user
159 7. Get info from gerrit from this user
160 6. Finally, delete the user from admin
161 group and openldap
162 """
163
164 # TODO split to several test cases. One check - per one test method. Make the login process in fixture
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300165 ldap_password = get_password(local_salt_client, 'openldap:client')
166 # Check that ldap_password is exists, otherwise skip test
mkraynov360c30d2018-09-27 17:02:45 +0400167 if not ldap_password:
168 pytest.skip("Openldap service or openldap:client pillar \
169 are not found on this environment.")
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500170 ldap_port = local_salt_client.pillar_get(
171 tgt='I@openldap:client and not I@salt:master',
172 param='_param:haproxy_openldap_bind_port',
173 expr_form='compound')
174 ldap_address = local_salt_client.pillar_get(
175 tgt='I@openldap:client and not I@salt:master',
176 param='_param:haproxy_openldap_bind_host',
177 expr_form='compound')
178 ldap_dc = local_salt_client.pillar_get(
179 tgt='openldap:client',
180 param='_param:openldap_dn')
181 ldap_con_admin = local_salt_client.pillar_get(
182 tgt='openldap:client',
183 param='openldap:client:server:auth:user')
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300184 ldap_url = 'ldap://{0}:{1}'.format(ldap_address, ldap_port)
mkraynov360c30d2018-09-27 17:02:45 +0400185 ldap_error = ''
186 ldap_result = ''
187 gerrit_result = ''
188 gerrit_error = ''
189 jenkins_error = ''
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300190 # Test user's CN
mkraynov360c30d2018-09-27 17:02:45 +0400191 test_user_name = 'DT_test_user'
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300192 test_user = 'cn={0},ou=people,{1}'.format(test_user_name, ldap_dc)
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300193 # Admins group CN
mkraynov360c30d2018-09-27 17:02:45 +0400194 admin_gr_dn = 'cn=admins,ou=groups,{0}'.format(ldap_dc)
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300195 user_pass = 'aSecretPassw'
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300196 # List of attributes for test user
mkraynov360c30d2018-09-27 17:02:45 +0400197 attrs = {}
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300198 attrs['objectclass'] = ['organizationalRole', 'simpleSecurityObject', 'shadowAccount']
mkraynov360c30d2018-09-27 17:02:45 +0400199 attrs['cn'] = test_user_name
200 attrs['uid'] = test_user_name
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300201 attrs['userPassword'] = user_pass
mkraynov360c30d2018-09-27 17:02:45 +0400202 attrs['description'] = 'Test user for CVP DT test'
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300203 # search_filter = '(cn={0})'.format(test_user_name)
204 search_filter = '(cn={})'.format(test_user_name)
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300205 # Get a test job name from config
mkraynov360c30d2018-09-27 17:02:45 +0400206 config = utils.get_configuration()
mkraynov058ee122018-11-30 13:15:49 +0400207 jenkins_cvp_job = config['jenkins_cvp_job']
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300208 logging.warning('test_user: {}'.format(test_user))
209 logging.warning('ldap_address: {}'.format(ldap_address))
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300210 # Open connection to ldap and creating test user in admins group
mkraynov360c30d2018-09-27 17:02:45 +0400211 try:
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300212 ldap_server = Server(host=ldap_address, port=ldap_port,
213 use_ssl=False, get_info='NO_INFO')
214 conn = Connection(ldap_server, client_strategy=LDIF)
215 conn.bind()
216 new_user = conn.add(test_user, test_user_name, attrs)
217 logging.warning('new_user: {}'.format(new_user))
218 conn.modify(admin_gr_dn,
219 {'memberUid': (MODIFY_ADD, [test_user_name])
220 })
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300221 # Check search test user in LDAP
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300222 conn2 = Connection(ldap_server)
223 conn2.bind()
224 ldap_result = conn2.search(search_base='dc=heat-cicd-queens-contrail41-sl,dc=local',
225 search_filter=search_filter, search_scope='SUBTREE', attributes=['cn'])
226 logging.warning('ldap_result: {}'.format(ldap_result))
227 logging.warning('conn2.entries.: {}'.format(conn2.entries))
228 except LDAPException as e:
mkraynov360c30d2018-09-27 17:02:45 +0400229 ldap_error = e
230 try:
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300231 # Check if user is created before connect from Jenkins
232 assert ldap_result, "Test user {} is not found".format(ldap_result)
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300233 # Check connection between Jenkins and LDAP
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300234 jenkins_server = join_to_jenkins(local_salt_client, test_user_name, user_pass)
mkraynov058ee122018-11-30 13:15:49 +0400235 jenkins_version = jenkins_server.get_job_name(jenkins_cvp_job)
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300236 # Check connection between Gerrit and LDAP
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300237 gerrit_server = join_to_gerrit(local_salt_client, 'admin', ldap_password)
mkraynov360c30d2018-09-27 17:02:45 +0400238 gerrit_check = gerrit_server.get("/changes/?q=owner:self%20status:open")
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300239 # Add test user to devops-contrib group in Gerrit and check login
mkraynov360c30d2018-09-27 17:02:45 +0400240 _link = "/groups/devops-contrib/members/{0}".format(test_user_name)
241 gerrit_add_user = gerrit_server.put(_link)
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300242 gerrit_server = join_to_gerrit(local_salt_client, test_user_name, user_pass)
mkraynov360c30d2018-09-27 17:02:45 +0400243 gerrit_result = gerrit_server.get("/changes/?q=owner:self%20status:open")
Hanna Arhipova56eab942019-05-06 20:14:18 +0300244 except HTTPError as e:
mkraynov360c30d2018-09-27 17:02:45 +0400245 gerrit_error = e
Hanna Arhipova56eab942019-05-06 20:14:18 +0300246 except jenkins.JenkinsException as e:
mkraynov360c30d2018-09-27 17:02:45 +0400247 jenkins_error = e
248 finally:
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300249 conn.modify(admin_gr_dn,
250 {'memberUid': (MODIFY_DELETE, [test_user_name])
251 })
252 conn.delete(test_user)
253 conn.unbind()
254 conn2.unbind()
255
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200256 assert ldap_error == '', (
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300257 "There is an error with connection to LDAP:\n{}".format(ldap_error))
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200258 assert jenkins_error == '', (
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300259 "Connection to Jenkins is not established:\n{}".format(jenkins_error))
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200260 assert gerrit_error == '', (
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300261 "Connection to Gerrit is not established:\n{}".format(gerrit_error))
262
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400263
Hanna Arhipovae792be52019-02-13 13:28:11 +0200264
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500265@pytest.mark.sl_dup
266#DockerService***Outage
267@pytest.mark.full
Oleksii Zhurba67aaec92019-04-15 18:05:13 -0500268def test_drivetrain_services_replicas(local_salt_client, check_cicd):
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300269 """
270 # Execute ` salt -C 'I@gerrit:client' cmd.run 'docker service ls'` command to get info for each docker service like that:
271 "x5nzktxsdlm6 jenkins_slave02 replicated 0/1 docker-prod-local.artifactory.mirantis.com/mirantis/cicd/jnlp-slave:2019.2.0 "
272 # Check that each service has all replicas
273 """
Hanna Arhipovaf2660bd2019-02-08 17:25:39 +0200274 # TODO: replace with rerunfalures plugin
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300275 wrong_items = []
Hanna Arhipovaf2660bd2019-02-08 17:25:39 +0200276 for _ in range(4):
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300277 docker_services_by_nodes = local_salt_client.cmd(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500278 tgt='I@gerrit:client',
279 param='docker service ls',
Hanna Arhipovaf2660bd2019-02-08 17:25:39 +0200280 expr_form='compound')
281 wrong_items = []
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300282 for line in docker_services_by_nodes[list(docker_services_by_nodes.keys())[0]].split('\n'):
Hanna Arhipovaf2660bd2019-02-08 17:25:39 +0200283 if line[line.find('/') - 1] != line[line.find('/') + 1] \
284 and 'replicated' in line:
285 wrong_items.append(line)
286 if len(wrong_items) == 0:
287 break
288 else:
Hanna Arhipovaf2660bd2019-02-08 17:25:39 +0200289 time.sleep(5)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200290 assert len(wrong_items) == 0, (
291 "Some DriveTrain services don't have expected number of replicas:\n"
292 "{}".format(json.dumps(wrong_items, indent=4))
293 )
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500294
295
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500296@pytest.mark.full
Hanna Arhipovab7e866c2019-04-10 13:49:56 +0300297def test_drivetrain_components_and_versions(local_salt_client, check_cicd):
Oleksii Zhurbab91c3142019-03-26 16:49:44 -0500298 """
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300299 1. Execute command `docker service ls --format "{{.Image}}"'` on the 'I@gerrit:client' target
300 2. Execute ` salt -C 'I@gerrit:client' pillar.get docker:client:images`
301 3. Check that list of images from step 1 is the same as a list from the step2
302 4. Check that all docker services has label that equals to mcp_version
303
304 """
Hanna Arhipova04344f12019-06-12 13:56:36 +0300305 def get_name(long_name):
306 return long_name.rsplit(':', 1)[0]
307
308 def get_tag(long_name):
309 return long_name.rsplit(':', 1)[-1]
310
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500311 table_with_docker_services = local_salt_client.cmd(tgt='I@gerrit:client',
312 param='docker service ls --format "{{.Image}}"',
Hanna Arhipovae792be52019-02-13 13:28:11 +0200313 expr_form='compound')
Hanna Arhipova8cc3a982019-07-22 14:58:03 +0300314 stack_info = local_salt_client.pillar_get(tgt='gerrit:client',
315 param='docker:client:stack')
316
Ievgeniia Zadorozhna4f470442020-01-09 13:22:14 +0200317 expected_images_list = list()
Hanna Arhipova8cc3a982019-07-22 14:58:03 +0300318 # find services in list of docker clients
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300319 for key, stack in list(stack_info.items()):
Hanna Arhipova8cc3a982019-07-22 14:58:03 +0300320 if stack.get('service'):
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300321 stack = [item.get('image') for _,item in list(stack.get('service').items()) if item.get('image')]
Ievgeniia Zadorozhna4f470442020-01-09 13:22:14 +0200322 expected_images_list += stack
323 expected_images = defaultdict(list)
Hanna Arhipova8cc3a982019-07-22 14:58:03 +0300324
Ievgeniia Zadorozhna4f470442020-01-09 13:22:14 +0200325 # collect unique tags for each image in same structure as for actual images
326 for image in expected_images_list:
327 if get_name(image) in expected_images:
328 if get_tag(image) not in expected_images[get_name(image)]:
329 expected_images[get_name(image)].append(get_tag(image))
330 else:
331 expected_images[get_name(image)].append(get_tag(image))
332
333 # collect tags for each image in same structure as for expected images
334 actual_images = defaultdict(list)
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300335 for image in set(table_with_docker_services[list(table_with_docker_services.keys())[0]].split('\n')):
Ievgeniia Zadorozhna4f470442020-01-09 13:22:14 +0200336 actual_images[get_name(image)].append(get_tag(image))
Hanna Arhipova8cc3a982019-07-22 14:58:03 +0300337
Ievgeniia Zadorozhna4f470442020-01-09 13:22:14 +0200338 # find difference between defaultdicts
339 total_diff = 0
340 for i in expected_images:
341 diff = set(expected_images[i]) - set(actual_images[i])
342 total_diff += len(diff)
343
344 assert actual_images == expected_images, (
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200345 "Some DriveTrain components do not have expected versions:\n{}".format(
Ievgeniia Zadorozhna4f470442020-01-09 13:22:14 +0200346 json.dumps(total_diff, indent=4))
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200347 )
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500348
349
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500350@pytest.mark.full
Oleksii Zhurba67aaec92019-04-15 18:05:13 -0500351def test_jenkins_jobs_branch(local_salt_client, check_cicd):
Oleksii Zhurbad52b5fe2019-03-28 11:11:35 -0500352 """ This test compares Jenkins jobs versions
353 collected from the cloud vs collected from pillars.
354 """
Hanna Arhipova91dc8152019-07-04 12:43:16 +0300355
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500356 excludes = ['upgrade-mcp-release', 'deploy-update-salt',
357 'git-mirror-downstream-mk-pipelines',
358 'git-mirror-downstream-pipeline-library']
Hanna Arhipova6f34fbb2019-02-08 11:19:41 +0200359
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500360 config = utils.get_configuration()
Hanna Arhipova6f34fbb2019-02-08 11:19:41 +0200361 drivetrain_version = config.get('drivetrain_version', '')
Hanna Arhipovae792be52019-02-13 13:28:11 +0200362 jenkins_password = get_password(local_salt_client, 'jenkins:client')
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500363 version_mismatch = []
Hanna Arhipovae792be52019-02-13 13:28:11 +0200364 server = join_to_jenkins(local_salt_client, 'admin', jenkins_password)
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400365 for job_instance in server.get_jobs():
366 job_name = job_instance.get('name')
Hanna Arhipova6f34fbb2019-02-08 11:19:41 +0200367 if job_name in excludes:
368 continue
369
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400370 job_config = server.get_job_config(job_name)
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500371 xml_data = minidom.parseString(job_config)
372 BranchSpec = xml_data.getElementsByTagName('hudson.plugins.git.BranchSpec')
Hanna Arhipova6f34fbb2019-02-08 11:19:41 +0200373
374 # We use master branch for pipeline-library in case of 'testing,stable,nighlty' versions
375 # Leave proposed version as is
376 # in other cases we get release/{drivetrain_version} (e.g release/2019.2.0)
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300377 if drivetrain_version in ['testing', 'nightly', 'stable']:
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400378 expected_version = 'master'
Hanna Arhipova6f34fbb2019-02-08 11:19:41 +0200379 else:
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500380 expected_version = local_salt_client.pillar_get(
381 tgt='gerrit:client',
382 param='jenkins:client:job:{}:scm:branch'.format(job_name))
Hanna Arhipova6f34fbb2019-02-08 11:19:41 +0200383
384 if not BranchSpec:
Hanna Arhipova56eab942019-05-06 20:14:18 +0300385 logging.debug("No BranchSpec has found for {} job".format(job_name))
Hanna Arhipova6f34fbb2019-02-08 11:19:41 +0200386 continue
387
388 actual_version = BranchSpec[0].getElementsByTagName('name')[0].childNodes[0].data
Oleksii Zhurba075cc7a2019-05-17 14:04:28 -0500389 if expected_version and actual_version not in expected_version:
Hanna Arhipova6f34fbb2019-02-08 11:19:41 +0200390 version_mismatch.append("Job {0} has {1} branch."
391 "Expected {2}".format(job_name,
392 actual_version,
393 expected_version))
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200394 assert len(version_mismatch) == 0, (
395 "Some DriveTrain jobs have version/branch mismatch:\n{}".format(
396 json.dumps(version_mismatch, indent=4))
397 )
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300398
399
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500400@pytest.mark.full
Hanna Arhipovab7e866c2019-04-10 13:49:56 +0300401def test_drivetrain_jenkins_job(local_salt_client, check_cicd):
Hanna Arhipova16a8f412019-04-08 17:10:38 +0300402 """
403 # Login to Jenkins on jenkins:client
404 # Read the name of jobs from configuration 'jenkins_test_job'
405 # Start job
406 # Wait till the job completed
407 # Check that job has completed with "SUCCESS" result
408 """
409 job_result = None
410
411 jenkins_password = get_password(local_salt_client, 'jenkins:client')
412 server = join_to_jenkins(local_salt_client, 'admin', jenkins_password)
413 # Getting Jenkins test job name from configuration
414 config = utils.get_configuration()
415 jenkins_test_job = config['jenkins_test_job']
416 if not server.get_job_name(jenkins_test_job):
417 server.create_job(jenkins_test_job, jenkins.EMPTY_CONFIG_XML)
418 if server.get_job_name(jenkins_test_job):
419 next_build_num = server.get_job_info(jenkins_test_job)['nextBuildNumber']
420 # If this is first build number skip building check
421 if next_build_num != 1:
422 # Check that test job is not running at this moment,
423 # Otherwise skip the test
424 last_build_num = server.get_job_info(jenkins_test_job)['lastBuild'].get('number')
425 last_build_status = server.get_build_info(jenkins_test_job, last_build_num)['building']
426 if last_build_status:
427 pytest.skip("Test job {0} is already running").format(jenkins_test_job)
428 server.build_job(jenkins_test_job)
429 timeout = 0
430 # Use job status True by default to exclude timeout between build job and start job.
431 job_status = True
432 while job_status and (timeout < 180):
433 time.sleep(10)
434 timeout += 10
435 job_status = server.get_build_info(jenkins_test_job, next_build_num)['building']
436 job_result = server.get_build_info(jenkins_test_job, next_build_num)['result']
437 else:
438 pytest.skip("The job {0} was not found").format(jenkins_test_job)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200439 assert job_result == 'SUCCESS', (
440 "Test job '{}' build is not successful or timeout is too "
441 "small.".format(jenkins_test_job)
442 )