blob: 528108113fe7cf9d029d5059375597eb319003ee [file] [log] [blame]
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +03001import jenkins
2from xml.dom import minidom
3import utils
4import json
5import pytest
6import time
7import os
8from pygerrit2 import GerritRestAPI, HTTPBasicAuth
9from requests import HTTPError
10import git
11import ldap
12import ldap.modlist as modlist
Hanna Arhipova1eef8312019-05-06 20:14:18 +030013import logging
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030014
Hanna Arhipova474ba922019-07-04 12:43:16 +030015
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030016def join_to_gerrit(local_salt_client, gerrit_user, gerrit_password):
Hanna Arhipova474ba922019-07-04 12:43:16 +030017 # Workaround for issue in test_drivetrain.join_to_jenkins https://github.com/kennethreitz/requests/issues/3829
18 os.environ["PYTHONHTTPSVERIFY"] = "0"
19
20 pytest.gerrit_port = local_salt_client.pillar_get(
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030021 tgt='I@gerrit:client and not I@salt:master',
22 param='_param:haproxy_gerrit_bind_port',
23 expr_form='compound')
Hanna Arhipova474ba922019-07-04 12:43:16 +030024 pytest.gerrit_address = local_salt_client.pillar_get(
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030025 tgt='I@gerrit:client and not I@salt:master',
26 param='_param:haproxy_gerrit_bind_host',
27 expr_form='compound')
Hanna Arhipova474ba922019-07-04 12:43:16 +030028
29 pytest.gerrit_protocol = local_salt_client.pillar_get(
30 tgt='I@gerrit:client and not I@salt:master',
31 param="gerrit:client:server:protocol",
32 expr_form='compound')
33
34 gerrit_url = '{protocol}://{address}:{port}'.format(
35 protocol=pytest.gerrit_protocol,
36 address=pytest.gerrit_address,
37 port=pytest.gerrit_port)
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030038 auth = HTTPBasicAuth(gerrit_user, gerrit_password)
Hanna Arhipova474ba922019-07-04 12:43:16 +030039 rest = GerritRestAPI(url=gerrit_url, auth=auth)
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030040 return rest
41
42
43def join_to_jenkins(local_salt_client, jenkins_user, jenkins_password):
Hanna Arhipova474ba922019-07-04 12:43:16 +030044
45 pytest.jenkins_port = local_salt_client.pillar_get(
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030046 tgt='I@jenkins:client and not I@salt:master',
47 param='_param:haproxy_jenkins_bind_port',
48 expr_form='compound')
Hanna Arhipova474ba922019-07-04 12:43:16 +030049 pytest.jenkins_address = local_salt_client.pillar_get(
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030050 tgt='I@jenkins:client and not I@salt:master',
51 param='_param:haproxy_jenkins_bind_host',
52 expr_form='compound')
Hanna Arhipova474ba922019-07-04 12:43:16 +030053 pytest.jenkins_protocol = local_salt_client.pillar_get(
54 tgt='I@gerrit:client and not I@salt:master',
55 param="_param:jenkins_master_protocol",
56 expr_form='compound')
57
58 jenkins_url = '{protocol}://{address}:{port}'.format(
59 protocol=pytest.jenkins_protocol,
60 address=pytest.jenkins_address,
61 port=pytest.jenkins_port)
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030062 server = jenkins.Jenkins(jenkins_url, username=jenkins_user, password=jenkins_password)
63 return server
64
65
66def get_password(local_salt_client,service):
67 password = local_salt_client.pillar_get(
68 tgt=service,
69 param='_param:openldap_admin_password')
70 return password
71
72
Oleksii Zhurba23c18332019-05-09 18:53:40 -050073@pytest.mark.full
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030074def test_drivetrain_gerrit(local_salt_client, check_cicd):
Hanna Arhipova474ba922019-07-04 12:43:16 +030075
76 gerrit_password = get_password(local_salt_client, 'gerrit:client')
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030077 gerrit_error = ''
78 current_date = time.strftime("%Y%m%d-%H.%M.%S", time.localtime())
79 test_proj_name = "test-dt-{0}".format(current_date)
Hanna Arhipova474ba922019-07-04 12:43:16 +030080
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030081 try:
Hanna Arhipova474ba922019-07-04 12:43:16 +030082 # Connecting to gerrit and check connection
83 server = join_to_gerrit(local_salt_client, 'admin', gerrit_password)
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030084 gerrit_check = server.get("/changes/?q=owner:self%20status:open")
Hanna Arhipova474ba922019-07-04 12:43:16 +030085 # Check deleteproject plugin and skip test if the plugin is not installed
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030086 gerrit_plugins = server.get("/plugins/?all")
87 if 'deleteproject' not in gerrit_plugins:
88 pytest.skip("Delete-project plugin is not installed")
Hanna Arhipova474ba922019-07-04 12:43:16 +030089 # Create test project and add description
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030090 server.put("/projects/"+test_proj_name)
Hanna Arhipova474ba922019-07-04 12:43:16 +030091 server.put("/projects/"+test_proj_name+"/description",
92 json={"description": "Test DriveTrain project", "commit_message": "Update the project description"})
Hanna Arhipova1eef8312019-05-06 20:14:18 +030093 except HTTPError as e:
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030094 gerrit_error = e
95 try:
Hanna Arhipova474ba922019-07-04 12:43:16 +030096 # Create test folder and init git
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +030097 repo_dir = os.path.join(os.getcwd(),test_proj_name)
98 file_name = os.path.join(repo_dir, current_date)
99 repo = git.Repo.init(repo_dir)
Hanna Arhipova474ba922019-07-04 12:43:16 +0300100 # Add remote url for this git repo
101 origin = repo.create_remote('origin', '{http}://admin:{password}@{address}:{port}/{project}.git'.format(
102 project=test_proj_name,
103 password=gerrit_password,
104 http=pytest.gerrit_protocol,
105 address=pytest.gerrit_address,
106 port=pytest.gerrit_port))
107 # Add commit-msg hook to automatically add Change-Id to our commit
108 os.system("curl -Lo {repo}/.git/hooks/commit-msg '{http}://admin:{password}@{address}:{port}/tools/hooks/commit-msg' > /dev/null 2>&1".format(
109 repo=repo_dir,
110 password=gerrit_password,
111 address=pytest.gerrit_address,
112 http=pytest.gerrit_protocol,
113 port=pytest.gerrit_port))
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300114 os.system("chmod u+x {0}/.git/hooks/commit-msg".format(repo_dir))
Hanna Arhipova474ba922019-07-04 12:43:16 +0300115 # Create a test file
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300116 f = open(file_name, 'w+')
117 f.write("This is a test file for DriveTrain test")
118 f.close()
Hanna Arhipova474ba922019-07-04 12:43:16 +0300119 # Add file to git and commit it to Gerrit for review
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300120 repo.index.add([file_name])
121 repo.index.commit("This is a test commit for DriveTrain test")
122 repo.git.push("origin", "HEAD:refs/for/master")
Hanna Arhipova474ba922019-07-04 12:43:16 +0300123 # Get change id from Gerrit. Set Code-Review +2 and submit this change
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300124 changes = server.get("/changes/?q=project:{0}".format(test_proj_name))
125 last_change = changes[0].get('change_id')
Hanna Arhipova474ba922019-07-04 12:43:16 +0300126 server.post("/changes/{0}/revisions/1/review".format(last_change), json={"message": "All is good","labels":{"Code-Review":"+2"}})
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300127 server.post("/changes/{0}/submit".format(last_change))
Hanna Arhipova1eef8312019-05-06 20:14:18 +0300128 except HTTPError as e:
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300129 gerrit_error = e
130 finally:
Hanna Arhipova474ba922019-07-04 12:43:16 +0300131 # Delete test project
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300132 server.post("/projects/"+test_proj_name+"/deleteproject~delete")
133 assert gerrit_error == '',\
134 'Something is wrong with Gerrit'.format(gerrit_error)
135
136
Oleksii Zhurba23c18332019-05-09 18:53:40 -0500137@pytest.mark.full
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300138def test_drivetrain_openldap(local_salt_client, check_cicd):
139 """
140 1. Create a test user 'DT_test_user' in openldap
141 2. Add the user to admin group
142 3. Login using the user to Jenkins
143 4. Check that no error occurred
144 5. Add the user to devops group in Gerrit and then login to Gerrit
145 using test_user credentials.
146 6 Start job in jenkins from this user
147 7. Get info from gerrit from this user
148 6. Finally, delete the user from admin
149 group and openldap
150 """
151
152 # TODO split to several test cases. One check - per one test method. Make the login process in fixture
Hanna Arhipova474ba922019-07-04 12:43:16 +0300153 ldap_password = get_password(local_salt_client, 'openldap:client')
154 # Check that ldap_password is exists, otherwise skip test
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300155 if not ldap_password:
156 pytest.skip("Openldap service or openldap:client pillar \
157 are not found on this environment.")
158 ldap_port = local_salt_client.pillar_get(
159 tgt='I@openldap:client and not I@salt:master',
160 param='_param:haproxy_openldap_bind_port',
161 expr_form='compound')
162 ldap_address = local_salt_client.pillar_get(
163 tgt='I@openldap:client and not I@salt:master',
164 param='_param:haproxy_openldap_bind_host',
165 expr_form='compound')
166 ldap_dc = local_salt_client.pillar_get(
167 tgt='openldap:client',
168 param='_param:openldap_dn')
169 ldap_con_admin = local_salt_client.pillar_get(
170 tgt='openldap:client',
171 param='openldap:client:server:auth:user')
172 ldap_url = 'ldap://{0}:{1}'.format(ldap_address,ldap_port)
173 ldap_error = ''
174 ldap_result = ''
175 gerrit_result = ''
176 gerrit_error = ''
177 jenkins_error = ''
Hanna Arhipova474ba922019-07-04 12:43:16 +0300178 # Test user's CN
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300179 test_user_name = 'DT_test_user'
180 test_user = 'cn={0},ou=people,{1}'.format(test_user_name,ldap_dc)
Hanna Arhipova474ba922019-07-04 12:43:16 +0300181 # Admins group CN
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300182 admin_gr_dn = 'cn=admins,ou=groups,{0}'.format(ldap_dc)
Hanna Arhipova474ba922019-07-04 12:43:16 +0300183 # List of attributes for test user
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300184 attrs = {}
185 attrs['objectclass'] = ['organizationalRole', 'simpleSecurityObject', 'shadowAccount']
186 attrs['cn'] = test_user_name
187 attrs['uid'] = test_user_name
188 attrs['userPassword'] = 'aSecretPassw'
189 attrs['description'] = 'Test user for CVP DT test'
190 searchFilter = 'cn={0}'.format(test_user_name)
Hanna Arhipova474ba922019-07-04 12:43:16 +0300191 # Get a test job name from config
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300192 config = utils.get_configuration()
193 jenkins_cvp_job = config['jenkins_cvp_job']
Hanna Arhipova474ba922019-07-04 12:43:16 +0300194 # Open connection to ldap and creating test user in admins group
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300195 try:
196 ldap_server = ldap.initialize(ldap_url)
197 ldap_server.simple_bind_s(ldap_con_admin,ldap_password)
198 ldif = modlist.addModlist(attrs)
Hanna Arhipova474ba922019-07-04 12:43:16 +0300199 ldap_server.add_s(test_user, ldif)
200 ldap_server.modify_s(admin_gr_dn, [(ldap.MOD_ADD, 'memberUid', [test_user_name],)],)
201 # Check search test user in LDAP
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300202 searchScope = ldap.SCOPE_SUBTREE
203 ldap_result = ldap_server.search_s(ldap_dc, searchScope, searchFilter)
Hanna Arhipova1eef8312019-05-06 20:14:18 +0300204 except ldap.LDAPError as e:
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300205 ldap_error = e
206 try:
Hanna Arhipova474ba922019-07-04 12:43:16 +0300207 # Check connection between Jenkins and LDAP
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300208 jenkins_server = join_to_jenkins(local_salt_client,test_user_name,'aSecretPassw')
209 jenkins_version = jenkins_server.get_job_name(jenkins_cvp_job)
Hanna Arhipova474ba922019-07-04 12:43:16 +0300210 # Check connection between Gerrit and LDAP
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300211 gerrit_server = join_to_gerrit(local_salt_client,'admin',ldap_password)
212 gerrit_check = gerrit_server.get("/changes/?q=owner:self%20status:open")
Hanna Arhipova474ba922019-07-04 12:43:16 +0300213 # Add test user to devops-contrib group in Gerrit and check login
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300214 _link = "/groups/devops-contrib/members/{0}".format(test_user_name)
215 gerrit_add_user = gerrit_server.put(_link)
216 gerrit_server = join_to_gerrit(local_salt_client,test_user_name,'aSecretPassw')
217 gerrit_result = gerrit_server.get("/changes/?q=owner:self%20status:open")
Hanna Arhipova1eef8312019-05-06 20:14:18 +0300218 except HTTPError as e:
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300219 gerrit_error = e
Hanna Arhipova1eef8312019-05-06 20:14:18 +0300220 except jenkins.JenkinsException as e:
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300221 jenkins_error = e
222 finally:
223 ldap_server.modify_s(admin_gr_dn,[(ldap.MOD_DELETE, 'memberUid', [test_user_name],)],)
224 ldap_server.delete_s(test_user)
225 ldap_server.unbind_s()
226 assert ldap_error == '', \
227 '''Something is wrong with connection to LDAP:
228 {0}'''.format(e)
229 assert jenkins_error == '', \
230 '''Connection to Jenkins was not established:
231 {0}'''.format(e)
232 assert gerrit_error == '', \
233 '''Connection to Gerrit was not established:
234 {0}'''.format(e)
235 assert ldap_result !=[], \
236 '''Test user was not found'''
237
238
Oleksii Zhurba23c18332019-05-09 18:53:40 -0500239@pytest.mark.sl_dup
240#DockerService***Outage
241@pytest.mark.full
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300242def test_drivetrain_services_replicas(local_salt_client, check_cicd):
243 """
244 # Execute ` salt -C 'I@gerrit:client' cmd.run 'docker service ls'` command to get info for each docker service like that:
245 "x5nzktxsdlm6 jenkins_slave02 replicated 0/1 docker-prod-local.artifactory.mirantis.com/mirantis/cicd/jnlp-slave:2019.2.0 "
246 # Check that each service has all replicas
247 """
248 # TODO: replace with rerunfalures plugin
249 wrong_items = []
250 for _ in range(4):
251 docker_services_by_nodes = local_salt_client.cmd(
252 tgt='I@gerrit:client',
253 param='docker service ls',
254 expr_form='compound')
255 wrong_items = []
256 for line in docker_services_by_nodes[docker_services_by_nodes.keys()[0]].split('\n'):
257 if line[line.find('/') - 1] != line[line.find('/') + 1] \
258 and 'replicated' in line:
259 wrong_items.append(line)
260 if len(wrong_items) == 0:
261 break
262 else:
Hanna Arhipova1eef8312019-05-06 20:14:18 +0300263 logging.error('''Some DriveTrain services doesn't have expected number of replicas:
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300264 {}\n'''.format(json.dumps(wrong_items, indent=4)))
265 time.sleep(5)
266 assert len(wrong_items) == 0
267
268
Oleksii Zhurba23c18332019-05-09 18:53:40 -0500269@pytest.mark.full
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300270def test_drivetrain_components_and_versions(local_salt_client, check_cicd):
271 """
272 1. Execute command `docker service ls --format "{{.Image}}"'` on the 'I@gerrit:client' target
273 2. Execute ` salt -C 'I@gerrit:client' pillar.get docker:client:images`
274 3. Check that list of images from step 1 is the same as a list from the step2
275 4. Check that all docker services has label that equals to mcp_version
276
277 """
Hanna Arhipovadcff7142019-06-12 13:56:36 +0300278 def get_name(long_name):
279 return long_name.rsplit(':', 1)[0]
280
281 def get_tag(long_name):
282 return long_name.rsplit(':', 1)[-1]
283
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300284 table_with_docker_services = local_salt_client.cmd(tgt='I@gerrit:client',
285 param='docker service ls --format "{{.Image}}"',
286 expr_form='compound')
Hanna Arhipova7227a952019-07-22 14:58:03 +0300287 stack_info = local_salt_client.pillar_get(tgt='gerrit:client',
288 param='docker:client:stack')
289
290 expected_images = list()
291 # find services in list of docker clients
292 for key, stack in stack_info.items():
293 if stack.get('service'):
294 stack = [item.get('image') for _,item in stack.get('service').items() if item.get('image')]
295 expected_images += stack
296
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300297 mismatch = {}
298 actual_images = {}
299 for image in set(table_with_docker_services[table_with_docker_services.keys()[0]].split('\n')):
Hanna Arhipovadcff7142019-06-12 13:56:36 +0300300 actual_images[get_name(image)] = get_tag(image)
Hanna Arhipova7227a952019-07-22 14:58:03 +0300301
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300302 for image in set(expected_images):
Hanna Arhipovadcff7142019-06-12 13:56:36 +0300303 im_name = get_name(image)
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300304 if im_name not in actual_images:
305 mismatch[im_name] = 'not found on env'
Hanna Arhipovadcff7142019-06-12 13:56:36 +0300306 elif get_tag(image) != actual_images[im_name]:
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300307 mismatch[im_name] = 'has {actual} version instead of {expected}'.format(
Hanna Arhipovadcff7142019-06-12 13:56:36 +0300308 actual=actual_images[im_name], expected=get_tag(image))
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300309 assert len(mismatch) == 0, \
310 '''Some DriveTrain components do not have expected versions:
311 {}'''.format(json.dumps(mismatch, indent=4))
312
313
Oleksii Zhurba23c18332019-05-09 18:53:40 -0500314@pytest.mark.full
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300315def test_jenkins_jobs_branch(local_salt_client, check_cicd):
316 """ This test compares Jenkins jobs versions
317 collected from the cloud vs collected from pillars.
318 """
Hanna Arhipova474ba922019-07-04 12:43:16 +0300319
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300320 excludes = ['upgrade-mcp-release', 'deploy-update-salt',
321 'git-mirror-downstream-mk-pipelines',
322 'git-mirror-downstream-pipeline-library']
323
324 config = utils.get_configuration()
325 drivetrain_version = config.get('drivetrain_version', '')
326 jenkins_password = get_password(local_salt_client, 'jenkins:client')
327 version_mismatch = []
328 server = join_to_jenkins(local_salt_client, 'admin', jenkins_password)
329 for job_instance in server.get_jobs():
330 job_name = job_instance.get('name')
331 if job_name in excludes:
332 continue
333
334 job_config = server.get_job_config(job_name)
335 xml_data = minidom.parseString(job_config)
336 BranchSpec = xml_data.getElementsByTagName('hudson.plugins.git.BranchSpec')
337
338 # We use master branch for pipeline-library in case of 'testing,stable,nighlty' versions
339 # Leave proposed version as is
340 # in other cases we get release/{drivetrain_version} (e.g release/2019.2.0)
341 if drivetrain_version in ['testing', 'nightly', 'stable']:
342 expected_version = 'master'
343 else:
344 expected_version = local_salt_client.pillar_get(
345 tgt='gerrit:client',
346 param='jenkins:client:job:{}:scm:branch'.format(job_name))
347
348 if not BranchSpec:
Hanna Arhipova1eef8312019-05-06 20:14:18 +0300349 logging.debug("No BranchSpec has found for {} job".format(job_name))
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300350 continue
351
352 actual_version = BranchSpec[0].getElementsByTagName('name')[0].childNodes[0].data
Oleksii Zhurbae01d5e82019-05-17 14:04:28 -0500353 if expected_version and actual_version not in expected_version:
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300354 version_mismatch.append("Job {0} has {1} branch."
355 "Expected {2}".format(job_name,
356 actual_version,
357 expected_version))
358 assert len(version_mismatch) == 0, \
359 '''Some DriveTrain jobs have version/branch mismatch:
360 {}'''.format(json.dumps(version_mismatch, indent=4))
361
362
Oleksii Zhurba23c18332019-05-09 18:53:40 -0500363@pytest.mark.full
Hanna Arhipovae6ed8e42019-05-15 16:27:08 +0300364def test_drivetrain_jenkins_job(local_salt_client, check_cicd):
365 """
366 # Login to Jenkins on jenkins:client
367 # Read the name of jobs from configuration 'jenkins_test_job'
368 # Start job
369 # Wait till the job completed
370 # Check that job has completed with "SUCCESS" result
371 """
372 job_result = None
373
374 jenkins_password = get_password(local_salt_client, 'jenkins:client')
375 server = join_to_jenkins(local_salt_client, 'admin', jenkins_password)
376 # Getting Jenkins test job name from configuration
377 config = utils.get_configuration()
378 jenkins_test_job = config['jenkins_test_job']
379 if not server.get_job_name(jenkins_test_job):
380 server.create_job(jenkins_test_job, jenkins.EMPTY_CONFIG_XML)
381 if server.get_job_name(jenkins_test_job):
382 next_build_num = server.get_job_info(jenkins_test_job)['nextBuildNumber']
383 # If this is first build number skip building check
384 if next_build_num != 1:
385 # Check that test job is not running at this moment,
386 # Otherwise skip the test
387 last_build_num = server.get_job_info(jenkins_test_job)['lastBuild'].get('number')
388 last_build_status = server.get_build_info(jenkins_test_job, last_build_num)['building']
389 if last_build_status:
390 pytest.skip("Test job {0} is already running").format(jenkins_test_job)
391 server.build_job(jenkins_test_job)
392 timeout = 0
393 # Use job status True by default to exclude timeout between build job and start job.
394 job_status = True
395 while job_status and (timeout < 180):
396 time.sleep(10)
397 timeout += 10
398 job_status = server.get_build_info(jenkins_test_job, next_build_num)['building']
399 job_result = server.get_build_info(jenkins_test_job, next_build_num)['result']
400 else:
401 pytest.skip("The job {0} was not found").format(jenkins_test_job)
402 assert job_result == 'SUCCESS', \
403 '''Test job '{0}' build was not successful or timeout is too small
404 '''.format(jenkins_test_job)