Merge lp:~mabac/svammel/get-success-logs into lp:svammel

Proposed by Mattias Backman
Status: Merged
Approved by: James Westby
Approved revision: 83
Merged at revision: 84
Proposed branch: lp:~mabac/svammel/get-success-logs
Merge into: lp:svammel
Prerequisite: lp:~mabac/svammel/add-version-check-and-tests
Diff against target: 701 lines (+428/-106)
5 files modified
config.py (+3/-0)
data_parsing.py (+78/-11)
file-failures.py (+14/-13)
tests/test_bug_logging.py (+1/-1)
tests/test_fail_filer.py (+332/-81)
To merge this branch: bzr merge lp:~mabac/svammel/get-success-logs
Reviewer Review Type Date Requested Status
James Westby (community) Approve
Review via email: mp+53643@code.launchpad.net

Description of the change

Hi,

This branch adds cross referencing successful builds before filing bugs. The action is added to filter_spph which did get quite messy. :/

Well, what it does for each package not already rejected is to iterate over all archives and ask for successful builds. We then get the successful build of the most recent package version and compare that to the version of the failed build.

If there are any successful builds in any archive the only way the failed build survives is if it is of a higher version than any of the successful builds. My reasoning is that if the fail is of the most recent version, it should be reported. And if there is any successful build for a more recent package there is nothing to report.

The interesting case is when we find a successful build of the same version of the package that we have already found a failure for. I think that this would mean that there isn't a porting issue then since the version can be built on armel so no bug will be filed.

Thanks,

Mattias

To post a comment you must log in.
lp:~mabac/svammel/get-success-logs updated
74. By Mattias Backman

Merge changes from add-version-and-tests.

75. By Mattias Backman

Docstring indentation and whitespace fix.

76. By Mattias Backman

Add basic filtering tests.

77. By Mattias Backman

Break long lines and add get_build_list tests.

78. By Mattias Backman

Add more filtering tests.

79. By Mattias Backman

remove double import.

Revision history for this message
James Westby (james-w) wrote :

9 + help='Disable bug filing. Combine with -v to enable useful output.')

Should -v just be implied?

61 + if spph_queue is None:
62 + raise NoVersionError("None supplied as list.")

I tend to not code defensively in cases like this. The developer
will get an error that is almost as obvious when it tries to iterate the
list, so I lean towards brevity. I reserve the checks for when the error
would be obtuse, or the code will do the wrong thing.

That's just my preference though, if you prefer this then leave it as is.

126 + if spph is None:
127 + continue

...

150 + spph = None

Could that just be a "break" where you set spph to None?

This looks good otherwise.

Thanks,

James

review: Approve
lp:~mabac/svammel/get-success-logs updated
80. By Mattias Backman

Make --dryrun enable -v output.

81. By Mattias Backman

Do not raise error for null queue.

82. By Mattias Backman

Improve test.

Revision history for this message
Mattias Backman (mabac) wrote :

> 9 + help='Disable bug filing. Combine with -v to enable useful
> output.')
>
> Should -v just be implied?

Yeah, that's a good idea. Fixed.

>
> 61 + if spph_queue is None:
> 62 + raise NoVersionError("None supplied as list.")
>
> I tend to not code defensively in cases like this. The developer
> will get an error that is almost as obvious when it tries to iterate the
> list, so I lean towards brevity. I reserve the checks for when the error
> would be obtuse, or the code will do the wrong thing.
>
> That's just my preference though, if you prefer this then leave it as is.

Mostly this is about fear of Coverity Prevent which flags any remotely theoretical possibility of an unchecked null pointer as a defect. I can probably take it more easy with this in svammel and get cleaner code. :)

>
> 126 + if spph is None:
> 127 + continue
>
> ...
>
> 150 + spph = None
>
> Could that just be a "break" where you set spph to None?

Yes, that's true.

lp:~mabac/svammel/get-success-logs updated
83. By Mattias Backman

Remove unused Error.

84. By Mattias Backman

Merged changes from add-version-check-and-tests.

85. By Mattias Backman

Merge changes from trunk.

86. By Mattias Backman

Merge James' fix for not shadowing logging.

