Merge lp:~xavi-garcia-mena/keeper/keeper-errors-in-state-property into lp:keeper/devel
- keeper-errors-in-state-property
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Xavi Garcia |
Approved revision: | 133 |
Merged at revision: | 125 |
Proposed branch: | lp:~xavi-garcia-mena/keeper/keeper-errors-in-state-property |
Merge into: | lp:keeper/devel |
Prerequisite: | lp:~xavi-garcia-mena/keeper/command-line-client-plus-bugs |
Diff against target: |
816 lines (+324/-27) 23 files modified
include/client/client.h (+3/-1) include/client/keeper-errors.h (+49/-0) include/helper/helper.h (+2/-0) src/cli/command-line-client-view.cpp (+54/-9) src/cli/command-line-client-view.h (+5/-2) src/client/CMakeLists.txt (+14/-0) src/client/client.cpp (+9/-1) src/client/keeper-errors.cpp (+74/-0) src/helper/backup-helper.cpp (+12/-2) src/helper/helper.cpp (+2/-1) src/helper/restore-helper.cpp (+9/-2) src/qdbus-stubs/dbus-types.h (+3/-1) src/service/CMakeLists.txt (+1/-0) src/service/keeper-task-backup.cpp (+1/-0) src/service/keeper-task.cpp (+28/-3) src/service/keeper-task.h (+4/-1) src/service/private/keeper-task_p.h (+4/-0) src/service/task-manager.cpp (+2/-1) tests/integration/helpers/helpers-test-failure.cpp (+7/-0) tests/integration/helpers/helpers-test.cc (+16/-3) tests/integration/helpers/test-helpers-base.cpp (+22/-0) tests/integration/helpers/test-helpers-base.h (+2/-0) tests/utils/CMakeLists.txt (+1/-0) |
To merge this branch: | bzr merge lp:~xavi-garcia-mena/keeper/keeper-errors-in-state-property |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
unity-api-1-bot | continuous-integration | Approve | |
Charles Kerr (community) | Approve | ||
Review via email: mp+313221@code.launchpad.net |
Commit message
This branch adds error notification in each keeper task.
Description of the change
This branch adds error notification in each keeper task.
The error is an enum located at the client headers.
I've also created a helper method in the client library that converts the enum from QDBusArgument to KeeperError (the final type).
As we return a QVariantMap in the state call it looks like Qt is not converting the type itself.
We should maybe return a own defined type and offer the user an interface to obtain the different values of the state.
unity-api-1-bot (unity-api-1-bot) wrote : | # |
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:132
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Charles Kerr (charlesk) wrote : | # |
Looks really good. As usual some minor suggestions, but less even of those than usual. Nice work.
Xavi Garcia (xavi-garcia-mena) wrote : | # |
Thanks for the review, Charles.
I did all the suggested changes
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:133
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: 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:/
unity-api-1-bot (unity-api-1-bot) : | # |
Preview Diff
1 | === modified file 'include/client/client.h' |
2 | --- include/client/client.h 2016-12-05 11:36:32 +0000 |
3 | +++ include/client/client.h 2016-12-21 08:37:30 +0000 |
4 | @@ -19,6 +19,8 @@ |
5 | |
6 | #pragma once |
7 | |
8 | +#include "keeper-errors.h" |
9 | + |
10 | #include <QObject> |
11 | #include <QScopedPointer> |
12 | #include <QStringList> |
13 | @@ -73,7 +75,7 @@ |
14 | void readyToBackupChanged(); |
15 | void backupBusyChanged(); |
16 | |
17 | - void taskStatusChanged(QString const & displayName, QString const & status, double percentage); |
18 | + void taskStatusChanged(QString const & displayName, QString const & status, double percentage, keeper::KeeperError error); |
19 | void finished(); |
20 | |
21 | private Q_SLOTS: |
22 | |
23 | === added file 'include/client/keeper-errors.h' |
24 | --- include/client/keeper-errors.h 1970-01-01 00:00:00 +0000 |
25 | +++ include/client/keeper-errors.h 2016-12-21 08:37:30 +0000 |
26 | @@ -0,0 +1,49 @@ |
27 | +/* |
28 | + * Copyright (C) 2016 Canonical, Ltd. |
29 | + * |
30 | + * This program is free software: you can redistribute it and/or modify it |
31 | + * under the terms of the GNU General Public License version 3, as published |
32 | + * by the Free Software Foundation. |
33 | + * |
34 | + * This program is distributed in the hope that it will be useful, but |
35 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
36 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
37 | + * PURPOSE. See the GNU General Public License for more details. |
38 | + * |
39 | + * You should have received a copy of the GNU General Public License along |
40 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
41 | + * |
42 | + * Authors: |
43 | + * Xavi Garcia Mena <xavi.garcia.mena@canonical.com> |
44 | + */ |
45 | + |
46 | +#pragma once |
47 | + |
48 | +#include <QDBusArgument> |
49 | +#include <QMetaType> |
50 | + |
51 | +namespace keeper |
52 | +{ |
53 | + |
54 | +enum class KeeperError |
55 | +{ |
56 | + OK, |
57 | + ERROR_UNKNOWN, |
58 | + HELPER_READ_ERROR, |
59 | + HELPER_WRITE_ERROR, |
60 | + HELPER_INACTIVITY_DETECTED, |
61 | + HELPER_SOCKET_ERROR, |
62 | + HELPER_START_TIMEOUT, |
63 | + NO_HELPER_INFORMATION_IN_REGISTRY, |
64 | + HELPER_BAD_URL, |
65 | + MANIFEST_STORAGE_ERROR, |
66 | + COMMITTING_DATA_ERROR |
67 | +}; |
68 | + |
69 | +KeeperError convertFromDBusVariant(const QVariant & value, bool *conversion_ok = nullptr); |
70 | +} // namespace keeper |
71 | + |
72 | +QDBusArgument &operator<<(QDBusArgument &argument, keeper::KeeperError value); |
73 | +const QDBusArgument &operator>>(const QDBusArgument &argument, keeper::KeeperError &val); |
74 | + |
75 | +Q_DECLARE_METATYPE(keeper::KeeperError) |
76 | |
77 | === modified file 'include/helper/helper.h' |
78 | --- include/helper/helper.h 2016-09-15 16:02:54 +0000 |
79 | +++ include/helper/helper.h 2016-12-21 08:37:30 +0000 |
80 | @@ -19,6 +19,7 @@ |
81 | |
82 | #pragma once |
83 | |
84 | +#include <client/keeper-errors.h> |
85 | #include <util/attributes.h> |
86 | |
87 | #include <QObject> |
88 | @@ -69,6 +70,7 @@ |
89 | Q_SIGNALS: |
90 | void state_changed(Helper::State); |
91 | void percent_done_changed(float); |
92 | + void error(keeper::KeeperError error); |
93 | |
94 | protected: |
95 | Helper(QString const & appid, const clock_func& clock=default_clock, QObject *parent=nullptr); |
96 | |
97 | === modified file 'src/cli/command-line-client-view.cpp' |
98 | --- src/cli/command-line-client-view.cpp 2016-12-01 14:18:57 +0000 |
99 | +++ src/cli/command-line-client-view.cpp 2016-12-21 08:37:30 +0000 |
100 | @@ -48,7 +48,7 @@ |
101 | |
102 | void CommandLineClientView::add_task(QString const & display_name, QString const & initial_status, double initial_percentage) |
103 | { |
104 | - tasks_strings_[display_name] = get_task_string(display_name, initial_status, initial_percentage); |
105 | + tasks_strings_[display_name] = get_task_string(display_name, initial_status, initial_percentage, keeper::KeeperError::OK); |
106 | // TODO see if we can do this in a better way |
107 | // We add a line per each backup task |
108 | std::cout << std::endl; |
109 | @@ -112,17 +112,62 @@ |
110 | return ret; |
111 | } |
112 | |
113 | -QString CommandLineClientView::get_task_string(QString const & displayName, QString const & status, double percentage) |
114 | -{ |
115 | - |
116 | - return QStringLiteral("%1 %2 % %3").arg(displayName, 15).arg((percentage * 100), 10, 'f', 2, ' ').arg(status, -15); |
117 | -} |
118 | - |
119 | -void CommandLineClientView::on_task_state_changed(QString const & displayName, QString const & status, double percentage) |
120 | +QString CommandLineClientView::get_task_string(QString const & displayName, QString const & status, double percentage, keeper::KeeperError error) |
121 | +{ |
122 | + |
123 | + if (error == keeper::KeeperError::OK) |
124 | + return QStringLiteral("%1 %2 % %3").arg(displayName, 15).arg((percentage * 100), 10, 'f', 2, ' ').arg(status, -15); |
125 | + else |
126 | + return QStringLiteral("%1 %2 % %3 %4").arg(displayName, 15).arg((percentage * 100), 10, 'f', 2, ' ').arg(status, -15).arg(get_error_string(error)); |
127 | +} |
128 | + |
129 | +QString CommandLineClientView::get_error_string(keeper::KeeperError error) |
130 | +{ |
131 | + QString ret; |
132 | + switch(error) |
133 | + { |
134 | + case keeper::KeeperError::ERROR_UNKNOWN: |
135 | + ret = QStringLiteral("Unknown error"); |
136 | + break; |
137 | + case keeper::KeeperError::HELPER_BAD_URL: |
138 | + ret = QStringLiteral("Bad URL for keeper helper"); |
139 | + break; |
140 | + case keeper::KeeperError::HELPER_INACTIVITY_DETECTED: |
141 | + ret = QStringLiteral("Inactivity detected in task"); |
142 | + break; |
143 | + case keeper::KeeperError::HELPER_START_TIMEOUT: |
144 | + ret = QStringLiteral("Task failed to start"); |
145 | + break; |
146 | + case keeper::KeeperError::HELPER_READ_ERROR: |
147 | + ret = QStringLiteral("Read error"); |
148 | + break; |
149 | + case keeper::KeeperError::HELPER_SOCKET_ERROR: |
150 | + ret = QStringLiteral("Error creating internal socket"); |
151 | + break; |
152 | + case keeper::KeeperError::HELPER_WRITE_ERROR: |
153 | + ret = QStringLiteral("Write error"); |
154 | + break; |
155 | + case keeper::KeeperError::MANIFEST_STORAGE_ERROR: |
156 | + ret = QStringLiteral("Error storing manifest file"); |
157 | + break; |
158 | + case keeper::KeeperError::NO_HELPER_INFORMATION_IN_REGISTRY: |
159 | + ret = QStringLiteral("No helper information in registry"); |
160 | + break; |
161 | + case keeper::KeeperError::OK: |
162 | + ret = QStringLiteral("Success"); |
163 | + break; |
164 | + case keeper::KeeperError::COMMITTING_DATA_ERROR: |
165 | + ret = QStringLiteral("Error uploading data"); |
166 | + break; |
167 | + } |
168 | + return ret; |
169 | +} |
170 | + |
171 | +void CommandLineClientView::on_task_state_changed(QString const & displayName, QString const & status, double percentage, keeper::KeeperError error) |
172 | { |
173 | auto iter = tasks_strings_.find(displayName); |
174 | if (iter != tasks_strings_.end()) |
175 | { |
176 | - tasks_strings_[displayName] = get_task_string(displayName, status, percentage); |
177 | + tasks_strings_[displayName] = get_task_string(displayName, status, percentage, error); |
178 | } |
179 | } |
180 | |
181 | === modified file 'src/cli/command-line-client-view.h' |
182 | --- src/cli/command-line-client-view.h 2016-11-30 14:46:29 +0000 |
183 | +++ src/cli/command-line-client-view.h 2016-12-21 08:37:30 +0000 |
184 | @@ -18,6 +18,8 @@ |
185 | */ |
186 | #pragma once |
187 | |
188 | +#include <client/keeper-errors.h> |
189 | + |
190 | #include <QMap> |
191 | #include <QObject> |
192 | #include <QTimer> |
193 | @@ -43,11 +45,12 @@ |
194 | |
195 | public Q_SLOTS: |
196 | void show_info(); |
197 | - void on_task_state_changed(QString const & displayName, QString const & status, double percentage); |
198 | + void on_task_state_changed(QString const & displayName, QString const & status, double percentage, keeper::KeeperError error); |
199 | |
200 | private: |
201 | char get_next_spin_char(); |
202 | - QString get_task_string(QString const & displayName, QString const & status, double percentage); |
203 | + QString get_task_string(QString const & displayName, QString const & status, double percentage, keeper::KeeperError error); |
204 | + QString get_error_string(keeper::KeeperError error); |
205 | |
206 | QString status_; |
207 | QTimer timer_status_; |
208 | |
209 | === modified file 'src/client/CMakeLists.txt' |
210 | --- src/client/CMakeLists.txt 2016-11-30 14:46:29 +0000 |
211 | +++ src/client/CMakeLists.txt 2016-12-21 08:37:30 +0000 |
212 | @@ -1,8 +1,21 @@ |
213 | add_subdirectory(qml-plugin) |
214 | |
215 | set( |
216 | + KEEPER_ERRORS_LIB |
217 | + keeper-errors-lib |
218 | +) |
219 | + |
220 | +add_library( |
221 | + ${KEEPER_ERRORS_LIB} |
222 | + STATIC |
223 | + keeper-errors.cpp |
224 | + ${CMAKE_SOURCE_DIR}/include/client/keeper-errors.h |
225 | +) |
226 | + |
227 | +set( |
228 | CLIENT_HEADERS |
229 | ${CMAKE_SOURCE_DIR}/include/client/client.h |
230 | + ${CMAKE_SOURCE_DIR}/include/client/keeper-errors.h |
231 | ) |
232 | |
233 | add_library( |
234 | @@ -18,6 +31,7 @@ |
235 | |
236 | target_link_libraries( |
237 | ${KEEPER_CLIENT_LIB} |
238 | + ${KEEPER_ERRORS_LIB} |
239 | qdbus-stubs |
240 | Qt5::Core |
241 | Qt5::DBus |
242 | |
243 | === modified file 'src/client/client.cpp' |
244 | --- src/client/client.cpp 2016-12-16 09:34:05 +0000 |
245 | +++ src/client/client.cpp 2016-12-21 08:37:30 +0000 |
246 | @@ -281,12 +281,20 @@ |
247 | double progress = state.value("percent-done").toDouble(); |
248 | auto status = state.value("action").toString(); |
249 | |
250 | + keeper::KeeperError keeper_error = keeper::KeeperError::OK; |
251 | + auto iter_error = state.find("error"); |
252 | + if (iter_error != state.end()) |
253 | + { |
254 | + bool conversion_ok; |
255 | + keeper_error = keeper::convertFromDBusVariant(state.value("error"), &conversion_ok); |
256 | + } |
257 | + |
258 | auto current_state = d->task_status[uuid]; |
259 | if (current_state.status != status || current_state.percentage < progress) |
260 | { |
261 | d->task_status[uuid].status = status; |
262 | d->task_status[uuid].percentage = progress; |
263 | - Q_EMIT(taskStatusChanged(state.value("display-name").toString(), status, progress)); |
264 | + Q_EMIT(taskStatusChanged(state.value("display-name").toString(), status, progress, keeper_error)); |
265 | } |
266 | } |
267 | |
268 | |
269 | === added file 'src/client/keeper-errors.cpp' |
270 | --- src/client/keeper-errors.cpp 1970-01-01 00:00:00 +0000 |
271 | +++ src/client/keeper-errors.cpp 2016-12-21 08:37:30 +0000 |
272 | @@ -0,0 +1,74 @@ |
273 | +/* |
274 | + * Copyright (C) 2016 Canonical, Ltd. |
275 | + * |
276 | + * This program is free software: you can redistribute it and/or modify it |
277 | + * under the terms of the GNU General Public License version 3, as published |
278 | + * by the Free Software Foundation. |
279 | + * |
280 | + * This program is distributed in the hope that it will be useful, but |
281 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
282 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
283 | + * PURPOSE. See the GNU General Public License for more details. |
284 | + * |
285 | + * You should have received a copy of the GNU General Public License along |
286 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
287 | + * |
288 | + * Authors: |
289 | + * Xavi Garcia <xavi.garcia.mena@canonical.com> |
290 | + */ |
291 | + |
292 | +#include <client/keeper-errors.h> |
293 | + |
294 | +#include <QDebug> |
295 | + |
296 | +QDBusArgument &operator<<(QDBusArgument &argument, keeper::KeeperError value) |
297 | +{ |
298 | + argument.beginStructure(); |
299 | + argument << static_cast<int>(value); |
300 | + argument.endStructure(); |
301 | + return argument; |
302 | +} |
303 | + |
304 | +const QDBusArgument &operator>>(const QDBusArgument &argument, keeper::KeeperError &val) |
305 | +{ |
306 | + int int_val; |
307 | + argument.beginStructure(); |
308 | + argument >> int_val; |
309 | + val = static_cast<keeper::KeeperError>(int_val); |
310 | + argument.endStructure(); |
311 | + return argument; |
312 | +} |
313 | + |
314 | +namespace keeper |
315 | +{ |
316 | +KeeperError convertFromDBusVariant(const QVariant & value, bool *conversion_ok) |
317 | +{ |
318 | + if (value.typeName() != QStringLiteral("QDBusArgument")) |
319 | + { |
320 | + qWarning() << Q_FUNC_INFO |
321 | + << " Error converting dbus QVariant to KeeperError, expected type is [ QDBusArgument ] and current type is: [" |
322 | + << value.typeName() << "]"; |
323 | + if (conversion_ok) |
324 | + *conversion_ok = false; |
325 | + return KeeperError(keeper::KeeperError::ERROR_UNKNOWN); |
326 | + } |
327 | + auto dbus_arg = value.value<QDBusArgument>(); |
328 | + |
329 | + if (dbus_arg.currentSignature() != "(i)") |
330 | + { |
331 | + qWarning() << Q_FUNC_INFO |
332 | + << " Error converting dbus QVariant to KeeperError, expected signature is \"(i)\" and current signature is: \"" |
333 | + << dbus_arg.currentSignature() << "\""; |
334 | + if (conversion_ok) |
335 | + *conversion_ok = false; |
336 | + return KeeperError(keeper::KeeperError::ERROR_UNKNOWN); |
337 | + } |
338 | + KeeperError ret; |
339 | + dbus_arg >> ret; |
340 | + |
341 | + if (conversion_ok) |
342 | + *conversion_ok = true; |
343 | + |
344 | + return ret; |
345 | +} |
346 | +} |
347 | |
348 | === modified file 'src/helper/backup-helper.cpp' |
349 | --- src/helper/backup-helper.cpp 2016-10-06 14:53:44 +0000 |
350 | +++ src/helper/backup-helper.cpp 2016-12-21 08:37:30 +0000 |
351 | @@ -62,8 +62,8 @@ |
352 | int rc = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds); |
353 | if (rc == -1) |
354 | { |
355 | - // TODO throw exception. |
356 | - qWarning() << "BackupHelperPrivate: error creating socket pair to communicate with helper "; |
357 | + qWarning() << QStringLiteral("Error creating socket to communicate with helper");; |
358 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_SOCKET_ERROR)); |
359 | return; |
360 | } |
361 | |
362 | @@ -140,7 +140,10 @@ |
363 | std::function<void(bool)>{[this](bool success){ |
364 | qDebug() << "Commit finished"; |
365 | if (!success) |
366 | + { |
367 | write_error_ = true; |
368 | + Q_EMIT(q_ptr->error(keeper::KeeperError::COMMITTING_DATA_ERROR)); |
369 | + } |
370 | else |
371 | uploader_committed_file_name_ = uploader_->file_name(); |
372 | uploader_.reset(); |
373 | @@ -175,6 +178,7 @@ |
374 | { |
375 | stop_inactivity_timer(); |
376 | qWarning() << "Inactivity detected in the helper...stopping it"; |
377 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_INACTIVITY_DETECTED)); |
378 | stop(); |
379 | } |
380 | |
381 | @@ -212,6 +216,7 @@ |
382 | } |
383 | else if (n < 0) { |
384 | read_error_ = true; |
385 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_READ_ERROR)); |
386 | stop(); |
387 | return; |
388 | } |
389 | @@ -228,6 +233,7 @@ |
390 | if (n < 0) { |
391 | write_error_ = true; |
392 | qWarning() << "Write error:" << socket->errorString(); |
393 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_WRITE_ERROR)); |
394 | stop(); |
395 | } |
396 | break; |
397 | @@ -258,6 +264,10 @@ |
398 | { |
399 | if (!q_ptr->is_helper_running()) |
400 | { |
401 | + if (n_uploaded_ > q_ptr->expected_size()) |
402 | + { |
403 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_WRITE_ERROR)); |
404 | + } |
405 | q_ptr->set_state(Helper::State::FAILED); |
406 | } |
407 | } |
408 | |
409 | === modified file 'src/helper/helper.cpp' |
410 | --- src/helper/helper.cpp 2016-11-21 12:03:56 +0000 |
411 | +++ src/helper/helper.cpp 2016-12-21 08:37:30 +0000 |
412 | @@ -359,7 +359,8 @@ |
413 | |
414 | void on_max_time_waiting_for_ual_started() |
415 | { |
416 | - qDebug() << "Max time reached waiting for UAL to start"; |
417 | + qWarning() << "Maximum time reached waiting for the helper to start."; |
418 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_START_TIMEOUT)); |
419 | q_ptr->set_state(Helper::State::FAILED); |
420 | stop_wait_for_ual_timer(); |
421 | } |
422 | |
423 | === modified file 'src/helper/restore-helper.cpp' |
424 | --- src/helper/restore-helper.cpp 2016-12-05 11:36:32 +0000 |
425 | +++ src/helper/restore-helper.cpp 2016-12-21 08:37:30 +0000 |
426 | @@ -57,8 +57,8 @@ |
427 | int rc = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds); |
428 | if (rc == -1) |
429 | { |
430 | - // TODO throw exception. |
431 | - qWarning() << "RestoreHelperPrivate: error creating socket pair to communicate with helper "; |
432 | + qWarning() << QStringLiteral("Error creating socket to communicate with helper");; |
433 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_SOCKET_ERROR)); |
434 | return; |
435 | } |
436 | |
437 | @@ -167,6 +167,7 @@ |
438 | { |
439 | stop_inactivity_timer(); |
440 | qWarning() << "Inactivity detected in the helper...stopping it"; |
441 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_INACTIVITY_DETECTED)); |
442 | stop(); |
443 | } |
444 | |
445 | @@ -207,6 +208,7 @@ |
446 | else if (n < 0) { |
447 | read_error_ = true; |
448 | qDebug() << "Read error in restore helper: " << socket->errorString(); |
449 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_READ_ERROR)); |
450 | stop(); |
451 | return; |
452 | } |
453 | @@ -226,6 +228,7 @@ |
454 | if (n < 0) { |
455 | write_error_ = true; |
456 | qWarning() << "Write error:" << write_socket_.errorString(); |
457 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_WRITE_ERROR)); |
458 | stop(); |
459 | } |
460 | break; |
461 | @@ -257,6 +260,10 @@ |
462 | { |
463 | if (!q_ptr->is_helper_running()) |
464 | { |
465 | + if (n_uploaded_ > q_ptr->expected_size()) |
466 | + { |
467 | + Q_EMIT(q_ptr->error(keeper::KeeperError::HELPER_WRITE_ERROR)); |
468 | + } |
469 | q_ptr->set_state(Helper::State::FAILED); |
470 | } |
471 | } |
472 | |
473 | === modified file 'src/qdbus-stubs/dbus-types.h' |
474 | --- src/qdbus-stubs/dbus-types.h 2016-11-30 14:46:29 +0000 |
475 | +++ src/qdbus-stubs/dbus-types.h 2016-12-21 08:37:30 +0000 |
476 | @@ -22,6 +22,7 @@ |
477 | #include <QtCore> |
478 | #include <QString> |
479 | #include <QVariantMap> |
480 | +#include <client/keeper-errors.h> |
481 | |
482 | typedef QMap<QString, QVariantMap> QVariantDictMap; |
483 | Q_DECLARE_METATYPE(QVariantDictMap) |
484 | @@ -35,10 +36,11 @@ |
485 | { |
486 | qRegisterMetaType<QVariantDictMap>("QVariantDictMap"); |
487 | qRegisterMetaType<QStringMap>("QStringMap"); |
488 | + qRegisterMetaType<keeper::KeeperError>("keeper::KeeperError"); |
489 | |
490 | qDBusRegisterMetaType<QVariantDictMap>(); |
491 | qDBusRegisterMetaType<QStringMap>(); |
492 | -// Helper::registerMetaTypes(); |
493 | + qDBusRegisterMetaType<keeper::KeeperError>(); |
494 | } |
495 | |
496 | constexpr const char KEEPER_SERVICE[] = "com.canonical.keeper"; |
497 | |
498 | === modified file 'src/service/CMakeLists.txt' |
499 | --- src/service/CMakeLists.txt 2016-11-11 14:50:06 +0000 |
500 | +++ src/service/CMakeLists.txt 2016-12-21 08:37:30 +0000 |
501 | @@ -49,6 +49,7 @@ |
502 | storage-framework |
503 | util |
504 | qdbus-stubs |
505 | + keeper-errors-lib |
506 | ) |
507 | |
508 | target_link_libraries( |
509 | |
510 | === modified file 'src/service/keeper-task-backup.cpp' |
511 | --- src/service/keeper-task-backup.cpp 2016-11-08 09:03:09 +0000 |
512 | +++ src/service/keeper-task-backup.cpp 2016-12-21 08:37:30 +0000 |
513 | @@ -50,6 +50,7 @@ |
514 | qDebug() << "Initializing a backup helper"; |
515 | helper_.reset(new BackupHelper(DEKKO_APP_ID), [](Helper *h){h->deleteLater();}); |
516 | qDebug() << "Helper " << static_cast<void*>(helper_.data()) << " was created"; |
517 | + QObject::connect(helper_.data(), &Helper::error, [this](keeper::KeeperError error){ error_ = error;}); |
518 | } |
519 | |
520 | void ask_for_uploader(quint64 n_bytes, QString const & dir_name) |
521 | |
522 | === modified file 'src/service/keeper-task.cpp' |
523 | --- src/service/keeper-task.cpp 2016-11-08 09:03:09 +0000 |
524 | +++ src/service/keeper-task.cpp 2016-12-21 08:37:30 +0000 |
525 | @@ -35,6 +35,7 @@ |
526 | , task_data_(task_data) |
527 | , helper_registry_(helper_registry) |
528 | , storage_(storage) |
529 | + , error_(keeper::KeeperError::OK) |
530 | { |
531 | } |
532 | |
533 | @@ -49,8 +50,8 @@ |
534 | if (urls.isEmpty()) |
535 | { |
536 | task_data_.action = helper_->to_string(Helper::State::FAILED); |
537 | - task_data_.error = "no helper information in registry"; |
538 | - qWarning() << "ERROR: uuid: " << task_data_.metadata.uuid() << " has no url"; |
539 | + error_ = keeper::KeeperError::HELPER_BAD_URL; |
540 | + qWarning() << QStringLiteral("Error: uuid %1 has no url").arg(task_data_.metadata.uuid()); |
541 | calculate_and_notify_state(Helper::State::FAILED); |
542 | return false; |
543 | } |
544 | @@ -65,6 +66,10 @@ |
545 | std::bind(&KeeperTaskPrivate::on_helper_percent_done_changed, this, std::placeholders::_1) |
546 | ); |
547 | |
548 | + QObject::connect(helper_.data(), &Helper::error, [this](keeper::KeeperError error){ |
549 | + error_ = error; |
550 | + }); |
551 | + |
552 | helper_->start(urls); |
553 | return true; |
554 | } |
555 | @@ -132,8 +137,16 @@ |
556 | auto const percent_done = helper_->percent_done(); |
557 | ret.insert(QStringLiteral("percent-done"), double(percent_done)); |
558 | |
559 | + qDebug() << "task_data_.action = " << task_data_.action; |
560 | if (task_data_.action == "failed" || task_data_.action == "cancelled") |
561 | - ret.insert(QStringLiteral("error"), task_data_.error); |
562 | + { |
563 | + auto error = error_; |
564 | + if (task_data_.error != keeper::KeeperError::OK) |
565 | + { |
566 | + error = task_data_.error; |
567 | + } |
568 | + ret.insert(QStringLiteral("error"), qVariantFromValue(error)); |
569 | + } |
570 | |
571 | ret.insert(QStringLiteral("uuid"), uuid); |
572 | |
573 | @@ -193,6 +206,11 @@ |
574 | } |
575 | } |
576 | |
577 | +keeper::KeeperError KeeperTaskPrivate::error() const |
578 | +{ |
579 | + return error_; |
580 | +} |
581 | + |
582 | KeeperTask::KeeperTask(TaskData & task_data, |
583 | QSharedPointer<HelperRegistry> const & helper_registry, |
584 | QSharedPointer<StorageFrameworkClient> const & storage, |
585 | @@ -251,3 +269,10 @@ |
586 | |
587 | return d->to_string(state); |
588 | } |
589 | + |
590 | +keeper::KeeperError KeeperTask::error() const |
591 | +{ |
592 | + Q_D(const KeeperTask); |
593 | + |
594 | + return d->error(); |
595 | +} |
596 | |
597 | === modified file 'src/service/keeper-task.h' |
598 | --- src/service/keeper-task.h 2016-11-08 09:03:09 +0000 |
599 | +++ src/service/keeper-task.h 2016-12-21 08:37:30 +0000 |
600 | @@ -20,6 +20,7 @@ |
601 | |
602 | #pragma once |
603 | |
604 | +#include "client/keeper-errors.h" |
605 | #include "helper/metadata.h" |
606 | #include "helper/backup-helper.h" |
607 | #include "helper/helper.h" |
608 | @@ -40,7 +41,7 @@ |
609 | struct TaskData |
610 | { |
611 | QString action; |
612 | - QString error; |
613 | + keeper::KeeperError error; |
614 | Metadata metadata; |
615 | }; |
616 | |
617 | @@ -61,6 +62,8 @@ |
618 | void cancel(); |
619 | |
620 | QString to_string(Helper::State state); |
621 | + |
622 | + keeper::KeeperError error() const; |
623 | Q_SIGNALS: |
624 | void task_state_changed(Helper::State state); |
625 | void task_socket_ready(int socket_descriptor); |
626 | |
627 | === modified file 'src/service/private/keeper-task_p.h' |
628 | --- src/service/private/keeper-task_p.h 2016-11-08 09:03:09 +0000 |
629 | +++ src/service/private/keeper-task_p.h 2016-12-21 08:37:30 +0000 |
630 | @@ -41,6 +41,9 @@ |
631 | static QVariantMap get_initial_state(KeeperTask::TaskData const &td); |
632 | |
633 | QString to_string(Helper::State state); |
634 | + |
635 | + keeper::KeeperError error() const; |
636 | + |
637 | protected: |
638 | void set_current_task_action(QString const& action); |
639 | void on_helper_percent_done_changed(float percent_done); |
640 | @@ -57,4 +60,5 @@ |
641 | QSharedPointer<StorageFrameworkClient> storage_; |
642 | QSharedPointer<Helper> helper_; |
643 | QVariantMap state_; |
644 | + keeper::KeeperError error_; |
645 | }; |
646 | |
647 | === modified file 'src/service/task-manager.cpp' |
648 | --- src/service/task-manager.cpp 2016-12-01 14:18:57 +0000 |
649 | +++ src/service/task-manager.cpp 2016-12-21 08:37:30 +0000 |
650 | @@ -147,6 +147,7 @@ |
651 | auto& td = task_data_[uuid]; |
652 | td.metadata = metadata; |
653 | td.action = QStringLiteral("queued"); // TODO i18n |
654 | + td.error = keeper::KeeperError::OK; |
655 | set_initial_task_state(td); |
656 | } |
657 | |
658 | @@ -169,7 +170,7 @@ |
659 | } |
660 | else |
661 | { |
662 | - td.error = "Error storing manifest file"; |
663 | + td.error = keeper::KeeperError::MANIFEST_STORAGE_ERROR; |
664 | set_current_task_action(task_->to_string(Helper::State::FAILED)); |
665 | } |
666 | active_manifest_.reset(); |
667 | |
668 | === modified file 'tests/integration/helpers/helpers-test-failure.cpp' |
669 | --- tests/integration/helpers/helpers-test-failure.cpp 2016-09-29 13:49:14 +0000 |
670 | +++ tests/integration/helpers/helpers-test-failure.cpp 2016-12-21 08:37:30 +0000 |
671 | @@ -90,6 +90,13 @@ |
672 | // this one uses pooling so it should just call Get once |
673 | EXPECT_TRUE(wait_for_all_tasks_have_action_state({user_folder_uuid}, "failed", user_iface)); |
674 | |
675 | + QVariant error_value; |
676 | + EXPECT_TRUE(get_task_property_now(user_folder_uuid, user_iface, "error", error_value)); |
677 | + bool conversion_ok; |
678 | + auto keeper_error = keeper::convertFromDBusVariant(error_value, &conversion_ok); |
679 | + EXPECT_TRUE(conversion_ok); |
680 | + EXPECT_EQ(keeper_error, keeper::KeeperError::HELPER_WRITE_ERROR); |
681 | + |
682 | // check that the content of the file is the expected |
683 | EXPECT_EQ(0, StorageFrameworkLocalUtils::check_storage_framework_nb_files()); |
684 | |
685 | |
686 | === modified file 'tests/integration/helpers/helpers-test.cc' |
687 | --- tests/integration/helpers/helpers-test.cc 2016-11-22 09:37:40 +0000 |
688 | +++ tests/integration/helpers/helpers-test.cc 2016-12-21 08:37:30 +0000 |
689 | @@ -41,6 +41,7 @@ |
690 | BackupHelper helper("com.test.multiple_first_1.2.3"); |
691 | |
692 | QSignalSpy spy(&helper, &BackupHelper::state_changed); |
693 | + QSignalSpy spy_error(&helper, &Helper::error); |
694 | |
695 | helper.start({"/bin/ls","/tmp"}); |
696 | |
697 | @@ -53,6 +54,8 @@ |
698 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::STARTED); |
699 | arguments = spy.takeFirst(); |
700 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::COMPLETE); |
701 | + |
702 | + EXPECT_EQ(spy_error.count(), 0); |
703 | } |
704 | |
705 | TEST_F(TestHelpers, StartFullTest) |
706 | @@ -300,15 +303,20 @@ |
707 | BackupHelper helper("com.bar_foo_8432.13.1"); |
708 | |
709 | QSignalSpy spy(&helper, &BackupHelper::state_changed); |
710 | + QSignalSpy spy_error(&helper, &Helper::error); |
711 | QStringList urls; |
712 | urls << "blah" << "/tmp"; |
713 | helper.start(urls); |
714 | |
715 | WAIT_FOR_SIGNALS(spy, 1, Helper::MAX_UAL_WAIT_TIME + 1000); |
716 | |
717 | - ASSERT_EQ(spy.count(), 1); |
718 | + ASSERT_EQ(1, spy.count()); |
719 | QList<QVariant> arguments = spy.takeFirst(); |
720 | - EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::FAILED); |
721 | + EXPECT_EQ(Helper::State::FAILED, qvariant_cast<Helper::State>(arguments.at(0))); |
722 | + |
723 | + ASSERT_EQ(1, spy_error.count()); |
724 | + arguments = spy_error.takeFirst(); |
725 | + EXPECT_EQ(keeper::KeeperError::HELPER_START_TIMEOUT, qvariant_cast<keeper::KeeperError>(arguments.at(0))); |
726 | } |
727 | |
728 | TEST_F(TestHelpers, Inactivity) |
729 | @@ -319,6 +327,7 @@ |
730 | BackupHelper helper("com.bar_foo_8432.13.1"); |
731 | |
732 | QSignalSpy spy(&helper, &BackupHelper::state_changed); |
733 | + QSignalSpy spy_error(&helper, &Helper::error); |
734 | QStringList urls; |
735 | urls << TEST_INACTIVE_HELPER << "/tmp"; |
736 | helper.start(urls); |
737 | @@ -329,9 +338,13 @@ |
738 | // We can also check at the end for the state, which should be CANCELLED |
739 | WAIT_FOR_SIGNALS(spy, 2, BackupHelper::MAX_INACTIVITY_TIME + 2000); |
740 | |
741 | - ASSERT_EQ(spy.count(), 2); |
742 | + ASSERT_EQ(2, spy.count()); |
743 | QList<QVariant> arguments = spy.takeFirst(); |
744 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::STARTED); |
745 | arguments = spy.takeFirst(); |
746 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::CANCELLED); |
747 | + |
748 | + ASSERT_EQ(1, spy_error.count()); |
749 | + arguments = spy_error.takeFirst(); |
750 | + EXPECT_EQ(keeper::KeeperError::HELPER_INACTIVITY_DETECTED, qvariant_cast<keeper::KeeperError>(arguments.at(0))); |
751 | } |
752 | |
753 | === modified file 'tests/integration/helpers/test-helpers-base.cpp' |
754 | --- tests/integration/helpers/test-helpers-base.cpp 2016-11-11 14:50:06 +0000 |
755 | +++ tests/integration/helpers/test-helpers-base.cpp 2016-12-21 08:37:30 +0000 |
756 | @@ -368,6 +368,7 @@ |
757 | void TestHelpersBase::SetUp() |
758 | { |
759 | Helper::registerMetaTypes(); |
760 | + DBusTypes::registerMetaTypes(); |
761 | |
762 | g_setenv("XDG_DATA_DIRS", CMAKE_SOURCE_DIR, true); |
763 | g_setenv("XDG_CACHE_HOME", CMAKE_SOURCE_DIR "/libertine-data", true); |
764 | @@ -440,6 +441,27 @@ |
765 | return finished; |
766 | } |
767 | |
768 | +bool TestHelpersBase::get_task_property_now(QString const & uuid, QSharedPointer<DBusInterfaceKeeperUser> const & keeper_user_iface, QString const & property, QVariant & value) const |
769 | +{ |
770 | + auto state = keeper_user_iface->state(); |
771 | + auto iter = state.find(uuid); |
772 | + if (iter == state.end()) |
773 | + { |
774 | + qWarning() << "Task " << uuid << " was not found in State"; |
775 | + return false; |
776 | + } |
777 | + |
778 | + auto iter_props = (*iter).find(property); |
779 | + if (iter_props == (*iter).end()) |
780 | + { |
781 | + qWarning() << "Property " << property << " was not found for task " << uuid; |
782 | + return false; |
783 | + } |
784 | + |
785 | + value = (*iter_props); |
786 | + return true; |
787 | +} |
788 | + |
789 | bool TestHelpersBase::check_task_has_action_state(QVariantDictMap const & state, QString const & uuid, QString const & action_state) |
790 | { |
791 | auto iter = state.find(uuid); |
792 | |
793 | === modified file 'tests/integration/helpers/test-helpers-base.h' |
794 | --- tests/integration/helpers/test-helpers-base.h 2016-10-14 09:23:11 +0000 |
795 | +++ tests/integration/helpers/test-helpers-base.h 2016-12-21 08:37:30 +0000 |
796 | @@ -97,6 +97,8 @@ |
797 | |
798 | bool check_task_has_action_state(QVariantDictMap const & state, QString const & uuid, QString const & action_state); |
799 | |
800 | + bool get_task_property_now(QString const & uuid, QSharedPointer<DBusInterfaceKeeperUser> const & keeper_user_iface, QString const & property, QVariant & value) const; |
801 | + |
802 | bool capture_and_check_state_until_all_tasks_complete(QSignalSpy & spy, QStringList const & uuids, QString const & action_state, int max_timeout_msec = 15000); |
803 | |
804 | bool cancel_first_task_at_percentage(QSignalSpy & spy, double expected_percentage, QSharedPointer<DBusInterfaceKeeperUser> const & user_iface, int max_timeout_msec = 15000); |
805 | |
806 | === modified file 'tests/utils/CMakeLists.txt' |
807 | --- tests/utils/CMakeLists.txt 2016-09-29 13:49:14 +0000 |
808 | +++ tests/utils/CMakeLists.txt 2016-12-21 08:37:30 +0000 |
809 | @@ -19,6 +19,7 @@ |
810 | target_link_libraries( |
811 | ${LIB_NAME} |
812 | backup-helper |
813 | + keeper-errors-lib |
814 | util |
815 | Qt5::Core |
816 | ) |
PASSED: Continuous integration, rev:131 /jenkins. canonical. com/unity- api-1/job/ lp-keeper- ci/150/ /jenkins. canonical. com/unity- api-1/job/ build/1268 /jenkins. canonical. com/unity- api-1/job/ build-0- fetch/1275 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1056 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1056/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= zesty/1056 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= zesty/1056/ artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1056 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1056/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= zesty/1056 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= zesty/1056/ artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1056 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1056/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= zesty/1056 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= zesty/1056/ artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/unity- api-1/job/ lp-keeper- ci/150/ rebuild
https:/