Merge ~juliank/britney/+git/britney2-ubuntu:lp1688516 into ~ubuntu-release/britney/+git/britney2-ubuntu:master
- Git
- lp:~juliank/britney/+git/britney2-ubuntu
- lp1688516
- Merge into master
Status: | Merged | ||||
---|---|---|---|---|---|
Merge reported by: | Julian Andres Klode | ||||
Merged at revision: | 04c3cdb382c2a94382187fd76139d88dec3c5f8d | ||||
Proposed branch: | ~juliank/britney/+git/britney2-ubuntu:lp1688516 | ||||
Merge into: | ~ubuntu-release/britney/+git/britney2-ubuntu:master | ||||
Diff against target: |
229 lines (+162/-6) 3 files modified
britney2/policies/autopkgtest.py (+31/-4) britney2/utils.py (+0/-2) tests/test_autopkgtest.py (+131/-0) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Iain Lane | Needs Fixing | ||
Review via email:
|
Commit message
needs some name bikeshedding
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Julian Andres Klode (juliank) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Julian Andres Klode (juliank) wrote : | # |
We can make ALWAYSFAIL an IGNORE-FAIL in such a case, or add a new state?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Iain Lane (laney) wrote : | # |
Basic approach is good, thanks!
As discussed, we should handle the multiple hint case differently: find the highest version that is at most the current trigger and look at that one. If there are multiple versions in play - a version in testing and a version (possibly this is one of many uploads!) in unstable, we want to be able to hint them independently.
I think an 'excuse' should be added so that it's clear on update_excuses.html that a test is only ALWAYSFAIL because it's been hinted - for force-skiptest we say "Should wait for tests relating to %s %s, but forced by %s". Our string could be very similar.
Does /arch work and can we have a test for that?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Iain Lane (laney) : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Julian Andres Klode (juliank) wrote : | # |
We don't correctly handle multiple hints, need to fix that.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Paul Gevers (paul-climbing) wrote : | # |
Are you aware of the changes I made in Debian to reset the base line?
In Debian I have a migration-
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Iain Lane (laney) wrote : | # |
Paul - I think you could use a hint like this to effect a 'reset the baseline to testing' check like you & Steve are proposing? I'm not sure that I've considered all the implications, but it sounds like you want consider that the baseline is always the version that's in testing? Maybe slightly modified to consider only the test runs where the triggering package/version is the one in testing.
@juliank - can you check https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Iain Lane (laney) wrote : | # |
Any comments or should I just merge this?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Julian Andres Klode (juliank) wrote : | # |
I must say that I prefer the Debian approach somewhat, as it solves two problems:
(a) Testing against the release pocket, and
(b) resetting the baseline
in one operation. That's somewhat easier than manually retrying it with a fake trigger like hello and then if that fails too force-reset-test it.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Iain Lane (laney) wrote : | # |
1) Why a fake trigger rather than the package/version in release?
2) While systematically forcing to the version in release is one potential use of this, I think that is a *policy* question that is as yet undecided in Ubuntu. In the absence of such a policy, release team members can use this hint when they decide that a regression should not be treated as one - for example if there is a 'fluke' pass, which sometimes happens. In other words, I think the "Debian" approach is the answer to a different question that we're not asking here.
Preview Diff
1 | diff --git a/britney2/policies/autopkgtest.py b/britney2/policies/autopkgtest.py |
2 | index 806debd..fbf83f8 100644 |
3 | --- a/britney2/policies/autopkgtest.py |
4 | +++ b/britney2/policies/autopkgtest.py |
5 | @@ -102,6 +102,7 @@ class AutopkgtestPolicy(BasePolicy): |
6 | |
7 | def register_hints(self, hint_parser): |
8 | hint_parser.register_hint_type('force-badtest', britney2.hints.split_into_one_hint_per_package) |
9 | + hint_parser.register_hint_type('force-badtest-until', britney2.hints.split_into_one_hint_per_package) |
10 | hint_parser.register_hint_type('force-skiptest', britney2.hints.split_into_one_hint_per_package) |
11 | |
12 | def initialise(self, britney): |
13 | @@ -658,12 +659,22 @@ class AutopkgtestPolicy(BasePolicy): |
14 | # save pending.json right away, so that we don't re-request if britney crashes |
15 | self.save_pending_json() |
16 | |
17 | - def check_ever_passed(self, src, arch): |
18 | - '''Check if tests for src ever passed on arch''' |
19 | + def check_ever_passed_before(self, src, max_ver, arch, min_ver=None): |
20 | + '''Check if tests for src ever passed on arch for specified range |
21 | + |
22 | + If min_ver is specified, it checks that all versions in |
23 | + [min_ver, max_ver) have passed; otherwise it checks that |
24 | + [min_ver, inf) have passed.''' |
25 | |
26 | # FIXME: add caching |
27 | for srcmap in self.test_results.values(): |
28 | try: |
29 | + too_high = apt_pkg.version_compare(srcmap[src][arch][1], max_ver) > 0 |
30 | + too_low = apt_pkg.version_compare(srcmap[src][arch][1], min_ver) <= 0 if min_ver else False |
31 | + |
32 | + if too_high or too_low: |
33 | + continue |
34 | + |
35 | if srcmap[src][arch][0]: |
36 | return True |
37 | except KeyError: |
38 | @@ -677,7 +688,8 @@ class AutopkgtestPolicy(BasePolicy): |
39 | EXCUSES_LABELS. log_url is None if the test is still running. |
40 | ''' |
41 | # determine current test result status |
42 | - ever_passed = self.check_ever_passed(src, arch) |
43 | + until = self.find_max_force_badtest_until(src, ver, arch) |
44 | + ever_passed = self.check_ever_passed_before(src, ver, arch, until) |
45 | url = None |
46 | try: |
47 | r = self.test_results[trigger][src][arch] |
48 | @@ -724,6 +736,22 @@ class AutopkgtestPolicy(BasePolicy): |
49 | |
50 | return (result, ver, url) |
51 | |
52 | + def find_max_force_badtest_until(self, src, ver, arch): |
53 | + '''Find the maximum force-badtest-until hint before/including ver''' |
54 | + hints = self.britney.hints.search('force-badtest-until', package=src) |
55 | + found_ver = None |
56 | + |
57 | + if hints: |
58 | + for hint in hints: |
59 | + for mi in hint.packages: |
60 | + if (mi.architecture in ['source', arch] and |
61 | + mi.version != 'all' and |
62 | + apt_pkg.version_compare(mi.version, ver) <= 0 and |
63 | + (found_ver is None or apt_pkg.version_compare(found_ver, mi.version) < 0)): |
64 | + found_ver = mi.version |
65 | + |
66 | + return found_ver |
67 | + |
68 | def has_force_badtest(self, src, ver, arch): |
69 | '''Check if src/ver/arch has a force-badtest hint''' |
70 | |
71 | @@ -736,4 +764,3 @@ class AutopkgtestPolicy(BasePolicy): |
72 | return True |
73 | |
74 | return False |
75 | - |
76 | diff --git a/britney2/utils.py b/britney2/utils.py |
77 | index 837dad6..25223c8 100644 |
78 | --- a/britney2/utils.py |
79 | +++ b/britney2/utils.py |
80 | @@ -368,8 +368,6 @@ def write_excuses(excuselist, dest_file, output_format="yaml"): |
81 | ensuredir(os.path.dirname(dest_file)) |
82 | with open(dest_file, 'w', encoding='utf-8') as f: |
83 | edatalist = [e.excusedata() for e in excuselist] |
84 | - for e in edatalist: |
85 | - del(e['excuses']) |
86 | excusesdata = { |
87 | 'sources': edatalist, |
88 | 'generated-date': datetime.utcnow(), |
89 | diff --git a/tests/test_autopkgtest.py b/tests/test_autopkgtest.py |
90 | index bc736ae..a780845 100755 |
91 | --- a/tests/test_autopkgtest.py |
92 | +++ b/tests/test_autopkgtest.py |
93 | @@ -1555,6 +1555,137 @@ class T(TestBase): |
94 | {'green': [('old-version', '1'), ('new-version', '2')] |
95 | }) |
96 | |
97 | + def test_hint_force_badtest_until_goodbad_alwaysfail(self): |
98 | + '''force-badtest-until hint marks as alwaysfail''' |
99 | + |
100 | + self.swift.set_results({'autopkgtest-series': { |
101 | + 'series/amd64/l/lightgreen/20150101_100100@': (0, 'lightgreen 1', tr('lightgreen/1')), |
102 | + 'series/amd64/l/lightgreen/20150101_100101@': (4, 'lightgreen 2', tr('lightgreen/2')), |
103 | + }}) |
104 | + |
105 | + self.create_hint('pitti', 'force-badtest-until lightgreen/1') |
106 | + |
107 | + self.do_test( |
108 | + [('lightgreen', {'Version': '2', 'Source': 'lightgreen', 'Depends': 'libc6'}, 'autopkgtest')], |
109 | + {'lightgreen': (True, { |
110 | + 'lightgreen/2': {'amd64': 'ALWAYSFAIL'}, |
111 | + }), |
112 | + }, |
113 | + {'lightgreen': [('old-version', '1'), ('new-version', '2')] |
114 | + }) |
115 | + |
116 | + def test_hint_force_badtest_until_goodbad_alwaysfail_arch(self): |
117 | + '''force-badtest-until hint marks as alwaysfail per arch''' |
118 | + |
119 | + self.swift.set_results({'autopkgtest-series': { |
120 | + 'series/amd64/l/lightgreen/20150101_100100@': (0, 'lightgreen 1', tr('lightgreen/1')), |
121 | + 'series/amd64/l/lightgreen/20150101_100101@': (4, 'lightgreen 2', tr('lightgreen/2')), |
122 | + 'series/i386/l/lightgreen/20150101_100100@': (0, 'lightgreen 1', tr('lightgreen/1')), |
123 | + 'series/i386/l/lightgreen/20150101_100101@': (4, 'lightgreen 2', tr('lightgreen/2')), |
124 | + }}) |
125 | + |
126 | + self.create_hint('pitti', 'force-badtest-until lightgreen/1/amd64') |
127 | + |
128 | + self.do_test( |
129 | + [('lightgreen', {'Version': '2', 'Source': 'lightgreen', 'Depends': 'libc6'}, 'autopkgtest')], |
130 | + {'lightgreen': (False, { |
131 | + 'lightgreen/2': {'amd64': 'ALWAYSFAIL', 'i386': 'REGRESSION'}, |
132 | + }), |
133 | + }, |
134 | + {'lightgreen': [('old-version', '1'), ('new-version', '2')] |
135 | + }) |
136 | + |
137 | + def test_hint_force_badtest_until_bad_good_pass(self): |
138 | + '''force-badtest-until hint followed by pass is pass''' |
139 | + |
140 | + self.swift.set_results({'autopkgtest-series': { |
141 | + 'series/amd64/l/lightgreen/20150101_100100@': (4, 'lightgreen 1', tr('lightgreen/1')), |
142 | + 'series/amd64/l/lightgreen/20150102_100101@': (0, 'lightgreen 2', tr('lightgreen/2')), |
143 | + }}) |
144 | + |
145 | + self.create_hint('pitti', 'force-badtest-until lightgreen/1') |
146 | + |
147 | + self.do_test( |
148 | + [('lightgreen', {'Version': '2', 'Source': 'lightgreen', 'Depends': 'libc6'}, 'autopkgtest')], |
149 | + {'lightgreen': (True, { |
150 | + 'lightgreen/2': {'amd64': 'PASS'}, |
151 | + }), |
152 | + }, |
153 | + {'lightgreen': [('old-version', '1'), ('new-version', '2')] |
154 | + }) |
155 | + |
156 | + def test_hint_force_badtest_until_bad_good_bad_regression(self): |
157 | + '''force-badtest-until hint followed by good, bad is regression''' |
158 | + |
159 | + self.swift.set_results({'autopkgtest-series': { |
160 | + 'series/amd64/l/lightgreen/20150101_100100@': (4, 'lightgreen 1', tr('lightgreen/1')), |
161 | + 'series/amd64/l/lightgreen/20150102_100101@': (0, 'lightgreen 2', tr('lightgreen/2')), |
162 | + 'series/amd64/l/lightgreen/20150103_100101@': (4, 'lightgreen 3', tr('lightgreen/3')), |
163 | + }}) |
164 | + |
165 | + self.create_hint('pitti', 'force-badtest-until lightgreen/1') |
166 | + |
167 | + self.do_test( |
168 | + [('lightgreen', {'Version': '3', 'Source': 'lightgreen', 'Depends': 'libc6'}, 'autopkgtest')], |
169 | + {'lightgreen': (False, { |
170 | + 'lightgreen/3': {'amd64': 'REGRESSION'}, |
171 | + }), |
172 | + }, |
173 | + {'lightgreen': [('old-version', '1'), ('new-version', '3')] |
174 | + }) |
175 | + |
176 | + def test_hint_force_badtest_until_multiple_hints(self): |
177 | + '''force-badtest-until multiple hints check ranges''' |
178 | + |
179 | + self.swift.set_results({'autopkgtest-series': { |
180 | + 'series/amd64/l/lightgreen/20150100_100100@': (0, 'lightgreen 1', tr('lightgreen/1')), |
181 | + 'series/amd64/l/lightgreen/20150101_100100@': (4, 'lightgreen 1', tr('green/2')), |
182 | + 'series/amd64/l/lightgreen/20150102_100101@': (0, 'lightgreen 2', tr('lightgreen/2')), |
183 | + 'series/amd64/l/lightgreen/20150103_100101@': (4, 'lightgreen 3', tr('lightgreen/3')), |
184 | + }}) |
185 | + |
186 | + |
187 | + self.do_test( |
188 | + [('libgreen1', {'Version': '2', 'Source': 'green', 'Depends': 'libc6'}, 'autopkgtest'), |
189 | + ('lightgreen', {'Version': '3', 'Source': 'lightgreen', 'Depends': 'libc6'}, 'autopkgtest')], |
190 | + {'green': (False, { |
191 | + 'lightgreen/1': {'amd64': 'REGRESSION'}, |
192 | + }), |
193 | + }, |
194 | + {'green': [('old-version', '1'), ('new-version', '2')], |
195 | + 'lightgreen': [('old-version', '1'), ('new-version', '3')], |
196 | + }) |
197 | + |
198 | + self.create_hint('pitti', 'force-badtest-until lightgreen/1') |
199 | + self.do_test( |
200 | + [], |
201 | + {'green': (True, { |
202 | + 'lightgreen/1': {'amd64': 'ALWAYSFAIL'}, |
203 | + }), |
204 | + 'lightgreen': (False, { |
205 | + 'lightgreen/3': {'amd64': 'REGRESSION'}, |
206 | + }), |
207 | + |
208 | + }, |
209 | + {'green': [('old-version', '1'), ('new-version', '2')], |
210 | + 'lightgreen': [('old-version', '1'), ('new-version', '3')], |
211 | + }) |
212 | + self.create_hint('pitti', 'force-badtest-until lightgreen/3') |
213 | + self.do_test( |
214 | + [], |
215 | + {'green': (True, { |
216 | + 'lightgreen/1': {'amd64': 'ALWAYSFAIL'}, |
217 | + }), |
218 | + 'lightgreen': (True, { |
219 | + 'lightgreen/3': {'amd64': 'ALWAYSFAIL'}, |
220 | + }), |
221 | + |
222 | + }, |
223 | + {'green': [('old-version', '1'), ('new-version', '2')], |
224 | + 'lightgreen': [('old-version', '1'), ('new-version', '3')], |
225 | + }) |
226 | + |
227 | + |
228 | def test_hint_force_badtest_multi_version(self): |
229 | '''force-badtest hint''' |
230 |
Might want to do something other than the revert of the excuses removal.