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
=== renamed file 'logging.py' => 'bug_logging.py'
=== modified file 'config.py'
--- config.py 2011-03-22 10:17:01 +0000
+++ config.py 2011-03-30 07:39:33 +0000
@@ -104,6 +104,9 @@
104 '-v', '--verbose', action='store_true', dest='verbose',104 '-v', '--verbose', action='store_true', dest='verbose',
105 help='Enable verbose messages.')105 help='Enable verbose messages.')
106 parser.add_argument(106 parser.add_argument(
107 '--dryrun', action='store_true', dest='dryrun',
108 help='Disable bug filing and enable verbose messages.')
109 parser.add_argument(
107 '--serviceroot', default='production',110 '--serviceroot', default='production',
108 choices=['production', 'staging', 'qastaging'],111 choices=['production', 'staging', 'qastaging'],
109 help='The Launchpad environment to connect to.')112 help='The Launchpad environment to connect to.')
110113
=== modified file 'data_parsing.py'
--- data_parsing.py 2011-03-30 07:39:33 +0000
+++ data_parsing.py 2011-03-30 07:39:33 +0000
@@ -85,14 +85,48 @@
85 self.version) < 0)85 self.version) < 0)
8686
8787
88def get_build_list(archive, state, source=None):
89
90 buildlist = archive.getBuildRecords(build_state=state, source_name=source)
91
92 # XXX mabac 2011-03-16: getBuildRecords filters on substrings
93 # so buildlist probably contains non exact matches.
94 # https://bugs.launchpad.net/launchpad/+bug/231862
95 if source is not None:
96 filter_list = []
97 for build in buildlist:
98 csp = build.current_source_publication
99 if csp is not None and csp.source_package_name == source:
100 filter_list.append(build)
101 return filter_list
102
103 return buildlist
104
105
106def get_highest_version(spph_queue):
107 """Returns the spph of the highest version in the list.
108
109 If more than one spph with the same version is in the list,
110 the first of the identical versions in the list is returned.
111 """
112 candidate_spph = None
113 while len(spph_queue) > 0:
114 new_spph = spph_queue.pop(0)
115 if new_spph is None:
116 continue
117 if new_spph.is_higher_version_than(candidate_spph):
118 candidate_spph = new_spph
119
120 return candidate_spph
121
122
88def fetch_pkg_list(archives):123def fetch_pkg_list(archives):
89 all_spph = dict()124 all_spph = dict()
90 for archive, archive_name in archives:125 for archive, archive_name in archives:
91 print_message("The following packages have failed to build " \126 print_message("The following packages have failed to build " \
92 "in '%s'." % archive_name)127 "in '%s'." % archive_name)
93128
94 buildlist = archive.getBuildRecords(build_state=FAILED_BUILD_STATE)129 buildlist = get_build_list(archive, FAILED_BUILD_STATE)
95
96 for build in buildlist:130 for build in buildlist:
97 csp = build.current_source_publication131 csp = build.current_source_publication
98 if csp is None:132 if csp is None:
@@ -112,13 +146,14 @@
112 return all_spph146 return all_spph
113147
114148
115def filter_spph(all_spph_list, fail_arch, ok_archs):149def filter_spph(all_spph_list, fail_arch, ok_archs, archives):
116 """Filter out the build failures that are unique to the target arch.150 """Filter out the build failures that are unique to the target arch.
117151
118 Arguments:152 Arguments:
119 all_spph_list -- List of all spphs to investigate.153 all_spph_list -- List of all spphs to investigate.
120 fail_arch -- The arch on which the builds should have failed.154 fail_arch -- The arch on which the builds should have failed.
121 ok_archs -- A list of archs on which the builds have not failed.155 ok_archs -- A list of archs on which the builds have not failed.
156 archives -- A list of archives to cross check for successful builds.
122157
123 Returns:158 Returns:
124 A subset of all_spph_list which represents the interesting packages.159 A subset of all_spph_list which represents the interesting packages.
@@ -126,13 +161,45 @@
126 filtered_list = []161 filtered_list = []
127 for spph in all_spph_list.values():162 for spph in all_spph_list.values():
128 if not spph.is_ftbfs(fail_arch):163 if not spph.is_ftbfs(fail_arch):
129 # Drop this spph since it did not fail on target arch.164 print_message("Ignoring package '%s' version '%s' since it did " \
130 continue165 "not fail on architecture '%s'." % \
131 if next((arch for arch in ok_archs if spph.is_ftbfs(arch)),166 (spph.package_name, spph.version, fail_arch))
132 None) is not None:167 continue
133 # Drop this spph since it did fail on other arch.168 also_failed = next((arch for arch in ok_archs
134 continue169 if spph.is_ftbfs(arch)), None)
135 filtered_list.append(spph)170 if also_failed is not None:
171 print_message("Ignoring package '%s' version '%s' since it also " \
172 "failed to build on architecture '%s'." % \
173 (spph.package_name, spph.version, also_failed))
174 continue
175
176 for archive, archive_name in archives:
177 # Get list of successful builds for the same package
178 success_list = get_build_list(archive, SUCCESS_BUILD_STATE,
179 spph.package_name)
180 success_spph_list = []
181 for success_build in success_list:
182 success_spph = SPPH(success_build.current_source_publication)
183 if success_build.arch_tag == fail_arch:
184 success_spph_list.append(success_spph)
185
186 candidate_success_spph = get_highest_version(success_spph_list)
187 if spph.is_higher_version_than(candidate_success_spph):
188 # Only care about the failed build if it is of a higher
189 # version than any successful build of the same package.
190 pass
191 else:
192 print_message("Failed build for package '%s' version '%s' " \
193 "overridden by successful build of " \
194 "version '%s' in archive '%s'." % \
195 (spph.package_name, spph.version,
196 candidate_success_spph.version,
197 archive_name))
198 spph = None
199 break
200
201 if spph is not None:
202 filtered_list.append(spph)
136203
137 return filtered_list204 return filtered_list
138205
@@ -179,4 +246,4 @@
179 print_message("Will be getting builds from archives " + ", ".join(246 print_message("Will be getting builds from archives " + ", ".join(
180 name for (archive, name) in archives))247 name for (archive, name) in archives))
181 spph_list = fetch_pkg_list(archives)248 spph_list = fetch_pkg_list(archives)
182 return filter_spph(spph_list, fail_platform, ok_platforms)249 return filter_spph(spph_list, fail_platform, ok_platforms, archives)
183250
=== modified file 'file-failures.py'
--- file-failures.py 2011-03-30 07:39:33 +0000
+++ file-failures.py 2011-03-30 07:39:33 +0000
@@ -13,7 +13,6 @@
13from data_parsing import (13from data_parsing import (
14 get_tags_for_fail,14 get_tags_for_fail,
15 get_build_status,15 get_build_status,
16 filter_spph,
17 )16 )
18from bug_reporting import (17from bug_reporting import (
19 file_bug_by_url,18 file_bug_by_url,
@@ -30,7 +29,7 @@
30 get_file_contents,29 get_file_contents,
31 get_interesting_part,30 get_interesting_part,
32)31)
33from logging import (32from bug_logging import (
34 Log,33 Log,
35 LogEntry,34 LogEntry,
36)35)
@@ -46,7 +45,7 @@
4645
47parser = get_args_parser()46parser = get_args_parser()
48args = parser.parse_args()47args = parser.parse_args()
49set_verbose_messages(args.verbose)48set_verbose_messages(args.verbose or args.dryrun)
5049
51init(args.serviceroot, 'testing', '~/.launchpadlib/cache/')50init(args.serviceroot, 'testing', '~/.launchpadlib/cache/')
5251
@@ -80,7 +79,7 @@
8079
81 build_record = spph.get_arch(fail_platform)80 build_record = spph.get_arch(fail_platform)
82 if build_record is not None:81 if build_record is not None:
83 build_build_record = get_file_contents(log.build_log_url)82 build_log = get_file_contents(build_record.build_log_url)
84 else:83 else:
85 print "%s build record not available for %s version %s." % \84 print "%s build record not available for %s version %s." % \
86 (fail_platform, spph.package_name, spph.version)85 (fail_platform, spph.package_name, spph.version)
@@ -99,12 +98,14 @@
99""" % (bug_title, build_record.web_link, build_record.build_log_url,98""" % (bug_title, build_record.web_link, build_record.build_log_url,
100 interesting_log_part)99 interesting_log_part)
101100
102 print_message(101 print_message("Will file bug for %s version %s with tags: %s" % \
103 "Will file bug for %s\n desc: %s\n title: %s\n tags: %s" %102 (spph.package_name, spph.version, bug_tags))
104 (spph.package_name, bug_description[0:220], bug_title, bug_tags))103 if not args.dryrun:
105 bug = file_bug_by_url(spph.url, bug_description, bug_title,104 bug = file_bug_by_url(spph.url, bug_description, bug_title,
106 bug_tags, get_launchpad())105 bug_tags, get_launchpad())
107 if bug is not None and args.logfile is not None:106 if bug is not None and args.logfile is not None:
108 bug_log.write_entry(107 bug_log.write_entry(
109 LogEntry(spph.package_name, spph.version, fail_platform,108 LogEntry(spph.package_name, spph.version, fail_platform,
110 bug.self_link).to_string())109 bug.self_link).to_string())
110 else:
111 print_message(" ... but didn't since dryrun is specified.")
111112
=== modified file 'tests/test_bug_logging.py'
--- tests/test_bug_logging.py 2011-03-23 11:12:12 +0000
+++ tests/test_bug_logging.py 2011-03-30 07:39:33 +0000
@@ -15,7 +15,7 @@
15 TestCaseWithFixtures,15 TestCaseWithFixtures,
16 MockSomethingFixture,16 MockSomethingFixture,
17 )17 )
18from logging import (18from bug_logging import (
19 LOG_ITEM_SEPARATOR,19 LOG_ITEM_SEPARATOR,
20 Log,20 Log,
21 LogEntry,21 LogEntry,
2222
=== modified file 'tests/test_fail_filer.py'
--- tests/test_fail_filer.py 2011-03-30 07:39:33 +0000
+++ tests/test_fail_filer.py 2011-03-30 07:39:33 +0000
@@ -9,8 +9,6 @@
9# Linaro Infrastructure Team - initial implementation9# Linaro Infrastructure Team - initial implementation
10###############################################################################10###############################################################################
11from testtools import TestCase11from testtools import TestCase
12
13from testtools import TestCase
14from datetime import (12from datetime import (
15 datetime,13 datetime,
16 )14 )
@@ -25,13 +23,13 @@
25 SUCCESS_BUILD_STATE,23 SUCCESS_BUILD_STATE,
26 SPPH,24 SPPH,
27 get_tags_for_fail,25 get_tags_for_fail,
26 get_highest_version,
27 filter_spph,
28 get_build_list,
28 )29 )
29from bug_reporting import (30from bug_reporting import (
30 bug_already_filed_by_url,31 bug_already_filed_by_url,
31# get_project_url,
32# file_bug,
33 )32 )
34import config
35from config import (33from config import (
36 get_service_root,34 get_service_root,
37 get_base_url,35 get_base_url,
@@ -42,9 +40,14 @@
42 inited,40 inited,
43 ConfigInitError,41 ConfigInitError,
44 LaunchpadError,42 LaunchpadError,
43 set_verbose_messages,
45 )44 )
4645
4746
47TEST_FAIL_ARCH = 'armel'
48TEST_OK_ARCHS = ['i386', 'amd64']
49
50
48class TestBugTags(TestCase):51class TestBugTags(TestCase):
4952
50 def setUp(self):53 def setUp(self):
@@ -69,6 +72,206 @@
69 msg='Got more than default tags without match.')72 msg='Got more than default tags without match.')
7073
7174
75class TestFilter(TestCaseWithFixtures):
76
77 class MockPackage(object):
78 def __init__(self, name, version):
79 self.source_package_version = version
80 self.source_package_name = name
81
82 class MockRecord(object):
83 class CSP:
84 def __init__(self, name, version):
85 self.source_package_name = name
86 self.source_package_version = version
87
88 def __init__(self, arch, datecreated, state=FAILED_BUILD_STATE,
89 name='packagename', version='1'):
90 self.arch_tag = arch
91 self.datecreated = datecreated
92 self.buildstate = state
93 self.current_source_publication = self.CSP(name, version)
94
95 class MockArchive(object):
96 def __init__(self, name, records_to_return=[]):
97 self.name = name
98 self.records_to_return = records_to_return
99
100 def getBuildRecords(self, build_state, source_name):
101 return self.records_to_return
102
103 def setUp(self):
104 super(TestFilter, self).setUp()
105
106 def init_dummy_config(self):
107 def mock_func(obj, appid, root, cachedir):
108 return 'this is a launchpad instance'
109
110 self.useFixture(MockSomethingFixture(
111 Launchpad, 'login_with', classmethod(mock_func)))
112 init('staging', 'dummyapp', 'dummycache')
113
114 def test_filter_fail_record_not_filtered(self):
115 self.init_dummy_config()
116 spph = SPPH(self.MockPackage('packagefail', '1'))
117 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
118 FAILED_BUILD_STATE)
119 spph.add_build_record(failrecord)
120 spph_list = dict()
121 spph_list[spph.package_name] = spph
122 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
123 [])
124 self.assertIn(spph, filtered_list)
125
126 def test_filter_success_record_filtered(self):
127 self.init_dummy_config()
128 spph = SPPH(self.MockPackage('packagesuccess', '1'))
129 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
130 SUCCESS_BUILD_STATE)
131 spph.add_build_record(failrecord)
132 spph_list = dict()
133 spph_list[spph.package_name] = spph
134 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
135 [])
136 self.assertNotIn(spph, filtered_list)
137
138 def test_filter_only_other_arch_filtered(self):
139 self.init_dummy_config()
140 spph = SPPH(self.MockPackage('packageotherarch', '1'))
141 failrecord = self.MockRecord(TEST_OK_ARCHS[0], datetime.now(),
142 FAILED_BUILD_STATE)
143 spph.add_build_record(failrecord)
144 spph_list = dict()
145 spph_list[spph.package_name] = spph
146 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
147 [])
148 self.assertNotIn(spph, filtered_list)
149
150 def test_filter_no_arch_filtered(self):
151 self.init_dummy_config()
152 spph = SPPH(self.MockPackage('packagenobuilds', '1'))
153 spph_list = dict()
154 spph_list[spph.package_name] = spph
155 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
156 [])
157 self.assertNotIn(spph, filtered_list)
158
159 def test_get_build_list_only_returns_exact_matches(self):
160 packagename = 'packagesubstring'
161 exactrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
162 SUCCESS_BUILD_STATE, packagename)
163 nonexactrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
164 SUCCESS_BUILD_STATE,
165 'pre' + packagename + 'post')
166 archive = self.MockArchive('archivename',
167 [exactrecord, nonexactrecord])
168 build_records = get_build_list(archive, SUCCESS_BUILD_STATE,
169 packagename)
170 self.assertIn(exactrecord, build_records)
171 self.assertNotIn(nonexactrecord, build_records)
172
173 def test_filter_success_on_same_arch_same_version_filtered(self):
174 self.init_dummy_config()
175 packagename = 'packagefailandok'
176 version = '1'
177 fail_spph = SPPH(self.MockPackage(packagename, version))
178 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
179 FAILED_BUILD_STATE, packagename, version)
180 successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
181 SUCCESS_BUILD_STATE, packagename,
182 version)
183 fail_spph.add_build_record(failrecord)
184 spph_list = dict()
185 spph_list[fail_spph.package_name] = fail_spph
186 archive = self.MockArchive('archivename', [successrecord])
187 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
188 [(archive, 'archivename')])
189 self.assertNotIn(fail_spph, filtered_list)
190
191 def test_filter_success_on_other_arch_not_filtered(self):
192 self.init_dummy_config()
193 packagename = 'packagename'
194 version = '1'
195 fail_spph = SPPH(self.MockPackage(packagename, version))
196 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
197 FAILED_BUILD_STATE, packagename, version)
198 successrecord = self.MockRecord(TEST_OK_ARCHS[0], datetime.now(),
199 SUCCESS_BUILD_STATE, packagename,
200 version)
201 fail_spph.add_build_record(failrecord)
202 spph_list = dict()
203 spph_list[fail_spph.package_name] = fail_spph
204 archive = self.MockArchive('archivename', [successrecord])
205 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
206 [(archive, 'archivename')])
207 self.assertIn(fail_spph, filtered_list)
208
209 def test_filter_success_on_higher_version_filtered(self):
210 self.init_dummy_config()
211 packagename = 'packagename'
212 low_version = '1'
213 high_version = '1.2.3'
214 fail_spph = SPPH(self.MockPackage(packagename, low_version))
215 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
216 FAILED_BUILD_STATE, packagename, low_version)
217 successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
218 SUCCESS_BUILD_STATE, packagename,
219 high_version)
220 fail_spph.add_build_record(failrecord)
221 spph_list = dict()
222 spph_list[fail_spph.package_name] = fail_spph
223 archive = self.MockArchive('archivename', [successrecord])
224 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
225 [(archive, 'archivename')])
226 self.assertNotIn(fail_spph, filtered_list)
227
228 def test_filter_success_on_lower_version_not_filtered(self):
229 self.init_dummy_config()
230 packagename = 'packagename'
231 low_version = '1'
232 high_version = '1.2.3'
233 fail_spph = SPPH(self.MockPackage(packagename, high_version))
234 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
235 FAILED_BUILD_STATE, packagename, high_version)
236 successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
237 SUCCESS_BUILD_STATE, packagename,
238 low_version)
239 fail_spph.add_build_record(failrecord)
240 spph_list = dict()
241 spph_list[fail_spph.package_name] = fail_spph
242 archive = self.MockArchive('archivename', [successrecord])
243 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
244 [(archive, 'archivename')])
245 self.assertIn(fail_spph, filtered_list)
246
247 def test_filter_success_on_lower_and_higher_version_filtered(self):
248 self.init_dummy_config()
249 packagename = 'midpackage'
250 low_version = '1'
251 mid_version = '2.1.3-1'
252 high_version = '3.2.3'
253 fail_spph = SPPH(self.MockPackage(packagename, mid_version))
254 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
255 FAILED_BUILD_STATE, packagename, mid_version)
256 low_successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
257 SUCCESS_BUILD_STATE, packagename,
258 low_version)
259 high_successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
260 SUCCESS_BUILD_STATE, packagename,
261 high_version)
262 fail_spph.add_build_record(failrecord)
263 spph_list = dict()
264 spph_list[fail_spph.package_name] = fail_spph
265 low_archive = self.MockArchive('archive_with_lower_version',
266 [low_successrecord])
267 high_archive = self.MockArchive('archive_with_higher_version',
268 [high_successrecord])
269 filtered_list = filter_spph(spph_list, TEST_FAIL_ARCH, TEST_OK_ARCHS,
270 [(low_archive, 'lo_archivename'),
271 (high_archive, 'hi_archivename')])
272 self.assertNotIn(fail_spph, filtered_list)
273
274
72class TestSPPH(TestCaseWithFixtures):275class TestSPPH(TestCaseWithFixtures):
73276
74 class MockPackage(object):277 class MockPackage(object):
@@ -76,7 +279,7 @@
76 self.source_package_version = version279 self.source_package_version = version
77 self.source_package_name = name280 self.source_package_name = name
78281
79 class MockLog(object):282 class MockRecord(object):
80 def __init__(self, arch, datecreated, state=FAILED_BUILD_STATE):283 def __init__(self, arch, datecreated, state=FAILED_BUILD_STATE):
81 self.arch_tag = arch284 self.arch_tag = arch
82 self.datecreated = datecreated285 self.datecreated = datecreated
@@ -103,90 +306,96 @@
103 spph = SPPH(self.MockPackage('dummy', '1.1.2-3'))306 spph = SPPH(self.MockPackage('dummy', '1.1.2-3'))
104 self.assertEquals(spph.version, '1.1.2-3')307 self.assertEquals(spph.version, '1.1.2-3')
105308
106 def test_new_sppg_has_no_logs(self):309 def test_new_spph_has_no_records(self):
107 self.init_dummy_config()310 self.init_dummy_config()
108 spph = SPPH(self.MockPackage('dummy', '1.1.2-3'))311 spph = SPPH(self.MockPackage('dummy', '1.1.2-3'))
109 self.assertTrue(len(spph.logs) == 0)312 self.assertEqual({}, spph.records)
110313
111 def test_add_build_log_does_so(self):314 def test_add_build_record_does_so(self):
112 self.init_dummy_config()315 self.init_dummy_config()
113 spph = SPPH(self.MockPackage('dummy', '1'))316 spph = SPPH(self.MockPackage('dummy', '1'))
114 log = self.MockLog('armel', datetime.now())317 record = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
115 spph.add_build_log(log)318 spph.add_build_record(record)
116 self.assertEquals(spph.logs['armel'], log)319 self.assertEquals(spph.records[TEST_FAIL_ARCH], record)
117320
118 def test_get_arch_does_so(self):321 def test_get_arch_does_so(self):
119 self.init_dummy_config()322 self.init_dummy_config()
120 spph = SPPH(self.MockPackage('dummy', '1'))323 spph = SPPH(self.MockPackage('dummy', '1'))
121 log = self.MockLog('armel', datetime.now())324 record = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
122 spph.add_build_log(log)325 spph.add_build_record(record)
123 self.assertEquals(spph.get_arch('armel'), log)326 self.assertEquals(spph.get_arch(TEST_FAIL_ARCH), record)
124 self.assertEquals(spph.get_arch('i386'), None)327 self.assertEquals(spph.get_arch(TEST_OK_ARCHS[0]), None)
125328
126 def test_add_newer_build_log_replaces(self):329 def test_add_newer_build_record_replaces(self):
127 self.init_dummy_config()330 self.init_dummy_config()
128 spph = SPPH(self.MockPackage('dummy', '1'))331 spph = SPPH(self.MockPackage('dummy', '1'))
129 oldlog = self.MockLog('armel', datetime.now())332 oldrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
130 newlog = self.MockLog('armel', datetime.now())333 newrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
131 spph.add_build_log(oldlog)334 spph.add_build_record(oldrecord)
132 spph.add_build_log(newlog)335 spph.add_build_record(newrecord)
133 self.assertEquals(spph.logs['armel'], newlog)336 self.assertEquals(spph.records[TEST_FAIL_ARCH], newrecord)
134337
135 def test_add_older_build_log_dont_replace(self):338 def test_add_older_build_record_dont_replace(self):
136 self.init_dummy_config()339 self.init_dummy_config()
137 spph = SPPH(self.MockPackage('dummy', '1'))340 spph = SPPH(self.MockPackage('dummy', '1'))
138 oldlog = self.MockLog('armel', datetime.now())341 oldrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
139 newlog = self.MockLog('armel', datetime.now())342 newrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
140 spph.add_build_log(newlog)343 spph.add_build_record(newrecord)
141 spph.add_build_log(oldlog)344 spph.add_build_record(oldrecord)
142 self.assertEquals(spph.logs['armel'], newlog)345 self.assertEquals(spph.records[TEST_FAIL_ARCH], newrecord)
143346
144 def test_add_other_arch_build_log_dont_replace(self):347 def test_add_other_arch_build_record_dont_replace(self):
145 self.init_dummy_config()348 self.init_dummy_config()
146 spph = SPPH(self.MockPackage('dummy', '1'))349 spph = SPPH(self.MockPackage('dummy', '1'))
147 armlog = self.MockLog('armel', datetime.now())350 armrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now())
148 i386log = self.MockLog('i386', datetime.now())351 i386record = self.MockRecord(TEST_OK_ARCHS[0], datetime.now())
149 spph.add_build_log(armlog)352 spph.add_build_record(armrecord)
150 spph.add_build_log(i386log)353 spph.add_build_record(i386record)
151 self.assertEquals(spph.logs['armel'], armlog)354 self.assertEquals(spph.records[TEST_FAIL_ARCH], armrecord)
152 self.assertEquals(spph.logs['i386'], i386log)355 self.assertEquals(spph.records[TEST_OK_ARCHS[0]], i386record)
153356
154 def test_is_not_ftbfs_when_no_log(self):357 def test_is_not_ftbfs_when_no_record(self):
155 self.init_dummy_config()358 self.init_dummy_config()
156 spph = SPPH(self.MockPackage('dummy', '1'))359 spph = SPPH(self.MockPackage('dummy', '1'))
157 self.assertFalse(spph.is_ftbfs('armel'))360 self.assertFalse(spph.is_ftbfs(TEST_FAIL_ARCH))
158361
159 def test_is_ftbfs_when_failed_log(self):362 def test_is_ftbfs_when_failed_record(self):
160 self.init_dummy_config()363 self.init_dummy_config()
161 spph = SPPH(self.MockPackage('dummy', '1'))364 spph = SPPH(self.MockPackage('dummy', '1'))
162 faillog = self.MockLog('armel', datetime.now(), FAILED_BUILD_STATE)365 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
163 spph.add_build_log(faillog)366 FAILED_BUILD_STATE)
164 self.assertTrue(spph.is_ftbfs('armel'))367 spph.add_build_record(failrecord)
165368 self.assertTrue(spph.is_ftbfs(TEST_FAIL_ARCH))
166 def test_is_not_ftbfs_when_success_log(self):369
167 self.init_dummy_config()370 def test_is_not_ftbfs_when_success_record(self):
168 spph = SPPH(self.MockPackage('dummy', '1'))371 self.init_dummy_config()
169 successlog = self.MockLog('armel', datetime.now(), SUCCESS_BUILD_STATE)372 spph = SPPH(self.MockPackage('dummy', '1'))
170 spph.add_build_log(successlog)373 successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
171 self.assertFalse(spph.is_ftbfs('armel'))374 SUCCESS_BUILD_STATE)
172375 spph.add_build_record(successrecord)
173 def test_is_not_ftbfs_when_replaced_log(self):376 self.assertFalse(spph.is_ftbfs(TEST_FAIL_ARCH))
174 self.init_dummy_config()377
175 spph = SPPH(self.MockPackage('dummy', '1'))378 def test_is_not_ftbfs_when_replaced_record(self):
176 faillog = self.MockLog('armel', datetime.now(), FAILED_BUILD_STATE)379 self.init_dummy_config()
177 successlog = self.MockLog('armel', datetime.now(), SUCCESS_BUILD_STATE)380 spph = SPPH(self.MockPackage('dummy', '1'))
178 spph.add_build_log(faillog)381 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
179 spph.add_build_log(successlog)382 FAILED_BUILD_STATE)
180 self.assertFalse(spph.is_ftbfs('armel'))383 successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
181384 SUCCESS_BUILD_STATE)
182 def test_is_ftbfs_when_replaced_log(self):385 spph.add_build_record(failrecord)
183 self.init_dummy_config()386 spph.add_build_record(successrecord)
184 spph = SPPH(self.MockPackage('dummy', '1'))387 self.assertFalse(spph.is_ftbfs(TEST_FAIL_ARCH))
185 successlog = self.MockLog('armel', datetime.now(), SUCCESS_BUILD_STATE)388
186 faillog = self.MockLog('armel', datetime.now(), FAILED_BUILD_STATE)389 def test_is_ftbfs_when_replaced_record(self):
187 spph.add_build_log(successlog)390 self.init_dummy_config()
188 spph.add_build_log(faillog)391 spph = SPPH(self.MockPackage('dummy', '1'))
189 self.assertTrue(spph.is_ftbfs('armel'))392 successrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
393 SUCCESS_BUILD_STATE)
394 failrecord = self.MockRecord(TEST_FAIL_ARCH, datetime.now(),
395 FAILED_BUILD_STATE)
396 spph.add_build_record(successrecord)
397 spph.add_build_record(failrecord)
398 self.assertTrue(spph.is_ftbfs(TEST_FAIL_ARCH))
190399
191 def test_spph_is_higher_version(self):400 def test_spph_is_higher_version(self):
192 self.init_dummy_config()401 self.init_dummy_config()
@@ -212,6 +421,48 @@
212 newspph = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))421 newspph = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
213 self.assertTrue(newspph.is_higher_version_than(oldspph))422 self.assertTrue(newspph.is_higher_version_than(oldspph))
214423
424 def test_get_highest_version_finds_single_version(self):
425 self.init_dummy_config()
426 spph = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
427 spphlist = [spph]
428 self.assertEquals(spph, get_highest_version(spphlist))
429
430 def test_get_highest_version_returns_first_of_same_version(self):
431 self.init_dummy_config()
432 spph_good = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
433 spph_bad = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
434 spphlist = [spph_good, spph_bad]
435 self.assertEquals(spph_good, get_highest_version(spphlist))
436
437 def test_get_highest_version_returns_highest_version_in_order(self):
438 self.init_dummy_config()
439 spph_good = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu3'))
440 spph_bad = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
441 spphlist = [spph_good, spph_bad]
442 self.assertEquals(spph_good, get_highest_version(spphlist))
443
444 def test_get_highest_version_returns_highest_version_out_of_order(self):
445 self.init_dummy_config()
446 spph_good = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu3'))
447 spph_bad = SPPH(self.MockPackage('packageversion', '0.5.32-0ubuntu2'))
448 spphlist = [spph_bad, spph_good]
449 self.assertEquals(spph_good, get_highest_version(spphlist))
450
451 def test_get_highest_version_returns_highest_version_mixed_order(self):
452 self.init_dummy_config()
453 spph_good = SPPH(self.MockPackage('packageversion', '99'))
454 spph_bad1 = SPPH(self.MockPackage('packageversion', '1'))
455 spph_bad2 = SPPH(self.MockPackage('packageversion', '2'))
456 spph_bad3 = SPPH(self.MockPackage('packageversion', '3'))
457 spphlist = [spph_bad1, spph_bad2, spph_bad1, spph_good, spph_bad3]
458 self.assertEquals(spph_good, get_highest_version(spphlist))
459
460 def test_get_highest_version_returns_null(self):
461 self.init_dummy_config()
462 self.assertTrue(get_highest_version([]) is None)
463 self.assertTrue(get_highest_version([None]) is None)
464 self.assertTrue(get_highest_version([None, None]) is None)
465
215466
216class TestFileBug(TestCase):467class TestFileBug(TestCase):
217468

Subscribers

People subscribed via source and target branches