87. By Mattias Backman

Fix build_build_record defect.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== renamed file 'logging.py' => 'bug_logging.py'
2=== modified file 'config.py'
3--- config.py 2011-03-22 10:17:01 +0000
4+++ config.py 2011-03-30 07:39:33 +0000
5@@ -104,6 +104,9 @@
6 '-v', '--verbose', action='store_true', dest='verbose',
7 help='Enable verbose messages.')
8 parser.add_argument(
9+ '--dryrun', action='store_true', dest='dryrun',
10+ help='Disable bug filing and enable verbose messages.')
11+ parser.add_argument(
12 '--serviceroot', default='production',
13 choices=['production', 'staging', 'qastaging'],
14 help='The Launchpad environment to connect to.')
15
16=== modified file 'data_parsing.py'
17--- data_parsing.py 2011-03-30 07:39:33 +0000
18+++ data_parsing.py 2011-03-30 07:39:33 +0000
19@@ -85,14 +85,48 @@
20 self.version) < 0)
21
22
23+def get_build_list(archive, state, source=None):
24+
25+ buildlist = archive.getBuildRecords(build_state=state, source_name=source)
26+
27+ # XXX mabac 2011-03-16: getBuildRecords filters on substrings
28+ # so buildlist probably contains non exact matches.
29+ # https://bugs.launchpad.net/launchpad/+bug/231862
30+ if source is not None:
31+ filter_list = []
32+ for build in buildlist:
33+ csp = build.current_source_publication
34+ if csp is not None and csp.source_package_name == source:
35+ filter_list.append(build)
36+ return filter_list
37+
38+ return buildlist
39+
40+
41+def get_highest_version(spph_queue):
42+ """Returns the spph of the highest version in the list.
43+
44+ If more than one spph with the same version is in the list,
45+ the first of the identical versions in the list is returned.
46+ """
47+ candidate_spph = None
48+ while len(spph_queue) > 0:
49+ new_spph = spph_queue.pop(0)
50+ if new_spph is None:
51+ continue
52+ if new_spph.is_higher_version_than(candidate_spph):
53+ candidate_spph = new_spph
54+
55+ return candidate_spph
56+
57+
58 def fetch_pkg_list(archives):
59 all_spph = dict()
60 for archive, archive_name in archives:
61 print_message("The following packages have failed to build " \
62 "in '%s'." % archive_name)
63
64- buildlist = archive.getBuildRecords(build_state=FAILED_BUILD_STATE)
65-
66+ buildlist = get_build_list(archive, FAILED_BUILD_STATE)
67 for build in buildlist:
68 csp = build.current_source_publication
69 if csp is None:
70@@ -112,13 +146,14 @@
71 return all_spph
72
73
74-def filter_spph(all_spph_list, fail_arch, ok_archs):
75+def filter_spph(all_spph_list, fail_arch, ok_archs, archives):
76 """Filter out the build failures that are unique to the target arch.
77
78 Arguments:
79 all_spph_list -- List of all spphs to investigate.
80 fail_arch -- The arch on which the builds should have failed.
81 ok_archs -- A list of archs on which the builds have not failed.
82+ archives -- A list of archives to cross check for successful builds.
83
84 Returns:
85 A subset of all_spph_list which represents the interesting packages.
86@@ -126,13 +161,45 @@
87 filtered_list = []
88 for spph in all_spph_list.values():
89 if not spph.is_ftbfs(fail_arch):
90- # Drop this spph since it did not fail on target arch.
91- continue
92- if next((arch for arch in ok_archs if spph.is_ftbfs(arch)),
93- None) is not None:
94- # Drop this spph since it did fail on other arch.
95- continue
96- filtered_list.append(spph)
97+ print_message("Ignoring package '%s' version '%s' since it did " \
98+ "not fail on architecture '%s'." % \
99+ (spph.package_name, spph.version, fail_arch))
100+ continue
101+ also_failed = next((arch for arch in ok_archs
102+ if spph.is_ftbfs(arch)), None)
103+ if also_failed is not None:
104+ print_message("Ignoring package '%s' version '%s' since it also " \
105+ "failed to build on architecture '%s'." % \
106+ (spph.package_name, spph.version, also_failed))
107+ continue
108+
109+ for archive, archive_name in archives:
110+ # Get list of successful builds for the same package
111+ success_list = get_build_list(archive, SUCCESS_BUILD_STATE,
112+ spph.package_name)
113+ success_spph_list = []
114+ for success_build in success_list:
115+ success_spph = SPPH(success_build.current_source_publication)
116+ if success_build.arch_tag == fail_arch:
117+ success_spph_list.append(success_spph)
118+
119+ candidate_success_spph = get_highest_version(success_spph_list)
120+ if spph.is_higher_version_than(candidate_success_spph):
121+ # Only care about the failed build if it is of a higher
122+ # version than any successful build of the same package.
123+ pass
124+ else:
125+ print_message("Failed build for package '%s' version '%s' " \
126+ "overridden by successful build of " \
127+ "version '%s' in archive '%s'." % \
128+ (spph.package_name, spph.version,
129+ candidate_success_spph.version,
130+ archive_name))
131+ spph = None
132+ break
133+
134+ if spph is not None:
135+ filtered_list.append(spph)
136
137 return filtered_list
138
139@@ -179,4 +246,4 @@
140 print_message("Will be getting builds from archives " + ", ".join(
141 name for (archive, name) in archives))
142 spph_list = fetch_pkg_list(archives)
143- return filter_spph(spph_list, fail_platform, ok_platforms)
144+ return filter_spph(spph_list, fail_platform, ok_platforms, archives)
145
146=== modified file 'file-failures.py'
147--- file-failures.py 2011-03-30 07:39:33 +0000
148+++ file-failures.py 2011-03-30 07:39:33 +0000
149@@ -13,7 +13,6 @@
150 from data_parsing import (
151 get_tags_for_fail,
152 get_build_status,
153- filter_spph,
154 )
155 from bug_reporting import (
156 file_bug_by_url,
157@@ -30,7 +29,7 @@
158 get_file_contents,
159 get_interesting_part,
160 )
161-from logging import (
162+from bug_logging import (
163 Log,
164 LogEntry,
165 )
166@@ -46,7 +45,7 @@
167
168 parser = get_args_parser()
169 args = parser.parse_args()
170-set_verbose_messages(args.verbose)
171+set_verbose_messages(args.verbose or args.dryrun)
172
173 init(args.serviceroot, 'testing', '~/.launchpadlib/cache/')
174
175@@ -80,7 +79,7 @@
176
177 build_record = spph.get_arch(fail_platform)
178 if build_record is not None:
179- build_build_record = get_file_contents(log.build_log_url)
180+ build_log = get_file_contents(build_record.build_log_url)
181 else:
182 print "%s build record not available for %s version %s." % \
183 (fail_platform, spph.package_name, spph.version)
184@@ -99,12 +98,14 @@
185 """ % (bug_title, build_record.web_link, build_record.build_log_url,
186 interesting_log_part)
187
188- print_message(
189- "Will file bug for %s\n desc: %s\n title: %s\n tags: %s" %
190- (spph.package_name, bug_description[0:220], bug_title, bug_tags))
191- bug = file_bug_by_url(spph.url, bug_description, bug_title,
192- bug_tags, get_launchpad())
193- if bug is not None and args.logfile is not None:
194- bug_log.write_entry(
195- LogEntry(spph.package_name, spph.version, fail_platform,
196- bug.self_link).to_string())
197+ print_message("Will file bug for %s version %s with tags: %s" % \
198+ (spph.package_name, spph.version, bug_tags))
199+ if not args.dryrun:
200+ bug = file_bug_by_url(spph.url, bug_description, bug_title,
201+ bug_tags, get_launchpad())
202+ if bug is not None and args.logfile is not None:
203+ bug_log.write_entry(
204+ LogEntry(spph.package_name, spph.version, fail_platform,
205+ bug.self_link).to_string())
206+ else:
207+ print_message(" ... but didn't since dryrun is specified.")
208
209=== modified file 'tests/test_bug_logging.py'
210--- tests/test_bug_logging.py 2011-03-23 11:12:12 +0000
211+++ tests/test_bug_logging.py 2011-03-30 07:39:33 +0000
212@@ -15,7 +15,7 @@
213 TestCaseWithFixtures,
214 MockSomethingFixture,
215 )
216-from logging import (
217+from bug_logging import (
218 LOG_ITEM_SEPARATOR,
219 Log,
220 LogEntry,
221
222=== modified file 'tests/test_fail_filer.py'
223--- tests/test_fail_filer.py 2011-03-30 07:39:33 +0000
224+++ tests/test_fail_filer.py 2011-03-30 07:39:33 +0000
225@@ -9,8 +9,6 @@
226 # Linaro Infrastructure Team - initial implementation
227 ###############################################################################
228 from testtools import TestCase
229-
230-from testtools import TestCase
231 from datetime import (
232 datetime,
233 )
234@@ -25,13 +23,13 @@
235 SUCCESS_BUILD_STATE,
236 SPPH,
237 get_tags_for_fail,
238+ get_highest_version,
239+ filter_spph,
240+ get_build_list,
241 )
242 from bug_reporting import (
243 bug_already_filed_by_url,
244-# get_project_url,
245-# file_bug,
246 )
247-import config
248 from config import (
249 get_service_root,
250 get_base_url,
251@@ -42,9 +40,14 @@
252 inited,
253 ConfigInitError,
254 LaunchpadError,
255+ set_verbose_messages,
256 )
257
258
259+TEST_FAIL_ARCH = 'armel'
260+TEST_OK_ARCHS = ['i386', 'amd64']
261+
262+
263 class TestBugTags(TestCase):
264
265 def setUp(self):
266@@ -69,6 +72,206 @@
267 msg='Got more than default tags without match.')
268
269
270+class TestFilter(TestCaseWithFixtures):
271+
272+ class MockPackage(object):
273+ def __init__(self, name, version):
274+ self.source_package_version = version
275+ self.source_package_name = name
276+
277+ class MockRecord(object):
278+ class CSP:
279+ def __init__(self, name, version):
280+ self.source_package_name = name
281+ self.source_package_version = version
282+
283+ def __init__(self, arch, datecreated, state=FAILED_BUILD_STATE,
284+ name='packagename', version='1'):
285+ self.arch_tag = arch
286+ self.datecreated = datecreated
287+ self.buildstate = state
288+ self.current_source_publication = self.CSP(name, version)
289+
290+ class MockArchive(object):
291+ def __init__(self, name, records_to_return=[]):
292+ self.name = name
293+ self.records_to_return = records_to_return
294+
295+ def getBuildRecords(self, build_state, source_name):
296+ return self.records_to_return
297+
298+ def setUp(self):
299+ super(TestFilter, self).setUp()
300+
301+ def init_dummy_config(self):
302+ def mock_func(obj, appid, root, cachedir):
303+ return 'this is a launchpad instance'
304+
305+ self.useFixture(MockSomethingFixture(
306+ Launchpad, 'login_with', classmethod(mock_func)))
307+ init('staging', 'dummyapp', 'dummycache')
308+
309+ def test_filter_fail_record_not_filtered(self):
310+ self.init_dummy_config()
311+ spph = SPPH(self.MockPackage('packagefail', '1'))
312+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
313+ FAILED_BUILD_STATE)
314+ spph.add_build_record(failrecord)
315+ spph_list = dict()
316+ spph_list[spph.package_name] = spph
317+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
318+ [])
319+ self.assertIn(spph, filtered_list)
320+
321+ def test_filter_success_record_filtered(self):
322+ self.init_dummy_config()
323+ spph = SPPH(self.MockPackage('packagesuccess', '1'))
324+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
325+ SUCCESS_BUILD_STATE)
326+ spph.add_build_record(failrecord)
327+ spph_list = dict()
328+ spph_list[spph.package_name] = spph
329+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
330+ [])
331+ self.assertNotIn(spph, filtered_list)
332+
333+ def test_filter_only_other_arch_filtered(self):
334+ self.init_dummy_config()
335+ spph = SPPH(self.MockPackage('packageotherarch', '1'))
336+ failrecord = self.MockRecord(TEST_OK_ARCHS[0], datetime.now(),
337+ FAILED_BUILD_STATE)
338+ spph.add_build_record(failrecord)
339+ spph_list = dict()
340+ spph_list[spph.package_name] = spph
341+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
342+ [])
343+ self.assertNotIn(spph, filtered_list)
344+
345+ def test_filter_no_arch_filtered(self):
346+ self.init_dummy_config()
347+ spph = SPPH(self.MockPackage('packagenobuilds', '1'))
348+ spph_list = dict()
349+ spph_list[spph.package_name] = spph
350+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
351+ [])
352+ self.assertNotIn(spph, filtered_list)
353+
354+ def test_get_build_list_only_returns_exact_matches(self):
355+ packagename = 'packagesubstring'
356+ exactrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
357+ SUCCESS_BUILD_STATE, packagename)
358+ nonexactrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
359+ SUCCESS_BUILD_STATE,
360+ 'pre' + packagename + 'post')
361+ archive = self.MockArchive('archivename',
362+ [exactrecord, nonexactrecord])
363+ build_records = get_build_list(archive, SUCCESS_BUILD_STATE,
364+ packagename)
365+ self.assertIn(exactrecord, build_records)
366+ self.assertNotIn(nonexactrecord, build_records)
367+
368+ def test_filter_success_on_same_arch_same_version_filtered(self):
369+ self.init_dummy_config()
370+ packagename = 'packagefailandok'
371+ version = '1'
372+ fail_spph = SPPH(self.MockPackage(packagename, version))
373+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
374+ FAILED_BUILD_STATE, packagename, version)
375+ successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
376+ SUCCESS_BUILD_STATE, packagename,
377+ version)
378+ fail_spph.add_build_record(failrecord)
379+ spph_list = dict()
380+ spph_list[fail_spph.package_name] = fail_spph
381+ archive = self.MockArchive('archivename', [successrecord])
382+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
383+ [(archive, 'archivename')])
384+ self.assertNotIn(fail_spph, filtered_list)
385+
386+ def test_filter_success_on_other_arch_not_filtered(self):
387+ self.init_dummy_config()
388+ packagename = 'packagename'
389+ version = '1'
390+ fail_spph = SPPH(self.MockPackage(packagename, version))
391+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
392+ FAILED_BUILD_STATE, packagename, version)
393+ successrecord = self.MockRecord(TEST_OK_ARCHS[0], datetime.now(),
394+ SUCCESS_BUILD_STATE, packagename,
395+ version)
396+ fail_spph.add_build_record(failrecord)
397+ spph_list = dict()
398+ spph_list[fail_spph.package_name] = fail_spph
399+ archive = self.MockArchive('archivename', [successrecord])
400+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
401+ [(archive, 'archivename')])
402+ self.assertIn(fail_spph, filtered_list)
403+
404+ def test_filter_success_on_higher_version_filtered(self):
405+ self.init_dummy_config()
406+ packagename = 'packagename'
407+ low_version = '1'
408+ high_version = '1.2.3'
409+ fail_spph = SPPH(self.MockPackage(packagename, low_version))
410+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
411+ FAILED_BUILD_STATE, packagename, low_version)
412+ successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
413+ SUCCESS_BUILD_STATE, packagename,
414+ high_version)
415+ fail_spph.add_build_record(failrecord)
416+ spph_list = dict()
417+ spph_list[fail_spph.package_name] = fail_spph
418+ archive = self.MockArchive('archivename', [successrecord])
419+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
420+ [(archive, 'archivename')])
421+ self.assertNotIn(fail_spph, filtered_list)
422+
423+ def test_filter_success_on_lower_version_not_filtered(self):
424+ self.init_dummy_config()
425+ packagename = 'packagename'
426+ low_version = '1'
427+ high_version = '1.2.3'
428+ fail_spph = SPPH(self.MockPackage(packagename, high_version))
429+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
430+ FAILED_BUILD_STATE, packagename, high_version)
431+ successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
432+ SUCCESS_BUILD_STATE, packagename,
433+ low_version)
434+ fail_spph.add_build_record(failrecord)
435+ spph_list = dict()
436+ spph_list[fail_spph.package_name] = fail_spph
437+ archive = self.MockArchive('archivename', [successrecord])
438+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
439+ [(archive, 'archivename')])
440+ self.assertIn(fail_spph, filtered_list)
441+
442+ def test_filter_success_on_lower_and_higher_version_filtered(self):
443+ self.init_dummy_config()
444+ packagename = 'midpackage'
445+ low_version = '1'
446+ mid_version = '2.1.3-1'
447+ high_version = '3.2.3'
448+ fail_spph = SPPH(self.MockPackage(packagename, mid_version))
449+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
450+ FAILED_BUILD_STATE, packagename, mid_version)
451+ low_successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
452+ SUCCESS_BUILD_STATE, packagename,
453+ low_version)
454+ high_successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
455+ SUCCESS_BUILD_STATE, packagename,
456+ high_version)
457+ fail_spph.add_build_record(failrecord)
458+ spph_list = dict()
459+ spph_list[fail_spph.package_name] = fail_spph
460+ low_archive = self.MockArchive('archive_with_lower_version',
461+ [low_successrecord])
462+ high_archive = self.MockArchive('archive_with_higher_version',
463+ [high_successrecord])
464+ filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
465+ [(low_archive, 'lo_archivename'),
466+ (high_archive, 'hi_archivename')])
467+ self.assertNotIn(fail_spph, filtered_list)
468+
469+
470 class TestSPPH(TestCaseWithFixtures):
471
472 class MockPackage(object):
473@@ -76,7 +279,7 @@
474 self.source_package_version = version
475 self.source_package_name = name
476
477- class MockLog(object):
478+ class MockRecord(object):
479 def __init__(self, arch, datecreated, state=FAILED_BUILD_STATE):
480 self.arch_tag = arch
481 self.datecreated = datecreated
482@@ -103,90 +306,96 @@
483 spph = SPPH(self.MockPackage('dummy', '1.1.2-3'))
484 self.assertEquals(spph.version, '1.1.2-3')
485
486- def test_new_sppg_has_no_logs(self):
487+ def test_new_spph_has_no_records(self):
488 self.init_dummy_config()
489 spph = SPPH(self.MockPackage('dummy', '1.1.2-3'))
490- self.assertTrue(len(spph.logs) == 0)
491+ self.assertEqual({}, spph.records)
492
493- def test_add_build_log_does_so(self):
494+ def test_add_build_record_does_so(self):
495 self.init_dummy_config()
496 spph = SPPH(self.MockPackage('dummy', '1'))
497- log = self.MockLog('armel', datetime.now())
498- spph.add_build_log(log)
499- self.assertEquals(spph.logs['armel'], log)
500+ record = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
501+ spph.add_build_record(record)
502+ self.assertEquals(spph.records[TEST_FAIL_ARCH], record)
503
504 def test_get_arch_does_so(self):
505 self.init_dummy_config()
506 spph = SPPH(self.MockPackage('dummy', '1'))
507- log = self.MockLog('armel', datetime.now())
508- spph.add_build_log(log)
509- self.assertEquals(spph.get_arch('armel'), log)
510- self.assertEquals(spph.get_arch('i386'), None)
511-
512- def test_add_newer_build_log_replaces(self):
513- self.init_dummy_config()
514- spph = SPPH(self.MockPackage('dummy', '1'))
515- oldlog = self.MockLog('armel', datetime.now())
516- newlog = self.MockLog('armel', datetime.now())
517- spph.add_build_log(oldlog)
518- spph.add_build_log(newlog)
519- self.assertEquals(spph.logs['armel'], newlog)
520-
521- def test_add_older_build_log_dont_replace(self):
522- self.init_dummy_config()
523- spph = SPPH(self.MockPackage('dummy', '1'))
524- oldlog = self.MockLog('armel', datetime.now())
525- newlog = self.MockLog('armel', datetime.now())
526- spph.add_build_log(newlog)
527- spph.add_build_log(oldlog)
528- self.assertEquals(spph.logs['armel'], newlog)
529-
530- def test_add_other_arch_build_log_dont_replace(self):
531- self.init_dummy_config()
532- spph = SPPH(self.MockPackage('dummy', '1'))
533- armlog = self.MockLog('armel', datetime.now())
534- i386log = self.MockLog('i386', datetime.now())
535- spph.add_build_log(armlog)
536- spph.add_build_log(i386log)
537- self.assertEquals(spph.logs['armel'], armlog)
538- self.assertEquals(spph.logs['i386'], i386log)
539-
540- def test_is_not_ftbfs_when_no_log(self):
541- self.init_dummy_config()
542- spph = SPPH(self.MockPackage('dummy', '1'))
543- self.assertFalse(spph.is_ftbfs('armel'))
544-
545- def test_is_ftbfs_when_failed_log(self):
546- self.init_dummy_config()
547- spph = SPPH(self.MockPackage('dummy', '1'))
548- faillog = self.MockLog('armel', datetime.now(), FAILED_BUILD_STATE)
549- spph.add_build_log(faillog)
550- self.assertTrue(spph.is_ftbfs('armel'))
551-
552- def test_is_not_ftbfs_when_success_log(self):
553- self.init_dummy_config()
554- spph = SPPH(self.MockPackage('dummy', '1'))
555- successlog = self.MockLog('armel', datetime.now(), SUCCESS_BUILD_STATE)
556- spph.add_build_log(successlog)
557- self.assertFalse(spph.is_ftbfs('armel'))
558-
559- def test_is_not_ftbfs_when_replaced_log(self):
560- self.init_dummy_config()
561- spph = SPPH(self.MockPackage('dummy', '1'))
562- faillog = self.MockLog('armel', datetime.now(), FAILED_BUILD_STATE)
563- successlog = self.MockLog('armel', datetime.now(), SUCCESS_BUILD_STATE)
564- spph.add_build_log(faillog)
565- spph.add_build_log(successlog)
566- self.assertFalse(spph.is_ftbfs('armel'))
567-
568- def test_is_ftbfs_when_replaced_log(self):
569- self.init_dummy_config()
570- spph = SPPH(self.MockPackage('dummy', '1'))
571- successlog = self.MockLog('armel', datetime.now(), SUCCESS_BUILD_STATE)
572- faillog = self.MockLog('armel', datetime.now(), FAILED_BUILD_STATE)
573- spph.add_build_log(successlog)
574- spph.add_build_log(faillog)
575- self.assertTrue(spph.is_ftbfs('armel'))
576+ record = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
577+ spph.add_build_record(record)
578+ self.assertEquals(spph.get_arch(TEST_FAIL_ARCH), record)
579+ self.assertEquals(spph.get_arch(TEST_OK_ARCHS[0]), None)
580+
581+ def test_add_newer_build_record_replaces(self):
582+ self.init_dummy_config()
583+ spph = SPPH(self.MockPackage('dummy', '1'))
584+ oldrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
585+ newrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
586+ spph.add_build_record(oldrecord)
587+ spph.add_build_record(newrecord)
588+ self.assertEquals(spph.records[TEST_FAIL_ARCH], newrecord)
589+
590+ def test_add_older_build_record_dont_replace(self):
591+ self.init_dummy_config()
592+ spph = SPPH(self.MockPackage('dummy', '1'))
593+ oldrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
594+ newrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
595+ spph.add_build_record(newrecord)
596+ spph.add_build_record(oldrecord)
597+ self.assertEquals(spph.records[TEST_FAIL_ARCH], newrecord)
598+
599+ def test_add_other_arch_build_record_dont_replace(self):
600+ self.init_dummy_config()
601+ spph = SPPH(self.MockPackage('dummy', '1'))
602+ armrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
603+ i386record = self.MockRecord(TEST_OK_ARCHS[0], datetime.now())
604+ spph.add_build_record(armrecord)
605+ spph.add_build_record(i386record)
606+ self.assertEquals(spph.records[TEST_FAIL_ARCH], armrecord)
607+ self.assertEquals(spph.records[TEST_OK_ARCHS[0]], i386record)
608+
609+ def test_is_not_ftbfs_when_no_record(self):
610+ self.init_dummy_config()
611+ spph = SPPH(self.MockPackage('dummy', '1'))
612+ self.assertFalse(spph.is_ftbfs(TEST_FAIL_ARCH))
613+
614+ def test_is_ftbfs_when_failed_record(self):
615+ self.init_dummy_config()
616+ spph = SPPH(self.MockPackage('dummy', '1'))
617+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
618+ FAILED_BUILD_STATE)
619+ spph.add_build_record(failrecord)
620+ self.assertTrue(spph.is_ftbfs(TEST_FAIL_ARCH))
621+
622+ def test_is_not_ftbfs_when_success_record(self):
623+ self.init_dummy_config()
624+ spph = SPPH(self.MockPackage('dummy', '1'))
625+ successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
626+ SUCCESS_BUILD_STATE)
627+ spph.add_build_record(successrecord)
628+ self.assertFalse(spph.is_ftbfs(TEST_FAIL_ARCH))
629+
630+ def test_is_not_ftbfs_when_replaced_record(self):
631+ self.init_dummy_config()
632+ spph = SPPH(self.MockPackage('dummy', '1'))
633+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
634+ FAILED_BUILD_STATE)
635+ successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
636+ SUCCESS_BUILD_STATE)
637+ spph.add_build_record(failrecord)
638+ spph.add_build_record(successrecord)
639+ self.assertFalse(spph.is_ftbfs(TEST_FAIL_ARCH))
640+
641+ def test_is_ftbfs_when_replaced_record(self):
642+ self.init_dummy_config()
643+ spph = SPPH(self.MockPackage('dummy', '1'))
644+ successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
645+ SUCCESS_BUILD_STATE)
646+ failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
647+ FAILED_BUILD_STATE)
648+ spph.add_build_record(successrecord)
649+ spph.add_build_record(failrecord)
650+ self.assertTrue(spph.is_ftbfs(TEST_FAIL_ARCH))
651
652 def test_spph_is_higher_version(self):
653 self.init_dummy_config()
654@@ -212,6 +421,48 @@
655 newspph = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
656 self.assertTrue(newspph.is_higher_version_than(oldspph))
657
658+ def test_get_highest_version_finds_single_version(self):
659+ self.init_dummy_config()
660+ spph = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
661+ spphlist = [spph]
662+ self.assertEquals(spph, get_highest_version(spphlist))
663+
664+ def test_get_highest_version_returns_first_of_same_version(self):
665+ self.init_dummy_config()
666+ spph_good = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
667+ spph_bad = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
668+ spphlist = [spph_good, spph_bad]
669+ self.assertEquals(spph_good, get_highest_version(spphlist))
670+
671+ def test_get_highest_version_returns_highest_version_in_order(self):
672+ self.init_dummy_config()
673+ spph_good = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu3'))
674+ spph_bad = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
675+ spphlist = [spph_good, spph_bad]
676+ self.assertEquals(spph_good, get_highest_version(spphlist))
677+
678+ def test_get_highest_version_returns_highest_version_out_of_order(self):
679+ self.init_dummy_config()
680+ spph_good = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu3'))
681+ spph_bad = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
682+ spphlist = [spph_bad, spph_good]
683+ self.assertEquals(spph_good, get_highest_version(spphlist))
684+
685+ def test_get_highest_version_returns_highest_version_mixed_order(self):
686+ self.init_dummy_config()
687+ spph_good = SPPH(self.MockPackage('packageversion', '99'))
688+ spph_bad1 = SPPH(self.MockPackage('packageversion', '1'))
689+ spph_bad2 = SPPH(self.MockPackage('packageversion', '2'))
690+ spph_bad3 = SPPH(self.MockPackage('packageversion', '3'))
691+ spphlist = [spph_bad1, spph_bad2, spph_bad1, spph_good, spph_bad3]
692+ self.assertEquals(spph_good, get_highest_version(spphlist))
693+
694+ def test_get_highest_version_returns_null(self):
695+ self.init_dummy_config()
696+ self.assertTrue(get_highest_version([]) is None)
697+ self.assertTrue(get_highest_version([None]) is None)
698+ self.assertTrue(get_highest_version([None, None]) is None)
699+
700
701 class TestFileBug(TestCase):
702

Subscribers

People subscribed via source and target branches