Merge lp:~cjwatson/launchpad/germinate-stale-files into lp:launchpad
- germinate-stale-files
- Merge into devel
| Status: | Merged |
|---|---|
| Approved by: | Benji York on 2012-05-21 |
| Approved revision: | no longer in the source branch. |
| Merged at revision: | 15280 |
| Proposed branch: | lp:~cjwatson/launchpad/germinate-stale-files |
| Merge into: | lp:launchpad |
| Diff against target: |
1019 lines (+352/-361) 4 files modified
lib/lp/archivepublisher/scripts/generate_extra_overrides.py (+36/-10) lib/lp/archivepublisher/tests/publisher-config.txt (+0/-195) lib/lp/archivepublisher/tests/test_config.py (+157/-2) lib/lp/archivepublisher/tests/test_generate_extra_overrides.py (+159/-154) |
| To merge this branch: | bzr merge lp:~cjwatson/launchpad/germinate-stale-files |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Benji York (community) | code | 2012-05-21 | Approve on 2012-05-21 |
|
Review via email:
|
|||
Commit Message
Remove stale files from config.
Description of the Change
== Summary ==
One of the problems identified in https:/
== Proposed fix ==
Keep track of the current set of files written for the current series, and remove any not in that set.
== Implementation details ==
Easy, except for LoC. I did some refactoring of test_generate_
== Tests ==
bin/test -vvct archivepublishe
== Demo and Q/A ==
On dogfood:
cp -a /srv/launchpad.
touch /srv/launchpad.
Then do a full publisher run, and verify that (a) /srv/launchpad.
| Colin Watson (cjwatson) wrote : | # |
Maybe I'm weird, but I prefer the with/pass pattern myself; however, a
helper function makes sense, and perhaps can be moved somewhere more
common in future. Done.
Preview Diff
| 1 | === modified file 'lib/lp/archivepublisher/scripts/generate_extra_overrides.py' |
| 2 | --- lib/lp/archivepublisher/scripts/generate_extra_overrides.py 2012-01-03 17:08:40 +0000 |
| 3 | +++ lib/lp/archivepublisher/scripts/generate_extra_overrides.py 2012-05-21 19:07:38 +0000 |
| 4 | @@ -1,4 +1,4 @@ |
| 5 | -# Copyright 2011 Canonical Ltd. This software is licensed under the |
| 6 | +# Copyright 2011-2012 Canonical Ltd. This software is licensed under the |
| 7 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 8 | |
| 9 | """Generate extra overrides using Germinate.""" |
| 10 | @@ -9,6 +9,7 @@ |
| 11 | ] |
| 12 | |
| 13 | from functools import partial |
| 14 | +import glob |
| 15 | import logging |
| 16 | from optparse import OptionValueError |
| 17 | import os |
| 18 | @@ -130,8 +131,9 @@ |
| 19 | |
| 20 | self.germinate_logger = logging.getLogger("germinate") |
| 21 | self.germinate_logger.setLevel(logging.INFO) |
| 22 | - log_file = os.path.join(self.config.germinateroot, "germinate.output") |
| 23 | - handler = logging.FileHandler(log_file, mode="w") |
| 24 | + self.log_file = os.path.join( |
| 25 | + self.config.germinateroot, "germinate.output") |
| 26 | + handler = logging.FileHandler(self.log_file, mode="w") |
| 27 | handler.setFormatter(GerminateFormatter()) |
| 28 | self.germinate_logger.addHandler(handler) |
| 29 | self.germinate_logger.propagate = False |
| 30 | @@ -186,8 +188,12 @@ |
| 31 | self.config.germinateroot, |
| 32 | "%s_%s_%s_%s" % (base, flavour, series_name, arch)) |
| 33 | |
| 34 | + def recordOutput(self, path, seed_outputs): |
| 35 | + if seed_outputs is not None: |
| 36 | + seed_outputs.add(os.path.basename(path)) |
| 37 | + |
| 38 | def writeGerminateOutput(self, germinator, structure, flavour, |
| 39 | - series_name, arch): |
| 40 | + series_name, arch, seed_outputs=None): |
| 41 | """Write dependency-expanded output files. |
| 42 | |
| 43 | These files are a reduced subset of those written by the germinate |
| 44 | @@ -198,18 +204,22 @@ |
| 45 | # The structure file makes it possible to figure out how the other |
| 46 | # output files relate to each other. |
| 47 | structure.write(path("structure")) |
| 48 | + self.recordOutput(path("structure"), seed_outputs) |
| 49 | |
| 50 | # "all" and "all.sources" list the full set of binary and source |
| 51 | # packages respectively for a given flavour/suite/architecture |
| 52 | # combination. |
| 53 | germinator.write_all_list(structure, path("all")) |
| 54 | + self.recordOutput(path("all"), seed_outputs) |
| 55 | germinator.write_all_source_list(structure, path("all.sources")) |
| 56 | + self.recordOutput(path("all.sources"), seed_outputs) |
| 57 | |
| 58 | # Write the dependency-expanded output for each seed. Several of |
| 59 | # these are used by archive administration tools, and others are |
| 60 | # useful for debugging, so it's best to just write them all. |
| 61 | for seedname in structure.names: |
| 62 | germinator.write_full_list(structure, path(seedname), seedname) |
| 63 | + self.recordOutput(path(seedname), seed_outputs) |
| 64 | |
| 65 | def parseTaskHeaders(self, seedtext): |
| 66 | """Parse a seed for Task headers. |
| 67 | @@ -263,15 +273,17 @@ |
| 68 | package, arch, key, value) |
| 69 | |
| 70 | def germinateArchFlavour(self, override_file, germinator, series_name, |
| 71 | - arch, flavour, structure, primary_flavour): |
| 72 | + arch, flavour, structure, primary_flavour, |
| 73 | + seed_outputs=None): |
| 74 | """Germinate seeds on a single flavour for a single architecture.""" |
| 75 | # Expand dependencies. |
| 76 | germinator.plant_seeds(structure) |
| 77 | germinator.grow(structure) |
| 78 | germinator.add_extras(structure) |
| 79 | |
| 80 | - self.writeGerminateOutput(germinator, structure, flavour, series_name, |
| 81 | - arch) |
| 82 | + self.writeGerminateOutput( |
| 83 | + germinator, structure, flavour, series_name, arch, |
| 84 | + seed_outputs=seed_outputs) |
| 85 | |
| 86 | write_overrides = partial( |
| 87 | self.writeOverrides, override_file, germinator, structure, arch) |
| 88 | @@ -295,7 +307,7 @@ |
| 89 | write_overrides("build-essential", "Build-Essential", "yes") |
| 90 | |
| 91 | def germinateArch(self, override_file, series_name, components, arch, |
| 92 | - flavours, structures): |
| 93 | + flavours, structures, seed_outputs=None): |
| 94 | """Germinate seeds on all flavours for a single architecture.""" |
| 95 | germinator = Germinator(arch) |
| 96 | |
| 97 | @@ -316,7 +328,19 @@ |
| 98 | |
| 99 | self.germinateArchFlavour( |
| 100 | override_file, germinator, series_name, arch, flavour, |
| 101 | - structures[flavour], flavour == flavours[0]) |
| 102 | + structures[flavour], flavour == flavours[0], |
| 103 | + seed_outputs=seed_outputs) |
| 104 | + |
| 105 | + def removeStaleOutputs(self, series_name, seed_outputs): |
| 106 | + """Remove stale outputs for a series. |
| 107 | + |
| 108 | + Any per-seed outputs not in seed_outputs are considered stale. |
| 109 | + """ |
| 110 | + all_outputs = glob.glob( |
| 111 | + os.path.join(self.config.germinateroot, "*_*_%s_*" % series_name)) |
| 112 | + for output in all_outputs: |
| 113 | + if os.path.basename(output) not in seed_outputs: |
| 114 | + os.remove(output) |
| 115 | |
| 116 | def generateExtraOverrides(self, series_name, components, architectures, |
| 117 | flavours, seed_bases=None): |
| 118 | @@ -324,6 +348,7 @@ |
| 119 | series_name, flavours, seed_bases=seed_bases) |
| 120 | |
| 121 | if structures: |
| 122 | + seed_outputs = set() |
| 123 | override_path = os.path.join( |
| 124 | self.config.miscroot, |
| 125 | "more-extra.override.%s.main" % series_name) |
| 126 | @@ -331,7 +356,8 @@ |
| 127 | for arch in architectures: |
| 128 | self.germinateArch( |
| 129 | override_file, series_name, components, arch, |
| 130 | - flavours, structures) |
| 131 | + flavours, structures, seed_outputs=seed_outputs) |
| 132 | + self.removeStaleOutputs(series_name, seed_outputs) |
| 133 | |
| 134 | def process(self, seed_bases=None): |
| 135 | """Do the bulk of the work.""" |
| 136 | |
| 137 | === removed file 'lib/lp/archivepublisher/tests/publisher-config.txt' |
| 138 | --- lib/lp/archivepublisher/tests/publisher-config.txt 2011-12-29 05:29:36 +0000 |
| 139 | +++ lib/lp/archivepublisher/tests/publisher-config.txt 1970-01-01 00:00:00 +0000 |
| 140 | @@ -1,195 +0,0 @@ |
| 141 | -Publisher Configuration Provider |
| 142 | -================================ |
| 143 | - |
| 144 | -The config module has a function to provide a modified publisher configuration |
| 145 | -that provides the right paths for its publication according to the given |
| 146 | -archive. |
| 147 | - |
| 148 | -We will use a helper function for dumping publisher configurations. |
| 149 | - |
| 150 | - >>> config_attributes = [ |
| 151 | - ... 'distroroot', |
| 152 | - ... 'archiveroot', |
| 153 | - ... 'poolroot', |
| 154 | - ... 'distsroot', |
| 155 | - ... 'overrideroot', |
| 156 | - ... 'cacheroot', |
| 157 | - ... 'miscroot', |
| 158 | - ... 'germinateroot', |
| 159 | - ... 'temproot', |
| 160 | - ... ] |
| 161 | - |
| 162 | - >>> def dump_config(config): |
| 163 | - ... for attr_name in config_attributes: |
| 164 | - ... print '%s: %s' % (attr_name, getattr(config, attr_name)) |
| 165 | - |
| 166 | - |
| 167 | -Primary |
| 168 | -------- |
| 169 | - |
| 170 | - >>> from lp.registry.interfaces.distribution import IDistributionSet |
| 171 | - >>> ubuntutest = getUtility(IDistributionSet)['ubuntutest'] |
| 172 | - |
| 173 | - >>> from lp.archivepublisher.config import getPubConfig |
| 174 | - >>> primary_config = getPubConfig(ubuntutest.main_archive) |
| 175 | - |
| 176 | - >>> dump_config(primary_config) |
| 177 | - distroroot: /var/tmp/archive |
| 178 | - archiveroot: /var/tmp/archive/ubuntutest |
| 179 | - poolroot: /var/tmp/archive/ubuntutest/pool |
| 180 | - distsroot: /var/tmp/archive/ubuntutest/dists |
| 181 | - overrideroot: /var/tmp/archive/ubuntutest-overrides |
| 182 | - cacheroot: /var/tmp/archive/ubuntutest-cache |
| 183 | - miscroot: /var/tmp/archive/ubuntutest-misc |
| 184 | - germinateroot: /var/tmp/archive/ubuntutest-germinate |
| 185 | - temproot: /var/tmp/archive/ubuntutest-temp |
| 186 | - |
| 187 | - |
| 188 | -PPAs |
| 189 | ----- |
| 190 | - |
| 191 | -Adjust Celso's PPA to point to a configured distribution and built its |
| 192 | -publisher configuration. |
| 193 | - |
| 194 | - >>> # cprov 20061127: We should *never* be able to change a PPA |
| 195 | - >>> # distribution, however 'ubuntu' is not prepared for publication, thus |
| 196 | - >>> # we have to override the PPA to 'ubuntutest' in order to perform the |
| 197 | - >>> # tests. |
| 198 | - |
| 199 | - >>> from lp.registry.interfaces.person import IPersonSet |
| 200 | - >>> cprov = getUtility(IPersonSet).getByName('cprov') |
| 201 | - >>> cprov_archive = cprov.archive |
| 202 | - >>> cprov_archive.distribution = ubuntutest |
| 203 | - |
| 204 | - >>> ppa_config = getPubConfig(cprov_archive) |
| 205 | - |
| 206 | -The base Archive publication location is set in the current Launchpad |
| 207 | -configuration file: |
| 208 | - |
| 209 | - >>> from lp.services.config import config |
| 210 | - >>> ppa_config.distroroot == config.personalpackagearchive.root |
| 211 | - True |
| 212 | - |
| 213 | -A PPA repository topology will follow: |
| 214 | - |
| 215 | -<PPA_BASE_DIR>/<PERSONNAME>/<DISTRIBUTION> |
| 216 | - |
| 217 | -And some paths are not used for PPA workflow, so they are set to |
| 218 | -None, so they won't get created: |
| 219 | - |
| 220 | - >>> dump_config(ppa_config) |
| 221 | - distroroot: /var/tmp/ppa.test/ |
| 222 | - archiveroot: /var/tmp/ppa.test/cprov/ppa/ubuntutest |
| 223 | - poolroot: /var/tmp/ppa.test/cprov/ppa/ubuntutest/pool |
| 224 | - distsroot: /var/tmp/ppa.test/cprov/ppa/ubuntutest/dists |
| 225 | - overrideroot: None |
| 226 | - cacheroot: None |
| 227 | - miscroot: None |
| 228 | - germinateroot: None |
| 229 | - temproot: /var/tmp/archive/ubuntutest-temp |
| 230 | - |
| 231 | -There is a separate location for private PPAs that is used if the |
| 232 | -archive is marked as private: |
| 233 | - |
| 234 | - >>> (config.personalpackagearchive.private_root != |
| 235 | - ... config.personalpackagearchive.root) |
| 236 | - True |
| 237 | - |
| 238 | - >>> cprov_private_ppa = factory.makeArchive( |
| 239 | - ... owner=cprov, name='myprivateppa', |
| 240 | - ... distribution=cprov_archive.distribution) |
| 241 | - >>> cprov_private_ppa.private = True |
| 242 | - >>> cprov_private_ppa.buildd_secret = "secret" |
| 243 | - >>> p3a_config = getPubConfig(cprov_private_ppa) |
| 244 | - |
| 245 | - >>> (p3a_config.distroroot == |
| 246 | - ... config.personalpackagearchive.private_root) |
| 247 | - True |
| 248 | - |
| 249 | - >>> dump_config(p3a_config) |
| 250 | - distroroot: /var/tmp/ppa |
| 251 | - archiveroot: /var/tmp/ppa/cprov/myprivateppa/ubuntutest |
| 252 | - poolroot: /var/tmp/ppa/cprov/myprivateppa/ubuntutest/pool |
| 253 | - distsroot: /var/tmp/ppa/cprov/myprivateppa/ubuntutest/dists |
| 254 | - overrideroot: None |
| 255 | - cacheroot: None |
| 256 | - miscroot: None |
| 257 | - germinateroot: None |
| 258 | - temproot: /var/tmp/archive/ubuntutest-temp |
| 259 | - |
| 260 | - |
| 261 | -Partner |
| 262 | -------- |
| 263 | - |
| 264 | -The publisher config for PARTNER contains only 'partner' in its |
| 265 | -components. This prevents non-partner being published in the partner |
| 266 | -archive. |
| 267 | - |
| 268 | - >>> from lp.soyuz.interfaces.archive import IArchiveSet |
| 269 | - >>> partner_archive = getUtility(IArchiveSet).getByDistroAndName( |
| 270 | - ... ubuntutest, 'partner') |
| 271 | - |
| 272 | - >>> partner_config = getPubConfig(partner_archive) |
| 273 | - |
| 274 | - >>> dump_config(partner_config) |
| 275 | - distroroot: /var/tmp/archive |
| 276 | - archiveroot: /var/tmp/archive/ubuntutest-partner |
| 277 | - poolroot: /var/tmp/archive/ubuntutest-partner/pool |
| 278 | - distsroot: /var/tmp/archive/ubuntutest-partner/dists |
| 279 | - overrideroot: None |
| 280 | - cacheroot: None |
| 281 | - miscroot: None |
| 282 | - germinateroot: None |
| 283 | - temproot: /var/tmp/archive/ubuntutest-temp |
| 284 | - |
| 285 | - |
| 286 | -DEBUG |
| 287 | ------ |
| 288 | - |
| 289 | -The publisher configuration for DEBUG archives points to directories |
| 290 | -besides PRIMARY repository ones, but the distribution part is |
| 291 | -modified to be clearly different than the PRIMARY one. |
| 292 | - |
| 293 | - >>> from lp.soyuz.enums import ArchivePurpose |
| 294 | - >>> debug_archive = getUtility(IArchiveSet).new( |
| 295 | - ... purpose=ArchivePurpose.DEBUG, owner=ubuntutest.owner, |
| 296 | - ... distribution=ubuntutest) |
| 297 | - |
| 298 | - >>> debug_config = getPubConfig(debug_archive) |
| 299 | - |
| 300 | - >>> dump_config(debug_config) |
| 301 | - distroroot: /var/tmp/archive |
| 302 | - archiveroot: /var/tmp/archive/ubuntutest-debug |
| 303 | - poolroot: /var/tmp/archive/ubuntutest-debug/pool |
| 304 | - distsroot: /var/tmp/archive/ubuntutest-debug/dists |
| 305 | - overrideroot: None |
| 306 | - cacheroot: None |
| 307 | - miscroot: None |
| 308 | - germinateroot: None |
| 309 | - temproot: /var/tmp/archive/ubuntutest-temp |
| 310 | - |
| 311 | - |
| 312 | -COPY |
| 313 | ----- |
| 314 | - |
| 315 | -In the case of copy archives (used for rebuild testing) the archiveroot |
| 316 | -is of the form distroroot/distroname-archivename/distroname |
| 317 | - |
| 318 | - >>> copy_archive = getUtility(IArchiveSet).new( |
| 319 | - ... purpose=ArchivePurpose.COPY, owner=ubuntutest.owner, |
| 320 | - ... distribution=ubuntutest, name="rebuildtest99") |
| 321 | - |
| 322 | - >>> copy_config = getPubConfig(copy_archive) |
| 323 | - |
| 324 | - >>> dump_config(copy_config) |
| 325 | - distroroot: /var/tmp/archive |
| 326 | - archiveroot: /var/tmp/archive/ubuntutest-rebuildtest99/ubuntutest |
| 327 | - poolroot: /var/tmp/archive/ubuntutest-rebuildtest99/ubuntutest/pool |
| 328 | - distsroot: /var/tmp/archive/ubuntutest-rebuildtest99/ubuntutest/dists |
| 329 | - overrideroot: |
| 330 | - /var/tmp/archive/ubuntutest-rebuildtest99/ubuntutest-overrides |
| 331 | - cacheroot: /var/tmp/archive/ubuntutest-rebuildtest99/ubuntutest-cache |
| 332 | - miscroot: /var/tmp/archive/ubuntutest-rebuildtest99/ubuntutest-misc |
| 333 | - germinateroot: |
| 334 | - /var/tmp/archive/ubuntutest-rebuildtest99/ubuntutest-germinate |
| 335 | - temproot: /var/tmp/archive/ubuntutest-rebuildtest99/ubuntutest-temp |
| 336 | |
| 337 | === modified file 'lib/lp/archivepublisher/tests/test_config.py' |
| 338 | --- lib/lp/archivepublisher/tests/test_config.py 2012-01-01 02:58:52 +0000 |
| 339 | +++ lib/lp/archivepublisher/tests/test_config.py 2012-05-21 19:07:38 +0000 |
| 340 | @@ -1,11 +1,20 @@ |
| 341 | -# Copyright 2011 Canonical Ltd. This software is licensed under the |
| 342 | +# Copyright 2011-2012 Canonical Ltd. This software is licensed under the |
| 343 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 344 | |
| 345 | -"""Test publisher configs handling.""" |
| 346 | +"""Test publisher configs handling. |
| 347 | + |
| 348 | +Publisher configuration provides archive-dependent filesystem paths. |
| 349 | +""" |
| 350 | |
| 351 | __metaclass__ = type |
| 352 | |
| 353 | +from zope.component import getUtility |
| 354 | + |
| 355 | from lp.archivepublisher.config import getPubConfig |
| 356 | +from lp.registry.interfaces.distribution import IDistributionSet |
| 357 | +from lp.services.config import config |
| 358 | +from lp.soyuz.enums import ArchivePurpose |
| 359 | +from lp.soyuz.interfaces.archive import IArchiveSet |
| 360 | from lp.testing import TestCaseWithFactory |
| 361 | from lp.testing.layers import ZopelessDatabaseLayer |
| 362 | |
| 363 | @@ -14,6 +23,152 @@ |
| 364 | |
| 365 | layer = ZopelessDatabaseLayer |
| 366 | |
| 367 | + def setUp(self): |
| 368 | + super(TestGetPubConfig, self).setUp() |
| 369 | + self.ubuntutest = getUtility(IDistributionSet)['ubuntutest'] |
| 370 | + self.root = "/var/tmp/archive" |
| 371 | + |
| 372 | def test_getPubConfig_returns_None_if_no_publisherconfig_found(self): |
| 373 | archive = self.factory.makeDistribution(no_pubconf=True).main_archive |
| 374 | self.assertEqual(None, getPubConfig(archive)) |
| 375 | + |
| 376 | + def test_primary_config(self): |
| 377 | + # Primary archive configuration is correct. |
| 378 | + primary_config = getPubConfig(self.ubuntutest.main_archive) |
| 379 | + self.assertEqual(self.root, primary_config.distroroot) |
| 380 | + archiveroot = self.root + "/ubuntutest" |
| 381 | + self.assertEqual(archiveroot, primary_config.archiveroot) |
| 382 | + self.assertEqual(archiveroot + "/pool", primary_config.poolroot) |
| 383 | + self.assertEqual(archiveroot + "/dists", primary_config.distsroot) |
| 384 | + self.assertEqual( |
| 385 | + archiveroot + "-overrides", primary_config.overrideroot) |
| 386 | + self.assertEqual(archiveroot + "-cache", primary_config.cacheroot) |
| 387 | + self.assertEqual(archiveroot + "-misc", primary_config.miscroot) |
| 388 | + self.assertEqual( |
| 389 | + archiveroot + "-germinate", primary_config.germinateroot) |
| 390 | + self.assertEqual( |
| 391 | + self.root + "/ubuntutest-temp", primary_config.temproot) |
| 392 | + |
| 393 | + def test_partner_config(self): |
| 394 | + # Partner archive configuration is correct. |
| 395 | + # The publisher config for PARTNER contains only 'partner' in its |
| 396 | + # components. This prevents non-partner being published in the |
| 397 | + # partner archive. |
| 398 | + partner_archive = getUtility(IArchiveSet).getByDistroAndName( |
| 399 | + self.ubuntutest, "partner") |
| 400 | + partner_config = getPubConfig(partner_archive) |
| 401 | + self.root = "/var/tmp/archive" |
| 402 | + self.assertEqual(self.root, partner_config.distroroot) |
| 403 | + archiveroot = self.root + "/ubuntutest-partner" |
| 404 | + self.assertEqual(archiveroot, partner_config.archiveroot) |
| 405 | + self.assertEqual(archiveroot + "/pool", partner_config.poolroot) |
| 406 | + self.assertEqual(archiveroot + "/dists", partner_config.distsroot) |
| 407 | + self.assertIsNone(partner_config.overrideroot) |
| 408 | + self.assertIsNone(partner_config.cacheroot) |
| 409 | + self.assertIsNone(partner_config.miscroot) |
| 410 | + self.assertIsNone(partner_config.germinateroot) |
| 411 | + self.assertEqual( |
| 412 | + self.root + "/ubuntutest-temp", partner_config.temproot) |
| 413 | + |
| 414 | + def test_debug_config(self): |
| 415 | + # The publisher configuration for DEBUG archives points to |
| 416 | + # directories beside PRIMARY repository ones, but the distribution |
| 417 | + # part is modified to be clearly different than the PRIMARY one. |
| 418 | + debug_archive = getUtility(IArchiveSet).new( |
| 419 | + purpose=ArchivePurpose.DEBUG, owner=self.ubuntutest.owner, |
| 420 | + distribution=self.ubuntutest) |
| 421 | + debug_config = getPubConfig(debug_archive) |
| 422 | + self.assertEqual(self.root, debug_config.distroroot) |
| 423 | + archiveroot = self.root + "/ubuntutest-debug" |
| 424 | + self.assertEqual(archiveroot, debug_config.archiveroot) |
| 425 | + self.assertEqual(archiveroot + "/pool", debug_config.poolroot) |
| 426 | + self.assertEqual(archiveroot + "/dists", debug_config.distsroot) |
| 427 | + self.assertIsNone(debug_config.overrideroot) |
| 428 | + self.assertIsNone(debug_config.cacheroot) |
| 429 | + self.assertIsNone(debug_config.miscroot) |
| 430 | + self.assertIsNone(debug_config.germinateroot) |
| 431 | + self.assertEqual(self.root + "/ubuntutest-temp", debug_config.temproot) |
| 432 | + |
| 433 | + def test_copy_config(self): |
| 434 | + # In the case of copy archives (used for rebuild testing) the |
| 435 | + # archiveroot is of the form |
| 436 | + # DISTROROOT/DISTRONAME-ARCHIVENAME/DISTRONAME. |
| 437 | + copy_archive = getUtility(IArchiveSet).new( |
| 438 | + purpose=ArchivePurpose.COPY, owner=self.ubuntutest.owner, |
| 439 | + distribution=self.ubuntutest, name="rebuildtest99") |
| 440 | + copy_config = getPubConfig(copy_archive) |
| 441 | + self.assertEqual(self.root, copy_config.distroroot) |
| 442 | + archiveroot = self.root + "/ubuntutest-rebuildtest99/ubuntutest" |
| 443 | + self.assertEqual(archiveroot, copy_config.archiveroot) |
| 444 | + self.assertEqual(archiveroot + "/pool", copy_config.poolroot) |
| 445 | + self.assertEqual(archiveroot + "/dists", copy_config.distsroot) |
| 446 | + self.assertEqual( |
| 447 | + archiveroot + "-overrides", copy_config.overrideroot) |
| 448 | + self.assertEqual(archiveroot + "-cache", copy_config.cacheroot) |
| 449 | + self.assertEqual(archiveroot + "-misc", copy_config.miscroot) |
| 450 | + self.assertEqual( |
| 451 | + archiveroot + "-germinate", copy_config.germinateroot) |
| 452 | + self.assertEqual(archiveroot + "-temp", copy_config.temproot) |
| 453 | + |
| 454 | + |
| 455 | +class TestGetPubConfigPPA(TestCaseWithFactory): |
| 456 | + |
| 457 | + layer = ZopelessDatabaseLayer |
| 458 | + |
| 459 | + def setUp(self): |
| 460 | + super(TestGetPubConfigPPA, self).setUp() |
| 461 | + self.ubuntutest = getUtility(IDistributionSet)['ubuntutest'] |
| 462 | + self.ppa = self.factory.makeArchive( |
| 463 | + distribution=self.ubuntutest, purpose=ArchivePurpose.PPA) |
| 464 | + self.ppa_config = getPubConfig(self.ppa) |
| 465 | + |
| 466 | + def test_ppa_root_matches_config(self): |
| 467 | + # The base publication location is set by Launchpad configuration. |
| 468 | + self.assertEqual( |
| 469 | + config.personalpackagearchive.root, self.ppa_config.distroroot) |
| 470 | + |
| 471 | + def test_ppa_config(self): |
| 472 | + # PPA configuration matches the PPA repository topology: |
| 473 | + # <PPA_BASE_DIR>/<PERSONNAME>/<DISTRIBUTION> |
| 474 | + # Some paths are not used in the PPA workflow, so they are set to |
| 475 | + # None in order that they won't get created. |
| 476 | + self.assertEqual("/var/tmp/ppa.test/", self.ppa_config.distroroot) |
| 477 | + archiveroot = "%s%s/%s/ubuntutest" % ( |
| 478 | + self.ppa_config.distroroot, self.ppa.owner.name, self.ppa.name) |
| 479 | + self.assertEqual(archiveroot, self.ppa_config.archiveroot) |
| 480 | + self.assertEqual(archiveroot + "/pool", self.ppa_config.poolroot) |
| 481 | + self.assertEqual(archiveroot + "/dists", self.ppa_config.distsroot) |
| 482 | + self.assertIsNone(self.ppa_config.overrideroot) |
| 483 | + self.assertIsNone(self.ppa_config.cacheroot) |
| 484 | + self.assertIsNone(self.ppa_config.miscroot) |
| 485 | + self.assertIsNone(self.ppa_config.germinateroot) |
| 486 | + self.assertEqual( |
| 487 | + "/var/tmp/archive/ubuntutest-temp", self.ppa_config.temproot) |
| 488 | + |
| 489 | + def test_private_ppa_separate_root(self): |
| 490 | + # Private PPAs are published to a different location. |
| 491 | + self.assertNotEqual( |
| 492 | + config.personalpackagearchive.private_root, |
| 493 | + config.personalpackagearchive.root) |
| 494 | + |
| 495 | + def test_private_ppa_config(self): |
| 496 | + # Private PPA configuration uses the separate base location. |
| 497 | + p3a = self.factory.makeArchive( |
| 498 | + owner=self.ppa.owner, name="myprivateppa", |
| 499 | + distribution=self.ubuntutest, purpose=ArchivePurpose.PPA) |
| 500 | + p3a.private = True |
| 501 | + p3a.buildd_secret = "secret" |
| 502 | + p3a_config = getPubConfig(p3a) |
| 503 | + self.assertEqual( |
| 504 | + config.personalpackagearchive.private_root, p3a_config.distroroot) |
| 505 | + archiveroot = "%s/%s/%s/ubuntutest" % ( |
| 506 | + p3a_config.distroroot, p3a.owner.name, p3a.name) |
| 507 | + self.assertEqual(archiveroot, p3a_config.archiveroot) |
| 508 | + self.assertEqual(archiveroot + "/pool", p3a_config.poolroot) |
| 509 | + self.assertEqual(archiveroot + "/dists", p3a_config.distsroot) |
| 510 | + self.assertIsNone(p3a_config.overrideroot) |
| 511 | + self.assertIsNone(p3a_config.cacheroot) |
| 512 | + self.assertIsNone(p3a_config.miscroot) |
| 513 | + self.assertIsNone(p3a_config.germinateroot) |
| 514 | + self.assertEqual( |
| 515 | + "/var/tmp/archive/ubuntutest-temp", p3a_config.temproot) |
| 516 | |
| 517 | === modified file 'lib/lp/archivepublisher/tests/test_generate_extra_overrides.py' |
| 518 | --- lib/lp/archivepublisher/tests/test_generate_extra_overrides.py 2012-01-03 17:08:40 +0000 |
| 519 | +++ lib/lp/archivepublisher/tests/test_generate_extra_overrides.py 2012-05-21 19:07:38 +0000 |
| 520 | @@ -1,10 +1,11 @@ |
| 521 | -# Copyright 2011 Canonical Ltd. This software is licensed under the |
| 522 | +# Copyright 2011-2012 Canonical Ltd. This software is licensed under the |
| 523 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 524 | |
| 525 | """Test for the `generate-extra-overrides` script.""" |
| 526 | |
| 527 | __metaclass__ = type |
| 528 | |
| 529 | +from functools import partial |
| 530 | import logging |
| 531 | from optparse import OptionValueError |
| 532 | import os |
| 533 | @@ -46,6 +47,12 @@ |
| 534 | return handle.read() |
| 535 | |
| 536 | |
| 537 | +def touch(path): |
| 538 | + """Create an empty file at path.""" |
| 539 | + with open_for_writing(path, "a"): |
| 540 | + pass |
| 541 | + |
| 542 | + |
| 543 | class TestAtomicFile(TestCaseWithFactory): |
| 544 | """Tests for the AtomicFile helper class.""" |
| 545 | |
| 546 | @@ -113,6 +120,24 @@ |
| 547 | script.distribution = distribution |
| 548 | return script |
| 549 | |
| 550 | + def setUpDistroAndScript(self, series_statuses=["DEVELOPMENT"], **kwargs): |
| 551 | + """Helper wrapping distro and script setup.""" |
| 552 | + self.distro = self.makeDistro() |
| 553 | + self.distroseries = [ |
| 554 | + self.factory.makeDistroSeries( |
| 555 | + distribution=self.distro, status=SeriesStatus.items[status]) |
| 556 | + for status in series_statuses] |
| 557 | + self.script = self.makeScript(self.distro, **kwargs) |
| 558 | + |
| 559 | + def setUpComponent(self, component=None): |
| 560 | + """Create a component and attach it to all distroseries.""" |
| 561 | + if component is None: |
| 562 | + component = self.factory.makeComponent() |
| 563 | + for distroseries in self.distroseries: |
| 564 | + self.factory.makeComponentSelection( |
| 565 | + distroseries=distroseries, component=component) |
| 566 | + return component |
| 567 | + |
| 568 | def makePackage(self, component, dases, **kwargs): |
| 569 | """Create a published source and binary package for testing.""" |
| 570 | package = self.factory.makeDistributionSourcePackage( |
| 571 | @@ -175,11 +200,8 @@ |
| 572 | self.seeddir, "%s.%s" % (flavour, series_name), seed_name) |
| 573 | |
| 574 | def makeSeedStructure(self, flavour, series_name, seed_names, |
| 575 | - seed_inherit=None): |
| 576 | + seed_inherit={}): |
| 577 | """Create a simple seed structure file.""" |
| 578 | - if seed_inherit is None: |
| 579 | - seed_inherit = {} |
| 580 | - |
| 581 | structure_path = self.composeSeedPath( |
| 582 | flavour, series_name, "STRUCTURE") |
| 583 | with open_for_writing(structure_path, "w") as structure: |
| 584 | @@ -246,130 +268,87 @@ |
| 585 | def test_looks_up_distro(self): |
| 586 | # The script looks up and keeps the distribution named on the |
| 587 | # command line. |
| 588 | - distro = self.makeDistro() |
| 589 | - self.factory.makeDistroSeries(distro) |
| 590 | - script = self.makeScript(distro) |
| 591 | - self.assertEqual(distro, script.distribution) |
| 592 | + self.setUpDistroAndScript() |
| 593 | + self.assertEqual(self.distro, self.script.distribution) |
| 594 | |
| 595 | def test_prefers_development_distro_series(self): |
| 596 | # The script prefers a DEVELOPMENT series for the named |
| 597 | # distribution over CURRENT and SUPPORTED series. |
| 598 | - distro = self.makeDistro() |
| 599 | - self.factory.makeDistroSeries(distro, status=SeriesStatus.SUPPORTED) |
| 600 | - self.factory.makeDistroSeries(distro, status=SeriesStatus.CURRENT) |
| 601 | - development_distroseries = self.factory.makeDistroSeries( |
| 602 | - distro, status=SeriesStatus.DEVELOPMENT) |
| 603 | - script = self.makeScript(distro) |
| 604 | - observed_series = [series.name for series in script.series] |
| 605 | - self.assertEqual([development_distroseries.name], observed_series) |
| 606 | + self.setUpDistroAndScript(["SUPPORTED", "CURRENT", "DEVELOPMENT"]) |
| 607 | + self.assertEqual([self.distroseries[2]], self.script.series) |
| 608 | |
| 609 | def test_permits_frozen_distro_series(self): |
| 610 | # If there is no DEVELOPMENT series, a FROZEN one will do. |
| 611 | - distro = self.makeDistro() |
| 612 | - self.factory.makeDistroSeries(distro, status=SeriesStatus.SUPPORTED) |
| 613 | - self.factory.makeDistroSeries(distro, status=SeriesStatus.CURRENT) |
| 614 | - frozen_distroseries = self.factory.makeDistroSeries( |
| 615 | - distro, status=SeriesStatus.FROZEN) |
| 616 | - script = self.makeScript(distro) |
| 617 | - observed_series = [series.name for series in script.series] |
| 618 | - self.assertEqual([frozen_distroseries.name], observed_series) |
| 619 | + self.setUpDistroAndScript(["SUPPORTED", "CURRENT", "FROZEN"]) |
| 620 | + self.assertEqual([self.distroseries[2]], self.script.series) |
| 621 | |
| 622 | def test_requires_development_frozen_distro_series(self): |
| 623 | # If there is no DEVELOPMENT or FROZEN series, the script fails. |
| 624 | - distro = self.makeDistro() |
| 625 | - self.factory.makeDistroSeries(distro, status=SeriesStatus.SUPPORTED) |
| 626 | - self.factory.makeDistroSeries(distro, status=SeriesStatus.CURRENT) |
| 627 | - script = self.makeScript(distro, run_setup=False) |
| 628 | - self.assertRaises(LaunchpadScriptFailure, script.processOptions) |
| 629 | + self.setUpDistroAndScript(["SUPPORTED", "CURRENT"], run_setup=False) |
| 630 | + self.assertRaises(LaunchpadScriptFailure, self.script.processOptions) |
| 631 | |
| 632 | def test_multiple_development_frozen_distro_series(self): |
| 633 | # If there are multiple DEVELOPMENT or FROZEN series, they are all |
| 634 | # used. |
| 635 | - distro = self.makeDistro() |
| 636 | - development_distroseries_one = self.factory.makeDistroSeries( |
| 637 | - distro, status=SeriesStatus.DEVELOPMENT) |
| 638 | - development_distroseries_two = self.factory.makeDistroSeries( |
| 639 | - distro, status=SeriesStatus.DEVELOPMENT) |
| 640 | - frozen_distroseries_one = self.factory.makeDistroSeries( |
| 641 | - distro, status=SeriesStatus.FROZEN) |
| 642 | - frozen_distroseries_two = self.factory.makeDistroSeries( |
| 643 | - distro, status=SeriesStatus.FROZEN) |
| 644 | - script = self.makeScript(distro) |
| 645 | - expected_series = [ |
| 646 | - development_distroseries_one.name, |
| 647 | - development_distroseries_two.name, |
| 648 | - frozen_distroseries_one.name, |
| 649 | - frozen_distroseries_two.name, |
| 650 | - ] |
| 651 | - observed_series = [series.name for series in script.series] |
| 652 | - self.assertContentEqual(expected_series, observed_series) |
| 653 | + self.setUpDistroAndScript( |
| 654 | + ["DEVELOPMENT", "DEVELOPMENT", "FROZEN", "FROZEN"]) |
| 655 | + self.assertContentEqual(self.distroseries, self.script.series) |
| 656 | |
| 657 | def test_components_exclude_partner(self): |
| 658 | # If a 'partner' component exists, it is excluded. |
| 659 | - distro = self.makeDistro() |
| 660 | - distroseries = self.factory.makeDistroSeries(distro) |
| 661 | - self.factory.makeComponentSelection( |
| 662 | - distroseries=distroseries, component="main") |
| 663 | - self.factory.makeComponentSelection( |
| 664 | - distroseries=distroseries, component="partner") |
| 665 | - script = self.makeScript(distro) |
| 666 | - self.assertEqual(1, len(script.series)) |
| 667 | - self.assertEqual(["main"], script.getComponents(script.series[0])) |
| 668 | + self.setUpDistroAndScript() |
| 669 | + self.setUpComponent(component="main") |
| 670 | + self.setUpComponent(component="partner") |
| 671 | + self.assertEqual(1, len(self.script.series)) |
| 672 | + self.assertEqual( |
| 673 | + ["main"], self.script.getComponents(self.script.series[0])) |
| 674 | |
| 675 | def test_compose_output_path_in_germinateroot(self): |
| 676 | # Output files are written to the correct locations under |
| 677 | # germinateroot. |
| 678 | - distro = self.makeDistro() |
| 679 | - distroseries = self.factory.makeDistroSeries(distro) |
| 680 | - script = self.makeScript(distro) |
| 681 | + self.setUpDistroAndScript() |
| 682 | flavour = self.factory.getUniqueString() |
| 683 | arch = self.factory.getUniqueString() |
| 684 | base = self.factory.getUniqueString() |
| 685 | - output = script.composeOutputPath( |
| 686 | - flavour, distroseries.name, arch, base) |
| 687 | + output = self.script.composeOutputPath( |
| 688 | + flavour, self.distroseries[0].name, arch, base) |
| 689 | self.assertEqual( |
| 690 | "%s/%s_%s_%s_%s" % ( |
| 691 | - script.config.germinateroot, base, flavour, distroseries.name, |
| 692 | - arch), |
| 693 | + self.script.config.germinateroot, base, flavour, |
| 694 | + self.distroseries[0].name, arch), |
| 695 | output) |
| 696 | |
| 697 | def test_make_seed_structures_missing_seeds(self): |
| 698 | # makeSeedStructures ignores missing seeds. |
| 699 | - distro = self.makeDistro() |
| 700 | - distroseries = self.factory.makeDistroSeries(distribution=distro) |
| 701 | - series_name = distroseries.name |
| 702 | - script = self.makeScript(distro) |
| 703 | + self.setUpDistroAndScript() |
| 704 | + series_name = self.distroseries[0].name |
| 705 | flavour = self.factory.getUniqueString() |
| 706 | |
| 707 | - structures = script.makeSeedStructures( |
| 708 | + structures = self.script.makeSeedStructures( |
| 709 | series_name, [flavour], seed_bases=["file://%s" % self.seeddir]) |
| 710 | self.assertEqual({}, structures) |
| 711 | |
| 712 | def test_make_seed_structures_empty_seed_structure(self): |
| 713 | # makeSeedStructures ignores an empty seed structure. |
| 714 | - distro = self.makeDistro() |
| 715 | - distroseries = self.factory.makeDistroSeries(distribution=distro) |
| 716 | - series_name = distroseries.name |
| 717 | - script = self.makeScript(distro) |
| 718 | + self.setUpDistroAndScript() |
| 719 | + series_name = self.distroseries[0].name |
| 720 | flavour = self.factory.getUniqueString() |
| 721 | self.makeSeedStructure(flavour, series_name, []) |
| 722 | |
| 723 | - structures = script.makeSeedStructures( |
| 724 | + structures = self.script.makeSeedStructures( |
| 725 | series_name, [flavour], seed_bases=["file://%s" % self.seeddir]) |
| 726 | self.assertEqual({}, structures) |
| 727 | |
| 728 | def test_make_seed_structures_valid_seeds(self): |
| 729 | # makeSeedStructures reads valid seeds successfully. |
| 730 | - distro = self.makeDistro() |
| 731 | - distroseries = self.factory.makeDistroSeries(distribution=distro) |
| 732 | - series_name = distroseries.name |
| 733 | - script = self.makeScript(distro) |
| 734 | + self.setUpDistroAndScript() |
| 735 | + series_name = self.distroseries[0].name |
| 736 | flavour = self.factory.getUniqueString() |
| 737 | seed = self.factory.getUniqueString() |
| 738 | self.makeSeedStructure(flavour, series_name, [seed]) |
| 739 | self.makeSeed(flavour, series_name, seed, []) |
| 740 | |
| 741 | - structures = script.makeSeedStructures( |
| 742 | + structures = self.script.makeSeedStructures( |
| 743 | series_name, [flavour], seed_bases=["file://%s" % self.seeddir]) |
| 744 | self.assertIn(flavour, structures) |
| 745 | |
| 746 | @@ -390,18 +369,15 @@ |
| 747 | def test_germinate_output(self): |
| 748 | # A single call to germinateArch produces output for all flavours on |
| 749 | # one architecture. |
| 750 | - distro = self.makeDistro() |
| 751 | - distroseries = self.factory.makeDistroSeries(distribution=distro) |
| 752 | - series_name = distroseries.name |
| 753 | - component = self.factory.makeComponent() |
| 754 | - self.factory.makeComponentSelection( |
| 755 | - distroseries=distroseries, component=component) |
| 756 | - das = self.factory.makeDistroArchSeries(distroseries=distroseries) |
| 757 | + self.setUpDistroAndScript() |
| 758 | + series_name = self.distroseries[0].name |
| 759 | + component = self.setUpComponent() |
| 760 | + das = self.factory.makeDistroArchSeries( |
| 761 | + distroseries=self.distroseries[0]) |
| 762 | arch = das.architecturetag |
| 763 | one = self.makePackage(component, [das]) |
| 764 | two = self.makePackage(component, [das]) |
| 765 | - script = self.makeScript(distro) |
| 766 | - self.makeIndexFiles(script, distroseries) |
| 767 | + self.makeIndexFiles(self.script, self.distroseries[0]) |
| 768 | |
| 769 | flavour_one = self.factory.getUniqueString() |
| 770 | flavour_two = self.factory.getUniqueString() |
| 771 | @@ -412,51 +388,49 @@ |
| 772 | self.makeSeed(flavour_two, series_name, seed, [two.name]) |
| 773 | |
| 774 | overrides = self.fetchGerminatedOverrides( |
| 775 | - script, distroseries, arch, [flavour_one, flavour_two]) |
| 776 | + self.script, self.distroseries[0], arch, |
| 777 | + [flavour_one, flavour_two]) |
| 778 | self.assertEqual([], overrides) |
| 779 | |
| 780 | seed_dir_one = os.path.join( |
| 781 | self.seeddir, "%s.%s" % (flavour_one, series_name)) |
| 782 | self.assertFilesEqual( |
| 783 | os.path.join(seed_dir_one, "STRUCTURE"), |
| 784 | - script.composeOutputPath( |
| 785 | + self.script.composeOutputPath( |
| 786 | flavour_one, series_name, arch, "structure")) |
| 787 | - self.assertTrue(file_exists(script.composeOutputPath( |
| 788 | + self.assertTrue(file_exists(self.script.composeOutputPath( |
| 789 | flavour_one, series_name, arch, "all"))) |
| 790 | - self.assertTrue(file_exists(script.composeOutputPath( |
| 791 | + self.assertTrue(file_exists(self.script.composeOutputPath( |
| 792 | flavour_one, series_name, arch, "all.sources"))) |
| 793 | - self.assertTrue(file_exists(script.composeOutputPath( |
| 794 | + self.assertTrue(file_exists(self.script.composeOutputPath( |
| 795 | flavour_one, series_name, arch, seed))) |
| 796 | |
| 797 | seed_dir_two = os.path.join( |
| 798 | self.seeddir, "%s.%s" % (flavour_two, series_name)) |
| 799 | self.assertFilesEqual( |
| 800 | os.path.join(seed_dir_two, "STRUCTURE"), |
| 801 | - script.composeOutputPath( |
| 802 | + self.script.composeOutputPath( |
| 803 | flavour_two, series_name, arch, "structure")) |
| 804 | - self.assertTrue(file_exists(script.composeOutputPath( |
| 805 | + self.assertTrue(file_exists(self.script.composeOutputPath( |
| 806 | flavour_two, series_name, arch, "all"))) |
| 807 | - self.assertTrue(file_exists(script.composeOutputPath( |
| 808 | + self.assertTrue(file_exists(self.script.composeOutputPath( |
| 809 | flavour_two, series_name, arch, "all.sources"))) |
| 810 | - self.assertTrue(file_exists(script.composeOutputPath( |
| 811 | + self.assertTrue(file_exists(self.script.composeOutputPath( |
| 812 | flavour_two, series_name, arch, seed))) |
| 813 | |
| 814 | def test_germinate_output_task(self): |
| 815 | # germinateArch produces Task extra overrides. |
| 816 | - distro = self.makeDistro() |
| 817 | - distroseries = self.factory.makeDistroSeries(distribution=distro) |
| 818 | - series_name = distroseries.name |
| 819 | - component = self.factory.makeComponent() |
| 820 | - self.factory.makeComponentSelection( |
| 821 | - distroseries=distroseries, component=component) |
| 822 | - das = self.factory.makeDistroArchSeries(distroseries=distroseries) |
| 823 | + self.setUpDistroAndScript() |
| 824 | + series_name = self.distroseries[0].name |
| 825 | + component = self.setUpComponent() |
| 826 | + das = self.factory.makeDistroArchSeries( |
| 827 | + distroseries=self.distroseries[0]) |
| 828 | arch = das.architecturetag |
| 829 | one = self.makePackage(component, [das]) |
| 830 | two = self.makePackage(component, [das], depends=one.name) |
| 831 | three = self.makePackage(component, [das]) |
| 832 | self.makePackage(component, [das]) |
| 833 | - script = self.makeScript(distro) |
| 834 | - self.makeIndexFiles(script, distroseries) |
| 835 | + self.makeIndexFiles(self.script, self.distroseries[0]) |
| 836 | |
| 837 | flavour = self.factory.getUniqueString() |
| 838 | seed_one = self.factory.getUniqueString() |
| 839 | @@ -470,7 +444,7 @@ |
| 840 | headers=["Task-Description: two"]) |
| 841 | |
| 842 | overrides = self.fetchGerminatedOverrides( |
| 843 | - script, distroseries, arch, [flavour]) |
| 844 | + self.script, self.distroseries[0], arch, [flavour]) |
| 845 | expected_overrides = [ |
| 846 | "%s/%s Task %s" % (one.name, arch, seed_one), |
| 847 | "%s/%s Task %s" % (two.name, arch, seed_one), |
| 848 | @@ -560,17 +534,14 @@ |
| 849 | |
| 850 | def test_germinate_output_build_essential(self): |
| 851 | # germinateArch produces Build-Essential extra overrides. |
| 852 | - distro = self.makeDistro() |
| 853 | - distroseries = self.factory.makeDistroSeries(distribution=distro) |
| 854 | - series_name = distroseries.name |
| 855 | - component = self.factory.makeComponent() |
| 856 | - self.factory.makeComponentSelection( |
| 857 | - distroseries=distroseries, component=component) |
| 858 | - das = self.factory.makeDistroArchSeries(distroseries=distroseries) |
| 859 | + self.setUpDistroAndScript() |
| 860 | + series_name = self.distroseries[0].name |
| 861 | + component = self.setUpComponent() |
| 862 | + das = self.factory.makeDistroArchSeries( |
| 863 | + distroseries=self.distroseries[0]) |
| 864 | arch = das.architecturetag |
| 865 | package = self.makePackage(component, [das]) |
| 866 | - script = self.makeScript(distro) |
| 867 | - self.makeIndexFiles(script, distroseries) |
| 868 | + self.makeIndexFiles(self.script, self.distroseries[0]) |
| 869 | |
| 870 | flavour = self.factory.getUniqueString() |
| 871 | seed = "build-essential" |
| 872 | @@ -578,55 +549,89 @@ |
| 873 | self.makeSeed(flavour, series_name, seed, [package.name]) |
| 874 | |
| 875 | overrides = self.fetchGerminatedOverrides( |
| 876 | - script, distroseries, arch, [flavour]) |
| 877 | + self.script, self.distroseries[0], arch, [flavour]) |
| 878 | self.assertContentEqual( |
| 879 | ["%s/%s Build-Essential yes" % (package.name, arch)], overrides) |
| 880 | |
| 881 | + def test_removes_only_stale_files(self): |
| 882 | + # removeStaleOutputs removes only stale germinate output files. |
| 883 | + self.setUpDistroAndScript() |
| 884 | + series_name = self.distroseries[0].name |
| 885 | + seed_old_file = "old_flavour_%s_i386" % series_name |
| 886 | + seed_new_file = "new_flavour_%s_i386" % series_name |
| 887 | + other_file = "other-file" |
| 888 | + output = partial(os.path.join, self.script.config.germinateroot) |
| 889 | + for base in (seed_old_file, seed_new_file, other_file): |
| 890 | + touch(output(base)) |
| 891 | + self.script.removeStaleOutputs(series_name, set([seed_new_file])) |
| 892 | + self.assertFalse(os.path.exists(output(seed_old_file))) |
| 893 | + self.assertTrue(os.path.exists(output(seed_new_file))) |
| 894 | + self.assertTrue(os.path.exists(output(other_file))) |
| 895 | + |
| 896 | def test_process_missing_seeds(self): |
| 897 | # The script ignores series with no seed structures. |
| 898 | - distro = self.makeDistro() |
| 899 | - distroseries_one = self.factory.makeDistroSeries(distribution=distro) |
| 900 | - distroseries_two = self.factory.makeDistroSeries(distribution=distro) |
| 901 | - component = self.factory.makeComponent() |
| 902 | - self.factory.makeComponentSelection( |
| 903 | - distroseries=distroseries_one, component=component) |
| 904 | - self.factory.makeComponentSelection( |
| 905 | - distroseries=distroseries_two, component=component) |
| 906 | - self.factory.makeDistroArchSeries(distroseries=distroseries_one) |
| 907 | - self.factory.makeDistroArchSeries(distroseries=distroseries_two) |
| 908 | flavour = self.factory.getUniqueString() |
| 909 | - script = self.makeScript(distro, extra_args=[flavour]) |
| 910 | - self.makeIndexFiles(script, distroseries_two) |
| 911 | + self.setUpDistroAndScript( |
| 912 | + ["DEVELOPMENT", "DEVELOPMENT"], extra_args=[flavour]) |
| 913 | + self.setUpComponent() |
| 914 | + self.factory.makeDistroArchSeries(distroseries=self.distroseries[0]) |
| 915 | + self.factory.makeDistroArchSeries(distroseries=self.distroseries[1]) |
| 916 | + self.makeIndexFiles(self.script, self.distroseries[1]) |
| 917 | seed = self.factory.getUniqueString() |
| 918 | - self.makeSeedStructure(flavour, distroseries_two.name, [seed]) |
| 919 | - self.makeSeed(flavour, distroseries_two.name, seed, []) |
| 920 | + self.makeSeedStructure(flavour, self.distroseries[1].name, [seed]) |
| 921 | + self.makeSeed(flavour, self.distroseries[1].name, seed, []) |
| 922 | |
| 923 | - script.process(seed_bases=["file://%s" % self.seeddir]) |
| 924 | + self.script.process(seed_bases=["file://%s" % self.seeddir]) |
| 925 | self.assertFalse(os.path.exists(os.path.join( |
| 926 | - script.config.miscroot, |
| 927 | - "more-extra.override.%s.main" % distroseries_one.name))) |
| 928 | + self.script.config.miscroot, |
| 929 | + "more-extra.override.%s.main" % self.distroseries[0].name))) |
| 930 | self.assertTrue(os.path.exists(os.path.join( |
| 931 | - script.config.miscroot, |
| 932 | - "more-extra.override.%s.main" % distroseries_two.name))) |
| 933 | + self.script.config.miscroot, |
| 934 | + "more-extra.override.%s.main" % self.distroseries[1].name))) |
| 935 | + |
| 936 | + def test_process_removes_only_stale_files(self): |
| 937 | + # The script removes only stale germinate output files. |
| 938 | + flavour = self.factory.getUniqueString() |
| 939 | + self.setUpDistroAndScript(extra_args=[flavour]) |
| 940 | + series_name = self.distroseries[0].name |
| 941 | + self.setUpComponent() |
| 942 | + das = self.factory.makeDistroArchSeries( |
| 943 | + distroseries=self.distroseries[0]) |
| 944 | + arch = das.architecturetag |
| 945 | + self.makeIndexFiles(self.script, self.distroseries[0]) |
| 946 | + |
| 947 | + seed_old = self.factory.getUniqueString() |
| 948 | + seed_new = self.factory.getUniqueString() |
| 949 | + self.makeSeedStructure(flavour, series_name, [seed_old]) |
| 950 | + self.makeSeed(flavour, series_name, seed_old, []) |
| 951 | + self.script.process(seed_bases=["file://%s" % self.seeddir]) |
| 952 | + output = partial( |
| 953 | + self.script.composeOutputPath, flavour, series_name, arch) |
| 954 | + self.assertTrue(os.path.exists(output(seed_old))) |
| 955 | + self.makeSeedStructure(flavour, series_name, [seed_new]) |
| 956 | + self.makeSeed(flavour, series_name, seed_new, []) |
| 957 | + self.script.process(seed_bases=["file://%s" % self.seeddir]) |
| 958 | + self.assertTrue(os.path.exists(os.path.join(self.script.log_file))) |
| 959 | + self.assertTrue(os.path.exists(output("structure"))) |
| 960 | + self.assertTrue(os.path.exists(output("all"))) |
| 961 | + self.assertTrue(os.path.exists(output("all.sources"))) |
| 962 | + self.assertTrue(os.path.exists(output(seed_new))) |
| 963 | + self.assertFalse(os.path.exists(output(seed_old))) |
| 964 | |
| 965 | def test_main(self): |
| 966 | # If run end-to-end, the script generates override files containing |
| 967 | # output for all architectures, and sends germinate's log output to |
| 968 | # a file. |
| 969 | - distro = self.makeDistro() |
| 970 | - distroseries = self.factory.makeDistroSeries(distribution=distro) |
| 971 | - series_name = distroseries.name |
| 972 | - component = self.factory.makeComponent() |
| 973 | - self.factory.makeComponentSelection( |
| 974 | - distroseries=distroseries, component=component) |
| 975 | - das_one = self.factory.makeDistroArchSeries(distroseries=distroseries) |
| 976 | - arch_one = das_one.architecturetag |
| 977 | - das_two = self.factory.makeDistroArchSeries(distroseries=distroseries) |
| 978 | - arch_two = das_two.architecturetag |
| 979 | + flavour = self.factory.getUniqueString() |
| 980 | + self.setUpDistroAndScript(extra_args=[flavour]) |
| 981 | + series_name = self.distroseries[0].name |
| 982 | + component = self.setUpComponent() |
| 983 | + das_one = self.factory.makeDistroArchSeries( |
| 984 | + distroseries=self.distroseries[0]) |
| 985 | + das_two = self.factory.makeDistroArchSeries( |
| 986 | + distroseries=self.distroseries[0]) |
| 987 | package = self.makePackage(component, [das_one, das_two]) |
| 988 | - flavour = self.factory.getUniqueString() |
| 989 | - script = self.makeScript(distro, extra_args=[flavour]) |
| 990 | - self.makeIndexFiles(script, distroseries) |
| 991 | + self.makeIndexFiles(self.script, self.distroseries[0]) |
| 992 | |
| 993 | seed = self.factory.getUniqueString() |
| 994 | self.makeSeedStructure(flavour, series_name, [seed]) |
| 995 | @@ -634,19 +639,19 @@ |
| 996 | flavour, series_name, seed, [package.name], |
| 997 | headers=["Task-Description: task"]) |
| 998 | |
| 999 | - script.process(seed_bases=["file://%s" % self.seeddir]) |
| 1000 | + self.script.process(seed_bases=["file://%s" % self.seeddir]) |
| 1001 | override_path = os.path.join( |
| 1002 | - script.config.miscroot, |
| 1003 | + self.script.config.miscroot, |
| 1004 | "more-extra.override.%s.main" % series_name) |
| 1005 | expected_overrides = [ |
| 1006 | - "%s/%s Task %s" % (package.name, arch_one, seed), |
| 1007 | - "%s/%s Task %s" % (package.name, arch_two, seed), |
| 1008 | + "%s/%s Task %s" % (package.name, das_one.architecturetag, seed), |
| 1009 | + "%s/%s Task %s" % (package.name, das_two.architecturetag, seed), |
| 1010 | ] |
| 1011 | self.assertContentEqual( |
| 1012 | expected_overrides, file_contents(override_path).splitlines()) |
| 1013 | |
| 1014 | log_file = os.path.join( |
| 1015 | - script.config.germinateroot, "germinate.output") |
| 1016 | + self.script.config.germinateroot, "germinate.output") |
| 1017 | self.assertIn("Downloading file://", file_contents(log_file)) |
| 1018 | |
| 1019 | def test_run_script(self): |

Looks good.
The with/pass in test_generate_ extra_overrides .py (line 877 of the diff)
confused me for a second. I wonder if an old-fashioned open().close()
wouldn't be easier to understand at first blush. Or maybe even a
"touch" helper function.