Merge lp:~julian-edwards/launchpad/ppa-expire-sources into lp:launchpad
- ppa-expire-sources
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Brad Crittenden |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~julian-edwards/launchpad/ppa-expire-sources |
Merge into: | lp:launchpad |
Diff against target: |
316 lines (+131/-36) 4 files modified
cronscripts/expire-ppa-files.py (+1/-1) database/schema/security.cfg (+3/-0) lib/lp/soyuz/scripts/expire_ppa_binaries.py (+57/-2) lib/lp/soyuz/scripts/tests/test_expire_ppa_bins.py (+70/-33) |
To merge this branch: | bzr merge lp:~julian-edwards/launchpad/ppa-expire-sources |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brad Crittenden (community) | code | Approve | |
Review via email: mp+17669@code.launchpad.net |
Commit message
Description of the change
Julian Edwards (julian-edwards) wrote : | # |
Brad Crittenden (bac) wrote : | # |
Hi Julian,
The branch looks good. You mentioned renaming the file but deferred due to time constraints. Seems like it would take 10 seconds so you might as well do it now. expire_
As far as refactoring the SQL it looks like you could use common aliases and then many of your comparisons would be the same, leaving you to just customize the WHERE clauses. Would that help? Or, if it was Storm-i-fied you may find it easier to refactor. Just two lame suggestions.
Otherwise your change looks very well done. Thanks.
Julian Edwards (julian-edwards) wrote : | # |
On Tuesday 19 January 2010 19:30:24 Brad Crittenden wrote:
> Review: Approve code
> Hi Julian,
>
> The branch looks good. You mentioned renaming the file but deferred due to
> time constraints. Seems like it would take 10 seconds so you might as
> well do it now. expire_
I would have done that if it were not for the fact that the losas also need to
change their crontabs, which makes it a >10 second job :) But still, we'll
take the hit and do it. Thanks for prodding me.
> As far as refactoring the SQL it looks like you could use common aliases
> and then many of your comparisons would be the same, leaving you to just
> customize the WHERE clauses. Would that help?
I tried. It was really unreadable and the refactoring didn't help reduce the
size of the code that much.
> Or, if it was Storm-i-fied
> you may find it easier to refactor. Just two lame suggestions.
I'd love to do that but it's quite hard, STORM doesn't have the EXCEPT
command.
> Otherwise your change looks very well done. Thanks.
Thanks, I'll land this soon!
Preview Diff
1 | === renamed file 'cronscripts/expire-ppa-binaries.py' => 'cronscripts/expire-ppa-files.py' | |||
2 | --- cronscripts/expire-ppa-binaries.py 2009-10-13 14:38:07 +0000 | |||
3 | +++ cronscripts/expire-ppa-files.py 2010-01-20 10:35:29 +0000 | |||
4 | @@ -17,6 +17,6 @@ | |||
5 | 17 | 17 | ||
6 | 18 | if __name__ == '__main__': | 18 | if __name__ == '__main__': |
7 | 19 | script = PPABinaryExpirer( | 19 | script = PPABinaryExpirer( |
9 | 20 | 'expire-ppa-binaries', dbuser=config.binaryfile_expire.dbuser) | 20 | 'expire-ppa-files', dbuser=config.binaryfile_expire.dbuser) |
10 | 21 | script.lock_and_run() | 21 | script.lock_and_run() |
11 | 22 | 22 | ||
12 | 23 | 23 | ||
13 | === modified file 'database/schema/security.cfg' | |||
14 | --- database/schema/security.cfg 2010-01-06 09:06:56 +0000 | |||
15 | +++ database/schema/security.cfg 2010-01-20 10:35:29 +0000 | |||
16 | @@ -1612,6 +1612,9 @@ | |||
17 | 1612 | public.person = SELECT | 1612 | public.person = SELECT |
18 | 1613 | public.libraryfilealias = SELECT, UPDATE | 1613 | public.libraryfilealias = SELECT, UPDATE |
19 | 1614 | public.securebinarypackagepublishinghistory = SELECT | 1614 | public.securebinarypackagepublishinghistory = SELECT |
20 | 1615 | public.sourcepackagereleasefile = SELECT | ||
21 | 1616 | public.sourcepackagepublishinghistory = SELECT | ||
22 | 1617 | public.sourcepackagerelease = SELECT | ||
23 | 1615 | 1618 | ||
24 | 1616 | [create-merge-proposals] | 1619 | [create-merge-proposals] |
25 | 1617 | type=user | 1620 | type=user |
26 | 1618 | 1621 | ||
27 | === modified file 'lib/lp/soyuz/scripts/expire_ppa_binaries.py' | |||
28 | --- lib/lp/soyuz/scripts/expire_ppa_binaries.py 2009-12-11 14:35:28 +0000 | |||
29 | +++ lib/lp/soyuz/scripts/expire_ppa_binaries.py 2010-01-20 10:35:29 +0000 | |||
30 | @@ -54,7 +54,61 @@ | |||
31 | 54 | help=("The number of days after which to expire binaries. " | 54 | help=("The number of days after which to expire binaries. " |
32 | 55 | "Must be specified.")) | 55 | "Must be specified.")) |
33 | 56 | 56 | ||
35 | 57 | def determineExpirables(self, num_days): | 57 | def determineSourceExpirables(self, num_days): |
36 | 58 | """Return expirable libraryfilealias IDs.""" | ||
37 | 59 | # Avoid circular imports. | ||
38 | 60 | from lp.soyuz.interfaces.archive import ArchivePurpose | ||
39 | 61 | |||
40 | 62 | stay_of_execution = '%d days' % num_days | ||
41 | 63 | |||
42 | 64 | # The subquery here has to repeat the checks for privacy and | ||
43 | 65 | # blacklisting on *other* publications that are also done in | ||
44 | 66 | # the main loop for the archive being considered. | ||
45 | 67 | results = self.store.execute(""" | ||
46 | 68 | SELECT lfa.id | ||
47 | 69 | FROM | ||
48 | 70 | LibraryFileAlias AS lfa, | ||
49 | 71 | Archive, | ||
50 | 72 | SourcePackageReleaseFile AS sprf, | ||
51 | 73 | SourcePackageRelease AS spr, | ||
52 | 74 | SourcePackagePublishingHistory AS spph | ||
53 | 75 | WHERE | ||
54 | 76 | lfa.id = sprf.libraryfile | ||
55 | 77 | AND spr.id = sprf.sourcepackagerelease | ||
56 | 78 | AND spph.sourcepackagerelease = spr.id | ||
57 | 79 | AND spph.dateremoved < ( | ||
58 | 80 | CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - interval %s) | ||
59 | 81 | AND spph.archive = archive.id | ||
60 | 82 | AND archive.purpose = %s | ||
61 | 83 | AND lfa.expires IS NULL | ||
62 | 84 | EXCEPT | ||
63 | 85 | SELECT sprf.libraryfile | ||
64 | 86 | FROM | ||
65 | 87 | SourcePackageRelease AS spr, | ||
66 | 88 | SourcePackageReleaseFile AS sprf, | ||
67 | 89 | SourcePackagePublishingHistory AS spph, | ||
68 | 90 | Archive AS a, | ||
69 | 91 | Person AS p | ||
70 | 92 | WHERE | ||
71 | 93 | spr.id = sprf.sourcepackagerelease | ||
72 | 94 | AND spph.sourcepackagerelease = spr.id | ||
73 | 95 | AND spph.archive = a.id | ||
74 | 96 | AND p.id = a.owner | ||
75 | 97 | AND ( | ||
76 | 98 | p.name IN %s | ||
77 | 99 | OR a.private IS TRUE | ||
78 | 100 | OR a.purpose != %s | ||
79 | 101 | OR dateremoved > | ||
80 | 102 | CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - interval %s | ||
81 | 103 | OR dateremoved IS NULL); | ||
82 | 104 | """ % sqlvalues( | ||
83 | 105 | stay_of_execution, ArchivePurpose.PPA, self.blacklist, | ||
84 | 106 | ArchivePurpose.PPA, stay_of_execution)) | ||
85 | 107 | |||
86 | 108 | lfa_ids = results.get_all() | ||
87 | 109 | return lfa_ids | ||
88 | 110 | |||
89 | 111 | def determineBinaryExpirables(self, num_days): | ||
90 | 58 | """Return expirable libraryfilealias IDs.""" | 112 | """Return expirable libraryfilealias IDs.""" |
91 | 59 | # Avoid circular imports. | 113 | # Avoid circular imports. |
92 | 60 | from lp.soyuz.interfaces.archive import ArchivePurpose | 114 | from lp.soyuz.interfaces.archive import ArchivePurpose |
93 | @@ -116,7 +170,8 @@ | |||
94 | 116 | self.store = getUtility(IStoreSelector).get( | 170 | self.store = getUtility(IStoreSelector).get( |
95 | 117 | MAIN_STORE, DEFAULT_FLAVOR) | 171 | MAIN_STORE, DEFAULT_FLAVOR) |
96 | 118 | 172 | ||
98 | 119 | lfa_ids = self.determineExpirables(num_days) | 173 | lfa_ids = self.determineSourceExpirables(num_days) |
99 | 174 | lfa_ids.extend(self.determineBinaryExpirables(num_days)) | ||
100 | 120 | batch_count = 0 | 175 | batch_count = 0 |
101 | 121 | batch_limit = 500 | 176 | batch_limit = 500 |
102 | 122 | for id in lfa_ids: | 177 | for id in lfa_ids: |
103 | 123 | 178 | ||
104 | === modified file 'lib/lp/soyuz/scripts/tests/test_expire_ppa_bins.py' | |||
105 | --- lib/lp/soyuz/scripts/tests/test_expire_ppa_bins.py 2009-12-11 14:35:28 +0000 | |||
106 | +++ lib/lp/soyuz/scripts/tests/test_expire_ppa_bins.py 2010-01-20 10:35:29 +0000 | |||
107 | @@ -74,54 +74,76 @@ | |||
108 | 74 | self.layer.switchDbUser(self.dbuser) | 74 | self.layer.switchDbUser(self.dbuser) |
109 | 75 | script.main() | 75 | script.main() |
110 | 76 | 76 | ||
120 | 77 | def assertExpired(self, publication): | 77 | def assertBinaryExpired(self, publication): |
121 | 78 | self.assertNotEqual( | 78 | self.assertNotEqual( |
122 | 79 | publication.binarypackagerelease.files[0].libraryfile.expires, | 79 | publication.binarypackagerelease.files[0].libraryfile.expires, |
123 | 80 | None, | 80 | None, |
124 | 81 | "lfa.expires should be set, but it's not.") | 81 | "lfa.expires should be set, but it's not.") |
125 | 82 | 82 | ||
126 | 83 | def assertNotExpired(self, publication): | 83 | def assertBinaryNotExpired(self, publication): |
127 | 84 | self.assertEqual( | 84 | self.assertEqual( |
128 | 85 | publication.binarypackagerelease.files[0].libraryfile.expires, | 85 | publication.binarypackagerelease.files[0].libraryfile.expires, |
129 | 86 | None, | ||
130 | 87 | "lfa.expires should be None, but it's not.") | ||
131 | 88 | |||
132 | 89 | def assertSourceExpired(self, publication): | ||
133 | 90 | self.assertNotEqual( | ||
134 | 91 | publication.sourcepackagerelease.files[0].libraryfile.expires, | ||
135 | 92 | None, | ||
136 | 93 | "lfa.expires should be set, but it's not.") | ||
137 | 94 | |||
138 | 95 | def assertSourceNotExpired(self, publication): | ||
139 | 96 | self.assertEqual( | ||
140 | 97 | publication.sourcepackagerelease.files[0].libraryfile.expires, | ||
141 | 86 | None, | 98 | None, |
142 | 87 | "lfa.expires should be None, but it's not.") | 99 | "lfa.expires should be None, but it's not.") |
143 | 88 | 100 | ||
144 | 89 | def testNoExpirationWithNoDateremoved(self): | 101 | def testNoExpirationWithNoDateremoved(self): |
145 | 90 | """Test that no expiring happens if no dateremoved set.""" | 102 | """Test that no expiring happens if no dateremoved set.""" |
146 | 91 | pkg1 = self.stp.getPubSource( | 103 | pkg1 = self.stp.getPubSource( |
148 | 92 | sourcename="pkg1", architecturehintlist="i386", archive=self.ppa) | 104 | sourcename="pkg1", architecturehintlist="i386", archive=self.ppa, |
149 | 105 | dateremoved=None) | ||
150 | 93 | [pub] = self.stp.getPubBinaries( | 106 | [pub] = self.stp.getPubBinaries( |
151 | 94 | pub_source=pkg1, dateremoved=None, archive=self.ppa) | 107 | pub_source=pkg1, dateremoved=None, archive=self.ppa) |
152 | 95 | 108 | ||
153 | 96 | self.runScript() | 109 | self.runScript() |
155 | 97 | self.assertNotExpired(pub) | 110 | self.assertSourceNotExpired(pkg1) |
156 | 111 | self.assertBinaryNotExpired(pub) | ||
157 | 98 | 112 | ||
158 | 99 | def testNoExpirationWithDateUnderThreshold(self): | 113 | def testNoExpirationWithDateUnderThreshold(self): |
159 | 100 | """Test no expiring if dateremoved too recent.""" | 114 | """Test no expiring if dateremoved too recent.""" |
160 | 101 | pkg2 = self.stp.getPubSource( | 115 | pkg2 = self.stp.getPubSource( |
162 | 102 | sourcename="pkg2", architecturehintlist="i386", archive=self.ppa) | 116 | sourcename="pkg2", architecturehintlist="i386", archive=self.ppa, |
163 | 117 | dateremoved=self.under_threshold_date) | ||
164 | 103 | [pub] = self.stp.getPubBinaries( | 118 | [pub] = self.stp.getPubBinaries( |
165 | 104 | pub_source=pkg2, dateremoved=self.under_threshold_date, | 119 | pub_source=pkg2, dateremoved=self.under_threshold_date, |
166 | 105 | archive=self.ppa) | 120 | archive=self.ppa) |
167 | 106 | 121 | ||
168 | 107 | self.runScript() | 122 | self.runScript() |
170 | 108 | self.assertNotExpired(pub) | 123 | self.assertSourceNotExpired(pkg2) |
171 | 124 | self.assertBinaryNotExpired(pub) | ||
172 | 109 | 125 | ||
173 | 110 | def testExpirationWithDateOverThreshold(self): | 126 | def testExpirationWithDateOverThreshold(self): |
174 | 111 | """Test expiring works if dateremoved old enough.""" | 127 | """Test expiring works if dateremoved old enough.""" |
175 | 112 | pkg3 = self.stp.getPubSource( | 128 | pkg3 = self.stp.getPubSource( |
177 | 113 | sourcename="pkg3", architecturehintlist="i386", archive=self.ppa) | 129 | sourcename="pkg3", architecturehintlist="i386", archive=self.ppa, |
178 | 130 | dateremoved=self.over_threshold_date) | ||
179 | 114 | [pub] = self.stp.getPubBinaries( | 131 | [pub] = self.stp.getPubBinaries( |
180 | 115 | pub_source=pkg3, dateremoved=self.over_threshold_date, | 132 | pub_source=pkg3, dateremoved=self.over_threshold_date, |
181 | 116 | archive=self.ppa) | 133 | archive=self.ppa) |
182 | 117 | 134 | ||
183 | 118 | self.runScript() | 135 | self.runScript() |
185 | 119 | self.assertExpired(pub) | 136 | self.assertSourceExpired(pkg3) |
186 | 137 | self.assertBinaryExpired(pub) | ||
187 | 120 | 138 | ||
188 | 121 | def testNoExpirationWithDateOverThresholdAndOtherValidPublication(self): | 139 | def testNoExpirationWithDateOverThresholdAndOtherValidPublication(self): |
189 | 122 | """Test no expiry if dateremoved old enough but other publication.""" | 140 | """Test no expiry if dateremoved old enough but other publication.""" |
190 | 123 | pkg4 = self.stp.getPubSource( | 141 | pkg4 = self.stp.getPubSource( |
192 | 124 | sourcename="pkg4", architecturehintlist="i386", archive=self.ppa) | 142 | sourcename="pkg4", architecturehintlist="i386", archive=self.ppa, |
193 | 143 | dateremoved=self.over_threshold_date) | ||
194 | 144 | other_source = pkg4.copyTo( | ||
195 | 145 | pkg4.distroseries, pkg4.pocket, self.ppa2) | ||
196 | 146 | other_source.secure_record.dateremoved = None | ||
197 | 125 | [pub] = self.stp.getPubBinaries( | 147 | [pub] = self.stp.getPubBinaries( |
198 | 126 | pub_source=pkg4, dateremoved=self.over_threshold_date, | 148 | pub_source=pkg4, dateremoved=self.over_threshold_date, |
199 | 127 | archive=self.ppa) | 149 | archive=self.ppa) |
200 | @@ -130,16 +152,21 @@ | |||
201 | 130 | other_binary.secure_record.dateremoved = None | 152 | other_binary.secure_record.dateremoved = None |
202 | 131 | 153 | ||
203 | 132 | self.runScript() | 154 | self.runScript() |
205 | 133 | self.assertNotExpired(pub) | 155 | self.assertSourceNotExpired(pkg4) |
206 | 156 | self.assertBinaryNotExpired(pub) | ||
207 | 134 | 157 | ||
208 | 135 | def testNoExpirationWithDateOverThresholdAndOtherPubUnderThreshold(self): | 158 | def testNoExpirationWithDateOverThresholdAndOtherPubUnderThreshold(self): |
209 | 136 | """Test no expiring. | 159 | """Test no expiring. |
211 | 137 | 160 | ||
212 | 138 | Test no expiring if dateremoved old enough but other publication | 161 | Test no expiring if dateremoved old enough but other publication |
213 | 139 | not over date threshold. | 162 | not over date threshold. |
214 | 140 | """ | 163 | """ |
215 | 141 | pkg5 = self.stp.getPubSource( | 164 | pkg5 = self.stp.getPubSource( |
217 | 142 | sourcename="pkg5", architecturehintlist="i386", archive=self.ppa) | 165 | sourcename="pkg5", architecturehintlist="i386", archive=self.ppa, |
218 | 166 | dateremoved=self.over_threshold_date) | ||
219 | 167 | other_source = pkg5.copyTo( | ||
220 | 168 | pkg5.distroseries, pkg5.pocket, self.ppa2) | ||
221 | 169 | other_source.secure_record.dateremoved = self.under_threshold_date | ||
222 | 143 | [pub] = self.stp.getPubBinaries( | 170 | [pub] = self.stp.getPubBinaries( |
223 | 144 | pub_source=pkg5, dateremoved=self.over_threshold_date, | 171 | pub_source=pkg5, dateremoved=self.over_threshold_date, |
224 | 145 | archive=self.ppa) | 172 | archive=self.ppa) |
225 | @@ -148,67 +175,77 @@ | |||
226 | 148 | other_binary.secure_record.dateremoved = self.under_threshold_date | 175 | other_binary.secure_record.dateremoved = self.under_threshold_date |
227 | 149 | 176 | ||
228 | 150 | self.runScript() | 177 | self.runScript() |
230 | 151 | self.assertNotExpired(pub) | 178 | self.assertSourceNotExpired(pkg5) |
231 | 179 | self.assertBinaryNotExpired(pub) | ||
232 | 152 | 180 | ||
233 | 153 | def _setUpExpirablePublications(self, archive=None): | 181 | def _setUpExpirablePublications(self, archive=None): |
234 | 154 | """Helper to set up two publications that are both expirable.""" | 182 | """Helper to set up two publications that are both expirable.""" |
235 | 155 | if archive is None: | 183 | if archive is None: |
236 | 156 | archive = self.ppa | 184 | archive = self.ppa |
237 | 157 | pkg5 = self.stp.getPubSource( | 185 | pkg5 = self.stp.getPubSource( |
239 | 158 | sourcename="pkg5", architecturehintlist="i386", archive=archive) | 186 | sourcename="pkg5", architecturehintlist="i386", archive=archive, |
240 | 187 | dateremoved=self.over_threshold_date) | ||
241 | 188 | other_source = pkg5.copyTo( | ||
242 | 189 | pkg5.distroseries, pkg5.pocket, self.ppa2) | ||
243 | 190 | other_source.secure_record.dateremoved = self.over_threshold_date | ||
244 | 159 | [pub] = self.stp.getPubBinaries( | 191 | [pub] = self.stp.getPubBinaries( |
245 | 160 | pub_source=pkg5, dateremoved=self.over_threshold_date, | 192 | pub_source=pkg5, dateremoved=self.over_threshold_date, |
246 | 161 | archive=archive) | 193 | archive=archive) |
247 | 162 | [other_binary] = pub.copyTo( | 194 | [other_binary] = pub.copyTo( |
248 | 163 | pub.distroarchseries.distroseries, pub.pocket, self.ppa2) | 195 | pub.distroarchseries.distroseries, pub.pocket, self.ppa2) |
249 | 164 | other_binary.secure_record.dateremoved = self.over_threshold_date | 196 | other_binary.secure_record.dateremoved = self.over_threshold_date |
251 | 165 | return pub | 197 | return pkg5, pub |
252 | 166 | 198 | ||
253 | 167 | def testNoExpirationWithDateOverThresholdAndOtherPubOverThreshold(self): | 199 | def testNoExpirationWithDateOverThresholdAndOtherPubOverThreshold(self): |
254 | 168 | """Test expiring works. | 200 | """Test expiring works. |
256 | 169 | 201 | ||
257 | 170 | Test expiring works if dateremoved old enough and other publication | 202 | Test expiring works if dateremoved old enough and other publication |
258 | 171 | is over date threshold. | 203 | is over date threshold. |
259 | 172 | """ | 204 | """ |
261 | 173 | pub = self._setUpExpirablePublications() | 205 | source, binary = self._setUpExpirablePublications() |
262 | 174 | self.runScript() | 206 | self.runScript() |
264 | 175 | self.assertExpired(pub) | 207 | self.assertSourceExpired(source) |
265 | 208 | self.assertBinaryExpired(binary) | ||
266 | 176 | 209 | ||
267 | 177 | def testBlacklistingWorks(self): | 210 | def testBlacklistingWorks(self): |
268 | 178 | """Test that blacklisted PPAs are not expired.""" | 211 | """Test that blacklisted PPAs are not expired.""" |
270 | 179 | pub = self._setUpExpirablePublications() | 212 | source, binary = self._setUpExpirablePublications() |
271 | 180 | script = self.getScript() | 213 | script = self.getScript() |
272 | 181 | script.blacklist = ["cprov",] | 214 | script.blacklist = ["cprov",] |
273 | 182 | self.layer.txn.commit() | 215 | self.layer.txn.commit() |
274 | 183 | self.layer.switchDbUser(self.dbuser) | 216 | self.layer.switchDbUser(self.dbuser) |
275 | 184 | script.main() | 217 | script.main() |
277 | 185 | self.assertNotExpired(pub) | 218 | self.assertSourceNotExpired(source) |
278 | 219 | self.assertBinaryNotExpired(binary) | ||
279 | 186 | 220 | ||
280 | 187 | def testPrivatePPAsNotExpired(self): | 221 | def testPrivatePPAsNotExpired(self): |
281 | 188 | """Test that private PPAs are not expired.""" | 222 | """Test that private PPAs are not expired.""" |
282 | 189 | self.ppa.private = True | 223 | self.ppa.private = True |
283 | 190 | self.ppa.buildd_secret = "foo" | 224 | self.ppa.buildd_secret = "foo" |
285 | 191 | pub = self._setUpExpirablePublications() | 225 | source, binary = self._setUpExpirablePublications() |
286 | 192 | self.runScript() | 226 | self.runScript() |
288 | 193 | self.assertNotExpired(pub) | 227 | self.assertSourceNotExpired(source) |
289 | 228 | self.assertBinaryNotExpired(binary) | ||
290 | 194 | 229 | ||
291 | 195 | def testDryRun(self): | 230 | def testDryRun(self): |
292 | 196 | """Test that when dryrun is specified, nothing is expired.""" | 231 | """Test that when dryrun is specified, nothing is expired.""" |
294 | 197 | pub = self._setUpExpirablePublications() | 232 | source, binary = self._setUpExpirablePublications() |
295 | 198 | # We have to commit here otherwise when the script aborts it | 233 | # We have to commit here otherwise when the script aborts it |
296 | 199 | # will remove the test publications we just created. | 234 | # will remove the test publications we just created. |
297 | 200 | self.layer.txn.commit() | 235 | self.layer.txn.commit() |
298 | 201 | script = self.getScript(['--dry-run']) | 236 | script = self.getScript(['--dry-run']) |
299 | 202 | self.layer.switchDbUser(self.dbuser) | 237 | self.layer.switchDbUser(self.dbuser) |
300 | 203 | script.main() | 238 | script.main() |
302 | 204 | self.assertNotExpired(pub) | 239 | self.assertSourceNotExpired(source) |
303 | 240 | self.assertBinaryNotExpired(binary) | ||
304 | 205 | 241 | ||
305 | 206 | def testDoesNotAffectNonPPA(self): | 242 | def testDoesNotAffectNonPPA(self): |
306 | 207 | """Test that expiry does not happen for non-PPA publications.""" | 243 | """Test that expiry does not happen for non-PPA publications.""" |
307 | 208 | ubuntu_archive = getUtility(IDistributionSet)['ubuntu'].main_archive | 244 | ubuntu_archive = getUtility(IDistributionSet)['ubuntu'].main_archive |
309 | 209 | pub = self._setUpExpirablePublications(ubuntu_archive) | 245 | source, binary = self._setUpExpirablePublications(ubuntu_archive) |
310 | 210 | self.runScript() | 246 | self.runScript() |
312 | 211 | self.assertNotExpired(pub) | 247 | self.assertSourceNotExpired(source) |
313 | 248 | self.assertBinaryNotExpired(binary) | ||
314 | 212 | 249 | ||
315 | 213 | 250 | ||
316 | 214 | def test_suite(): | 251 | def test_suite(): |
= Summary =
Expire superseded PPA source files
== Proposed fix ==
This change extends the existing script that expires PPA binaries so that it
expires sources as well.
== Pre-implementation notes ==
None, I suck. Besides, it's trivial.
== Implementation details ==
Fairly straightforward extension of the existing script so that it injects
librarian IDs for sources into the loop that was deleting just the binaries.
My only question to you, my reviewer, is to ask if you can come up with a
decent refactoring of the two nearly identical SQL strings. I tried a bunch
of things but only succeeded in making it totally unreadable.
Finally, the script name is now slightly bogus, but that can be fixed some
other time. The LOSAs are desperate for more librarian space.
== Tests == ppa_bins
bin/test -vvct test_expire_
== Demo and Q/A ==
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: schema/ security. cfg soyuz/scripts/ tests/test_ expire_ ppa_bins. py soyuz/scripts/ expire_ ppa_binaries. py
database/
lib/lp/
lib/lp/