The Gatekeeper, or a project gating system
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

701 lines
25 KiB

  1. # Copyright 2019 Red Hat
  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. import re
  15. import os
  16. import git
  17. import yaml
  18. import socket
  19. import zuul.rpcclient
  20. from tests.base import ZuulTestCase, simple_layout
  21. from tests.base import ZuulWebFixture
  22. from testtools.matchers import MatchesRegex
  23. class TestGitlabWebhook(ZuulTestCase):
  24. config_file = 'zuul-gitlab-driver.conf'
  25. def setUp(self):
  26. super().setUp()
  27. # Start the web server
  28. self.web = self.useFixture(
  29. ZuulWebFixture(self.gearman_server.port, self.changes, self.config,
  30. self.additional_event_queues, self.upstream_root,
  31. self.rpcclient, self.poller_events,
  32. self.git_url_with_auth, self.addCleanup,
  33. self.test_root))
  34. host = '127.0.0.1'
  35. # Wait until web server is started
  36. while True:
  37. port = self.web.port
  38. try:
  39. with socket.create_connection((host, port)):
  40. break
  41. except ConnectionRefusedError:
  42. pass
  43. self.fake_gitlab.setZuulWebPort(port)
  44. def tearDown(self):
  45. super(TestGitlabWebhook, self).tearDown()
  46. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  47. def test_webhook(self):
  48. A = self.fake_gitlab.openFakeMergeRequest(
  49. 'org/project', 'master', 'A')
  50. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent(),
  51. use_zuulweb=False,
  52. project='org/project')
  53. self.waitUntilSettled()
  54. self.assertEqual('SUCCESS',
  55. self.getJobFromHistory('project-test1').result)
  56. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  57. def test_webhook_via_zuulweb(self):
  58. A = self.fake_gitlab.openFakeMergeRequest(
  59. 'org/project', 'master', 'A')
  60. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent(),
  61. use_zuulweb=True,
  62. project='org/project')
  63. self.waitUntilSettled()
  64. self.assertEqual('SUCCESS',
  65. self.getJobFromHistory('project-test1').result)
  66. class TestGitlabDriver(ZuulTestCase):
  67. config_file = 'zuul-gitlab-driver.conf'
  68. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  69. def test_merge_request_opened(self):
  70. description = "This is the\nMR description."
  71. A = self.fake_gitlab.openFakeMergeRequest(
  72. 'org/project', 'master', 'A', description=description)
  73. self.fake_gitlab.emitEvent(
  74. A.getMergeRequestOpenedEvent(), project='org/project')
  75. self.waitUntilSettled()
  76. self.assertEqual('SUCCESS',
  77. self.getJobFromHistory('project-test1').result)
  78. self.assertEqual('SUCCESS',
  79. self.getJobFromHistory('project-test2').result)
  80. job = self.getJobFromHistory('project-test2')
  81. zuulvars = job.parameters['zuul']
  82. self.assertEqual(str(A.number), zuulvars['change'])
  83. self.assertEqual(str(A.sha), zuulvars['patchset'])
  84. self.assertEqual('master', zuulvars['branch'])
  85. self.assertEquals('https://gitlab/org/project/merge_requests/1',
  86. zuulvars['items'][0]['change_url'])
  87. self.assertEqual(zuulvars["message"], description)
  88. self.assertEqual(2, len(self.history))
  89. self.assertEqual(2, len(A.notes))
  90. self.assertEqual(
  91. A.notes[0]['body'], "Starting check jobs.")
  92. self.assertThat(
  93. A.notes[1]['body'],
  94. MatchesRegex(r'.*project-test1.*SUCCESS.*', re.DOTALL))
  95. self.assertThat(
  96. A.notes[1]['body'],
  97. MatchesRegex(r'.*project-test2.*SUCCESS.*', re.DOTALL))
  98. self.assertTrue(A.approved)
  99. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  100. def test_merge_request_updated(self):
  101. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  102. mr_tip1_sha = A.sha
  103. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  104. self.waitUntilSettled()
  105. self.assertEqual(2, len(self.history))
  106. self.assertHistory(
  107. [
  108. {'name': 'project-test1', 'changes': '1,%s' % mr_tip1_sha},
  109. {'name': 'project-test2', 'changes': '1,%s' % mr_tip1_sha},
  110. ], ordered=False
  111. )
  112. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  113. mr_tip2_sha = A.sha
  114. self.waitUntilSettled()
  115. self.assertEqual(4, len(self.history))
  116. self.assertHistory(
  117. [
  118. {'name': 'project-test1', 'changes': '1,%s' % mr_tip1_sha},
  119. {'name': 'project-test2', 'changes': '1,%s' % mr_tip1_sha},
  120. {'name': 'project-test1', 'changes': '1,%s' % mr_tip2_sha},
  121. {'name': 'project-test2', 'changes': '1,%s' % mr_tip2_sha}
  122. ], ordered=False
  123. )
  124. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  125. def test_merge_request_approved(self):
  126. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  127. self.fake_gitlab.emitEvent(A.getMergeRequestApprovedEvent())
  128. self.waitUntilSettled()
  129. self.assertEqual(1, len(self.history))
  130. self.fake_gitlab.emitEvent(A.getMergeRequestUnapprovedEvent())
  131. self.waitUntilSettled()
  132. self.assertEqual(2, len(self.history))
  133. job = self.getJobFromHistory('project-test-approval')
  134. zuulvars = job.parameters['zuul']
  135. self.assertEqual('check-approval', zuulvars['pipeline'])
  136. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  137. def test_merge_request_updated_during_build(self):
  138. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  139. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  140. old = A.sha
  141. A.addCommit()
  142. new = A.sha
  143. self.assertNotEqual(old, new)
  144. self.waitUntilSettled()
  145. self.assertEqual(2, len(self.history))
  146. # MR must not be approved: tested commit isn't current commit
  147. self.assertFalse(A.approved)
  148. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  149. self.waitUntilSettled()
  150. self.assertEqual(4, len(self.history))
  151. self.assertTrue(A.approved)
  152. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  153. def test_merge_request_labeled(self):
  154. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  155. self.fake_gitlab.emitEvent(A.getMergeRequestLabeledEvent(
  156. labels=('label1', 'label2')))
  157. self.waitUntilSettled()
  158. self.assertEqual(0, len(self.history))
  159. self.fake_gitlab.emitEvent(A.getMergeRequestLabeledEvent(
  160. labels=('gateit', )))
  161. self.waitUntilSettled()
  162. self.assertEqual(1, len(self.history))
  163. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  164. def test_merge_request_merged(self):
  165. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  166. self.fake_gitlab.emitEvent(A.getMergeRequestMergedEvent())
  167. self.waitUntilSettled()
  168. self.assertEqual(1, len(self.history))
  169. self.assertHistory([{'name': 'project-promote'}])
  170. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  171. def test_merge_request_updated_builds_aborted(self):
  172. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  173. mr_tip1_sha = A.sha
  174. self.executor_server.hold_jobs_in_build = True
  175. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  176. self.waitUntilSettled()
  177. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  178. mr_tip2_sha = A.sha
  179. self.waitUntilSettled()
  180. self.executor_server.hold_jobs_in_build = False
  181. self.executor_server.release()
  182. self.waitUntilSettled()
  183. self.assertHistory(
  184. [
  185. {'name': 'project-test1', 'result': 'ABORTED',
  186. 'changes': '1,%s' % mr_tip1_sha},
  187. {'name': 'project-test2', 'result': 'ABORTED',
  188. 'changes': '1,%s' % mr_tip1_sha},
  189. {'name': 'project-test1', 'changes': '1,%s' % mr_tip2_sha},
  190. {'name': 'project-test2', 'changes': '1,%s' % mr_tip2_sha}
  191. ], ordered=False
  192. )
  193. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  194. def test_merge_request_commented(self):
  195. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  196. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  197. self.waitUntilSettled()
  198. self.assertEqual(2, len(self.history))
  199. self.fake_gitlab.emitEvent(
  200. A.getMergeRequestCommentedEvent('I like that change'))
  201. self.waitUntilSettled()
  202. self.assertEqual(2, len(self.history))
  203. self.fake_gitlab.emitEvent(
  204. A.getMergeRequestCommentedEvent('recheck'))
  205. self.waitUntilSettled()
  206. self.assertEqual(4, len(self.history))
  207. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  208. def test_ref_updated(self):
  209. event = self.fake_gitlab.getPushEvent('org/project')
  210. expected_newrev = event[1]['after']
  211. expected_oldrev = event[1]['before']
  212. self.fake_gitlab.emitEvent(event)
  213. self.waitUntilSettled()
  214. self.assertEqual(1, len(self.history))
  215. self.assertEqual(
  216. 'SUCCESS',
  217. self.getJobFromHistory('project-post-job').result)
  218. job = self.getJobFromHistory('project-post-job')
  219. zuulvars = job.parameters['zuul']
  220. self.assertEqual('refs/heads/master', zuulvars['ref'])
  221. self.assertEqual('post', zuulvars['pipeline'])
  222. self.assertEqual('project-post-job', zuulvars['job'])
  223. self.assertEqual('master', zuulvars['branch'])
  224. self.assertEqual(
  225. 'https://gitlab/org/project/tree/%s' % zuulvars['newrev'],
  226. zuulvars['change_url'])
  227. self.assertEqual(expected_newrev, zuulvars['newrev'])
  228. self.assertEqual(expected_oldrev, zuulvars['oldrev'])
  229. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  230. def test_ref_created(self):
  231. self.create_branch('org/project', 'stable-1.0')
  232. path = os.path.join(self.upstream_root, 'org/project')
  233. repo = git.Repo(path)
  234. newrev = repo.commit('refs/heads/stable-1.0').hexsha
  235. event = self.fake_gitlab.getPushEvent(
  236. 'org/project', branch='refs/heads/stable-1.0',
  237. before='0' * 40, after=newrev)
  238. old = self.scheds.first.sched.tenant_last_reconfigured.get(
  239. 'tenant-one', 0)
  240. self.fake_gitlab.emitEvent(event)
  241. self.waitUntilSettled()
  242. new = self.scheds.first.sched.tenant_last_reconfigured.get(
  243. 'tenant-one', 0)
  244. # New timestamp should be greater than the old timestamp
  245. self.assertLess(old, new)
  246. self.assertEqual(1, len(self.history))
  247. self.assertEqual(
  248. 'SUCCESS',
  249. self.getJobFromHistory('project-post-job').result)
  250. job = self.getJobFromHistory('project-post-job')
  251. zuulvars = job.parameters['zuul']
  252. self.assertEqual('refs/heads/stable-1.0', zuulvars['ref'])
  253. self.assertEqual('post', zuulvars['pipeline'])
  254. self.assertEqual('project-post-job', zuulvars['job'])
  255. self.assertEqual('stable-1.0', zuulvars['branch'])
  256. self.assertEqual(newrev, zuulvars['newrev'])
  257. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  258. def test_ref_deleted(self):
  259. event = self.fake_gitlab.getPushEvent(
  260. 'org/project', 'stable-1.0', after='0' * 40)
  261. self.fake_gitlab.emitEvent(event)
  262. self.waitUntilSettled()
  263. self.assertEqual(0, len(self.history))
  264. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  265. def test_tag_created(self):
  266. path = os.path.join(self.upstream_root, 'org/project')
  267. repo = git.Repo(path)
  268. repo.create_tag('1.0')
  269. tagsha = repo.tags['1.0'].commit.hexsha
  270. event = self.fake_gitlab.getGitTagEvent(
  271. 'org/project', '1.0', tagsha)
  272. self.fake_gitlab.emitEvent(event)
  273. self.waitUntilSettled()
  274. self.assertEqual(1, len(self.history))
  275. self.assertEqual(
  276. 'SUCCESS',
  277. self.getJobFromHistory('project-tag-job').result)
  278. job = self.getJobFromHistory('project-tag-job')
  279. zuulvars = job.parameters['zuul']
  280. self.assertEqual('refs/tags/1.0', zuulvars['ref'])
  281. self.assertEqual('tag', zuulvars['pipeline'])
  282. self.assertEqual('project-tag-job', zuulvars['job'])
  283. self.assertEqual(tagsha, zuulvars['newrev'])
  284. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  285. def test_pull_request_with_dyn_reconf(self):
  286. zuul_yaml = [
  287. {'job': {
  288. 'name': 'project-test3',
  289. 'run': 'job.yaml'
  290. }},
  291. {'project': {
  292. 'check': {
  293. 'jobs': [
  294. 'project-test3'
  295. ]
  296. }
  297. }}
  298. ]
  299. playbook = "- hosts: all\n tasks: []"
  300. A = self.fake_gitlab.openFakeMergeRequest(
  301. 'org/project', 'master', 'A')
  302. A.addCommit(
  303. {'.zuul.yaml': yaml.dump(zuul_yaml),
  304. 'job.yaml': playbook}
  305. )
  306. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  307. self.waitUntilSettled()
  308. self.assertEqual('SUCCESS',
  309. self.getJobFromHistory('project-test1').result)
  310. self.assertEqual('SUCCESS',
  311. self.getJobFromHistory('project-test2').result)
  312. self.assertEqual('SUCCESS',
  313. self.getJobFromHistory('project-test3').result)
  314. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  315. def test_ref_updated_and_tenant_reconfigure(self):
  316. self.waitUntilSettled()
  317. old = self.scheds.first.sched.tenant_last_reconfigured\
  318. .get('tenant-one', 0)
  319. zuul_yaml = [
  320. {'job': {
  321. 'name': 'project-post-job2',
  322. 'run': 'job.yaml'
  323. }},
  324. {'project': {
  325. 'post': {
  326. 'jobs': [
  327. 'project-post-job2'
  328. ]
  329. }
  330. }}
  331. ]
  332. playbook = "- hosts: all\n tasks: []"
  333. self.create_commit(
  334. 'org/project',
  335. {'.zuul.yaml': yaml.dump(zuul_yaml),
  336. 'job.yaml': playbook},
  337. message='Add InRepo configuration'
  338. )
  339. event = self.fake_gitlab.getPushEvent('org/project')
  340. self.fake_gitlab.emitEvent(event)
  341. self.waitUntilSettled()
  342. new = self.scheds.first.sched.tenant_last_reconfigured\
  343. .get('tenant-one', 0)
  344. # New timestamp should be greater than the old timestamp
  345. self.assertLess(old, new)
  346. self.assertHistory(
  347. [{'name': 'project-post-job'},
  348. {'name': 'project-post-job2'},
  349. ], ordered=False
  350. )
  351. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  352. def test_client_dequeue_change(self):
  353. client = zuul.rpcclient.RPCClient('127.0.0.1',
  354. self.gearman_server.port)
  355. self.addCleanup(client.shutdown)
  356. self.executor_server.hold_jobs_in_build = True
  357. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  358. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  359. self.waitUntilSettled()
  360. client.dequeue(
  361. tenant='tenant-one',
  362. pipeline='check',
  363. project='org/project',
  364. change='%s,%s' % (A.number, A.sha),
  365. ref=None)
  366. self.waitUntilSettled()
  367. tenant = self.scheds.first.sched.abide.tenants.get('tenant-one')
  368. check_pipeline = tenant.layout.pipelines['check']
  369. self.assertEqual(check_pipeline.getAllItems(), [])
  370. self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 2)
  371. self.executor_server.hold_jobs_in_build = False
  372. self.executor_server.release()
  373. self.waitUntilSettled()
  374. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  375. def test_client_enqueue_change(self):
  376. A = self.fake_gitlab.openFakeMergeRequest('org/project', 'master', 'A')
  377. client = zuul.rpcclient.RPCClient('127.0.0.1',
  378. self.gearman_server.port)
  379. self.addCleanup(client.shutdown)
  380. r = client.enqueue(tenant='tenant-one',
  381. pipeline='check',
  382. project='org/project',
  383. trigger='gitlab',
  384. change='%s,%s' % (A.number, A.sha))
  385. self.waitUntilSettled()
  386. self.assertEqual(self.getJobFromHistory('project-test1').result,
  387. 'SUCCESS')
  388. self.assertEqual(self.getJobFromHistory('project-test2').result,
  389. 'SUCCESS')
  390. self.assertEqual(r, True)
  391. @simple_layout('layouts/basic-gitlab.yaml', driver='gitlab')
  392. def test_client_enqueue_ref(self):
  393. repo_path = os.path.join(self.upstream_root, 'org/project')
  394. repo = git.Repo(repo_path)
  395. headsha = repo.head.commit.hexsha
  396. client = zuul.rpcclient.RPCClient('127.0.0.1',
  397. self.gearman_server.port)
  398. self.addCleanup(client.shutdown)
  399. r = client.enqueue_ref(
  400. tenant='tenant-one',
  401. pipeline='post',
  402. project='org/project',
  403. trigger='gitlab',
  404. ref='master',
  405. oldrev='1' * 40,
  406. newrev=headsha)
  407. self.waitUntilSettled()
  408. self.assertEqual(self.getJobFromHistory('project-post-job').result,
  409. 'SUCCESS')
  410. self.assertEqual(r, True)
  411. @simple_layout('layouts/crd-gitlab.yaml', driver='gitlab')
  412. def test_crd_independent(self):
  413. # Create a change in project1 that a project2 change will depend on
  414. A = self.fake_gitlab.openFakeMergeRequest(
  415. 'org/project1', 'master', 'A')
  416. # Create a commit in B that sets the dependency on A
  417. msg = "Depends-On: %s" % A.url
  418. B = self.fake_gitlab.openFakeMergeRequest(
  419. 'org/project2', 'master', 'B', description=msg)
  420. # Make an event to re-use
  421. self.fake_gitlab.emitEvent(B.getMergeRequestOpenedEvent())
  422. self.waitUntilSettled()
  423. # The changes for the job from project2 should include the project1
  424. # PR content
  425. changes = self.getJobFromHistory(
  426. 'project2-test', 'org/project2').changes
  427. self.assertEqual(changes, "%s,%s %s,%s" % (A.number,
  428. A.sha,
  429. B.number,
  430. B.sha))
  431. # There should be no more changes in the queue
  432. tenant = self.scheds.first.sched.abide.tenants.get('tenant-one')
  433. self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
  434. @simple_layout('layouts/requirements-gitlab.yaml', driver='gitlab')
  435. def test_state_require(self):
  436. A = self.fake_gitlab.openFakeMergeRequest(
  437. 'org/project1', 'master', 'A')
  438. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  439. self.waitUntilSettled()
  440. self.assertEqual(1, len(self.history))
  441. # Close the MR
  442. A.closeMergeRequest()
  443. # A recheck will not trigger the job
  444. self.fake_gitlab.emitEvent(
  445. A.getMergeRequestCommentedEvent('recheck'))
  446. self.waitUntilSettled()
  447. self.assertEqual(1, len(self.history))
  448. # Merge the MR
  449. A.mergeMergeRequest()
  450. # A recheck will not trigger the job
  451. self.fake_gitlab.emitEvent(
  452. A.getMergeRequestCommentedEvent('recheck'))
  453. self.waitUntilSettled()
  454. self.assertEqual(1, len(self.history))
  455. # Re-open the MR
  456. A.reopenMergeRequest()
  457. # A recheck will trigger the job
  458. self.fake_gitlab.emitEvent(
  459. A.getMergeRequestCommentedEvent('recheck'))
  460. self.waitUntilSettled()
  461. self.assertEqual(2, len(self.history))
  462. @simple_layout('layouts/requirements-gitlab.yaml', driver='gitlab')
  463. def test_approval_require(self):
  464. A = self.fake_gitlab.openFakeMergeRequest(
  465. 'org/project2', 'master', 'A')
  466. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  467. self.waitUntilSettled()
  468. self.assertEqual(0, len(self.history))
  469. A.approved = True
  470. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  471. self.waitUntilSettled()
  472. self.assertEqual(1, len(self.history))
  473. A.approved = False
  474. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  475. self.waitUntilSettled()
  476. self.assertEqual(1, len(self.history))
  477. @simple_layout('layouts/requirements-gitlab.yaml', driver='gitlab')
  478. def test_approval_require_community_edition(self):
  479. with self.fake_gitlab.enable_community_edition():
  480. A = self.fake_gitlab.openFakeMergeRequest(
  481. 'org/project2', 'master', 'A')
  482. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  483. self.waitUntilSettled()
  484. self.assertEqual(0, len(self.history))
  485. A.approved = True
  486. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  487. self.waitUntilSettled()
  488. self.assertEqual(1, len(self.history))
  489. A.approved = False
  490. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  491. self.waitUntilSettled()
  492. self.assertEqual(1, len(self.history))
  493. @simple_layout('layouts/requirements-gitlab.yaml', driver='gitlab')
  494. def test_label_require(self):
  495. A = self.fake_gitlab.openFakeMergeRequest(
  496. 'org/project3', 'master', 'A')
  497. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  498. self.waitUntilSettled()
  499. self.assertEqual(0, len(self.history))
  500. A.labels = ['gateit', 'prio:low']
  501. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  502. self.waitUntilSettled()
  503. self.assertEqual(1, len(self.history))
  504. @simple_layout('layouts/merging-gitlab.yaml', driver='gitlab')
  505. def test_merge_action_in_independent(self):
  506. A = self.fake_gitlab.openFakeMergeRequest(
  507. 'org/project1', 'master', 'A')
  508. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  509. self.waitUntilSettled()
  510. self.assertEqual(1, len(self.history))
  511. self.assertEqual('SUCCESS',
  512. self.getJobFromHistory('project-test').result)
  513. self.assertEqual('merged', A.state)
  514. @simple_layout('layouts/merging-gitlab.yaml', driver='gitlab')
  515. def test_merge_action_in_dependent(self):
  516. A = self.fake_gitlab.openFakeMergeRequest(
  517. 'org/project2', 'master', 'A')
  518. A.merge_status = 'cannot_be_merged'
  519. self.fake_gitlab.emitEvent(A.getMergeRequestOpenedEvent())
  520. self.waitUntilSettled()
  521. # canMerge is not validated
  522. self.assertEqual(0, len(self.history))
  523. # Set Merge request can be merged
  524. A.merge_status = 'can_be_merged'
  525. self.fake_gitlab.emitEvent(A.getMergeRequestUpdatedEvent())
  526. self.waitUntilSettled()
  527. # canMerge is validated
  528. self.assertEqual(1, len(self.history))
  529. self.assertEqual('SUCCESS',
  530. self.getJobFromHistory('project-test').result)
  531. self.assertEqual('merged', A.state)
  532. @simple_layout('layouts/crd-gitlab.yaml', driver='gitlab')
  533. def test_crd_dependent(self):
  534. # Create a change in project3 that a project4 change will depend on
  535. A = self.fake_gitlab.openFakeMergeRequest(
  536. 'org/project3', 'master', 'A')
  537. A.approved = True
  538. # Create a change B that sets the dependency on A
  539. msg = "Depends-On: %s" % A.url
  540. B = self.fake_gitlab.openFakeMergeRequest(
  541. 'org/project4', 'master', 'B', description=msg)
  542. # Emit B opened event
  543. event = B.getMergeRequestOpenedEvent()
  544. self.fake_gitlab.emitEvent(event)
  545. self.waitUntilSettled()
  546. # B cannot be merged (not approved)
  547. self.assertEqual(0, len(self.history))
  548. # Approve B
  549. B.approved = True
  550. # And send the event
  551. self.fake_gitlab.emitEvent(event)
  552. self.waitUntilSettled()
  553. # The changes for the job from project4 should include the project3
  554. # PR content
  555. changes = self.getJobFromHistory(
  556. 'project4-test', 'org/project4').changes
  557. self.assertEqual(changes, "%s,%s %s,%s" % (A.number,
  558. A.sha,
  559. B.number,
  560. B.sha))
  561. self.assertTrue(A.is_merged)
  562. self.assertTrue(B.is_merged)