Merge lp:~michihenning/storage-framework/upload-download into lp:storage-framework/devel
- upload-download
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Michi Henning |
Approved revision: | 106 |
Merged at revision: | 79 |
Proposed branch: | lp:~michihenning/storage-framework/upload-download |
Merge into: | lp:storage-framework/devel |
Diff against target: |
3131 lines (+1837/-204) 38 files modified
include/unity/storage/qt/Downloader.h (+27/-16) include/unity/storage/qt/Item.h (+4/-0) include/unity/storage/qt/StorageError.h (+2/-3) include/unity/storage/qt/Uploader.h (+26/-14) include/unity/storage/qt/internal/AccountImpl.h (+4/-4) include/unity/storage/qt/internal/AccountsJobImpl.h (+3/-3) include/unity/storage/qt/internal/DownloaderImpl.h (+71/-0) include/unity/storage/qt/internal/Handler.h (+19/-3) include/unity/storage/qt/internal/ItemImpl.h (+5/-5) include/unity/storage/qt/internal/ItemJobImpl.h (+8/-8) include/unity/storage/qt/internal/ItemListJobImpl.h (+8/-8) include/unity/storage/qt/internal/ListJobImplBase.h (+2/-2) include/unity/storage/qt/internal/MultiItemJobImpl.h (+4/-4) include/unity/storage/qt/internal/MultiItemListJobImpl.h (+6/-6) include/unity/storage/qt/internal/StorageErrorImpl.h (+0/-1) include/unity/storage/qt/internal/UploaderImpl.h (+90/-0) include/unity/storage/qt/internal/VoidJobImpl.h (+8/-5) src/provider/CMakeLists.txt (+6/-1) src/provider/internal/Handler.cpp (+0/-1) src/qt/CMakeLists.txt (+10/-2) src/qt/Downloader.cpp (+76/-0) src/qt/Item.cpp (+0/-1) src/qt/Uploader.cpp (+86/-0) src/qt/client/CMakeLists.txt (+1/-1) src/qt/internal/AccountImpl.cpp (+7/-7) src/qt/internal/AccountsJobImpl.cpp (+7/-7) src/qt/internal/DownloaderImpl.cpp (+280/-0) src/qt/internal/ItemImpl.cpp (+71/-25) src/qt/internal/ItemJobImpl.cpp (+10/-9) src/qt/internal/ItemListJobImpl.cpp (+15/-15) src/qt/internal/ListJobImplBase.cpp (+3/-3) src/qt/internal/MultiItemJobImpl.cpp (+11/-11) src/qt/internal/MultiItemListJobImpl.cpp (+9/-8) src/qt/internal/StorageErrorImpl.cpp (+1/-9) src/qt/internal/UploaderImpl.cpp (+332/-0) src/qt/internal/VoidJobImpl.cpp (+6/-6) tests/remote-client/MockProvider.cpp (+28/-12) tests/remote-client/remote-client_test.cpp (+591/-4) |
To merge this branch: | bzr merge lp:~michihenning/storage-framework/upload-download |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
unity-api-1-bot | continuous-integration | Approve | |
Unity API Team | Pending | ||
Review via email:
|
Commit message
Download implementation.
Description of the change
Download implementation.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
- 100. By Michi Henning
-
Upload implementation with basic test only.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:100
https:/
Executed test runs:
Click here to trigger a rebuild:
https:/
- 101. By Michi Henning
-
Fixed typos.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:101
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 102. By Michi Henning
-
Got rid of DeletedError (not needed). Setting error info on cancallation now.
- 103. By Michi Henning
-
Work around compiler bug on Vivid: https:/
/gcc.gnu. org/bugzilla/ show_bug. cgi?id= 60420
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:103
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
ABORTED: https:/
ABORTED: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 104. By Michi Henning
-
Another fix for non-const reply argument.
Added suppression for tons of warnings on Vivid from provider/internal/ ProviderInterfa ce.cpp. - 105. By Michi Henning
-
Two more Vivid errors.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:104
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
ABORTED: https:/
ABORTED: https:/
ABORTED: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
ABORTED: https:/
Click here to trigger a rebuild:
https:/
- 106. By Michi Henning
-
Fixed more compiler warnings.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:105
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:106
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'include/unity/storage/qt/Downloader.h' |
2 | --- include/unity/storage/qt/Downloader.h 2016-10-10 04:07:07 +0000 |
3 | +++ include/unity/storage/qt/Downloader.h 2016-10-12 08:09:09 +0000 |
4 | @@ -18,7 +18,10 @@ |
5 | |
6 | #pragma once |
7 | |
8 | -#include <QIODevice> |
9 | +#include <unity/storage/qt/Item.h> |
10 | +#include <unity/storage/qt/StorageError.h> |
11 | + |
12 | +#include <QLocalSocket> |
13 | |
14 | namespace unity |
15 | { |
16 | @@ -26,17 +29,20 @@ |
17 | { |
18 | namespace qt |
19 | { |
20 | - |
21 | -class Item; |
22 | -class StorageError; |
23 | - |
24 | -class Q_DECL_EXPORT Downloader final : public QIODevice |
25 | +namespace internal |
26 | +{ |
27 | + |
28 | +class DownloaderImpl; |
29 | + |
30 | +} // namespace internal |
31 | + |
32 | +class Q_DECL_EXPORT Downloader final : public QLocalSocket |
33 | { |
34 | Q_OBJECT |
35 | Q_PROPERTY(bool isValid READ isValid NOTIFY statusChanged FINAL) |
36 | - Q_PROPERTY(unity::Storage::qt::Downloader::Status status READ status NOTIFY statusChanged FINAL) |
37 | - Q_PROPERTY(unity::Storage::qt::StorageError error READ error NOTIFY statusChanged FINAL) |
38 | - Q_PROPERTY(unity::Storage::qt::Item item READ item NOTIFY statusChanged FINAL) |
39 | + Q_PROPERTY(unity::storage::qt::Downloader::Status status READ status NOTIFY statusChanged FINAL) |
40 | + Q_PROPERTY(unity::storage::qt::StorageError error READ error NOTIFY statusChanged FINAL) |
41 | + Q_PROPERTY(unity::storage::qt::Item item READ item NOTIFY statusChanged FINAL) |
42 | |
43 | public: |
44 | enum Status { Loading, Ready, Cancelled, Finished, Error }; |
45 | @@ -45,12 +51,12 @@ |
46 | Downloader(); |
47 | virtual ~Downloader(); |
48 | |
49 | - bool isValid(); |
50 | + bool isValid() const; // Not nice, hides QLocalSocket::isValid() |
51 | Status status() const; |
52 | - StorageError error() const; |
53 | - Item item() const; |
54 | + StorageError error() const; // Not nice, hides QLocalSocket::error() |
55 | + Item item() const; // TODO: Should we keep this? |
56 | |
57 | - Q_INVOKABLE void finishDownload(); // TODO: finish() |
58 | + Q_INVOKABLE void finishDownload(); |
59 | Q_INVOKABLE void cancel(); |
60 | |
61 | // TODO: will probably need QML invokable methods for reading and writing to/from QIODevice |
62 | @@ -58,11 +64,16 @@ |
63 | Q_SIGNALS: |
64 | void statusChanged(unity::storage::qt::Downloader::Status status) const; |
65 | |
66 | -protected: |
67 | - virtual qint64 readData(char* data, qint64 maxSize) override; |
68 | - virtual qint64 writeData(char const* data, qint64 maxSize) override; |
69 | +private: |
70 | + Downloader(std::unique_ptr<internal::DownloaderImpl> p); |
71 | + |
72 | + std::unique_ptr<internal::DownloaderImpl> p_; |
73 | + |
74 | + friend class internal::DownloaderImpl; |
75 | }; |
76 | |
77 | } // namespace qt |
78 | } // namespace storage |
79 | } // namespace unity |
80 | + |
81 | +Q_DECLARE_METATYPE(unity::storage::qt::Downloader::Status) |
82 | |
83 | === modified file 'include/unity/storage/qt/Item.h' |
84 | --- include/unity/storage/qt/Item.h 2016-10-10 05:27:03 +0000 |
85 | +++ include/unity/storage/qt/Item.h 2016-10-12 08:09:09 +0000 |
86 | @@ -39,6 +39,8 @@ |
87 | { |
88 | |
89 | class ItemImpl; |
90 | +class DownloaderImpl; |
91 | +class UploaderImpl; |
92 | |
93 | } // namespace internal |
94 | |
95 | @@ -126,6 +128,8 @@ |
96 | std::shared_ptr<internal::ItemImpl> p_; |
97 | |
98 | friend class internal::ItemImpl; |
99 | + friend class internal::DownloaderImpl; |
100 | + friend class internal::UploaderImpl; |
101 | }; |
102 | |
103 | // Note: qHash(Item) does *not* return the same hash value is std::hash<Item> because |
104 | |
105 | === modified file 'include/unity/storage/qt/StorageError.h' |
106 | --- include/unity/storage/qt/StorageError.h 2016-10-10 04:07:07 +0000 |
107 | +++ include/unity/storage/qt/StorageError.h 2016-10-12 08:09:09 +0000 |
108 | @@ -58,9 +58,8 @@ |
109 | |
110 | enum Type |
111 | { |
112 | - NoError, LocalCommsError, RemoteCommsError, Deleted, RuntimeDestroyed, NotExists, |
113 | - Exists, Conflict, PermissionDenied, Cancelled, LogicError, InvalidArgument, ResourceError, |
114 | - QuotaExceeded, |
115 | + NoError, LocalCommsError, RemoteCommsError, RuntimeDestroyed, NotExists, Exists, Conflict, |
116 | + PermissionDenied, Cancelled, LogicError, InvalidArgument, ResourceError, QuotaExceeded, |
117 | __LAST_STORAGE_ERROR |
118 | }; |
119 | Q_ENUMS(Type) |
120 | |
121 | === modified file 'include/unity/storage/qt/Uploader.h' |
122 | --- include/unity/storage/qt/Uploader.h 2016-10-10 04:07:07 +0000 |
123 | +++ include/unity/storage/qt/Uploader.h 2016-10-12 08:09:09 +0000 |
124 | @@ -18,9 +18,10 @@ |
125 | |
126 | #pragma once |
127 | |
128 | -#include <unity/storage/common.h> |
129 | +#include <unity/storage/qt/Item.h> |
130 | +#include <unity/storage/qt/StorageError.h> |
131 | |
132 | -#include <QIODevice> |
133 | +#include <QLocalSocket> |
134 | |
135 | namespace unity |
136 | { |
137 | @@ -28,31 +29,37 @@ |
138 | { |
139 | namespace qt |
140 | { |
141 | +namespace internal |
142 | +{ |
143 | + |
144 | +class UploaderImpl; |
145 | + |
146 | +} // namespace internal |
147 | |
148 | class Item; |
149 | class StorageError; |
150 | |
151 | -class Q_DECL_EXPORT Uploader final : public QIODevice |
152 | +class Q_DECL_EXPORT Uploader final : public QLocalSocket |
153 | { |
154 | Q_OBJECT |
155 | - Q_PROPERTY(bool isValid READ isValid NOTIFY statusChanged FINAL) // TODO: Need notify |
156 | + Q_PROPERTY(bool isValid READ isValid NOTIFY statusChanged FINAL) |
157 | Q_PROPERTY(unity::storage::qt::Uploader::Status status READ status NOTIFY statusChanged FINAL) |
158 | - Q_PROPERTY(unity::storage::qt::StorageError READ error NOTIFY statusChanged FINAL) |
159 | - Q_PROPERTY(unity::storage::qt::Item::ConflictPolicy policy READ policy CONSTANT FINAL) |
160 | - Q_PROPERTY(qint64 sizeInBytes READ sizeInBytes CONSTANT FINAL) |
161 | + Q_PROPERTY(unity::storage::qt::StorageError error READ error NOTIFY statusChanged FINAL) |
162 | + Q_PROPERTY(unity::storage::qt::Item::ConflictPolicy policy READ policy NOTIFY statusChanged FINAL) |
163 | + Q_PROPERTY(qint64 sizeInBytes READ sizeInBytes NOTIFY statusChanged FINAL) |
164 | Q_PROPERTY(unity::storage::qt::Item item READ item NOTIFY statusChanged FINAL) |
165 | |
166 | public: |
167 | - enum Status { Loading, Cancelled, Finished, Error }; |
168 | + enum Status { Loading, Ready, Cancelled, Finished, Error }; |
169 | Q_ENUMS(Status) |
170 | |
171 | Uploader(); |
172 | virtual ~Uploader(); |
173 | |
174 | - bool isValid() const; |
175 | + bool isValid() const; // Not nice, hides QLocalSocket::isValid() |
176 | Status status() const; |
177 | - StorageError error() const; |
178 | - ConflictPolicy policy() const; |
179 | + StorageError error() const; // Not nice, hides QLocalSocket::error() |
180 | + Item::ConflictPolicy policy() const; |
181 | qint64 sizeInBytes() const; |
182 | Item item() const; |
183 | |
184 | @@ -62,11 +69,16 @@ |
185 | Q_SIGNALS: |
186 | void statusChanged(unity::storage::qt::Uploader::Status status) const; |
187 | |
188 | -protected: |
189 | - virtual qint64 readData(char* data, qint64 maxSize) override; |
190 | - virtual qint64 writeData(char const* data, qint64 maxSize) override; |
191 | +private: |
192 | + Uploader(std::unique_ptr<internal::UploaderImpl> p); |
193 | + |
194 | + std::unique_ptr<internal::UploaderImpl> p_; |
195 | + |
196 | + friend class internal::UploaderImpl; |
197 | }; |
198 | |
199 | } // namespace qt |
200 | } // namespace storage |
201 | } // namespace unity |
202 | + |
203 | +Q_DECLARE_METATYPE(unity::storage::qt::Uploader::Status) |
204 | |
205 | === modified file 'include/unity/storage/qt/internal/AccountImpl.h' |
206 | --- include/unity/storage/qt/internal/AccountImpl.h 2016-09-26 08:57:05 +0000 |
207 | +++ include/unity/storage/qt/internal/AccountImpl.h 2016-10-12 08:09:09 +0000 |
208 | @@ -63,10 +63,10 @@ |
209 | |
210 | size_t hash() const; |
211 | |
212 | - std::shared_ptr<RuntimeImpl> runtime() const; |
213 | + std::shared_ptr<RuntimeImpl> runtime_impl() const; |
214 | std::shared_ptr<ProviderInterface> provider() const; |
215 | |
216 | - static Account make_account(std::shared_ptr<RuntimeImpl> const& runtime, |
217 | + static Account make_account(std::shared_ptr<RuntimeImpl> const& runtime_impl, |
218 | QString const& bus_name, |
219 | QString const& object_path, |
220 | QString const& owner_id, |
221 | @@ -74,7 +74,7 @@ |
222 | QString const& description); |
223 | |
224 | private: |
225 | - AccountImpl(std::shared_ptr<RuntimeImpl> const& runtime, |
226 | + AccountImpl(std::shared_ptr<RuntimeImpl> const& runtime_impl, |
227 | QString const& bus_name, |
228 | QString const& object_path, |
229 | QString const& owner_id, |
230 | @@ -87,7 +87,7 @@ |
231 | QString owner_id_; |
232 | QString owner_; |
233 | QString description_; |
234 | - std::weak_ptr<RuntimeImpl> runtime_; |
235 | + std::weak_ptr<RuntimeImpl> runtime_impl_; |
236 | std::shared_ptr<ProviderInterface> provider_; |
237 | |
238 | friend class unity::storage::qt::Account; |
239 | |
240 | === modified file 'include/unity/storage/qt/internal/AccountsJobImpl.h' |
241 | --- include/unity/storage/qt/internal/AccountsJobImpl.h 2016-09-26 02:12:30 +0000 |
242 | +++ include/unity/storage/qt/internal/AccountsJobImpl.h 2016-10-12 08:09:09 +0000 |
243 | @@ -35,7 +35,7 @@ |
244 | { |
245 | Q_OBJECT |
246 | public: |
247 | - AccountsJobImpl(AccountsJob* public_instance, std::shared_ptr<RuntimeImpl> const& runtime); |
248 | + AccountsJobImpl(AccountsJob* public_instance, std::shared_ptr<RuntimeImpl> const& runtime_impl); |
249 | AccountsJobImpl(AccountsJob* public_instance, StorageError const& error); |
250 | virtual ~AccountsJobImpl() = default; |
251 | |
252 | @@ -49,7 +49,7 @@ |
253 | void timeout(); |
254 | |
255 | private: |
256 | - std::shared_ptr<RuntimeImpl> get_runtime(QString const& method) const; |
257 | + std::shared_ptr<RuntimeImpl> get_runtime_impl(QString const& method) const; |
258 | void initialize_accounts(); |
259 | AccountsJob::Status emit_status_changed(AccountsJob::Status new_status) const; |
260 | |
261 | @@ -57,7 +57,7 @@ |
262 | AccountsJob::Status status_; |
263 | StorageError error_; |
264 | QList<unity::storage::qt::Account> accounts_; |
265 | - std::weak_ptr<RuntimeImpl> const runtime_; |
266 | + std::weak_ptr<RuntimeImpl> const runtime_impl_; |
267 | QTimer timer_; |
268 | |
269 | friend class unity::storage::qt::AccountsJob; |
270 | |
271 | === added file 'include/unity/storage/qt/internal/DownloaderImpl.h' |
272 | --- include/unity/storage/qt/internal/DownloaderImpl.h 1970-01-01 00:00:00 +0000 |
273 | +++ include/unity/storage/qt/internal/DownloaderImpl.h 2016-10-12 08:09:09 +0000 |
274 | @@ -0,0 +1,71 @@ |
275 | +/* |
276 | + * Copyright (C) 2016 Canonical Ltd |
277 | + * |
278 | + * This program is free software: you can redistribute it and/or modify |
279 | + * it under the terms of the GNU Lesser General Public License version 3 as |
280 | + * published by the Free Software Foundation. |
281 | + * |
282 | + * This program is distributed in the hope that it will be useful, |
283 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
284 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
285 | + * GNU Lesser General Public License for more details. |
286 | + * |
287 | + * You should have received a copy of the GNU Lesser General Public License |
288 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
289 | + * |
290 | + * Authors: Michi Henning <michi.henning@canonical.com> |
291 | + */ |
292 | + |
293 | +#pragma once |
294 | + |
295 | +#include <unity/storage/qt/Downloader.h> |
296 | + |
297 | +#include <QDBusPendingReply> |
298 | +#include <QDBusUnixFileDescriptor> |
299 | + |
300 | +namespace unity |
301 | +{ |
302 | +namespace storage |
303 | +{ |
304 | +namespace qt |
305 | +{ |
306 | +namespace internal |
307 | +{ |
308 | + |
309 | +class DownloaderImpl : public QObject |
310 | +{ |
311 | + Q_OBJECT |
312 | +public: |
313 | + DownloaderImpl(std::shared_ptr<ItemImpl> const& item_impl, |
314 | + QString const& method, |
315 | + QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply); |
316 | + DownloaderImpl(StorageError const& e); |
317 | + virtual ~DownloaderImpl(); |
318 | + |
319 | + bool isValid() const; |
320 | + Downloader::Status status() const; |
321 | + StorageError error() const; |
322 | + Item item() const; |
323 | + |
324 | + void finishDownload(); |
325 | + void cancel(); |
326 | + |
327 | + static Downloader* make_job(std::shared_ptr<ItemImpl> const& item_impl, |
328 | + QString const& method, |
329 | + QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply); |
330 | + static Downloader* make_job(StorageError const& e); |
331 | + |
332 | +private: |
333 | + Downloader* public_instance_; |
334 | + Downloader::Status status_; |
335 | + StorageError error_; |
336 | + std::shared_ptr<ItemImpl> item_impl_; |
337 | + QString download_id_; |
338 | + QDBusUnixFileDescriptor fd_; |
339 | + bool finalizing_ = false; |
340 | +}; |
341 | + |
342 | +} // namespace internal |
343 | +} // namespace qt |
344 | +} // namespace storage |
345 | +} // namespace unity |
346 | |
347 | === modified file 'include/unity/storage/qt/internal/Handler.h' |
348 | --- include/unity/storage/qt/internal/Handler.h 2016-09-29 03:17:56 +0000 |
349 | +++ include/unity/storage/qt/internal/Handler.h 2016-10-12 08:09:09 +0000 |
350 | @@ -36,18 +36,32 @@ |
351 | namespace internal |
352 | { |
353 | |
354 | +// TODO: HACK: The reply argument really should be passed by const reference, which also |
355 | +// would make the explicit conversion of the call to QDBusPendingReply<QDBusArgs...> |
356 | +// unnecessary. But this doesn't work with gcc 4.9: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60420 |
357 | +// Once we get rid of Vivid, this should be changed back to |
358 | +// |
359 | +// Handler(QObject* parent, |
360 | +// QDBusPendingReply<DBusArgs...> const& reply, |
361 | +// std::function<void(decltype(reply)&)> const& success_closure, |
362 | +// std::function<void(StorageError const&)> const& error_closure) |
363 | +// |
364 | +// Unfortunately, this const error ripples through the entire call hierarchy, so |
365 | +// the various JobImpl that process replies also need to be changed back to accept |
366 | +// a non-const reply. |
367 | + |
368 | template<typename T> |
369 | class Handler : public HandlerBase |
370 | { |
371 | public: |
372 | template<typename ... DBusArgs> |
373 | Handler(QObject* parent, |
374 | - QDBusPendingReply<DBusArgs...> const& reply, |
375 | + QDBusPendingReply<DBusArgs...>& reply, |
376 | std::function<void(decltype(reply)&)> const& success_closure, |
377 | std::function<void(StorageError const&)> const& error_closure) |
378 | : HandlerBase(parent, |
379 | reply, |
380 | - [this, success_closure, error_closure](QDBusPendingCallWatcher& call) |
381 | + [this, &reply, success_closure, error_closure](QDBusPendingCallWatcher& call) |
382 | { |
383 | if (call.isError()) |
384 | { |
385 | @@ -81,8 +95,10 @@ |
386 | error_closure(e); |
387 | return; |
388 | } |
389 | + // TODO: See HACK above. Should just be success_closure(call); |
390 | + // We do the assignment to get an lvalue from the reference. |
391 | QDBusPendingReply<DBusArgs...> r = call; |
392 | - success_closure(call); |
393 | + success_closure(r); |
394 | }) |
395 | { |
396 | } |
397 | |
398 | === modified file 'include/unity/storage/qt/internal/ItemImpl.h' |
399 | --- include/unity/storage/qt/internal/ItemImpl.h 2016-10-10 04:07:07 +0000 |
400 | +++ include/unity/storage/qt/internal/ItemImpl.h 2016-10-12 08:09:09 +0000 |
401 | @@ -42,7 +42,7 @@ |
402 | public: |
403 | ItemImpl(); |
404 | ItemImpl(storage::internal::ItemMetadata const& md, |
405 | - std::shared_ptr<AccountImpl> const& account); |
406 | + std::shared_ptr<AccountImpl> const& account_impl); |
407 | ItemImpl(ItemImpl const&) = default; |
408 | ItemImpl(ItemImpl&&) = delete; |
409 | ~ItemImpl() = default; |
410 | @@ -82,9 +82,9 @@ |
411 | |
412 | static Item make_item(QString const& method, |
413 | storage::internal::ItemMetadata const& md, |
414 | - std::shared_ptr<AccountImpl> const& account); |
415 | + std::shared_ptr<AccountImpl> const& account_impl); |
416 | |
417 | - std::shared_ptr<RuntimeImpl> runtime() const; |
418 | + std::shared_ptr<RuntimeImpl> runtime_impl() const; |
419 | std::shared_ptr<AccountImpl> account_impl() const; |
420 | |
421 | private: |
422 | @@ -98,7 +98,7 @@ |
423 | |
424 | bool is_valid_; |
425 | storage::internal::ItemMetadata md_; |
426 | - std::shared_ptr<AccountImpl> account_; |
427 | + std::shared_ptr<AccountImpl> account_impl_; |
428 | |
429 | friend class unity::storage::qt::Item; |
430 | }; |
431 | @@ -111,7 +111,7 @@ |
432 | auto e = StorageErrorImpl::logic_error(method + ": cannot create job from invalid item"); |
433 | return T::make_job(e); |
434 | } |
435 | - auto runtime = account_->runtime(); |
436 | + auto runtime = account_impl_->runtime_impl(); |
437 | if (!runtime || !runtime->isValid()) |
438 | { |
439 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); |
440 | |
441 | === modified file 'include/unity/storage/qt/internal/ItemJobImpl.h' |
442 | --- include/unity/storage/qt/internal/ItemJobImpl.h 2016-09-29 02:40:05 +0000 |
443 | +++ include/unity/storage/qt/internal/ItemJobImpl.h 2016-10-12 08:09:09 +0000 |
444 | @@ -53,24 +53,24 @@ |
445 | StorageError error() const; |
446 | Item item() const; |
447 | |
448 | - static ItemJob* make_job(std::shared_ptr<AccountImpl> const& account, |
449 | + static ItemJob* make_job(std::shared_ptr<AccountImpl> const& account_impl, |
450 | QString const& method, |
451 | - QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
452 | + QDBusPendingReply<storage::internal::ItemMetadata>& reply, |
453 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
454 | - static ItemJob* make_job(std::shared_ptr<ItemImpl> const&, |
455 | + static ItemJob* make_job(std::shared_ptr<ItemImpl> const& item_impl, |
456 | QString const& method, |
457 | - QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
458 | + QDBusPendingReply<storage::internal::ItemMetadata>& reply, |
459 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
460 | static ItemJob* make_job(StorageError const& e); |
461 | |
462 | private: |
463 | ItemJobImpl(std::shared_ptr<AccountImpl> const& account, |
464 | QString const& method, |
465 | - QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
466 | + QDBusPendingReply<storage::internal::ItemMetadata>& reply, |
467 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
468 | - ItemJobImpl(std::shared_ptr<ItemImpl> const& item, |
469 | + ItemJobImpl(std::shared_ptr<ItemImpl> const& item_impl, |
470 | QString const& method, |
471 | - QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
472 | + QDBusPendingReply<storage::internal::ItemMetadata>& reply, |
473 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
474 | ItemJobImpl(StorageError const& e); |
475 | |
476 | @@ -78,7 +78,7 @@ |
477 | ItemJob::Status status_; |
478 | StorageError error_; |
479 | QString method_; |
480 | - std::shared_ptr<AccountImpl> account_; |
481 | + std::shared_ptr<AccountImpl> account_impl_; |
482 | std::shared_ptr<ItemImpl> item_impl_; |
483 | std::function<void(storage::internal::ItemMetadata const&)> validate_; |
484 | Item item_; |
485 | |
486 | === modified file 'include/unity/storage/qt/internal/ItemListJobImpl.h' |
487 | --- include/unity/storage/qt/internal/ItemListJobImpl.h 2016-10-10 03:55:32 +0000 |
488 | +++ include/unity/storage/qt/internal/ItemListJobImpl.h 2016-10-12 08:09:09 +0000 |
489 | @@ -48,25 +48,25 @@ |
490 | public: |
491 | virtual ~ItemListJobImpl() = default; |
492 | |
493 | - static ItemListJob* make_job(std::shared_ptr<AccountImpl> const& account, |
494 | + static ItemListJob* make_job(std::shared_ptr<AccountImpl> const& account_impl, |
495 | QString const& method, |
496 | - QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
497 | + QDBusPendingReply<QList<storage::internal::ItemMetadata>>& reply, |
498 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
499 | - static ItemListJob* make_job(std::shared_ptr<ItemImpl> const& item, |
500 | + static ItemListJob* make_job(std::shared_ptr<ItemImpl> const& item_impl, |
501 | QString const& method, |
502 | - QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
503 | + QDBusPendingReply<QList<storage::internal::ItemMetadata>>& reply, |
504 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
505 | static ItemListJob* make_job(StorageError const& error); |
506 | |
507 | private: |
508 | ItemListJobImpl() = default; |
509 | - ItemListJobImpl(std::shared_ptr<AccountImpl> const& account, |
510 | + ItemListJobImpl(std::shared_ptr<AccountImpl> const& account_impl, |
511 | QString const& method, |
512 | - QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
513 | + QDBusPendingReply<QList<storage::internal::ItemMetadata>>& reply, |
514 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
515 | - ItemListJobImpl(std::shared_ptr<ItemImpl> const& account, |
516 | + ItemListJobImpl(std::shared_ptr<ItemImpl> const& item_impl, |
517 | QString const& method, |
518 | - QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
519 | + QDBusPendingReply<QList<storage::internal::ItemMetadata>>& reply, |
520 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
521 | |
522 | std::shared_ptr<ItemImpl> item_impl_; |
523 | |
524 | === modified file 'include/unity/storage/qt/internal/ListJobImplBase.h' |
525 | --- include/unity/storage/qt/internal/ListJobImplBase.h 2016-10-10 03:55:32 +0000 |
526 | +++ include/unity/storage/qt/internal/ListJobImplBase.h 2016-10-12 08:09:09 +0000 |
527 | @@ -49,7 +49,7 @@ |
528 | { |
529 | public: |
530 | ListJobImplBase(); // Makes job in Finished state. |
531 | - ListJobImplBase(std::shared_ptr<AccountImpl> const& account, |
532 | + ListJobImplBase(std::shared_ptr<AccountImpl> const& account_impl, |
533 | QString const& method, |
534 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
535 | ListJobImplBase(StorageError const& error); |
536 | @@ -69,7 +69,7 @@ |
537 | ItemListJob::Status status_; |
538 | StorageError error_; |
539 | QString method_; |
540 | - std::shared_ptr<AccountImpl> account_; |
541 | + std::shared_ptr<AccountImpl> account_impl_; |
542 | std::function<void(storage::internal::ItemMetadata const&)> validate_; |
543 | }; |
544 | |
545 | |
546 | === modified file 'include/unity/storage/qt/internal/MultiItemJobImpl.h' |
547 | --- include/unity/storage/qt/internal/MultiItemJobImpl.h 2016-09-30 01:48:08 +0000 |
548 | +++ include/unity/storage/qt/internal/MultiItemJobImpl.h 2016-10-12 08:09:09 +0000 |
549 | @@ -50,16 +50,16 @@ |
550 | |
551 | virtual ~MultiItemJobImpl() = default; |
552 | |
553 | - static ItemListJob* make_job(std::shared_ptr<AccountImpl> const& account, |
554 | + static ItemListJob* make_job(std::shared_ptr<AccountImpl> const& account_impl, |
555 | QString const& method, |
556 | - ReplyType const& replies, |
557 | + ReplyType& replies, |
558 | ValidateFunc const& validate); |
559 | |
560 | private: |
561 | MultiItemJobImpl() = default; |
562 | - MultiItemJobImpl(std::shared_ptr<AccountImpl> const& account, |
563 | + MultiItemJobImpl(std::shared_ptr<AccountImpl> const& account_impl, |
564 | QString const& method, |
565 | - ReplyType const& replies, |
566 | + ReplyType& replies, |
567 | ValidateFunc const& validate); |
568 | |
569 | int replies_remaining_; |
570 | |
571 | === modified file 'include/unity/storage/qt/internal/MultiItemListJobImpl.h' |
572 | --- include/unity/storage/qt/internal/MultiItemListJobImpl.h 2016-10-10 03:55:32 +0000 |
573 | +++ include/unity/storage/qt/internal/MultiItemListJobImpl.h 2016-10-12 08:09:09 +0000 |
574 | @@ -47,23 +47,23 @@ |
575 | public: |
576 | using ReplyType = QDBusPendingReply<QList<storage::internal::ItemMetadata>, QString>; |
577 | using ValidateFunc = std::function<void(storage::internal::ItemMetadata const&)>; |
578 | - using FetchFunc = std::function<QDBusPendingReply<QList<unity::storage::internal::ItemMetadata>, |
579 | - QString>(QString const& page_token)>; |
580 | + using FetchFunc = std::function |
581 | + <QDBusPendingReply<QList<unity::storage::internal::ItemMetadata>, QString>(QString const& page_token)>; |
582 | |
583 | virtual ~MultiItemListJobImpl() = default; |
584 | |
585 | - static ItemListJob* make_job(std::shared_ptr<ItemImpl> const& item, |
586 | + static ItemListJob* make_job(std::shared_ptr<ItemImpl> const& item_impl, |
587 | QString const& method, |
588 | - ReplyType const& reply, |
589 | + ReplyType& reply, |
590 | ValidateFunc const& validate, |
591 | FetchFunc const& fetch_next); |
592 | static ItemListJob* make_job(StorageError const& error); |
593 | |
594 | private: |
595 | MultiItemListJobImpl() = default; |
596 | - MultiItemListJobImpl(std::shared_ptr<ItemImpl> const& item, |
597 | + MultiItemListJobImpl(std::shared_ptr<ItemImpl> const& item_impl, |
598 | QString const& method, |
599 | - ReplyType const& reply, |
600 | + ReplyType& reply, |
601 | ValidateFunc const& validate, |
602 | FetchFunc const& fetch_next); |
603 | |
604 | |
605 | === modified file 'include/unity/storage/qt/internal/StorageErrorImpl.h' |
606 | --- include/unity/storage/qt/internal/StorageErrorImpl.h 2016-10-10 01:18:01 +0000 |
607 | +++ include/unity/storage/qt/internal/StorageErrorImpl.h 2016-10-12 08:09:09 +0000 |
608 | @@ -58,7 +58,6 @@ |
609 | // Factories to make things more convenient and ensure consistency. |
610 | static StorageError local_comms_error(QString const& msg); |
611 | static StorageError remote_comms_error(QString const& msg); |
612 | - static StorageError deleted_error(QString const& msg, QString const& item_id); |
613 | static StorageError runtime_destroyed_error(QString const& msg); |
614 | static StorageError not_exists_error(QString const& msg, QString const& key); |
615 | static StorageError exists_error(QString const& msg, QString const& item_id, QString const& item_name); |
616 | |
617 | === added file 'include/unity/storage/qt/internal/UploaderImpl.h' |
618 | --- include/unity/storage/qt/internal/UploaderImpl.h 1970-01-01 00:00:00 +0000 |
619 | +++ include/unity/storage/qt/internal/UploaderImpl.h 2016-10-12 08:09:09 +0000 |
620 | @@ -0,0 +1,90 @@ |
621 | +/* |
622 | + * Copyright (C) 2016 Canonical Ltd |
623 | + * |
624 | + * This program is free software: you can redistribute it and/or modify |
625 | + * it under the terms of the GNU Lesser General Public License version 3 as |
626 | + * published by the Free Software Foundation. |
627 | + * |
628 | + * This program is distributed in the hope that it will be useful, |
629 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
630 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
631 | + * GNU Lesser General Public License for more details. |
632 | + * |
633 | + * You should have received a copy of the GNU Lesser General Public License |
634 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
635 | + * |
636 | + * Authors: Michi Henning <michi.henning@canonical.com> |
637 | + */ |
638 | + |
639 | +#pragma once |
640 | + |
641 | +#include <unity/storage/qt/Uploader.h> |
642 | + |
643 | +#include <QDBusPendingReply> |
644 | +#include <QDBusUnixFileDescriptor> |
645 | + |
646 | +namespace unity |
647 | +{ |
648 | +namespace storage |
649 | +{ |
650 | +namespace internal |
651 | +{ |
652 | + |
653 | +class ItemMetadata; |
654 | + |
655 | +} // namespace internal |
656 | + |
657 | +namespace qt |
658 | +{ |
659 | +namespace internal |
660 | +{ |
661 | + |
662 | +class UploaderImpl : public QObject |
663 | +{ |
664 | + Q_OBJECT |
665 | +public: |
666 | + UploaderImpl(std::shared_ptr<ItemImpl> const& item_impl, |
667 | + QString const& method, |
668 | + QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply, |
669 | + std::function<void(storage::internal::ItemMetadata const&)> const& validate, |
670 | + Item::ConflictPolicy policy, |
671 | + qint64 size_in_bytes); |
672 | + UploaderImpl(StorageError const& e); |
673 | + virtual ~UploaderImpl(); |
674 | + |
675 | + bool isValid() const; |
676 | + Uploader::Status status() const; |
677 | + StorageError error() const; |
678 | + Item::ConflictPolicy policy() const; |
679 | + qint64 sizeInBytes() const; |
680 | + Item item() const; |
681 | + |
682 | + void finishUpload(); |
683 | + void cancel(); |
684 | + |
685 | + static Uploader* make_job(std::shared_ptr<ItemImpl> const& item_impl, |
686 | + QString const& method, |
687 | + QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply, |
688 | + std::function<void(storage::internal::ItemMetadata const&)> const& validate, |
689 | + Item::ConflictPolicy policy, |
690 | + qint64 size_in_bytes); |
691 | + static Uploader* make_job(StorageError const& e); |
692 | + |
693 | +private: |
694 | + Uploader* public_instance_; |
695 | + Uploader::Status status_; |
696 | + StorageError error_; |
697 | + QString method_; |
698 | + std::shared_ptr<ItemImpl> item_impl_; |
699 | + std::function<void(storage::internal::ItemMetadata const&)> validate_; |
700 | + Item::ConflictPolicy policy_ = Item::ConflictPolicy::Overwrite; |
701 | + qint64 size_in_bytes_ = 0; |
702 | + QString upload_id_; |
703 | + QDBusUnixFileDescriptor fd_; |
704 | + bool finalizing_ = false; |
705 | +}; |
706 | + |
707 | +} // namespace internal |
708 | +} // namespace qt |
709 | +} // namespace storage |
710 | +} // namespace unity |
711 | |
712 | === modified file 'include/unity/storage/qt/internal/VoidJobImpl.h' |
713 | --- include/unity/storage/qt/internal/VoidJobImpl.h 2016-09-28 04:37:14 +0000 |
714 | +++ include/unity/storage/qt/internal/VoidJobImpl.h 2016-10-12 08:09:09 +0000 |
715 | @@ -22,7 +22,10 @@ |
716 | |
717 | #include <unity/storage/qt/StorageError.h> |
718 | |
719 | +#pragma GCC diagnostic push |
720 | +#pragma GCC diagnostic ignored "-Wctor-dtor-privacy" |
721 | #include <QDBusPendingReply> |
722 | +#pragma GCC diagnostic pop |
723 | |
724 | namespace unity |
725 | { |
726 | @@ -45,22 +48,22 @@ |
727 | VoidJob::Status status() const; |
728 | StorageError error() const; |
729 | |
730 | - static VoidJob* make_job(std::shared_ptr<ItemImpl> const& item, |
731 | + static VoidJob* make_job(std::shared_ptr<ItemImpl> const& item_impl, |
732 | QString const& method, |
733 | - QDBusPendingReply<void> const& reply); |
734 | + QDBusPendingReply<void>& reply); |
735 | static VoidJob* make_job(StorageError const& e); |
736 | |
737 | private: |
738 | - VoidJobImpl(std::shared_ptr<ItemImpl> const& item, |
739 | + VoidJobImpl(std::shared_ptr<ItemImpl> const& item_impl, |
740 | QString const& method, |
741 | - QDBusPendingReply<void> const& reply); |
742 | + QDBusPendingReply<void>& reply); |
743 | VoidJobImpl(StorageError const& e); |
744 | |
745 | VoidJob* public_instance_; |
746 | VoidJob::Status status_; |
747 | StorageError error_; |
748 | QString method_; |
749 | - std::shared_ptr<ItemImpl> item_; |
750 | + std::shared_ptr<ItemImpl> item_impl_; |
751 | }; |
752 | |
753 | } // namespace internal |
754 | |
755 | === modified file 'src/provider/CMakeLists.txt' |
756 | --- src/provider/CMakeLists.txt 2016-09-03 00:53:43 +0000 |
757 | +++ src/provider/CMakeLists.txt 2016-10-12 08:09:09 +0000 |
758 | @@ -6,7 +6,7 @@ |
759 | qt5_add_dbus_interface(generated_files bus.xml businterface) |
760 | |
761 | set_source_files_properties(${generated_files} PROPERTIES |
762 | - COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wmissing-field-initializers" |
763 | + COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wno-missing-field-initializers" |
764 | GENERATED TRUE |
765 | ) |
766 | |
767 | @@ -42,6 +42,11 @@ |
768 | ${CMAKE_SOURCE_DIR}/include/unity/storage/provider/internal/TempfileUploadJobImpl.h |
769 | ${CMAKE_SOURCE_DIR}/include/unity/storage/provider/internal/UploadJobImpl.h |
770 | ) |
771 | + |
772 | +set_source_files_properties(internal/ProviderInterface.cpp PROPERTIES |
773 | + COMPILE_FLAGS "-Wno-missing-field-initializers" |
774 | +) |
775 | + |
776 | add_dependencies(sf-provider-objects sf-provider-generated-files) |
777 | set_target_properties(sf-provider-objects PROPERTIES |
778 | AUTOMOC TRUE |
779 | |
780 | === modified file 'src/provider/internal/Handler.cpp' |
781 | --- src/provider/internal/Handler.cpp 2016-08-12 06:19:22 +0000 |
782 | +++ src/provider/internal/Handler.cpp 2016-10-12 08:09:09 +0000 |
783 | @@ -105,7 +105,6 @@ |
784 | } |
785 | catch (std::exception const& e) |
786 | { |
787 | - qDebug() << e.what(); |
788 | marshal_exception(current_exception()); |
789 | } |
790 | QMetaObject::invokeMethod(this, "send_reply", Qt::QueuedConnection); |
791 | |
792 | === modified file 'src/qt/CMakeLists.txt' |
793 | --- src/qt/CMakeLists.txt 2016-10-10 05:24:16 +0000 |
794 | +++ src/qt/CMakeLists.txt 2016-10-12 08:09:09 +0000 |
795 | @@ -9,8 +9,8 @@ |
796 | ${CMAKE_SOURCE_DIR}/data/provider.xml |
797 | ProviderInterface |
798 | ) |
799 | -set_source_files_properties(${generated_files} PROPERTIES |
800 | - COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wmissing-field-initializers" |
801 | +set_source_files_properties(${generated_files} dbusmarshal.cpp PROPERTIES |
802 | + COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wno-missing-field-initializers" |
803 | GENERATED TRUE |
804 | ) |
805 | |
806 | @@ -18,14 +18,17 @@ |
807 | set(QT_CLIENT_LIB_V2_SRC |
808 | Account.cpp |
809 | AccountsJob.cpp |
810 | + Downloader.cpp |
811 | Item.cpp |
812 | ItemJob.cpp |
813 | ItemListJob.cpp |
814 | Runtime.cpp |
815 | StorageError.cpp |
816 | + Uploader.cpp |
817 | VoidJob.cpp |
818 | internal/AccountImpl.cpp |
819 | internal/AccountsJobImpl.cpp |
820 | + internal/DownloaderImpl.cpp |
821 | internal/HandlerBase.cpp |
822 | internal/ItemImpl.cpp |
823 | internal/ItemJobImpl.cpp |
824 | @@ -37,15 +40,19 @@ |
825 | internal/StorageErrorImpl.cpp |
826 | internal/unmarshal_error.cpp |
827 | internal/validate.cpp |
828 | + internal/UploaderImpl.cpp |
829 | internal/VoidJobImpl.cpp |
830 | ${generated_files} |
831 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/Account.h |
832 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/AccountsJob.h |
833 | + ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/Downloader.h |
834 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/Item.h |
835 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/ItemJob.h |
836 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/ItemListJob.h |
837 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/Runtime.h |
838 | + ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/Uploader.h |
839 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/VoidJob.h |
840 | + ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/DownloaderImpl.h |
841 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/AccountsJobImpl.h |
842 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/HandlerBase.h |
843 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/ItemJobImpl.h |
844 | @@ -53,6 +60,7 @@ |
845 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/ListJobImplBase.h |
846 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/MultiItemJobImpl.h |
847 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/MultiItemListJobImpl.h |
848 | + ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/UploaderImpl.h |
849 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/VoidJobImpl.h |
850 | ) |
851 | |
852 | |
853 | === added file 'src/qt/Downloader.cpp' |
854 | --- src/qt/Downloader.cpp 1970-01-01 00:00:00 +0000 |
855 | +++ src/qt/Downloader.cpp 2016-10-12 08:09:09 +0000 |
856 | @@ -0,0 +1,76 @@ |
857 | +/* |
858 | + * Copyright (C) 2016 Canonical Ltd |
859 | + * |
860 | + * This program is free software: you can redistribute it and/or modify |
861 | + * it under the terms of the GNU Lesser General Public License version 3 as |
862 | + * published by the Free Software Foundation. |
863 | + * |
864 | + * This program is distributed in the hope that it will be useful, |
865 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
866 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
867 | + * GNU Lesser General Public License for more details. |
868 | + * |
869 | + * You should have received a copy of the GNU Lesser General Public License |
870 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
871 | + * |
872 | + * Authors: Michi Henning <michi.henning@canonical.com> |
873 | + */ |
874 | + |
875 | +#include <unity/storage/qt/Downloader.h> |
876 | + |
877 | +#include <unity/storage/qt/internal/DownloaderImpl.h> |
878 | + |
879 | +#include <cassert> |
880 | + |
881 | +using namespace std; |
882 | + |
883 | +namespace unity |
884 | +{ |
885 | +namespace storage |
886 | +{ |
887 | +namespace qt |
888 | +{ |
889 | + |
890 | +Downloader::Downloader() = default; |
891 | + |
892 | +Downloader::Downloader(unique_ptr<internal::DownloaderImpl> p) |
893 | + : p_(move(p)) |
894 | +{ |
895 | + assert(p_); |
896 | +} |
897 | + |
898 | +Downloader::~Downloader() = default; |
899 | + |
900 | +bool Downloader::isValid() const |
901 | +{ |
902 | + return p_->isValid(); |
903 | +} |
904 | + |
905 | +Downloader::Status Downloader::status() const |
906 | +{ |
907 | + return p_->status(); |
908 | +} |
909 | + |
910 | +StorageError Downloader::error() const |
911 | +{ |
912 | + return p_->error(); |
913 | +} |
914 | + |
915 | +Item Downloader::item() const |
916 | +{ |
917 | + return p_->item(); |
918 | +} |
919 | + |
920 | +void Downloader::finishDownload() |
921 | +{ |
922 | + p_->finishDownload(); |
923 | +} |
924 | + |
925 | +void Downloader::cancel() |
926 | +{ |
927 | + p_->cancel(); |
928 | +} |
929 | + |
930 | +} // namespace qt |
931 | +} // namespace storage |
932 | +} // namespace unity |
933 | |
934 | === modified file 'src/qt/Item.cpp' |
935 | --- src/qt/Item.cpp 2016-09-28 04:37:14 +0000 |
936 | +++ src/qt/Item.cpp 2016-10-12 08:09:09 +0000 |
937 | @@ -20,7 +20,6 @@ |
938 | #include <unity/storage/qt/internal/ItemImpl.h> |
939 | |
940 | #include <cassert> |
941 | -#include <QDebug> // TODO: remove this |
942 | |
943 | using namespace std; |
944 | |
945 | |
946 | === added file 'src/qt/Uploader.cpp' |
947 | --- src/qt/Uploader.cpp 1970-01-01 00:00:00 +0000 |
948 | +++ src/qt/Uploader.cpp 2016-10-12 08:09:09 +0000 |
949 | @@ -0,0 +1,86 @@ |
950 | +/* |
951 | + * Copyright (C) 2016 Canonical Ltd |
952 | + * |
953 | + * This program is free software: you can redistribute it and/or modify |
954 | + * it under the terms of the GNU Lesser General Public License version 3 as |
955 | + * published by the Free Software Foundation. |
956 | + * |
957 | + * This program is distributed in the hope that it will be useful, |
958 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
959 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
960 | + * GNU Lesser General Public License for more details. |
961 | + * |
962 | + * You should have received a copy of the GNU Lesser General Public License |
963 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
964 | + * |
965 | + * Authors: Michi Henning <michi.henning@canonical.com> |
966 | + */ |
967 | + |
968 | +#include <unity/storage/qt/Uploader.h> |
969 | + |
970 | +#include <unity/storage/qt/internal/UploaderImpl.h> |
971 | + |
972 | +#include <cassert> |
973 | + |
974 | +using namespace std; |
975 | + |
976 | +namespace unity |
977 | +{ |
978 | +namespace storage |
979 | +{ |
980 | +namespace qt |
981 | +{ |
982 | + |
983 | +Uploader::Uploader() = default; |
984 | + |
985 | +Uploader::Uploader(unique_ptr<internal::UploaderImpl> p) |
986 | + : p_(move(p)) |
987 | +{ |
988 | + assert(p_); |
989 | +} |
990 | + |
991 | +Uploader::~Uploader() = default; |
992 | + |
993 | +bool Uploader::isValid() const |
994 | +{ |
995 | + return p_->isValid(); |
996 | +} |
997 | + |
998 | +Uploader::Status Uploader::status() const |
999 | +{ |
1000 | + return p_->status(); |
1001 | +} |
1002 | + |
1003 | +StorageError Uploader::error() const |
1004 | +{ |
1005 | + return p_->error(); |
1006 | +} |
1007 | + |
1008 | +Item::ConflictPolicy Uploader::policy() const |
1009 | +{ |
1010 | + return p_->policy(); |
1011 | +} |
1012 | + |
1013 | +qint64 Uploader::sizeInBytes() const |
1014 | +{ |
1015 | + return p_->sizeInBytes(); |
1016 | +} |
1017 | + |
1018 | +Item Uploader::item() const |
1019 | +{ |
1020 | + return p_->item(); |
1021 | +} |
1022 | + |
1023 | +void Uploader::finishUpload() |
1024 | +{ |
1025 | + p_->finishUpload(); |
1026 | +} |
1027 | + |
1028 | +void Uploader::cancel() |
1029 | +{ |
1030 | + p_->cancel(); |
1031 | +} |
1032 | + |
1033 | +} // namespace qt |
1034 | +} // namespace storage |
1035 | +} // namespace unity |
1036 | |
1037 | === modified file 'src/qt/client/CMakeLists.txt' |
1038 | --- src/qt/client/CMakeLists.txt 2016-09-21 05:03:19 +0000 |
1039 | +++ src/qt/client/CMakeLists.txt 2016-10-12 08:09:09 +0000 |
1040 | @@ -88,7 +88,7 @@ |
1041 | ProviderInterface |
1042 | ) |
1043 | set_source_files_properties(${generated_files} PROPERTIES |
1044 | - COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wmissing-field-initializers" |
1045 | + COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wno-missing-field-initializers" |
1046 | GENERATED TRUE |
1047 | ) |
1048 | |
1049 | |
1050 | === modified file 'src/qt/internal/AccountImpl.cpp' |
1051 | --- src/qt/internal/AccountImpl.cpp 2016-09-29 02:40:05 +0000 |
1052 | +++ src/qt/internal/AccountImpl.cpp 2016-10-12 08:09:09 +0000 |
1053 | @@ -47,7 +47,7 @@ |
1054 | { |
1055 | } |
1056 | |
1057 | -AccountImpl::AccountImpl(shared_ptr<RuntimeImpl> const& runtime, |
1058 | +AccountImpl::AccountImpl(shared_ptr<RuntimeImpl> const& runtime_impl, |
1059 | QString const& bus_name, |
1060 | QString const& object_path, |
1061 | QString const& owner_id, |
1062 | @@ -59,8 +59,8 @@ |
1063 | , owner_id_(owner_id) |
1064 | , owner_(owner) |
1065 | , description_(description) |
1066 | - , runtime_(runtime) |
1067 | - , provider_(new ProviderInterface(bus_name, object_path, runtime->connection())) |
1068 | + , runtime_impl_(runtime_impl) |
1069 | + , provider_(new ProviderInterface(bus_name, object_path, runtime_impl->connection())) |
1070 | { |
1071 | assert(!bus_name.isEmpty()); |
1072 | assert(!object_path.isEmpty()); |
1073 | @@ -85,7 +85,7 @@ |
1074 | { |
1075 | QString const method = "Account::roots()"; |
1076 | |
1077 | - auto runtime = runtime_.lock(); |
1078 | + auto runtime = runtime_impl_.lock(); |
1079 | if (!is_valid_) |
1080 | { |
1081 | auto e = StorageErrorImpl::logic_error(method + ": cannot create job from invalid account"); |
1082 | @@ -121,7 +121,7 @@ |
1083 | auto e = StorageErrorImpl::logic_error(method + ": cannot create job from invalid account"); |
1084 | return ItemJobImpl::make_job(e); |
1085 | } |
1086 | - auto runtime = runtime_.lock(); |
1087 | + auto runtime = runtime_impl_.lock(); |
1088 | if (!runtime || !runtime->isValid()) |
1089 | { |
1090 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); |
1091 | @@ -199,9 +199,9 @@ |
1092 | return !operator<(other); |
1093 | } |
1094 | |
1095 | -shared_ptr<RuntimeImpl> AccountImpl::runtime() const |
1096 | +shared_ptr<RuntimeImpl> AccountImpl::runtime_impl() const |
1097 | { |
1098 | - return runtime_.lock(); |
1099 | + return runtime_impl_.lock(); |
1100 | } |
1101 | |
1102 | shared_ptr<ProviderInterface> AccountImpl::provider() const |
1103 | |
1104 | === modified file 'src/qt/internal/AccountsJobImpl.cpp' |
1105 | --- src/qt/internal/AccountsJobImpl.cpp 2016-09-29 03:17:56 +0000 |
1106 | +++ src/qt/internal/AccountsJobImpl.cpp 2016-10-12 08:09:09 +0000 |
1107 | @@ -50,13 +50,13 @@ |
1108 | |
1109 | } // namespace |
1110 | |
1111 | -AccountsJobImpl::AccountsJobImpl(AccountsJob* public_instance, shared_ptr<RuntimeImpl> const& runtime) |
1112 | +AccountsJobImpl::AccountsJobImpl(AccountsJob* public_instance, shared_ptr<RuntimeImpl> const& runtime_impl) |
1113 | : public_instance_(public_instance) |
1114 | , status_(AccountsJob::Status::Loading) |
1115 | - , runtime_(runtime) |
1116 | + , runtime_impl_(runtime_impl) |
1117 | { |
1118 | assert(public_instance); |
1119 | - assert(runtime); |
1120 | + assert(runtime_impl); |
1121 | |
1122 | initialize_accounts(); |
1123 | } |
1124 | @@ -89,7 +89,7 @@ |
1125 | |
1126 | QList<Account> AccountsJobImpl::accounts() const |
1127 | { |
1128 | - auto runtime = get_runtime("AccountsJob::accounts()"); |
1129 | + auto runtime = get_runtime_impl("AccountsJob::accounts()"); |
1130 | if (!runtime) |
1131 | { |
1132 | return QList<Account>(); |
1133 | @@ -131,9 +131,9 @@ |
1134 | return new_status; |
1135 | } |
1136 | |
1137 | -shared_ptr<RuntimeImpl> AccountsJobImpl::get_runtime(QString const& method) const |
1138 | +shared_ptr<RuntimeImpl> AccountsJobImpl::get_runtime_impl(QString const& method) const |
1139 | { |
1140 | - auto runtime = runtime_.lock(); |
1141 | + auto runtime = runtime_impl_.lock(); |
1142 | if (!runtime || !runtime->isValid()) |
1143 | { |
1144 | QString msg = method + ": Runtime was destroyed previously"; |
1145 | @@ -146,7 +146,7 @@ |
1146 | |
1147 | void AccountsJobImpl::initialize_accounts() |
1148 | { |
1149 | - auto runtime = get_runtime("AccountsJob()"); |
1150 | + auto runtime = get_runtime_impl("AccountsJob()"); |
1151 | assert(runtime); |
1152 | |
1153 | auto manager = runtime->accounts_manager(); |
1154 | |
1155 | === added file 'src/qt/internal/DownloaderImpl.cpp' |
1156 | --- src/qt/internal/DownloaderImpl.cpp 1970-01-01 00:00:00 +0000 |
1157 | +++ src/qt/internal/DownloaderImpl.cpp 2016-10-12 08:09:09 +0000 |
1158 | @@ -0,0 +1,280 @@ |
1159 | +/* |
1160 | + * Copyright (C) 2016 Canonical Ltd |
1161 | + * |
1162 | + * This program is free software: you can redistribute it and/or modify |
1163 | + * it under the terms of the GNU Lesser General Public License version 3 as |
1164 | + * published by the Free Software Foundation. |
1165 | + * |
1166 | + * This program is distributed in the hope that it will be useful, |
1167 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1168 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1169 | + * GNU Lesser General Public License for more details. |
1170 | + * |
1171 | + * You should have received a copy of the GNU Lesser General Public License |
1172 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1173 | + * |
1174 | + * Authors: Michi Henning <michi.henning@canonical.com> |
1175 | + */ |
1176 | + |
1177 | +#include <unity/storage/qt/internal/DownloaderImpl.h> |
1178 | + |
1179 | +#include "ProviderInterface.h" |
1180 | +#include <unity/storage/qt/internal/Handler.h> |
1181 | +#include <unity/storage/qt/internal/ItemImpl.h> |
1182 | +#include <unity/storage/qt/internal/VoidJobImpl.h> |
1183 | +#include <unity/storage/qt/ItemJob.h> |
1184 | + |
1185 | +#include <cassert> |
1186 | + |
1187 | +using namespace std; |
1188 | + |
1189 | +namespace unity |
1190 | +{ |
1191 | +namespace storage |
1192 | +{ |
1193 | +namespace qt |
1194 | +{ |
1195 | +namespace internal |
1196 | +{ |
1197 | + |
1198 | +DownloaderImpl::DownloaderImpl(shared_ptr<ItemImpl> const& item_impl, |
1199 | + QString const& method, |
1200 | + QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply) |
1201 | + : status_(Downloader::Status::Loading) |
1202 | + , item_impl_(item_impl) |
1203 | +{ |
1204 | + assert(item_impl); |
1205 | + assert(!method.isEmpty()); |
1206 | + |
1207 | + auto process_reply = [this, method](decltype(reply)& r) |
1208 | + { |
1209 | + if (status_ != Downloader::Status::Loading) |
1210 | + { |
1211 | + return; // Don't transition to a final state more than once. |
1212 | + } |
1213 | + |
1214 | + auto runtime = item_impl_->runtime_impl(); |
1215 | + if (!runtime || !runtime->isValid()) |
1216 | + { |
1217 | + QString msg = method + ": Runtime was destroyed previously"; |
1218 | + error_ = StorageErrorImpl::runtime_destroyed_error(msg); |
1219 | + public_instance_->abort(); |
1220 | + public_instance_->setErrorString(msg); |
1221 | + status_ = Downloader::Status::Error; |
1222 | + Q_EMIT public_instance_->statusChanged(status_); |
1223 | + return; |
1224 | + } |
1225 | + |
1226 | + download_id_ = r.argumentAt<0>(); |
1227 | + fd_ = r.argumentAt<1>(); |
1228 | + if (fd_.fileDescriptor() < 0) |
1229 | + { |
1230 | + // LCOV_EXCL_START |
1231 | + QString msg = method + ": invalid file descriptor returned by provider"; |
1232 | + qCritical().noquote() << msg; |
1233 | + error_ = StorageErrorImpl::local_comms_error(msg); |
1234 | + public_instance_->abort(); |
1235 | + public_instance_->setErrorString(msg); |
1236 | + status_ = Downloader::Status::Error; |
1237 | + Q_EMIT public_instance_->statusChanged(status_); |
1238 | + return; |
1239 | + // LCOV_EXCL_STOP |
1240 | + } |
1241 | + |
1242 | + public_instance_->setSocketDescriptor(fd_.fileDescriptor(), QLocalSocket::ConnectedState, QIODevice::ReadOnly); |
1243 | + status_ = Downloader::Status::Ready; |
1244 | + Q_EMIT public_instance_->statusChanged(status_); |
1245 | + }; |
1246 | + |
1247 | + auto process_error = [this](StorageError const& error) |
1248 | + { |
1249 | + // TODO: This does not set the method |
1250 | + error_ = error; |
1251 | + status_ = Downloader::Status::Error; |
1252 | + public_instance_->abort(); |
1253 | + public_instance_->setErrorString(error.errorString()); |
1254 | + Q_EMIT public_instance_->statusChanged(status_); |
1255 | + }; |
1256 | + |
1257 | + new Handler<storage::internal::ItemMetadata>(this, reply, process_reply, process_error); |
1258 | +} |
1259 | + |
1260 | +DownloaderImpl::DownloaderImpl(StorageError const& e) |
1261 | + : status_(Downloader::Status::Error) |
1262 | + , error_(e) |
1263 | +{ |
1264 | +} |
1265 | + |
1266 | +DownloaderImpl::~DownloaderImpl() |
1267 | +{ |
1268 | + switch (status_) |
1269 | + { |
1270 | + case Downloader::Status::Loading: |
1271 | + case Downloader::Status::Finished: |
1272 | + case Downloader::Status::Cancelled: |
1273 | + case Downloader::Status::Error: |
1274 | + break; |
1275 | + case Downloader::Status::Ready: |
1276 | + public_instance_->abort(); |
1277 | + break; |
1278 | + default: |
1279 | + abort(); // Impossible. // LCOV_EXCL_LINE |
1280 | + } |
1281 | +} |
1282 | + |
1283 | +bool DownloaderImpl::isValid() const |
1284 | +{ |
1285 | + return status_ != Downloader::Status::Error && status_ != Downloader::Status::Cancelled; |
1286 | +} |
1287 | + |
1288 | +Downloader::Status DownloaderImpl::status() const |
1289 | +{ |
1290 | + return status_; |
1291 | +} |
1292 | + |
1293 | +StorageError DownloaderImpl::error() const |
1294 | +{ |
1295 | + return error_; |
1296 | +} |
1297 | + |
1298 | +Item DownloaderImpl::item() const |
1299 | +{ |
1300 | + if (status_ == Downloader::Status::Error) |
1301 | + { |
1302 | + return Item(); |
1303 | + } |
1304 | + return Item(item_impl_); |
1305 | +} |
1306 | + |
1307 | +void DownloaderImpl::finishDownload() |
1308 | +{ |
1309 | + static QString const method = "Downloader::finishDownload()"; |
1310 | + |
1311 | + // If we encountered an error earlier or were cancelled, or if finishDownload() was |
1312 | + // called already, we ignore the call. |
1313 | + if (status_ == Downloader::Status::Error || status_ == Downloader::Status::Cancelled || finalizing_) |
1314 | + { |
1315 | + return; |
1316 | + } |
1317 | + |
1318 | + // Complain if we are asked to finalize while in the Loading or Finished state. |
1319 | + if (status_ != Downloader::Ready) |
1320 | + { |
1321 | + QString msg = method + ": cannot finalize while Downloader is not in the Ready state"; |
1322 | + error_ = StorageErrorImpl::logic_error(msg); |
1323 | + public_instance_->abort(); |
1324 | + public_instance_->setErrorString(msg); |
1325 | + status_ = Downloader::Status::Error; |
1326 | + Q_EMIT public_instance_->statusChanged(status_); |
1327 | + return; |
1328 | + } |
1329 | + |
1330 | + auto runtime = item_impl_->runtime_impl(); |
1331 | + if (!runtime || !runtime->isValid()) |
1332 | + { |
1333 | + QString msg = method + ": Runtime was destroyed previously"; |
1334 | + error_ = StorageErrorImpl::runtime_destroyed_error(msg); |
1335 | + status_ = Downloader::Status::Error; |
1336 | + Q_EMIT public_instance_->statusChanged(status_); |
1337 | + return; |
1338 | + } |
1339 | + |
1340 | + finalizing_ = true; |
1341 | + auto reply = item_impl_->account_impl()->provider()->FinishDownload(download_id_); |
1342 | + |
1343 | + auto process_reply = [this](decltype(reply)&) |
1344 | + { |
1345 | + if (status_ == Downloader::Status::Cancelled || status_ == Downloader::Status::Error) |
1346 | + { |
1347 | + return; // Don't transition to a final state more than once. |
1348 | + } |
1349 | + |
1350 | + auto runtime = item_impl_->runtime_impl(); |
1351 | + if (!runtime || !runtime->isValid()) |
1352 | + { |
1353 | + QString msg = method + ": Runtime was destroyed previously"; |
1354 | + error_ = StorageErrorImpl::runtime_destroyed_error(msg); |
1355 | + public_instance_->abort(); |
1356 | + public_instance_->setErrorString(msg); |
1357 | + status_ = Downloader::Status::Error; |
1358 | + Q_EMIT public_instance_->statusChanged(status_); |
1359 | + return; |
1360 | + } |
1361 | + |
1362 | + status_ = Downloader::Status::Finished; |
1363 | + Q_EMIT public_instance_->statusChanged(status_); |
1364 | + }; |
1365 | + |
1366 | + auto process_error = [this](StorageError const& error) |
1367 | + { |
1368 | + if (status_ != Downloader::Status::Ready) |
1369 | + { |
1370 | + return; // Don't transition to a final state more than once. |
1371 | + } |
1372 | + |
1373 | + // TODO: this doesn't set the method |
1374 | + error_ = error; |
1375 | + public_instance_->abort(); |
1376 | + public_instance_->setErrorString(error.errorString()); |
1377 | + status_ = Downloader::Status::Error; |
1378 | + Q_EMIT public_instance_->statusChanged(status_); |
1379 | + }; |
1380 | + |
1381 | + new Handler<void>(this, reply, process_reply, process_error); |
1382 | +} |
1383 | + |
1384 | +void DownloaderImpl::cancel() |
1385 | +{ |
1386 | + static QString const method = "Downloader::cancel()"; |
1387 | + |
1388 | + // If we are in a final state already, ignore the call. |
1389 | + if ( status_ == Downloader::Status::Error |
1390 | + || status_ == Downloader::Status::Finished |
1391 | + || status_ == Downloader::Status::Cancelled) |
1392 | + { |
1393 | + return; |
1394 | + } |
1395 | + auto runtime = item_impl_->runtime_impl(); |
1396 | + if (!runtime || !runtime->isValid()) |
1397 | + { |
1398 | + QString msg = method + ": Runtime was destroyed previously"; |
1399 | + error_ = StorageErrorImpl::runtime_destroyed_error(msg); |
1400 | + status_ = Downloader::Status::Error; |
1401 | + Q_EMIT public_instance_->statusChanged(status_); |
1402 | + return; |
1403 | + } |
1404 | + |
1405 | + QString msg = method + ": download was cancelled"; |
1406 | + error_ = StorageErrorImpl::cancelled_error(msg); |
1407 | + public_instance_->abort(); |
1408 | + public_instance_->setErrorString(msg); |
1409 | + status_ = Downloader::Status::Cancelled; |
1410 | + Q_EMIT public_instance_->statusChanged(status_); |
1411 | +} |
1412 | + |
1413 | +Downloader* DownloaderImpl::make_job(shared_ptr<ItemImpl> const& item_impl, |
1414 | + QString const& method, |
1415 | + QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply) |
1416 | +{ |
1417 | + unique_ptr<DownloaderImpl> impl(new DownloaderImpl(item_impl, method, reply)); |
1418 | + auto downloader = new Downloader(move(impl)); |
1419 | + downloader->p_->public_instance_ = downloader; |
1420 | + return downloader; |
1421 | +} |
1422 | + |
1423 | +Downloader* DownloaderImpl::make_job(StorageError const& e) |
1424 | +{ |
1425 | + unique_ptr<DownloaderImpl> impl(new DownloaderImpl(e)); |
1426 | + auto downloader = new Downloader(move(impl)); |
1427 | + downloader->p_->public_instance_ = downloader; |
1428 | + QMetaObject::invokeMethod(downloader, |
1429 | + "statusChanged", |
1430 | + Qt::QueuedConnection, |
1431 | + Q_ARG(unity::storage::qt::Downloader::Status, downloader->p_->status_)); |
1432 | + return downloader; |
1433 | +} |
1434 | + |
1435 | +} // namespace internal |
1436 | +} // namespace qt |
1437 | +} // namespace storage |
1438 | +} // namespace unity |
1439 | |
1440 | === modified file 'src/qt/internal/ItemImpl.cpp' |
1441 | --- src/qt/internal/ItemImpl.cpp 2016-10-10 23:31:31 +0000 |
1442 | +++ src/qt/internal/ItemImpl.cpp 2016-10-12 08:09:09 +0000 |
1443 | @@ -20,10 +20,12 @@ |
1444 | |
1445 | #include "ProviderInterface.h" |
1446 | #include <unity/storage/provider/metadata_keys.h> |
1447 | +#include <unity/storage/qt/internal/DownloaderImpl.h> |
1448 | #include <unity/storage/qt/internal/ItemJobImpl.h> |
1449 | #include <unity/storage/qt/internal/ItemListJobImpl.h> |
1450 | #include <unity/storage/qt/internal/MultiItemJobImpl.h> |
1451 | #include <unity/storage/qt/internal/MultiItemListJobImpl.h> |
1452 | +#include <unity/storage/qt/internal/UploaderImpl.h> |
1453 | #include <unity/storage/qt/internal/VoidJobImpl.h> |
1454 | #include <unity/storage/qt/internal/validate.h> |
1455 | |
1456 | @@ -49,12 +51,12 @@ |
1457 | } |
1458 | |
1459 | ItemImpl::ItemImpl(storage::internal::ItemMetadata const& md, |
1460 | - std::shared_ptr<AccountImpl> const& account) |
1461 | + std::shared_ptr<AccountImpl> const& account_impl) |
1462 | : is_valid_(true) |
1463 | , md_(md) |
1464 | - , account_(account) |
1465 | + , account_impl_(account_impl) |
1466 | { |
1467 | - assert(account); |
1468 | + assert(account_impl); |
1469 | } |
1470 | |
1471 | QString ItemImpl::itemId() const |
1472 | @@ -69,7 +71,7 @@ |
1473 | |
1474 | Account ItemImpl::account() const |
1475 | { |
1476 | - return is_valid_ ? account_ : Account(); |
1477 | + return is_valid_ ? account_impl_ : Account(); |
1478 | } |
1479 | |
1480 | QString ItemImpl::etag() const |
1481 | @@ -88,7 +90,7 @@ |
1482 | case storage::ItemType::root: |
1483 | return Item::Type::Root; |
1484 | default: |
1485 | - abort(); // LCOV_EXCL_LINE // Impossible |
1486 | + abort(); // Impossible. // LCOV_EXCL_LINE |
1487 | } |
1488 | } |
1489 | |
1490 | @@ -133,7 +135,7 @@ |
1491 | QList<QDBusPendingReply<storage::internal::ItemMetadata>> replies; |
1492 | for (auto const& id : md_.parent_ids) |
1493 | { |
1494 | - auto reply = account_->provider()->Metadata(id); |
1495 | + auto reply = account_impl_->provider()->Metadata(id); |
1496 | replies.append(reply); |
1497 | } |
1498 | |
1499 | @@ -147,7 +149,7 @@ |
1500 | } |
1501 | }; |
1502 | |
1503 | - return MultiItemJobImpl::make_job(account_, method, replies, validate); |
1504 | + return MultiItemJobImpl::make_job(account_impl_, method, replies, validate); |
1505 | } |
1506 | |
1507 | ItemJob* ItemImpl::copy(Item const& newParent, QString const& newName) const |
1508 | @@ -172,7 +174,7 @@ |
1509 | } |
1510 | }; |
1511 | |
1512 | - auto reply = account_->provider()->Copy(md_.item_id, newParent.itemId(), newName); |
1513 | + auto reply = account_impl_->provider()->Copy(md_.item_id, newParent.itemId(), newName); |
1514 | auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
1515 | return ItemJobImpl::make_job(This, method, reply, validate); |
1516 | } |
1517 | @@ -205,7 +207,7 @@ |
1518 | } |
1519 | }; |
1520 | |
1521 | - auto reply = account_->provider()->Move(md_.item_id, newParent.itemId(), newName); |
1522 | + auto reply = account_impl_->provider()->Move(md_.item_id, newParent.itemId(), newName); |
1523 | auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
1524 | return ItemJobImpl::make_job(This, method, reply, validate); |
1525 | } |
1526 | @@ -225,19 +227,63 @@ |
1527 | return VoidJobImpl::make_job(e); |
1528 | } |
1529 | |
1530 | - auto reply = account_->provider()->Delete(md_.item_id); |
1531 | + auto reply = account_impl_->provider()->Delete(md_.item_id); |
1532 | auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
1533 | return VoidJobImpl::make_job(This, method, reply); |
1534 | } |
1535 | |
1536 | Uploader* ItemImpl::createUploader(Item::ConflictPolicy policy, qint64 sizeInBytes) const |
1537 | { |
1538 | - return nullptr; // TODO |
1539 | + QString const method = "Item::createUploader()"; |
1540 | + |
1541 | + auto invalid_job = check_invalid_or_destroyed<UploaderImpl>(method); |
1542 | + if (invalid_job) |
1543 | + { |
1544 | + return invalid_job; |
1545 | + } |
1546 | + if (md_.type != storage::ItemType::file) |
1547 | + { |
1548 | + auto e = StorageErrorImpl::logic_error(method + ": cannot upload to a directory"); |
1549 | + return UploaderImpl::make_job(e); |
1550 | + } |
1551 | + if (sizeInBytes < 0) |
1552 | + { |
1553 | + auto e = StorageErrorImpl::logic_error(method + ": size must be >= 0"); |
1554 | + return UploaderImpl::make_job(e); |
1555 | + } |
1556 | + |
1557 | + auto validate = [method](storage::internal::ItemMetadata const& md) |
1558 | + { |
1559 | + if (md.type != storage::ItemType::file) |
1560 | + { |
1561 | + throw StorageErrorImpl::local_comms_error(method + ": impossible directory item returned by provider"); |
1562 | + } |
1563 | + }; |
1564 | + |
1565 | + auto etag = policy == Item::ConflictPolicy::Overwrite ? "" : md_.etag; |
1566 | + auto reply = account_impl_->provider()->Update(md_.item_id, sizeInBytes, etag); |
1567 | + auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
1568 | + return UploaderImpl::make_job(This, method, reply, validate, policy, sizeInBytes); |
1569 | } |
1570 | |
1571 | Downloader* ItemImpl::createDownloader() const |
1572 | { |
1573 | - return nullptr; // TODO |
1574 | + QString const method = "Item::createDownloader()"; |
1575 | + |
1576 | + auto invalid_job = check_invalid_or_destroyed<DownloaderImpl>(method); |
1577 | + if (invalid_job) |
1578 | + { |
1579 | + return invalid_job; |
1580 | + } |
1581 | + if (md_.type != storage::ItemType::file) |
1582 | + { |
1583 | + auto e = StorageErrorImpl::logic_error(method + ": cannot download a directory"); |
1584 | + return DownloaderImpl::make_job(e); |
1585 | + } |
1586 | + |
1587 | + auto reply = account_impl_->provider()->Download(md_.item_id); |
1588 | + auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
1589 | + return DownloaderImpl::make_job(This, method, reply); |
1590 | } |
1591 | |
1592 | ItemListJob* ItemImpl::list() const |
1593 | @@ -267,10 +313,10 @@ |
1594 | |
1595 | auto fetch_next = [this](QString const& page_token) |
1596 | { |
1597 | - return account_->provider()->List(md_.item_id, page_token); |
1598 | + return account_impl_->provider()->List(md_.item_id, page_token); |
1599 | }; |
1600 | |
1601 | - auto reply = account_->provider()->List(md_.item_id, ""); |
1602 | + auto reply = account_impl_->provider()->List(md_.item_id, ""); |
1603 | auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
1604 | return MultiItemListJobImpl::make_job(This, method, reply, validate, fetch_next); |
1605 | } |
1606 | @@ -294,7 +340,7 @@ |
1607 | { |
1608 | }; |
1609 | |
1610 | - auto reply = account_->provider()->Lookup(md_.item_id, name); |
1611 | + auto reply = account_impl_->provider()->Lookup(md_.item_id, name); |
1612 | auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
1613 | return ItemListJobImpl::make_job(This, method, reply, validate); |
1614 | } |
1615 | @@ -325,7 +371,7 @@ |
1616 | throw StorageErrorImpl::local_comms_error(msg); |
1617 | }; |
1618 | |
1619 | - auto reply = account_->provider()->CreateFolder(md_.item_id, name); |
1620 | + auto reply = account_impl_->provider()->CreateFolder(md_.item_id, name); |
1621 | auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
1622 | return ItemJobImpl::make_job(This, method, reply, validate); |
1623 | } |
1624 | @@ -350,7 +396,7 @@ |
1625 | if (is_valid_) |
1626 | { |
1627 | return other.is_valid_ |
1628 | - && *account_ == *other.account_ |
1629 | + && *account_impl_ == *other.account_impl_ |
1630 | && md_.item_id == other.md_.item_id; |
1631 | } |
1632 | return !other.is_valid_; |
1633 | @@ -372,11 +418,11 @@ |
1634 | return false; |
1635 | } |
1636 | assert(is_valid_ && other.is_valid_); |
1637 | - if (*account_ < *other.account_) |
1638 | + if (*account_impl_ < *other.account_impl_) |
1639 | { |
1640 | return true; |
1641 | } |
1642 | - if (*account_ > *other.account_) |
1643 | + if (*account_impl_ > *other.account_impl_) |
1644 | { |
1645 | return false; |
1646 | } |
1647 | @@ -405,28 +451,28 @@ |
1648 | return 0; |
1649 | } |
1650 | size_t hash = 0; |
1651 | - boost::hash_combine(hash, account_->hash()); |
1652 | + boost::hash_combine(hash, account_impl_->hash()); |
1653 | boost::hash_combine(hash, qHash(md_.item_id)); |
1654 | return hash; |
1655 | } |
1656 | |
1657 | Item ItemImpl::make_item(QString const& method, |
1658 | storage::internal::ItemMetadata const& md, |
1659 | - std::shared_ptr<AccountImpl> const& account) |
1660 | + std::shared_ptr<AccountImpl> const& account_impl) |
1661 | { |
1662 | validate(method, md); // Throws if no good. |
1663 | - auto p = make_shared<ItemImpl>(md, account); |
1664 | + auto p = make_shared<ItemImpl>(md, account_impl); |
1665 | return Item(p); |
1666 | } |
1667 | |
1668 | -shared_ptr<RuntimeImpl> ItemImpl::runtime() const |
1669 | +shared_ptr<RuntimeImpl> ItemImpl::runtime_impl() const |
1670 | { |
1671 | - return account_->runtime(); |
1672 | + return account_impl_->runtime_impl(); |
1673 | } |
1674 | |
1675 | shared_ptr<AccountImpl> ItemImpl::account_impl() const |
1676 | { |
1677 | - return account_; |
1678 | + return account_impl_; |
1679 | } |
1680 | |
1681 | } // namespace internal |
1682 | |
1683 | === modified file 'src/qt/internal/ItemJobImpl.cpp' |
1684 | --- src/qt/internal/ItemJobImpl.cpp 2016-09-30 01:48:08 +0000 |
1685 | +++ src/qt/internal/ItemJobImpl.cpp 2016-10-12 08:09:09 +0000 |
1686 | @@ -36,22 +36,22 @@ |
1687 | namespace internal |
1688 | { |
1689 | |
1690 | -ItemJobImpl::ItemJobImpl(shared_ptr<AccountImpl> const& account, |
1691 | +ItemJobImpl::ItemJobImpl(shared_ptr<AccountImpl> const& account_impl, |
1692 | QString const& method, |
1693 | - QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
1694 | + QDBusPendingReply<storage::internal::ItemMetadata>& reply, |
1695 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1696 | : status_(ItemJob::Status::Loading) |
1697 | , method_(method) |
1698 | - , account_(account) |
1699 | + , account_impl_(account_impl) |
1700 | , validate_(validate) |
1701 | { |
1702 | assert(!method.isEmpty()); |
1703 | - assert(account); |
1704 | + assert(account_impl); |
1705 | assert(validate); |
1706 | |
1707 | auto process_reply = [this](decltype(reply)& r) |
1708 | { |
1709 | - auto runtime = account_->runtime(); |
1710 | + auto runtime = account_impl_->runtime_impl(); |
1711 | if (!runtime || !runtime->isValid()) |
1712 | { |
1713 | error_ = StorageErrorImpl::runtime_destroyed_error(method_ + ": Runtime was destroyed previously"); |
1714 | @@ -64,12 +64,13 @@ |
1715 | try |
1716 | { |
1717 | validate_(metadata); |
1718 | - item_ = ItemImpl::make_item(method_, metadata, account_); |
1719 | + item_ = ItemImpl::make_item(method_, metadata, account_impl_); |
1720 | status_ = ItemJob::Status::Finished; |
1721 | } |
1722 | catch (StorageError const& e) |
1723 | { |
1724 | // Bad metadata received from provider, validate_() or make_item() have logged it. |
1725 | + // TODO: This does not set the method. |
1726 | error_ = e; |
1727 | status_ = ItemJob::Status::Error; |
1728 | } |
1729 | @@ -88,7 +89,7 @@ |
1730 | |
1731 | ItemJobImpl::ItemJobImpl(shared_ptr<ItemImpl> const& item, |
1732 | QString const& method, |
1733 | - QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
1734 | + QDBusPendingReply<storage::internal::ItemMetadata>& reply, |
1735 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1736 | : ItemJobImpl(item->account_impl(), method, reply, validate) |
1737 | { |
1738 | @@ -123,7 +124,7 @@ |
1739 | |
1740 | ItemJob* ItemJobImpl::make_job(shared_ptr<AccountImpl> const& account, |
1741 | QString const& method, |
1742 | - QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
1743 | + QDBusPendingReply<storage::internal::ItemMetadata>& reply, |
1744 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1745 | { |
1746 | unique_ptr<ItemJobImpl> impl(new ItemJobImpl(account, method, reply, validate)); |
1747 | @@ -134,7 +135,7 @@ |
1748 | |
1749 | ItemJob* ItemJobImpl::make_job(shared_ptr<ItemImpl> const& item, |
1750 | QString const& method, |
1751 | - QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
1752 | + QDBusPendingReply<storage::internal::ItemMetadata>& reply, |
1753 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1754 | { |
1755 | unique_ptr<ItemJobImpl> impl(new ItemJobImpl(item, method, reply, validate)); |
1756 | |
1757 | === modified file 'src/qt/internal/ItemListJobImpl.cpp' |
1758 | --- src/qt/internal/ItemListJobImpl.cpp 2016-10-10 03:55:32 +0000 |
1759 | +++ src/qt/internal/ItemListJobImpl.cpp 2016-10-12 08:09:09 +0000 |
1760 | @@ -35,15 +35,15 @@ |
1761 | namespace internal |
1762 | { |
1763 | |
1764 | -ItemListJobImpl::ItemListJobImpl(shared_ptr<AccountImpl> const& account, |
1765 | +ItemListJobImpl::ItemListJobImpl(shared_ptr<AccountImpl> const& account_impl, |
1766 | QString const& method, |
1767 | - QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
1768 | + QDBusPendingReply<QList<storage::internal::ItemMetadata>>& reply, |
1769 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1770 | - : ListJobImplBase(account, method, validate) |
1771 | + : ListJobImplBase(account_impl, method, validate) |
1772 | { |
1773 | auto process_reply = [this](decltype(reply)& r) |
1774 | { |
1775 | - auto runtime = account_->runtime(); |
1776 | + auto runtime = account_impl_->runtime_impl(); |
1777 | if (!runtime || !runtime->isValid()) |
1778 | { |
1779 | error_ = StorageErrorImpl::runtime_destroyed_error(method_ + ": Runtime was destroyed previously"); |
1780 | @@ -59,7 +59,7 @@ |
1781 | try |
1782 | { |
1783 | validate_(md); |
1784 | - auto item = ItemImpl::make_item(method_, md, account_); |
1785 | + auto item = ItemImpl::make_item(method_, md, account_impl_); |
1786 | items.append(item); |
1787 | } |
1788 | catch (StorageError const&) |
1789 | @@ -86,32 +86,32 @@ |
1790 | new Handler<QList<storage::internal::ItemMetadata>>(this, reply, process_reply, process_error); |
1791 | } |
1792 | |
1793 | -ItemListJobImpl::ItemListJobImpl(shared_ptr<ItemImpl> const& item, |
1794 | +ItemListJobImpl::ItemListJobImpl(shared_ptr<ItemImpl> const& item_impl, |
1795 | QString const& method, |
1796 | - QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
1797 | + QDBusPendingReply<QList<storage::internal::ItemMetadata>>& reply, |
1798 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1799 | - : ItemListJobImpl(item->account_impl(), method, reply, validate) |
1800 | + : ItemListJobImpl(item_impl->account_impl(), method, reply, validate) |
1801 | { |
1802 | - item_impl_ = item; |
1803 | + item_impl_ = item_impl; |
1804 | } |
1805 | |
1806 | -ItemListJob* ItemListJobImpl::make_job(shared_ptr<AccountImpl> const& account, |
1807 | +ItemListJob* ItemListJobImpl::make_job(shared_ptr<AccountImpl> const& account_impl, |
1808 | QString const& method, |
1809 | - QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
1810 | + QDBusPendingReply<QList<storage::internal::ItemMetadata>>& reply, |
1811 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1812 | { |
1813 | - unique_ptr<ItemListJobImpl> impl(new ItemListJobImpl(account, method, reply, validate)); |
1814 | + unique_ptr<ItemListJobImpl> impl(new ItemListJobImpl(account_impl, method, reply, validate)); |
1815 | auto job = new ItemListJob(move(impl)); |
1816 | job->p_->set_public_instance(job); |
1817 | return job; |
1818 | } |
1819 | |
1820 | -ItemListJob* ItemListJobImpl::make_job(shared_ptr<ItemImpl> const& item, |
1821 | +ItemListJob* ItemListJobImpl::make_job(shared_ptr<ItemImpl> const& item_impl, |
1822 | QString const& method, |
1823 | - QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
1824 | + QDBusPendingReply<QList<storage::internal::ItemMetadata>>& reply, |
1825 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1826 | { |
1827 | - unique_ptr<ItemListJobImpl> impl(new ItemListJobImpl(item, method, reply, validate)); |
1828 | + unique_ptr<ItemListJobImpl> impl(new ItemListJobImpl(item_impl, method, reply, validate)); |
1829 | auto job = new ItemListJob(move(impl)); |
1830 | job->p_->set_public_instance(job); |
1831 | return job; |
1832 | |
1833 | === modified file 'src/qt/internal/ListJobImplBase.cpp' |
1834 | --- src/qt/internal/ListJobImplBase.cpp 2016-09-29 03:17:56 +0000 |
1835 | +++ src/qt/internal/ListJobImplBase.cpp 2016-10-12 08:09:09 +0000 |
1836 | @@ -41,16 +41,16 @@ |
1837 | { |
1838 | } |
1839 | |
1840 | -ListJobImplBase::ListJobImplBase(shared_ptr<AccountImpl> const& account, |
1841 | +ListJobImplBase::ListJobImplBase(shared_ptr<AccountImpl> const& account_impl, |
1842 | QString const& method, |
1843 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
1844 | : status_(ItemListJob::Status::Loading) |
1845 | , method_(method) |
1846 | - , account_(account) |
1847 | + , account_impl_(account_impl) |
1848 | , validate_(validate) |
1849 | { |
1850 | assert(!method.isEmpty()); |
1851 | - assert(account); |
1852 | + assert(account_impl); |
1853 | assert(validate); |
1854 | } |
1855 | |
1856 | |
1857 | === modified file 'src/qt/internal/MultiItemJobImpl.cpp' |
1858 | --- src/qt/internal/MultiItemJobImpl.cpp 2016-09-30 01:48:08 +0000 |
1859 | +++ src/qt/internal/MultiItemJobImpl.cpp 2016-10-12 08:09:09 +0000 |
1860 | @@ -35,15 +35,15 @@ |
1861 | namespace internal |
1862 | { |
1863 | |
1864 | -MultiItemJobImpl::MultiItemJobImpl(shared_ptr<AccountImpl> const& account, |
1865 | +MultiItemJobImpl::MultiItemJobImpl(shared_ptr<AccountImpl> const& account_impl, |
1866 | QString const& method, |
1867 | - ReplyType const& replies, |
1868 | + ReplyType& replies, |
1869 | ValidateFunc const& validate) |
1870 | - : ListJobImplBase(account, method, validate) |
1871 | + : ListJobImplBase(account_impl, method, validate) |
1872 | , replies_remaining_(replies.size()) |
1873 | { |
1874 | assert(!method.isEmpty()); |
1875 | - assert(account); |
1876 | + assert(account_impl); |
1877 | assert(validate); |
1878 | |
1879 | // We ask the provider for the metadata for each of this item's parents. |
1880 | @@ -52,7 +52,7 @@ |
1881 | // If anything goes wrong at all, we report the first error and then ignore all |
1882 | // other replies. |
1883 | |
1884 | - auto process_reply = [this](QDBusPendingReply<storage::internal::ItemMetadata> const& r) |
1885 | + auto process_reply = [this](QDBusPendingReply<storage::internal::ItemMetadata>& r) |
1886 | { |
1887 | if (status_ != ItemListJob::Status::Loading) |
1888 | { |
1889 | @@ -61,7 +61,7 @@ |
1890 | |
1891 | --replies_remaining_; |
1892 | |
1893 | - auto runtime = account_->runtime(); |
1894 | + auto runtime = account_impl_->runtime_impl(); |
1895 | if (!runtime || !runtime->isValid()) |
1896 | { |
1897 | error_ = StorageErrorImpl::runtime_destroyed_error(method_ + ": Runtime was destroyed previously"); |
1898 | @@ -75,7 +75,7 @@ |
1899 | try |
1900 | { |
1901 | validate_(metadata); |
1902 | - item = ItemImpl::make_item(method_, metadata, account_); |
1903 | + item = ItemImpl::make_item(method_, metadata, account_impl_); |
1904 | } |
1905 | catch (StorageError const& e) |
1906 | { |
1907 | @@ -110,18 +110,18 @@ |
1908 | Q_EMIT public_instance_->statusChanged(status_); |
1909 | }; |
1910 | |
1911 | - for (auto const& reply : replies) |
1912 | + for (auto& reply : replies) |
1913 | { |
1914 | new Handler<storage::internal::ItemMetadata>(this, reply, process_reply, process_error); |
1915 | } |
1916 | } |
1917 | |
1918 | -ItemListJob* MultiItemJobImpl::make_job(shared_ptr<AccountImpl> const& account, |
1919 | +ItemListJob* MultiItemJobImpl::make_job(shared_ptr<AccountImpl> const& account_impl, |
1920 | QString const& method, |
1921 | - ReplyType const& replies, |
1922 | + ReplyType& replies, |
1923 | ValidateFunc const& validate) |
1924 | { |
1925 | - unique_ptr<MultiItemJobImpl> impl(new MultiItemJobImpl(account, method, replies, validate)); |
1926 | + unique_ptr<MultiItemJobImpl> impl(new MultiItemJobImpl(account_impl, method, replies, validate)); |
1927 | auto job = new ItemListJob(move(impl)); |
1928 | job->p_->set_public_instance(job); |
1929 | return job; |
1930 | |
1931 | === modified file 'src/qt/internal/MultiItemListJobImpl.cpp' |
1932 | --- src/qt/internal/MultiItemListJobImpl.cpp 2016-10-10 04:07:07 +0000 |
1933 | +++ src/qt/internal/MultiItemListJobImpl.cpp 2016-10-12 08:09:09 +0000 |
1934 | @@ -35,17 +35,17 @@ |
1935 | namespace internal |
1936 | { |
1937 | |
1938 | -MultiItemListJobImpl::MultiItemListJobImpl(shared_ptr<ItemImpl> const& item, |
1939 | +MultiItemListJobImpl::MultiItemListJobImpl(shared_ptr<ItemImpl> const& item_impl, |
1940 | QString const& method, |
1941 | - ReplyType const& reply, |
1942 | + ReplyType& reply, |
1943 | ValidateFunc const& validate, |
1944 | FetchFunc const& fetch_next) |
1945 | - : ListJobImplBase(item->account_impl(), method, validate) |
1946 | + : ListJobImplBase(item_impl->account_impl(), method, validate) |
1947 | , fetch_next_(fetch_next) |
1948 | { |
1949 | assert(fetch_next); |
1950 | |
1951 | - item_impl_ = item; |
1952 | + item_impl_ = item_impl; |
1953 | |
1954 | process_reply_ = [this](ReplyType const& r) |
1955 | { |
1956 | @@ -53,7 +53,7 @@ |
1957 | { |
1958 | return; |
1959 | } |
1960 | - auto runtime = item_impl_->account_impl()->runtime(); |
1961 | + auto runtime = item_impl_->account_impl()->runtime_impl(); |
1962 | if (!runtime || !runtime->isValid()) |
1963 | { |
1964 | error_ = StorageErrorImpl::runtime_destroyed_error(method_ + ": Runtime was destroyed previously"); |
1965 | @@ -69,7 +69,7 @@ |
1966 | try |
1967 | { |
1968 | validate_(md); |
1969 | - auto item = ItemImpl::make_item(method_, md, account_); |
1970 | + auto item = ItemImpl::make_item(method_, md, account_impl_); |
1971 | items.append(item); |
1972 | } |
1973 | catch (StorageError const& e) |
1974 | @@ -96,7 +96,8 @@ |
1975 | } |
1976 | else |
1977 | { |
1978 | - new Handler<ReplyType>(this, fetch_next_(token), process_reply_, process_error_); |
1979 | + auto reply = fetch_next_(token); |
1980 | + new Handler<ReplyType>(this, reply, process_reply_, process_error_); |
1981 | } |
1982 | }; |
1983 | |
1984 | @@ -115,7 +116,7 @@ |
1985 | |
1986 | ItemListJob* MultiItemListJobImpl::make_job(shared_ptr<ItemImpl> const& item, |
1987 | QString const& method, |
1988 | - ReplyType const& reply, |
1989 | + ReplyType& reply, |
1990 | ValidateFunc const& validate, |
1991 | FetchFunc const& fetch_next) |
1992 | { |
1993 | |
1994 | === modified file 'src/qt/internal/StorageErrorImpl.cpp' |
1995 | --- src/qt/internal/StorageErrorImpl.cpp 2016-10-10 04:07:07 +0000 |
1996 | +++ src/qt/internal/StorageErrorImpl.cpp 2016-10-12 08:09:09 +0000 |
1997 | @@ -40,7 +40,6 @@ |
1998 | QStringLiteral("NoError"), |
1999 | QStringLiteral("LocalCommsError"), |
2000 | QStringLiteral("RemoteCommsError"), |
2001 | - QStringLiteral("Deleted"), |
2002 | QStringLiteral("RuntimeDestroyed"), |
2003 | QStringLiteral("NotExists"), |
2004 | QStringLiteral("Exists"), |
2005 | @@ -86,8 +85,7 @@ |
2006 | StorageErrorImpl::StorageErrorImpl(StorageError::Type type, QString const& msg, QString const& key) |
2007 | : StorageErrorImpl(type) |
2008 | { |
2009 | - assert( type == StorageError::Type::Deleted |
2010 | - || type == StorageError::Type::NotExists); |
2011 | + assert(type == StorageError::Type::NotExists); |
2012 | assert(!msg.isEmpty()); |
2013 | |
2014 | message_ = msg; |
2015 | @@ -177,12 +175,6 @@ |
2016 | return StorageError(move(p)); |
2017 | } |
2018 | |
2019 | -StorageError StorageErrorImpl::deleted_error(QString const& msg, QString const& item_id) |
2020 | -{ |
2021 | - unique_ptr<StorageErrorImpl> p(new StorageErrorImpl(StorageError::Type::Deleted, msg, item_id)); |
2022 | - return StorageError(move(p)); |
2023 | -} |
2024 | - |
2025 | StorageError StorageErrorImpl::runtime_destroyed_error(QString const& msg) |
2026 | { |
2027 | unique_ptr<StorageErrorImpl> p(new StorageErrorImpl(StorageError::Type::RuntimeDestroyed, msg)); |
2028 | |
2029 | === added file 'src/qt/internal/UploaderImpl.cpp' |
2030 | --- src/qt/internal/UploaderImpl.cpp 1970-01-01 00:00:00 +0000 |
2031 | +++ src/qt/internal/UploaderImpl.cpp 2016-10-12 08:09:09 +0000 |
2032 | @@ -0,0 +1,332 @@ |
2033 | +/* |
2034 | + * Copyright (C) 2016 Canonical Ltd |
2035 | + * |
2036 | + * This program is free software: you can redistribute it and/or modify |
2037 | + * it under the terms of the GNU Lesser General Public License version 3 as |
2038 | + * published by the Free Software Foundation. |
2039 | + * |
2040 | + * This program is distributed in the hope that it will be useful, |
2041 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2042 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2043 | + * GNU Lesser General Public License for more details. |
2044 | + * |
2045 | + * You should have received a copy of the GNU Lesser General Public License |
2046 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2047 | + * |
2048 | + * Authors: Michi Henning <michi.henning@canonical.com> |
2049 | + */ |
2050 | + |
2051 | +#include <unity/storage/qt/internal/UploaderImpl.h> |
2052 | + |
2053 | +#include "ProviderInterface.h" |
2054 | +#include <unity/storage/qt/internal/Handler.h> |
2055 | +#include <unity/storage/qt/internal/ItemImpl.h> |
2056 | +#include <unity/storage/qt/internal/VoidJobImpl.h> |
2057 | +#include <unity/storage/qt/ItemJob.h> |
2058 | + |
2059 | +#include <cassert> |
2060 | + |
2061 | +using namespace std; |
2062 | + |
2063 | +namespace unity |
2064 | +{ |
2065 | +namespace storage |
2066 | +{ |
2067 | +namespace qt |
2068 | +{ |
2069 | +namespace internal |
2070 | +{ |
2071 | + |
2072 | +UploaderImpl::UploaderImpl(shared_ptr<ItemImpl> const& item_impl, |
2073 | + QString const& method, |
2074 | + QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply, |
2075 | + std::function<void(storage::internal::ItemMetadata const&)> const& validate, |
2076 | + Item::ConflictPolicy policy, |
2077 | + qint64 size_in_bytes) |
2078 | + : status_(Uploader::Status::Loading) |
2079 | + , method_(method) |
2080 | + , item_impl_(item_impl) |
2081 | + , validate_(validate) |
2082 | + , policy_(policy) |
2083 | + , size_in_bytes_(size_in_bytes) |
2084 | +{ |
2085 | + assert(item_impl); |
2086 | + assert(validate); |
2087 | + assert(!method.isEmpty()); |
2088 | + assert(size_in_bytes >= 0); |
2089 | + |
2090 | + auto process_reply = [this, method](decltype(reply)& r) |
2091 | + { |
2092 | + if (status_ != Uploader::Status::Loading) |
2093 | + { |
2094 | + return; // Don't transition to a final state more than once. |
2095 | + } |
2096 | + |
2097 | + auto runtime = item_impl_->runtime_impl(); |
2098 | + if (!runtime || !runtime->isValid()) |
2099 | + { |
2100 | + QString msg = method + ": Runtime was destroyed previously"; |
2101 | + error_ = StorageErrorImpl::runtime_destroyed_error(msg); |
2102 | + public_instance_->abort(); |
2103 | + public_instance_->setErrorString(msg); |
2104 | + status_ = Uploader::Status::Error; |
2105 | + Q_EMIT public_instance_->statusChanged(status_); |
2106 | + return; |
2107 | + } |
2108 | + |
2109 | + upload_id_ = r.argumentAt<0>(); |
2110 | + fd_ = r.argumentAt<1>(); |
2111 | + if (fd_.fileDescriptor() < 0) |
2112 | + { |
2113 | + // LCOV_EXCL_START |
2114 | + QString msg = method + ": invalid file descriptor returned by provider"; |
2115 | + qCritical().noquote() << msg; |
2116 | + error_ = StorageErrorImpl::local_comms_error(msg); |
2117 | + public_instance_->abort(); |
2118 | + public_instance_->setErrorString(msg); |
2119 | + status_ = Uploader::Status::Error; |
2120 | + Q_EMIT public_instance_->statusChanged(status_); |
2121 | + return; |
2122 | + // LCOV_EXCL_STOP |
2123 | + } |
2124 | + |
2125 | + public_instance_->setSocketDescriptor(fd_.fileDescriptor(), QLocalSocket::ConnectedState, QIODevice::WriteOnly); |
2126 | + status_ = Uploader::Status::Ready; |
2127 | + Q_EMIT public_instance_->statusChanged(status_); |
2128 | + }; |
2129 | + |
2130 | + auto process_error = [this](StorageError const& error) |
2131 | + { |
2132 | + // TODO: This does not set the method |
2133 | + error_ = error; |
2134 | + status_ = Uploader::Status::Error; |
2135 | + public_instance_->abort(); |
2136 | + public_instance_->setErrorString(error.errorString()); |
2137 | + Q_EMIT public_instance_->statusChanged(status_); |
2138 | + }; |
2139 | + |
2140 | + new Handler<storage::internal::ItemMetadata>(this, reply, process_reply, process_error); |
2141 | +} |
2142 | + |
2143 | +UploaderImpl::UploaderImpl(StorageError const& e) |
2144 | + : status_(Uploader::Status::Error) |
2145 | + , error_(e) |
2146 | +{ |
2147 | +} |
2148 | + |
2149 | +UploaderImpl::~UploaderImpl() |
2150 | +{ |
2151 | + switch (status_) |
2152 | + { |
2153 | + case Uploader::Status::Loading: |
2154 | + case Uploader::Status::Finished: |
2155 | + case Uploader::Status::Cancelled: |
2156 | + case Uploader::Status::Error: |
2157 | + break; |
2158 | + case Uploader::Status::Ready: |
2159 | + public_instance_->abort(); |
2160 | + break; |
2161 | + default: |
2162 | + abort(); // Impossible. // LCOV_EXCL_LINE |
2163 | + } |
2164 | +} |
2165 | + |
2166 | +bool UploaderImpl::isValid() const |
2167 | +{ |
2168 | + return status_ != Uploader::Status::Error && status_ != Uploader::Status::Cancelled; |
2169 | +} |
2170 | + |
2171 | +Uploader::Status UploaderImpl::status() const |
2172 | +{ |
2173 | + return status_; |
2174 | +} |
2175 | + |
2176 | +StorageError UploaderImpl::error() const |
2177 | +{ |
2178 | + return error_; |
2179 | +} |
2180 | + |
2181 | +Item::ConflictPolicy UploaderImpl::policy() const |
2182 | +{ |
2183 | + return policy_; |
2184 | +} |
2185 | + |
2186 | +qint64 UploaderImpl::sizeInBytes() const |
2187 | +{ |
2188 | + return size_in_bytes_; |
2189 | +} |
2190 | + |
2191 | +Item UploaderImpl::item() const |
2192 | +{ |
2193 | + if (status_ == Uploader::Status::Error || status_ == Uploader::Status::Cancelled) |
2194 | + { |
2195 | + return Item(); |
2196 | + } |
2197 | + return Item(item_impl_); |
2198 | +} |
2199 | + |
2200 | +void UploaderImpl::finishUpload() |
2201 | +{ |
2202 | + static QString const method = "Uploader::finishUpload()"; |
2203 | + |
2204 | + // If we encountered an error earlier or were cancelled, or if finishUpload() was |
2205 | + // called already, we ignore the call. |
2206 | + if (status_ == Uploader::Status::Error || status_ == Uploader::Status::Cancelled || finalizing_) |
2207 | + { |
2208 | + return; |
2209 | + } |
2210 | + |
2211 | + // Complain if we are asked to finalize while in the Loading or Finished state. |
2212 | + if (status_ != Uploader::Ready) |
2213 | + { |
2214 | + QString msg = method + ": cannot finalize while Uploader is not in the Ready state"; |
2215 | + error_ = StorageErrorImpl::logic_error(msg); |
2216 | + public_instance_->abort(); |
2217 | + public_instance_->setErrorString(msg); |
2218 | + status_ = Uploader::Status::Error; |
2219 | + Q_EMIT public_instance_->statusChanged(status_); |
2220 | + return; |
2221 | + } |
2222 | + |
2223 | + auto runtime = item_impl_->runtime_impl(); |
2224 | + if (!runtime || !runtime->isValid()) |
2225 | + { |
2226 | + QString msg = method + ": Runtime was destroyed previously"; |
2227 | + error_ = StorageErrorImpl::runtime_destroyed_error(msg); |
2228 | + status_ = Uploader::Status::Error; |
2229 | + Q_EMIT public_instance_->statusChanged(status_); |
2230 | + return; |
2231 | + } |
2232 | + |
2233 | + finalizing_ = true; |
2234 | + public_instance_->disconnectFromServer(); |
2235 | + auto reply = item_impl_->account_impl()->provider()->FinishUpload(upload_id_); |
2236 | + |
2237 | + auto process_reply = [this](decltype(reply)& r) |
2238 | + { |
2239 | + if (status_ == Uploader::Status::Cancelled || status_ == Uploader::Status::Error) |
2240 | + { |
2241 | + return; // Don't transition to a final state more than once. |
2242 | + } |
2243 | + |
2244 | + auto runtime = item_impl_->runtime_impl(); |
2245 | + if (!runtime || !runtime->isValid()) |
2246 | + { |
2247 | + QString msg = method + ": Runtime was destroyed previously"; |
2248 | + error_ = StorageErrorImpl::runtime_destroyed_error(msg); |
2249 | + public_instance_->abort(); |
2250 | + public_instance_->setErrorString(msg); |
2251 | + status_ = Uploader::Status::Error; |
2252 | + Q_EMIT public_instance_->statusChanged(status_); |
2253 | + return; |
2254 | + } |
2255 | + |
2256 | + auto metadata = r.value(); |
2257 | + try |
2258 | + { |
2259 | + validate_(metadata); |
2260 | + item_impl_ = make_shared<ItemImpl>(metadata, item_impl_->account_impl()); |
2261 | + status_ = Uploader::Status::Finished; |
2262 | + } |
2263 | + catch (StorageError const& e) |
2264 | + { |
2265 | + // Bad metadata received from provider, validate_() or make_item() have logged it. |
2266 | + // TODO: This does not set the method. |
2267 | + error_ = e; |
2268 | + status_ = Uploader::Status::Error; |
2269 | + } |
2270 | + Q_EMIT public_instance_->statusChanged(status_); |
2271 | + }; |
2272 | + |
2273 | + auto process_error = [this](StorageError const& error) |
2274 | + { |
2275 | + if (status_ != Uploader::Status::Ready) |
2276 | + { |
2277 | + return; // Don't transition to a final state more than once. |
2278 | + } |
2279 | + |
2280 | + // TODO: this doesn't set the method |
2281 | + error_ = error; |
2282 | + public_instance_->abort(); |
2283 | + public_instance_->setErrorString(error.errorString()); |
2284 | + status_ = Uploader::Status::Error; |
2285 | + Q_EMIT public_instance_->statusChanged(status_); |
2286 | + }; |
2287 | + |
2288 | + new Handler<void>(this, reply, process_reply, process_error); |
2289 | +} |
2290 | + |
2291 | +void UploaderImpl::cancel() |
2292 | +{ |
2293 | + static QString const method = "Uploader::cancel()"; |
2294 | + |
2295 | + // If we are in a final state already, ignore the call. |
2296 | + if ( status_ == Uploader::Status::Error |
2297 | + || status_ == Uploader::Status::Finished |
2298 | + || status_ == Uploader::Status::Cancelled) |
2299 | + { |
2300 | + return; |
2301 | + } |
2302 | + auto runtime = item_impl_->runtime_impl(); |
2303 | + if (!runtime || !runtime->isValid()) |
2304 | + { |
2305 | + QString msg = method + ": Runtime was destroyed previously"; |
2306 | + error_ = StorageErrorImpl::runtime_destroyed_error(msg); |
2307 | + status_ = Uploader::Status::Error; |
2308 | + Q_EMIT public_instance_->statusChanged(status_); |
2309 | + return; |
2310 | + } |
2311 | + |
2312 | + if (!upload_id_.isEmpty()) |
2313 | + { |
2314 | + // We just send the cancel and ignore any reply because it is best-effort only. |
2315 | + auto reply = item_impl_->account_impl()->provider()->CancelUpload(upload_id_); |
2316 | + |
2317 | + auto process_reply = [](decltype(reply)&) |
2318 | + { |
2319 | + }; |
2320 | + |
2321 | + auto process_error = [](StorageError const&) |
2322 | + { |
2323 | + }; |
2324 | + |
2325 | + new Handler<void>(this, reply, process_reply, process_error); |
2326 | + } |
2327 | + |
2328 | + QString msg = method + ": upload was cancelled"; |
2329 | + error_ = StorageErrorImpl::cancelled_error(msg); |
2330 | + public_instance_->abort(); |
2331 | + public_instance_->setErrorString(msg); |
2332 | + status_ = Uploader::Status::Cancelled; |
2333 | + Q_EMIT public_instance_->statusChanged(status_); |
2334 | +} |
2335 | + |
2336 | +Uploader* UploaderImpl::make_job(shared_ptr<ItemImpl> const& item_impl, |
2337 | + QString const& method, |
2338 | + QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply, |
2339 | + std::function<void(storage::internal::ItemMetadata const&)> const& validate, |
2340 | + Item::ConflictPolicy policy, |
2341 | + qint64 size_in_bytes) |
2342 | +{ |
2343 | + unique_ptr<UploaderImpl> impl(new UploaderImpl(item_impl, method, reply, validate, policy, size_in_bytes)); |
2344 | + auto uploader = new Uploader(move(impl)); |
2345 | + uploader->p_->public_instance_ = uploader; |
2346 | + return uploader; |
2347 | +} |
2348 | + |
2349 | +Uploader* UploaderImpl::make_job(StorageError const& e) |
2350 | +{ |
2351 | + unique_ptr<UploaderImpl> impl(new UploaderImpl(e)); |
2352 | + auto uploader = new Uploader(move(impl)); |
2353 | + uploader->p_->public_instance_ = uploader; |
2354 | + QMetaObject::invokeMethod(uploader, |
2355 | + "statusChanged", |
2356 | + Qt::QueuedConnection, |
2357 | + Q_ARG(unity::storage::qt::Uploader::Status, uploader->p_->status_)); |
2358 | + return uploader; |
2359 | +} |
2360 | + |
2361 | +} // namespace internal |
2362 | +} // namespace qt |
2363 | +} // namespace storage |
2364 | +} // namespace unity |
2365 | |
2366 | === modified file 'src/qt/internal/VoidJobImpl.cpp' |
2367 | --- src/qt/internal/VoidJobImpl.cpp 2016-09-29 03:17:56 +0000 |
2368 | +++ src/qt/internal/VoidJobImpl.cpp 2016-10-12 08:09:09 +0000 |
2369 | @@ -33,19 +33,19 @@ |
2370 | namespace internal |
2371 | { |
2372 | |
2373 | -VoidJobImpl::VoidJobImpl(shared_ptr<ItemImpl> const& item, |
2374 | +VoidJobImpl::VoidJobImpl(shared_ptr<ItemImpl> const& item_impl, |
2375 | QString const& method, |
2376 | - QDBusPendingReply<void> const& reply) |
2377 | + QDBusPendingReply<void>& reply) |
2378 | : status_(VoidJob::Status::Loading) |
2379 | , method_(method) |
2380 | - , item_(item) |
2381 | + , item_impl_(item_impl) |
2382 | { |
2383 | assert(!method_.isEmpty()); |
2384 | - assert(item); |
2385 | + assert(item_impl); |
2386 | |
2387 | auto process_reply = [this](decltype(reply)&) |
2388 | { |
2389 | - auto runtime = item_->runtime(); |
2390 | + auto runtime = item_impl_->runtime_impl(); |
2391 | if (!runtime || !runtime->isValid()) |
2392 | { |
2393 | error_ = StorageErrorImpl::runtime_destroyed_error(method_ + ": Runtime was destroyed previously"); |
2394 | @@ -91,7 +91,7 @@ |
2395 | |
2396 | VoidJob* VoidJobImpl::make_job(shared_ptr<ItemImpl> const& item, |
2397 | QString const& method, |
2398 | - QDBusPendingReply<void> const& reply) |
2399 | + QDBusPendingReply<void>& reply) |
2400 | { |
2401 | unique_ptr<VoidJobImpl> impl(new VoidJobImpl(item, method, reply)); |
2402 | auto job = new VoidJob(move(impl)); |
2403 | |
2404 | === modified file 'tests/remote-client/MockProvider.cpp' |
2405 | --- tests/remote-client/MockProvider.cpp 2016-10-10 03:55:32 +0000 |
2406 | +++ tests/remote-client/MockProvider.cpp 2016-10-12 08:09:09 +0000 |
2407 | @@ -46,7 +46,7 @@ |
2408 | |
2409 | boost::future<ItemList> MockProvider::roots(Context const&) |
2410 | { |
2411 | - if (cmd_ == "slow_roots") |
2412 | + if (cmd_ == "roots_slow") |
2413 | { |
2414 | this_thread::sleep_for(chrono::seconds(1)); |
2415 | } |
2416 | @@ -258,37 +258,45 @@ |
2417 | return make_ready_future<Item>(metadata); |
2418 | } |
2419 | |
2420 | -string make_job_id() |
2421 | -{ |
2422 | - static int last_job_id = 0; |
2423 | - return to_string(++last_job_id); |
2424 | -} |
2425 | - |
2426 | boost::future<unique_ptr<UploadJob>> MockProvider::create_file( |
2427 | string const&, string const&, |
2428 | int64_t, string const&, bool, Context const&) |
2429 | { |
2430 | - return make_ready_future<unique_ptr<UploadJob>>(new MockUploadJob(make_job_id())); |
2431 | + return make_ready_future<unique_ptr<UploadJob>>(new MockUploadJob()); |
2432 | } |
2433 | |
2434 | boost::future<unique_ptr<UploadJob>> MockProvider::update( |
2435 | string const&, int64_t, string const&, Context const&) |
2436 | { |
2437 | - return make_ready_future<unique_ptr<UploadJob>>(new MockUploadJob(make_job_id())); |
2438 | + return make_ready_future<unique_ptr<UploadJob>>(new MockUploadJob()); |
2439 | } |
2440 | |
2441 | boost::future<unique_ptr<DownloadJob>> MockProvider::download( |
2442 | string const&, Context const&) |
2443 | { |
2444 | - unique_ptr<DownloadJob> job(new MockDownloadJob(make_job_id())); |
2445 | + if (cmd_ == "download_slow") |
2446 | + { |
2447 | + this_thread::sleep_for(chrono::seconds(1)); |
2448 | + } |
2449 | + if (cmd_ == "download_error") |
2450 | + { |
2451 | + unique_ptr<DownloadJob> job(new MockDownloadJob()); |
2452 | + ResourceException e("test error", 42); |
2453 | + job->report_error(make_exception_ptr(e)); |
2454 | + return make_exceptional_future<unique_ptr<DownloadJob>>(e); |
2455 | + } |
2456 | + unique_ptr<DownloadJob> job(new MockDownloadJob(cmd_)); |
2457 | const char contents[] = "Hello world"; |
2458 | - if (write(job->write_socket(), contents, sizeof(contents)) != sizeof(contents)) |
2459 | + if (write(job->write_socket(), contents, strlen(contents)) != int(strlen(contents))) |
2460 | { |
2461 | ResourceException e("download(): write failed", errno); |
2462 | job->report_error(make_exception_ptr(e)); |
2463 | return make_exceptional_future<unique_ptr<DownloadJob>>(e); |
2464 | } |
2465 | - job->report_complete(); |
2466 | + if (cmd_ != "finish_download_error" && cmd_ != "finish_download_slow_error") |
2467 | + { |
2468 | + job->report_complete(); |
2469 | + } |
2470 | return make_ready_future(std::move(job)); |
2471 | } |
2472 | |
2473 | @@ -402,5 +410,13 @@ |
2474 | |
2475 | boost::future<void> MockDownloadJob::finish() |
2476 | { |
2477 | + if (cmd_ == "finish_download_slow" || cmd_ == "finish_download_slow_error") |
2478 | + { |
2479 | + this_thread::sleep_for(chrono::seconds(1)); |
2480 | + } |
2481 | + if (cmd_ == "finish_download_error" || cmd_ == "finish_download_slow_error") |
2482 | + { |
2483 | + return make_exceptional_future<void>(NotExistsException("no such item", "item_id")); |
2484 | + } |
2485 | return make_ready_future(); |
2486 | } |
2487 | |
2488 | === modified file 'tests/remote-client/remote-client_test.cpp' |
2489 | --- tests/remote-client/remote-client_test.cpp 2016-10-10 23:31:31 +0000 |
2490 | +++ tests/remote-client/remote-client_test.cpp 2016-10-12 08:09:09 +0000 |
2491 | @@ -54,10 +54,13 @@ |
2492 | Account acc_; |
2493 | }; |
2494 | |
2495 | +class RuntimeTest : public ProviderFixture {}; |
2496 | + |
2497 | class AccountTest : public RemoteClientTest {}; |
2498 | class CopyTest : public RemoteClientTest {}; |
2499 | class CreateFolderTest : public RemoteClientTest {}; |
2500 | class DeleteTest : public RemoteClientTest {}; |
2501 | +class DownloadTest : public RemoteClientTest {}; |
2502 | class GetTest : public RemoteClientTest {}; |
2503 | class ItemTest : public RemoteClientTest {}; |
2504 | class ListTest : public RemoteClientTest {}; |
2505 | @@ -65,7 +68,7 @@ |
2506 | class MoveTest : public RemoteClientTest {}; |
2507 | class ParentsTest : public RemoteClientTest {}; |
2508 | class RootsTest : public RemoteClientTest {}; |
2509 | -class RuntimeTest : public ProviderFixture {}; |
2510 | +class UploadTest : public RemoteClientTest {}; |
2511 | |
2512 | TEST(Runtime, lifecycle) |
2513 | { |
2514 | @@ -428,7 +431,7 @@ |
2515 | |
2516 | TEST_F(RootsTest, runtime_destroyed_while_item_list_job_running) |
2517 | { |
2518 | - set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("slow_roots"))); |
2519 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("roots_slow"))); |
2520 | |
2521 | unique_ptr<ItemListJob> j(acc_.roots()); |
2522 | EXPECT_TRUE(j->isValid()); |
2523 | @@ -767,7 +770,7 @@ |
2524 | auto arg = spy.takeFirst(); |
2525 | EXPECT_EQ(VoidJob::Status::Error, qvariant_cast<VoidJob::Status>(arg.at(0))); |
2526 | |
2527 | - EXPECT_EQ("Item::deleteItem(): Runtime was destroyed previously", j->error().message()) << j->error().message().toStdString(); |
2528 | + EXPECT_EQ("Item::deleteItem(): Runtime was destroyed previously", j->error().message()); |
2529 | } |
2530 | |
2531 | TEST_F(DeleteTest, invalid_item) |
2532 | @@ -1555,7 +1558,7 @@ |
2533 | EXPECT_FALSE(j->isValid()); |
2534 | EXPECT_EQ(ItemJob::Status::Error, j->status()); |
2535 | EXPECT_EQ(StorageError::Type::LogicError, j->error().type()); |
2536 | - EXPECT_EQ("LogicError: Item::copy(): newParent cannot be a file", j->error().errorString()) << j->error().errorString().toStdString(); |
2537 | + EXPECT_EQ("LogicError: Item::copy(): newParent cannot be a file", j->error().errorString()); |
2538 | |
2539 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2540 | spy.wait(SIGNAL_WAIT_TIME); |
2541 | @@ -2234,6 +2237,590 @@ |
2542 | EXPECT_EQ(StorageError::Type::PermissionDenied, j->error().type()); |
2543 | } |
2544 | |
2545 | +// TODO: This leaks: |
2546 | +// ==4645== 1,369 (272 direct, 1,097 indirect) bytes in 1 blocks are definitely lost in loss record 193 of 203 |
2547 | +// ==4645== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) |
2548 | +// ==4645== by 0x4FD9D0A: boost::promise<void>::promise() (future.hpp:2309) |
2549 | +// ==4645== by 0x4FDA6F2: boost::make_ready_future() (future.hpp:3935) |
2550 | +// ==4645== by 0x4FD96B0: unity::storage::provider::internal::DownloadJobImpl::cancel(unity::storage::provider::DownloadJob&) (DownloadJobImpl.cpp:161) |
2551 | +// ==4645== by 0x4FEE198: void unity::storage::provider::internal::PendingJobs::cancel_job<unity::storage::provider::DownloadJob>(std::shared_ptr<unity::storage::provider::DownloadJob> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (PendingJobs.cpp:181) |
2552 | +// ==4645== by 0x4FEA3BF: unity::storage::provider::internal::PendingJobs::~PendingJobs() (PendingJobs.cpp:55) |
2553 | +// ==4645== by 0x4FEA6CD: unity::storage::provider::internal::PendingJobs::~PendingJobs() (PendingJobs.cpp:61) |
2554 | +// ==4645== by 0x4F8E927: std::default_delete<unity::storage::provider::internal::PendingJobs>::operator()(unity::storage::provider::internal::PendingJobs*) const (unique_ptr.h:76) |
2555 | +// ==4645== by 0x4F8D85B: std::unique_ptr<unity::storage::provider::internal::PendingJobs, std::default_delete<unity::storage::provider::internal::PendingJobs> >::~unique_ptr() (unique_ptr.h:236) |
2556 | +// ==4645== by 0x4F89449: unity::storage::provider::internal::AccountData::~AccountData() (AccountData.h:51) |
2557 | +// ==4645== by 0x504D9A6: void __gnu_cxx::new_allocator<unity::storage::provider::internal::AccountData>::destroy<unity::storage::provider::internal::AccountData>(unity::storage::provider::internal::AccountData*) (new_allocator.h:124) |
2558 | +// ==4645== by 0x504D8AA: void std::allocator_traits<std::allocator<unity::storage::provider::internal::AccountData> >::destroy<unity::storage::provider::internal::AccountData>(std::allocator<unity::storage::provider::internal::AccountData>&, unity::storage::provider::internal::AccountData*) (alloc_traits.h:542) |
2559 | + |
2560 | +TEST_F(DownloadTest, memory_leak) |
2561 | +{ |
2562 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); |
2563 | + |
2564 | + Item root; |
2565 | + { |
2566 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2567 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2568 | + spy.wait(SIGNAL_WAIT_TIME); |
2569 | + root = j->item(); |
2570 | + } |
2571 | + |
2572 | + Item child; |
2573 | + { |
2574 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2575 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2576 | + spy.wait(SIGNAL_WAIT_TIME); |
2577 | + child = j->item(); |
2578 | + } |
2579 | + |
2580 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2581 | + EXPECT_TRUE(downloader->isValid()); |
2582 | + EXPECT_EQ(Downloader::Status::Loading, downloader->status()); |
2583 | + EXPECT_EQ(StorageError::NoError, downloader->error().type()); |
2584 | + EXPECT_EQ(child, downloader->item()); |
2585 | + |
2586 | + { |
2587 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2588 | + spy.wait(SIGNAL_WAIT_TIME); |
2589 | + auto arg = spy.takeFirst(); |
2590 | + EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0))); |
2591 | + } |
2592 | +} |
2593 | + |
2594 | +TEST_F(DownloadTest, basic) |
2595 | +{ |
2596 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); |
2597 | + |
2598 | + Item root; |
2599 | + { |
2600 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2601 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2602 | + spy.wait(SIGNAL_WAIT_TIME); |
2603 | + root = j->item(); |
2604 | + } |
2605 | + |
2606 | + Item child; |
2607 | + { |
2608 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2609 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2610 | + spy.wait(SIGNAL_WAIT_TIME); |
2611 | + child = j->item(); |
2612 | + } |
2613 | + |
2614 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2615 | + EXPECT_TRUE(downloader->isValid()); |
2616 | + EXPECT_EQ(Downloader::Status::Loading, downloader->status()); |
2617 | + EXPECT_EQ(StorageError::NoError, downloader->error().type()); |
2618 | + EXPECT_EQ(child, downloader->item()); |
2619 | + |
2620 | + QSignalSpy status_spy(downloader.get(), &Downloader::statusChanged); |
2621 | + { |
2622 | + QSignalSpy read_spy(downloader.get(), &Downloader::readyRead); |
2623 | + ASSERT_TRUE(status_spy.wait(SIGNAL_WAIT_TIME)); |
2624 | + auto arg = status_spy.takeFirst(); |
2625 | + EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0))); |
2626 | + |
2627 | + if (read_spy.count() != 1) |
2628 | + { |
2629 | + read_spy.wait(SIGNAL_WAIT_TIME); |
2630 | + } |
2631 | + } |
2632 | + auto data = downloader->readAll(); |
2633 | + EXPECT_EQ(QByteArray("Hello world", -1), data); |
2634 | + |
2635 | + downloader->finishDownload(); |
2636 | + ASSERT_TRUE(status_spy.wait(SIGNAL_WAIT_TIME)); |
2637 | + auto arg = status_spy.takeFirst(); |
2638 | + EXPECT_EQ(Downloader::Status::Finished, qvariant_cast<Downloader::Status>(arg.at(0))); |
2639 | +} |
2640 | + |
2641 | +TEST_F(DownloadTest, runtime_destroyed) |
2642 | +{ |
2643 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); |
2644 | + |
2645 | + Item root; |
2646 | + { |
2647 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2648 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2649 | + spy.wait(SIGNAL_WAIT_TIME); |
2650 | + root = j->item(); |
2651 | + } |
2652 | + |
2653 | + Item child; |
2654 | + { |
2655 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2656 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2657 | + spy.wait(SIGNAL_WAIT_TIME); |
2658 | + child = j->item(); |
2659 | + } |
2660 | + |
2661 | + EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); |
2662 | + |
2663 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2664 | + EXPECT_FALSE(downloader->isValid()); |
2665 | + EXPECT_EQ(Downloader::Status::Error, downloader->status()); |
2666 | + EXPECT_EQ(StorageError::RuntimeDestroyed, downloader->error().type()); |
2667 | + EXPECT_EQ("RuntimeDestroyed: Item::createDownloader(): Runtime was destroyed previously", |
2668 | + downloader->error().errorString()); |
2669 | + EXPECT_EQ(Item(), downloader->item()); |
2670 | + |
2671 | + // Signal must arrive. |
2672 | + { |
2673 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2674 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2675 | + auto arg = spy.takeFirst(); |
2676 | + EXPECT_EQ(Downloader::Status::Error, qvariant_cast<Downloader::Status>(arg.at(0))); |
2677 | + } |
2678 | +} |
2679 | + |
2680 | +TEST_F(DownloadTest, runtime_destroyed_while_download_running) |
2681 | +{ |
2682 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("download_slow"))); |
2683 | + |
2684 | + Item root; |
2685 | + { |
2686 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2687 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2688 | + spy.wait(SIGNAL_WAIT_TIME); |
2689 | + root = j->item(); |
2690 | + } |
2691 | + |
2692 | + Item child; |
2693 | + { |
2694 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2695 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2696 | + spy.wait(SIGNAL_WAIT_TIME); |
2697 | + child = j->item(); |
2698 | + } |
2699 | + |
2700 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2701 | + EXPECT_TRUE(downloader->isValid()); |
2702 | + |
2703 | + EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime, provider still sleeping |
2704 | + |
2705 | + // Signal must arrive. |
2706 | + { |
2707 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2708 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2709 | + auto arg = spy.takeFirst(); |
2710 | + EXPECT_EQ(Downloader::Status::Error, qvariant_cast<Downloader::Status>(arg.at(0))); |
2711 | + } |
2712 | + |
2713 | + EXPECT_FALSE(downloader->isValid()); |
2714 | + EXPECT_EQ(Downloader::Status::Error, downloader->status()); |
2715 | + EXPECT_EQ(StorageError::RuntimeDestroyed, downloader->error().type()); |
2716 | + EXPECT_EQ("RuntimeDestroyed: Item::createDownloader(): Runtime was destroyed previously", |
2717 | + downloader->error().errorString()); |
2718 | + EXPECT_EQ(Item(), downloader->item()); |
2719 | +} |
2720 | + |
2721 | +TEST_F(DownloadTest, download_error) |
2722 | +{ |
2723 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("download_error"))); |
2724 | + |
2725 | + Item root; |
2726 | + { |
2727 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2728 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2729 | + spy.wait(SIGNAL_WAIT_TIME); |
2730 | + root = j->item(); |
2731 | + } |
2732 | + |
2733 | + Item child; |
2734 | + { |
2735 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2736 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2737 | + spy.wait(SIGNAL_WAIT_TIME); |
2738 | + child = j->item(); |
2739 | + } |
2740 | + |
2741 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2742 | + EXPECT_TRUE(downloader->isValid()); |
2743 | + |
2744 | + // Signal must arrive. |
2745 | + { |
2746 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2747 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2748 | + auto arg = spy.takeFirst(); |
2749 | + EXPECT_EQ(Downloader::Status::Error, qvariant_cast<Downloader::Status>(arg.at(0))); |
2750 | + } |
2751 | + |
2752 | + EXPECT_FALSE(downloader->isValid()); |
2753 | + EXPECT_EQ(Downloader::Status::Error, downloader->status()); |
2754 | + EXPECT_EQ(StorageError::ResourceError, downloader->error().type()); |
2755 | + EXPECT_EQ("ResourceError: test error", downloader->error().errorString()); |
2756 | + EXPECT_EQ(42, downloader->error().errorCode()); |
2757 | + EXPECT_EQ(Item(), downloader->item()); |
2758 | + |
2759 | + // For coverage: call finishDownload() while in the Error state. |
2760 | + { |
2761 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2762 | + downloader->finishDownload(); |
2763 | + EXPECT_FALSE(spy.wait(1000)); |
2764 | + } |
2765 | +} |
2766 | + |
2767 | +TEST_F(DownloadTest, finish_too_soon) |
2768 | +{ |
2769 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); |
2770 | + |
2771 | + Item root; |
2772 | + { |
2773 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2774 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2775 | + spy.wait(SIGNAL_WAIT_TIME); |
2776 | + root = j->item(); |
2777 | + } |
2778 | + |
2779 | + Item child; |
2780 | + { |
2781 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2782 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2783 | + spy.wait(SIGNAL_WAIT_TIME); |
2784 | + child = j->item(); |
2785 | + } |
2786 | + |
2787 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2788 | + EXPECT_TRUE(downloader->isValid()); |
2789 | + |
2790 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2791 | + |
2792 | + downloader->finishDownload(); |
2793 | + |
2794 | + ASSERT_EQ(1, spy.count()); |
2795 | + auto arg = spy.takeFirst(); |
2796 | + EXPECT_EQ(Downloader::Status::Error, qvariant_cast<Downloader::Status>(arg.at(0))); |
2797 | + |
2798 | + EXPECT_FALSE(downloader->isValid()); |
2799 | + EXPECT_EQ(Downloader::Status::Error, downloader->status()); |
2800 | + EXPECT_EQ(StorageError::LogicError, downloader->error().type()); |
2801 | + EXPECT_EQ("LogicError: Downloader::finishDownload(): cannot finalize while Downloader is not in the Ready state", |
2802 | + downloader->error().errorString()); |
2803 | +} |
2804 | + |
2805 | +TEST_F(DownloadTest, finish_runtime_destroyed) |
2806 | +{ |
2807 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); |
2808 | + |
2809 | + Item root; |
2810 | + { |
2811 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2812 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2813 | + spy.wait(SIGNAL_WAIT_TIME); |
2814 | + root = j->item(); |
2815 | + } |
2816 | + |
2817 | + Item child; |
2818 | + { |
2819 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2820 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2821 | + spy.wait(SIGNAL_WAIT_TIME); |
2822 | + child = j->item(); |
2823 | + } |
2824 | + |
2825 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2826 | + EXPECT_TRUE(downloader->isValid()); |
2827 | + |
2828 | + { |
2829 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2830 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2831 | + auto arg = spy.takeFirst(); |
2832 | + EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0))); |
2833 | + } |
2834 | + |
2835 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2836 | + |
2837 | + EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime |
2838 | + |
2839 | + downloader->finishDownload(); |
2840 | + |
2841 | + ASSERT_EQ(1, spy.count()); |
2842 | + auto arg = spy.takeFirst(); |
2843 | + EXPECT_EQ(Downloader::Status::Error, qvariant_cast<Downloader::Status>(arg.at(0))); |
2844 | + |
2845 | + EXPECT_FALSE(downloader->isValid()); |
2846 | + EXPECT_EQ(Downloader::Status::Error, downloader->status()); |
2847 | + EXPECT_EQ(StorageError::RuntimeDestroyed, downloader->error().type()); |
2848 | + EXPECT_EQ("Downloader::finishDownload(): Runtime was destroyed previously", downloader->error().message()); |
2849 | +} |
2850 | + |
2851 | +TEST_F(DownloadTest, finish_runtime_destroyed_while_reply_outstanding) |
2852 | +{ |
2853 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow"))); |
2854 | + |
2855 | + Item root; |
2856 | + { |
2857 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2858 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2859 | + spy.wait(SIGNAL_WAIT_TIME); |
2860 | + root = j->item(); |
2861 | + } |
2862 | + |
2863 | + Item child; |
2864 | + { |
2865 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2866 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2867 | + spy.wait(SIGNAL_WAIT_TIME); |
2868 | + child = j->item(); |
2869 | + } |
2870 | + |
2871 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2872 | + EXPECT_TRUE(downloader->isValid()); |
2873 | + |
2874 | + { |
2875 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2876 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2877 | + auto arg = spy.takeFirst(); |
2878 | + EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0))); |
2879 | + } |
2880 | + |
2881 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2882 | + |
2883 | + downloader->finishDownload(); |
2884 | + |
2885 | + EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime, provider still sleeping |
2886 | + |
2887 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2888 | + auto arg = spy.takeFirst(); |
2889 | + EXPECT_EQ(Downloader::Status::Error, qvariant_cast<Downloader::Status>(arg.at(0))); |
2890 | + |
2891 | + EXPECT_FALSE(downloader->isValid()); |
2892 | + EXPECT_EQ(Downloader::Status::Error, downloader->status()); |
2893 | + EXPECT_EQ(StorageError::RuntimeDestroyed, downloader->error().type()); |
2894 | + EXPECT_EQ("Downloader::finishDownload(): Runtime was destroyed previously", downloader->error().message()); |
2895 | +} |
2896 | + |
2897 | +TEST_F(DownloadTest, finish_twice) |
2898 | +{ |
2899 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); |
2900 | + |
2901 | + Item root; |
2902 | + { |
2903 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2904 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2905 | + spy.wait(SIGNAL_WAIT_TIME); |
2906 | + root = j->item(); |
2907 | + } |
2908 | + |
2909 | + Item child; |
2910 | + { |
2911 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2912 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2913 | + spy.wait(SIGNAL_WAIT_TIME); |
2914 | + child = j->item(); |
2915 | + } |
2916 | + |
2917 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2918 | + EXPECT_TRUE(downloader->isValid()); |
2919 | + |
2920 | + { |
2921 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2922 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2923 | + auto arg = spy.takeFirst(); |
2924 | + EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0))); |
2925 | + } |
2926 | + |
2927 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2928 | + |
2929 | + downloader->finishDownload(); |
2930 | + downloader->finishDownload(); |
2931 | + |
2932 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2933 | + auto arg = spy.takeFirst(); |
2934 | + EXPECT_EQ(Downloader::Status::Finished, qvariant_cast<Downloader::Status>(arg.at(0))); |
2935 | +} |
2936 | + |
2937 | +TEST_F(DownloadTest, finish_error) |
2938 | +{ |
2939 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_error"))); |
2940 | + |
2941 | + Item root; |
2942 | + { |
2943 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2944 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2945 | + spy.wait(SIGNAL_WAIT_TIME); |
2946 | + root = j->item(); |
2947 | + } |
2948 | + |
2949 | + Item child; |
2950 | + { |
2951 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2952 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2953 | + spy.wait(SIGNAL_WAIT_TIME); |
2954 | + child = j->item(); |
2955 | + } |
2956 | + |
2957 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
2958 | + EXPECT_TRUE(downloader->isValid()); |
2959 | + |
2960 | + { |
2961 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2962 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2963 | + auto arg = spy.takeFirst(); |
2964 | + EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0))); |
2965 | + } |
2966 | + |
2967 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
2968 | + |
2969 | + downloader->finishDownload(); |
2970 | + |
2971 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
2972 | + auto arg = spy.takeFirst(); |
2973 | + EXPECT_EQ(Downloader::Status::Error, qvariant_cast<Downloader::Status>(arg.at(0))); |
2974 | + |
2975 | + EXPECT_FALSE(downloader->isValid()); |
2976 | + EXPECT_EQ(Downloader::Status::Error, downloader->status()); |
2977 | + EXPECT_EQ(StorageError::NotExists, downloader->error().type()); |
2978 | + EXPECT_EQ("no such item", downloader->error().message()); |
2979 | + EXPECT_EQ("item_id", downloader->error().itemId()); |
2980 | + EXPECT_EQ("item_id", downloader->error().itemName()); |
2981 | + EXPECT_EQ("NotExists", downloader->error().name()); |
2982 | +} |
2983 | + |
2984 | +TEST_F(DownloadTest, cancel) |
2985 | +{ |
2986 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow_error"))); |
2987 | + |
2988 | + Item root; |
2989 | + { |
2990 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
2991 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
2992 | + spy.wait(SIGNAL_WAIT_TIME); |
2993 | + root = j->item(); |
2994 | + } |
2995 | + |
2996 | + Item child; |
2997 | + { |
2998 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
2999 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
3000 | + spy.wait(SIGNAL_WAIT_TIME); |
3001 | + child = j->item(); |
3002 | + } |
3003 | + |
3004 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
3005 | + EXPECT_TRUE(downloader->isValid()); |
3006 | + |
3007 | + { |
3008 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
3009 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
3010 | + auto arg = spy.takeFirst(); |
3011 | + EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0))); |
3012 | + } |
3013 | + |
3014 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
3015 | + |
3016 | + downloader->finishDownload(); |
3017 | + |
3018 | + downloader->cancel(); |
3019 | + downloader->cancel(); // Second time for coverage |
3020 | + |
3021 | + downloader->finishDownload(); // Second time for coverage |
3022 | + |
3023 | + EXPECT_EQ(1, spy.count()); |
3024 | + auto arg = spy.takeFirst(); |
3025 | + EXPECT_EQ(Downloader::Status::Cancelled, qvariant_cast<Downloader::Status>(arg.at(0))); |
3026 | + |
3027 | + EXPECT_EQ(Downloader::Status::Cancelled, downloader->status()); |
3028 | + EXPECT_EQ(StorageError::Type::Cancelled, downloader->error().type()); |
3029 | + EXPECT_EQ("Downloader::cancel(): download was cancelled", downloader->error().message()); |
3030 | + |
3031 | + // We wait here to get coverage for when the reply to a finishDownload() call |
3032 | + // finds the downloader in a final state. |
3033 | + EXPECT_FALSE(spy.wait(2000)); |
3034 | +} |
3035 | + |
3036 | +TEST_F(DownloadTest, cancel_runtime_destroyed) |
3037 | +{ |
3038 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow_error"))); |
3039 | + |
3040 | + Item root; |
3041 | + { |
3042 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
3043 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
3044 | + spy.wait(SIGNAL_WAIT_TIME); |
3045 | + root = j->item(); |
3046 | + } |
3047 | + |
3048 | + Item child; |
3049 | + { |
3050 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
3051 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
3052 | + spy.wait(SIGNAL_WAIT_TIME); |
3053 | + child = j->item(); |
3054 | + } |
3055 | + |
3056 | + unique_ptr<Downloader> downloader(child.createDownloader()); |
3057 | + EXPECT_TRUE(downloader->isValid()); |
3058 | + |
3059 | + { |
3060 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
3061 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
3062 | + auto arg = spy.takeFirst(); |
3063 | + EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0))); |
3064 | + } |
3065 | + |
3066 | + QSignalSpy spy(downloader.get(), &Downloader::statusChanged); |
3067 | + |
3068 | + EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime |
3069 | + |
3070 | + downloader->cancel(); |
3071 | + |
3072 | + if (spy.count() == 0) |
3073 | + { |
3074 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
3075 | + } |
3076 | + auto arg = spy.takeFirst(); |
3077 | + EXPECT_EQ(Downloader::Status::Error, qvariant_cast<Downloader::Status>(arg.at(0))); |
3078 | + |
3079 | + EXPECT_EQ(Downloader::Status::Error, downloader->status()); |
3080 | + EXPECT_EQ(StorageError::Type::RuntimeDestroyed, downloader->error().type()); |
3081 | + EXPECT_EQ("Downloader::cancel(): Runtime was destroyed previously", downloader->error().message()); |
3082 | +} |
3083 | + |
3084 | +TEST_F(UploadTest, basic) |
3085 | +{ |
3086 | + set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); |
3087 | + |
3088 | + Item root; |
3089 | + { |
3090 | + unique_ptr<ItemJob> j(acc_.get("root_id")); |
3091 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
3092 | + spy.wait(SIGNAL_WAIT_TIME); |
3093 | + root = j->item(); |
3094 | + } |
3095 | + |
3096 | + Item child; |
3097 | + { |
3098 | + unique_ptr<ItemJob> j(acc_.get("child_id")); |
3099 | + QSignalSpy spy(j.get(), &ItemJob::statusChanged); |
3100 | + spy.wait(SIGNAL_WAIT_TIME); |
3101 | + child = j->item(); |
3102 | + } |
3103 | + |
3104 | + QByteArray contents("Hello world", -1); |
3105 | + unique_ptr<Uploader> uploader(child.createUploader(Item::ConflictPolicy::Overwrite, contents.size())); |
3106 | + EXPECT_TRUE(uploader->isValid()); |
3107 | + EXPECT_EQ(Uploader::Status::Loading, uploader->status()); |
3108 | + EXPECT_EQ(StorageError::NoError, uploader->error().type()); |
3109 | + EXPECT_EQ(child, uploader->item()); |
3110 | + |
3111 | + { |
3112 | + QSignalSpy spy(uploader.get(), &Uploader::statusChanged); |
3113 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
3114 | + auto arg = spy.takeFirst(); |
3115 | + EXPECT_EQ(Uploader::Status::Ready, qvariant_cast<Uploader::Status>(arg.at(0))); |
3116 | + } |
3117 | + |
3118 | + EXPECT_EQ(contents.size(), uploader->write(contents)); |
3119 | + |
3120 | + QSignalSpy spy(uploader.get(), &Uploader::statusChanged); |
3121 | + uploader->finishUpload(); |
3122 | + ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME)); |
3123 | + auto arg = spy.takeFirst(); |
3124 | + EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0))); |
3125 | + |
3126 | + EXPECT_EQ(Uploader::Status::Finished, uploader->status()); |
3127 | +} |
3128 | + |
3129 | int main(int argc, char** argv) |
3130 | { |
3131 | QCoreApplication app(argc, argv); |
FAILED: Continuous integration, rev:99 /jenkins. canonical. com/unity- api-1/job/ lp-storage- framework- ci/147/ /jenkins. canonical. com/unity- api-1/job/ build/868/ console /jenkins. canonical. com/unity- api-1/job/ build-0- fetch/875 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 681/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 681/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= yakkety/ 681/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 681/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 681/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= yakkety/ 681/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 681/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 681/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= yakkety/ 681/console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: 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-storage- framework- ci/147/ rebuild
https:/