Merge lp:~xavi-garcia-mena/keeper/keeper-errors-in-state-property into lp:keeper/devel

Proposed by Xavi Garcia
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
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.

To post a comment you must log in.
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:131
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/150/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1268
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1275
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1056
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1056/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1056
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1056/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1056
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1056/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1056
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1056/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1056
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1056/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1056
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1056/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/150/rebuild

review: Approve (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:132
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/151/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1269
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1276
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1057
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1057/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1057
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1057/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1057
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1057/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1057
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1057/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1057
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1057/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1057
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1057/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/151/rebuild

review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Looks really good. As usual some minor suggestions, but less even of those than usual. Nice work.

review: Approve
Revision history for this message
Xavi Garcia (xavi-garcia-mena) wrote :

Thanks for the review, Charles.

I did all the suggested changes

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:133
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/157/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1288
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1295
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1076
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1076/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1076
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1076/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1076
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1076/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1076
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1076/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1076
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1076/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1076
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1076/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/157/rebuild

review: Approve (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Autolanding.
More details in the following jenkins job:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-autoland/21/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1289/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1296
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1077
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1077/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1077
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1077/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1077/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1077
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1077/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1077
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1077/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1077
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1077/artifact/output/*zip*/output.zip

review: Needs Fixing (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Autolanding.
More details in the following jenkins job:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-autoland/22/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1290/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1297
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1078
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1078/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1078
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1078/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1078
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1078/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1078
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1078/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1078
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1078/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1078/console

review: Needs Fixing (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 )

Subscribers

People subscribed via source and target branches

to all changes: