Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | # Copyright 2012 Hewlett-Packard Development Company, L.P. |
| 4 | # Copyright 2014 Wikimedia Foundation Inc. |
| 5 | # |
| 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 7 | # not use this file except in compliance with the License. You may obtain |
| 8 | # a copy of the License at |
| 9 | # |
| 10 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | # |
| 12 | # Unless required by applicable law or agreed to in writing, software |
| 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 15 | # License for the specific language governing permissions and limitations |
| 16 | # under the License. |
| 17 | |
James E. Blair | df37ad2 | 2018-02-01 13:59:48 -0800 | [diff] [blame] | 18 | try: |
| 19 | from unittest import mock |
| 20 | except ImportError: |
| 21 | import mock |
| 22 | |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 23 | import logging |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 24 | import time |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 25 | |
Tristan Cacqueray | 8095440 | 2017-05-28 00:33:55 +0000 | [diff] [blame] | 26 | import zuul.executor.server |
| 27 | import zuul.model |
| 28 | |
James E. Blair | d8af542 | 2017-05-24 13:59:40 -0700 | [diff] [blame] | 29 | from tests.base import ZuulTestCase, simple_layout |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 30 | |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 31 | |
James E. Blair | b3b5b38 | 2017-06-02 11:29:57 -0700 | [diff] [blame] | 32 | class TestExecutorRepos(ZuulTestCase): |
James E. Blair | d8af542 | 2017-05-24 13:59:40 -0700 | [diff] [blame] | 33 | tenant_config_file = 'config/single-tenant/main.yaml' |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 34 | |
James E. Blair | b3b5b38 | 2017-06-02 11:29:57 -0700 | [diff] [blame] | 35 | log = logging.getLogger("zuul.test.executor") |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 36 | |
James E. Blair | af3d01e | 2017-05-26 14:30:18 -0700 | [diff] [blame] | 37 | def assertRepoState(self, repo, state, project, build, number): |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 38 | if 'branch' in state: |
| 39 | self.assertFalse(repo.head.is_detached, |
| 40 | 'Project %s commit for build %s #%s should ' |
| 41 | 'not have a detached HEAD' % ( |
| 42 | project, build, number)) |
zhangyangyang | c3e786f | 2017-09-13 10:47:52 +0800 | [diff] [blame] | 43 | self.assertEqual(repo.active_branch.name, |
| 44 | state['branch'], |
| 45 | 'Project %s commit for build %s #%s should ' |
| 46 | 'be on the correct branch' % ( |
| 47 | project, build, number)) |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 48 | if 'commit' in state: |
zhangyangyang | c3e786f | 2017-09-13 10:47:52 +0800 | [diff] [blame] | 49 | self.assertEqual(state['commit'], |
| 50 | str(repo.commit('HEAD')), |
| 51 | 'Project %s commit for build %s #%s should ' |
| 52 | 'be correct' % ( |
| 53 | project, build, number)) |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 54 | ref = repo.commit('HEAD') |
| 55 | repo_messages = set( |
| 56 | [c.message.strip() for c in repo.iter_commits(ref)]) |
| 57 | if 'present' in state: |
| 58 | for change in state['present']: |
James E. Blair | af3d01e | 2017-05-26 14:30:18 -0700 | [diff] [blame] | 59 | msg = '%s-1' % change.subject |
| 60 | self.assertTrue(msg in repo_messages, |
| 61 | 'Project %s for build %s #%s should ' |
| 62 | 'have change %s' % ( |
| 63 | project, build, number, change.subject)) |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 64 | if 'absent' in state: |
| 65 | for change in state['absent']: |
James E. Blair | af3d01e | 2017-05-26 14:30:18 -0700 | [diff] [blame] | 66 | msg = '%s-1' % change.subject |
| 67 | self.assertTrue(msg not in repo_messages, |
| 68 | 'Project %s for build %s #%s should ' |
| 69 | 'not have change %s' % ( |
| 70 | project, build, number, change.subject)) |
| 71 | |
James E. Blair | 987855f | 2017-06-06 14:41:58 -0700 | [diff] [blame] | 72 | def assertBuildStates(self, states, projects): |
| 73 | for number, build in enumerate(self.builds): |
| 74 | work = build.getWorkspaceRepos(projects) |
| 75 | state = states[number] |
| 76 | |
| 77 | for project in projects: |
| 78 | self.assertRepoState(work[project], state[project], |
| 79 | project, build, number) |
| 80 | |
| 81 | self.executor_server.hold_jobs_in_build = False |
| 82 | self.executor_server.release() |
| 83 | self.waitUntilSettled() |
| 84 | |
James E. Blair | d8af542 | 2017-05-24 13:59:40 -0700 | [diff] [blame] | 85 | @simple_layout('layouts/repo-checkout-two-project.yaml') |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 86 | def test_one_branch(self): |
James E. Blair | d8af542 | 2017-05-24 13:59:40 -0700 | [diff] [blame] | 87 | self.executor_server.hold_jobs_in_build = True |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 88 | |
James E. Blair | d8af542 | 2017-05-24 13:59:40 -0700 | [diff] [blame] | 89 | p1 = 'review.example.com/org/project1' |
| 90 | p2 = 'review.example.com/org/project2' |
| 91 | projects = [p1, p2] |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 92 | A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A') |
| 93 | B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B') |
Tobias Henkel | bf24fd1 | 2017-07-27 06:13:07 +0200 | [diff] [blame] | 94 | A.addApproval('Code-Review', 2) |
| 95 | B.addApproval('Code-Review', 2) |
| 96 | self.fake_gerrit.addEvent(A.addApproval('Approved', 1)) |
| 97 | self.fake_gerrit.addEvent(B.addApproval('Approved', 1)) |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 98 | |
| 99 | self.waitUntilSettled() |
| 100 | |
zhangyangyang | c3e786f | 2017-09-13 10:47:52 +0800 | [diff] [blame] | 101 | self.assertEqual(2, len(self.builds), "Two builds are running") |
Antoine Musso | 45dd2cb | 2014-01-29 17:17:43 +0100 | [diff] [blame] | 102 | |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 103 | upstream = self.getUpstreamRepos(projects) |
| 104 | states = [ |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 105 | {p1: dict(present=[A], absent=[B], branch='master'), |
| 106 | p2: dict(commit=str(upstream[p2].commit('master')), |
| 107 | branch='master'), |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 108 | }, |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 109 | {p1: dict(present=[A], absent=[B], branch='master'), |
| 110 | p2: dict(present=[B], absent=[A], branch='master'), |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 111 | }, |
Joshua Hesketh | 29d99b7 | 2014-08-19 16:27:42 +1000 | [diff] [blame] | 112 | ] |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 113 | |
James E. Blair | 987855f | 2017-06-06 14:41:58 -0700 | [diff] [blame] | 114 | self.assertBuildStates(states, projects) |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 115 | |
James E. Blair | af3d01e | 2017-05-26 14:30:18 -0700 | [diff] [blame] | 116 | @simple_layout('layouts/repo-checkout-four-project.yaml') |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 117 | def test_multi_branch(self): |
James E. Blair | af3d01e | 2017-05-26 14:30:18 -0700 | [diff] [blame] | 118 | self.executor_server.hold_jobs_in_build = True |
| 119 | |
| 120 | p1 = 'review.example.com/org/project1' |
| 121 | p2 = 'review.example.com/org/project2' |
| 122 | p3 = 'review.example.com/org/project3' |
| 123 | p4 = 'review.example.com/org/project4' |
| 124 | projects = [p1, p2, p3, p4] |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 125 | |
| 126 | self.create_branch('org/project2', 'stable/havana') |
| 127 | self.create_branch('org/project4', 'stable/havana') |
| 128 | A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A') |
Joshua Hesketh | 29d99b7 | 2014-08-19 16:27:42 +1000 | [diff] [blame] | 129 | B = self.fake_gerrit.addFakeChange('org/project2', 'stable/havana', |
| 130 | 'B') |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 131 | C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C') |
Tobias Henkel | bf24fd1 | 2017-07-27 06:13:07 +0200 | [diff] [blame] | 132 | A.addApproval('Code-Review', 2) |
| 133 | B.addApproval('Code-Review', 2) |
| 134 | C.addApproval('Code-Review', 2) |
| 135 | self.fake_gerrit.addEvent(A.addApproval('Approved', 1)) |
| 136 | self.fake_gerrit.addEvent(B.addApproval('Approved', 1)) |
| 137 | self.fake_gerrit.addEvent(C.addApproval('Approved', 1)) |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 138 | |
| 139 | self.waitUntilSettled() |
| 140 | |
zhangyangyang | c3e786f | 2017-09-13 10:47:52 +0800 | [diff] [blame] | 141 | self.assertEqual(3, len(self.builds), "Three builds are running") |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 142 | |
| 143 | upstream = self.getUpstreamRepos(projects) |
| 144 | states = [ |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 145 | {p1: dict(present=[A], absent=[B, C], branch='master'), |
| 146 | p2: dict(commit=str(upstream[p2].commit('master')), |
| 147 | branch='master'), |
| 148 | p3: dict(commit=str(upstream[p3].commit('master')), |
| 149 | branch='master'), |
| 150 | p4: dict(commit=str(upstream[p4].commit('master')), |
| 151 | branch='master'), |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 152 | }, |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 153 | {p1: dict(present=[A], absent=[B, C], branch='master'), |
| 154 | p2: dict(present=[B], absent=[A, C], branch='stable/havana'), |
| 155 | p3: dict(commit=str(upstream[p3].commit('master')), |
| 156 | branch='master'), |
| 157 | p4: dict(commit=str(upstream[p4].commit('stable/havana')), |
| 158 | branch='stable/havana'), |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 159 | }, |
James E. Blair | bcaa2d4 | 2017-05-26 15:44:23 -0700 | [diff] [blame] | 160 | {p1: dict(present=[A], absent=[B, C], branch='master'), |
| 161 | p2: dict(commit=str(upstream[p2].commit('master')), |
| 162 | branch='master'), |
| 163 | p3: dict(present=[C], absent=[A, B], branch='master'), |
| 164 | p4: dict(commit=str(upstream[p4].commit('master')), |
| 165 | branch='master'), |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 166 | }, |
Joshua Hesketh | 29d99b7 | 2014-08-19 16:27:42 +1000 | [diff] [blame] | 167 | ] |
James E. Blair | 97d902e | 2014-08-21 13:25:56 -0700 | [diff] [blame] | 168 | |
James E. Blair | 987855f | 2017-06-06 14:41:58 -0700 | [diff] [blame] | 169 | self.assertBuildStates(states, projects) |
James E. Blair | bce35e1 | 2014-08-21 14:31:17 -0700 | [diff] [blame] | 170 | |
James E. Blair | 4de8d9e | 2017-06-01 15:41:40 -0700 | [diff] [blame] | 171 | @simple_layout('layouts/repo-checkout-six-project.yaml') |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 172 | def test_project_override(self): |
James E. Blair | 4de8d9e | 2017-06-01 15:41:40 -0700 | [diff] [blame] | 173 | self.executor_server.hold_jobs_in_build = True |
| 174 | |
| 175 | p1 = 'review.example.com/org/project1' |
| 176 | p2 = 'review.example.com/org/project2' |
| 177 | p3 = 'review.example.com/org/project3' |
| 178 | p4 = 'review.example.com/org/project4' |
| 179 | p5 = 'review.example.com/org/project5' |
| 180 | p6 = 'review.example.com/org/project6' |
| 181 | projects = [p1, p2, p3, p4, p5, p6] |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 182 | |
| 183 | self.create_branch('org/project3', 'stable/havana') |
| 184 | self.create_branch('org/project4', 'stable/havana') |
| 185 | self.create_branch('org/project6', 'stable/havana') |
| 186 | A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A') |
| 187 | B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B') |
| 188 | C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C') |
Joshua Hesketh | 29d99b7 | 2014-08-19 16:27:42 +1000 | [diff] [blame] | 189 | D = self.fake_gerrit.addFakeChange('org/project3', 'stable/havana', |
| 190 | 'D') |
Tobias Henkel | bf24fd1 | 2017-07-27 06:13:07 +0200 | [diff] [blame] | 191 | A.addApproval('Code-Review', 2) |
| 192 | B.addApproval('Code-Review', 2) |
| 193 | C.addApproval('Code-Review', 2) |
| 194 | D.addApproval('Code-Review', 2) |
| 195 | self.fake_gerrit.addEvent(A.addApproval('Approved', 1)) |
| 196 | self.fake_gerrit.addEvent(B.addApproval('Approved', 1)) |
| 197 | self.fake_gerrit.addEvent(C.addApproval('Approved', 1)) |
| 198 | self.fake_gerrit.addEvent(D.addApproval('Approved', 1)) |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 199 | |
| 200 | self.waitUntilSettled() |
| 201 | |
zhangyangyang | c3e786f | 2017-09-13 10:47:52 +0800 | [diff] [blame] | 202 | self.assertEqual(4, len(self.builds), "Four builds are running") |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 203 | |
| 204 | upstream = self.getUpstreamRepos(projects) |
| 205 | states = [ |
James E. Blair | 4de8d9e | 2017-06-01 15:41:40 -0700 | [diff] [blame] | 206 | {p1: dict(present=[A], absent=[B, C, D], branch='master'), |
| 207 | p2: dict(commit=str(upstream[p2].commit('master')), |
| 208 | branch='master'), |
| 209 | p3: dict(commit=str(upstream[p3].commit('master')), |
| 210 | branch='master'), |
| 211 | p4: dict(commit=str(upstream[p4].commit('master')), |
| 212 | branch='master'), |
| 213 | p5: dict(commit=str(upstream[p5].commit('master')), |
| 214 | branch='master'), |
| 215 | p6: dict(commit=str(upstream[p6].commit('master')), |
| 216 | branch='master'), |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 217 | }, |
James E. Blair | 4de8d9e | 2017-06-01 15:41:40 -0700 | [diff] [blame] | 218 | {p1: dict(present=[A, B], absent=[C, D], branch='master'), |
| 219 | p2: dict(commit=str(upstream[p2].commit('master')), |
| 220 | branch='master'), |
| 221 | p3: dict(commit=str(upstream[p3].commit('master')), |
| 222 | branch='master'), |
| 223 | p4: dict(commit=str(upstream[p4].commit('master')), |
| 224 | branch='master'), |
| 225 | p5: dict(commit=str(upstream[p5].commit('master')), |
| 226 | branch='master'), |
| 227 | p6: dict(commit=str(upstream[p6].commit('master')), |
| 228 | branch='master'), |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 229 | }, |
James E. Blair | 4de8d9e | 2017-06-01 15:41:40 -0700 | [diff] [blame] | 230 | {p1: dict(present=[A, B], absent=[C, D], branch='master'), |
| 231 | p2: dict(present=[C], absent=[A, B, D], branch='master'), |
| 232 | p3: dict(commit=str(upstream[p3].commit('master')), |
| 233 | branch='master'), |
| 234 | p4: dict(commit=str(upstream[p4].commit('master')), |
| 235 | branch='master'), |
| 236 | p5: dict(commit=str(upstream[p5].commit('master')), |
| 237 | branch='master'), |
| 238 | p6: dict(commit=str(upstream[p6].commit('master')), |
| 239 | branch='master'), |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 240 | }, |
James E. Blair | 4de8d9e | 2017-06-01 15:41:40 -0700 | [diff] [blame] | 241 | {p1: dict(present=[A, B], absent=[C, D], branch='master'), |
| 242 | p2: dict(present=[C], absent=[A, B, D], branch='master'), |
| 243 | p3: dict(present=[D], absent=[A, B, C], |
| 244 | branch='stable/havana'), |
| 245 | p4: dict(commit=str(upstream[p4].commit('master')), |
| 246 | branch='master'), |
| 247 | p5: dict(commit=str(upstream[p5].commit('master')), |
| 248 | branch='master'), |
| 249 | p6: dict(commit=str(upstream[p6].commit('stable/havana')), |
| 250 | branch='stable/havana'), |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 251 | }, |
Joshua Hesketh | 29d99b7 | 2014-08-19 16:27:42 +1000 | [diff] [blame] | 252 | ] |
James E. Blair | f042022 | 2014-08-21 16:02:17 -0700 | [diff] [blame] | 253 | |
James E. Blair | 987855f | 2017-06-06 14:41:58 -0700 | [diff] [blame] | 254 | self.assertBuildStates(states, projects) |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 255 | |
James E. Blair | 2103778 | 2017-07-19 11:56:55 -0700 | [diff] [blame] | 256 | def test_periodic_override(self): |
| 257 | # This test can not use simple_layout because it must start |
| 258 | # with a configuration which does not include a |
| 259 | # timer-triggered job so that we have an opportunity to set |
| 260 | # the hold flag before the first job. |
| 261 | |
| 262 | # This tests that we can override the branch in a timer |
| 263 | # trigger (mostly to ensure backwards compatability for jobs). |
| 264 | self.executor_server.hold_jobs_in_build = True |
| 265 | # Start timer trigger - also org/project |
| 266 | self.commitConfigUpdate('common-config', |
| 267 | 'layouts/repo-checkout-timer-override.yaml') |
| 268 | self.sched.reconfigure(self.config) |
| 269 | |
| 270 | p1 = 'review.example.com/org/project1' |
| 271 | projects = [p1] |
| 272 | self.create_branch('org/project1', 'stable/havana') |
| 273 | |
| 274 | # The pipeline triggers every second, so we should have seen |
| 275 | # several by now. |
| 276 | time.sleep(5) |
| 277 | self.waitUntilSettled() |
| 278 | |
| 279 | # Stop queuing timer triggered jobs so that the assertions |
| 280 | # below don't race against more jobs being queued. |
| 281 | self.commitConfigUpdate('common-config', |
James E. Blair | 0b137b4 | 2017-07-27 08:51:25 -0700 | [diff] [blame] | 282 | 'layouts/repo-checkout-no-timer-override.yaml') |
James E. Blair | 2103778 | 2017-07-19 11:56:55 -0700 | [diff] [blame] | 283 | self.sched.reconfigure(self.config) |
James E. Blair | 0b137b4 | 2017-07-27 08:51:25 -0700 | [diff] [blame] | 284 | self.waitUntilSettled() |
James E. Blair | 78ae478 | 2017-08-02 14:19:10 -0700 | [diff] [blame] | 285 | # If APScheduler is in mid-event when we remove the job, we |
| 286 | # can end up with one more event firing, so give it an extra |
| 287 | # second to settle. |
| 288 | time.sleep(1) |
| 289 | self.waitUntilSettled() |
James E. Blair | 2103778 | 2017-07-19 11:56:55 -0700 | [diff] [blame] | 290 | |
zhangyangyang | c3e786f | 2017-09-13 10:47:52 +0800 | [diff] [blame] | 291 | self.assertEqual(1, len(self.builds), "One build is running") |
James E. Blair | 2103778 | 2017-07-19 11:56:55 -0700 | [diff] [blame] | 292 | |
| 293 | upstream = self.getUpstreamRepos(projects) |
| 294 | states = [ |
| 295 | {p1: dict(commit=str(upstream[p1].commit('stable/havana')), |
| 296 | branch='stable/havana'), |
| 297 | }, |
| 298 | ] |
| 299 | |
| 300 | self.assertBuildStates(states, projects) |
| 301 | |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 302 | def test_periodic(self): |
James E. Blair | 95ae4fc | 2017-06-01 15:54:53 -0700 | [diff] [blame] | 303 | # This test can not use simple_layout because it must start |
| 304 | # with a configuration which does not include a |
| 305 | # timer-triggered job so that we have an opportunity to set |
| 306 | # the hold flag before the first job. |
| 307 | self.executor_server.hold_jobs_in_build = True |
| 308 | # Start timer trigger - also org/project |
| 309 | self.commitConfigUpdate('common-config', |
| 310 | 'layouts/repo-checkout-timer.yaml') |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 311 | self.sched.reconfigure(self.config) |
James E. Blair | 95ae4fc | 2017-06-01 15:54:53 -0700 | [diff] [blame] | 312 | |
| 313 | p1 = 'review.example.com/org/project1' |
| 314 | projects = [p1] |
| 315 | self.create_branch('org/project1', 'stable/havana') |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 316 | |
| 317 | # The pipeline triggers every second, so we should have seen |
| 318 | # several by now. |
| 319 | time.sleep(5) |
| 320 | self.waitUntilSettled() |
| 321 | |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 322 | # Stop queuing timer triggered jobs so that the assertions |
| 323 | # below don't race against more jobs being queued. |
James E. Blair | 95ae4fc | 2017-06-01 15:54:53 -0700 | [diff] [blame] | 324 | self.commitConfigUpdate('common-config', |
| 325 | 'layouts/repo-checkout-no-timer.yaml') |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 326 | self.sched.reconfigure(self.config) |
James E. Blair | 0b137b4 | 2017-07-27 08:51:25 -0700 | [diff] [blame] | 327 | self.waitUntilSettled() |
James E. Blair | 78ae478 | 2017-08-02 14:19:10 -0700 | [diff] [blame] | 328 | # If APScheduler is in mid-event when we remove the job, we |
| 329 | # can end up with one more event firing, so give it an extra |
| 330 | # second to settle. |
| 331 | time.sleep(1) |
| 332 | self.waitUntilSettled() |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 333 | |
zhangyangyang | c3e786f | 2017-09-13 10:47:52 +0800 | [diff] [blame] | 334 | self.assertEqual(2, len(self.builds), "Two builds are running") |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 335 | |
| 336 | upstream = self.getUpstreamRepos(projects) |
| 337 | states = [ |
James E. Blair | 95ae4fc | 2017-06-01 15:54:53 -0700 | [diff] [blame] | 338 | {p1: dict(commit=str(upstream[p1].commit('stable/havana')), |
| 339 | branch='stable/havana'), |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 340 | }, |
James E. Blair | 2103778 | 2017-07-19 11:56:55 -0700 | [diff] [blame] | 341 | {p1: dict(commit=str(upstream[p1].commit('master')), |
| 342 | branch='master'), |
| 343 | }, |
Joshua Hesketh | 29d99b7 | 2014-08-19 16:27:42 +1000 | [diff] [blame] | 344 | ] |
James E. Blair | 2103778 | 2017-07-19 11:56:55 -0700 | [diff] [blame] | 345 | if self.builds[0].parameters['zuul']['ref'] == 'refs/heads/master': |
| 346 | states = list(reversed(states)) |
James E. Blair | 217b10d | 2015-01-08 16:25:28 -0800 | [diff] [blame] | 347 | |
James E. Blair | 987855f | 2017-06-06 14:41:58 -0700 | [diff] [blame] | 348 | self.assertBuildStates(states, projects) |
Sachi King | 9f16d52 | 2016-03-16 12:20:45 +1100 | [diff] [blame] | 349 | |
James E. Blair | bbe811e | 2017-06-02 10:47:44 -0700 | [diff] [blame] | 350 | @simple_layout('layouts/repo-checkout-post.yaml') |
Sachi King | 9f16d52 | 2016-03-16 12:20:45 +1100 | [diff] [blame] | 351 | def test_post_and_master_checkout(self): |
James E. Blair | 1de2e49 | 2017-06-02 11:04:42 -0700 | [diff] [blame] | 352 | self.executor_server.hold_jobs_in_build = True |
| 353 | p1 = "review.example.com/org/project1" |
| 354 | p2 = "review.example.com/org/project2" |
| 355 | projects = [p1, p2] |
James E. Blair | 289f593 | 2017-07-27 15:02:29 -0700 | [diff] [blame] | 356 | upstream = self.getUpstreamRepos(projects) |
James E. Blair | 8cce42e | 2016-10-18 08:18:36 -0700 | [diff] [blame] | 357 | |
James E. Blair | 1de2e49 | 2017-06-02 11:04:42 -0700 | [diff] [blame] | 358 | A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A') |
James E. Blair | 8cce42e | 2016-10-18 08:18:36 -0700 | [diff] [blame] | 359 | event = A.getRefUpdatedEvent() |
| 360 | A.setMerged() |
James E. Blair | 289f593 | 2017-07-27 15:02:29 -0700 | [diff] [blame] | 361 | A_commit = str(upstream[p1].commit('master')) |
| 362 | self.log.debug("A commit: %s" % A_commit) |
| 363 | |
| 364 | # Add another commit to the repo that merged right after this |
| 365 | # one to make sure that our post job runs with the one that we |
| 366 | # intended rather than simply the current repo state. |
| 367 | B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B', |
| 368 | parent='refs/changes/1/1/1') |
| 369 | B.setMerged() |
| 370 | B_commit = str(upstream[p1].commit('master')) |
| 371 | self.log.debug("B commit: %s" % B_commit) |
| 372 | |
James E. Blair | 8cce42e | 2016-10-18 08:18:36 -0700 | [diff] [blame] | 373 | self.fake_gerrit.addEvent(event) |
| 374 | self.waitUntilSettled() |
| 375 | |
James E. Blair | 1de2e49 | 2017-06-02 11:04:42 -0700 | [diff] [blame] | 376 | states = [ |
James E. Blair | 289f593 | 2017-07-27 15:02:29 -0700 | [diff] [blame] | 377 | {p1: dict(commit=A_commit, |
| 378 | present=[A], absent=[B], branch='master'), |
James E. Blair | 1de2e49 | 2017-06-02 11:04:42 -0700 | [diff] [blame] | 379 | p2: dict(commit=str(upstream[p2].commit('master')), |
James E. Blair | 289f593 | 2017-07-27 15:02:29 -0700 | [diff] [blame] | 380 | absent=[A, B], branch='master'), |
James E. Blair | 1de2e49 | 2017-06-02 11:04:42 -0700 | [diff] [blame] | 381 | }, |
| 382 | ] |
James E. Blair | 8cce42e | 2016-10-18 08:18:36 -0700 | [diff] [blame] | 383 | |
James E. Blair | 987855f | 2017-06-06 14:41:58 -0700 | [diff] [blame] | 384 | self.assertBuildStates(states, projects) |
Tristan Cacqueray | 8095440 | 2017-05-28 00:33:55 +0000 | [diff] [blame] | 385 | |
James E. Blair | edff2c2 | 2017-10-30 14:04:48 -0700 | [diff] [blame] | 386 | @simple_layout('layouts/repo-checkout-tag.yaml') |
| 387 | def test_tag_checkout(self): |
| 388 | self.executor_server.hold_jobs_in_build = True |
| 389 | p1 = "review.example.com/org/project1" |
| 390 | p2 = "review.example.com/org/project2" |
| 391 | projects = [p1, p2] |
| 392 | upstream = self.getUpstreamRepos(projects) |
| 393 | |
| 394 | self.create_branch('org/project2', 'stable/havana') |
| 395 | files = {'README': 'tagged readme'} |
| 396 | self.addCommitToRepo('org/project2', 'tagged commit', |
| 397 | files, branch='stable/havana', tag='test-tag') |
| 398 | |
| 399 | A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A') |
| 400 | self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1)) |
| 401 | self.waitUntilSettled() |
| 402 | |
| 403 | states = [ |
| 404 | {p1: dict(present=[A], branch='master'), |
| 405 | p2: dict(commit=str(upstream[p2].commit('test-tag')), |
| 406 | absent=[A]), |
| 407 | }, |
| 408 | ] |
| 409 | |
| 410 | self.assertBuildStates(states, projects) |
| 411 | |
Tristan Cacqueray | 8095440 | 2017-05-28 00:33:55 +0000 | [diff] [blame] | 412 | |
| 413 | class TestAnsibleJob(ZuulTestCase): |
| 414 | tenant_config_file = 'config/ansible/main.yaml' |
| 415 | |
| 416 | def setUp(self): |
| 417 | super(TestAnsibleJob, self).setUp() |
| 418 | job = zuul.model.Job('test') |
| 419 | job.unique = 'test' |
| 420 | self.test_job = zuul.executor.server.AnsibleJob(self.executor_server, |
| 421 | job) |
| 422 | |
| 423 | def test_getHostList_host_keys(self): |
Tobias Henkel | aea4344 | 2017-09-05 14:36:33 +0200 | [diff] [blame] | 424 | # Test without connection_port set |
Tristan Cacqueray | 8095440 | 2017-05-28 00:33:55 +0000 | [diff] [blame] | 425 | node = {'name': 'fake-host', |
| 426 | 'host_keys': ['fake-host-key'], |
| 427 | 'interface_ip': 'localhost'} |
James E. Blair | 67cd859 | 2018-02-14 09:30:07 -0800 | [diff] [blame] | 428 | keys = self.test_job.getHostList({'nodes': [node], |
| 429 | 'host_vars': {}})[0]['host_keys'] |
Tristan Cacqueray | 8095440 | 2017-05-28 00:33:55 +0000 | [diff] [blame] | 430 | self.assertEqual(keys[0], 'localhost fake-host-key') |
| 431 | |
Tobias Henkel | aea4344 | 2017-09-05 14:36:33 +0200 | [diff] [blame] | 432 | # Test with custom connection_port set |
| 433 | node['connection_port'] = 22022 |
James E. Blair | 67cd859 | 2018-02-14 09:30:07 -0800 | [diff] [blame] | 434 | keys = self.test_job.getHostList({'nodes': [node], |
| 435 | 'host_vars': {}})[0]['host_keys'] |
Tristan Cacqueray | 8095440 | 2017-05-28 00:33:55 +0000 | [diff] [blame] | 436 | self.assertEqual(keys[0], '[localhost]:22022 fake-host-key') |
Tobias Henkel | 055cda3 | 2017-10-17 13:08:18 +0200 | [diff] [blame] | 437 | |
| 438 | |
| 439 | class TestExecutorHostname(ZuulTestCase): |
| 440 | config_file = 'zuul-executor-hostname.conf' |
| 441 | tenant_config_file = 'config/single-tenant/main.yaml' |
| 442 | |
| 443 | def test_executor_hostname(self): |
Tobias Henkel | e2d3566 | 2017-10-19 19:01:03 +0200 | [diff] [blame] | 444 | self.assertEqual('test-executor-hostname.example.com', |
Tobias Henkel | 055cda3 | 2017-10-17 13:08:18 +0200 | [diff] [blame] | 445 | self.executor_server.hostname) |
James E. Blair | df37ad2 | 2018-02-01 13:59:48 -0800 | [diff] [blame] | 446 | |
| 447 | |
| 448 | class TestGovernor(ZuulTestCase): |
| 449 | tenant_config_file = 'config/governor/main.yaml' |
| 450 | |
| 451 | @mock.patch('os.getloadavg') |
| 452 | @mock.patch('psutil.virtual_memory') |
| 453 | def test_load_governor(self, vm_mock, loadavg_mock): |
| 454 | class Dummy(object): |
| 455 | pass |
| 456 | ram = Dummy() |
| 457 | ram.percent = 20.0 # 20% used |
| 458 | vm_mock.return_value = ram |
| 459 | loadavg_mock.return_value = (0.0, 0.0, 0.0) |
| 460 | self.executor_server.manageLoad() |
| 461 | self.assertTrue(self.executor_server.accepting_work) |
| 462 | ram.percent = 99.0 # 99% used |
| 463 | loadavg_mock.return_value = (100.0, 100.0, 100.0) |
| 464 | self.executor_server.manageLoad() |
| 465 | self.assertFalse(self.executor_server.accepting_work) |
| 466 | |
| 467 | def waitForExecutorBuild(self, jobname): |
| 468 | timeout = time.time() + 30 |
| 469 | build = None |
| 470 | while (time.time() < timeout and not build): |
| 471 | for b in self.builds: |
| 472 | if b.name == jobname: |
| 473 | build = b |
| 474 | break |
| 475 | time.sleep(0.1) |
| 476 | build_id = build.uuid |
| 477 | while (time.time() < timeout and |
| 478 | build_id not in self.executor_server.job_workers): |
| 479 | time.sleep(0.1) |
| 480 | worker = self.executor_server.job_workers[build_id] |
| 481 | while (time.time() < timeout and |
| 482 | not worker.started): |
| 483 | time.sleep(0.1) |
| 484 | return build |
| 485 | |
| 486 | def waitForWorkerCompletion(self, build): |
| 487 | timeout = time.time() + 30 |
| 488 | while (time.time() < timeout and |
| 489 | build.uuid in self.executor_server.job_workers): |
| 490 | time.sleep(0.1) |
| 491 | |
| 492 | def test_slow_start(self): |
| 493 | self.executor_server.hold_jobs_in_build = True |
| 494 | self.executor_server.max_starting_builds = 1 |
James E. Blair | acb632d | 2018-02-05 10:36:36 -0800 | [diff] [blame] | 495 | self.executor_server.min_starting_builds = 1 |
James E. Blair | df37ad2 | 2018-02-01 13:59:48 -0800 | [diff] [blame] | 496 | self.executor_server.manageLoad() |
| 497 | self.assertTrue(self.executor_server.accepting_work) |
| 498 | A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A') |
| 499 | self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1)) |
| 500 | |
| 501 | build1 = self.waitForExecutorBuild('test1') |
| 502 | # With one job (test1) being started, we should no longer |
| 503 | # be accepting new work |
| 504 | self.assertFalse(self.executor_server.accepting_work) |
| 505 | self.assertEqual(len(self.executor_server.job_workers), 1) |
| 506 | # Allow enough starting builds for the test to complete. |
| 507 | self.executor_server.max_starting_builds = 3 |
| 508 | build1.release() |
| 509 | self.waitForWorkerCompletion(build1) |
| 510 | self.executor_server.manageLoad() |
| 511 | |
| 512 | self.waitForExecutorBuild('test2') |
| 513 | self.waitForExecutorBuild('test3') |
| 514 | self.assertFalse(self.executor_server.accepting_work) |
| 515 | |
| 516 | self.executor_server.hold_jobs_in_build = False |
| 517 | self.executor_server.release() |
| 518 | self.waitUntilSettled() |
| 519 | self.executor_server.manageLoad() |
| 520 | self.assertTrue(self.executor_server.accepting_work) |