Merge lp:~alan-griffiths/miral/fix-1717061 into lp:miral
- fix-1717061
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Alan Griffiths | ||||
Approved revision: | 580 | ||||
Merged at revision: | 580 | ||||
Proposed branch: | lp:~alan-griffiths/miral/fix-1717061 | ||||
Merge into: | lp:miral | ||||
Diff against target: |
350 lines (+174/-39) 7 files modified
miral/CMakeLists.txt (+1/-0) miral/set_window_management_policy.cpp (+16/-16) miral/window_info.cpp (+49/-15) miral/window_info_defaults.h (+36/-0) miral/window_management_trace.cpp (+10/-8) test/CMakeLists.txt (+1/-0) test/window_info.cpp (+61/-0) |
||||
To merge this branch: | bzr merge lp:~alan-griffiths/miral/fix-1717061 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mir CI Bot | continuous-integration | Approve | |
Gerry Boland (community) | Approve | ||
Brandon Schaefer (community) | Approve | ||
Review via email: mp+330832@code.launchpad.net |
Commit message
Define default window settings in one place and clamp the actual values to avoid ldiv0. (LP: #1717061)
Description of the change
Mir CI Bot (mir-ci-bot) wrote : | # |
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:580
https:/
Executed test runs:
ABORTED: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Gerry Boland (gerboland) wrote : | # |
+unsigned clamp_dim(unsigned dim)
+{
+ return std::min<unsigned long>(std:
+}
There's a mix of types here: unsigned int, unsigned long and signed long, which is causing me problems understanding. I know sizeof(unsigned int) <= sizeof(long), which implies to me that
dim <= std::numeric_
<= std::numeric_
so the min() will always choose "dim". So I don't understand what it is clamping to.
+// For our convenience when doing calculations we clamp the dimensions of the aspect ratio
+// so they will fit into a long without overflow.
What "long"? AspectRatio is a pair of unsigned ints.
Alan Griffiths (alan-griffiths) wrote : | # |
> +unsigned clamp_dim(unsigned dim)
> +{
> + return std::min<unsigned long>(std:
> +}
>
> There's a mix of types here: unsigned int, unsigned long and signed long,
> which is causing me problems understanding. I know sizeof(unsigned int) <=
> sizeof(long), which implies to me that
>
> dim <= std::numeric_
> <= std::numeric_
when, as Brandon encountered on armhf, long and int are the same size.
std:
> so the min() will always choose "dim". So I don't understand what it is
> clamping to.
In the above case it is clamping to std::numeric_
> +// For our convenience when doing calculations we clamp the dimensions of the
> aspect ratio
> +// so they will fit into a long without overflow.
> What "long"? AspectRatio is a pair of unsigned ints.
If std::numeric_
Brandon Schaefer (brandontschaefer) wrote : | # |
Yeah this seems a bit more robust then what I was doing in my branch.
I was just figuring since sizeof(long) >= sizeof(int) we could just cheat and assign the aspect to int::max() vs unsigned::max() but you do end up losing a byte there if really wanted on amd64 machines.
Though wont it all be going through the values that are depended in the RPC? Should we at some point look at moving to proper int sizes (u)int8/16/32/64 to know we wont have changing int values depending on the architecture.
Also that test is sort of ... different then this overflow issue but still nice to test. Wasnt sure if we actually had more checking higher up the stack when we come from the RPC.
LGTM
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
ABORTED: https:/
ABORTED: https:/
ABORTED: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Mir CI Bot (mir-ci-bot) : | # |
Preview Diff
1 | === modified file 'miral/CMakeLists.txt' |
2 | --- miral/CMakeLists.txt 2017-07-26 10:44:19 +0000 |
3 | +++ miral/CMakeLists.txt 2017-09-15 13:33:35 +0000 |
4 | @@ -64,6 +64,7 @@ |
5 | ${miral_include}/mir/client/connection.h |
6 | ${miral_include}/mir/client/display_config.h |
7 | ${miral_include}/mir/client/window.h |
8 | + window_info_defaults.h |
9 | ) |
10 | |
11 | target_include_directories(mirclientcpp |
12 | |
13 | === modified file 'miral/set_window_management_policy.cpp' |
14 | --- miral/set_window_management_policy.cpp 2017-08-10 16:59:22 +0000 |
15 | +++ miral/set_window_management_policy.cpp 2017-09-15 13:33:35 +0000 |
16 | @@ -32,22 +32,6 @@ |
17 | char const* const trace_option = "window-management-trace"; |
18 | } |
19 | |
20 | -MIRAL_FAKE_OLD_SYMBOL( |
21 | - _ZN5miral24SetWindowManagmentPolicyC1ERKSt8functionIFSt10unique_ptrINS_22WindowManagementPolicyESt14default_deleteIS3_EERKNS_18WindowManagerToolsEEE, |
22 | - _ZN5miral25SetWindowManagementPolicyC1ERKSt8functionIFSt10unique_ptrINS_22WindowManagementPolicyESt14default_deleteIS3_EERKNS_18WindowManagerToolsEEE) |
23 | - |
24 | -MIRAL_FAKE_OLD_SYMBOL( |
25 | - _ZNK5miral24SetWindowManagmentPolicyclERN3mir6ServerE, |
26 | - _ZNK5miral25SetWindowManagementPolicyclERN3mir6ServerE) |
27 | - |
28 | -MIRAL_FAKE_OLD_SYMBOL( |
29 | - _ZN5miral24SetWindowManagmentPolicyD1Ev, |
30 | - _ZN5miral25SetWindowManagementPolicyD1Ev) |
31 | - |
32 | -MIRAL_FAKE_OLD_SYMBOL( |
33 | - _ZN5miral24SetWindowManagmentPolicyD2Ev, |
34 | - _ZN5miral25SetWindowManagementPolicyD2Ev) |
35 | - |
36 | miral::SetWindowManagementPolicy::SetWindowManagementPolicy(WindowManagementPolicyBuilder const& builder) : |
37 | builder{builder} |
38 | { |
39 | @@ -89,3 +73,19 @@ |
40 | builder); |
41 | }); |
42 | } |
43 | + |
44 | +MIRAL_FAKE_OLD_SYMBOL( |
45 | + _ZN5miral24SetWindowManagmentPolicyC1ERKSt8functionIFSt10unique_ptrINS_22WindowManagementPolicyESt14default_deleteIS3_EERKNS_18WindowManagerToolsEEE, |
46 | + _ZN5miral25SetWindowManagementPolicyC1ERKSt8functionIFSt10unique_ptrINS_22WindowManagementPolicyESt14default_deleteIS3_EERKNS_18WindowManagerToolsEEE) |
47 | + |
48 | +MIRAL_FAKE_OLD_SYMBOL( |
49 | + _ZNK5miral24SetWindowManagmentPolicyclERN3mir6ServerE, |
50 | + _ZNK5miral25SetWindowManagementPolicyclERN3mir6ServerE) |
51 | + |
52 | +MIRAL_FAKE_OLD_SYMBOL( |
53 | + _ZN5miral24SetWindowManagmentPolicyD1Ev, |
54 | + _ZN5miral25SetWindowManagementPolicyD1Ev) |
55 | + |
56 | +MIRAL_FAKE_OLD_SYMBOL( |
57 | + _ZN5miral24SetWindowManagmentPolicyD2Ev, |
58 | + _ZN5miral25SetWindowManagementPolicyD2Ev) |
59 | |
60 | === modified file 'miral/window_info.cpp' |
61 | --- miral/window_info.cpp 2017-08-10 16:59:22 +0000 |
62 | +++ miral/window_info.cpp 2017-09-15 13:33:35 +0000 |
63 | @@ -17,6 +17,7 @@ |
64 | */ |
65 | |
66 | #include "miral/window_info.h" |
67 | +#include "window_info_defaults.h" |
68 | |
69 | #include "both_versions.h" |
70 | |
71 | @@ -35,7 +36,40 @@ |
72 | { |
73 | return optional_value.is_set() ? optional_value.value() : default_; |
74 | } |
75 | -} |
76 | + |
77 | +unsigned clamp_dim(unsigned dim) |
78 | +{ |
79 | + return std::min<unsigned long>(std::numeric_limits<long>::max(), dim); |
80 | +} |
81 | + |
82 | +// For our convenience when doing calculations we clamp the dimensions of the aspect ratio |
83 | +// so they will fit into a long without overflow. |
84 | +miral::WindowInfo::AspectRatio clamp(miral::WindowInfo::AspectRatio const& source) |
85 | +{ |
86 | + return {clamp_dim(source.width), clamp_dim(source.height)}; |
87 | +} |
88 | + |
89 | +miral::Width clamp(miral::Width const& source) |
90 | +{ |
91 | + return std::min(miral::default_max_width, std::max(miral::default_min_width, source)); |
92 | +} |
93 | + |
94 | +miral::Height clamp(miral::Height const& source) |
95 | +{ |
96 | + return std::min(miral::default_max_height, std::max(miral::default_min_height, source)); |
97 | +} |
98 | +} |
99 | + |
100 | +miral::Width const miral::default_min_width{0}; |
101 | +miral::Height const miral::default_min_height{0}; |
102 | +miral::Width const miral::default_max_width{std::numeric_limits<int>::max()}; |
103 | +miral::Height const miral::default_max_height{std::numeric_limits<int>::max()}; |
104 | +miral::DeltaX const miral::default_width_inc{1}; |
105 | +miral::DeltaY const miral::default_height_inc{1}; |
106 | +miral::WindowInfo::AspectRatio const miral::default_min_aspect_ratio{ |
107 | + clamp(WindowInfo::AspectRatio{0U, std::numeric_limits<unsigned>::max()})}; |
108 | +miral::WindowInfo::AspectRatio const miral::default_max_aspect_ratio{ |
109 | + clamp(WindowInfo::AspectRatio{std::numeric_limits<unsigned>::max(), 0U})}; |
110 | |
111 | struct miral::WindowInfo::Self |
112 | { |
113 | @@ -71,16 +105,16 @@ |
114 | type{optional_value_or_default(params.type(), mir_window_type_normal)}, |
115 | state{optional_value_or_default(params.state(), mir_window_state_restored)}, |
116 | restore_rect{params.top_left().value(), params.size().value()}, |
117 | - min_width{optional_value_or_default(params.min_width())}, |
118 | - min_height{optional_value_or_default(params.min_height())}, |
119 | - max_width{optional_value_or_default(params.max_width(), Width{std::numeric_limits<int>::max()})}, |
120 | - max_height{optional_value_or_default(params.max_height(), Height{std::numeric_limits<int>::max()})}, |
121 | + min_width{optional_value_or_default(params.min_width(), miral::default_min_width)}, |
122 | + min_height{optional_value_or_default(params.min_height(), miral::default_min_height)}, |
123 | + max_width{optional_value_or_default(params.max_width(), miral::default_max_width)}, |
124 | + max_height{optional_value_or_default(params.max_height(), miral::default_max_height)}, |
125 | preferred_orientation{optional_value_or_default(params.preferred_orientation(), mir_orientation_mode_any)}, |
126 | confine_pointer(optional_value_or_default(params.confine_pointer(), mir_pointer_unconfined)), |
127 | - width_inc{optional_value_or_default(params.width_inc(), DeltaX{1})}, |
128 | - height_inc{optional_value_or_default(params.height_inc(), DeltaY{1})}, |
129 | - min_aspect(optional_value_or_default(params.min_aspect(), AspectRatio{0U, std::numeric_limits<unsigned>::max()})), |
130 | - max_aspect(optional_value_or_default(params.max_aspect(), AspectRatio{std::numeric_limits<unsigned>::max(), 0U})), |
131 | + width_inc{optional_value_or_default(params.width_inc(), default_width_inc)}, |
132 | + height_inc{optional_value_or_default(params.height_inc(), default_height_inc)}, |
133 | + min_aspect(optional_value_or_default(params.min_aspect(), default_min_aspect_ratio)), |
134 | + max_aspect(optional_value_or_default(params.max_aspect(), default_max_aspect_ratio)), |
135 | shell_chrome(optional_value_or_default(params.shell_chrome(), mir_shell_chrome_normal)) |
136 | { |
137 | if (params.output_id().is_set()) |
138 | @@ -450,7 +484,7 @@ |
139 | |
140 | void miral::WindowInfo::min_width(mir::geometry::Width min_width) |
141 | { |
142 | - self->min_width = min_width; |
143 | + self->min_width = clamp(min_width); |
144 | } |
145 | |
146 | auto miral::WindowInfo::min_height() const -> mir::geometry::Height |
147 | @@ -460,7 +494,7 @@ |
148 | |
149 | void miral::WindowInfo::min_height(mir::geometry::Height min_height) |
150 | { |
151 | - self->min_height = min_height; |
152 | + self->min_height = clamp(min_height); |
153 | } |
154 | |
155 | auto miral::WindowInfo::max_width() const -> mir::geometry::Width |
156 | @@ -470,7 +504,7 @@ |
157 | |
158 | void miral::WindowInfo::max_width(mir::geometry::Width max_width) |
159 | { |
160 | - self->max_width = max_width; |
161 | + self->max_width = clamp(max_width); |
162 | } |
163 | |
164 | auto miral::WindowInfo::max_height() const -> mir::geometry::Height |
165 | @@ -480,7 +514,7 @@ |
166 | |
167 | void miral::WindowInfo::max_height(mir::geometry::Height max_height) |
168 | { |
169 | - self->max_height = max_height; |
170 | + self->max_height = clamp(max_height); |
171 | } |
172 | |
173 | auto miral::WindowInfo::userdata() const -> std::shared_ptr<void> |
174 | @@ -520,7 +554,7 @@ |
175 | |
176 | void miral::WindowInfo::min_aspect(AspectRatio min_aspect) |
177 | { |
178 | - self->min_aspect = min_aspect; |
179 | + self->min_aspect = clamp(min_aspect); |
180 | } |
181 | |
182 | auto miral::WindowInfo::max_aspect() const -> AspectRatio |
183 | @@ -530,7 +564,7 @@ |
184 | |
185 | void miral::WindowInfo::max_aspect(AspectRatio max_aspect) |
186 | { |
187 | - self->max_aspect = max_aspect; |
188 | + self->max_aspect = clamp(max_aspect); |
189 | } |
190 | |
191 | bool miral::WindowInfo::has_output_id() const |
192 | |
193 | === added file 'miral/window_info_defaults.h' |
194 | --- miral/window_info_defaults.h 1970-01-01 00:00:00 +0000 |
195 | +++ miral/window_info_defaults.h 2017-09-15 13:33:35 +0000 |
196 | @@ -0,0 +1,36 @@ |
197 | +/* |
198 | + * Copyright © 2017 Canonical Ltd. |
199 | + * |
200 | + * This program is free software: you can redistribute it and/or modify it |
201 | + * under the terms of the GNU General Public License version 2 or 3, |
202 | + * as published by the Free Software Foundation. |
203 | + * |
204 | + * This program is distributed in the hope that it will be useful, |
205 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
206 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
207 | + * GNU General Public License for more details. |
208 | + * |
209 | + * You should have received a copy of the GNU General Public License |
210 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
211 | + * |
212 | + * Authored by: Alan Griffiths <alan@octopull.co.uk> |
213 | + */ |
214 | + |
215 | +#ifndef MIR_WINDOW_INFO_DEFAULTS_H |
216 | +#define MIR_WINDOW_INFO_DEFAULTS_H |
217 | + |
218 | +#include "miral/window_info.h" |
219 | + |
220 | +namespace miral |
221 | +{ |
222 | +Width extern const default_min_width; |
223 | +Height extern const default_min_height; |
224 | +Width extern const default_max_width; |
225 | +Height extern const default_max_height; |
226 | +DeltaX extern const default_width_inc; |
227 | +DeltaY extern const default_height_inc; |
228 | +WindowInfo::AspectRatio extern const default_min_aspect_ratio; |
229 | +WindowInfo::AspectRatio extern const default_max_aspect_ratio; |
230 | +} |
231 | + |
232 | +#endif //MIR_WINDOW_INFO_DEFAULTS_H |
233 | |
234 | === modified file 'miral/window_management_trace.cpp' |
235 | --- miral/window_management_trace.cpp 2017-08-10 16:59:22 +0000 |
236 | +++ miral/window_management_trace.cpp 2017-09-15 13:33:35 +0000 |
237 | @@ -17,6 +17,7 @@ |
238 | */ |
239 | |
240 | #include "window_management_trace.h" |
241 | +#include "window_info_defaults.h" |
242 | |
243 | #include <miral/application_info.h> |
244 | #include <miral/window_info.h> |
245 | @@ -133,18 +134,19 @@ |
246 | APPEND(name); |
247 | APPEND(type); |
248 | APPEND(state); |
249 | + bout.append("size", info.window().size()); |
250 | if (info.state() != mir_window_state_restored) APPEND(restore_rect); |
251 | if (std::shared_ptr<mir::scene::Surface> parent = info.parent()) |
252 | bout.append("parent", parent->name()); |
253 | bout.append("children", dump_of(info.children())); |
254 | - if (info.min_width() != Width{0}) APPEND(min_width); |
255 | - if (info.min_height() != Height{0}) APPEND(min_height); |
256 | - if (info.max_width() != Width{std::numeric_limits<int>::max()}) APPEND(max_width); |
257 | - if (info.max_height() != Height{std::numeric_limits<int>::max()}) APPEND(max_height); |
258 | - if (info.width_inc() != DeltaX{1}) APPEND(width_inc); |
259 | - if (info.height_inc() != DeltaY{1}) APPEND(height_inc); |
260 | - if (info.min_aspect() != miral::WindowInfo::AspectRatio{0U, std::numeric_limits<unsigned>::max()}) APPEND(min_aspect); |
261 | - if (info.max_aspect() != miral::WindowInfo::AspectRatio{std::numeric_limits<unsigned>::max(), 0U}) APPEND(max_aspect); |
262 | + if (info.min_width() != miral::default_min_width) APPEND(min_width); |
263 | + if (info.min_height() != miral::default_min_height) APPEND(min_height); |
264 | + if (info.max_width() != miral::default_max_width) APPEND(max_width); |
265 | + if (info.max_height() != miral::default_max_height) APPEND(max_height); |
266 | + if (info.width_inc() != miral::default_width_inc) APPEND(width_inc); |
267 | + if (info.height_inc() != miral::default_height_inc) APPEND(height_inc); |
268 | + if (info.min_aspect() != miral::default_min_aspect_ratio) APPEND(min_aspect); |
269 | + if (info.max_aspect() != miral::default_max_aspect_ratio) APPEND(max_aspect); |
270 | APPEND(preferred_orientation); |
271 | APPEND(confine_pointer); |
272 | |
273 | |
274 | === modified file 'test/CMakeLists.txt' |
275 | --- test/CMakeLists.txt 2017-04-11 11:17:34 +0000 |
276 | +++ test/CMakeLists.txt 2017-09-15 13:33:35 +0000 |
277 | @@ -55,6 +55,7 @@ |
278 | window_id.cpp |
279 | runner.cpp |
280 | select_active_window.cpp |
281 | + window_info.cpp |
282 | window_placement.cpp |
283 | window_placement_anchors_to_parent.cpp |
284 | window_placement_client_api.cpp |
285 | |
286 | === added file 'test/window_info.cpp' |
287 | --- test/window_info.cpp 1970-01-01 00:00:00 +0000 |
288 | +++ test/window_info.cpp 2017-09-15 13:33:35 +0000 |
289 | @@ -0,0 +1,61 @@ |
290 | +/* |
291 | + * Copyright © 2017 Canonical Ltd. |
292 | + * |
293 | + * This program is free software: you can redistribute it and/or modify it |
294 | + * under the terms of the GNU General Public License version 2 or 3 as |
295 | + * published by the Free Software Foundation. |
296 | + * |
297 | + * This program is distributed in the hope that it will be useful, |
298 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
299 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
300 | + * GNU General Public License for more details. |
301 | + * |
302 | + * You should have received a copy of the GNU General Public License |
303 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
304 | + * |
305 | + * Authored by: Brandon Schaefer <brandon.schaefer@canonical.com> |
306 | + */ |
307 | + |
308 | +#include <miral/window_info.h> |
309 | + |
310 | +#include "mir_test_framework/process.h" |
311 | + |
312 | +#include <gtest/gtest.h> |
313 | +#include <gmock/gmock.h> |
314 | + |
315 | +using namespace miral; |
316 | +namespace mtf = mir_test_framework; |
317 | + |
318 | +namespace |
319 | +{ |
320 | +static int a_successful_exit_function() |
321 | +{ |
322 | + return EXIT_SUCCESS; |
323 | +} |
324 | +} |
325 | + |
326 | +// Test for crash http://paste.ubuntu.com/25523431/ |
327 | +TEST(WindowInfo, negative_window_size_does_not_divide_by_zero) |
328 | +{ |
329 | + auto p = mtf::fork_and_run_in_a_different_process( |
330 | + [] { |
331 | + Window window; |
332 | + WindowSpecification params; |
333 | + |
334 | + Point p{0, 0}; |
335 | + Size s{-300, -300}; |
336 | + |
337 | + params.name() = ""; |
338 | + params.top_left() = p; |
339 | + params.size() = s; |
340 | + |
341 | + WindowInfo info(window, params); |
342 | + |
343 | + info.min_width(s.width); |
344 | + info.min_height(s.height); |
345 | + |
346 | + info.constrain_resize(p, s); |
347 | + }, a_successful_exit_function); |
348 | + |
349 | + EXPECT_TRUE(p->wait_for_termination().succeeded()); |
350 | +} |
FAILED: Continuous integration, rev:580 /mir-jenkins. ubuntu. com/job/ miral-ci/ 76/ /mir-jenkins. ubuntu. com/job/ build-miral/ 122/console /mir-jenkins. ubuntu. com/job/ build-0- fetch/5242 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= artful/ 5230 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 5230 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= zesty/5230 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- miral/arch= i386,release= artful/ 126/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- miral/arch= i386,release= xenial/ 126 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- miral/arch= i386,release= xenial/ 126/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- miral/arch= i386,release= zesty/126/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
ABORTED: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ miral-ci/ 76/rebuild
https:/