Merge lp:~unity-api-team/keeper/restore into lp:keeper/devel
- restore
- Merge into devel
Status: | Needs review |
---|---|
Proposed branch: | lp:~unity-api-team/keeper/restore |
Merge into: | lp:keeper/devel |
Diff against target: |
3175 lines (+1957/-302) 52 files modified
data/helper-registry.json.in (+6/-1) include/helper/data-dir-registry.h (+2/-0) include/helper/metadata.h (+1/-0) include/helper/registry.h (+1/-0) include/helper/restore-helper.h (+61/-0) src/CMakeLists.txt (+1/-0) src/cli/main.cpp (+42/-0) src/helper/CMakeLists.txt (+2/-0) src/helper/data-dir-registry.cpp (+43/-9) src/helper/helper.cpp (+2/-2) src/helper/metadata.cpp (+1/-0) src/helper/restore-helper.cpp (+378/-0) src/service/CMakeLists.txt (+1/-0) src/service/keeper-helper.cpp (+5/-2) src/service/keeper-task-backup.cpp (+2/-2) src/service/keeper-task-backup.h (+1/-1) src/service/keeper-task-restore.cpp (+129/-0) src/service/keeper-task-restore.h (+46/-0) src/service/keeper-task.cpp (+37/-4) src/service/keeper-task.h (+3/-1) src/service/keeper-user.cpp (+4/-2) src/service/keeper.cpp (+103/-48) src/service/keeper.h (+6/-1) src/service/manifest.cpp (+3/-3) src/service/private/keeper-task_p.h (+4/-2) src/service/task-manager.cpp (+55/-12) src/service/task-manager.h (+2/-0) src/storage-framework/CMakeLists.txt (+3/-0) src/storage-framework/downloader.h (+46/-0) src/storage-framework/sf-downloader.cpp (+71/-0) src/storage-framework/sf-downloader.h (+48/-0) src/storage-framework/storage_framework_client.cpp (+16/-15) src/storage-framework/storage_framework_client.h (+2/-1) src/test-restore/CMakeLists.txt (+40/-0) src/test-restore/main.cpp (+32/-0) src/test-restore/test-restore-socket.cpp (+139/-0) src/test-restore/test-restore-socket.h (+56/-0) tests/CMakeLists.txt (+6/-0) tests/com_canonical_keeper.py (+17/-0) tests/fakes/CMakeLists.txt (+10/-0) tests/fakes/fake-restore-helper.cpp (+101/-0) tests/fakes/fake-restore-helper.h (+26/-0) tests/fakes/restore-reader.cpp (+81/-0) tests/fakes/restore-reader.h (+43/-0) tests/integration/helpers/CMakeLists.txt (+4/-0) tests/integration/helpers/helpers-test.cc (+219/-184) tests/integration/helpers/test-helpers-base.cpp (+8/-3) tests/unit/manifest/manifest-test.cpp (+1/-1) tests/unit/storage-framework/create-uploader-test.cpp (+6/-7) tests/utils/file-utils.cpp (+3/-1) tests/utils/storage-framework-local.cpp (+34/-0) tests/utils/storage-framework-local.h (+4/-0) |
To merge this branch: | bzr merge lp:~unity-api-team/keeper/restore |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
unity-api-1-bot | continuous-integration | Needs Fixing | |
Unity API Team | Pending | ||
Review via email: mp+311070@code.launchpad.net |
Commit message
First version of restore.
Description of the change
DO NOT REVIEW YET, branch created for initial jenkins test
This is based on <https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
- 131. By Charles Kerr
-
debug messages and whitespace
- 132. By Charles Kerr
-
eliminate some possible points of failure in the RestoreReader fake
- 133. By Charles Kerr
-
add more debugging info to FileUtils:
:compare_ files()
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:133
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
- 133. By Charles Kerr
-
add more debugging info to FileUtils:
:compare_ files() - 132. By Charles Kerr
-
eliminate some possible points of failure in the RestoreReader fake
- 131. By Charles Kerr
-
debug messages and whitespace
- 130. By Charles Kerr
-
fix missing gpl copyright in keeper dbusmock template
- 129. By Charles Kerr
-
fix cppcheck warning: non-explicit object ctor taking one argument
Preview Diff
1 | === modified file 'data/helper-registry.json.in' | |||
2 | --- data/helper-registry.json.in 2016-08-09 04:20:33 +0000 | |||
3 | +++ data/helper-registry.json.in 2016-11-17 00:23:33 +0000 | |||
4 | @@ -4,5 +4,10 @@ | |||
5 | 4 | "@FOLDER_BACKUP_EXEC@", | 4 | "@FOLDER_BACKUP_EXEC@", |
6 | 5 | "${subtype}" | 5 | "${subtype}" |
7 | 6 | ] | 6 | ] |
9 | 7 | } | 7 | , |
10 | 8 | "restore-urls": [ | ||
11 | 9 | "@FOLDER_RESTORE_EXEC@", | ||
12 | 10 | "${subtype}" | ||
13 | 11 | ] | ||
14 | 12 | } | ||
15 | 8 | } | 13 | } |
16 | 9 | 14 | ||
17 | === modified file 'include/helper/data-dir-registry.h' | |||
18 | --- include/helper/data-dir-registry.h 2016-08-09 05:44:25 +0000 | |||
19 | +++ include/helper/data-dir-registry.h 2016-11-17 00:23:33 +0000 | |||
20 | @@ -39,6 +39,8 @@ | |||
21 | 39 | 39 | ||
22 | 40 | QStringList get_backup_helper_urls(Metadata const& metadata) override; | 40 | QStringList get_backup_helper_urls(Metadata const& metadata) override; |
23 | 41 | 41 | ||
24 | 42 | QStringList get_restore_helper_urls(Metadata const& metadata) override; | ||
25 | 43 | |||
26 | 42 | private: | 44 | private: |
27 | 43 | class Impl; | 45 | class Impl; |
28 | 44 | friend class Impl; | 46 | friend class Impl; |
29 | 45 | 47 | ||
30 | === modified file 'include/helper/metadata.h' | |||
31 | --- include/helper/metadata.h 2016-10-14 09:23:11 +0000 | |||
32 | +++ include/helper/metadata.h 2016-11-17 00:23:33 +0000 | |||
33 | @@ -42,6 +42,7 @@ | |||
34 | 42 | static QString const TITLE_KEY; | 42 | static QString const TITLE_KEY; |
35 | 43 | static QString const VERSION_KEY; | 43 | static QString const VERSION_KEY; |
36 | 44 | static QString const FILE_NAME_KEY; | 44 | static QString const FILE_NAME_KEY; |
37 | 45 | static QString const DIR_NAME_KEY; | ||
38 | 45 | static QString const DISPLAY_NAME_KEY; | 46 | static QString const DISPLAY_NAME_KEY; |
39 | 46 | 47 | ||
40 | 47 | // metadata values | 48 | // metadata values |
41 | 48 | 49 | ||
42 | === modified file 'include/helper/registry.h' | |||
43 | --- include/helper/registry.h 2016-08-08 04:56:35 +0000 | |||
44 | +++ include/helper/registry.h 2016-11-17 00:23:33 +0000 | |||
45 | @@ -30,6 +30,7 @@ | |||
46 | 30 | Q_DISABLE_COPY(HelperRegistry) | 30 | Q_DISABLE_COPY(HelperRegistry) |
47 | 31 | 31 | ||
48 | 32 | virtual QStringList get_backup_helper_urls(Metadata const& task) =0; | 32 | virtual QStringList get_backup_helper_urls(Metadata const& task) =0; |
49 | 33 | virtual QStringList get_restore_helper_urls(Metadata const& task) =0; | ||
50 | 33 | 34 | ||
51 | 34 | protected: | 35 | protected: |
52 | 35 | HelperRegistry() =default; | 36 | HelperRegistry() =default; |
53 | 36 | 37 | ||
54 | === added file 'include/helper/restore-helper.h' | |||
55 | --- include/helper/restore-helper.h 1970-01-01 00:00:00 +0000 | |||
56 | +++ include/helper/restore-helper.h 2016-11-17 00:23:33 +0000 | |||
57 | @@ -0,0 +1,61 @@ | |||
58 | 1 | /* | ||
59 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
60 | 3 | * | ||
61 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
62 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
63 | 6 | * by the Free Software Foundation. | ||
64 | 7 | * | ||
65 | 8 | * This program is distributed in the hope that it will be useful, but | ||
66 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
67 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
68 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
69 | 12 | * | ||
70 | 13 | * You should have received a copy of the GNU General Public License along | ||
71 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
72 | 15 | * | ||
73 | 16 | * Authors: | ||
74 | 17 | * Xavi Garcia <xavi.garcia.mena@canonical.com> | ||
75 | 18 | * Charles Kerr <charles.kerr@canonical.com> | ||
76 | 19 | */ | ||
77 | 20 | |||
78 | 21 | #pragma once | ||
79 | 22 | |||
80 | 23 | #include "storage-framework/downloader.h" | ||
81 | 24 | #include "helper/helper.h" // parent class | ||
82 | 25 | #include "helper/registry.h" | ||
83 | 26 | |||
84 | 27 | #include <QObject> | ||
85 | 28 | #include <QScopedPointer> | ||
86 | 29 | #include <QString> | ||
87 | 30 | |||
88 | 31 | #include <memory> | ||
89 | 32 | |||
90 | 33 | class RestoreHelperPrivate; | ||
91 | 34 | class RestoreHelper final: public Helper | ||
92 | 35 | { | ||
93 | 36 | Q_OBJECT | ||
94 | 37 | Q_DECLARE_PRIVATE(RestoreHelper) | ||
95 | 38 | |||
96 | 39 | public: | ||
97 | 40 | RestoreHelper( | ||
98 | 41 | QString const & appid, | ||
99 | 42 | clock_func const & clock=Helper::default_clock, | ||
100 | 43 | QObject * parent=nullptr | ||
101 | 44 | ); | ||
102 | 45 | virtual ~RestoreHelper(); | ||
103 | 46 | Q_DISABLE_COPY(RestoreHelper) | ||
104 | 47 | |||
105 | 48 | static constexpr int MAX_INACTIVITY_TIME = 15000; | ||
106 | 49 | |||
107 | 50 | void set_downloader(std::shared_ptr<Downloader> const& downloader); | ||
108 | 51 | void start(QStringList const& urls) override; | ||
109 | 52 | void stop() override; | ||
110 | 53 | int get_helper_socket() const; | ||
111 | 54 | QString to_string(Helper::State state) const override; | ||
112 | 55 | void set_state(State) override; | ||
113 | 56 | protected: | ||
114 | 57 | void on_helper_finished() override; | ||
115 | 58 | |||
116 | 59 | private: | ||
117 | 60 | QScopedPointer<RestoreHelperPrivate> const d_ptr; | ||
118 | 61 | }; | ||
119 | 0 | 62 | ||
120 | === modified file 'src/CMakeLists.txt' | |||
121 | --- src/CMakeLists.txt 2016-08-09 10:13:48 +0000 | |||
122 | +++ src/CMakeLists.txt 2016-11-17 00:23:33 +0000 | |||
123 | @@ -11,6 +11,7 @@ | |||
124 | 11 | add_subdirectory(storage-framework) | 11 | add_subdirectory(storage-framework) |
125 | 12 | add_subdirectory(tar) | 12 | add_subdirectory(tar) |
126 | 13 | add_subdirectory(util) | 13 | add_subdirectory(util) |
127 | 14 | add_subdirectory(test-restore) | ||
128 | 14 | 15 | ||
129 | 15 | set( | 16 | set( |
130 | 16 | COVERAGE_REPORT_TARGETS | 17 | COVERAGE_REPORT_TARGETS |
131 | 17 | 18 | ||
132 | === modified file 'src/cli/main.cpp' | |||
133 | --- src/cli/main.cpp 2016-08-30 14:16:19 +0000 | |||
134 | +++ src/cli/main.cpp 2016-11-17 00:23:33 +0000 | |||
135 | @@ -88,6 +88,48 @@ | |||
136 | 88 | qWarning() << "Error starting backup:" << backup_reply.error().message(); | 88 | qWarning() << "Error starting backup:" << backup_reply.error().message(); |
137 | 89 | } | 89 | } |
138 | 90 | } | 90 | } |
139 | 91 | else if(argc == 2 && QStringLiteral("--restore") == argv[1]) | ||
140 | 92 | { | ||
141 | 93 | QScopedPointer<DBusInterfaceKeeperUser> user_iface(new DBusInterfaceKeeperUser( | ||
142 | 94 | DBusTypes::KEEPER_SERVICE, | ||
143 | 95 | DBusTypes::KEEPER_USER_PATH, | ||
144 | 96 | QDBusConnection::sessionBus() | ||
145 | 97 | ) ); | ||
146 | 98 | QDBusPendingReply<QVariantDictMap> choices = user_iface->call("GetRestoreChoices"); | ||
147 | 99 | choices.waitForFinished(); | ||
148 | 100 | if (choices.isError()) | ||
149 | 101 | { | ||
150 | 102 | qFatal("Call to '%s.GetRestoreChoices() at '%s' call failed: %s", | ||
151 | 103 | DBusTypes::KEEPER_SERVICE, | ||
152 | 104 | qPrintable(DBusTypes::KEEPER_USER_PATH), | ||
153 | 105 | qPrintable(choices.error().message()) | ||
154 | 106 | ); | ||
155 | 107 | } | ||
156 | 108 | |||
157 | 109 | QStringList uuids; | ||
158 | 110 | auto choices_values = choices.value(); | ||
159 | 111 | for(auto iter = choices_values.begin(); iter != choices_values.end(); ++iter) | ||
160 | 112 | { | ||
161 | 113 | const auto& values = iter.value(); | ||
162 | 114 | auto iter_values = values.find("type"); | ||
163 | 115 | if (iter_values != values.end()) | ||
164 | 116 | { | ||
165 | 117 | if (iter_values.value().toString() == "folder") | ||
166 | 118 | { | ||
167 | 119 | qDebug() << "Adding uuid" << iter.key() << "with type:" << "folder"; | ||
168 | 120 | uuids << iter.key(); | ||
169 | 121 | } | ||
170 | 122 | } | ||
171 | 123 | } | ||
172 | 124 | |||
173 | 125 | QStringList restoreUUids{uuids.at(0)}; | ||
174 | 126 | QDBusPendingReply<void> backup_reply = user_iface->call("StartRestore", restoreUUids); | ||
175 | 127 | |||
176 | 128 | if (!backup_reply.isValid()) | ||
177 | 129 | { | ||
178 | 130 | qWarning() << "Error starting restore:" << backup_reply.error().message(); | ||
179 | 131 | } | ||
180 | 132 | } | ||
181 | 91 | else | 133 | else |
182 | 92 | { | 134 | { |
183 | 93 | qWarning() << "FIXME"; | 135 | qWarning() << "FIXME"; |
184 | 94 | 136 | ||
185 | === modified file 'src/helper/CMakeLists.txt' | |||
186 | --- src/helper/CMakeLists.txt 2016-09-06 01:31:59 +0000 | |||
187 | +++ src/helper/CMakeLists.txt 2016-11-17 00:23:33 +0000 | |||
188 | @@ -48,10 +48,12 @@ | |||
189 | 48 | ${HELPER_LIB} | 48 | ${HELPER_LIB} |
190 | 49 | STATIC | 49 | STATIC |
191 | 50 | backup-helper.cpp | 50 | backup-helper.cpp |
192 | 51 | restore-helper.cpp | ||
193 | 51 | data-dir-registry.cpp | 52 | data-dir-registry.cpp |
194 | 52 | helper.cpp | 53 | helper.cpp |
195 | 53 | metadata.cpp | 54 | metadata.cpp |
196 | 54 | ${CMAKE_SOURCE_DIR}/include/helper/backup-helper.h | 55 | ${CMAKE_SOURCE_DIR}/include/helper/backup-helper.h |
197 | 56 | ${CMAKE_SOURCE_DIR}/include/helper/restore-helper.h | ||
198 | 55 | ${CMAKE_SOURCE_DIR}/include/helper/data-dir-registry.h | 57 | ${CMAKE_SOURCE_DIR}/include/helper/data-dir-registry.h |
199 | 56 | ${CMAKE_SOURCE_DIR}/include/helper/helper.h | 58 | ${CMAKE_SOURCE_DIR}/include/helper/helper.h |
200 | 57 | ${CMAKE_SOURCE_DIR}/include/helper/registry.h | 59 | ${CMAKE_SOURCE_DIR}/include/helper/registry.h |
201 | 58 | 60 | ||
202 | === modified file 'src/helper/data-dir-registry.cpp' | |||
203 | --- src/helper/data-dir-registry.cpp 2016-08-10 02:29:17 +0000 | |||
204 | +++ src/helper/data-dir-registry.cpp 2016-11-17 00:23:33 +0000 | |||
205 | @@ -49,15 +49,29 @@ | |||
206 | 49 | 49 | ||
207 | 50 | QStringList get_backup_helper_urls(Metadata const& task) | 50 | QStringList get_backup_helper_urls(Metadata const& task) |
208 | 51 | { | 51 | { |
209 | 52 | return get_helper_urls(task, "backup"); | ||
210 | 53 | } | ||
211 | 54 | |||
212 | 55 | QStringList get_restore_helper_urls(Metadata const& task) | ||
213 | 56 | { | ||
214 | 57 | return get_helper_urls(task, "restore"); | ||
215 | 58 | } | ||
216 | 59 | |||
217 | 60 | |||
218 | 61 | |||
219 | 62 | private: | ||
220 | 63 | |||
221 | 64 | QStringList get_helper_urls(Metadata const& task, QString const & prop) | ||
222 | 65 | { | ||
223 | 52 | QStringList ret; | 66 | QStringList ret; |
224 | 53 | 67 | ||
225 | 54 | QString type; | 68 | QString type; |
226 | 55 | if (task.get_property(Metadata::TYPE_KEY, type)) | 69 | if (task.get_property(Metadata::TYPE_KEY, type)) |
227 | 56 | { | 70 | { |
229 | 57 | auto it = registry_.find(std::make_pair(type,QStringLiteral("backup"))); | 71 | auto it = registry_.find(std::make_pair(type,prop)); |
230 | 58 | if (it == registry_.end()) | 72 | if (it == registry_.end()) |
231 | 59 | { | 73 | { |
233 | 60 | qCritical() << "can't get backup helper urls for unhandled type" << type; | 74 | qCritical() << "can't get " << prop << " helper urls for unhandled type" << type; |
234 | 61 | } | 75 | } |
235 | 62 | else | 76 | else |
236 | 63 | { | 77 | { |
237 | @@ -73,8 +87,6 @@ | |||
238 | 73 | return ret; | 87 | return ret; |
239 | 74 | } | 88 | } |
240 | 75 | 89 | ||
241 | 76 | private: | ||
242 | 77 | |||
243 | 78 | // replace "${key}" with task.get_property("key") | 90 | // replace "${key}" with task.get_property("key") |
244 | 79 | QStringList perform_url_substitution(Metadata const& task, QStringList const& urls_in) | 91 | QStringList perform_url_substitution(Metadata const& task, QStringList const& urls_in) |
245 | 80 | { | 92 | { |
246 | @@ -139,6 +151,10 @@ | |||
247 | 139 | * "backup-urls": [ | 151 | * "backup-urls": [ |
248 | 140 | * "/path/to/helper.sh", | 152 | * "/path/to/helper.sh", |
249 | 141 | * "${subtype}" | 153 | * "${subtype}" |
250 | 154 | * ], | ||
251 | 155 | * "restore-urls": [ | ||
252 | 156 | * "/path/to/helper.sh", | ||
253 | 157 | * "${subtype}" | ||
254 | 142 | * ] | 158 | * ] |
255 | 143 | * } | 159 | * } |
256 | 144 | * } | 160 | * } |
257 | @@ -160,21 +176,33 @@ | |||
258 | 160 | for (auto tit=obj.begin(), tend=obj.end(); tit!=tend; ++tit) | 176 | for (auto tit=obj.begin(), tend=obj.end(); tit!=tend; ++tit) |
259 | 161 | { | 177 | { |
260 | 162 | auto const type = tit.key(); | 178 | auto const type = tit.key(); |
261 | 163 | auto& info = registry_[std::make_pair(type,QStringLiteral("backup"))]; | ||
262 | 164 | |||
263 | 165 | auto const props = tit.value().toObject(); | 179 | auto const props = tit.value().toObject(); |
264 | 180 | |||
265 | 166 | auto const urls_jsonval = props["backup-urls"]; | 181 | auto const urls_jsonval = props["backup-urls"]; |
266 | 167 | if (urls_jsonval.isArray()) | 182 | if (urls_jsonval.isArray()) |
267 | 168 | { | 183 | { |
268 | 184 | auto& info = registry_[std::make_pair(type,QStringLiteral("backup"))]; | ||
269 | 169 | for (auto url_jsonval : urls_jsonval.toArray()) | 185 | for (auto url_jsonval : urls_jsonval.toArray()) |
270 | 170 | { | 186 | { |
271 | 171 | info.urls.push_back(url_jsonval.toString()); | 187 | info.urls.push_back(url_jsonval.toString()); |
272 | 172 | } | 188 | } |
273 | 189 | qDebug() << "loaded" << type << "backup urls from" << path; | ||
274 | 190 | for(auto const& url : info.urls) | ||
275 | 191 | qDebug() << "\turl:" << url; | ||
276 | 173 | } | 192 | } |
277 | 174 | 193 | ||
281 | 175 | qDebug() << "loaded" << type << "backup urls from" << path; | 194 | auto const urls_jsonval_restore = props["restore-urls"]; |
282 | 176 | for(auto const& url : info.urls) | 195 | if (urls_jsonval_restore.isArray()) |
283 | 177 | qDebug() << "\turl:" << url; | 196 | { |
284 | 197 | auto& info = registry_[std::make_pair(type,QStringLiteral("restore"))]; | ||
285 | 198 | for (auto url_jsonval : urls_jsonval_restore.toArray()) | ||
286 | 199 | { | ||
287 | 200 | info.urls.push_back(url_jsonval.toString()); | ||
288 | 201 | } | ||
289 | 202 | qDebug() << "loaded" << type << "restore urls from" << path; | ||
290 | 203 | for(auto const& url : info.urls) | ||
291 | 204 | qDebug() << "\turl:" << url; | ||
292 | 205 | } | ||
293 | 178 | } | 206 | } |
294 | 179 | } | 207 | } |
295 | 180 | } | 208 | } |
296 | @@ -198,3 +226,9 @@ | |||
297 | 198 | { | 226 | { |
298 | 199 | return impl_->get_backup_helper_urls(task); | 227 | return impl_->get_backup_helper_urls(task); |
299 | 200 | } | 228 | } |
300 | 229 | |||
301 | 230 | QStringList | ||
302 | 231 | DataDirRegistry::get_restore_helper_urls(Metadata const& task) | ||
303 | 232 | { | ||
304 | 233 | return impl_->get_restore_helper_urls(task); | ||
305 | 234 | } | ||
306 | 201 | 235 | ||
307 | === modified file 'src/helper/helper.cpp' | |||
308 | --- src/helper/helper.cpp 2016-09-15 14:05:17 +0000 | |||
309 | +++ src/helper/helper.cpp 2016-11-17 00:23:33 +0000 | |||
310 | @@ -301,7 +301,7 @@ | |||
311 | 301 | 301 | ||
312 | 302 | void ual_stop() | 302 | void ual_stop() |
313 | 303 | { | 303 | { |
315 | 304 | qDebug() << "Stopping helper for app:" << appid_; | 304 | qDebug() << "------------------------------------------------------ Stopping helper for app:" << appid_; |
316 | 305 | auto backupType = ubuntu::app_launch::Helper::Type::from_raw(HELPER_TYPE); | 305 | auto backupType = ubuntu::app_launch::Helper::Type::from_raw(HELPER_TYPE); |
317 | 306 | 306 | ||
318 | 307 | auto appid = ubuntu::app_launch::AppID::parse(appid_.toStdString()); | 307 | auto appid = ubuntu::app_launch::AppID::parse(appid_.toStdString()); |
319 | @@ -359,7 +359,7 @@ | |||
320 | 359 | 359 | ||
321 | 360 | void on_max_time_waiting_for_ual_started() | 360 | void on_max_time_waiting_for_ual_started() |
322 | 361 | { | 361 | { |
324 | 362 | qDebug() << "Max time reached waiting for UAL to start"; | 362 | qDebug() << "========================================================================== Max time reached waiting for UAL to start"; |
325 | 363 | q_ptr->set_state(Helper::State::FAILED); | 363 | q_ptr->set_state(Helper::State::FAILED); |
326 | 364 | stop_wait_for_ual_timer(); | 364 | stop_wait_for_ual_timer(); |
327 | 365 | } | 365 | } |
328 | 366 | 366 | ||
329 | === modified file 'src/helper/metadata.cpp' | |||
330 | --- src/helper/metadata.cpp 2016-10-14 09:23:11 +0000 | |||
331 | +++ src/helper/metadata.cpp 2016-11-17 00:23:33 +0000 | |||
332 | @@ -42,6 +42,7 @@ | |||
333 | 42 | const QString Metadata::TITLE_KEY = QStringLiteral("title"); | 42 | const QString Metadata::TITLE_KEY = QStringLiteral("title"); |
334 | 43 | const QString Metadata::VERSION_KEY = QStringLiteral("version"); | 43 | const QString Metadata::VERSION_KEY = QStringLiteral("version"); |
335 | 44 | const QString Metadata::FILE_NAME_KEY = QStringLiteral("file-name"); | 44 | const QString Metadata::FILE_NAME_KEY = QStringLiteral("file-name"); |
336 | 45 | const QString Metadata::DIR_NAME_KEY = QStringLiteral("dir-name"); | ||
337 | 45 | const QString Metadata::DISPLAY_NAME_KEY = QStringLiteral("display-name"); | 46 | const QString Metadata::DISPLAY_NAME_KEY = QStringLiteral("display-name"); |
338 | 46 | 47 | ||
339 | 47 | // Metadata values | 48 | // Metadata values |
340 | 48 | 49 | ||
341 | === added file 'src/helper/restore-helper.cpp' | |||
342 | --- src/helper/restore-helper.cpp 1970-01-01 00:00:00 +0000 | |||
343 | +++ src/helper/restore-helper.cpp 2016-11-17 00:23:33 +0000 | |||
344 | @@ -0,0 +1,378 @@ | |||
345 | 1 | /* | ||
346 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
347 | 3 | * | ||
348 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
349 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
350 | 6 | * by the Free Software Foundation. | ||
351 | 7 | * | ||
352 | 8 | * This program is distributed in the hope that it will be useful, but | ||
353 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
354 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
355 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
356 | 12 | * | ||
357 | 13 | * You should have received a copy of the GNU General Public License along | ||
358 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
359 | 15 | * | ||
360 | 16 | * Authors: | ||
361 | 17 | * Xavi Garcia <xavi.garcia.mena@canonical.com> | ||
362 | 18 | * Charles Kerr <charles.kerr@canonical.com> | ||
363 | 19 | */ | ||
364 | 20 | |||
365 | 21 | #include "util/connection-helper.h" | ||
366 | 22 | #include "helper/restore-helper.h" | ||
367 | 23 | #include "service/app-const.h" // HELPER_TYPE | ||
368 | 24 | |||
369 | 25 | #include <QByteArray> | ||
370 | 26 | #include <QDebug> | ||
371 | 27 | #include <QLocalSocket> | ||
372 | 28 | #include <QMap> | ||
373 | 29 | #include <QObject> | ||
374 | 30 | #include <QString> | ||
375 | 31 | #include <QTimer> | ||
376 | 32 | #include <QVector> | ||
377 | 33 | #include <QCryptographicHash> | ||
378 | 34 | |||
379 | 35 | #include <fcntl.h> | ||
380 | 36 | #include <sys/types.h> | ||
381 | 37 | #include <sys/socket.h> | ||
382 | 38 | |||
383 | 39 | #include <functional> // std::bind() | ||
384 | 40 | |||
385 | 41 | |||
386 | 42 | class RestoreHelperPrivate | ||
387 | 43 | { | ||
388 | 44 | public: | ||
389 | 45 | |||
390 | 46 | explicit RestoreHelperPrivate( | ||
391 | 47 | RestoreHelper* backup_helper | ||
392 | 48 | ) | ||
393 | 49 | : q_ptr(backup_helper) | ||
394 | 50 | { | ||
395 | 51 | // listen for inactivity from storage framework | ||
396 | 52 | QObject::connect(&timer_, &QTimer::timeout, | ||
397 | 53 | std::bind(&RestoreHelperPrivate::on_inactivity_detected, this) | ||
398 | 54 | ); | ||
399 | 55 | |||
400 | 56 | // fire up the sockets | ||
401 | 57 | int fds[2]; | ||
402 | 58 | int rc = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds); | ||
403 | 59 | if (rc == -1) | ||
404 | 60 | { | ||
405 | 61 | // TODO throw exception. | ||
406 | 62 | qWarning() << "RestoreHelperPrivate: error creating socket pair to communicate with helper "; | ||
407 | 63 | return; | ||
408 | 64 | } | ||
409 | 65 | |||
410 | 66 | // helper socket is for the client. | ||
411 | 67 | helper_socket_.setSocketDescriptor(fds[0], QLocalSocket::ConnectedState, QIODevice::ReadOnly); | ||
412 | 68 | |||
413 | 69 | write_socket_.setSocketDescriptor(fds[1], QLocalSocket::ConnectedState, QIODevice::WriteOnly); | ||
414 | 70 | } | ||
415 | 71 | |||
416 | 72 | ~RestoreHelperPrivate() = default; | ||
417 | 73 | |||
418 | 74 | Q_DISABLE_COPY(RestoreHelperPrivate) | ||
419 | 75 | |||
420 | 76 | void start(QStringList const& urls) | ||
421 | 77 | { | ||
422 | 78 | q_ptr->Helper::start(urls); | ||
423 | 79 | reset_inactivity_timer(); | ||
424 | 80 | } | ||
425 | 81 | |||
426 | 82 | void set_downloader(std::shared_ptr<Downloader> const& downloader) | ||
427 | 83 | { | ||
428 | 84 | qDebug() << "RestoreHelper::set_downloader"; | ||
429 | 85 | downloader_ = downloader; | ||
430 | 86 | n_read_ = 0; | ||
431 | 87 | n_uploaded_ = 0; | ||
432 | 88 | read_error_ = false; | ||
433 | 89 | write_error_ = false; | ||
434 | 90 | cancelled_ = false; | ||
435 | 91 | |||
436 | 92 | q_ptr->set_expected_size(downloader->file_size()); | ||
437 | 93 | |||
438 | 94 | qDebug() << "Storage framework socket is: " << static_cast<void *>(downloader_->socket().get()); | ||
439 | 95 | |||
440 | 96 | // listen for data ready to read | ||
441 | 97 | QObject::connect(downloader_->socket().get(), &QLocalSocket::readyRead, | ||
442 | 98 | std::bind(&RestoreHelperPrivate::on_ready_read, this) | ||
443 | 99 | ); | ||
444 | 100 | |||
445 | 101 | connections_.remember(QObject::connect( | ||
446 | 102 | &write_socket_, &QLocalSocket::bytesWritten, | ||
447 | 103 | std::bind(&RestoreHelperPrivate::on_data_uploaded, this, std::placeholders::_1) | ||
448 | 104 | )); | ||
449 | 105 | |||
450 | 106 | // maybe there's already readable data | ||
451 | 107 | process_more(); | ||
452 | 108 | |||
453 | 109 | reset_inactivity_timer(); | ||
454 | 110 | } | ||
455 | 111 | |||
456 | 112 | void stop() | ||
457 | 113 | { | ||
458 | 114 | write_socket_.disconnectFromServer(); | ||
459 | 115 | cancelled_ = true; | ||
460 | 116 | q_ptr->Helper::stop(); | ||
461 | 117 | } | ||
462 | 118 | |||
463 | 119 | int get_helper_socket() const | ||
464 | 120 | { | ||
465 | 121 | return int(helper_socket_.socketDescriptor()); | ||
466 | 122 | } | ||
467 | 123 | |||
468 | 124 | QString to_string(Helper::State state) const | ||
469 | 125 | { | ||
470 | 126 | return state == Helper::State::STARTED | ||
471 | 127 | ? QStringLiteral("restoring") | ||
472 | 128 | : q_ptr->Helper::to_string(state); | ||
473 | 129 | } | ||
474 | 130 | |||
475 | 131 | void on_state_changed(Helper::State state) | ||
476 | 132 | { | ||
477 | 133 | switch (state) | ||
478 | 134 | { | ||
479 | 135 | case Helper::State::CANCELLED: | ||
480 | 136 | case Helper::State::FAILED: | ||
481 | 137 | qDebug() << "cancelled/failed, calling downloader_.reset()"; | ||
482 | 138 | downloader_.reset(); | ||
483 | 139 | break; | ||
484 | 140 | |||
485 | 141 | case Helper::State::DATA_COMPLETE: { | ||
486 | 142 | qDebug() << "Restore helper finished, calling downloader_.finish()"; | ||
487 | 143 | write_socket_.disconnectFromServer(); | ||
488 | 144 | downloader_->finish(); | ||
489 | 145 | downloader_.reset(); | ||
490 | 146 | break; | ||
491 | 147 | } | ||
492 | 148 | |||
493 | 149 | //case Helper::State::NOT_STARTED: | ||
494 | 150 | //case Helper::State::STARTED: | ||
495 | 151 | default: | ||
496 | 152 | break; | ||
497 | 153 | } | ||
498 | 154 | } | ||
499 | 155 | |||
500 | 156 | void on_helper_finished() | ||
501 | 157 | { | ||
502 | 158 | stop_inactivity_timer(); | ||
503 | 159 | check_for_done(); | ||
504 | 160 | } | ||
505 | 161 | |||
506 | 162 | private: | ||
507 | 163 | |||
508 | 164 | void on_inactivity_detected() | ||
509 | 165 | { | ||
510 | 166 | stop_inactivity_timer(); | ||
511 | 167 | qWarning() << "Inactivity detected in the helper...stopping it"; | ||
512 | 168 | stop(); | ||
513 | 169 | } | ||
514 | 170 | |||
515 | 171 | void on_ready_read() | ||
516 | 172 | { | ||
517 | 173 | process_more(); | ||
518 | 174 | } | ||
519 | 175 | |||
520 | 176 | void on_data_uploaded(qint64 n) | ||
521 | 177 | { | ||
522 | 178 | n_uploaded_ += n; | ||
523 | 179 | q_ptr->record_data_transferred(n); | ||
524 | 180 | qDebug("n_read %zu n_uploaded %zu (newly uploaded %zu)", size_t(n_read_), size_t(n_uploaded_), size_t(n)); | ||
525 | 181 | process_more(); | ||
526 | 182 | check_for_done(); | ||
527 | 183 | } | ||
528 | 184 | |||
529 | 185 | void process_more() | ||
530 | 186 | { | ||
531 | 187 | qDebug() << Q_FUNC_INFO; | ||
532 | 188 | |||
533 | 189 | if (!downloader_) | ||
534 | 190 | return; | ||
535 | 191 | |||
536 | 192 | qDebug() << Q_FUNC_INFO << "2"; | ||
537 | 193 | |||
538 | 194 | char readbuf[UPLOAD_BUFFER_MAX_]; | ||
539 | 195 | auto socket = downloader_->socket(); | ||
540 | 196 | for(;;) | ||
541 | 197 | { | ||
542 | 198 | if (!socket->bytesAvailable()) | ||
543 | 199 | break; | ||
544 | 200 | // try to fill the upload buf | ||
545 | 201 | int max_bytes = (UPLOAD_BUFFER_MAX_) - upload_buffer_.size(); | ||
546 | 202 | if (max_bytes > 0) { | ||
547 | 203 | const auto n = socket->read(readbuf, max_bytes); | ||
548 | 204 | if (n > 0) { | ||
549 | 205 | n_read_ += n; | ||
550 | 206 | upload_buffer_.append(readbuf, int(n)); | ||
551 | 207 | qDebug("buffer_.size() is %zu after reading %zu", size_t(upload_buffer_.size()), size_t(n)); | ||
552 | 208 | } | ||
553 | 209 | else if (n < 0) { | ||
554 | 210 | read_error_ = true; | ||
555 | 211 | qDebug() << "Read error in" << Q_FUNC_INFO << ":" << socket->errorString(); | ||
556 | 212 | stop(); | ||
557 | 213 | return; | ||
558 | 214 | } | ||
559 | 215 | } | ||
560 | 216 | |||
561 | 217 | // THIS IS JUST FOR EXTRA DEBUG INFORMATION | ||
562 | 218 | QCryptographicHash hash(QCryptographicHash::Sha1); | ||
563 | 219 | hash.addData(upload_buffer_.left(100)); | ||
564 | 220 | qDebug() << "************************************************ Hash send: " << hash.result().toHex() << " Size: " << upload_buffer_.size() << " Total: " << n_read_; | ||
565 | 221 | // THIS IS JUST FOR EXTRA DEBUG INFORMATION | ||
566 | 222 | |||
567 | 223 | // try to empty the upload buf | ||
568 | 224 | const auto n = write_socket_.write(upload_buffer_); | ||
569 | 225 | if (n > 0) { | ||
570 | 226 | upload_buffer_.remove(0, int(n)); | ||
571 | 227 | qDebug("buffer_.size() is %zu after writing %zu", size_t(upload_buffer_.size()), size_t(n)); | ||
572 | 228 | continue; | ||
573 | 229 | } | ||
574 | 230 | else { | ||
575 | 231 | if (n < 0) { | ||
576 | 232 | write_error_ = true; | ||
577 | 233 | qWarning() << "Write error:" << write_socket_.errorString(); | ||
578 | 234 | stop(); | ||
579 | 235 | } | ||
580 | 236 | break; | ||
581 | 237 | } | ||
582 | 238 | } | ||
583 | 239 | |||
584 | 240 | reset_inactivity_timer(); | ||
585 | 241 | } | ||
586 | 242 | |||
587 | 243 | void reset_inactivity_timer() | ||
588 | 244 | { | ||
589 | 245 | static constexpr int MAX_TIME_WAITING_FOR_DATA {RestoreHelper::MAX_INACTIVITY_TIME}; | ||
590 | 246 | timer_.start(MAX_TIME_WAITING_FOR_DATA); | ||
591 | 247 | } | ||
592 | 248 | |||
593 | 249 | void stop_inactivity_timer() | ||
594 | 250 | { | ||
595 | 251 | timer_.stop(); | ||
596 | 252 | } | ||
597 | 253 | |||
598 | 254 | void check_for_done() | ||
599 | 255 | { | ||
600 | 256 | qDebug() << "Checking for done."; | ||
601 | 257 | if (cancelled_) | ||
602 | 258 | { | ||
603 | 259 | q_ptr->set_state(Helper::State::CANCELLED); | ||
604 | 260 | } | ||
605 | 261 | else if (read_error_ || write_error_ || n_uploaded_ > q_ptr->expected_size()) | ||
606 | 262 | { | ||
607 | 263 | if (!q_ptr->is_helper_running()) | ||
608 | 264 | { | ||
609 | 265 | q_ptr->set_state(Helper::State::FAILED); | ||
610 | 266 | } | ||
611 | 267 | } | ||
612 | 268 | else if (n_uploaded_ == q_ptr->expected_size()) | ||
613 | 269 | { | ||
614 | 270 | if (downloader_) | ||
615 | 271 | { | ||
616 | 272 | if (q_ptr->is_helper_running()) | ||
617 | 273 | { | ||
618 | 274 | // only in the case that the helper process finished we move to the next state | ||
619 | 275 | // this is to prevent to start the next task too early | ||
620 | 276 | q_ptr->set_state(Helper::State::DATA_COMPLETE); | ||
621 | 277 | stop_inactivity_timer(); | ||
622 | 278 | } | ||
623 | 279 | } | ||
624 | 280 | else | ||
625 | 281 | q_ptr->set_state(Helper::State::COMPLETE); | ||
626 | 282 | } | ||
627 | 283 | } | ||
628 | 284 | |||
629 | 285 | /*** | ||
630 | 286 | **** | ||
631 | 287 | ***/ | ||
632 | 288 | |||
633 | 289 | static constexpr int UPLOAD_BUFFER_MAX_ {1024*16}; | ||
634 | 290 | |||
635 | 291 | RestoreHelper * const q_ptr; | ||
636 | 292 | QTimer timer_; | ||
637 | 293 | std::shared_ptr<Downloader> downloader_; | ||
638 | 294 | QLocalSocket helper_socket_; | ||
639 | 295 | QLocalSocket write_socket_; | ||
640 | 296 | QByteArray upload_buffer_; | ||
641 | 297 | qint64 n_read_ = 0; | ||
642 | 298 | qint64 n_uploaded_ = 0; | ||
643 | 299 | bool read_error_ = false; | ||
644 | 300 | bool write_error_ = false; | ||
645 | 301 | bool cancelled_ = false; | ||
646 | 302 | ConnectionHelper connections_; | ||
647 | 303 | QString uploader_committed_file_name_; | ||
648 | 304 | }; | ||
649 | 305 | |||
650 | 306 | /*** | ||
651 | 307 | **** | ||
652 | 308 | ***/ | ||
653 | 309 | |||
654 | 310 | RestoreHelper::RestoreHelper( | ||
655 | 311 | QString const & appid, | ||
656 | 312 | clock_func const & clock, | ||
657 | 313 | QObject * parent | ||
658 | 314 | ) | ||
659 | 315 | : Helper(appid, clock, parent) | ||
660 | 316 | , d_ptr(new RestoreHelperPrivate(this)) | ||
661 | 317 | { | ||
662 | 318 | } | ||
663 | 319 | |||
664 | 320 | RestoreHelper::~RestoreHelper() =default; | ||
665 | 321 | |||
666 | 322 | void | ||
667 | 323 | RestoreHelper::start(QStringList const& url) | ||
668 | 324 | { | ||
669 | 325 | Q_D(RestoreHelper); | ||
670 | 326 | |||
671 | 327 | d->start(url); | ||
672 | 328 | } | ||
673 | 329 | |||
674 | 330 | void | ||
675 | 331 | RestoreHelper::stop() | ||
676 | 332 | { | ||
677 | 333 | Q_D(RestoreHelper); | ||
678 | 334 | |||
679 | 335 | d->stop(); | ||
680 | 336 | } | ||
681 | 337 | |||
682 | 338 | void | ||
683 | 339 | RestoreHelper::set_downloader(std::shared_ptr<Downloader> const& downloader) | ||
684 | 340 | { | ||
685 | 341 | Q_D(RestoreHelper); | ||
686 | 342 | |||
687 | 343 | d->set_downloader(downloader); | ||
688 | 344 | } | ||
689 | 345 | |||
690 | 346 | int | ||
691 | 347 | RestoreHelper::get_helper_socket() const | ||
692 | 348 | { | ||
693 | 349 | Q_D(const RestoreHelper); | ||
694 | 350 | |||
695 | 351 | return d->get_helper_socket(); | ||
696 | 352 | } | ||
697 | 353 | |||
698 | 354 | QString | ||
699 | 355 | RestoreHelper::to_string(Helper::State state) const | ||
700 | 356 | { | ||
701 | 357 | Q_D(const RestoreHelper); | ||
702 | 358 | |||
703 | 359 | return d->to_string(state); | ||
704 | 360 | } | ||
705 | 361 | |||
706 | 362 | void | ||
707 | 363 | RestoreHelper::set_state(Helper::State state) | ||
708 | 364 | { | ||
709 | 365 | Q_D(RestoreHelper); | ||
710 | 366 | |||
711 | 367 | qDebug() << Q_FUNC_INFO; | ||
712 | 368 | Helper::set_state(state); | ||
713 | 369 | d->on_state_changed(state); | ||
714 | 370 | } | ||
715 | 371 | |||
716 | 372 | void RestoreHelper::on_helper_finished() | ||
717 | 373 | { | ||
718 | 374 | Q_D(RestoreHelper); | ||
719 | 375 | |||
720 | 376 | Helper::on_helper_finished(); | ||
721 | 377 | d->on_helper_finished(); | ||
722 | 378 | } | ||
723 | 0 | 379 | ||
724 | === modified file 'src/service/CMakeLists.txt' | |||
725 | --- src/service/CMakeLists.txt 2016-10-28 15:11:21 +0000 | |||
726 | +++ src/service/CMakeLists.txt 2016-11-17 00:23:33 +0000 | |||
727 | @@ -15,6 +15,7 @@ | |||
728 | 15 | task-manager.cpp | 15 | task-manager.cpp |
729 | 16 | keeper-task.cpp | 16 | keeper-task.cpp |
730 | 17 | keeper-task-backup.cpp | 17 | keeper-task-backup.cpp |
731 | 18 | keeper-task-restore.cpp | ||
732 | 18 | manifest.cpp | 19 | manifest.cpp |
733 | 19 | metadata-provider.h | 20 | metadata-provider.h |
734 | 20 | ) | 21 | ) |
735 | 21 | 22 | ||
736 | === modified file 'src/service/keeper-helper.cpp' | |||
737 | --- src/service/keeper-helper.cpp 2016-08-10 02:06:08 +0000 | |||
738 | +++ src/service/keeper-helper.cpp 2016-11-17 00:23:33 +0000 | |||
739 | @@ -44,8 +44,11 @@ | |||
740 | 44 | 44 | ||
741 | 45 | QDBusUnixFileDescriptor KeeperHelper::StartRestore() | 45 | QDBusUnixFileDescriptor KeeperHelper::StartRestore() |
742 | 46 | { | 46 | { |
745 | 47 | // TODO get the file descriptor of the item in storage framework | 47 | // pass it back to Keeper to do the work |
746 | 48 | return QDBusUnixFileDescriptor(); | 48 | Q_ASSERT(calledFromDBus()); |
747 | 49 | auto bus = connection(); | ||
748 | 50 | auto& msg = message(); | ||
749 | 51 | return keeper_.StartRestore(bus, msg); | ||
750 | 49 | } | 52 | } |
751 | 50 | 53 | ||
752 | 51 | void KeeperHelper::UpdateStatus(const QString &app_id, const QString &status, double percentage) | 54 | void KeeperHelper::UpdateStatus(const QString &app_id, const QString &status, double percentage) |
753 | 52 | 55 | ||
754 | === modified file 'src/service/keeper-task-backup.cpp' | |||
755 | --- src/service/keeper-task-backup.cpp 2016-10-06 14:53:44 +0000 | |||
756 | +++ src/service/keeper-task-backup.cpp 2016-11-17 00:23:33 +0000 | |||
757 | @@ -31,7 +31,7 @@ | |||
758 | 31 | Q_DECLARE_PUBLIC(KeeperTaskBackup) | 31 | Q_DECLARE_PUBLIC(KeeperTaskBackup) |
759 | 32 | public: | 32 | public: |
760 | 33 | KeeperTaskBackupPrivate(KeeperTask * keeper_task, | 33 | KeeperTaskBackupPrivate(KeeperTask * keeper_task, |
762 | 34 | KeeperTask::TaskData const & task_data, | 34 | KeeperTask::TaskData & task_data, |
763 | 35 | QSharedPointer<HelperRegistry> const & helper_registry, | 35 | QSharedPointer<HelperRegistry> const & helper_registry, |
764 | 36 | QSharedPointer<StorageFrameworkClient> const & storage) | 36 | QSharedPointer<StorageFrameworkClient> const & storage) |
765 | 37 | : KeeperTaskPrivate(keeper_task, task_data, helper_registry, storage) | 37 | : KeeperTaskPrivate(keeper_task, task_data, helper_registry, storage) |
766 | @@ -90,7 +90,7 @@ | |||
767 | 90 | QString file_name_; | 90 | QString file_name_; |
768 | 91 | }; | 91 | }; |
769 | 92 | 92 | ||
771 | 93 | KeeperTaskBackup::KeeperTaskBackup(TaskData const & task_data, | 93 | KeeperTaskBackup::KeeperTaskBackup(TaskData & task_data, |
772 | 94 | QSharedPointer<HelperRegistry> const & helper_registry, | 94 | QSharedPointer<HelperRegistry> const & helper_registry, |
773 | 95 | QSharedPointer<StorageFrameworkClient> const & storage, | 95 | QSharedPointer<StorageFrameworkClient> const & storage, |
774 | 96 | QObject *parent) | 96 | QObject *parent) |
775 | 97 | 97 | ||
776 | === modified file 'src/service/keeper-task-backup.h' | |||
777 | --- src/service/keeper-task-backup.h 2016-10-06 14:53:44 +0000 | |||
778 | +++ src/service/keeper-task-backup.h 2016-11-17 00:23:33 +0000 | |||
779 | @@ -29,7 +29,7 @@ | |||
780 | 29 | Q_DECLARE_PRIVATE(KeeperTaskBackup) | 29 | Q_DECLARE_PRIVATE(KeeperTaskBackup) |
781 | 30 | public: | 30 | public: |
782 | 31 | 31 | ||
784 | 32 | KeeperTaskBackup(TaskData const & task_data, | 32 | KeeperTaskBackup(TaskData & task_data, |
785 | 33 | QSharedPointer<HelperRegistry> const & helper_registry, | 33 | QSharedPointer<HelperRegistry> const & helper_registry, |
786 | 34 | QSharedPointer<StorageFrameworkClient> const & storage, | 34 | QSharedPointer<StorageFrameworkClient> const & storage, |
787 | 35 | QObject *parent = nullptr); | 35 | QObject *parent = nullptr); |
788 | 36 | 36 | ||
789 | === added file 'src/service/keeper-task-restore.cpp' | |||
790 | --- src/service/keeper-task-restore.cpp 1970-01-01 00:00:00 +0000 | |||
791 | +++ src/service/keeper-task-restore.cpp 2016-11-17 00:23:33 +0000 | |||
792 | @@ -0,0 +1,129 @@ | |||
793 | 1 | /* | ||
794 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
795 | 3 | * | ||
796 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
797 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
798 | 6 | * by the Free Software Foundation. | ||
799 | 7 | * | ||
800 | 8 | * This program is distributed in the hope that it will be useful, but | ||
801 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
802 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
803 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
804 | 12 | * | ||
805 | 13 | * You should have received a copy of the GNU General Public License along | ||
806 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
807 | 15 | * | ||
808 | 16 | * Authors: | ||
809 | 17 | * Xavi Garcia <xavi.garcia.mena@canonical.com> | ||
810 | 18 | * Charles Kerr <charles.kerr@canonical.com> | ||
811 | 19 | */ | ||
812 | 20 | |||
813 | 21 | #include "util/connection-helper.h" | ||
814 | 22 | #include "storage-framework/storage_framework_client.h" | ||
815 | 23 | #include "helper/restore-helper.h" | ||
816 | 24 | #include "service/app-const.h" // DEKKO_APP_ID | ||
817 | 25 | #include "service/keeper-task-restore.h" | ||
818 | 26 | #include "service/keeper-task.h" | ||
819 | 27 | #include "service/private/keeper-task_p.h" | ||
820 | 28 | |||
821 | 29 | namespace sf = unity::storage::qt::client; | ||
822 | 30 | |||
823 | 31 | class KeeperTaskRestorePrivate : public KeeperTaskPrivate | ||
824 | 32 | { | ||
825 | 33 | Q_DECLARE_PUBLIC(KeeperTaskRestore) | ||
826 | 34 | public: | ||
827 | 35 | KeeperTaskRestorePrivate(KeeperTask * keeper_task, | ||
828 | 36 | KeeperTask::TaskData & task_data, | ||
829 | 37 | QSharedPointer<HelperRegistry> const & helper_registry, | ||
830 | 38 | QSharedPointer<StorageFrameworkClient> const & storage) | ||
831 | 39 | : KeeperTaskPrivate(keeper_task, task_data, helper_registry, storage) | ||
832 | 40 | { | ||
833 | 41 | } | ||
834 | 42 | |||
835 | 43 | ~KeeperTaskRestorePrivate() = default; | ||
836 | 44 | |||
837 | 45 | QStringList get_helper_urls() const | ||
838 | 46 | { | ||
839 | 47 | return helper_registry_->get_restore_helper_urls(task_data_.metadata); | ||
840 | 48 | } | ||
841 | 49 | |||
842 | 50 | void init_helper() | ||
843 | 51 | { | ||
844 | 52 | qDebug() << Q_FUNC_INFO; | ||
845 | 53 | helper_.reset(new RestoreHelper(DEKKO_APP_ID), [](Helper *h){h->deleteLater();}); // TODO change this to a restore helper | ||
846 | 54 | qDebug() << "Helper " << static_cast<void*>(helper_.data()) << " was created"; | ||
847 | 55 | } | ||
848 | 56 | |||
849 | 57 | void ask_for_downloader() | ||
850 | 58 | { | ||
851 | 59 | qDebug() << "asking storage framework for a socket for reading"; | ||
852 | 60 | |||
853 | 61 | QString file_name; | ||
854 | 62 | task_data_.metadata.get_property(Metadata::FILE_NAME_KEY, file_name); | ||
855 | 63 | if (file_name.isEmpty()) | ||
856 | 64 | { | ||
857 | 65 | qWarning() << "ERROR: the restore task does not provide a valid file name to read from."; | ||
858 | 66 | return; | ||
859 | 67 | } | ||
860 | 68 | |||
861 | 69 | QString dir_name; | ||
862 | 70 | task_data_.metadata.get_property(Metadata::DIR_NAME_KEY, dir_name); | ||
863 | 71 | if (dir_name.isEmpty()) | ||
864 | 72 | { | ||
865 | 73 | qWarning() << "ERROR: the restore task does not provide a valid directory name."; | ||
866 | 74 | return; | ||
867 | 75 | } | ||
868 | 76 | |||
869 | 77 | // extract the dir_name. | ||
870 | 78 | connections_.connect_future( | ||
871 | 79 | storage_->get_new_downloader(dir_name, file_name), | ||
872 | 80 | std::function<void(std::shared_ptr<Downloader> const&)>{ | ||
873 | 81 | [this](std::shared_ptr<Downloader> const& downloader){ | ||
874 | 82 | qDebug() << "Downloader is" << static_cast<void*>(downloader.get()); | ||
875 | 83 | int fd {-1}; | ||
876 | 84 | if (downloader) { | ||
877 | 85 | qDebug() << "Helper is " << static_cast<void*>(helper_.data()); | ||
878 | 86 | auto restore_helper = qSharedPointerDynamicCast<RestoreHelper>(helper_); | ||
879 | 87 | restore_helper->set_downloader(downloader); | ||
880 | 88 | fd = restore_helper->get_helper_socket(); | ||
881 | 89 | } | ||
882 | 90 | qDebug("emitting task_socket_ready(socket=%d)", fd); | ||
883 | 91 | Q_EMIT(q_ptr->task_socket_ready(fd)); | ||
884 | 92 | } | ||
885 | 93 | } | ||
886 | 94 | ); | ||
887 | 95 | } | ||
888 | 96 | private: | ||
889 | 97 | ConnectionHelper connections_; | ||
890 | 98 | }; | ||
891 | 99 | |||
892 | 100 | KeeperTaskRestore::KeeperTaskRestore(TaskData & task_data, | ||
893 | 101 | QSharedPointer<HelperRegistry> const & helper_registry, | ||
894 | 102 | QSharedPointer<StorageFrameworkClient> const & storage, | ||
895 | 103 | QObject *parent) | ||
896 | 104 | : KeeperTask(*new KeeperTaskRestorePrivate(this, task_data, helper_registry, storage), parent) | ||
897 | 105 | { | ||
898 | 106 | } | ||
899 | 107 | |||
900 | 108 | KeeperTaskRestore::~KeeperTaskRestore() = default; | ||
901 | 109 | |||
902 | 110 | QStringList KeeperTaskRestore::get_helper_urls() const | ||
903 | 111 | { | ||
904 | 112 | Q_D(const KeeperTaskRestore); | ||
905 | 113 | |||
906 | 114 | return d->get_helper_urls(); | ||
907 | 115 | } | ||
908 | 116 | |||
909 | 117 | void KeeperTaskRestore::init_helper() | ||
910 | 118 | { | ||
911 | 119 | Q_D(KeeperTaskRestore); | ||
912 | 120 | |||
913 | 121 | d->init_helper(); | ||
914 | 122 | } | ||
915 | 123 | |||
916 | 124 | void KeeperTaskRestore::ask_for_downloader() | ||
917 | 125 | { | ||
918 | 126 | Q_D(KeeperTaskRestore); | ||
919 | 127 | |||
920 | 128 | d->ask_for_downloader(); | ||
921 | 129 | } | ||
922 | 0 | 130 | ||
923 | === added file 'src/service/keeper-task-restore.h' | |||
924 | --- src/service/keeper-task-restore.h 1970-01-01 00:00:00 +0000 | |||
925 | +++ src/service/keeper-task-restore.h 2016-11-17 00:23:33 +0000 | |||
926 | @@ -0,0 +1,46 @@ | |||
927 | 1 | /* | ||
928 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
929 | 3 | * | ||
930 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
931 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
932 | 6 | * by the Free Software Foundation. | ||
933 | 7 | * | ||
934 | 8 | * This program is distributed in the hope that it will be useful, but | ||
935 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
936 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
937 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
938 | 12 | * | ||
939 | 13 | * You should have received a copy of the GNU General Public License along | ||
940 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
941 | 15 | * | ||
942 | 16 | * Authors: | ||
943 | 17 | * Xavi Garcia <xavi.garcia.mena@canonical.com> | ||
944 | 18 | * Charles Kerr <charles.kerr@canonical.com> | ||
945 | 19 | */ | ||
946 | 20 | #pragma once | ||
947 | 21 | |||
948 | 22 | #include "keeper-task.h" | ||
949 | 23 | |||
950 | 24 | class KeeperTaskRestorePrivate; | ||
951 | 25 | |||
952 | 26 | class KeeperTaskRestore : public KeeperTask | ||
953 | 27 | { | ||
954 | 28 | Q_OBJECT | ||
955 | 29 | Q_DECLARE_PRIVATE(KeeperTaskRestore) | ||
956 | 30 | |||
957 | 31 | public: | ||
958 | 32 | KeeperTaskRestore(TaskData & task_data, | ||
959 | 33 | QSharedPointer<HelperRegistry> const & helper_registry, | ||
960 | 34 | QSharedPointer<StorageFrameworkClient> const & storage, | ||
961 | 35 | QObject *parent = nullptr); | ||
962 | 36 | virtual ~KeeperTaskRestore(); | ||
963 | 37 | |||
964 | 38 | Q_DISABLE_COPY(KeeperTaskRestore) | ||
965 | 39 | |||
966 | 40 | void ask_for_downloader(); | ||
967 | 41 | |||
968 | 42 | protected: | ||
969 | 43 | QStringList get_helper_urls() const override; | ||
970 | 44 | void init_helper() override; | ||
971 | 45 | |||
972 | 46 | }; | ||
973 | 0 | 47 | ||
974 | === modified file 'src/service/keeper-task.cpp' | |||
975 | --- src/service/keeper-task.cpp 2016-09-30 09:23:09 +0000 | |||
976 | +++ src/service/keeper-task.cpp 2016-11-17 00:23:33 +0000 | |||
977 | @@ -28,7 +28,7 @@ | |||
978 | 28 | #include <QString> | 28 | #include <QString> |
979 | 29 | 29 | ||
980 | 30 | KeeperTaskPrivate::KeeperTaskPrivate(KeeperTask * keeper_task, | 30 | KeeperTaskPrivate::KeeperTaskPrivate(KeeperTask * keeper_task, |
982 | 31 | KeeperTask::TaskData const & task_data, | 31 | KeeperTask::TaskData & task_data, |
983 | 32 | QSharedPointer<HelperRegistry> const & helper_registry, | 32 | QSharedPointer<HelperRegistry> const & helper_registry, |
984 | 33 | QSharedPointer<StorageFrameworkClient> const & storage) | 33 | QSharedPointer<StorageFrameworkClient> const & storage) |
985 | 34 | : q_ptr(keeper_task) | 34 | : q_ptr(keeper_task) |
986 | @@ -132,7 +132,7 @@ | |||
987 | 132 | auto const percent_done = helper_->percent_done(); | 132 | auto const percent_done = helper_->percent_done(); |
988 | 133 | ret.insert(QStringLiteral("percent-done"), double(percent_done)); | 133 | ret.insert(QStringLiteral("percent-done"), double(percent_done)); |
989 | 134 | 134 | ||
991 | 135 | if (task_data_.action == "failed") | 135 | if (task_data_.action == "failed" || task_data_.action == "cancelled") |
992 | 136 | ret.insert(QStringLiteral("error"), task_data_.error); | 136 | ret.insert(QStringLiteral("error"), task_data_.error); |
993 | 137 | 137 | ||
994 | 138 | ret.insert(QStringLiteral("uuid"), uuid); | 138 | ret.insert(QStringLiteral("uuid"), uuid); |
995 | @@ -145,8 +145,13 @@ | |||
996 | 145 | 145 | ||
997 | 146 | void KeeperTaskPrivate::calculate_and_notify_state(Helper::State state) | 146 | void KeeperTaskPrivate::calculate_and_notify_state(Helper::State state) |
998 | 147 | { | 147 | { |
999 | 148 | recalculate_task_state(); | ||
1000 | 149 | Q_EMIT(q_ptr->task_state_changed(state)); | ||
1001 | 150 | } | ||
1002 | 151 | |||
1003 | 152 | void KeeperTaskPrivate::recalculate_task_state() | ||
1004 | 153 | { | ||
1005 | 148 | state_ = calculate_task_state(); | 154 | state_ = calculate_task_state(); |
1006 | 149 | Q_EMIT(q_ptr->task_state_changed(state)); | ||
1007 | 150 | } | 155 | } |
1008 | 151 | 156 | ||
1009 | 152 | void KeeperTaskPrivate::cancel() | 157 | void KeeperTaskPrivate::cancel() |
1010 | @@ -175,7 +180,20 @@ | |||
1011 | 175 | return ret; | 180 | return ret; |
1012 | 176 | } | 181 | } |
1013 | 177 | 182 | ||
1015 | 178 | KeeperTask::KeeperTask(TaskData const & task_data, | 183 | QString KeeperTaskPrivate::to_string(Helper::State state) |
1016 | 184 | { | ||
1017 | 185 | if (helper_) | ||
1018 | 186 | { | ||
1019 | 187 | return helper_->to_string(state); | ||
1020 | 188 | } | ||
1021 | 189 | else | ||
1022 | 190 | { | ||
1023 | 191 | qWarning() << "Asking for the string of a state when the helper is not initialized yet"; | ||
1024 | 192 | return "bug"; | ||
1025 | 193 | } | ||
1026 | 194 | } | ||
1027 | 195 | |||
1028 | 196 | KeeperTask::KeeperTask(TaskData & task_data, | ||
1029 | 179 | QSharedPointer<HelperRegistry> const & helper_registry, | 197 | QSharedPointer<HelperRegistry> const & helper_registry, |
1030 | 180 | QSharedPointer<StorageFrameworkClient> const & storage, | 198 | QSharedPointer<StorageFrameworkClient> const & storage, |
1031 | 181 | QObject *parent) | 199 | QObject *parent) |
1032 | @@ -207,6 +225,14 @@ | |||
1033 | 207 | return d->state(); | 225 | return d->state(); |
1034 | 208 | } | 226 | } |
1035 | 209 | 227 | ||
1036 | 228 | void KeeperTask::recalculate_task_state() | ||
1037 | 229 | { | ||
1038 | 230 | Q_D(KeeperTask); | ||
1039 | 231 | |||
1040 | 232 | return d->recalculate_task_state(); | ||
1041 | 233 | } | ||
1042 | 234 | |||
1043 | 235 | |||
1044 | 210 | QVariantMap KeeperTask::get_initial_state(KeeperTask::TaskData const &td) | 236 | QVariantMap KeeperTask::get_initial_state(KeeperTask::TaskData const &td) |
1045 | 211 | { | 237 | { |
1046 | 212 | return KeeperTaskPrivate::get_initial_state(td); | 238 | return KeeperTaskPrivate::get_initial_state(td); |
1047 | @@ -218,3 +244,10 @@ | |||
1048 | 218 | 244 | ||
1049 | 219 | return d->cancel(); | 245 | return d->cancel(); |
1050 | 220 | } | 246 | } |
1051 | 247 | |||
1052 | 248 | QString KeeperTask::to_string(Helper::State state) | ||
1053 | 249 | { | ||
1054 | 250 | Q_D(KeeperTask); | ||
1055 | 251 | |||
1056 | 252 | return d->to_string(state); | ||
1057 | 253 | } | ||
1058 | 221 | 254 | ||
1059 | === modified file 'src/service/keeper-task.h' | |||
1060 | --- src/service/keeper-task.h 2016-09-28 13:42:21 +0000 | |||
1061 | +++ src/service/keeper-task.h 2016-11-17 00:23:33 +0000 | |||
1062 | @@ -44,7 +44,7 @@ | |||
1063 | 44 | Metadata metadata; | 44 | Metadata metadata; |
1064 | 45 | }; | 45 | }; |
1065 | 46 | 46 | ||
1067 | 47 | KeeperTask(TaskData const & task_data, | 47 | KeeperTask(TaskData & task_data, |
1068 | 48 | QSharedPointer<HelperRegistry> const & helper_registry, | 48 | QSharedPointer<HelperRegistry> const & helper_registry, |
1069 | 49 | QSharedPointer<StorageFrameworkClient> const & storage, | 49 | QSharedPointer<StorageFrameworkClient> const & storage, |
1070 | 50 | QObject *parent = nullptr); | 50 | QObject *parent = nullptr); |
1071 | @@ -54,11 +54,13 @@ | |||
1072 | 54 | 54 | ||
1073 | 55 | bool start(); | 55 | bool start(); |
1074 | 56 | QVariantMap state() const; | 56 | QVariantMap state() const; |
1075 | 57 | void recalculate_task_state(); | ||
1076 | 57 | 58 | ||
1077 | 58 | static QVariantMap get_initial_state(KeeperTask::TaskData const &td); | 59 | static QVariantMap get_initial_state(KeeperTask::TaskData const &td); |
1078 | 59 | 60 | ||
1079 | 60 | void cancel(); | 61 | void cancel(); |
1080 | 61 | 62 | ||
1081 | 63 | QString to_string(Helper::State state); | ||
1082 | 62 | Q_SIGNALS: | 64 | Q_SIGNALS: |
1083 | 63 | void task_state_changed(Helper::State state); | 65 | void task_state_changed(Helper::State state); |
1084 | 64 | void task_socket_ready(int socket_descriptor); | 66 | void task_socket_ready(int socket_descriptor); |
1085 | 65 | 67 | ||
1086 | === modified file 'src/service/keeper-user.cpp' | |||
1087 | --- src/service/keeper-user.cpp 2016-10-28 15:11:21 +0000 | |||
1088 | +++ src/service/keeper-user.cpp 2016-11-17 00:23:33 +0000 | |||
1089 | @@ -70,9 +70,11 @@ | |||
1090 | 70 | void | 70 | void |
1091 | 71 | KeeperUser::StartRestore (const QStringList& keys) | 71 | KeeperUser::StartRestore (const QStringList& keys) |
1092 | 72 | { | 72 | { |
1094 | 73 | // FIXME: writeme | 73 | Q_ASSERT(calledFromDBus()); |
1095 | 74 | 74 | ||
1097 | 75 | qDebug() << keys; | 75 | auto bus = connection(); |
1098 | 76 | auto& msg = message(); | ||
1099 | 77 | keeper_.start_tasks(keys, bus, msg, true); | ||
1100 | 76 | } | 78 | } |
1101 | 77 | 79 | ||
1102 | 78 | QVariantDictMap | 80 | QVariantDictMap |
1103 | 79 | 81 | ||
1104 | === modified file 'src/service/keeper.cpp' | |||
1105 | --- src/service/keeper.cpp 2016-10-28 15:11:21 +0000 | |||
1106 | +++ src/service/keeper.cpp 2016-11-17 00:23:33 +0000 | |||
1107 | @@ -76,14 +76,25 @@ | |||
1108 | 76 | { | 76 | { |
1109 | 77 | } | 77 | } |
1110 | 78 | 78 | ||
1111 | 79 | enum class ChoicesType { BACKUP_CHOICES, RESTORES_CHOICES }; | ||
1112 | 80 | |||
1113 | 79 | ~KeeperPrivate() =default; | 81 | ~KeeperPrivate() =default; |
1114 | 80 | 82 | ||
1115 | 81 | Q_DISABLE_COPY(KeeperPrivate) | 83 | Q_DISABLE_COPY(KeeperPrivate) |
1116 | 82 | 84 | ||
1117 | 83 | void start_tasks(QStringList const & uuids, | 85 | void start_tasks(QStringList const & uuids, |
1120 | 84 | QDBusConnection bus, | 86 | QDBusConnection bus, |
1121 | 85 | QDBusMessage const & msg) | 87 | QDBusMessage const & msg, |
1122 | 88 | bool reset_cached_choices) | ||
1123 | 86 | { | 89 | { |
1124 | 90 | if (reset_cached_choices) | ||
1125 | 91 | { | ||
1126 | 92 | // if we start a restore right after a backup the uuid | ||
1127 | 93 | // will be found as a backup uuid. | ||
1128 | 94 | // Just clear the backup cache to avoid that. | ||
1129 | 95 | cached_backup_choices_.clear(); | ||
1130 | 96 | } | ||
1131 | 97 | |||
1132 | 87 | auto get_tasks = [](const QVector<Metadata>& pool, QStringList const& keys){ | 98 | auto get_tasks = [](const QVector<Metadata>& pool, QStringList const& keys){ |
1133 | 88 | QMap<QString,Metadata> tasks; | 99 | QMap<QString,Metadata> tasks; |
1134 | 89 | for (auto const& key : keys) { | 100 | for (auto const& key : keys) { |
1135 | @@ -95,9 +106,10 @@ | |||
1136 | 95 | }; | 106 | }; |
1137 | 96 | 107 | ||
1138 | 97 | // async part | 108 | // async part |
1139 | 109 | qDebug() << "Looking for backup options...."; | ||
1140 | 98 | connections_.connect_oneshot( | 110 | connections_.connect_oneshot( |
1141 | 99 | this, | 111 | this, |
1143 | 100 | &KeeperPrivate::choices_ready, | 112 | &KeeperPrivate::backup_choices_ready, |
1144 | 101 | std::function<void()>{[this, uuids, msg, bus, get_tasks](){ | 113 | std::function<void()>{[this, uuids, msg, bus, get_tasks](){ |
1145 | 102 | auto tasks = get_tasks(cached_backup_choices_, uuids); | 114 | auto tasks = get_tasks(cached_backup_choices_, uuids); |
1146 | 103 | if (!tasks.empty()) | 115 | if (!tasks.empty()) |
1147 | @@ -114,12 +126,15 @@ | |||
1148 | 114 | } | 126 | } |
1149 | 115 | else // restore | 127 | else // restore |
1150 | 116 | { | 128 | { |
1151 | 129 | qDebug() << "Looking for restore options...."; | ||
1152 | 117 | connections_.connect_oneshot( | 130 | connections_.connect_oneshot( |
1153 | 118 | this, | 131 | this, |
1155 | 119 | &KeeperPrivate::choices_ready, | 132 | &KeeperPrivate::restore_choices_ready, |
1156 | 120 | std::function<void()>{[this, uuids, msg, bus, get_tasks](){ | 133 | std::function<void()>{[this, uuids, msg, bus, get_tasks](){ |
1157 | 134 | qDebug() << "Choices ready"; | ||
1158 | 121 | auto unhandled = QSet<QString>::fromList(uuids); | 135 | auto unhandled = QSet<QString>::fromList(uuids); |
1159 | 122 | auto restore_tasks = get_tasks(cached_restore_choices_, uuids); | 136 | auto restore_tasks = get_tasks(cached_restore_choices_, uuids); |
1160 | 137 | qDebug() << "After getting tasks..."; | ||
1161 | 123 | if (!restore_tasks.empty() && task_manager_.start_restore(restore_tasks.values())) | 138 | if (!restore_tasks.empty() && task_manager_.start_restore(restore_tasks.values())) |
1162 | 124 | unhandled.subtract(QSet<QString>::fromList(restore_tasks.keys())); | 139 | unhandled.subtract(QSet<QString>::fromList(restore_tasks.keys())); |
1163 | 125 | 140 | ||
1164 | @@ -130,34 +145,58 @@ | |||
1165 | 130 | bus.send(reply); | 145 | bus.send(reply); |
1166 | 131 | }} | 146 | }} |
1167 | 132 | ); | 147 | ); |
1169 | 133 | get_restore_choices(); | 148 | get_choices(restore_choices_, KeeperPrivate::ChoicesType::RESTORES_CHOICES); |
1170 | 134 | } | 149 | } |
1171 | 135 | }} | 150 | }} |
1172 | 136 | ); | 151 | ); |
1173 | 137 | 152 | ||
1175 | 138 | get_backup_choices(); | 153 | get_choices(backup_choices_, KeeperPrivate::ChoicesType::BACKUP_CHOICES); |
1176 | 139 | msg.setDelayedReply(true); | 154 | msg.setDelayedReply(true); |
1177 | 140 | } | 155 | } |
1178 | 141 | 156 | ||
1182 | 142 | void get_backup_choices() | 157 | void emit_choices_ready(ChoicesType type) |
1183 | 143 | { | 158 | { |
1184 | 144 | if (cached_backup_choices_.isEmpty()) | 159 | switch(type) |
1185 | 160 | { | ||
1186 | 161 | case KeeperPrivate::ChoicesType::BACKUP_CHOICES: | ||
1187 | 162 | Q_EMIT(backup_choices_ready()); | ||
1188 | 163 | break; | ||
1189 | 164 | case KeeperPrivate::ChoicesType::RESTORES_CHOICES: | ||
1190 | 165 | Q_EMIT(restore_choices_ready()); | ||
1191 | 166 | break; | ||
1192 | 167 | } | ||
1193 | 168 | } | ||
1194 | 169 | void get_choices(const QSharedPointer<MetadataProvider> & provider, ChoicesType type) | ||
1195 | 170 | { | ||
1196 | 171 | qDebug() << Q_FUNC_INFO; | ||
1197 | 172 | bool check_empty = (type == KeeperPrivate::ChoicesType::BACKUP_CHOICES) | ||
1198 | 173 | ? cached_backup_choices_.isEmpty() : cached_restore_choices_.isEmpty(); | ||
1199 | 174 | if (check_empty) | ||
1200 | 145 | { | 175 | { |
1201 | 146 | connections_.connect_oneshot( | 176 | connections_.connect_oneshot( |
1203 | 147 | backup_choices_.data(), | 177 | provider.data(), |
1204 | 148 | &MetadataProvider::finished, | 178 | &MetadataProvider::finished, |
1209 | 149 | std::function<void()>{[this](){ | 179 | std::function<void()>{[this, provider, type](){ |
1210 | 150 | qDebug() << "Get backups finished"; | 180 | qDebug() << "Get choices finished"; |
1211 | 151 | cached_backup_choices_ = backup_choices_->get_backups(); | 181 | switch (type) |
1212 | 152 | Q_EMIT(choices_ready()); | 182 | { |
1213 | 183 | case KeeperPrivate::ChoicesType::BACKUP_CHOICES: | ||
1214 | 184 | cached_backup_choices_ = provider->get_backups(); | ||
1215 | 185 | break; | ||
1216 | 186 | case KeeperPrivate::ChoicesType::RESTORES_CHOICES: | ||
1217 | 187 | cached_restore_choices_ = provider->get_backups(); | ||
1218 | 188 | break; | ||
1219 | 189 | }; | ||
1220 | 190 | emit_choices_ready(type); | ||
1221 | 153 | }} | 191 | }} |
1222 | 154 | ); | 192 | ); |
1223 | 155 | 193 | ||
1225 | 156 | backup_choices_->get_backups_async(); | 194 | provider->get_backups_async(); |
1226 | 157 | } | 195 | } |
1227 | 158 | else | 196 | else |
1228 | 159 | { | 197 | { |
1230 | 160 | Q_EMIT(choices_ready()); | 198 | qDebug() << "emit choices_ready()"; |
1231 | 199 | emit_choices_ready(type); | ||
1232 | 161 | } | 200 | } |
1233 | 162 | } | 201 | } |
1234 | 163 | 202 | ||
1235 | @@ -166,7 +205,7 @@ | |||
1236 | 166 | { | 205 | { |
1237 | 167 | connections_.connect_oneshot( | 206 | connections_.connect_oneshot( |
1238 | 168 | this, | 207 | this, |
1240 | 169 | &KeeperPrivate::choices_ready, | 208 | &KeeperPrivate::backup_choices_ready, |
1241 | 170 | std::function<void()>{[this, msg, bus](){ | 209 | std::function<void()>{[this, msg, bus](){ |
1242 | 171 | qDebug() << "Backup choices are ready"; | 210 | qDebug() << "Backup choices are ready"; |
1243 | 172 | // reply now to the dbus call | 211 | // reply now to the dbus call |
1244 | @@ -176,7 +215,7 @@ | |||
1245 | 176 | }} | 215 | }} |
1246 | 177 | ); | 216 | ); |
1247 | 178 | 217 | ||
1249 | 179 | get_backup_choices(); | 218 | get_choices(backup_choices_, KeeperPrivate::ChoicesType::BACKUP_CHOICES); |
1250 | 180 | msg.setDelayedReply(true); | 219 | msg.setDelayedReply(true); |
1251 | 181 | return QVariantDictMap(); | 220 | return QVariantDictMap(); |
1252 | 182 | } | 221 | } |
1253 | @@ -186,7 +225,7 @@ | |||
1254 | 186 | { | 225 | { |
1255 | 187 | connections_.connect_oneshot( | 226 | connections_.connect_oneshot( |
1256 | 188 | this, | 227 | this, |
1258 | 189 | &KeeperPrivate::choices_ready, | 228 | &KeeperPrivate::restore_choices_ready, |
1259 | 190 | std::function<void()>{[this, msg, bus](){ | 229 | std::function<void()>{[this, msg, bus](){ |
1260 | 191 | qDebug() << "Restore choices are ready"; | 230 | qDebug() << "Restore choices are ready"; |
1261 | 192 | // reply now to the dbus call | 231 | // reply now to the dbus call |
1262 | @@ -196,34 +235,11 @@ | |||
1263 | 196 | }} | 235 | }} |
1264 | 197 | ); | 236 | ); |
1265 | 198 | 237 | ||
1267 | 199 | get_restore_choices(); | 238 | get_choices(restore_choices_, KeeperPrivate::ChoicesType::RESTORES_CHOICES); |
1268 | 200 | msg.setDelayedReply(true); | 239 | msg.setDelayedReply(true); |
1269 | 201 | return QVariantDictMap(); | 240 | return QVariantDictMap(); |
1270 | 202 | } | 241 | } |
1271 | 203 | 242 | ||
1272 | 204 | // TODO REFACTOR THIS TO USE THE SAME METHOD POR RESTORES AND BACKUPS | ||
1273 | 205 | void get_restore_choices() | ||
1274 | 206 | { | ||
1275 | 207 | if (cached_restore_choices_.isEmpty()) | ||
1276 | 208 | { | ||
1277 | 209 | connections_.connect_oneshot( | ||
1278 | 210 | restore_choices_.data(), | ||
1279 | 211 | &MetadataProvider::finished, | ||
1280 | 212 | std::function<void()>{[this](){ | ||
1281 | 213 | qDebug() << "Get restores finished"; | ||
1282 | 214 | cached_restore_choices_ = restore_choices_->get_backups(); | ||
1283 | 215 | Q_EMIT(choices_ready()); | ||
1284 | 216 | }} | ||
1285 | 217 | ); | ||
1286 | 218 | |||
1287 | 219 | restore_choices_->get_backups_async(); | ||
1288 | 220 | } | ||
1289 | 221 | else | ||
1290 | 222 | { | ||
1291 | 223 | Q_EMIT(choices_ready()); | ||
1292 | 224 | } | ||
1293 | 225 | } | ||
1294 | 226 | |||
1295 | 227 | QVariantDictMap get_state() const | 243 | QVariantDictMap get_state() const |
1296 | 228 | { | 244 | { |
1297 | 229 | return task_manager_.get_state(); | 245 | return task_manager_.get_state(); |
1298 | @@ -233,7 +249,7 @@ | |||
1299 | 233 | QDBusMessage const & msg, | 249 | QDBusMessage const & msg, |
1300 | 234 | quint64 n_bytes) | 250 | quint64 n_bytes) |
1301 | 235 | { | 251 | { |
1303 | 236 | qDebug("Keeper::StartBackup(n_bytes=%zu)", size_t(n_bytes)); | 252 | qDebug() << Q_FUNC_INFO << "n_bytes:" << n_bytes; |
1304 | 237 | 253 | ||
1305 | 238 | connections_.connect_oneshot( | 254 | connections_.connect_oneshot( |
1306 | 239 | &task_manager_, | 255 | &task_manager_, |
1307 | @@ -248,7 +264,7 @@ | |||
1308 | 248 | } | 264 | } |
1309 | 249 | ); | 265 | ); |
1310 | 250 | 266 | ||
1312 | 251 | qDebug() << "Asking for an storage framework socket to the task manager"; | 267 | qDebug() << "Asking TaskManager for a socket to upload to"; |
1313 | 252 | task_manager_.ask_for_uploader(n_bytes); | 268 | task_manager_.ask_for_uploader(n_bytes); |
1314 | 253 | 269 | ||
1315 | 254 | // tell the caller that we'll be responding async | 270 | // tell the caller that we'll be responding async |
1316 | @@ -256,12 +272,41 @@ | |||
1317 | 256 | return QDBusUnixFileDescriptor(0); | 272 | return QDBusUnixFileDescriptor(0); |
1318 | 257 | } | 273 | } |
1319 | 258 | 274 | ||
1320 | 275 | |||
1321 | 276 | QDBusUnixFileDescriptor start_restore(QDBusConnection bus, | ||
1322 | 277 | QDBusMessage const & msg) | ||
1323 | 278 | { | ||
1324 | 279 | qDebug() << Q_FUNC_INFO; | ||
1325 | 280 | |||
1326 | 281 | connections_.connect_oneshot( | ||
1327 | 282 | &task_manager_, | ||
1328 | 283 | &TaskManager::socket_ready, | ||
1329 | 284 | std::function<void(int)>{ | ||
1330 | 285 | [bus,msg](int fd){ | ||
1331 | 286 | qDebug("TaskManager::ask_for_downloader() returned socket %d", fd); | ||
1332 | 287 | auto reply = msg.createReply(); | ||
1333 | 288 | reply << QVariant::fromValue(QDBusUnixFileDescriptor(fd)); | ||
1334 | 289 | bus.send(reply); | ||
1335 | 290 | } | ||
1336 | 291 | } | ||
1337 | 292 | ); | ||
1338 | 293 | |||
1339 | 294 | qDebug() << "Asking TaskManager for a socket to download from"; | ||
1340 | 295 | task_manager_.ask_for_downloader(); | ||
1341 | 296 | |||
1342 | 297 | // tell the caller that we'll be responding async | ||
1343 | 298 | msg.setDelayedReply(true); | ||
1344 | 299 | return QDBusUnixFileDescriptor(0); | ||
1345 | 300 | } | ||
1346 | 301 | |||
1347 | 259 | void cancel() | 302 | void cancel() |
1348 | 260 | { | 303 | { |
1349 | 261 | task_manager_.cancel(); | 304 | task_manager_.cancel(); |
1350 | 262 | } | 305 | } |
1351 | 306 | |||
1352 | 263 | Q_SIGNALS: | 307 | Q_SIGNALS: |
1354 | 264 | void choices_ready(); | 308 | void backup_choices_ready(); |
1355 | 309 | void restore_choices_ready(); | ||
1356 | 265 | 310 | ||
1357 | 266 | private: | 311 | private: |
1358 | 267 | 312 | ||
1359 | @@ -305,11 +350,12 @@ | |||
1360 | 305 | void | 350 | void |
1361 | 306 | Keeper::start_tasks(QStringList const & uuids, | 351 | Keeper::start_tasks(QStringList const & uuids, |
1362 | 307 | QDBusConnection bus, | 352 | QDBusConnection bus, |
1364 | 308 | QDBusMessage const & msg) | 353 | QDBusMessage const & msg, |
1365 | 354 | bool reset_cached_choices) | ||
1366 | 309 | { | 355 | { |
1367 | 310 | Q_D(Keeper); | 356 | Q_D(Keeper); |
1368 | 311 | 357 | ||
1370 | 312 | d->start_tasks(uuids, bus, msg); | 358 | d->start_tasks(uuids, bus, msg, reset_cached_choices); |
1371 | 313 | } | 359 | } |
1372 | 314 | 360 | ||
1373 | 315 | QDBusUnixFileDescriptor | 361 | QDBusUnixFileDescriptor |
1374 | @@ -322,6 +368,15 @@ | |||
1375 | 322 | return d->start_backup(bus, msg, n_bytes); | 368 | return d->start_backup(bus, msg, n_bytes); |
1376 | 323 | } | 369 | } |
1377 | 324 | 370 | ||
1378 | 371 | QDBusUnixFileDescriptor | ||
1379 | 372 | Keeper::StartRestore(QDBusConnection bus, | ||
1380 | 373 | QDBusMessage const & msg) | ||
1381 | 374 | { | ||
1382 | 375 | Q_D(Keeper); | ||
1383 | 376 | |||
1384 | 377 | return d->start_restore(bus, msg); | ||
1385 | 378 | } | ||
1386 | 379 | |||
1387 | 325 | QVariantDictMap | 380 | QVariantDictMap |
1388 | 326 | Keeper::get_backup_choices_var_dict_map(QDBusConnection bus, | 381 | Keeper::get_backup_choices_var_dict_map(QDBusConnection bus, |
1389 | 327 | QDBusMessage const & msg) | 382 | QDBusMessage const & msg) |
1390 | 328 | 383 | ||
1391 | === modified file 'src/service/keeper.h' | |||
1392 | --- src/service/keeper.h 2016-10-28 15:11:21 +0000 | |||
1393 | +++ src/service/keeper.h 2016-11-17 00:23:33 +0000 | |||
1394 | @@ -59,9 +59,14 @@ | |||
1395 | 59 | QDBusMessage const & message, | 59 | QDBusMessage const & message, |
1396 | 60 | quint64 nbytes); | 60 | quint64 nbytes); |
1397 | 61 | 61 | ||
1398 | 62 | |||
1399 | 63 | QDBusUnixFileDescriptor StartRestore(QDBusConnection, | ||
1400 | 64 | QDBusMessage const & message); | ||
1401 | 65 | |||
1402 | 62 | void start_tasks(QStringList const & uuids, | 66 | void start_tasks(QStringList const & uuids, |
1403 | 63 | QDBusConnection bus, | 67 | QDBusConnection bus, |
1405 | 64 | QDBusMessage const & msg); | 68 | QDBusMessage const & msg, |
1406 | 69 | bool reset_cached_choices = false); | ||
1407 | 65 | 70 | ||
1408 | 66 | QVariantDictMap get_state() const; | 71 | QVariantDictMap get_state() const; |
1409 | 67 | 72 | ||
1410 | 68 | 73 | ||
1411 | === modified file 'src/service/manifest.cpp' | |||
1412 | --- src/service/manifest.cpp 2016-10-13 12:22:31 +0000 | |||
1413 | +++ src/service/manifest.cpp 2016-11-17 00:23:33 +0000 | |||
1414 | @@ -110,8 +110,8 @@ | |||
1415 | 110 | { | 110 | { |
1416 | 111 | connections_.connect_future( | 111 | connections_.connect_future( |
1417 | 112 | storage_->get_new_downloader(dir_, MANIFEST_FILE_NAME), | 112 | storage_->get_new_downloader(dir_, MANIFEST_FILE_NAME), |
1420 | 113 | std::function<void(sf::Downloader::SPtr const&)>{ | 113 | std::function<void(std::shared_ptr<Downloader> const&)>{ |
1421 | 114 | [this](sf::Downloader::SPtr const& downloader){ | 114 | [this](std::shared_ptr<Downloader> const& downloader){ |
1422 | 115 | qDebug() << "Manifest downloader is" << static_cast<void*>(downloader.get()); | 115 | qDebug() << "Manifest downloader is" << static_cast<void*>(downloader.get()); |
1423 | 116 | if (downloader) | 116 | if (downloader) |
1424 | 117 | { | 117 | { |
1425 | @@ -125,7 +125,7 @@ | |||
1426 | 125 | } | 125 | } |
1427 | 126 | auto json_content = socket->readAll(); | 126 | auto json_content = socket->readAll(); |
1428 | 127 | from_json(json_content); | 127 | from_json(json_content); |
1430 | 128 | downloader->finish_download(); | 128 | downloader->finish(); |
1431 | 129 | finish(); | 129 | finish(); |
1432 | 130 | } | 130 | } |
1433 | 131 | else | 131 | else |
1434 | 132 | 132 | ||
1435 | === modified file 'src/service/private/keeper-task_p.h' | |||
1436 | --- src/service/private/keeper-task_p.h 2016-09-28 13:42:21 +0000 | |||
1437 | +++ src/service/private/keeper-task_p.h 2016-11-17 00:23:33 +0000 | |||
1438 | @@ -26,7 +26,7 @@ | |||
1439 | 26 | Q_DECLARE_PUBLIC(KeeperTask) | 26 | Q_DECLARE_PUBLIC(KeeperTask) |
1440 | 27 | public: | 27 | public: |
1441 | 28 | KeeperTaskPrivate(KeeperTask * keeper_task, | 28 | KeeperTaskPrivate(KeeperTask * keeper_task, |
1443 | 29 | KeeperTask::TaskData const & task_data, | 29 | KeeperTask::TaskData & task_data, |
1444 | 30 | QSharedPointer<HelperRegistry> const & helper_registry, | 30 | QSharedPointer<HelperRegistry> const & helper_registry, |
1445 | 31 | QSharedPointer<StorageFrameworkClient> const & storage); | 31 | QSharedPointer<StorageFrameworkClient> const & storage); |
1446 | 32 | 32 | ||
1447 | @@ -40,17 +40,19 @@ | |||
1448 | 40 | 40 | ||
1449 | 41 | static QVariantMap get_initial_state(KeeperTask::TaskData const &td); | 41 | static QVariantMap get_initial_state(KeeperTask::TaskData const &td); |
1450 | 42 | 42 | ||
1451 | 43 | QString to_string(Helper::State state); | ||
1452 | 43 | protected: | 44 | protected: |
1453 | 44 | void set_current_task_action(QString const& action); | 45 | void set_current_task_action(QString const& action); |
1454 | 45 | void on_helper_percent_done_changed(float percent_done); | 46 | void on_helper_percent_done_changed(float percent_done); |
1455 | 46 | QVariantMap calculate_task_state(); | 47 | QVariantMap calculate_task_state(); |
1456 | 47 | void calculate_and_notify_state(Helper::State state); | 48 | void calculate_and_notify_state(Helper::State state); |
1457 | 49 | void recalculate_task_state(); | ||
1458 | 48 | void on_backup_socket_ready(std::shared_ptr<QLocalSocket> const & sf_socket); | 50 | void on_backup_socket_ready(std::shared_ptr<QLocalSocket> const & sf_socket); |
1459 | 49 | 51 | ||
1460 | 50 | virtual void on_helper_state_changed(Helper::State state); | 52 | virtual void on_helper_state_changed(Helper::State state); |
1461 | 51 | 53 | ||
1462 | 52 | KeeperTask * const q_ptr; | 54 | KeeperTask * const q_ptr; |
1464 | 53 | KeeperTask::TaskData task_data_; | 55 | KeeperTask::TaskData & task_data_; |
1465 | 54 | QSharedPointer<HelperRegistry> helper_registry_; | 56 | QSharedPointer<HelperRegistry> helper_registry_; |
1466 | 55 | QSharedPointer<StorageFrameworkClient> storage_; | 57 | QSharedPointer<StorageFrameworkClient> storage_; |
1467 | 56 | QSharedPointer<Helper> helper_; | 58 | QSharedPointer<Helper> helper_; |
1468 | 57 | 59 | ||
1469 | === modified file 'src/service/task-manager.cpp' | |||
1470 | --- src/service/task-manager.cpp 2016-11-03 10:32:49 +0000 | |||
1471 | +++ src/service/task-manager.cpp 2016-11-17 00:23:33 +0000 | |||
1472 | @@ -20,6 +20,7 @@ | |||
1473 | 20 | 20 | ||
1474 | 21 | #include "helper/metadata.h" | 21 | #include "helper/metadata.h" |
1475 | 22 | #include "keeper-task-backup.h" | 22 | #include "keeper-task-backup.h" |
1476 | 23 | #include "keeper-task-restore.h" | ||
1477 | 23 | #include "manifest.h" | 24 | #include "manifest.h" |
1478 | 24 | #include "storage-framework/storage_framework_client.h" | 25 | #include "storage-framework/storage_framework_client.h" |
1479 | 25 | #include "task-manager.h" | 26 | #include "task-manager.h" |
1480 | @@ -50,6 +51,7 @@ | |||
1481 | 50 | 51 | ||
1482 | 51 | bool start_restore(QList<Metadata> const& tasks) | 52 | bool start_restore(QList<Metadata> const& tasks) |
1483 | 52 | { | 53 | { |
1484 | 54 | qDebug() << "Starting restore..."; | ||
1485 | 53 | return start_tasks(tasks, Mode::RESTORE); | 55 | return start_tasks(tasks, Mode::RESTORE); |
1486 | 54 | } | 56 | } |
1487 | 55 | 57 | ||
1488 | @@ -78,6 +80,23 @@ | |||
1489 | 78 | } | 80 | } |
1490 | 79 | } | 81 | } |
1491 | 80 | 82 | ||
1492 | 83 | void ask_for_downloader() | ||
1493 | 84 | { | ||
1494 | 85 | qDebug() << Q_FUNC_INFO; | ||
1495 | 86 | |||
1496 | 87 | if (task_) | ||
1497 | 88 | { | ||
1498 | 89 | auto restore_task_ = qSharedPointerDynamicCast<KeeperTaskRestore>(task_); | ||
1499 | 90 | if (!restore_task_) | ||
1500 | 91 | { | ||
1501 | 92 | qWarning() << "Only restore tasks are allowed to ask for storage framework downloaders"; | ||
1502 | 93 | // TODO Mark this as an error at the current task and move to the next task | ||
1503 | 94 | return; | ||
1504 | 95 | } | ||
1505 | 96 | restore_task_->ask_for_downloader(); | ||
1506 | 97 | } | ||
1507 | 98 | } | ||
1508 | 99 | |||
1509 | 81 | void cancel() | 100 | void cancel() |
1510 | 82 | { | 101 | { |
1511 | 83 | if (task_) | 102 | if (task_) |
1512 | @@ -140,19 +159,40 @@ | |||
1513 | 140 | return success; | 159 | return success; |
1514 | 141 | } | 160 | } |
1515 | 142 | 161 | ||
1516 | 162 | void manifest_stored(bool success) | ||
1517 | 163 | { | ||
1518 | 164 | qDebug() << "Manifest upload finished success = " << success << " current task=" << current_task_; | ||
1519 | 165 | auto& td = task_data_[current_task_]; | ||
1520 | 166 | if (success) | ||
1521 | 167 | { | ||
1522 | 168 | update_task_state(td); | ||
1523 | 169 | } | ||
1524 | 170 | else | ||
1525 | 171 | { | ||
1526 | 172 | td.error = "Error storing manifest file"; | ||
1527 | 173 | set_current_task_action(task_->to_string(Helper::State::FAILED)); | ||
1528 | 174 | } | ||
1529 | 175 | active_manifest_.reset(); | ||
1530 | 176 | } | ||
1531 | 177 | |||
1532 | 143 | void on_helper_state_changed(Helper::State state) | 178 | void on_helper_state_changed(Helper::State state) |
1533 | 144 | { | 179 | { |
1535 | 145 | qDebug() << "Task State changed"; | 180 | auto backup_task_ = qSharedPointerDynamicCast<KeeperTaskBackup>(task_); |
1536 | 146 | auto& td = task_data_[current_task_]; | 181 | auto& td = task_data_[current_task_]; |
1537 | 147 | update_task_state(td); | 182 | update_task_state(td); |
1538 | 148 | 183 | ||
1539 | 184 | // for the last completed backup task we delay updating the | ||
1540 | 185 | // state until the manifest file is stored | ||
1541 | 186 | if (remaining_tasks_.size() || state != Helper::State::COMPLETE) | ||
1542 | 187 | update_task_state(td); | ||
1543 | 188 | |||
1544 | 149 | if (state == Helper::State::COMPLETE || state == Helper::State::FAILED) | 189 | if (state == Helper::State::COMPLETE || state == Helper::State::FAILED) |
1545 | 150 | { | 190 | { |
1546 | 151 | auto backup_task_ = qSharedPointerDynamicCast<KeeperTaskBackup>(task_); | ||
1547 | 152 | if (backup_task_ && state == Helper::State::COMPLETE && active_manifest_) | 191 | if (backup_task_ && state == Helper::State::COMPLETE && active_manifest_) |
1548 | 153 | { | 192 | { |
1549 | 154 | qDebug() << "Backup task finished. The file created in storage framework is: [" << backup_task_->get_file_name() << "]"; | 193 | qDebug() << "Backup task finished. The file created in storage framework is: [" << backup_task_->get_file_name() << "]"; |
1550 | 155 | td.metadata.set_property(Metadata::FILE_NAME_KEY, backup_task_->get_file_name()); | 194 | td.metadata.set_property(Metadata::FILE_NAME_KEY, backup_task_->get_file_name()); |
1551 | 195 | td.metadata.set_property(Metadata::DIR_NAME_KEY, backup_dir_name_); | ||
1552 | 156 | active_manifest_->add_entry(td.metadata); | 196 | active_manifest_->add_entry(td.metadata); |
1553 | 157 | } | 197 | } |
1554 | 158 | if (remaining_tasks_.size()) | 198 | if (remaining_tasks_.size()) |
1555 | @@ -162,9 +202,6 @@ | |||
1556 | 162 | } | 202 | } |
1557 | 163 | else | 203 | else |
1558 | 164 | { | 204 | { |
1559 | 165 | // TODO we should revisit this. | ||
1560 | 166 | // TODO Maybe we could treat the manifest storage as a new task (with a different task type) to check | ||
1561 | 167 | // TODO when all tasks are finished and prompt something to the user. | ||
1562 | 168 | if (active_manifest_ && active_manifest_->get_entries().size()) | 205 | if (active_manifest_ && active_manifest_->get_entries().size()) |
1563 | 169 | { | 206 | { |
1564 | 170 | qDebug() << "STORING MANIFEST------------"; | 207 | qDebug() << "STORING MANIFEST------------"; |
1565 | @@ -172,11 +209,7 @@ | |||
1566 | 172 | active_manifest_.data(), | 209 | active_manifest_.data(), |
1567 | 173 | &Manifest::finished, | 210 | &Manifest::finished, |
1568 | 174 | std::function<void(bool)>{[this](bool success){ | 211 | std::function<void(bool)>{[this](bool success){ |
1574 | 175 | if (!success) | 212 | manifest_stored(success); |
1570 | 176 | qWarning() << "Manifest store finished with error: " << active_manifest_->error(); | ||
1571 | 177 | else | ||
1572 | 178 | qDebug() << "Manifest store finished successfully"; | ||
1573 | 179 | active_manifest_.reset(); | ||
1575 | 180 | }} | 213 | }} |
1576 | 181 | ); | 214 | ); |
1577 | 182 | active_manifest_->store(); | 215 | active_manifest_->store(); |
1578 | @@ -203,14 +236,16 @@ | |||
1579 | 203 | qDebug() << "Creating task for uuid = " << uuid; | 236 | qDebug() << "Creating task for uuid = " << uuid; |
1580 | 204 | // initialize a new task | 237 | // initialize a new task |
1581 | 205 | 238 | ||
1583 | 206 | task_.data()->disconnect(); | 239 | if (task_) |
1584 | 240 | task_.data()->disconnect(); | ||
1585 | 241 | |||
1586 | 207 | if (mode_ == Mode::BACKUP) | 242 | if (mode_ == Mode::BACKUP) |
1587 | 208 | { | 243 | { |
1588 | 209 | task_.reset(new KeeperTaskBackup(td, helper_registry_, storage_)); | 244 | task_.reset(new KeeperTaskBackup(td, helper_registry_, storage_)); |
1589 | 210 | } | 245 | } |
1590 | 211 | else | 246 | else |
1591 | 212 | { | 247 | { |
1593 | 213 | // TODO initialize a Restore task | 248 | task_.reset(new KeeperTaskRestore(td, helper_registry_, storage_)); |
1594 | 214 | } | 249 | } |
1595 | 215 | 250 | ||
1596 | 216 | qDebug() << "task created: " << state_; | 251 | qDebug() << "task created: " << state_; |
1597 | @@ -311,6 +346,7 @@ | |||
1598 | 311 | { | 346 | { |
1599 | 312 | auto& td = task_data_[current_task_]; | 347 | auto& td = task_data_[current_task_]; |
1600 | 313 | td.action = action; | 348 | td.action = action; |
1601 | 349 | task_->recalculate_task_state(); | ||
1602 | 314 | update_task_state(td); | 350 | update_task_state(td); |
1603 | 315 | } | 351 | } |
1604 | 316 | 352 | ||
1605 | @@ -381,6 +417,13 @@ | |||
1606 | 381 | d->ask_for_uploader(n_bytes); | 417 | d->ask_for_uploader(n_bytes); |
1607 | 382 | } | 418 | } |
1608 | 383 | 419 | ||
1609 | 420 | void TaskManager::ask_for_downloader() | ||
1610 | 421 | { | ||
1611 | 422 | Q_D(TaskManager); | ||
1612 | 423 | |||
1613 | 424 | d->ask_for_downloader(); | ||
1614 | 425 | } | ||
1615 | 426 | |||
1616 | 384 | void TaskManager::cancel() | 427 | void TaskManager::cancel() |
1617 | 385 | { | 428 | { |
1618 | 386 | Q_D(TaskManager); | 429 | Q_D(TaskManager); |
1619 | 387 | 430 | ||
1620 | === modified file 'src/service/task-manager.h' | |||
1621 | --- src/service/task-manager.h 2016-09-28 13:42:21 +0000 | |||
1622 | +++ src/service/task-manager.h 2016-11-17 00:23:33 +0000 | |||
1623 | @@ -58,6 +58,8 @@ | |||
1624 | 58 | 58 | ||
1625 | 59 | void ask_for_uploader(quint64 n_bytes); | 59 | void ask_for_uploader(quint64 n_bytes); |
1626 | 60 | 60 | ||
1627 | 61 | void ask_for_downloader(); | ||
1628 | 62 | |||
1629 | 61 | void cancel(); | 63 | void cancel(); |
1630 | 62 | 64 | ||
1631 | 63 | Q_SIGNALS: | 65 | Q_SIGNALS: |
1632 | 64 | 66 | ||
1633 | === modified file 'src/storage-framework/CMakeLists.txt' | |||
1634 | --- src/storage-framework/CMakeLists.txt 2016-09-05 17:24:18 +0000 | |||
1635 | +++ src/storage-framework/CMakeLists.txt 2016-11-17 00:23:33 +0000 | |||
1636 | @@ -11,6 +11,9 @@ | |||
1637 | 11 | uploader.h | 11 | uploader.h |
1638 | 12 | sf-uploader.cpp | 12 | sf-uploader.cpp |
1639 | 13 | sf-uploader.h | 13 | sf-uploader.h |
1640 | 14 | downloader.h | ||
1641 | 15 | sf-downloader.cpp | ||
1642 | 16 | sf-downloader.h | ||
1643 | 14 | ) | 17 | ) |
1644 | 15 | 18 | ||
1645 | 16 | set_target_properties( | 19 | set_target_properties( |
1646 | 17 | 20 | ||
1647 | === added file 'src/storage-framework/downloader.h' | |||
1648 | --- src/storage-framework/downloader.h 1970-01-01 00:00:00 +0000 | |||
1649 | +++ src/storage-framework/downloader.h 2016-11-17 00:23:33 +0000 | |||
1650 | @@ -0,0 +1,46 @@ | |||
1651 | 1 | /* | ||
1652 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
1653 | 3 | * | ||
1654 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1655 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
1656 | 6 | * by the Free Software Foundation. | ||
1657 | 7 | * | ||
1658 | 8 | * This program is distributed in the hope that it will be useful, but | ||
1659 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1660 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1661 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
1662 | 12 | * | ||
1663 | 13 | * You should have received a copy of the GNU General Public License along | ||
1664 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1665 | 15 | * | ||
1666 | 16 | * Authors: | ||
1667 | 17 | * Charles Kerr <charles.kerr@canonical.com> | ||
1668 | 18 | * Xavi Garcia Mena <xavi.garcia.mena@canonical.com> | ||
1669 | 19 | */ | ||
1670 | 20 | |||
1671 | 21 | #pragma once | ||
1672 | 22 | |||
1673 | 23 | #include <QLocalSocket> | ||
1674 | 24 | #include <QObject> | ||
1675 | 25 | |||
1676 | 26 | #include <memory> | ||
1677 | 27 | |||
1678 | 28 | class Downloader: public QObject | ||
1679 | 29 | { | ||
1680 | 30 | Q_OBJECT | ||
1681 | 31 | |||
1682 | 32 | public: | ||
1683 | 33 | |||
1684 | 34 | Q_DISABLE_COPY(Downloader) | ||
1685 | 35 | |||
1686 | 36 | Downloader(QObject *parent=nullptr): QObject(parent) {} | ||
1687 | 37 | virtual ~Downloader() =default; | ||
1688 | 38 | |||
1689 | 39 | virtual std::shared_ptr<QLocalSocket> socket() =0; | ||
1690 | 40 | virtual void finish() =0; | ||
1691 | 41 | virtual qint64 file_size() const =0; | ||
1692 | 42 | |||
1693 | 43 | Q_SIGNALS: | ||
1694 | 44 | |||
1695 | 45 | void download_finished(); | ||
1696 | 46 | }; | ||
1697 | 0 | 47 | ||
1698 | === added file 'src/storage-framework/sf-downloader.cpp' | |||
1699 | --- src/storage-framework/sf-downloader.cpp 1970-01-01 00:00:00 +0000 | |||
1700 | +++ src/storage-framework/sf-downloader.cpp 2016-11-17 00:23:33 +0000 | |||
1701 | @@ -0,0 +1,71 @@ | |||
1702 | 1 | /* | ||
1703 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
1704 | 3 | * | ||
1705 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1706 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
1707 | 6 | * by the Free Software Foundation. | ||
1708 | 7 | * | ||
1709 | 8 | * This program is distributed in the hope that it will be useful, but | ||
1710 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1711 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1712 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
1713 | 12 | * | ||
1714 | 13 | * You should have received a copy of the GNU General Public License along | ||
1715 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1716 | 15 | * | ||
1717 | 16 | * Authors: | ||
1718 | 17 | * Charles Kerr <charles.kerr@canonical.com> | ||
1719 | 18 | * Xavi Garcia Mena <xavi.garcia.mena@canonical.com> | ||
1720 | 19 | */ | ||
1721 | 20 | |||
1722 | 21 | #include "storage-framework/sf-downloader.h" | ||
1723 | 22 | |||
1724 | 23 | #include <QFuture> | ||
1725 | 24 | #include <QFutureWatcher> | ||
1726 | 25 | |||
1727 | 26 | StorageFrameworkDownloader::StorageFrameworkDownloader( | ||
1728 | 27 | unity::storage::qt::client::Downloader::SPtr const& downloader, | ||
1729 | 28 | qint64 file_size, | ||
1730 | 29 | QObject *parent | ||
1731 | 30 | ): | ||
1732 | 31 | Downloader(parent), | ||
1733 | 32 | downloader_(downloader), | ||
1734 | 33 | file_size_(file_size) | ||
1735 | 34 | { | ||
1736 | 35 | qDebug() << "StorageFrameworkDownloader"; | ||
1737 | 36 | } | ||
1738 | 37 | |||
1739 | 38 | std::shared_ptr<QLocalSocket> | ||
1740 | 39 | StorageFrameworkDownloader::socket() | ||
1741 | 40 | { | ||
1742 | 41 | return downloader_->socket(); | ||
1743 | 42 | } | ||
1744 | 43 | |||
1745 | 44 | void | ||
1746 | 45 | StorageFrameworkDownloader::finish() | ||
1747 | 46 | { | ||
1748 | 47 | qDebug() << Q_FUNC_INFO << "is finishing"; | ||
1749 | 48 | |||
1750 | 49 | // connections_.connect_future( | ||
1751 | 50 | // uploader_->finish_upload(), | ||
1752 | 51 | // std::function<void(std::shared_ptr<unity::storage::qt::client::File> const&)>{ | ||
1753 | 52 | // [this](std::shared_ptr<unity::storage::qt::client::File> const& file){ | ||
1754 | 53 | // auto const success = bool(file); | ||
1755 | 54 | // qDebug() << "commit finished with" << success; | ||
1756 | 55 | // if (success) | ||
1757 | 56 | // { | ||
1758 | 57 | // file_name_after_commit_ = file->name(); | ||
1759 | 58 | // } | ||
1760 | 59 | // Q_EMIT(commit_finished(success)); | ||
1761 | 60 | // } | ||
1762 | 61 | // } | ||
1763 | 62 | // ); | ||
1764 | 63 | downloader_->finish_download(); | ||
1765 | 64 | Q_EMIT(download_finished()); // TODO add the code to call finish_download | ||
1766 | 65 | } | ||
1767 | 66 | |||
1768 | 67 | qint64 | ||
1769 | 68 | StorageFrameworkDownloader::file_size() const | ||
1770 | 69 | { | ||
1771 | 70 | return file_size_; | ||
1772 | 71 | } | ||
1773 | 0 | 72 | ||
1774 | === added file 'src/storage-framework/sf-downloader.h' | |||
1775 | --- src/storage-framework/sf-downloader.h 1970-01-01 00:00:00 +0000 | |||
1776 | +++ src/storage-framework/sf-downloader.h 2016-11-17 00:23:33 +0000 | |||
1777 | @@ -0,0 +1,48 @@ | |||
1778 | 1 | /* | ||
1779 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
1780 | 3 | * | ||
1781 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1782 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
1783 | 6 | * by the Free Software Foundation. | ||
1784 | 7 | * | ||
1785 | 8 | * This program is distributed in the hope that it will be useful, but | ||
1786 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1787 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1788 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
1789 | 12 | * | ||
1790 | 13 | * You should have received a copy of the GNU General Public License along | ||
1791 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1792 | 15 | * | ||
1793 | 16 | * Authors: | ||
1794 | 17 | * Charles Kerr <charles.kerr@canonical.com> | ||
1795 | 18 | */ | ||
1796 | 19 | |||
1797 | 20 | #pragma once | ||
1798 | 21 | |||
1799 | 22 | #include "util/connection-helper.h" | ||
1800 | 23 | #include "storage-framework/downloader.h" | ||
1801 | 24 | |||
1802 | 25 | #include <unity/storage/qt/client/client-api.h> | ||
1803 | 26 | |||
1804 | 27 | #include <QLocalSocket> | ||
1805 | 28 | |||
1806 | 29 | #include <memory> | ||
1807 | 30 | |||
1808 | 31 | class StorageFrameworkDownloader final: public Downloader | ||
1809 | 32 | { | ||
1810 | 33 | public: | ||
1811 | 34 | |||
1812 | 35 | StorageFrameworkDownloader(unity::storage::qt::client::Downloader::SPtr const& uploader, | ||
1813 | 36 | qint64 file_size, | ||
1814 | 37 | QObject * parent = nullptr); | ||
1815 | 38 | std::shared_ptr<QLocalSocket> socket() override; | ||
1816 | 39 | void finish() override; | ||
1817 | 40 | qint64 file_size() const override; | ||
1818 | 41 | |||
1819 | 42 | private: | ||
1820 | 43 | |||
1821 | 44 | unity::storage::qt::client::Downloader::SPtr const downloader_; | ||
1822 | 45 | qint64 file_size_; | ||
1823 | 46 | |||
1824 | 47 | ConnectionHelper connections_; | ||
1825 | 48 | }; | ||
1826 | 0 | 49 | ||
1827 | === modified file 'src/storage-framework/storage_framework_client.cpp' | |||
1828 | --- src/storage-framework/storage_framework_client.cpp 2016-11-03 10:32:49 +0000 | |||
1829 | +++ src/storage-framework/storage_framework_client.cpp 2016-11-17 00:23:33 +0000 | |||
1830 | @@ -19,6 +19,7 @@ | |||
1831 | 19 | */ | 19 | */ |
1832 | 20 | 20 | ||
1833 | 21 | #include "storage-framework/storage_framework_client.h" | 21 | #include "storage-framework/storage_framework_client.h" |
1834 | 22 | #include "storage-framework/sf-downloader.h" | ||
1835 | 22 | #include "storage-framework/sf-uploader.h" | 23 | #include "storage-framework/sf-uploader.h" |
1836 | 23 | 24 | ||
1837 | 24 | #include <QDateTime> | 25 | #include <QDateTime> |
1838 | @@ -39,7 +40,7 @@ | |||
1839 | 39 | { | 40 | { |
1840 | 40 | } | 41 | } |
1841 | 41 | 42 | ||
1843 | 42 | StorageFrameworkClient::~StorageFrameworkClient() =default; | 43 | StorageFrameworkClient::~StorageFrameworkClient() = default; |
1844 | 43 | 44 | ||
1845 | 44 | /*** | 45 | /*** |
1846 | 45 | **** | 46 | **** |
1847 | @@ -154,10 +155,10 @@ | |||
1848 | 154 | return fi.future(); | 155 | return fi.future(); |
1849 | 155 | } | 156 | } |
1850 | 156 | 157 | ||
1852 | 157 | QFuture<sf::Downloader::SPtr> | 158 | QFuture<std::shared_ptr<Downloader>> |
1853 | 158 | StorageFrameworkClient::get_new_downloader(QString const & dir_name, QString const & file_name) | 159 | StorageFrameworkClient::get_new_downloader(QString const & dir_name, QString const & file_name) |
1854 | 159 | { | 160 | { |
1856 | 160 | QFutureInterface<sf::Downloader::SPtr> fi; | 161 | QFutureInterface<std::shared_ptr<Downloader>> fi; |
1857 | 161 | 162 | ||
1858 | 162 | add_roots_task([this, fi, dir_name, file_name](QVector<sf::Root::SPtr> const& roots) | 163 | add_roots_task([this, fi, dir_name, file_name](QVector<sf::Root::SPtr> const& roots) |
1859 | 163 | { | 164 | { |
1860 | @@ -171,7 +172,7 @@ | |||
1861 | 171 | if (!keeper_root) | 172 | if (!keeper_root) |
1862 | 172 | { | 173 | { |
1863 | 173 | qWarning() << "Error accessing keeper root folder"; | 174 | qWarning() << "Error accessing keeper root folder"; |
1865 | 174 | sf::Downloader::SPtr ret; | 175 | std::shared_ptr<Downloader> ret; |
1866 | 175 | QFutureInterface<decltype(ret)> qfi(fi); | 176 | QFutureInterface<decltype(ret)> qfi(fi); |
1867 | 176 | qfi.reportResult(ret); | 177 | qfi.reportResult(ret); |
1868 | 177 | qfi.reportFinished(); | 178 | qfi.reportFinished(); |
1869 | @@ -183,27 +184,27 @@ | |||
1870 | 183 | get_storage_framework_file(keeper_root, file_name), | 184 | get_storage_framework_file(keeper_root, file_name), |
1871 | 184 | std::function<void(sf::File::SPtr const&)>{ | 185 | std::function<void(sf::File::SPtr const&)>{ |
1872 | 185 | [this, fi](sf::File::SPtr const& sf_file){ | 186 | [this, fi](sf::File::SPtr const& sf_file){ |
1873 | 186 | sf::Downloader::SPtr ret_null; | ||
1874 | 187 | if (sf_file) { | 187 | if (sf_file) { |
1875 | 188 | connection_helper_.connect_future( | 188 | connection_helper_.connect_future( |
1876 | 189 | sf_file->create_downloader(), | 189 | sf_file->create_downloader(), |
1877 | 190 | std::function<void(sf::Downloader::SPtr const&)>{ | 190 | std::function<void(sf::Downloader::SPtr const&)>{ |
1880 | 191 | [this, fi, ret_null](sf::Downloader::SPtr const& sf_downloader){ | 191 | [this, fi, sf_file](sf::Downloader::SPtr const& sf_downloader){ |
1881 | 192 | QFutureInterface<decltype(ret_null)> qfi(fi); | 192 | std::shared_ptr<Downloader> ret; |
1882 | 193 | if (sf_downloader) | 193 | if (sf_downloader) |
1883 | 194 | { | 194 | { |
1892 | 195 | qfi.reportResult(sf_downloader); | 195 | ret.reset( |
1893 | 196 | qfi.reportFinished(); | 196 | new StorageFrameworkDownloader(sf_downloader, sf_file->size(), this), |
1894 | 197 | } | 197 | [](Downloader* d){d->deleteLater();} |
1895 | 198 | else | 198 | ); |
1896 | 199 | { | 199 | } |
1897 | 200 | qfi.reportResult(ret_null); | 200 | QFutureInterface<decltype(ret)> qfi(fi); |
1898 | 201 | qfi.reportFinished(); | 201 | qfi.reportResult(ret); |
1899 | 202 | } | 202 | qfi.reportFinished(); |
1900 | 203 | } | 203 | } |
1901 | 204 | } | 204 | } |
1902 | 205 | ); | 205 | ); |
1903 | 206 | } else { | 206 | } else { |
1904 | 207 | std::shared_ptr<Downloader> ret_null; | ||
1905 | 207 | QFutureInterface<decltype(ret_null)> qfi(fi); | 208 | QFutureInterface<decltype(ret_null)> qfi(fi); |
1906 | 208 | qfi.reportResult(ret_null); | 209 | qfi.reportResult(ret_null); |
1907 | 209 | qfi.reportFinished(); | 210 | qfi.reportFinished(); |
1908 | 210 | 211 | ||
1909 | === modified file 'src/storage-framework/storage_framework_client.h' | |||
1910 | --- src/storage-framework/storage_framework_client.h 2016-11-03 10:32:49 +0000 | |||
1911 | +++ src/storage-framework/storage_framework_client.h 2016-11-17 00:23:33 +0000 | |||
1912 | @@ -22,6 +22,7 @@ | |||
1913 | 22 | 22 | ||
1914 | 23 | #include "util/connection-helper.h" | 23 | #include "util/connection-helper.h" |
1915 | 24 | #include "storage-framework/uploader.h" | 24 | #include "storage-framework/uploader.h" |
1916 | 25 | #include "storage-framework/downloader.h" | ||
1917 | 25 | 26 | ||
1918 | 26 | #include <unity/storage/qt/client/client-api.h> | 27 | #include <unity/storage/qt/client/client-api.h> |
1919 | 27 | 28 | ||
1920 | @@ -43,7 +44,7 @@ | |||
1921 | 43 | virtual ~StorageFrameworkClient(); | 44 | virtual ~StorageFrameworkClient(); |
1922 | 44 | 45 | ||
1923 | 45 | QFuture<std::shared_ptr<Uploader>> get_new_uploader(int64_t n_bytes, QString const & dir_name, QString const & file_name); | 46 | QFuture<std::shared_ptr<Uploader>> get_new_uploader(int64_t n_bytes, QString const & dir_name, QString const & file_name); |
1925 | 46 | QFuture<unity::storage::qt::client::Downloader::SPtr> get_new_downloader(QString const & dir_name, QString const & file_name); | 47 | QFuture<std::shared_ptr<Downloader>> get_new_downloader(QString const & dir_name, QString const & file_name); |
1926 | 47 | QFuture<QVector<QString>> get_keeper_dirs(); | 48 | QFuture<QVector<QString>> get_keeper_dirs(); |
1927 | 48 | 49 | ||
1928 | 49 | static QString const KEEPER_FOLDER; | 50 | static QString const KEEPER_FOLDER; |
1929 | 50 | 51 | ||
1930 | === added directory 'src/test-restore' | |||
1931 | === added file 'src/test-restore/CMakeLists.txt' | |||
1932 | --- src/test-restore/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
1933 | +++ src/test-restore/CMakeLists.txt 2016-11-17 00:23:33 +0000 | |||
1934 | @@ -0,0 +1,40 @@ | |||
1935 | 1 | set(TEST_RESTORE_EXEC "test-restore-socket") | ||
1936 | 2 | |||
1937 | 3 | include_directories("${CMAKE_SOURCE_DIR}/src") | ||
1938 | 4 | include_directories("${CMAKE_BINARY_DIR}/src/qdbus-stubs") | ||
1939 | 5 | include_directories("${CMAKE_SOURCE_DIR}/src/qdbus-stubs") | ||
1940 | 6 | |||
1941 | 7 | set(TEST_RESTORE_SOURCES | ||
1942 | 8 | main.cpp | ||
1943 | 9 | test-restore-socket.cpp | ||
1944 | 10 | ) | ||
1945 | 11 | |||
1946 | 12 | add_executable( | ||
1947 | 13 | ${TEST_RESTORE_EXEC} | ||
1948 | 14 | ${TEST_RESTORE_SOURCES} | ||
1949 | 15 | ) | ||
1950 | 16 | |||
1951 | 17 | link_directories( | ||
1952 | 18 | ${SERVICE_DEPS_LIBRARY_DIRS} | ||
1953 | 19 | ) | ||
1954 | 20 | |||
1955 | 21 | set( | ||
1956 | 22 | RESTORE_STATIC_LIBS | ||
1957 | 23 | storage-framework | ||
1958 | 24 | util | ||
1959 | 25 | # qdbus-stubs | ||
1960 | 26 | ) | ||
1961 | 27 | |||
1962 | 28 | target_link_libraries( | ||
1963 | 29 | ${TEST_RESTORE_EXEC} | ||
1964 | 30 | ${RESTORE_STATIC_LIBS} | ||
1965 | 31 | ${SERVICE_DEVEL_SF_DEPS_LIBRARIES} | ||
1966 | 32 | Qt5::Core | ||
1967 | 33 | Qt5::DBus | ||
1968 | 34 | ) | ||
1969 | 35 | |||
1970 | 36 | install( | ||
1971 | 37 | TARGETS | ||
1972 | 38 | ${TEST_RESTORE_EXEC} | ||
1973 | 39 | RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR} | ||
1974 | 40 | ) | ||
1975 | 0 | 41 | ||
1976 | === added file 'src/test-restore/main.cpp' | |||
1977 | --- src/test-restore/main.cpp 1970-01-01 00:00:00 +0000 | |||
1978 | +++ src/test-restore/main.cpp 2016-11-17 00:23:33 +0000 | |||
1979 | @@ -0,0 +1,32 @@ | |||
1980 | 1 | /* | ||
1981 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
1982 | 3 | * | ||
1983 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1984 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
1985 | 6 | * by the Free Software Foundation. | ||
1986 | 7 | * | ||
1987 | 8 | * This program is distributed in the hope that it will be useful, but | ||
1988 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1989 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1990 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
1991 | 12 | * | ||
1992 | 13 | * You should have received a copy of the GNU General Public License along | ||
1993 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1994 | 15 | * | ||
1995 | 16 | * Authors: | ||
1996 | 17 | * Charles Kerr <charles.kerr@canonical.com> | ||
1997 | 18 | * Xavi Garcia Mena <xavi.garcia.mena@canonical.com> | ||
1998 | 19 | */ | ||
1999 | 20 | #include <QCoreApplication> | ||
2000 | 21 | |||
2001 | 22 | #include "test-restore-socket.h" | ||
2002 | 23 | |||
2003 | 24 | int main(int argc, char **argv) | ||
2004 | 25 | { | ||
2005 | 26 | QCoreApplication app(argc, argv); | ||
2006 | 27 | |||
2007 | 28 | TestRestoreSocket test_restore; | ||
2008 | 29 | test_restore.start("test_dir", "test_file"); | ||
2009 | 30 | |||
2010 | 31 | return app.exec(); | ||
2011 | 32 | } | ||
2012 | 0 | 33 | ||
2013 | === added file 'src/test-restore/test-restore-socket.cpp' | |||
2014 | --- src/test-restore/test-restore-socket.cpp 1970-01-01 00:00:00 +0000 | |||
2015 | +++ src/test-restore/test-restore-socket.cpp 2016-11-17 00:23:33 +0000 | |||
2016 | @@ -0,0 +1,139 @@ | |||
2017 | 1 | /* | ||
2018 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
2019 | 3 | * | ||
2020 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2021 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2022 | 6 | * by the Free Software Foundation. | ||
2023 | 7 | * | ||
2024 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2025 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2026 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2027 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2028 | 12 | * | ||
2029 | 13 | * You should have received a copy of the GNU General Public License along | ||
2030 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2031 | 15 | * | ||
2032 | 16 | * Authors: | ||
2033 | 17 | * Charles Kerr <charles.kerr@canonical.com> | ||
2034 | 18 | * Xavi Garcia Mena <xavi.garcia.mena@canonical.com> | ||
2035 | 19 | */ | ||
2036 | 20 | |||
2037 | 21 | #include "test-restore-socket.h" | ||
2038 | 22 | |||
2039 | 23 | #include "storage-framework/storage_framework_client.h" | ||
2040 | 24 | #include "storage-framework/sf-downloader.h" | ||
2041 | 25 | |||
2042 | 26 | constexpr int UPLOAD_BUFFER_MAX_ {1024*16}; | ||
2043 | 27 | |||
2044 | 28 | TestRestoreSocket::TestRestoreSocket(QObject *parent) | ||
2045 | 29 | : QObject(parent) | ||
2046 | 30 | , sf_client_(new StorageFrameworkClient) | ||
2047 | 31 | , file_("/tmp/test-downloader") | ||
2048 | 32 | { | ||
2049 | 33 | file_.open(QIODevice::WriteOnly); | ||
2050 | 34 | connect (&future_watcher_, &QFutureWatcher<std::shared_ptr<Downloader>>::finished, [this]{on_socket_received(future_watcher_.result());}); | ||
2051 | 35 | } | ||
2052 | 36 | |||
2053 | 37 | TestRestoreSocket::~TestRestoreSocket() = default; | ||
2054 | 38 | |||
2055 | 39 | void TestRestoreSocket::start(QString const & dir_name, QString const & file_name) | ||
2056 | 40 | { | ||
2057 | 41 | qDebug() << "asking storage framework for a socket for reading"; | ||
2058 | 42 | |||
2059 | 43 | future_watcher_.setFuture(sf_client_->get_new_downloader(dir_name, file_name)); | ||
2060 | 44 | // connections_.connect_future( | ||
2061 | 45 | // sf_client_->get_new_downloader(dir_name, file_name), | ||
2062 | 46 | // std::function<void(std::shared_ptr<Downloader> const&)>{ | ||
2063 | 47 | // [this](std::shared_ptr<Downloader> const& downloader){ | ||
2064 | 48 | // qDebug() << "Downloader is" << static_cast<void*>(downloader.get()); | ||
2065 | 49 | // if (downloader) { | ||
2066 | 50 | // this->on_socket_received(downloader); | ||
2067 | 51 | // } | ||
2068 | 52 | // } | ||
2069 | 53 | // } | ||
2070 | 54 | // ); | ||
2071 | 55 | } | ||
2072 | 56 | |||
2073 | 57 | void TestRestoreSocket::read_data() | ||
2074 | 58 | { | ||
2075 | 59 | if (socket_->bytesAvailable()) | ||
2076 | 60 | { | ||
2077 | 61 | //// char readbuf[UPLOAD_BUFFER_MAX_]; | ||
2078 | 62 | //// const auto n = socket_->read(readbuf, sizeof(readbuf)); | ||
2079 | 63 | //// if (n > 0) { | ||
2080 | 64 | //// n_read_ += n; | ||
2081 | 65 | //// qDebug() << "Read " << n << " bytes. Total: " << n_read_; | ||
2082 | 66 | // | ||
2083 | 67 | // char readbuf[64 *1024]; | ||
2084 | 68 | // // try to fill the upload buf | ||
2085 | 69 | // int max_bytes = UPLOAD_BUFFER_MAX_;// - upload_buffer_.size(); | ||
2086 | 70 | // if (max_bytes > 0) { | ||
2087 | 71 | // const auto n = socket_->read(readbuf, max_bytes); | ||
2088 | 72 | // if (n > 0) { | ||
2089 | 73 | // n_read_ += n; | ||
2090 | 74 | // qDebug() << "Read " << n << " bytes. Total: " << n_read_; | ||
2091 | 75 | // | ||
2092 | 76 | //// if (file_.isOpen()) | ||
2093 | 77 | //// { | ||
2094 | 78 | //// file_.write(readbuf, max_bytes); | ||
2095 | 79 | //// } | ||
2096 | 80 | //// } | ||
2097 | 81 | //// else if (n < 0) { | ||
2098 | 82 | //// qDebug() << "Read error: " << socket_->errorString(); | ||
2099 | 83 | //// return; | ||
2100 | 84 | // if (file_.isOpen()) | ||
2101 | 85 | // { | ||
2102 | 86 | // file_.write(readbuf, n); | ||
2103 | 87 | // } | ||
2104 | 88 | // } | ||
2105 | 89 | // else if (n < 0) { | ||
2106 | 90 | // qDebug() << "Read error: " << socket_->errorString(); | ||
2107 | 91 | // return; | ||
2108 | 92 | // } | ||
2109 | 93 | // } | ||
2110 | 94 | |||
2111 | 95 | char readbuf[64 *1024]; | ||
2112 | 96 | const auto n = socket_->read(readbuf, sizeof(readbuf)); | ||
2113 | 97 | if (n > 0) { | ||
2114 | 98 | n_read_ += n; | ||
2115 | 99 | qDebug() << "Read " << n << " bytes. Total: " << n_read_; | ||
2116 | 100 | if (file_.isOpen()) | ||
2117 | 101 | { | ||
2118 | 102 | file_.write(readbuf, n); | ||
2119 | 103 | } | ||
2120 | 104 | } | ||
2121 | 105 | else if (n < 0) { | ||
2122 | 106 | qDebug() << "Read error: " << socket_->errorString(); | ||
2123 | 107 | return; | ||
2124 | 108 | } | ||
2125 | 109 | } | ||
2126 | 110 | } | ||
2127 | 111 | |||
2128 | 112 | void TestRestoreSocket::on_disconnected() | ||
2129 | 113 | { | ||
2130 | 114 | qDebug() << "Socket disconnected"; | ||
2131 | 115 | auto avail = socket_->bytesAvailable(); | ||
2132 | 116 | while (avail > 0) | ||
2133 | 117 | { | ||
2134 | 118 | read_data(); | ||
2135 | 119 | avail = socket_->bytesAvailable(); | ||
2136 | 120 | } | ||
2137 | 121 | |||
2138 | 122 | if (file_.isOpen()) | ||
2139 | 123 | { | ||
2140 | 124 | file_.close(); | ||
2141 | 125 | } | ||
2142 | 126 | } | ||
2143 | 127 | |||
2144 | 128 | void TestRestoreSocket::on_data_stored(qint64 /*n*/) | ||
2145 | 129 | { | ||
2146 | 130 | read_data(); | ||
2147 | 131 | } | ||
2148 | 132 | |||
2149 | 133 | void TestRestoreSocket::on_socket_received(std::shared_ptr<Downloader> const & downloader) | ||
2150 | 134 | { | ||
2151 | 135 | socket_ = downloader->socket(); | ||
2152 | 136 | QObject::connect(socket_.get(), &QLocalSocket::readyRead, this, &TestRestoreSocket::read_data); | ||
2153 | 137 | QObject::connect(socket_.get(), &QLocalSocket::disconnected, this, &TestRestoreSocket::on_disconnected); | ||
2154 | 138 | QObject::connect(&file_, &QIODevice::bytesWritten, this, &TestRestoreSocket::on_data_stored); | ||
2155 | 139 | } | ||
2156 | 0 | 140 | ||
2157 | === added file 'src/test-restore/test-restore-socket.h' | |||
2158 | --- src/test-restore/test-restore-socket.h 1970-01-01 00:00:00 +0000 | |||
2159 | +++ src/test-restore/test-restore-socket.h 2016-11-17 00:23:33 +0000 | |||
2160 | @@ -0,0 +1,56 @@ | |||
2161 | 1 | /* | ||
2162 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
2163 | 3 | * | ||
2164 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2165 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2166 | 6 | * by the Free Software Foundation. | ||
2167 | 7 | * | ||
2168 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2169 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2170 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2171 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2172 | 12 | * | ||
2173 | 13 | * You should have received a copy of the GNU General Public License along | ||
2174 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2175 | 15 | * | ||
2176 | 16 | * Authors: | ||
2177 | 17 | * Charles Kerr <charles.kerr@canonical.com> | ||
2178 | 18 | * Xavi Garcia Mena <xavi.garcia.mena@canonical.com> | ||
2179 | 19 | */ | ||
2180 | 20 | #pragma once | ||
2181 | 21 | |||
2182 | 22 | #include "util/connection-helper.h" | ||
2183 | 23 | |||
2184 | 24 | #include <QObject> | ||
2185 | 25 | #include <QScopedPointer> | ||
2186 | 26 | #include <QFile> | ||
2187 | 27 | |||
2188 | 28 | #include <memory> | ||
2189 | 29 | |||
2190 | 30 | class QLocalSocket; | ||
2191 | 31 | class StorageFrameworkClient; | ||
2192 | 32 | class Downloader; | ||
2193 | 33 | |||
2194 | 34 | class TestRestoreSocket : public QObject | ||
2195 | 35 | { | ||
2196 | 36 | Q_OBJECT | ||
2197 | 37 | public: | ||
2198 | 38 | explicit TestRestoreSocket(QObject *parent = nullptr); | ||
2199 | 39 | virtual ~TestRestoreSocket(); | ||
2200 | 40 | |||
2201 | 41 | void start(QString const & dir_name, QString const & file_name); | ||
2202 | 42 | |||
2203 | 43 | public Q_SLOTS: | ||
2204 | 44 | void read_data(); | ||
2205 | 45 | void on_socket_received(std::shared_ptr<Downloader> const & downloader); | ||
2206 | 46 | void on_disconnected(); | ||
2207 | 47 | void on_data_stored(qint64 n); | ||
2208 | 48 | |||
2209 | 49 | private: | ||
2210 | 50 | std::shared_ptr<QLocalSocket> socket_; | ||
2211 | 51 | QScopedPointer<StorageFrameworkClient> sf_client_; | ||
2212 | 52 | ConnectionHelper connections_; | ||
2213 | 53 | qint64 n_read_ = 0; | ||
2214 | 54 | QFile file_; | ||
2215 | 55 | QFutureWatcher<std::shared_ptr<Downloader>> future_watcher_; | ||
2216 | 56 | }; | ||
2217 | 0 | 57 | ||
2218 | === modified file 'tests/CMakeLists.txt' | |||
2219 | --- tests/CMakeLists.txt 2016-09-05 13:54:15 +0000 | |||
2220 | +++ tests/CMakeLists.txt 2016-11-17 00:23:33 +0000 | |||
2221 | @@ -20,6 +20,11 @@ | |||
2222 | 20 | ) | 20 | ) |
2223 | 21 | 21 | ||
2224 | 22 | set( | 22 | set( |
2225 | 23 | RESTORE_HELPER | ||
2226 | 24 | fake-restore-helper | ||
2227 | 25 | ) | ||
2228 | 26 | |||
2229 | 27 | set( | ||
2230 | 23 | BACKUP_HELPER_FAILURE | 28 | BACKUP_HELPER_FAILURE |
2231 | 24 | fake-backup-helper-failure | 29 | fake-backup-helper-failure |
2232 | 25 | ) | 30 | ) |
2233 | @@ -27,6 +32,7 @@ | |||
2234 | 27 | set(KEEPER_TAR_CREATE_BIN ${CMAKE_BINARY_DIR}/src/tar/keeper-tar-create) | 32 | set(KEEPER_TAR_CREATE_BIN ${CMAKE_BINARY_DIR}/src/tar/keeper-tar-create) |
2235 | 28 | set(KEEPER_HELPER_TEST_LOCATION ${CMAKE_BINARY_DIR}/tests/fakes/helpers-test.sh) | 33 | set(KEEPER_HELPER_TEST_LOCATION ${CMAKE_BINARY_DIR}/tests/fakes/helpers-test.sh) |
2236 | 29 | set(BACKUP_HELPER_FAILURE_LOCATION ${CMAKE_BINARY_DIR}/tests/fakes/${BACKUP_HELPER_FAILURE}) | 34 | set(BACKUP_HELPER_FAILURE_LOCATION ${CMAKE_BINARY_DIR}/tests/fakes/${BACKUP_HELPER_FAILURE}) |
2237 | 35 | set(RESTORE_HELPER_TEST_LOCATION ${CMAKE_BINARY_DIR}/tests/fakes/${RESTORE_HELPER}) | ||
2238 | 30 | 36 | ||
2239 | 31 | add_definitions( | 37 | add_definitions( |
2240 | 32 | -DCMAKE_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" | 38 | -DCMAKE_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" |
2241 | 33 | 39 | ||
2242 | === modified file 'tests/com_canonical_keeper.py' | |||
2243 | --- tests/com_canonical_keeper.py 2016-08-03 18:38:12 +0000 | |||
2244 | +++ tests/com_canonical_keeper.py 2016-11-17 00:23:33 +0000 | |||
2245 | @@ -1,3 +1,20 @@ | |||
2246 | 1 | # Copyright (C) 2016 Canonical, Ltd. | ||
2247 | 2 | # | ||
2248 | 3 | # This program is free software: you can redistribute it and/or modify it | ||
2249 | 4 | # under the terms of the GNU General Public License version 3, as published | ||
2250 | 5 | # by the Free Software Foundation. | ||
2251 | 6 | # | ||
2252 | 7 | # This program is distributed in the hope that it will be useful, but | ||
2253 | 8 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2254 | 9 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2255 | 10 | # PURPOSE. See the GNU General Public License for more details. | ||
2256 | 11 | # | ||
2257 | 12 | # You should have received a copy of the GNU General Public License along | ||
2258 | 13 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2259 | 14 | # | ||
2260 | 15 | # Authors: | ||
2261 | 16 | # Charles Kerr <charles.kerr@canonical.com> | ||
2262 | 17 | |||
2263 | 1 | import copy | 18 | import copy |
2264 | 2 | import dbus | 19 | import dbus |
2265 | 3 | import dbus.service | 20 | import dbus.service |
2266 | 4 | 21 | ||
2267 | === modified file 'tests/fakes/CMakeLists.txt' | |||
2268 | --- tests/fakes/CMakeLists.txt 2016-08-30 12:50:46 +0000 | |||
2269 | +++ tests/fakes/CMakeLists.txt 2016-11-17 00:23:33 +0000 | |||
2270 | @@ -30,6 +30,16 @@ | |||
2271 | 30 | ) | 30 | ) |
2272 | 31 | 31 | ||
2273 | 32 | add_executable( | 32 | add_executable( |
2274 | 33 | ${RESTORE_HELPER} | ||
2275 | 34 | fake-restore-helper.cpp | ||
2276 | 35 | restore-reader.cpp | ||
2277 | 36 | ) | ||
2278 | 37 | target_link_libraries( | ||
2279 | 38 | ${RESTORE_HELPER} | ||
2280 | 39 | ${LINK_LIBS} | ||
2281 | 40 | ) | ||
2282 | 41 | |||
2283 | 42 | add_executable( | ||
2284 | 33 | ${BACKUP_HELPER_FAILURE} | 43 | ${BACKUP_HELPER_FAILURE} |
2285 | 34 | fake-backup-helper.cpp | 44 | fake-backup-helper.cpp |
2286 | 35 | ) | 45 | ) |
2287 | 36 | 46 | ||
2288 | === added file 'tests/fakes/fake-restore-helper.cpp' | |||
2289 | --- tests/fakes/fake-restore-helper.cpp 1970-01-01 00:00:00 +0000 | |||
2290 | +++ tests/fakes/fake-restore-helper.cpp 2016-11-17 00:23:33 +0000 | |||
2291 | @@ -0,0 +1,101 @@ | |||
2292 | 1 | /* | ||
2293 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
2294 | 3 | * | ||
2295 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2296 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2297 | 6 | * by the Free Software Foundation. | ||
2298 | 7 | * | ||
2299 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2300 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2301 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2302 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2303 | 12 | * | ||
2304 | 13 | * You should have received a copy of the GNU General Public License along | ||
2305 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2306 | 15 | * | ||
2307 | 16 | * Authors: | ||
2308 | 17 | * Charles Kerr <charles.kerr@canonical.com> | ||
2309 | 18 | */ | ||
2310 | 19 | |||
2311 | 20 | #include "fake-restore-helper.h" | ||
2312 | 21 | #include "restore-reader.h" | ||
2313 | 22 | |||
2314 | 23 | #include <qdbus-stubs/dbus-types.h> | ||
2315 | 24 | #include <qdbus-stubs/keeper_helper_interface.h> | ||
2316 | 25 | |||
2317 | 26 | #include <QCoreApplication> | ||
2318 | 27 | #include <QDebug> | ||
2319 | 28 | #include <QDBusConnection> | ||
2320 | 29 | #include <QDBusInterface> | ||
2321 | 30 | #include <QDBusReply> | ||
2322 | 31 | #include <QProcessEnvironment> | ||
2323 | 32 | #include <QLocalSocket> | ||
2324 | 33 | #include <QtGlobal> | ||
2325 | 34 | |||
2326 | 35 | #include <unistd.h> | ||
2327 | 36 | #include <sys/ioctl.h> | ||
2328 | 37 | |||
2329 | 38 | void myMessageHandler(QtMsgType type, const QMessageLogContext &, const QString & msg) | ||
2330 | 39 | { | ||
2331 | 40 | QString txt; | ||
2332 | 41 | switch (type) { | ||
2333 | 42 | case QtDebugMsg: | ||
2334 | 43 | txt = QString("Debug: %1").arg(msg); | ||
2335 | 44 | break; | ||
2336 | 45 | case QtWarningMsg: | ||
2337 | 46 | txt = QString("Warning: %1").arg(msg); | ||
2338 | 47 | break; | ||
2339 | 48 | case QtCriticalMsg: | ||
2340 | 49 | txt = QString("Critical: %1").arg(msg); | ||
2341 | 50 | break; | ||
2342 | 51 | case QtFatalMsg: | ||
2343 | 52 | txt = QString("Fatal: %1").arg(msg); | ||
2344 | 53 | abort(); | ||
2345 | 54 | } | ||
2346 | 55 | QFile outFile("/tmp/restore-helper-output"); | ||
2347 | 56 | outFile.open(QIODevice::WriteOnly | QIODevice::Append); | ||
2348 | 57 | QTextStream ts(&outFile); | ||
2349 | 58 | ts << txt << endl; | ||
2350 | 59 | } | ||
2351 | 60 | |||
2352 | 61 | int | ||
2353 | 62 | main(int argc, char **argv) | ||
2354 | 63 | { | ||
2355 | 64 | QCoreApplication app(argc, argv); | ||
2356 | 65 | qInstallMessageHandler(myMessageHandler); | ||
2357 | 66 | |||
2358 | 67 | // dump the inputs to stdout | ||
2359 | 68 | qDebug() << "argc:" << argc; | ||
2360 | 69 | for(int i=0; i<argc; ++i) | ||
2361 | 70 | qDebug() << "argv[" << i << "] is" << argv[i]; | ||
2362 | 71 | const auto env = QProcessEnvironment::systemEnvironment(); | ||
2363 | 72 | for(const auto& key : env.keys()) | ||
2364 | 73 | qDebug() << "env" << qPrintable(key) << "is" << qPrintable(env.value(key)); | ||
2365 | 74 | |||
2366 | 75 | qDebug() << "Retrieving connection"; | ||
2367 | 76 | |||
2368 | 77 | // ask the service for a socket | ||
2369 | 78 | auto conn = QDBusConnection::connectToBus(QDBusConnection::SessionBus, DBusTypes::KEEPER_SERVICE); | ||
2370 | 79 | const auto object_path = QString::fromUtf8(DBusTypes::KEEPER_HELPER_PATH); | ||
2371 | 80 | DBusInterfaceKeeperHelper helper_iface (DBusTypes::KEEPER_SERVICE, object_path, conn); | ||
2372 | 81 | |||
2373 | 82 | qDebug() << "Is valid:" << helper_iface.isValid(); | ||
2374 | 83 | |||
2375 | 84 | auto fd_reply = helper_iface.StartRestore(); | ||
2376 | 85 | fd_reply.waitForFinished(); | ||
2377 | 86 | if (fd_reply.isError()) | ||
2378 | 87 | { | ||
2379 | 88 | qFatal("Call to '%s.StartRestore() at '%s' call failed: %s", | ||
2380 | 89 | DBusTypes::KEEPER_SERVICE, | ||
2381 | 90 | qPrintable(object_path), | ||
2382 | 91 | qPrintable(fd_reply.error().message()) | ||
2383 | 92 | ); | ||
2384 | 93 | } | ||
2385 | 94 | const auto ufd = fd_reply.value(); | ||
2386 | 95 | |||
2387 | 96 | // write the blob | ||
2388 | 97 | const auto fd = ufd.fileDescriptor(); | ||
2389 | 98 | qDebug() << "The file descriptor obtained is: " << fd; | ||
2390 | 99 | RestoreReader reader(fd, TEST_RESTORE_FILE_PATH); | ||
2391 | 100 | return app.exec(); | ||
2392 | 101 | } | ||
2393 | 0 | 102 | ||
2394 | === added file 'tests/fakes/fake-restore-helper.h' | |||
2395 | --- tests/fakes/fake-restore-helper.h 1970-01-01 00:00:00 +0000 | |||
2396 | +++ tests/fakes/fake-restore-helper.h 2016-11-17 00:23:33 +0000 | |||
2397 | @@ -0,0 +1,26 @@ | |||
2398 | 1 | /* | ||
2399 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
2400 | 3 | * | ||
2401 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2402 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2403 | 6 | * by the Free Software Foundation. | ||
2404 | 7 | * | ||
2405 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2406 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2407 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2408 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2409 | 12 | * | ||
2410 | 13 | * You should have received a copy of the GNU General Public License along | ||
2411 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2412 | 15 | * | ||
2413 | 16 | * Authors: | ||
2414 | 17 | * Charles Kerr <charles.kerr@canonical.com> | ||
2415 | 18 | */ | ||
2416 | 19 | |||
2417 | 20 | #pragma once | ||
2418 | 21 | |||
2419 | 22 | namespace | ||
2420 | 23 | { | ||
2421 | 24 | static char const TEST_RESTORE_FILE_PATH[] = "/tmp/test-restore-helper"; | ||
2422 | 25 | |||
2423 | 26 | } | ||
2424 | 0 | 27 | ||
2425 | === added file 'tests/fakes/restore-reader.cpp' | |||
2426 | --- tests/fakes/restore-reader.cpp 1970-01-01 00:00:00 +0000 | |||
2427 | +++ tests/fakes/restore-reader.cpp 2016-11-17 00:23:33 +0000 | |||
2428 | @@ -0,0 +1,81 @@ | |||
2429 | 1 | /* | ||
2430 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
2431 | 3 | * | ||
2432 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2433 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2434 | 6 | * by the Free Software Foundation. | ||
2435 | 7 | * | ||
2436 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2437 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2438 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2439 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2440 | 12 | * | ||
2441 | 13 | * You should have received a copy of the GNU General Public License along | ||
2442 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2443 | 15 | * | ||
2444 | 16 | * Authors: | ||
2445 | 17 | * Xavi Garcia <xavi.garcia.mena@canonical.com> | ||
2446 | 18 | */ | ||
2447 | 19 | |||
2448 | 20 | #include "restore-reader.h" | ||
2449 | 21 | |||
2450 | 22 | #include <QCoreApplication> | ||
2451 | 23 | #include <QCryptographicHash> | ||
2452 | 24 | |||
2453 | 25 | #include <unistd.h> | ||
2454 | 26 | |||
2455 | 27 | //static constexpr int UPLOAD_BUFFER_MAX_ {1024*16}; | ||
2456 | 28 | constexpr int UPLOAD_BUFFER_MAX_ = 16 * 1024; | ||
2457 | 29 | |||
2458 | 30 | RestoreReader::RestoreReader(qint64 fd, QString const & file_path, QObject * parent) | ||
2459 | 31 | : QObject(parent) | ||
2460 | 32 | , file_(file_path) | ||
2461 | 33 | { | ||
2462 | 34 | socket_.setSocketDescriptor(fd); | ||
2463 | 35 | connect(&socket_, &QLocalSocket::readyRead, this, &RestoreReader::read_all); | ||
2464 | 36 | connect(&socket_, &QLocalSocket::disconnected, this, &RestoreReader::finish); | ||
2465 | 37 | if (!file_.open(QIODevice::WriteOnly | QIODevice::Truncate)) | ||
2466 | 38 | { | ||
2467 | 39 | qFatal("Error opening file"); | ||
2468 | 40 | } | ||
2469 | 41 | |||
2470 | 42 | read_all(); | ||
2471 | 43 | } | ||
2472 | 44 | |||
2473 | 45 | void RestoreReader::read_all() | ||
2474 | 46 | { | ||
2475 | 47 | qDebug() << Q_FUNC_INFO; | ||
2476 | 48 | |||
2477 | 49 | for (;;) | ||
2478 | 50 | { | ||
2479 | 51 | auto const chunk = socket_.readAll(); | ||
2480 | 52 | if (chunk.isEmpty()) | ||
2481 | 53 | { | ||
2482 | 54 | qDebug() << "Failed to read from server" << socket_.errorString(); | ||
2483 | 55 | break; | ||
2484 | 56 | } | ||
2485 | 57 | |||
2486 | 58 | n_bytes_read_ += chunk.size(); | ||
2487 | 59 | qDebug() << Q_FUNC_INFO << "n_bytes_read is now" << n_bytes_read_ << "after reading" << chunk.size(); | ||
2488 | 60 | if (file_.write(chunk) == -1) | ||
2489 | 61 | qDebug() << Q_FUNC_INFO << "file write failed" << file_.errorString(); | ||
2490 | 62 | |||
2491 | 63 | // THIS IS JUST FOR EXTRA DEBUG INFORMATION | ||
2492 | 64 | QCryptographicHash hash(QCryptographicHash::Sha1); | ||
2493 | 65 | hash.addData(chunk.data(), 100); | ||
2494 | 66 | qInfo() << "Hash: bytes total: " << n_bytes_read_ << " " << hash.result().toHex(); | ||
2495 | 67 | // THIS IS JUST FOR EXTRA DEBUG INFORMATION | ||
2496 | 68 | } | ||
2497 | 69 | } | ||
2498 | 70 | |||
2499 | 71 | void RestoreReader::finish() | ||
2500 | 72 | { | ||
2501 | 73 | qDebug() << "Finishing"; | ||
2502 | 74 | read_all(); | ||
2503 | 75 | |||
2504 | 76 | file_.flush(); | ||
2505 | 77 | fsync(file_.handle()); | ||
2506 | 78 | file_.close(); | ||
2507 | 79 | |||
2508 | 80 | QCoreApplication::exit(); | ||
2509 | 81 | } | ||
2510 | 0 | 82 | ||
2511 | === added file 'tests/fakes/restore-reader.h' | |||
2512 | --- tests/fakes/restore-reader.h 1970-01-01 00:00:00 +0000 | |||
2513 | +++ tests/fakes/restore-reader.h 2016-11-17 00:23:33 +0000 | |||
2514 | @@ -0,0 +1,43 @@ | |||
2515 | 1 | /* | ||
2516 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
2517 | 3 | * | ||
2518 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2519 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2520 | 6 | * by the Free Software Foundation. | ||
2521 | 7 | * | ||
2522 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2523 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2524 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2525 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2526 | 12 | * | ||
2527 | 13 | * You should have received a copy of the GNU General Public License along | ||
2528 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2529 | 15 | * | ||
2530 | 16 | * Authors: | ||
2531 | 17 | * Xavi Garcia <xavi.garcia.mena@canonical.com> | ||
2532 | 18 | */ | ||
2533 | 19 | |||
2534 | 20 | #pragma once | ||
2535 | 21 | |||
2536 | 22 | #include <QObject> | ||
2537 | 23 | #include <QFile> | ||
2538 | 24 | #include <QLocalSocket> | ||
2539 | 25 | |||
2540 | 26 | class RestoreReader : public QObject | ||
2541 | 27 | { | ||
2542 | 28 | Q_OBJECT | ||
2543 | 29 | public: | ||
2544 | 30 | RestoreReader(qint64 fd, QString const & file_path, QObject * parent = nullptr); | ||
2545 | 31 | ~RestoreReader() = default; | ||
2546 | 32 | |||
2547 | 33 | private Q_SLOTS: | ||
2548 | 34 | void read_all(); | ||
2549 | 35 | void finish(); | ||
2550 | 36 | |||
2551 | 37 | private: | ||
2552 | 38 | void check_for_done(); | ||
2553 | 39 | |||
2554 | 40 | QLocalSocket socket_; | ||
2555 | 41 | qint64 n_bytes_read_ = 0; | ||
2556 | 42 | QFile file_; | ||
2557 | 43 | }; | ||
2558 | 0 | 44 | ||
2559 | === modified file 'tests/integration/helpers/CMakeLists.txt' | |||
2560 | --- tests/integration/helpers/CMakeLists.txt 2016-10-28 15:11:21 +0000 | |||
2561 | +++ tests/integration/helpers/CMakeLists.txt 2016-11-17 00:23:33 +0000 | |||
2562 | @@ -65,6 +65,10 @@ | |||
2563 | 65 | FOLDER_BACKUP_EXEC | 65 | FOLDER_BACKUP_EXEC |
2564 | 66 | ${KEEPER_HELPER_TEST_LOCATION} | 66 | ${KEEPER_HELPER_TEST_LOCATION} |
2565 | 67 | ) | 67 | ) |
2566 | 68 | set( | ||
2567 | 69 | FOLDER_RESTORE_EXEC | ||
2568 | 70 | ${RESTORE_HELPER_TEST_LOCATION} | ||
2569 | 71 | ) | ||
2570 | 68 | configure_file( | 72 | configure_file( |
2571 | 69 | ${CMAKE_SOURCE_DIR}/data/${HELPER_REGISTRY_FILENAME}.in | 73 | ${CMAKE_SOURCE_DIR}/data/${HELPER_REGISTRY_FILENAME}.in |
2572 | 70 | ${HELPERS_TEST}-registry.json | 74 | ${HELPERS_TEST}-registry.json |
2573 | 71 | 75 | ||
2574 | === modified file 'tests/integration/helpers/helpers-test.cc' | |||
2575 | --- tests/integration/helpers/helpers-test.cc 2016-11-02 14:01:23 +0000 | |||
2576 | +++ tests/integration/helpers/helpers-test.cc 2016-11-17 00:23:33 +0000 | |||
2577 | @@ -20,6 +20,7 @@ | |||
2578 | 20 | */ | 20 | */ |
2579 | 21 | 21 | ||
2580 | 22 | #include "test-helpers-base.h" | 22 | #include "test-helpers-base.h" |
2581 | 23 | #include "tests/fakes/fake-restore-helper.h" | ||
2582 | 23 | 24 | ||
2583 | 24 | class TestHelpers: public TestHelpersBase | 25 | class TestHelpers: public TestHelpersBase |
2584 | 25 | { | 26 | { |
2585 | @@ -32,30 +33,31 @@ | |||
2586 | 32 | } | 33 | } |
2587 | 33 | }; | 34 | }; |
2588 | 34 | 35 | ||
2610 | 35 | TEST_F(TestHelpers, StartHelper) | 36 | //TEST_F(TestHelpers, StartHelper) |
2611 | 36 | { | 37 | //{ |
2612 | 37 | // starts the services, including keeper-service | 38 | // // starts the services, including keeper-service |
2613 | 38 | start_tasks(); | 39 | // start_tasks(); |
2614 | 39 | 40 | // | |
2615 | 40 | BackupHelper helper("com.test.multiple_first_1.2.3"); | 41 | // BackupHelper helper("com.test.multiple_first_1.2.3"); |
2616 | 41 | 42 | // | |
2617 | 42 | QSignalSpy spy(&helper, &BackupHelper::state_changed); | 43 | // QSignalSpy spy(&helper, &BackupHelper::state_changed); |
2618 | 43 | 44 | // | |
2619 | 44 | helper.start({"/bin/ls","/tmp"}); | 45 | // helper.start({"/bin/ls","/tmp"}); |
2620 | 45 | 46 | // | |
2621 | 46 | // wait for 2 signals. | 47 | // // wait for 2 signals. |
2622 | 47 | // One for started, another one when the helper stops | 48 | // // One for started, another one when the helper stops |
2623 | 48 | WAIT_FOR_SIGNALS(spy, 2, 15000); | 49 | // WAIT_FOR_SIGNALS(spy, 2, 15000); |
2624 | 49 | 50 | // | |
2625 | 50 | ASSERT_EQ(spy.count(), 2); | 51 | // ASSERT_EQ(spy.count(), 2); |
2626 | 51 | QList<QVariant> arguments = spy.takeFirst(); | 52 | // QList<QVariant> arguments = spy.takeFirst(); |
2627 | 52 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::STARTED); | 53 | // EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::STARTED); |
2628 | 53 | arguments = spy.takeFirst(); | 54 | // arguments = spy.takeFirst(); |
2629 | 54 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::COMPLETE); | 55 | // EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::COMPLETE); |
2630 | 55 | } | 56 | //} |
2631 | 56 | 57 | ||
2632 | 57 | TEST_F(TestHelpers, StartFullTest) | 58 | TEST_F(TestHelpers, StartFullTest) |
2633 | 58 | { | 59 | { |
2634 | 60 | system("rm -f /tmp/restore-helper-output"); | ||
2635 | 59 | XdgUserDirsSandbox tmp_dir; | 61 | XdgUserDirsSandbox tmp_dir; |
2636 | 60 | 62 | ||
2637 | 61 | // starts the services, including keeper-service | 63 | // starts the services, including keeper-service |
2638 | @@ -82,7 +84,7 @@ | |||
2639 | 82 | qDebug() << "USER DIR:" << user_dir; | 84 | qDebug() << "USER DIR:" << user_dir; |
2640 | 83 | 85 | ||
2641 | 84 | // fill something in the music dir | 86 | // fill something in the music dir |
2643 | 85 | FileUtils::fillTemporaryDirectory(user_dir, qrand() % 100); | 87 | FileUtils::fillTemporaryDirectory(user_dir, qrand() % 10); |
2644 | 86 | 88 | ||
2645 | 87 | // search for the user folder uuid | 89 | // search for the user folder uuid |
2646 | 88 | auto user_folder_uuid = get_uuid_for_xdg_folder_path(user_dir, choices.value()); | 90 | auto user_folder_uuid = get_uuid_for_xdg_folder_path(user_dir, choices.value()); |
2647 | @@ -101,7 +103,7 @@ | |||
2648 | 101 | qDebug() << "USER DIR 2:" << user_dir_2; | 103 | qDebug() << "USER DIR 2:" << user_dir_2; |
2649 | 102 | 104 | ||
2650 | 103 | // fill something in the music dir | 105 | // fill something in the music dir |
2652 | 104 | FileUtils::fillTemporaryDirectory(user_dir_2, qrand() % 100); | 106 | FileUtils::fillTemporaryDirectory(user_dir_2, qrand() % 10); |
2653 | 105 | 107 | ||
2654 | 106 | // search for the user folder uuid | 108 | // search for the user folder uuid |
2655 | 107 | auto user_folder_uuid_2 = get_uuid_for_xdg_folder_path(user_dir_2, choices.value()); | 109 | auto user_folder_uuid_2 = get_uuid_for_xdg_folder_path(user_dir_2, choices.value()); |
2656 | @@ -140,164 +142,197 @@ | |||
2657 | 140 | 142 | ||
2658 | 141 | // finally check that we have a valid manifest file. | 143 | // finally check that we have a valid manifest file. |
2659 | 142 | EXPECT_TRUE(check_manifest_file(backup_items)); | 144 | EXPECT_TRUE(check_manifest_file(backup_items)); |
2821 | 143 | } | 145 | |
2822 | 144 | 146 | QDBusPendingReply<QVariantDictMap> restore_choices_reply = user_iface->call("GetRestoreChoices"); | |
2823 | 145 | TEST_F(TestHelpers, StartFullTestCancelling) | 147 | restore_choices_reply.waitForFinished(); |
2824 | 146 | { | 148 | EXPECT_TRUE(restore_choices_reply.isValid()) << qPrintable(choices.error().message()); |
2825 | 147 | XdgUserDirsSandbox tmp_dir; | 149 | |
2826 | 148 | 150 | const auto restore_choices = restore_choices_reply.value(); | |
2827 | 149 | // starts the services, including keeper-service | 151 | EXPECT_EQ(2, restore_choices.size()); |
2828 | 150 | start_tasks(); | 152 | |
2829 | 151 | 153 | // check that we have the first uuid that we did the backup | |
2830 | 152 | QSharedPointer<DBusInterfaceKeeperUser> user_iface(new DBusInterfaceKeeperUser( | 154 | const auto iter_restore = restore_choices.find(user_folder_uuid); |
2831 | 153 | DBusTypes::KEEPER_SERVICE, | 155 | EXPECT_NE(iter_restore, restore_choices.end()); |
2832 | 154 | DBusTypes::KEEPER_USER_PATH, | 156 | EXPECT_EQ(user_folder_uuid, iter_restore.key()); |
2833 | 155 | dbus_test_runner.sessionConnection() | 157 | |
2834 | 156 | ) ); | 158 | // ask to restore that uuid |
2835 | 157 | 159 | QDBusPendingReply<void> restore_reply = user_iface->call("StartRestore", QStringList{iter_restore.key()}); | |
2836 | 158 | ASSERT_TRUE(user_iface->isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); | 160 | restore_reply.waitForFinished(); |
2837 | 159 | 161 | ASSERT_TRUE(restore_reply.isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); | |
2838 | 160 | // ask for a list of backup choices | 162 | |
2839 | 161 | QDBusReply<QVariantDictMap> choices = user_iface->call("GetBackupChoices"); | 163 | // waits until all tasks are complete, recording PropertiesChanged signals |
2840 | 162 | EXPECT_TRUE(choices.isValid()) << qPrintable(choices.error().message()); | 164 | // and checks all the recorded values |
2841 | 163 | 165 | EXPECT_TRUE(capture_and_check_state_until_all_tasks_complete(spy, {iter_restore.key()}, "complete")); | |
2842 | 164 | QString user_option = QStringLiteral("XDG_MUSIC_DIR"); | 166 | |
2843 | 165 | 167 | // verify that the file that the fake restore helper creates is one of the ones in storage framework | |
2844 | 166 | auto user_dir = qgetenv(user_option.toLatin1().data()); | 168 | QString storage_framework_file_path; |
2845 | 167 | ASSERT_FALSE(user_dir.isEmpty()); | 169 | EXPECT_TRUE(StorageFrameworkLocalUtils::get_storage_frameowork_file_equal_to(TEST_RESTORE_FILE_PATH, storage_framework_file_path)); |
2846 | 168 | qDebug() << "USER DIR:" << user_dir; | 170 | |
2847 | 169 | 171 | // Finally check that the storage framework file that matched is the right one | |
2848 | 170 | // fill something in the music dir | 172 | // Keeper uses the display name plus .keeper extension for the files it creates |
2849 | 171 | FileUtils::fillTemporaryDirectory(user_dir, qrand() % 1000); | 173 | QFileInfo sf_file_info(storage_framework_file_path); |
2850 | 172 | 174 | EXPECT_EQ(sf_file_info.fileName(), QStringLiteral("%1.keeper").arg(get_display_name_for_xdg_folder_path(user_dir, choices.value()))); | |
2851 | 173 | // search for the user folder uuid | 175 | |
2852 | 174 | auto user_folder_uuid = get_uuid_for_xdg_folder_path(user_dir, choices.value()); | 176 | qDebug() << "-----------------------------------------------------"; |
2853 | 175 | ASSERT_FALSE(user_folder_uuid.isEmpty()); | 177 | system("cat /tmp/restore-helper-output"); |
2854 | 176 | qDebug() << "User folder UUID is:" << user_folder_uuid; | 178 | } |
2855 | 177 | 179 | ||
2856 | 178 | QString user_option_2 = QStringLiteral("XDG_VIDEOS_DIR"); | 180 | //TEST_F(TestHelpers, StartFullTestCancelling) |
2857 | 179 | 181 | //{ | |
2858 | 180 | auto user_dir_2 = qgetenv(user_option_2.toLatin1().data()); | 182 | // XdgUserDirsSandbox tmp_dir; |
2859 | 181 | ASSERT_FALSE(user_dir_2.isEmpty()); | 183 | // |
2860 | 182 | qDebug() << "USER DIR 2:" << user_dir_2; | 184 | // // starts the services, including keeper-service |
2861 | 183 | 185 | // start_tasks(); | |
2862 | 184 | // fill something in the music dir | 186 | // |
2863 | 185 | FileUtils::fillTemporaryDirectory(user_dir_2, qrand() % 1000); | 187 | // QSharedPointer<DBusInterfaceKeeperUser> user_iface(new DBusInterfaceKeeperUser( |
2864 | 186 | 188 | // DBusTypes::KEEPER_SERVICE, | |
2865 | 187 | // search for the user folder uuid | 189 | // DBusTypes::KEEPER_USER_PATH, |
2866 | 188 | auto user_folder_uuid_2 = get_uuid_for_xdg_folder_path(user_dir_2, choices.value()); | 190 | // dbus_test_runner.sessionConnection() |
2867 | 189 | ASSERT_FALSE(user_folder_uuid_2.isEmpty()); | 191 | // ) ); |
2868 | 190 | qDebug() << "User folder 2 UUID is:" << user_folder_uuid_2; | 192 | // |
2869 | 191 | 193 | // ASSERT_TRUE(user_iface->isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); | |
2870 | 192 | QSharedPointer<DBusPropertiesInterface> properties_interface(new DBusPropertiesInterface( | 194 | // |
2871 | 193 | DBusTypes::KEEPER_SERVICE, | 195 | // // ask for a list of backup choices |
2872 | 194 | DBusTypes::KEEPER_USER_PATH, | 196 | // QDBusReply<QVariantDictMap> choices = user_iface->call("GetBackupChoices"); |
2873 | 195 | dbus_test_runner.sessionConnection() | 197 | // EXPECT_TRUE(choices.isValid()) << qPrintable(choices.error().message()); |
2874 | 196 | ) ); | 198 | // |
2875 | 197 | 199 | // QString user_option = QStringLiteral("XDG_MUSIC_DIR"); | |
2876 | 198 | ASSERT_TRUE(properties_interface->isValid()) << qPrintable(QDBusConnection::sessionBus().lastError().message()); | 200 | // |
2877 | 199 | 201 | // auto user_dir = qgetenv(user_option.toLatin1().data()); | |
2878 | 200 | QSignalSpy spy(properties_interface.data(),&DBusPropertiesInterface::PropertiesChanged); | 202 | // ASSERT_FALSE(user_dir.isEmpty()); |
2879 | 201 | 203 | // qDebug() << "USER DIR:" << user_dir; | |
2880 | 202 | // Now we know the music folder uuid, let's start the backup for it. | 204 | // |
2881 | 203 | QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{user_folder_uuid, user_folder_uuid_2}); | 205 | // // fill something in the music dir |
2882 | 204 | ASSERT_TRUE(backup_reply.isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); | 206 | // FileUtils::fillTemporaryDirectory(user_dir, qrand() % 1000); |
2883 | 205 | 207 | // | |
2884 | 206 | EXPECT_TRUE(cancel_first_task_at_percentage(spy, 0.05, user_iface)); | 208 | // // search for the user folder uuid |
2885 | 207 | 209 | // auto user_folder_uuid = get_uuid_for_xdg_folder_path(user_dir, choices.value()); | |
2886 | 208 | // wait until all the tasks have the action state "complete" | 210 | // ASSERT_FALSE(user_folder_uuid.isEmpty()); |
2887 | 209 | // this one uses pooling so it should just call Get once | 211 | // qDebug() << "User folder UUID is:" << user_folder_uuid; |
2888 | 210 | EXPECT_TRUE(wait_for_all_tasks_have_action_state({user_folder_uuid, user_folder_uuid_2}, "cancelled", user_iface)); | 212 | // |
2889 | 211 | 213 | // QString user_option_2 = QStringLiteral("XDG_VIDEOS_DIR"); | |
2890 | 212 | // check that we have no files in storage framework | 214 | // |
2891 | 213 | EXPECT_EQ(0, StorageFrameworkLocalUtils::check_storage_framework_nb_files()); | 215 | // auto user_dir_2 = qgetenv(user_option_2.toLatin1().data()); |
2892 | 214 | } | 216 | // ASSERT_FALSE(user_dir_2.isEmpty()); |
2893 | 215 | 217 | // qDebug() << "USER DIR 2:" << user_dir_2; | |
2894 | 216 | TEST_F(TestHelpers, CheckBadUUIDS) | 218 | // |
2895 | 217 | { | 219 | // // fill something in the music dir |
2896 | 218 | XdgUserDirsSandbox tmp_dir; | 220 | // FileUtils::fillTemporaryDirectory(user_dir_2, qrand() % 1000); |
2897 | 219 | 221 | // | |
2898 | 220 | // starts the services, including keeper-service | 222 | // // search for the user folder uuid |
2899 | 221 | start_tasks(); | 223 | // auto user_folder_uuid_2 = get_uuid_for_xdg_folder_path(user_dir_2, choices.value()); |
2900 | 222 | 224 | // ASSERT_FALSE(user_folder_uuid_2.isEmpty()); | |
2901 | 223 | QSharedPointer<DBusInterfaceKeeperUser> user_iface(new DBusInterfaceKeeperUser( | 225 | // qDebug() << "User folder 2 UUID is:" << user_folder_uuid_2; |
2902 | 224 | DBusTypes::KEEPER_SERVICE, | 226 | // |
2903 | 225 | DBusTypes::KEEPER_USER_PATH, | 227 | // QSharedPointer<DBusPropertiesInterface> properties_interface(new DBusPropertiesInterface( |
2904 | 226 | dbus_test_runner.sessionConnection() | 228 | // DBusTypes::KEEPER_SERVICE, |
2905 | 227 | ) ); | 229 | // DBusTypes::KEEPER_USER_PATH, |
2906 | 228 | 230 | // dbus_test_runner.sessionConnection() | |
2907 | 229 | ASSERT_TRUE(user_iface->isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); | 231 | // ) ); |
2908 | 230 | 232 | // | |
2909 | 231 | // Now we know the music folder uuid, let's start the backup for it. | 233 | // ASSERT_TRUE(properties_interface->isValid()) << qPrintable(QDBusConnection::sessionBus().lastError().message()); |
2910 | 232 | QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{"bad_uuid_1", "bad_uuid_2"}); | 234 | // |
2911 | 233 | 235 | // QSignalSpy spy(properties_interface.data(),&DBusPropertiesInterface::PropertiesChanged); | |
2912 | 234 | ASSERT_FALSE(backup_reply.isValid()); | 236 | // |
2913 | 235 | 237 | // // Now we know the music folder uuid, let's start the backup for it. | |
2914 | 236 | // check the error message | 238 | // QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{user_folder_uuid, user_folder_uuid_2}); |
2915 | 237 | // the uuids are not printed always in the same order | 239 | // ASSERT_TRUE(backup_reply.isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); |
2916 | 238 | QString error_message = dbus_test_runner.sessionConnection().lastError().message(); | 240 | // |
2917 | 239 | EXPECT_TRUE(error_message.startsWith("unhandled uuids: ")); | 241 | // EXPECT_TRUE(cancel_first_task_at_percentage(spy, 0.05, user_iface)); |
2918 | 240 | EXPECT_TRUE(error_message.contains("bad_uuid_1")); | 242 | // |
2919 | 241 | EXPECT_TRUE(error_message.contains("bad_uuid_2")); | 243 | // // wait until all the tasks have the action state "complete" |
2920 | 242 | } | 244 | // // this one uses pooling so it should just call Get once |
2921 | 243 | 245 | // EXPECT_TRUE(wait_for_all_tasks_have_action_state({user_folder_uuid, user_folder_uuid_2}, "cancelled", user_iface)); | |
2922 | 244 | TEST_F(TestHelpers, SimplyCheckThatTheSecondDBusInterfaceIsFine) | 246 | // |
2923 | 245 | { | 247 | // // check that we have no files in storage framework |
2924 | 246 | XdgUserDirsSandbox tmp_dir; | 248 | // EXPECT_EQ(0, StorageFrameworkLocalUtils::check_storage_framework_nb_files()); |
2925 | 247 | 249 | //} | |
2926 | 248 | // starts the services, including keeper-service | 250 | // |
2927 | 249 | start_tasks(); | 251 | //TEST_F(TestHelpers, CheckBadUUIDS) |
2928 | 250 | 252 | //{ | |
2929 | 251 | QSharedPointer<DBusInterfaceKeeperUser> user_iface(new DBusInterfaceKeeperUser( | 253 | // XdgUserDirsSandbox tmp_dir; |
2930 | 252 | DBusTypes::KEEPER_SERVICE, | 254 | // |
2931 | 253 | DBusTypes::KEEPER_USER_PATH, | 255 | // // starts the services, including keeper-service |
2932 | 254 | dbus_test_runner.sessionConnection() | 256 | // start_tasks(); |
2933 | 255 | ) ); | 257 | // |
2934 | 256 | 258 | // QSharedPointer<DBusInterfaceKeeperUser> user_iface(new DBusInterfaceKeeperUser( | |
2935 | 257 | ASSERT_TRUE(user_iface->isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); | 259 | // DBusTypes::KEEPER_SERVICE, |
2936 | 258 | 260 | // DBusTypes::KEEPER_USER_PATH, | |
2937 | 259 | } | 261 | // dbus_test_runner.sessionConnection() |
2938 | 260 | 262 | // ) ); | |
2939 | 261 | TEST_F(TestHelpers, BadHelperPath) | 263 | // |
2940 | 262 | { | 264 | // ASSERT_TRUE(user_iface->isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); |
2941 | 263 | // starts the services, including keeper-service | 265 | // |
2942 | 264 | start_tasks(); | 266 | // // Now we know the music folder uuid, let's start the backup for it. |
2943 | 265 | 267 | // QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{"bad_uuid_1", "bad_uuid_2"}); | |
2944 | 266 | BackupHelper helper("com.bar_foo_8432.13.1"); | 268 | // |
2945 | 267 | 269 | // ASSERT_FALSE(backup_reply.isValid()); | |
2946 | 268 | QSignalSpy spy(&helper, &BackupHelper::state_changed); | 270 | // |
2947 | 269 | QStringList urls; | 271 | // // check the error message |
2948 | 270 | urls << "blah" << "/tmp"; | 272 | // // the uuids are not printed always in the same order |
2949 | 271 | helper.start(urls); | 273 | // QString error_message = dbus_test_runner.sessionConnection().lastError().message(); |
2950 | 272 | 274 | // EXPECT_TRUE(error_message.startsWith("unhandled uuids: ")); | |
2951 | 273 | WAIT_FOR_SIGNALS(spy, 1, Helper::MAX_UAL_WAIT_TIME + 1000); | 275 | // EXPECT_TRUE(error_message.contains("bad_uuid_1")); |
2952 | 274 | 276 | // EXPECT_TRUE(error_message.contains("bad_uuid_2")); | |
2953 | 275 | ASSERT_EQ(spy.count(), 1); | 277 | //} |
2954 | 276 | QList<QVariant> arguments = spy.takeFirst(); | 278 | // |
2955 | 277 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::FAILED); | 279 | //TEST_F(TestHelpers, SimplyCheckThatTheSecondDBusInterfaceIsFine) |
2956 | 278 | } | 280 | //{ |
2957 | 279 | 281 | // XdgUserDirsSandbox tmp_dir; | |
2958 | 280 | TEST_F(TestHelpers, Inactivity) | 282 | // |
2959 | 281 | { | 283 | // // starts the services, including keeper-service |
2960 | 282 | // starts the services, including keeper-service | 284 | // start_tasks(); |
2961 | 283 | start_tasks(); | 285 | // |
2962 | 284 | 286 | // QSharedPointer<DBusInterfaceKeeperUser> user_iface(new DBusInterfaceKeeperUser( | |
2963 | 285 | BackupHelper helper("com.bar_foo_8432.13.1"); | 287 | // DBusTypes::KEEPER_SERVICE, |
2964 | 286 | 288 | // DBusTypes::KEEPER_USER_PATH, | |
2965 | 287 | QSignalSpy spy(&helper, &BackupHelper::state_changed); | 289 | // dbus_test_runner.sessionConnection() |
2966 | 288 | QStringList urls; | 290 | // ) ); |
2967 | 289 | urls << TEST_INACTIVE_HELPER << "/tmp"; | 291 | // |
2968 | 290 | helper.start(urls); | 292 | // ASSERT_TRUE(user_iface->isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message()); |
2969 | 291 | 293 | // | |
2970 | 292 | // wait 15 seconds at most. | 294 | //} |
2971 | 293 | // the inactive helper sleeps for 100 seconds so | 295 | // |
2972 | 294 | // if we get the 2 signals it means it was stopped due to inactivity | 296 | //TEST_F(TestHelpers, BadHelperPath) |
2973 | 295 | // We can also check at the end for the state, which should be CANCELLED | 297 | //{ |
2974 | 296 | WAIT_FOR_SIGNALS(spy, 2, BackupHelper::MAX_INACTIVITY_TIME + 2000); | 298 | // // starts the services, including keeper-service |
2975 | 297 | 299 | // start_tasks(); | |
2976 | 298 | ASSERT_EQ(spy.count(), 2); | 300 | // |
2977 | 299 | QList<QVariant> arguments = spy.takeFirst(); | 301 | // BackupHelper helper("com.bar_foo_8432.13.1"); |
2978 | 300 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::STARTED); | 302 | // |
2979 | 301 | arguments = spy.takeFirst(); | 303 | // QSignalSpy spy(&helper, &BackupHelper::state_changed); |
2980 | 302 | EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::CANCELLED); | 304 | // QStringList urls; |
2981 | 303 | } | 305 | // urls << "blah" << "/tmp"; |
2982 | 306 | // helper.start(urls); | ||
2983 | 307 | // | ||
2984 | 308 | // WAIT_FOR_SIGNALS(spy, 1, Helper::MAX_UAL_WAIT_TIME + 1000); | ||
2985 | 309 | // | ||
2986 | 310 | // ASSERT_EQ(spy.count(), 1); | ||
2987 | 311 | // QList<QVariant> arguments = spy.takeFirst(); | ||
2988 | 312 | // EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::FAILED); | ||
2989 | 313 | //} | ||
2990 | 314 | // | ||
2991 | 315 | //TEST_F(TestHelpers, Inactivity) | ||
2992 | 316 | //{ | ||
2993 | 317 | // // starts the services, including keeper-service | ||
2994 | 318 | // start_tasks(); | ||
2995 | 319 | // | ||
2996 | 320 | // BackupHelper helper("com.bar_foo_8432.13.1"); | ||
2997 | 321 | // | ||
2998 | 322 | // QSignalSpy spy(&helper, &BackupHelper::state_changed); | ||
2999 | 323 | // QStringList urls; | ||
3000 | 324 | // urls << TEST_INACTIVE_HELPER << "/tmp"; | ||
3001 | 325 | // helper.start(urls); | ||
3002 | 326 | // | ||
3003 | 327 | // // wait 15 seconds at most. | ||
3004 | 328 | // // the inactive helper sleeps for 100 seconds so | ||
3005 | 329 | // // if we get the 2 signals it means it was stopped due to inactivity | ||
3006 | 330 | // // We can also check at the end for the state, which should be CANCELLED | ||
3007 | 331 | // WAIT_FOR_SIGNALS(spy, 2, BackupHelper::MAX_INACTIVITY_TIME + 2000); | ||
3008 | 332 | // | ||
3009 | 333 | // ASSERT_EQ(spy.count(), 2); | ||
3010 | 334 | // QList<QVariant> arguments = spy.takeFirst(); | ||
3011 | 335 | // EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::STARTED); | ||
3012 | 336 | // arguments = spy.takeFirst(); | ||
3013 | 337 | // EXPECT_EQ(qvariant_cast<Helper::State>(arguments.at(0)), Helper::State::CANCELLED); | ||
3014 | 338 | //} | ||
3015 | 304 | 339 | ||
3016 | === modified file 'tests/integration/helpers/test-helpers-base.cpp' | |||
3017 | --- tests/integration/helpers/test-helpers-base.cpp 2016-11-03 08:58:51 +0000 | |||
3018 | +++ tests/integration/helpers/test-helpers-base.cpp 2016-11-17 00:23:33 +0000 | |||
3019 | @@ -179,15 +179,19 @@ | |||
3020 | 179 | { | 179 | { |
3021 | 180 | return previous == "saving" || previous == "queued"; | 180 | return previous == "saving" || previous == "queued"; |
3022 | 181 | } | 181 | } |
3023 | 182 | else if (current == "restoring") | ||
3024 | 183 | { | ||
3025 | 184 | return previous == "restoring" || previous == "queued"; | ||
3026 | 185 | } | ||
3027 | 182 | else if (current == "finishing") | 186 | else if (current == "finishing") |
3028 | 183 | { | 187 | { |
3030 | 184 | return previous == "finishing" || previous == "saving"; | 188 | return previous == "finishing" || previous == "saving" || previous == "restoring"; |
3031 | 185 | } | 189 | } |
3032 | 186 | else if (current == "complete") | 190 | else if (current == "complete") |
3033 | 187 | { | 191 | { |
3034 | 188 | // we may pass from "saving" to "complete" if we don't have enough time | 192 | // we may pass from "saving" to "complete" if we don't have enough time |
3035 | 189 | // to emit the "finishing" state change | 193 | // to emit the "finishing" state change |
3037 | 190 | return previous == "complete" || previous == "finishing" || previous == "saving"; | 194 | return previous == "complete" || previous == "finishing" || previous == "saving" || previous == "restoring"; |
3038 | 191 | } | 195 | } |
3039 | 192 | else if (current == "failed") | 196 | else if (current == "failed") |
3040 | 193 | { | 197 | { |
3041 | @@ -704,7 +708,7 @@ | |||
3042 | 704 | return false; | 708 | return false; |
3043 | 705 | } | 709 | } |
3044 | 706 | 710 | ||
3046 | 707 | QSharedPointer<StorageFrameworkClient> sf_client(new StorageFrameworkClient); | 711 | QSharedPointer<StorageFrameworkClient> sf_client(new StorageFrameworkClient, [](StorageFrameworkClient* sf){sf->deleteLater();}); |
3047 | 708 | Manifest manifest_read(sf_client, dir_name); | 712 | Manifest manifest_read(sf_client, dir_name); |
3048 | 709 | QSignalSpy spy_read(&manifest_read, &Manifest::finished); | 713 | QSignalSpy spy_read(&manifest_read, &Manifest::finished); |
3049 | 710 | 714 | ||
3050 | @@ -716,6 +720,7 @@ | |||
3051 | 716 | if (!spy_read.count()) | 720 | if (!spy_read.count()) |
3052 | 717 | { | 721 | { |
3053 | 718 | qWarning() << "Failed reading manifest file"; | 722 | qWarning() << "Failed reading manifest file"; |
3054 | 723 | sf_client.reset(); | ||
3055 | 719 | return false; | 724 | return false; |
3056 | 720 | } | 725 | } |
3057 | 721 | 726 | ||
3058 | 722 | 727 | ||
3059 | === modified file 'tests/unit/manifest/manifest-test.cpp' | |||
3060 | --- tests/unit/manifest/manifest-test.cpp 2016-10-06 14:53:44 +0000 | |||
3061 | +++ tests/unit/manifest/manifest-test.cpp 2016-11-17 00:23:33 +0000 | |||
3062 | @@ -78,7 +78,7 @@ | |||
3063 | 78 | 78 | ||
3064 | 79 | g_setenv("XDG_DATA_HOME", tmp_dir.path().toLatin1().data(), true); | 79 | g_setenv("XDG_DATA_HOME", tmp_dir.path().toLatin1().data(), true); |
3065 | 80 | 80 | ||
3067 | 81 | QSharedPointer<StorageFrameworkClient> sf_client(new StorageFrameworkClient); | 81 | QSharedPointer<StorageFrameworkClient> sf_client(new StorageFrameworkClient, [](StorageFrameworkClient* sf){sf->deleteLater();}); |
3068 | 82 | Manifest manifest(sf_client, test_dir); | 82 | Manifest manifest(sf_client, test_dir); |
3069 | 83 | 83 | ||
3070 | 84 | auto objects_to_test = 10; | 84 | auto objects_to_test = 10; |
3071 | 85 | 85 | ||
3072 | === modified file 'tests/unit/storage-framework/create-uploader-test.cpp' | |||
3073 | --- tests/unit/storage-framework/create-uploader-test.cpp 2016-11-02 11:31:09 +0000 | |||
3074 | +++ tests/unit/storage-framework/create-uploader-test.cpp 2016-11-17 00:23:33 +0000 | |||
3075 | @@ -86,7 +86,7 @@ | |||
3076 | 86 | // create a downloader | 86 | // create a downloader |
3077 | 87 | auto downloader_fut = sf_client.get_new_downloader(test_dir, test_file_name); | 87 | auto downloader_fut = sf_client.get_new_downloader(test_dir, test_file_name); |
3078 | 88 | { | 88 | { |
3080 | 89 | QFutureWatcher<sf::Downloader::SPtr> w; | 89 | QFutureWatcher<std::shared_ptr<Downloader>> w; |
3081 | 90 | QSignalSpy spy(&w, &decltype(w)::finished); | 90 | QSignalSpy spy(&w, &decltype(w)::finished); |
3082 | 91 | w.setFuture(downloader_fut); | 91 | w.setFuture(downloader_fut); |
3083 | 92 | assert(spy.wait()); | 92 | assert(spy.wait()); |
3084 | @@ -107,14 +107,13 @@ | |||
3085 | 107 | 107 | ||
3086 | 108 | EXPECT_EQ(downloader_content, test_content); | 108 | EXPECT_EQ(downloader_content, test_content); |
3087 | 109 | 109 | ||
3089 | 110 | auto finish_downloader_fut = downloader->finish_download(); | 110 | QSignalSpy spy_downloader(downloader.get(), &Downloader::download_finished); |
3090 | 111 | downloader->finish(); | ||
3091 | 112 | if (!spy_downloader.count()) | ||
3092 | 111 | { | 113 | { |
3098 | 112 | QFutureWatcher<void> w; | 114 | spy_downloader.wait(); |
3094 | 113 | QSignalSpy spy(&w, &decltype(w)::finished); | ||
3095 | 114 | w.setFuture(finish_downloader_fut); | ||
3096 | 115 | assert(spy.wait()); | ||
3097 | 116 | ASSERT_EQ(spy.count(), 1); | ||
3099 | 117 | } | 115 | } |
3100 | 116 | EXPECT_EQ(1, spy_downloader.count()); | ||
3101 | 118 | 117 | ||
3102 | 119 | // get another uploader | 118 | // get another uploader |
3103 | 120 | QString test_file_name_2 = QStringLiteral("test_file2"); | 119 | QString test_file_name_2 = QStringLiteral("test_file2"); |
3104 | 121 | 120 | ||
3105 | === modified file 'tests/utils/file-utils.cpp' | |||
3106 | --- tests/utils/file-utils.cpp 2016-11-02 10:43:30 +0000 | |||
3107 | +++ tests/utils/file-utils.cpp 2016-11-17 00:23:33 +0000 | |||
3108 | @@ -198,8 +198,10 @@ | |||
3109 | 198 | qWarning() << "File to compare:" << info2.absoluteFilePath() << "does not exist"; | 198 | qWarning() << "File to compare:" << info2.absoluteFilePath() << "does not exist"; |
3110 | 199 | return false; | 199 | return false; |
3111 | 200 | } | 200 | } |
3112 | 201 | qDebug() << "File 1 size: " << info1.size() << info1.absoluteFilePath(); | ||
3113 | 202 | qDebug() << "File 2 size: " << info2.size() << info2.absoluteFilePath(); | ||
3114 | 201 | auto checksum1 = calculate_checksum(filePath1, QCryptographicHash::Md5); | 203 | auto checksum1 = calculate_checksum(filePath1, QCryptographicHash::Md5); |
3116 | 202 | auto checksum2 = calculate_checksum(filePath1, QCryptographicHash::Md5); | 204 | auto checksum2 = calculate_checksum(filePath2, QCryptographicHash::Md5); |
3117 | 203 | if (checksum1 != checksum2) | 205 | if (checksum1 != checksum2) |
3118 | 204 | { | 206 | { |
3119 | 205 | qWarning() << "Checksum for file:" << filePath1 << "differ"; | 207 | qWarning() << "Checksum for file:" << filePath1 << "differ"; |
3120 | 206 | 208 | ||
3121 | === modified file 'tests/utils/storage-framework-local.cpp' | |||
3122 | --- tests/utils/storage-framework-local.cpp 2016-10-28 15:11:21 +0000 | |||
3123 | +++ tests/utils/storage-framework-local.cpp 2016-11-17 00:23:33 +0000 | |||
3124 | @@ -170,4 +170,38 @@ | |||
3125 | 170 | : ""; | 170 | : ""; |
3126 | 171 | } | 171 | } |
3127 | 172 | 172 | ||
3128 | 173 | bool get_storage_frameowork_file_equal_to(QString const & file_path, QString & path) | ||
3129 | 174 | { | ||
3130 | 175 | auto const backups = get_storage_framework_files(); | ||
3131 | 176 | for (auto const& backup : backups) | ||
3132 | 177 | { | ||
3133 | 178 | auto const backup_filename = backup.absoluteFilePath(); | ||
3134 | 179 | if (FileUtils::compareFiles(file_path, backup_filename)) | ||
3135 | 180 | { | ||
3136 | 181 | path = backup_filename; | ||
3137 | 182 | return true; | ||
3138 | 183 | } | ||
3139 | 184 | } | ||
3140 | 185 | return false; | ||
3141 | 186 | } | ||
3142 | 187 | |||
3143 | 188 | bool get_storage_frameowork_file_equal_in_size_to(QString const & file_path, QString & path) | ||
3144 | 189 | { | ||
3145 | 190 | auto const backups = get_storage_framework_files(); | ||
3146 | 191 | for (auto const& backup : backups) | ||
3147 | 192 | { | ||
3148 | 193 | auto const backup_filename = backup.absoluteFilePath(); | ||
3149 | 194 | QFileInfo info1(backup_filename); | ||
3150 | 195 | QFileInfo info2(file_path); | ||
3151 | 196 | qDebug() << "File 1 size = " << info1.size(); | ||
3152 | 197 | qDebug() << "File 2 size = " << info2.size(); | ||
3153 | 198 | if (info1.size() == info2.size()) | ||
3154 | 199 | { | ||
3155 | 200 | path = backup_filename; | ||
3156 | 201 | return true; | ||
3157 | 202 | } | ||
3158 | 203 | } | ||
3159 | 204 | return false; | ||
3160 | 205 | } | ||
3161 | 206 | |||
3162 | 173 | } // namespace StorageFrameworkLocalUtils | 207 | } // namespace StorageFrameworkLocalUtils |
3163 | 174 | 208 | ||
3164 | === modified file 'tests/utils/storage-framework-local.h' | |||
3165 | --- tests/utils/storage-framework-local.h 2016-10-28 15:11:21 +0000 | |||
3166 | +++ tests/utils/storage-framework-local.h 2016-11-17 00:23:33 +0000 | |||
3167 | @@ -41,4 +41,8 @@ | |||
3168 | 41 | QFileInfoList get_storage_framework_files(); | 41 | QFileInfoList get_storage_framework_files(); |
3169 | 42 | 42 | ||
3170 | 43 | QString get_storage_framework_dir_name(); | 43 | QString get_storage_framework_dir_name(); |
3171 | 44 | |||
3172 | 45 | bool get_storage_frameowork_file_equal_to(QString const & file_path, QString & path); | ||
3173 | 46 | |||
3174 | 47 | bool get_storage_frameowork_file_equal_in_size_to(QString const & file_path, QString & path); | ||
3175 | 44 | } | 48 | } |
FAILED: Continuous integration, rev:130 /jenkins. canonical. com/unity- api-1/job/ lp-keeper- ci/124/ /jenkins. canonical. com/unity- api-1/job/ build/1092/ console /jenkins. canonical. com/unity- api-1/job/ build-0- fetch/1099 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 890/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= zesty/890/ console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 890/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= zesty/890/ console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 890/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= zesty/890/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/unity- api-1/job/ lp-keeper- ci/124/ rebuild
https:/