Merge lp:~robru/cupstream2distro/parallelize-migration into lp:cupstream2distro
- parallelize-migration
- Merge into trunk
Proposed by
Robert Bruce Park
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Robert Bruce Park | ||||
Approved revision: | 1233 | ||||
Merged at revision: | 1227 | ||||
Proposed branch: | lp:~robru/cupstream2distro/parallelize-migration | ||||
Merge into: | lp:cupstream2distro | ||||
Diff against target: |
400 lines (+108/-134) 6 files modified
citrain/jenkins-templates/status.xml.tmpl (+31/-11) citrain/setup_citrain.py (+6/-2) citrain/status.py (+16/-30) files/config.xml (+22/-0) tests/unit/test_script_setup_citrain.py (+5/-2) tests/unit/test_script_status.py (+28/-89) |
||||
To merge this branch: | bzr merge lp:~robru/cupstream2distro/parallelize-migration | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Bruce Park (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+278121@code.launchpad.net |
Commit message
Parallelize migration script.
Description of the change
To post a comment you must log in.
Revision history for this message
Robert Bruce Park (robru) wrote : | # |
- 1232. By Robert Bruce Park
-
Run with 10 minute frequency.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1232
http://
Executed test runs:
Click here to trigger a rebuild:
http://
review:
Approve
(continuous-integration)
- 1233. By Robert Bruce Park
-
Keep more logs but fewer artifacts.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1233
http://
Executed test runs:
Click here to trigger a rebuild:
http://
review:
Approve
(continuous-integration)
Revision history for this message
Robert Bruce Park (robru) wrote : | # |
This loks amazing in staging.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === renamed file 'citrain/jenkins-templates/check-publication-migration.xml.tmpl' => 'citrain/jenkins-templates/status.xml.tmpl' | |||
2 | --- citrain/jenkins-templates/check-publication-migration.xml.tmpl 2015-11-18 05:51:13 +0000 | |||
3 | +++ citrain/jenkins-templates/status.xml.tmpl 2015-11-20 11:31:16 +0000 | |||
4 | @@ -1,25 +1,25 @@ | |||
5 | 1 | <?xml version='1.0' encoding='UTF-8'?> | 1 | <?xml version='1.0' encoding='UTF-8'?> |
6 | 2 | <project> | 2 | <project> |
7 | 3 | <actions/> | 3 | <actions/> |
9 | 4 | <description>Automatically check destination migration for packages.</description> | 4 | <description>Regularly refresh silo status.</description> |
10 | 5 | <logRotator> | 5 | <logRotator> |
13 | 6 | <daysToKeep>1</daysToKeep> | 6 | <daysToKeep>7</daysToKeep> |
14 | 7 | <numToKeep>500</numToKeep> | 7 | <numToKeep>-1</numToKeep> |
15 | 8 | <artifactDaysToKeep>-1</artifactDaysToKeep> | 8 | <artifactDaysToKeep>-1</artifactDaysToKeep> |
17 | 9 | <artifactNumToKeep>-1</artifactNumToKeep> | 9 | <artifactNumToKeep>5</artifactNumToKeep> |
18 | 10 | </logRotator> | 10 | </logRotator> |
19 | 11 | <keepDependencies>false</keepDependencies> | 11 | <keepDependencies>false</keepDependencies> |
20 | 12 | <properties> | 12 | <properties> |
21 | 13 | <hudson.security.AuthorizationMatrixProperty> | 13 | <hudson.security.AuthorizationMatrixProperty> |
22 | 14 | <permission>hudson.model.Item.Cancel:ubuntu-core-dev</permission> | 14 | <permission>hudson.model.Item.Cancel:ubuntu-core-dev</permission> |
23 | 15 | <permission>hudson.model.Item.Cancel:canonical-ci-eng</permission> | 15 | <permission>hudson.model.Item.Cancel:canonical-ci-eng</permission> |
25 | 16 | <permission>hudson.model.Item.Cancel:ci-train-users</permission> | 16 | <permission>hudson.model.Item.Cancel:ci-train-ppa-service</permission> |
26 | 17 | <permission>hudson.model.Item.Build:ubuntu-core-dev</permission> | 17 | <permission>hudson.model.Item.Build:ubuntu-core-dev</permission> |
27 | 18 | <permission>hudson.model.Item.Build:canonical-ci-eng</permission> | 18 | <permission>hudson.model.Item.Build:canonical-ci-eng</permission> |
29 | 19 | <permission>hudson.model.Item.Build:ci-train-users</permission> | 19 | <permission>hudson.model.Item.Build:ci-train-ppa-service</permission> |
30 | 20 | <permission>hudson.model.Item.Read:ubuntu-core-dev</permission> | 20 | <permission>hudson.model.Item.Read:ubuntu-core-dev</permission> |
31 | 21 | <permission>hudson.model.Item.Read:canonical-ci-eng</permission> | 21 | <permission>hudson.model.Item.Read:canonical-ci-eng</permission> |
33 | 22 | <permission>hudson.model.Item.Read:ci-train-users</permission> | 22 | <permission>hudson.model.Item.Read:ci-train-ppa-service</permission> |
34 | 23 | </hudson.security.AuthorizationMatrixProperty> | 23 | </hudson.security.AuthorizationMatrixProperty> |
35 | 24 | <hudson.model.ParametersDefinitionProperty> | 24 | <hudson.model.ParametersDefinitionProperty> |
36 | 25 | <parameterDefinitions> | 25 | <parameterDefinitions> |
37 | @@ -38,7 +38,7 @@ | |||
38 | 38 | <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding> | 38 | <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding> |
39 | 39 | <triggers> | 39 | <triggers> |
40 | 40 | <hudson.triggers.TimerTrigger> | 40 | <hudson.triggers.TimerTrigger> |
42 | 41 | <spec>H/30 * * * *</spec> | 41 | <spec>H/10 * * * *</spec> |
43 | 42 | </hudson.triggers.TimerTrigger> | 42 | </hudson.triggers.TimerTrigger> |
44 | 43 | </triggers> | 43 | </triggers> |
45 | 44 | <concurrentBuild>false</concurrentBuild> | 44 | <concurrentBuild>false</concurrentBuild> |
46 | @@ -46,15 +46,35 @@ | |||
47 | 46 | <hudson.tasks.Shell> | 46 | <hudson.tasks.Shell> |
48 | 47 | <command>#!/bin/sh | 47 | <command>#!/bin/sh |
49 | 48 | export LANG=en_US.UTF-8 | 48 | export LANG=en_US.UTF-8 |
50 | 49 | export WORKSPACE="$PWD" | ||
51 | 50 | export SILONAME="{SILO_NAME}" | ||
52 | 49 | export PYTHONPATH={LIBDIR} | 51 | export PYTHONPATH={LIBDIR} |
53 | 50 | 52 | ||
57 | 51 | cd # go to home directory | 53 | [ "$DEBUG" = "true" ] && set -x |
58 | 52 | 54 | ||
59 | 53 | {BINDIR}/migration.py | 55 | [ -e {SILOS_DIR}/{SILO_NAME}/request_id_* ] || exit 0 |
60 | 56 | |||
61 | 57 | rm -rf $WORKSPACE/* | ||
62 | 58 | |||
63 | 59 | cd {SILOS_DIR}/{SILO_NAME} | ||
64 | 60 | |||
65 | 61 | {BINDIR}/status.py | ||
66 | 62 | RETVAL=$? | ||
67 | 63 | |||
68 | 64 | cp *.diff "$WORKSPACE" 2>/dev/null || true | ||
69 | 65 | |||
70 | 66 | exit $RETVAL | ||
71 | 54 | </command> | 67 | </command> |
72 | 55 | </hudson.tasks.Shell> | 68 | </hudson.tasks.Shell> |
73 | 56 | </builders> | 69 | </builders> |
74 | 57 | <publishers> | 70 | <publishers> |
75 | 71 | <hudson.tasks.ArtifactArchiver> | ||
76 | 72 | <artifacts>*.diff</artifacts> | ||
77 | 73 | <allowEmptyArchive>true</allowEmptyArchive> | ||
78 | 74 | <onlyIfSuccessful>false</onlyIfSuccessful> | ||
79 | 75 | <fingerprint>false</fingerprint> | ||
80 | 76 | <defaultExcludes>true</defaultExcludes> | ||
81 | 77 | </hudson.tasks.ArtifactArchiver> | ||
82 | 58 | </publishers> | 78 | </publishers> |
83 | 59 | <buildWrappers/> | 79 | <buildWrappers/> |
84 | 60 | </project> | 80 | </project> |
85 | 61 | 81 | ||
86 | === modified file 'citrain/setup_citrain.py' | |||
87 | --- citrain/setup_citrain.py 2015-11-04 16:32:54 +0000 | |||
88 | +++ citrain/setup_citrain.py 2015-11-20 11:31:16 +0000 | |||
89 | @@ -101,7 +101,12 @@ | |||
90 | 101 | """Setup a silo jenkins job.""" | 101 | """Setup a silo jenkins job.""" |
91 | 102 | context = dict(SILOS_DIR=SILOS_DIR, SILO_NAME=siloname) | 102 | context = dict(SILOS_DIR=SILOS_DIR, SILO_NAME=siloname) |
92 | 103 | siloname = siloname.replace('/', '-') | 103 | siloname = siloname.replace('/', '-') |
94 | 104 | steps = dict(build='1', publish='2', autopkgtests='2.5', merge_clean='3') | 104 | steps = dict( |
95 | 105 | status='0', | ||
96 | 106 | build='1', | ||
97 | 107 | publish='2', | ||
98 | 108 | autopkgtests='2.5', | ||
99 | 109 | merge_clean='3') | ||
100 | 105 | for job, i in sorted(steps.items()): | 110 | for job, i in sorted(steps.items()): |
101 | 106 | job = job.replace('_', '-') | 111 | job = job.replace('_', '-') |
102 | 107 | setup_job('{}-{}-{}'.format(siloname, i, job), template(job), context) | 112 | setup_job('{}-{}-{}'.format(siloname, i, job), template(job), context) |
103 | @@ -114,7 +119,6 @@ | |||
104 | 114 | setup_silo(siloname) | 119 | setup_silo(siloname) |
105 | 115 | setup_job('cyphermox-test') | 120 | setup_job('cyphermox-test') |
106 | 116 | setup_job('prepare-silo') | 121 | setup_job('prepare-silo') |
107 | 117 | setup_job('check-publication-migration') | ||
108 | 118 | setup_job('staleness-report') | 122 | setup_job('staleness-report') |
109 | 119 | setup_job('upgrade-chroot') | 123 | setup_job('upgrade-chroot') |
110 | 120 | setup_job('apt-get-clean') | 124 | setup_job('apt-get-clean') |
111 | 121 | 125 | ||
112 | === renamed file 'citrain/migration.py' => 'citrain/status.py' | |||
113 | --- citrain/migration.py 2015-11-19 23:08:21 +0000 | |||
114 | +++ citrain/status.py 2015-11-20 11:31:16 +0000 | |||
115 | @@ -15,9 +15,9 @@ | |||
116 | 15 | # this program; if not, write to the Free Software Foundation, Inc., | 15 | # this program; if not, write to the Free Software Foundation, Inc., |
117 | 16 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 16 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
118 | 17 | 17 | ||
120 | 18 | """CI Train Migration Script | 18 | """CI Train Status Script |
121 | 19 | 19 | ||
123 | 20 | Check if all silo packages have migrated, and if so, trigger merge & clean. | 20 | Update silo status, also triggering Merge&Clean if silo is ready. |
124 | 21 | 21 | ||
125 | 22 | Environment variables: | 22 | Environment variables: |
126 | 23 | 23 | ||
127 | @@ -30,36 +30,22 @@ | |||
128 | 30 | 30 | ||
129 | 31 | from citrain.recipes.base import BuildBase | 31 | from citrain.recipes.base import BuildBase |
130 | 32 | from citrain.recipes.manager import Manager | 32 | from citrain.recipes.manager import Manager |
133 | 33 | from cupstream2distro.utils import env, run_script | 33 | from cupstream2distro.utils import run_script |
134 | 34 | from cupstream2distro.silomanager import SiloState, stock_main | 34 | from cupstream2distro.silomanager import stock_main |
135 | 35 | from citrain.merge_clean import merge | 35 | from citrain.merge_clean import merge |
136 | 36 | 36 | ||
137 | 37 | SUCCESS = re.compile(r'^((Release|Updates) pocket( \([^()]+\). ?)?)+$') | 37 | SUCCESS = re.compile(r'^((Release|Updates) pocket( \([^()]+\). ?)?)+$') |
138 | 38 | 38 | ||
139 | 39 | 39 | ||
166 | 40 | def main(): | 40 | def update_status(silo_state): |
167 | 41 | """Execute the migration check, logging & saving any errors. | 41 | """Set the status for this silo.""" |
168 | 42 | 42 | silo_state.lock_fd.close() | |
169 | 43 | :returns: 0. Always. | 43 | BuildBase.failures.clear() |
170 | 44 | """ | 44 | logging.info('Inspecting PPA %s:', silo_state.ppa.web_link) |
171 | 45 | for silo_state in SiloState.iterate(): | 45 | status = silo_state.status = Manager(silo_state).get_states() |
172 | 46 | env.SILONAME = silo_state | 46 | if SUCCESS.match(status): |
173 | 47 | BuildBase.failures.clear() | 47 | logging.info('Looks good, proceeding with merge & clean.') |
174 | 48 | logging.info('\n\nInspecting silo %s:', silo_state.ppa.web_link) | 48 | stock_main(merge) |
175 | 49 | try: | 49 | |
176 | 50 | silo_state.enforce_lock() | 50 | |
177 | 51 | silo_state.lock_fd.close() | 51 | run_script(__name__, __doc__, lambda: stock_main(update_status)) |
152 | 52 | except BlockingIOError: | ||
153 | 53 | logging.info('Silo %s is in use, skipping.', env.SILONAME) | ||
154 | 54 | continue | ||
155 | 55 | |||
156 | 56 | status = silo_state.status = Manager(silo_state).get_states() | ||
157 | 57 | if SUCCESS.match(status): | ||
158 | 58 | logging.info('Looks good, proceeding with merge & clean.') | ||
159 | 59 | stock_main(merge) | ||
160 | 60 | continue | ||
161 | 61 | silo_state.save_config() | ||
162 | 62 | return 0 | ||
163 | 63 | |||
164 | 64 | |||
165 | 65 | run_script(__name__, __doc__, main) | ||
178 | 66 | 52 | ||
179 | === modified file 'files/config.xml' | |||
180 | --- files/config.xml 2015-10-28 23:28:38 +0000 | |||
181 | +++ files/config.xml 2015-11-20 11:31:16 +0000 | |||
182 | @@ -202,6 +202,28 @@ | |||
183 | 202 | </hudson.model.AllView> | 202 | </hudson.model.AllView> |
184 | 203 | <listView> | 203 | <listView> |
185 | 204 | <owner class="hudson" reference="../../.."/> | 204 | <owner class="hudson" reference="../../.."/> |
186 | 205 | <name>0. Status</name> | ||
187 | 206 | <filterExecutors>false</filterExecutors> | ||
188 | 207 | <filterQueue>false</filterQueue> | ||
189 | 208 | <properties class="hudson.model.View$PropertyList"/> | ||
190 | 209 | <jobNames> | ||
191 | 210 | <comparator class="hudson.util.CaseInsensitiveComparator"/> | ||
192 | 211 | </jobNames> | ||
193 | 212 | <jobFilters/> | ||
194 | 213 | <columns> | ||
195 | 214 | <hudson.views.StatusColumn/> | ||
196 | 215 | <hudson.views.WeatherColumn/> | ||
197 | 216 | <hudson.views.JobColumn/> | ||
198 | 217 | <hudson.views.LastSuccessColumn/> | ||
199 | 218 | <hudson.views.LastFailureColumn/> | ||
200 | 219 | <hudson.views.LastDurationColumn/> | ||
201 | 220 | <hudson.views.BuildButtonColumn/> | ||
202 | 221 | </columns> | ||
203 | 222 | <includeRegex>.*-0-status</includeRegex> | ||
204 | 223 | <recurse>false</recurse> | ||
205 | 224 | </listView> | ||
206 | 225 | <listView> | ||
207 | 226 | <owner class="hudson" reference="../../.."/> | ||
208 | 205 | <name>1. Build</name> | 227 | <name>1. Build</name> |
209 | 206 | <filterExecutors>false</filterExecutors> | 228 | <filterExecutors>false</filterExecutors> |
210 | 207 | <filterQueue>false</filterQueue> | 229 | <filterQueue>false</filterQueue> |
211 | 208 | 230 | ||
212 | === modified file 'tests/unit/test_script_setup_citrain.py' | |||
213 | --- tests/unit/test_script_setup_citrain.py 2015-11-04 16:32:54 +0000 | |||
214 | +++ tests/unit/test_script_setup_citrain.py 2015-11-20 11:31:16 +0000 | |||
215 | @@ -123,6 +123,10 @@ | |||
216 | 123 | 'publish.xml.tmpl', | 123 | 'publish.xml.tmpl', |
217 | 124 | {'SILO_NAME': 'ubuntu/landing-000', | 124 | {'SILO_NAME': 'ubuntu/landing-000', |
218 | 125 | 'SILOS_DIR': os.path.expanduser('~/silos')}), | 125 | 'SILOS_DIR': os.path.expanduser('~/silos')}), |
219 | 126 | call('ubuntu-landing-000-0-status', | ||
220 | 127 | 'status.xml.tmpl', | ||
221 | 128 | {'SILO_NAME': 'ubuntu/landing-000', | ||
222 | 129 | 'SILOS_DIR': os.path.expanduser('~/silos')}), | ||
223 | 126 | ]) | 130 | ]) |
224 | 127 | 131 | ||
225 | 128 | def test_main(self): | 132 | def test_main(self): |
226 | @@ -137,7 +141,6 @@ | |||
227 | 137 | self.assertEqual(self.script.setup_job.mock_calls, [ | 141 | self.assertEqual(self.script.setup_job.mock_calls, [ |
228 | 138 | call('cyphermox-test'), | 142 | call('cyphermox-test'), |
229 | 139 | call('prepare-silo'), | 143 | call('prepare-silo'), |
230 | 140 | call('check-publication-migration'), | ||
231 | 141 | call('staleness-report'), | 144 | call('staleness-report'), |
232 | 142 | call('upgrade-chroot'), | 145 | call('upgrade-chroot'), |
233 | 143 | call('apt-get-clean'), | 146 | call('apt-get-clean'), |
234 | @@ -152,11 +155,11 @@ | |||
235 | 152 | 'abandon/config.xml', | 155 | 'abandon/config.xml', |
236 | 153 | 'apt-get-clean/config.xml', | 156 | 'apt-get-clean/config.xml', |
237 | 154 | 'cyphermox-test/config.xml', | 157 | 'cyphermox-test/config.xml', |
238 | 155 | 'check-publication-migration/config.xml', | ||
239 | 156 | 'pbuilder-clean/config.xml', | 158 | 'pbuilder-clean/config.xml', |
240 | 157 | 'prepare-silo/config.xml', | 159 | 'prepare-silo/config.xml', |
241 | 158 | 'revert/config.xml', | 160 | 'revert/config.xml', |
242 | 159 | 'staleness-report/config.xml', | 161 | 'staleness-report/config.xml', |
243 | 162 | 'ubuntu-landing-{:03d}-0-status/config.xml', | ||
244 | 160 | 'ubuntu-landing-{:03d}-1-build/config.xml', | 163 | 'ubuntu-landing-{:03d}-1-build/config.xml', |
245 | 161 | 'ubuntu-landing-{:03d}-2-publish/config.xml', | 164 | 'ubuntu-landing-{:03d}-2-publish/config.xml', |
246 | 162 | 'ubuntu-landing-{:03d}-2.5-autopkgtests/config.xml', | 165 | 'ubuntu-landing-{:03d}-2.5-autopkgtests/config.xml', |
247 | 163 | 166 | ||
248 | === renamed file 'tests/unit/test_script_migration.py' => 'tests/unit/test_script_status.py' | |||
249 | --- tests/unit/test_script_migration.py 2015-11-19 23:08:21 +0000 | |||
250 | +++ tests/unit/test_script_status.py 2015-11-20 11:31:16 +0000 | |||
251 | @@ -14,31 +14,25 @@ | |||
252 | 14 | # this program; if not, write to the Free Software Foundation, Inc., | 14 | # this program; if not, write to the Free Software Foundation, Inc., |
253 | 15 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 15 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
254 | 16 | 16 | ||
256 | 17 | """Tests for CI Train Migration script.""" | 17 | """Tests for CI Train Status script.""" |
257 | 18 | 18 | ||
258 | 19 | from os.path import join | ||
259 | 20 | from mock import Mock, call | 19 | from mock import Mock, call |
260 | 21 | 20 | ||
261 | 22 | from tests.unit import CITrainScriptTestCase | 21 | from tests.unit import CITrainScriptTestCase |
262 | 23 | 22 | ||
263 | 24 | from cupstream2distro.settings import SILOS_DIR | ||
264 | 25 | |||
265 | 26 | # Unused import necessary for code coverage reporting | 23 | # Unused import necessary for code coverage reporting |
273 | 27 | from citrain import migration | 24 | from citrain import status |
274 | 28 | COVERAGE = [migration] | 25 | COVERAGE = [status] |
275 | 29 | 26 | ||
276 | 30 | 27 | ||
277 | 31 | class MigrationTestCase(CITrainScriptTestCase): | 28 | class StatusTestCase(CITrainScriptTestCase): |
278 | 32 | """Tests for CI Train Migration script.""" | 29 | """Tests for CI Train Status script.""" |
279 | 33 | scriptname = 'migration.py' | 30 | scriptname = 'status.py' |
280 | 34 | 31 | ||
281 | 35 | def setUp(self): | 32 | def setUp(self): |
282 | 36 | super().setUp() | 33 | super().setUp() |
283 | 37 | self.script.Manager = Mock() | 34 | self.script.Manager = Mock() |
284 | 38 | self.script.stock_main = Mock() | 35 | self.script.stock_main = Mock() |
285 | 39 | self.script.glob.return_value = [ | ||
286 | 40 | join(SILOS_DIR, 'ubuntu', 'landing-00{}'.format(x)) | ||
287 | 41 | for x in range(3)] | ||
288 | 42 | 36 | ||
289 | 43 | def test_success_regex(self): | 37 | def test_success_regex(self): |
290 | 44 | """Ensure we can properly recognize silos ready to auto-merge.""" | 38 | """Ensure we can properly recognize silos ready to auto-merge.""" |
291 | @@ -60,89 +54,34 @@ | |||
292 | 60 | results = [bool(self.script.SUCCESS.match(stat)) for stat in bad] | 54 | results = [bool(self.script.SUCCESS.match(stat)) for stat in bad] |
293 | 61 | self.assertEqual(results, [False] * len(bad)) | 55 | self.assertEqual(results, [False] * len(bad)) |
294 | 62 | 56 | ||
296 | 63 | def test_main(self): | 57 | def test_status(self): |
297 | 64 | """Trigger merges after successful migrations.""" | 58 | """Trigger merges after successful migrations.""" |
298 | 65 | tokenize = lambda: Mock(return_value={'hi'}) | 59 | tokenize = lambda: Mock(return_value={'hi'}) |
303 | 66 | states = self.script.SiloState.iterate.return_value = [Mock( | 60 | silo_state = Mock(tokenize=tokenize()) |
300 | 67 | tokenize=tokenize(), | ||
301 | 68 | is_published=True, | ||
302 | 69 | is_autopkgtesting=False) for rid in range(3)] | ||
304 | 70 | mgr = self.script.Manager.return_value | 61 | mgr = self.script.Manager.return_value |
305 | 71 | mgr.get_states.return_value = 'Release pocket (foo).' | 62 | mgr.get_states.return_value = 'Release pocket (foo).' |
312 | 72 | self.assertEqual(self.script.main(), 0) | 63 | self.assertIsNone(self.script.update_status(silo_state)) |
313 | 73 | for state in states: | 64 | self.assertEqual(silo_state.mock_calls, [ |
314 | 74 | self.assertEqual(state.mock_calls, [ | 65 | call.lock_fd.close(), |
315 | 75 | call.enforce_lock(), | 66 | ]) |
310 | 76 | call.lock_fd.close(), | ||
311 | 77 | ]) | ||
316 | 78 | self.assertEqual(self.script.Manager.mock_calls, [ | 67 | self.assertEqual(self.script.Manager.mock_calls, [ |
322 | 79 | call(states[0]), | 68 | call(silo_state), |
318 | 80 | call().get_states(), | ||
319 | 81 | call(states[1]), | ||
320 | 82 | call().get_states(), | ||
321 | 83 | call(states[2]), | ||
323 | 84 | call().get_states(), | 69 | call().get_states(), |
324 | 85 | ]) | 70 | ]) |
325 | 86 | self.assertEqual(self.script.stock_main.mock_calls, [ | 71 | self.assertEqual(self.script.stock_main.mock_calls, [ |
326 | 87 | call(self.script.merge) | 72 | call(self.script.merge) |
346 | 88 | ] * 3) | 73 | ]) |
347 | 89 | 74 | ||
348 | 90 | def test_main_skip_empty_silos(self): | 75 | def test_status_skip_unpublished_silos(self): |
330 | 91 | """Don't check silos that are empty.""" | ||
331 | 92 | self.script.SiloState.iterate.return_value = [] | ||
332 | 93 | self.assertEqual(self.script.main(), 0) | ||
333 | 94 | self.assertEqual(self.script.Manager.mock_calls, []) | ||
334 | 95 | self.assertEqual(self.script.stock_main.mock_calls, []) | ||
335 | 96 | |||
336 | 97 | def test_main_skip_locked_silos(self): | ||
337 | 98 | """Skip over silos that are currently used by other processes.""" | ||
338 | 99 | states = self.script.SiloState.iterate.return_value = [Mock()] | ||
339 | 100 | states[0].enforce_lock.side_effect = BlockingIOError | ||
340 | 101 | self.assertEqual(self.script.main(), 0) | ||
341 | 102 | self.assertEqual(self.script.Manager.mock_calls, []) | ||
342 | 103 | self.assertEqual(self.script.stock_main.mock_calls, []) | ||
343 | 104 | self.assertEqual(states[0].mock_calls, [call.enforce_lock()]) | ||
344 | 105 | |||
345 | 106 | def test_main_skip_unpublished_silos(self): | ||
349 | 107 | """Don't merge silos that are unpublished.""" | 76 | """Don't merge silos that are unpublished.""" |
350 | 108 | tokenize = Mock(return_value={'hi'}) | 77 | tokenize = Mock(return_value={'hi'}) |
391 | 109 | states = self.script.SiloState.iterate.return_value = [ | 78 | silo_state = Mock(tokenize=tokenize) |
392 | 110 | Mock(tokenize=tokenize, is_published=False) for rid in range(3)] | 79 | mgr = self.script.Manager.return_value |
393 | 111 | mgr = self.script.Manager.return_value | 80 | mgr.get_states.return_value = 'Proposed pocket (foo).' |
394 | 112 | mgr.get_states.return_value = 'Proposed pocket (foo).' | 81 | self.assertIsNone(self.script.update_status(silo_state)) |
395 | 113 | self.assertEqual(self.script.main(), 0) | 82 | self.assertEqual(self.script.Manager.mock_calls, [ |
396 | 114 | self.assertEqual(self.script.Manager.mock_calls, [ | 83 | call(silo_state), |
397 | 115 | call(states[0]), | 84 | call().get_states(), |
398 | 116 | call().get_states(), | 85 | ]) |
399 | 117 | call(states[1]), | 86 | self.assertEqual(self.script.stock_main.mock_calls, []) |
400 | 118 | call().get_states(), | 87 | self.assertEqual(silo_state.save_config.mock_calls, []) |
361 | 119 | call(states[2]), | ||
362 | 120 | call().get_states(), | ||
363 | 121 | ]) | ||
364 | 122 | self.assertEqual(self.script.stock_main.mock_calls, []) | ||
365 | 123 | for state in states: | ||
366 | 124 | self.assertEqual(state.set_migrating.mock_calls, []) | ||
367 | 125 | self.assertEqual(state.save_config.mock_calls, [call()]) | ||
368 | 126 | |||
369 | 127 | def test_main_dont_merge_migrating_silos(self): | ||
370 | 128 | """Don't merge silos that are still migrating.""" | ||
371 | 129 | tokenize = Mock(return_value={'hi'}) | ||
372 | 130 | states = self.script.SiloState.iterate.return_value = [Mock( | ||
373 | 131 | tokenize=tokenize, | ||
374 | 132 | is_published=True, | ||
375 | 133 | requestid=str(1), | ||
376 | 134 | )] | ||
377 | 135 | mgr = self.script.Manager.return_value | ||
378 | 136 | mgr.get_states.return_value = 'Proposed pocket (foo).' | ||
379 | 137 | self.assertEqual(self.script.main(), 0) | ||
380 | 138 | self.assertEqual(states[0].status, mgr.get_states.return_value) | ||
381 | 139 | self.assertEqual(states[0].mock_calls, [ | ||
382 | 140 | call.enforce_lock(), | ||
383 | 141 | call.lock_fd.close(), | ||
384 | 142 | call.save_config(), | ||
385 | 143 | ]) | ||
386 | 144 | self.assertEqual(self.script.Manager.mock_calls, [ | ||
387 | 145 | call(states[0]), | ||
388 | 146 | call().get_states(), | ||
389 | 147 | ]) | ||
390 | 148 | self.assertEqual(self.script.stock_main.mock_calls, []) |
https:/ /ci-train. staging. ubuntu. com/view/ 0.%20Status/
I'm enjoying this in staging, just need to write tests.