Merge lp:~michihenning/storage-framework/parents into lp:storage-framework/devel
- parents
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Michi Henning |
Approved revision: | 92 |
Merged at revision: | 74 |
Proposed branch: | lp:~michihenning/storage-framework/parents |
Merge into: | lp:storage-framework/devel |
Prerequisite: | lp:~michihenning/storage-framework/more-tests |
Diff against target: |
1841 lines (+1086/-153) 26 files modified
include/unity/storage/internal/ItemMetadata.h (+1/-3) include/unity/storage/qt/Item.h (+2/-2) include/unity/storage/qt/ItemListJob.h (+8/-4) include/unity/storage/qt/internal/Handler.h (+3/-2) include/unity/storage/qt/internal/ItemImpl.h (+1/-2) include/unity/storage/qt/internal/ItemJobImpl.h (+5/-5) include/unity/storage/qt/internal/ItemListJobImpl.h (+8/-20) include/unity/storage/qt/internal/ListJobImplBase.h (+76/-0) include/unity/storage/qt/internal/MultiItemJobImpl.h (+68/-0) include/unity/storage/qt/internal/StorageErrorImpl.h (+2/-0) include/unity/storage/qt/internal/VoidJobImpl.h (+4/-4) src/qt/CMakeLists.txt (+4/-0) src/qt/Item.cpp (+2/-9) src/qt/ItemListJob.cpp (+2/-1) src/qt/client/internal/remote_client/ItemImpl.cpp (+8/-1) src/qt/internal/AccountImpl.cpp (+14/-4) src/qt/internal/ItemImpl.cpp (+55/-8) src/qt/internal/ItemJobImpl.cpp (+5/-5) src/qt/internal/ItemListJobImpl.cpp (+9/-45) src/qt/internal/ListJobImplBase.cpp (+111/-0) src/qt/internal/MultiItemJobImpl.cpp (+135/-0) src/qt/internal/StorageErrorImpl.cpp (+37/-24) src/qt/internal/VoidJobImpl.cpp (+4/-4) tests/provider-ProviderInterface/ProviderInterface_test.cpp (+7/-7) tests/remote-client/MockProvider.cpp (+43/-2) tests/remote-client/remote-client_test.cpp (+472/-1) |
To merge this branch: | bzr merge lp:~michihenning/storage-framework/parents |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
unity-api-1-bot | continuous-integration | Approve | |
James Henstridge | Approve | ||
Review via email:
|
Commit message
Changed ItemMetadata for parent_ids to QList (from QVector).
Added parents() implementation.
Refactored ItemListJobImpl and MultiItemJobImpl to use a base class that does most of the work, so we can create an ItemListJob from both a single invocation that returns a list, and from multiple invocations that return a single item each.
Minor renaming of the make_* factory methods for brevity.
A few minor bug fixes here and there.
Lots more tests.
Description of the change
Changed ItemMetadata for parent_ids to QList (from QVector).
Added parents() implementation.
Refactored ItemListJobImpl and MultiItemJobImpl to use a base class that does most of the work, so we can create an ItemListJob from both a single invocation that returns a list, and from multiple invocations that return a single item each.
Minor renaming of the make_* factory methods for brevity.
A few minor bug fixes here and there.
Lots more tests.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:91
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)
James Henstridge (jamesh) wrote : | # |
This looks good. I've left a few minor comments that are mostly stylistic in nature rather than issues with the branch. So I'm approving the branch but will leave it up to you to top-approve when you're ready.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michi Henning (michihenning) wrote : | # |
Thanks for the review! I've commented in-line.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michi Henning (michihenning) wrote : | # |
Thanks for the review! I've commented in-line.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:92
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 : | # |
FAILED: Autolanding.
Unapproved changes made after approval.
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:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
unity-api-1-bot (unity-api-1-bot) : | # |
Preview Diff
1 | === modified file 'include/unity/storage/internal/ItemMetadata.h' | |||
2 | --- include/unity/storage/internal/ItemMetadata.h 2016-09-16 06:25:08 +0000 | |||
3 | +++ include/unity/storage/internal/ItemMetadata.h 2016-10-10 01:18:55 +0000 | |||
4 | @@ -24,9 +24,7 @@ | |||
5 | 24 | #pragma GCC diagnostic ignored "-Wcast-align" | 24 | #pragma GCC diagnostic ignored "-Wcast-align" |
6 | 25 | #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" | 25 | #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" |
7 | 26 | #pragma GCC diagnostic ignored "-Wswitch-default" | 26 | #pragma GCC diagnostic ignored "-Wswitch-default" |
8 | 27 | #include <QMap> | ||
9 | 28 | #include <QVariant> | 27 | #include <QVariant> |
10 | 29 | #include <QVector> | ||
11 | 30 | #pragma GCC diagnostic pop | 28 | #pragma GCC diagnostic pop |
12 | 31 | 29 | ||
13 | 32 | namespace unity | 30 | namespace unity |
14 | @@ -39,7 +37,7 @@ | |||
15 | 39 | struct ItemMetadata | 37 | struct ItemMetadata |
16 | 40 | { | 38 | { |
17 | 41 | QString item_id; | 39 | QString item_id; |
19 | 42 | QVector<QString> parent_ids; | 40 | QList<QString> parent_ids; |
20 | 43 | QString name; | 41 | QString name; |
21 | 44 | QString etag; | 42 | QString etag; |
22 | 45 | ItemType type; | 43 | ItemType type; |
23 | 46 | 44 | ||
24 | === modified file 'include/unity/storage/qt/Item.h' | |||
25 | --- include/unity/storage/qt/Item.h 2016-09-26 08:57:05 +0000 | |||
26 | +++ include/unity/storage/qt/Item.h 2016-10-10 01:18:55 +0000 | |||
27 | @@ -60,7 +60,7 @@ | |||
28 | 60 | Q_PROPERTY(unity::storage::qt::Item::Type type READ type FINAL) | 60 | Q_PROPERTY(unity::storage::qt::Item::Type type READ type FINAL) |
29 | 61 | Q_PROPERTY(QVariantMap metadata READ metadata FINAL) | 61 | Q_PROPERTY(QVariantMap metadata READ metadata FINAL) |
30 | 62 | Q_PROPERTY(QDateTime lastModifiedTime READ lastModifiedTime FINAL) | 62 | Q_PROPERTY(QDateTime lastModifiedTime READ lastModifiedTime FINAL) |
32 | 63 | Q_PROPERTY(QVector<QString> parentIds READ parentIds FINAL) | 63 | Q_PROPERTY(QList<QString> parentIds READ parentIds FINAL) |
33 | 64 | 64 | ||
34 | 65 | public: | 65 | public: |
35 | 66 | Item(); | 66 | Item(); |
36 | @@ -93,7 +93,7 @@ | |||
37 | 93 | Type type() const; | 93 | Type type() const; |
38 | 94 | QVariantMap metadata() const; | 94 | QVariantMap metadata() const; |
39 | 95 | QDateTime lastModifiedTime() const; | 95 | QDateTime lastModifiedTime() const; |
41 | 96 | QVector<QString> parentIds() const; // TODO: should be QList | 96 | QList<QString> parentIds() const; |
42 | 97 | 97 | ||
43 | 98 | Q_INVOKABLE ItemListJob* parents() const; | 98 | Q_INVOKABLE ItemListJob* parents() const; |
44 | 99 | Q_INVOKABLE ItemJob* copy(Item const& newParent, QString const& newName) const; | 99 | Q_INVOKABLE ItemJob* copy(Item const& newParent, QString const& newName) const; |
45 | 100 | 100 | ||
46 | === modified file 'include/unity/storage/qt/ItemListJob.h' | |||
47 | --- include/unity/storage/qt/ItemListJob.h 2016-09-26 02:12:30 +0000 | |||
48 | +++ include/unity/storage/qt/ItemListJob.h 2016-10-10 01:18:55 +0000 | |||
49 | @@ -34,7 +34,9 @@ | |||
50 | 34 | namespace internal | 34 | namespace internal |
51 | 35 | { | 35 | { |
52 | 36 | 36 | ||
53 | 37 | class ListJobImplBase; | ||
54 | 37 | class ItemListJobImpl; | 38 | class ItemListJobImpl; |
55 | 39 | class MultiItemJobImpl; | ||
56 | 38 | 40 | ||
57 | 39 | } // namespace internal | 41 | } // namespace internal |
58 | 40 | 42 | ||
59 | @@ -63,11 +65,13 @@ | |||
60 | 63 | void itemsReady(QList<unity::storage::qt::Item> const& items) const; | 65 | void itemsReady(QList<unity::storage::qt::Item> const& items) const; |
61 | 64 | 66 | ||
62 | 65 | private: | 67 | private: |
67 | 66 | ItemListJob(std::unique_ptr<internal::ItemListJobImpl> p); | 68 | ItemListJob(std::unique_ptr<internal::ListJobImplBase> p); |
68 | 67 | 69 | ||
69 | 68 | std::unique_ptr<internal::ItemListJobImpl> const p_; | 70 | std::unique_ptr<internal::ListJobImplBase> const p_; |
70 | 69 | 71 | ||
71 | 72 | friend class internal::ListJobImplBase; | ||
72 | 70 | friend class internal::ItemListJobImpl; | 73 | friend class internal::ItemListJobImpl; |
73 | 74 | friend class internal::MultiItemJobImpl; | ||
74 | 71 | }; | 75 | }; |
75 | 72 | 76 | ||
76 | 73 | } // namespace qt | 77 | } // namespace qt |
77 | 74 | 78 | ||
78 | === modified file 'include/unity/storage/qt/internal/Handler.h' | |||
79 | --- include/unity/storage/qt/internal/Handler.h 2016-09-16 06:25:08 +0000 | |||
80 | +++ include/unity/storage/qt/internal/Handler.h 2016-10-10 01:18:55 +0000 | |||
81 | @@ -58,7 +58,7 @@ | |||
82 | 58 | { | 58 | { |
83 | 59 | // LCOV_EXCL_START | 59 | // LCOV_EXCL_START |
84 | 60 | QString msg = "impossible provider exception: " + e.errorString(); | 60 | QString msg = "impossible provider exception: " + e.errorString(); |
86 | 61 | qCritical() << msg; | 61 | qCritical().noquote() << msg; |
87 | 62 | e = StorageErrorImpl::local_comms_error(msg); | 62 | e = StorageErrorImpl::local_comms_error(msg); |
88 | 63 | break; | 63 | break; |
89 | 64 | // LCOV_EXCL_STOP | 64 | // LCOV_EXCL_STOP |
90 | @@ -68,7 +68,8 @@ | |||
91 | 68 | case StorageError::ResourceError: | 68 | case StorageError::ResourceError: |
92 | 69 | { | 69 | { |
93 | 70 | // Log these errors because they are unexpected. | 70 | // Log these errors because they are unexpected. |
95 | 71 | qCritical() << "provider exception:" << e.errorString(); | 71 | QString msg = "provider exception: " + e.errorString(); |
96 | 72 | qCritical().noquote() << msg; | ||
97 | 72 | break; | 73 | break; |
98 | 73 | } | 74 | } |
99 | 74 | default: | 75 | default: |
100 | 75 | 76 | ||
101 | === modified file 'include/unity/storage/qt/internal/ItemImpl.h' | |||
102 | --- include/unity/storage/qt/internal/ItemImpl.h 2016-09-26 08:57:05 +0000 | |||
103 | +++ include/unity/storage/qt/internal/ItemImpl.h 2016-10-10 01:18:55 +0000 | |||
104 | @@ -53,7 +53,7 @@ | |||
105 | 53 | Item::Type type() const; | 53 | Item::Type type() const; |
106 | 54 | QVariantMap metadata() const; | 54 | QVariantMap metadata() const; |
107 | 55 | QDateTime lastModifiedTime() const; | 55 | QDateTime lastModifiedTime() const; |
109 | 56 | QVector<QString> parentIds() const; | 56 | QList<QString> parentIds() const; |
110 | 57 | 57 | ||
111 | 58 | ItemListJob* parents() const; | 58 | ItemListJob* parents() const; |
112 | 59 | ItemJob* copy(Item const& newParent, QString const& newName) const; | 59 | ItemJob* copy(Item const& newParent, QString const& newName) const; |
113 | @@ -89,7 +89,6 @@ | |||
114 | 89 | bool is_valid_; | 89 | bool is_valid_; |
115 | 90 | storage::internal::ItemMetadata md_; | 90 | storage::internal::ItemMetadata md_; |
116 | 91 | std::shared_ptr<AccountImpl> account_; | 91 | std::shared_ptr<AccountImpl> account_; |
117 | 92 | //std::shared_ptr<RootImpl> root_; | ||
118 | 93 | 92 | ||
119 | 94 | friend class unity::storage::qt::Item; | 93 | friend class unity::storage::qt::Item; |
120 | 95 | }; | 94 | }; |
121 | 96 | 95 | ||
122 | === modified file 'include/unity/storage/qt/internal/ItemJobImpl.h' | |||
123 | --- include/unity/storage/qt/internal/ItemJobImpl.h 2016-09-26 08:57:05 +0000 | |||
124 | +++ include/unity/storage/qt/internal/ItemJobImpl.h 2016-10-10 01:18:55 +0000 | |||
125 | @@ -53,11 +53,11 @@ | |||
126 | 53 | StorageError error() const; | 53 | StorageError error() const; |
127 | 54 | Item item() const; | 54 | Item item() const; |
128 | 55 | 55 | ||
134 | 56 | static ItemJob* make_item_job(std::shared_ptr<AccountImpl> const& account, | 56 | static ItemJob* make_job(std::shared_ptr<AccountImpl> const& account, |
135 | 57 | QString const& method, | 57 | QString const& method, |
136 | 58 | QDBusPendingReply<storage::internal::ItemMetadata> const& reply, | 58 | QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
137 | 59 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); | 59 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
138 | 60 | static ItemJob* make_item_job(StorageError const& e); | 60 | static ItemJob* make_job(StorageError const& e); |
139 | 61 | 61 | ||
140 | 62 | private: | 62 | private: |
141 | 63 | ItemJobImpl(std::shared_ptr<AccountImpl> const& account, | 63 | ItemJobImpl(std::shared_ptr<AccountImpl> const& account, |
142 | 64 | 64 | ||
143 | === modified file 'include/unity/storage/qt/internal/ItemListJobImpl.h' | |||
144 | --- include/unity/storage/qt/internal/ItemListJobImpl.h 2016-09-26 08:57:05 +0000 | |||
145 | +++ include/unity/storage/qt/internal/ItemListJobImpl.h 2016-10-10 01:18:55 +0000 | |||
146 | @@ -18,10 +18,9 @@ | |||
147 | 18 | 18 | ||
148 | 19 | #pragma once | 19 | #pragma once |
149 | 20 | 20 | ||
150 | 21 | #include <unity/storage/qt/internal/ListJobImplBase.h> | ||
151 | 21 | #include <unity/storage/qt/ItemListJob.h> | 22 | #include <unity/storage/qt/ItemListJob.h> |
152 | 22 | 23 | ||
153 | 23 | #include <unity/storage/qt/StorageError.h> | ||
154 | 24 | |||
155 | 25 | #include <QDBusPendingReply> | 24 | #include <QDBusPendingReply> |
156 | 26 | 25 | ||
157 | 27 | namespace unity | 26 | namespace unity |
158 | @@ -42,35 +41,24 @@ | |||
159 | 42 | 41 | ||
160 | 43 | class AccountImpl; | 42 | class AccountImpl; |
161 | 44 | 43 | ||
163 | 45 | class ItemListJobImpl : public QObject | 44 | class ItemListJobImpl : public ListJobImplBase |
164 | 46 | { | 45 | { |
165 | 47 | Q_OBJECT | 46 | Q_OBJECT |
166 | 48 | public: | 47 | public: |
167 | 49 | virtual ~ItemListJobImpl() = default; | 48 | virtual ~ItemListJobImpl() = default; |
168 | 50 | 49 | ||
178 | 51 | bool isValid() const; | 50 | static ItemListJob* make_job(std::shared_ptr<AccountImpl> const& account, |
179 | 52 | ItemListJob::Status status() const; | 51 | QString const& method, |
180 | 53 | StorageError error() const; | 52 | QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
181 | 54 | 53 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); | |
182 | 55 | static ItemListJob* make_item_list_job(std::shared_ptr<AccountImpl> const& account, | 54 | static ItemListJob* make_job(StorageError const& error); |
174 | 56 | QString const& method, | ||
175 | 57 | QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, | ||
176 | 58 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); | ||
177 | 59 | static ItemListJob* make_item_list_job(StorageError const& error); | ||
183 | 60 | 55 | ||
184 | 61 | private: | 56 | private: |
185 | 57 | ItemListJobImpl() = default; | ||
186 | 62 | ItemListJobImpl(std::shared_ptr<AccountImpl> const& account, | 58 | ItemListJobImpl(std::shared_ptr<AccountImpl> const& account, |
187 | 63 | QString const& method, | 59 | QString const& method, |
188 | 64 | QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, | 60 | QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
189 | 65 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); | 61 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); |
190 | 66 | ItemListJobImpl(StorageError const& error); | ||
191 | 67 | |||
192 | 68 | ItemListJob* public_instance_; | ||
193 | 69 | ItemListJob::Status status_; | ||
194 | 70 | StorageError error_; | ||
195 | 71 | QString method_; | ||
196 | 72 | std::shared_ptr<AccountImpl> account_; | ||
197 | 73 | std::function<void(storage::internal::ItemMetadata const&)> validate_; | ||
198 | 74 | }; | 62 | }; |
199 | 75 | 63 | ||
200 | 76 | } // namespace internal | 64 | } // namespace internal |
201 | 77 | 65 | ||
202 | === added file 'include/unity/storage/qt/internal/ListJobImplBase.h' | |||
203 | --- include/unity/storage/qt/internal/ListJobImplBase.h 1970-01-01 00:00:00 +0000 | |||
204 | +++ include/unity/storage/qt/internal/ListJobImplBase.h 2016-10-10 01:18:55 +0000 | |||
205 | @@ -0,0 +1,76 @@ | |||
206 | 1 | /* | ||
207 | 2 | * Copyright (C) 2016 Canonical Ltd | ||
208 | 3 | * | ||
209 | 4 | * This program is free software: you can redistribute it and/or modify | ||
210 | 5 | * it under the terms of the GNU Lesser General Public License version 3 as | ||
211 | 6 | * published by the Free Software Foundation. | ||
212 | 7 | * | ||
213 | 8 | * This program is distributed in the hope that it will be useful, | ||
214 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
215 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
216 | 11 | * GNU Lesser General Public License for more details. | ||
217 | 12 | * | ||
218 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
219 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
220 | 15 | * | ||
221 | 16 | * Authors: Michi Henning <michi.henning@canonical.com> | ||
222 | 17 | */ | ||
223 | 18 | |||
224 | 19 | #pragma once | ||
225 | 20 | |||
226 | 21 | #include <unity/storage/qt/ItemListJob.h> | ||
227 | 22 | #include <unity/storage/qt/StorageError.h> | ||
228 | 23 | |||
229 | 24 | #include <QDBusPendingReply> | ||
230 | 25 | |||
231 | 26 | namespace unity | ||
232 | 27 | { | ||
233 | 28 | namespace storage | ||
234 | 29 | { | ||
235 | 30 | namespace internal | ||
236 | 31 | { | ||
237 | 32 | |||
238 | 33 | class ItemMetadata; | ||
239 | 34 | |||
240 | 35 | } // namespace internal | ||
241 | 36 | |||
242 | 37 | namespace qt | ||
243 | 38 | { | ||
244 | 39 | namespace internal | ||
245 | 40 | { | ||
246 | 41 | |||
247 | 42 | class AccountImpl; | ||
248 | 43 | class MultiItemJobImpl; | ||
249 | 44 | |||
250 | 45 | class ListJobImplBase : public QObject | ||
251 | 46 | { | ||
252 | 47 | public: | ||
253 | 48 | ListJobImplBase(); // Makes job in Finished state. | ||
254 | 49 | ListJobImplBase(std::shared_ptr<AccountImpl> const& account, | ||
255 | 50 | QString const& method, | ||
256 | 51 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); | ||
257 | 52 | ListJobImplBase(StorageError const& error); | ||
258 | 53 | virtual ~ListJobImplBase() = default; | ||
259 | 54 | |||
260 | 55 | bool isValid() const; | ||
261 | 56 | ItemListJob::Status status() const; | ||
262 | 57 | StorageError error() const; | ||
263 | 58 | |||
264 | 59 | void set_public_instance(ItemListJob* p); | ||
265 | 60 | |||
266 | 61 | static ItemListJob* make_job(StorageError const& error); | ||
267 | 62 | static ItemListJob* make_empty_job(); | ||
268 | 63 | |||
269 | 64 | protected: | ||
270 | 65 | ItemListJob* public_instance_; | ||
271 | 66 | ItemListJob::Status status_; | ||
272 | 67 | StorageError error_; | ||
273 | 68 | QString method_; | ||
274 | 69 | std::shared_ptr<AccountImpl> account_; | ||
275 | 70 | std::function<void(storage::internal::ItemMetadata const&)> validate_; | ||
276 | 71 | }; | ||
277 | 72 | |||
278 | 73 | } // namespace internal | ||
279 | 74 | } // namespace qt | ||
280 | 75 | } // namespace storage | ||
281 | 76 | } // namespace unity | ||
282 | 0 | 77 | ||
283 | === added file 'include/unity/storage/qt/internal/MultiItemJobImpl.h' | |||
284 | --- include/unity/storage/qt/internal/MultiItemJobImpl.h 1970-01-01 00:00:00 +0000 | |||
285 | +++ include/unity/storage/qt/internal/MultiItemJobImpl.h 2016-10-10 01:18:55 +0000 | |||
286 | @@ -0,0 +1,68 @@ | |||
287 | 1 | /* | ||
288 | 2 | * Copyright (C) 2016 Canonical Ltd | ||
289 | 3 | * | ||
290 | 4 | * This program is free software: you can redistribute it and/or modify | ||
291 | 5 | * it under the terms of the GNU Lesser General Public License version 3 as | ||
292 | 6 | * published by the Free Software Foundation. | ||
293 | 7 | * | ||
294 | 8 | * This program is distributed in the hope that it will be useful, | ||
295 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
296 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
297 | 11 | * GNU Lesser General Public License for more details. | ||
298 | 12 | * | ||
299 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
300 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
301 | 15 | * | ||
302 | 16 | * Authors: Michi Henning <michi.henning@canonical.com> | ||
303 | 17 | */ | ||
304 | 18 | |||
305 | 19 | #pragma once | ||
306 | 20 | |||
307 | 21 | #include <unity/storage/qt/internal/ListJobImplBase.h> | ||
308 | 22 | #include <unity/storage/qt/ItemListJob.h> | ||
309 | 23 | |||
310 | 24 | #include <QDBusPendingReply> | ||
311 | 25 | |||
312 | 26 | namespace unity | ||
313 | 27 | { | ||
314 | 28 | namespace storage | ||
315 | 29 | { | ||
316 | 30 | namespace internal | ||
317 | 31 | { | ||
318 | 32 | |||
319 | 33 | class ItemMetadata; | ||
320 | 34 | |||
321 | 35 | } // namespace internal | ||
322 | 36 | |||
323 | 37 | namespace qt | ||
324 | 38 | { | ||
325 | 39 | namespace internal | ||
326 | 40 | { | ||
327 | 41 | |||
328 | 42 | class AccountImpl; | ||
329 | 43 | |||
330 | 44 | class MultiItemJobImpl : public ListJobImplBase | ||
331 | 45 | { | ||
332 | 46 | Q_OBJECT | ||
333 | 47 | public: | ||
334 | 48 | virtual ~MultiItemJobImpl() = default; | ||
335 | 49 | |||
336 | 50 | static ItemListJob* make_job(std::shared_ptr<AccountImpl> const& account, | ||
337 | 51 | QString const& method, | ||
338 | 52 | QList<QDBusPendingReply<storage::internal::ItemMetadata>> const& replies, | ||
339 | 53 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); | ||
340 | 54 | |||
341 | 55 | private: | ||
342 | 56 | MultiItemJobImpl() = default; | ||
343 | 57 | MultiItemJobImpl(std::shared_ptr<AccountImpl> const& account, | ||
344 | 58 | QString const& method, | ||
345 | 59 | QList<QDBusPendingReply<storage::internal::ItemMetadata>> const& replies, | ||
346 | 60 | std::function<void(storage::internal::ItemMetadata const&)> const& validate); | ||
347 | 61 | |||
348 | 62 | int replies_remaining_; | ||
349 | 63 | }; | ||
350 | 64 | |||
351 | 65 | } // namespace internal | ||
352 | 66 | } // namespace qt | ||
353 | 67 | } // namespace storage | ||
354 | 68 | } // namespace unity | ||
355 | 0 | 69 | ||
356 | === modified file 'include/unity/storage/qt/internal/StorageErrorImpl.h' | |||
357 | --- include/unity/storage/qt/internal/StorageErrorImpl.h 2016-09-16 06:25:08 +0000 | |||
358 | +++ include/unity/storage/qt/internal/StorageErrorImpl.h 2016-10-10 01:18:55 +0000 | |||
359 | @@ -70,6 +70,8 @@ | |||
360 | 70 | static StorageError resource_error(QString const& msg, int error_code); | 70 | static StorageError resource_error(QString const& msg, int error_code); |
361 | 71 | 71 | ||
362 | 72 | private: | 72 | private: |
363 | 73 | StorageErrorImpl(StorageError::Type type); | ||
364 | 74 | |||
365 | 73 | StorageError::Type type_; | 75 | StorageError::Type type_; |
366 | 74 | QString name_; | 76 | QString name_; |
367 | 75 | QString message_; | 77 | QString message_; |
368 | 76 | 78 | ||
369 | === modified file 'include/unity/storage/qt/internal/VoidJobImpl.h' | |||
370 | --- include/unity/storage/qt/internal/VoidJobImpl.h 2016-09-26 22:22:09 +0000 | |||
371 | +++ include/unity/storage/qt/internal/VoidJobImpl.h 2016-10-10 01:18:55 +0000 | |||
372 | @@ -45,10 +45,10 @@ | |||
373 | 45 | VoidJob::Status status() const; | 45 | VoidJob::Status status() const; |
374 | 46 | StorageError error() const; | 46 | StorageError error() const; |
375 | 47 | 47 | ||
380 | 48 | static VoidJob* make_void_job(std::shared_ptr<ItemImpl> const& item, | 48 | static VoidJob* make_job(std::shared_ptr<ItemImpl> const& item, |
381 | 49 | QString const& method, | 49 | QString const& method, |
382 | 50 | QDBusPendingReply<void> const& reply); | 50 | QDBusPendingReply<void> const& reply); |
383 | 51 | static VoidJob* make_void_job(StorageError const& e); | 51 | static VoidJob* make_job(StorageError const& e); |
384 | 52 | 52 | ||
385 | 53 | private: | 53 | private: |
386 | 54 | VoidJobImpl(std::shared_ptr<ItemImpl> const& item, | 54 | VoidJobImpl(std::shared_ptr<ItemImpl> const& item, |
387 | 55 | 55 | ||
388 | === modified file 'src/qt/CMakeLists.txt' | |||
389 | --- src/qt/CMakeLists.txt 2016-09-26 08:57:05 +0000 | |||
390 | +++ src/qt/CMakeLists.txt 2016-10-10 01:18:55 +0000 | |||
391 | @@ -30,6 +30,8 @@ | |||
392 | 30 | internal/ItemImpl.cpp | 30 | internal/ItemImpl.cpp |
393 | 31 | internal/ItemJobImpl.cpp | 31 | internal/ItemJobImpl.cpp |
394 | 32 | internal/ItemListJobImpl.cpp | 32 | internal/ItemListJobImpl.cpp |
395 | 33 | internal/ListJobImplBase.cpp | ||
396 | 34 | internal/MultiItemJobImpl.cpp | ||
397 | 33 | internal/RuntimeImpl.cpp | 35 | internal/RuntimeImpl.cpp |
398 | 34 | internal/StorageErrorImpl.cpp | 36 | internal/StorageErrorImpl.cpp |
399 | 35 | internal/unmarshal_error.cpp | 37 | internal/unmarshal_error.cpp |
400 | @@ -46,6 +48,8 @@ | |||
401 | 46 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/HandlerBase.h | 48 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/HandlerBase.h |
402 | 47 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/ItemJobImpl.h | 49 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/ItemJobImpl.h |
403 | 48 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/ItemListJobImpl.h | 50 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/ItemListJobImpl.h |
404 | 51 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/ListJobImplBase.h | ||
405 | 52 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/MultiItemJobImpl.h | ||
406 | 49 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/VoidJobImpl.h | 53 | ${CMAKE_SOURCE_DIR}/include/unity/storage/qt/internal/VoidJobImpl.h |
407 | 50 | ) | 54 | ) |
408 | 51 | 55 | ||
409 | 52 | 56 | ||
410 | === modified file 'src/qt/Item.cpp' | |||
411 | --- src/qt/Item.cpp 2016-09-22 01:52:20 +0000 | |||
412 | +++ src/qt/Item.cpp 2016-10-10 01:18:55 +0000 | |||
413 | @@ -48,6 +48,7 @@ | |||
414 | 48 | } | 48 | } |
415 | 49 | 49 | ||
416 | 50 | Item::Item(Item&& other) | 50 | Item::Item(Item&& other) |
417 | 51 | : p_(make_shared<internal::ItemImpl>()) | ||
418 | 51 | { | 52 | { |
419 | 52 | p_->is_valid_ = false; | 53 | p_->is_valid_ = false; |
420 | 53 | swap(p_, other.p_); | 54 | swap(p_, other.p_); |
421 | @@ -92,14 +93,6 @@ | |||
422 | 92 | return p_->account(); | 93 | return p_->account(); |
423 | 93 | } | 94 | } |
424 | 94 | 95 | ||
425 | 95 | #if 0 | ||
426 | 96 | Item Item::root() const | ||
427 | 97 | { | ||
428 | 98 | |||
429 | 99 | return p_->root(); | ||
430 | 100 | } | ||
431 | 101 | #endif | ||
432 | 102 | |||
433 | 103 | QString Item::etag() const | 96 | QString Item::etag() const |
434 | 104 | { | 97 | { |
435 | 105 | return p_->etag(); | 98 | return p_->etag(); |
436 | @@ -120,7 +113,7 @@ | |||
437 | 120 | return p_->lastModifiedTime(); | 113 | return p_->lastModifiedTime(); |
438 | 121 | } | 114 | } |
439 | 122 | 115 | ||
441 | 123 | QVector<QString> Item::parentIds() const | 116 | QList<QString> Item::parentIds() const |
442 | 124 | { | 117 | { |
443 | 125 | return p_->parentIds(); | 118 | return p_->parentIds(); |
444 | 126 | } | 119 | } |
445 | 127 | 120 | ||
446 | === modified file 'src/qt/ItemListJob.cpp' | |||
447 | --- src/qt/ItemListJob.cpp 2016-09-16 06:25:08 +0000 | |||
448 | +++ src/qt/ItemListJob.cpp 2016-10-10 01:18:55 +0000 | |||
449 | @@ -19,6 +19,7 @@ | |||
450 | 19 | #include <unity/storage/qt/ItemListJob.h> | 19 | #include <unity/storage/qt/ItemListJob.h> |
451 | 20 | 20 | ||
452 | 21 | #include <unity/storage/qt/internal/ItemListJobImpl.h> | 21 | #include <unity/storage/qt/internal/ItemListJobImpl.h> |
453 | 22 | #include <unity/storage/qt/internal/MultiItemJobImpl.h> | ||
454 | 22 | 23 | ||
455 | 23 | using namespace unity::storage::qt; | 24 | using namespace unity::storage::qt; |
456 | 24 | using namespace std; | 25 | using namespace std; |
457 | @@ -30,7 +31,7 @@ | |||
458 | 30 | namespace qt | 31 | namespace qt |
459 | 31 | { | 32 | { |
460 | 32 | 33 | ||
462 | 33 | ItemListJob::ItemListJob(unique_ptr<internal::ItemListJobImpl> p) | 34 | ItemListJob::ItemListJob(unique_ptr<internal::ListJobImplBase> p) |
463 | 34 | : p_(move(p)) | 35 | : p_(move(p)) |
464 | 35 | { | 36 | { |
465 | 36 | } | 37 | } |
466 | 37 | 38 | ||
467 | === modified file 'src/qt/client/internal/remote_client/ItemImpl.cpp' | |||
468 | --- src/qt/client/internal/remote_client/ItemImpl.cpp 2016-08-26 04:45:56 +0000 | |||
469 | +++ src/qt/client/internal/remote_client/ItemImpl.cpp 2016-10-10 01:18:55 +0000 | |||
470 | @@ -217,7 +217,14 @@ | |||
471 | 217 | { | 217 | { |
472 | 218 | throw_if_destroyed("Item::parent_ids()"); | 218 | throw_if_destroyed("Item::parent_ids()"); |
473 | 219 | // TODO, need different metadata representation, affects xml | 219 | // TODO, need different metadata representation, affects xml |
475 | 220 | return md_.parent_ids; | 220 | // We changed ItemMetadata to contain a QList for the v2 API, |
476 | 221 | // so we copy here. | ||
477 | 222 | QVector<QString> ids; | ||
478 | 223 | for (auto const& id : md_.parent_ids) | ||
479 | 224 | { | ||
480 | 225 | ids.append(id); | ||
481 | 226 | } | ||
482 | 227 | return ids; | ||
483 | 221 | } | 228 | } |
484 | 222 | 229 | ||
485 | 223 | QFuture<void> ItemImpl::delete_item() | 230 | QFuture<void> ItemImpl::delete_item() |
486 | 224 | 231 | ||
487 | === modified file 'src/qt/internal/AccountImpl.cpp' | |||
488 | --- src/qt/internal/AccountImpl.cpp 2016-09-26 08:57:05 +0000 | |||
489 | +++ src/qt/internal/AccountImpl.cpp 2016-10-10 01:18:55 +0000 | |||
490 | @@ -86,10 +86,15 @@ | |||
491 | 86 | QString const method = "Account::roots()"; | 86 | QString const method = "Account::roots()"; |
492 | 87 | 87 | ||
493 | 88 | auto runtime = runtime_.lock(); | 88 | auto runtime = runtime_.lock(); |
494 | 89 | if (!is_valid_) | ||
495 | 90 | { | ||
496 | 91 | auto e = StorageErrorImpl::logic_error(method + ": cannot create job from invalid account"); | ||
497 | 92 | return ItemListJobImpl::make_job(e); | ||
498 | 93 | } | ||
499 | 89 | if (!runtime || !runtime->isValid()) | 94 | if (!runtime || !runtime->isValid()) |
500 | 90 | { | 95 | { |
501 | 91 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); | 96 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); |
503 | 92 | return ItemListJobImpl::make_item_list_job(e); | 97 | return ItemListJobImpl::make_job(e); |
504 | 93 | } | 98 | } |
505 | 94 | 99 | ||
506 | 95 | auto validate = [method](storage::internal::ItemMetadata const& md) | 100 | auto validate = [method](storage::internal::ItemMetadata const& md) |
507 | @@ -104,18 +109,23 @@ | |||
508 | 104 | 109 | ||
509 | 105 | auto reply = provider_->Roots(); | 110 | auto reply = provider_->Roots(); |
510 | 106 | auto This = const_pointer_cast<AccountImpl>(shared_from_this()); | 111 | auto This = const_pointer_cast<AccountImpl>(shared_from_this()); |
512 | 107 | return ItemListJobImpl::make_item_list_job(This, method, reply, validate); | 112 | return ItemListJobImpl::make_job(This, method, reply, validate); |
513 | 108 | } | 113 | } |
514 | 109 | 114 | ||
515 | 110 | ItemJob* AccountImpl::get(QString const& itemId) const | 115 | ItemJob* AccountImpl::get(QString const& itemId) const |
516 | 111 | { | 116 | { |
517 | 112 | QString const method = "Account::get()"; | 117 | QString const method = "Account::get()"; |
518 | 113 | 118 | ||
519 | 119 | if (!is_valid_) | ||
520 | 120 | { | ||
521 | 121 | auto e = StorageErrorImpl::logic_error(method + ": cannot create job from invalid account"); | ||
522 | 122 | return ItemJobImpl::make_job(e); | ||
523 | 123 | } | ||
524 | 114 | auto runtime = runtime_.lock(); | 124 | auto runtime = runtime_.lock(); |
525 | 115 | if (!runtime || !runtime->isValid()) | 125 | if (!runtime || !runtime->isValid()) |
526 | 116 | { | 126 | { |
527 | 117 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); | 127 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); |
529 | 118 | return ItemJobImpl::make_item_job(e); | 128 | return ItemJobImpl::make_job(e); |
530 | 119 | } | 129 | } |
531 | 120 | 130 | ||
532 | 121 | // LCOV_EXCL_START | 131 | // LCOV_EXCL_START |
533 | @@ -126,7 +136,7 @@ | |||
534 | 126 | 136 | ||
535 | 127 | auto reply = provider_->Metadata(itemId); | 137 | auto reply = provider_->Metadata(itemId); |
536 | 128 | auto This = const_pointer_cast<AccountImpl>(shared_from_this()); | 138 | auto This = const_pointer_cast<AccountImpl>(shared_from_this()); |
538 | 129 | return ItemJobImpl::make_item_job(This, method, reply, validate); | 139 | return ItemJobImpl::make_job(This, method, reply, validate); |
539 | 130 | } | 140 | } |
540 | 131 | 141 | ||
541 | 132 | bool AccountImpl::operator==(AccountImpl const& other) const | 142 | bool AccountImpl::operator==(AccountImpl const& other) const |
542 | 133 | 143 | ||
543 | === modified file 'src/qt/internal/ItemImpl.cpp' | |||
544 | --- src/qt/internal/ItemImpl.cpp 2016-09-26 08:57:05 +0000 | |||
545 | +++ src/qt/internal/ItemImpl.cpp 2016-10-10 01:18:55 +0000 | |||
546 | @@ -22,6 +22,8 @@ | |||
547 | 22 | #include <unity/storage/provider/metadata_keys.h> | 22 | #include <unity/storage/provider/metadata_keys.h> |
548 | 23 | #include <unity/storage/qt/internal/AccountImpl.h> | 23 | #include <unity/storage/qt/internal/AccountImpl.h> |
549 | 24 | #include <unity/storage/qt/internal/ItemJobImpl.h> | 24 | #include <unity/storage/qt/internal/ItemJobImpl.h> |
550 | 25 | #include <unity/storage/qt/internal/ItemListJobImpl.h> | ||
551 | 26 | #include <unity/storage/qt/internal/MultiItemJobImpl.h> | ||
552 | 25 | #include <unity/storage/qt/internal/RuntimeImpl.h> | 27 | #include <unity/storage/qt/internal/RuntimeImpl.h> |
553 | 26 | #include <unity/storage/qt/internal/StorageErrorImpl.h> | 28 | #include <unity/storage/qt/internal/StorageErrorImpl.h> |
554 | 27 | #include <unity/storage/qt/internal/VoidJobImpl.h> | 29 | #include <unity/storage/qt/internal/VoidJobImpl.h> |
555 | @@ -104,14 +106,56 @@ | |||
556 | 104 | : QDateTime(); | 106 | : QDateTime(); |
557 | 105 | } | 107 | } |
558 | 106 | 108 | ||
560 | 107 | QVector<QString> ItemImpl::parentIds() const | 109 | QList<QString> ItemImpl::parentIds() const |
561 | 108 | { | 110 | { |
563 | 109 | return is_valid_ ? md_.parent_ids : QVector<QString>(); | 111 | if (!is_valid_ || md_.type == storage::ItemType::root) |
564 | 112 | { | ||
565 | 113 | return QList<QString>(); | ||
566 | 114 | } | ||
567 | 115 | return md_.parent_ids; | ||
568 | 110 | } | 116 | } |
569 | 111 | 117 | ||
570 | 112 | ItemListJob* ItemImpl::parents() const | 118 | ItemListJob* ItemImpl::parents() const |
571 | 113 | { | 119 | { |
573 | 114 | return nullptr; // TODO | 120 | QString const method = "Item::parents()"; |
574 | 121 | |||
575 | 122 | if (!is_valid_) | ||
576 | 123 | { | ||
577 | 124 | auto e = StorageErrorImpl::logic_error(method + ": cannot create job from invalid item"); | ||
578 | 125 | return ListJobImplBase::make_job(e); | ||
579 | 126 | } | ||
580 | 127 | auto runtime = account_->runtime(); | ||
581 | 128 | if (!runtime || !runtime->isValid()) | ||
582 | 129 | { | ||
583 | 130 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); | ||
584 | 131 | return ListJobImplBase::make_job(e); | ||
585 | 132 | } | ||
586 | 133 | |||
587 | 134 | if (md_.type == storage::ItemType::root) | ||
588 | 135 | { | ||
589 | 136 | return ListJobImplBase::make_empty_job(); // Root has no parents. | ||
590 | 137 | } | ||
591 | 138 | |||
592 | 139 | assert(!md_.parent_ids.isEmpty()); | ||
593 | 140 | |||
594 | 141 | QList<QDBusPendingReply<storage::internal::ItemMetadata>> replies; | ||
595 | 142 | for (auto const& id : md_.parent_ids) | ||
596 | 143 | { | ||
597 | 144 | auto reply = account_->provider()->Metadata(id); | ||
598 | 145 | replies.append(reply); | ||
599 | 146 | } | ||
600 | 147 | |||
601 | 148 | auto validate = [method](storage::internal::ItemMetadata const& md) | ||
602 | 149 | { | ||
603 | 150 | if (md.type == ItemType::file) | ||
604 | 151 | { | ||
605 | 152 | QString msg = method + ": provider returned a file as a parent"; | ||
606 | 153 | qCritical() << msg; | ||
607 | 154 | throw StorageErrorImpl::local_comms_error(msg); | ||
608 | 155 | } | ||
609 | 156 | }; | ||
610 | 157 | |||
611 | 158 | return MultiItemJobImpl::make_job(account_, method, replies, validate); | ||
612 | 115 | } | 159 | } |
613 | 116 | 160 | ||
614 | 117 | ItemJob* ItemImpl::copy(Item const& newParent, QString const& newName) const | 161 | ItemJob* ItemImpl::copy(Item const& newParent, QString const& newName) const |
615 | @@ -128,23 +172,26 @@ | |||
616 | 128 | { | 172 | { |
617 | 129 | QString const method = "Item::deleteItem()"; | 173 | QString const method = "Item::deleteItem()"; |
618 | 130 | 174 | ||
620 | 131 | assert(account_); | 175 | if (!is_valid_) |
621 | 176 | { | ||
622 | 177 | auto e = StorageErrorImpl::logic_error(method + ": cannot create job from invalid item"); | ||
623 | 178 | return VoidJobImpl::make_job(e); | ||
624 | 179 | } | ||
625 | 132 | auto runtime = account_->runtime(); | 180 | auto runtime = account_->runtime(); |
626 | 133 | if (!runtime || !runtime->isValid()) | 181 | if (!runtime || !runtime->isValid()) |
627 | 134 | { | 182 | { |
628 | 135 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); | 183 | auto e = StorageErrorImpl::runtime_destroyed_error(method + ": Runtime was destroyed previously"); |
630 | 136 | return VoidJobImpl::make_void_job(e); | 184 | return VoidJobImpl::make_job(e); |
631 | 137 | } | 185 | } |
632 | 138 | |||
633 | 139 | if (md_.type == storage::ItemType::root) | 186 | if (md_.type == storage::ItemType::root) |
634 | 140 | { | 187 | { |
635 | 141 | auto e = StorageErrorImpl::logic_error(method + ": cannot delete root"); | 188 | auto e = StorageErrorImpl::logic_error(method + ": cannot delete root"); |
637 | 142 | return VoidJobImpl::make_void_job(e); | 189 | return VoidJobImpl::make_job(e); |
638 | 143 | } | 190 | } |
639 | 144 | 191 | ||
640 | 145 | auto reply = account_->provider()->Delete(md_.item_id); | 192 | auto reply = account_->provider()->Delete(md_.item_id); |
641 | 146 | auto This = const_pointer_cast<ItemImpl>(shared_from_this()); | 193 | auto This = const_pointer_cast<ItemImpl>(shared_from_this()); |
643 | 147 | return VoidJobImpl::make_void_job(This, method, reply); | 194 | return VoidJobImpl::make_job(This, method, reply); |
644 | 148 | } | 195 | } |
645 | 149 | 196 | ||
646 | 150 | Uploader* ItemImpl::createUploader(Item::ConflictPolicy policy, qint64 sizeInBytes) const | 197 | Uploader* ItemImpl::createUploader(Item::ConflictPolicy policy, qint64 sizeInBytes) const |
647 | 151 | 198 | ||
648 | === modified file 'src/qt/internal/ItemJobImpl.cpp' | |||
649 | --- src/qt/internal/ItemJobImpl.cpp 2016-09-26 08:57:05 +0000 | |||
650 | +++ src/qt/internal/ItemJobImpl.cpp 2016-10-10 01:18:55 +0000 | |||
651 | @@ -112,10 +112,10 @@ | |||
652 | 112 | return item_; | 112 | return item_; |
653 | 113 | } | 113 | } |
654 | 114 | 114 | ||
659 | 115 | ItemJob* ItemJobImpl::make_item_job(shared_ptr<AccountImpl> const& account, | 115 | ItemJob* ItemJobImpl::make_job(shared_ptr<AccountImpl> const& account, |
660 | 116 | QString const& method, | 116 | QString const& method, |
661 | 117 | QDBusPendingReply<storage::internal::ItemMetadata> const& reply, | 117 | QDBusPendingReply<storage::internal::ItemMetadata> const& reply, |
662 | 118 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) | 118 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
663 | 119 | { | 119 | { |
664 | 120 | unique_ptr<ItemJobImpl> impl(new ItemJobImpl(account, method, reply, validate)); | 120 | unique_ptr<ItemJobImpl> impl(new ItemJobImpl(account, method, reply, validate)); |
665 | 121 | auto job = new ItemJob(move(impl)); | 121 | auto job = new ItemJob(move(impl)); |
666 | @@ -123,7 +123,7 @@ | |||
667 | 123 | return job; | 123 | return job; |
668 | 124 | } | 124 | } |
669 | 125 | 125 | ||
671 | 126 | ItemJob* ItemJobImpl::make_item_job(StorageError const& error) | 126 | ItemJob* ItemJobImpl::make_job(StorageError const& error) |
672 | 127 | { | 127 | { |
673 | 128 | unique_ptr<ItemJobImpl> impl(new ItemJobImpl(error)); | 128 | unique_ptr<ItemJobImpl> impl(new ItemJobImpl(error)); |
674 | 129 | auto job = new ItemJob(move(impl)); | 129 | auto job = new ItemJob(move(impl)); |
675 | 130 | 130 | ||
676 | === modified file 'src/qt/internal/ItemListJobImpl.cpp' | |||
677 | --- src/qt/internal/ItemListJobImpl.cpp 2016-09-26 08:57:05 +0000 | |||
678 | +++ src/qt/internal/ItemListJobImpl.cpp 2016-10-10 01:18:55 +0000 | |||
679 | @@ -19,7 +19,6 @@ | |||
680 | 19 | #include <unity/storage/qt/internal/ItemListJobImpl.h> | 19 | #include <unity/storage/qt/internal/ItemListJobImpl.h> |
681 | 20 | 20 | ||
682 | 21 | #include <unity/storage/internal/dbusmarshal.h> | 21 | #include <unity/storage/internal/dbusmarshal.h> |
683 | 22 | #include <unity/storage/internal/ItemMetadata.h> | ||
684 | 23 | #include <unity/storage/qt/internal/AccountImpl.h> | 22 | #include <unity/storage/qt/internal/AccountImpl.h> |
685 | 24 | #include <unity/storage/qt/internal/Handler.h> | 23 | #include <unity/storage/qt/internal/Handler.h> |
686 | 25 | #include <unity/storage/qt/internal/ItemImpl.h> | 24 | #include <unity/storage/qt/internal/ItemImpl.h> |
687 | @@ -40,15 +39,8 @@ | |||
688 | 40 | QString const& method, | 39 | QString const& method, |
689 | 41 | QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, | 40 | QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
690 | 42 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) | 41 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
695 | 43 | : status_(ItemListJob::Loading) | 42 | : ListJobImplBase(account, method, validate) |
692 | 44 | , method_(method) | ||
693 | 45 | , account_(account) | ||
694 | 46 | , validate_(validate) | ||
696 | 47 | { | 43 | { |
697 | 48 | assert(!method.isEmpty()); | ||
698 | 49 | assert(account); | ||
699 | 50 | assert(validate); | ||
700 | 51 | |||
701 | 52 | auto process_reply = [this](decltype(reply)& r) | 44 | auto process_reply = [this](decltype(reply)& r) |
702 | 53 | { | 45 | { |
703 | 54 | auto runtime = account_->runtime(); | 46 | auto runtime = account_->runtime(); |
704 | @@ -82,6 +74,7 @@ | |||
705 | 82 | 74 | ||
706 | 83 | auto process_error = [this](StorageError const& error) | 75 | auto process_error = [this](StorageError const& error) |
707 | 84 | { | 76 | { |
708 | 77 | // TODO: method name is not being set this way. | ||
709 | 85 | error_ = error; | 78 | error_ = error; |
710 | 86 | status_ = ItemListJob::Error; | 79 | status_ = ItemListJob::Error; |
711 | 87 | Q_EMIT public_instance_->statusChanged(status_); | 80 | Q_EMIT public_instance_->statusChanged(status_); |
712 | @@ -90,49 +83,20 @@ | |||
713 | 90 | new Handler<QList<storage::internal::ItemMetadata>>(this, reply, process_reply, process_error); | 83 | new Handler<QList<storage::internal::ItemMetadata>>(this, reply, process_reply, process_error); |
714 | 91 | } | 84 | } |
715 | 92 | 85 | ||
742 | 93 | ItemListJobImpl::ItemListJobImpl(StorageError const& error) | 86 | ItemListJob* ItemListJobImpl::make_job(shared_ptr<AccountImpl> const& account, |
743 | 94 | : status_(ItemListJob::Error) | 87 | QString const& method, |
744 | 95 | , error_(error) | 88 | QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, |
745 | 96 | { | 89 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) |
720 | 97 | } | ||
721 | 98 | |||
722 | 99 | bool ItemListJobImpl::isValid() const | ||
723 | 100 | { | ||
724 | 101 | return status_ != ItemListJob::Status::Error; | ||
725 | 102 | } | ||
726 | 103 | |||
727 | 104 | ItemListJob::Status ItemListJobImpl::status() const | ||
728 | 105 | { | ||
729 | 106 | return status_; | ||
730 | 107 | } | ||
731 | 108 | |||
732 | 109 | StorageError ItemListJobImpl::error() const | ||
733 | 110 | { | ||
734 | 111 | return error_; | ||
735 | 112 | } | ||
736 | 113 | |||
737 | 114 | ItemListJob* ItemListJobImpl::make_item_list_job( | ||
738 | 115 | shared_ptr<AccountImpl> const& account, | ||
739 | 116 | QString const& method, | ||
740 | 117 | QDBusPendingReply<QList<storage::internal::ItemMetadata>> const& reply, | ||
741 | 118 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) | ||
746 | 119 | { | 90 | { |
747 | 120 | unique_ptr<ItemListJobImpl> impl(new ItemListJobImpl(account, method, reply, validate)); | 91 | unique_ptr<ItemListJobImpl> impl(new ItemListJobImpl(account, method, reply, validate)); |
748 | 121 | auto job = new ItemListJob(move(impl)); | 92 | auto job = new ItemListJob(move(impl)); |
750 | 122 | job->p_->public_instance_ = job; | 93 | job->p_->set_public_instance(job); |
751 | 123 | return job; | 94 | return job; |
752 | 124 | } | 95 | } |
753 | 125 | 96 | ||
755 | 126 | ItemListJob* ItemListJobImpl::make_item_list_job(StorageError const& error) | 97 | ItemListJob* ItemListJobImpl::make_job(StorageError const& error) |
756 | 127 | { | 98 | { |
765 | 128 | unique_ptr<ItemListJobImpl> impl(new ItemListJobImpl(error)); | 99 | return ListJobImplBase::make_job(error); |
758 | 129 | auto job = new ItemListJob(move(impl)); | ||
759 | 130 | job->p_->public_instance_ = job; | ||
760 | 131 | QMetaObject::invokeMethod(job, | ||
761 | 132 | "statusChanged", | ||
762 | 133 | Qt::QueuedConnection, | ||
763 | 134 | Q_ARG(unity::storage::qt::ItemListJob::Status, job->p_->status_)); | ||
764 | 135 | return job; | ||
766 | 136 | } | 100 | } |
767 | 137 | 101 | ||
768 | 138 | } // namespace internal | 102 | } // namespace internal |
769 | 139 | 103 | ||
770 | === added file 'src/qt/internal/ListJobImplBase.cpp' | |||
771 | --- src/qt/internal/ListJobImplBase.cpp 1970-01-01 00:00:00 +0000 | |||
772 | +++ src/qt/internal/ListJobImplBase.cpp 2016-10-10 01:18:55 +0000 | |||
773 | @@ -0,0 +1,111 @@ | |||
774 | 1 | /* | ||
775 | 2 | * Copyright (C) 2016 Canonical Ltd | ||
776 | 3 | * | ||
777 | 4 | * This program is free software: you can redistribute it and/or modify | ||
778 | 5 | * it under the terms of the GNU Lesser General Public License version 3 as | ||
779 | 6 | * published by the Free Software Foundation. | ||
780 | 7 | * | ||
781 | 8 | * This program is distributed in the hope that it will be useful, | ||
782 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
783 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
784 | 11 | * GNU Lesser General Public License for more details. | ||
785 | 12 | * | ||
786 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
787 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
788 | 15 | * | ||
789 | 16 | * Authors: Michi Henning <michi.henning@canonical.com> | ||
790 | 17 | */ | ||
791 | 18 | |||
792 | 19 | #include <unity/storage/qt/internal/ListJobImplBase.h> | ||
793 | 20 | |||
794 | 21 | #include <unity/storage/internal/dbusmarshal.h> | ||
795 | 22 | #include <unity/storage/internal/ItemMetadata.h> | ||
796 | 23 | #include <unity/storage/qt/internal/AccountImpl.h> | ||
797 | 24 | #include <unity/storage/qt/internal/Handler.h> | ||
798 | 25 | #include <unity/storage/qt/internal/ItemImpl.h> | ||
799 | 26 | #include <unity/storage/qt/internal/RuntimeImpl.h> | ||
800 | 27 | |||
801 | 28 | using namespace std; | ||
802 | 29 | |||
803 | 30 | namespace unity | ||
804 | 31 | { | ||
805 | 32 | namespace storage | ||
806 | 33 | { | ||
807 | 34 | namespace qt | ||
808 | 35 | { | ||
809 | 36 | namespace internal | ||
810 | 37 | { | ||
811 | 38 | |||
812 | 39 | ListJobImplBase::ListJobImplBase() | ||
813 | 40 | : status_(ItemListJob::Finished) | ||
814 | 41 | { | ||
815 | 42 | } | ||
816 | 43 | |||
817 | 44 | ListJobImplBase::ListJobImplBase(shared_ptr<AccountImpl> const& account, | ||
818 | 45 | QString const& method, | ||
819 | 46 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) | ||
820 | 47 | : status_(ItemListJob::Loading) | ||
821 | 48 | , method_(method) | ||
822 | 49 | , account_(account) | ||
823 | 50 | , validate_(validate) | ||
824 | 51 | { | ||
825 | 52 | assert(!method.isEmpty()); | ||
826 | 53 | assert(account); | ||
827 | 54 | assert(validate); | ||
828 | 55 | } | ||
829 | 56 | |||
830 | 57 | ListJobImplBase::ListJobImplBase(StorageError const& error) | ||
831 | 58 | : status_(ItemListJob::Error) | ||
832 | 59 | , error_(error) | ||
833 | 60 | { | ||
834 | 61 | } | ||
835 | 62 | |||
836 | 63 | bool ListJobImplBase::isValid() const | ||
837 | 64 | { | ||
838 | 65 | return status_ != ItemListJob::Status::Error; | ||
839 | 66 | } | ||
840 | 67 | |||
841 | 68 | ItemListJob::Status ListJobImplBase::status() const | ||
842 | 69 | { | ||
843 | 70 | return status_; | ||
844 | 71 | } | ||
845 | 72 | |||
846 | 73 | StorageError ListJobImplBase::error() const | ||
847 | 74 | { | ||
848 | 75 | return error_; | ||
849 | 76 | } | ||
850 | 77 | |||
851 | 78 | void ListJobImplBase::set_public_instance(ItemListJob* p) | ||
852 | 79 | { | ||
853 | 80 | assert(p); | ||
854 | 81 | public_instance_ = p; | ||
855 | 82 | } | ||
856 | 83 | |||
857 | 84 | ItemListJob* ListJobImplBase::make_job(StorageError const& error) | ||
858 | 85 | { | ||
859 | 86 | unique_ptr<ListJobImplBase> impl(new ListJobImplBase(error)); | ||
860 | 87 | auto job = new ItemListJob(move(impl)); | ||
861 | 88 | job->p_->public_instance_ = job; | ||
862 | 89 | QMetaObject::invokeMethod(job, | ||
863 | 90 | "statusChanged", | ||
864 | 91 | Qt::QueuedConnection, | ||
865 | 92 | Q_ARG(unity::storage::qt::ItemListJob::Status, job->status())); | ||
866 | 93 | return job; | ||
867 | 94 | } | ||
868 | 95 | |||
869 | 96 | ItemListJob* ListJobImplBase::make_empty_job() | ||
870 | 97 | { | ||
871 | 98 | unique_ptr<ListJobImplBase> impl(new ListJobImplBase()); | ||
872 | 99 | auto job = new ItemListJob(move(impl)); | ||
873 | 100 | job->p_->public_instance_ = job; | ||
874 | 101 | QMetaObject::invokeMethod(job, | ||
875 | 102 | "statusChanged", | ||
876 | 103 | Qt::QueuedConnection, | ||
877 | 104 | Q_ARG(unity::storage::qt::ItemListJob::Status, job->status())); | ||
878 | 105 | return job; | ||
879 | 106 | } | ||
880 | 107 | |||
881 | 108 | } // namespace internal | ||
882 | 109 | } // namespace qt | ||
883 | 110 | } // namespace storage | ||
884 | 111 | } // namespace unity | ||
885 | 0 | 112 | ||
886 | === added file 'src/qt/internal/MultiItemJobImpl.cpp' | |||
887 | --- src/qt/internal/MultiItemJobImpl.cpp 1970-01-01 00:00:00 +0000 | |||
888 | +++ src/qt/internal/MultiItemJobImpl.cpp 2016-10-10 01:18:55 +0000 | |||
889 | @@ -0,0 +1,135 @@ | |||
890 | 1 | /* | ||
891 | 2 | * Copyright (C) 2016 Canonical Ltd | ||
892 | 3 | * | ||
893 | 4 | * This program is free software: you can redistribute it and/or modify | ||
894 | 5 | * it under the terms of the GNU Lesser General Public License version 3 as | ||
895 | 6 | * published by the Free Software Foundation. | ||
896 | 7 | * | ||
897 | 8 | * This program is distributed in the hope that it will be useful, | ||
898 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
899 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
900 | 11 | * GNU Lesser General Public License for more details. | ||
901 | 12 | * | ||
902 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
903 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
904 | 15 | * | ||
905 | 16 | * Authors: Michi Henning <michi.henning@canonical.com> | ||
906 | 17 | */ | ||
907 | 18 | |||
908 | 19 | #include <unity/storage/qt/internal/MultiItemJobImpl.h> | ||
909 | 20 | |||
910 | 21 | #include <unity/storage/internal/dbusmarshal.h> | ||
911 | 22 | #include <unity/storage/qt/internal/AccountImpl.h> | ||
912 | 23 | #include <unity/storage/qt/internal/Handler.h> | ||
913 | 24 | #include <unity/storage/qt/internal/ItemImpl.h> | ||
914 | 25 | #include <unity/storage/qt/internal/RuntimeImpl.h> | ||
915 | 26 | |||
916 | 27 | using namespace std; | ||
917 | 28 | |||
918 | 29 | namespace unity | ||
919 | 30 | { | ||
920 | 31 | namespace storage | ||
921 | 32 | { | ||
922 | 33 | namespace qt | ||
923 | 34 | { | ||
924 | 35 | namespace internal | ||
925 | 36 | { | ||
926 | 37 | |||
927 | 38 | MultiItemJobImpl::MultiItemJobImpl(shared_ptr<AccountImpl> const& account, | ||
928 | 39 | QString const& method, | ||
929 | 40 | QList<QDBusPendingReply<storage::internal::ItemMetadata>> const& replies, | ||
930 | 41 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) | ||
931 | 42 | : ListJobImplBase(account, method, validate) | ||
932 | 43 | , replies_remaining_(replies.size()) | ||
933 | 44 | { | ||
934 | 45 | assert(!method.isEmpty()); | ||
935 | 46 | assert(account); | ||
936 | 47 | assert(validate); | ||
937 | 48 | |||
938 | 49 | // We ask the provider for the metadata for each of this item's parents. | ||
939 | 50 | // As the replies trickle in, we track when the last reply has arrived and | ||
940 | 51 | // signal that the job is complete. | ||
941 | 52 | // If anything goes wrong at all, we report the first error and then ignore all | ||
942 | 53 | // other replies. | ||
943 | 54 | |||
944 | 55 | auto process_reply = [this](QDBusPendingReply<storage::internal::ItemMetadata> const& r) | ||
945 | 56 | { | ||
946 | 57 | assert(status_ != ItemListJob::Finished); | ||
947 | 58 | |||
948 | 59 | --replies_remaining_; | ||
949 | 60 | |||
950 | 61 | if (status_ == ItemListJob::Error) | ||
951 | 62 | { | ||
952 | 63 | return; | ||
953 | 64 | } | ||
954 | 65 | |||
955 | 66 | auto runtime = account_->runtime(); | ||
956 | 67 | if (!runtime || !runtime->isValid()) | ||
957 | 68 | { | ||
958 | 69 | error_ = StorageErrorImpl::runtime_destroyed_error(method_ + ": Runtime was destroyed previously"); | ||
959 | 70 | status_ = ItemListJob::Error; | ||
960 | 71 | Q_EMIT public_instance_->statusChanged(status_); | ||
961 | 72 | return; | ||
962 | 73 | } | ||
963 | 74 | |||
964 | 75 | auto metadata = r.value(); | ||
965 | 76 | Item item; | ||
966 | 77 | try | ||
967 | 78 | { | ||
968 | 79 | validate_(metadata); | ||
969 | 80 | item = ItemImpl::make_item(method_, metadata, account_); | ||
970 | 81 | } | ||
971 | 82 | catch (StorageError const& e) | ||
972 | 83 | { | ||
973 | 84 | // Bad metadata received from provider, validate_() or make_item() have logged it. | ||
974 | 85 | status_ = ItemListJob::Error; | ||
975 | 86 | error_ = e; | ||
976 | 87 | Q_EMIT public_instance_->statusChanged(status_); | ||
977 | 88 | return; | ||
978 | 89 | } | ||
979 | 90 | QList<Item> items; | ||
980 | 91 | items.append(item); | ||
981 | 92 | Q_EMIT public_instance_->itemsReady(items); | ||
982 | 93 | |||
983 | 94 | if (replies_remaining_ == 0) | ||
984 | 95 | { | ||
985 | 96 | status_ = ItemListJob::Finished; | ||
986 | 97 | Q_EMIT public_instance_->statusChanged(status_); | ||
987 | 98 | } | ||
988 | 99 | }; | ||
989 | 100 | |||
990 | 101 | auto process_error = [this](StorageError const& error) | ||
991 | 102 | { | ||
992 | 103 | assert(status_ != ItemListJob::Finished); | ||
993 | 104 | |||
994 | 105 | if (status_ == ItemListJob::Error) | ||
995 | 106 | { | ||
996 | 107 | return; | ||
997 | 108 | } | ||
998 | 109 | // TODO: method name is not being set this way. | ||
999 | 110 | error_ = error; | ||
1000 | 111 | status_ = ItemListJob::Error; | ||
1001 | 112 | Q_EMIT public_instance_->statusChanged(status_); | ||
1002 | 113 | }; | ||
1003 | 114 | |||
1004 | 115 | for (auto const& reply : replies) | ||
1005 | 116 | { | ||
1006 | 117 | new Handler<storage::internal::ItemMetadata>(this, reply, process_reply, process_error); | ||
1007 | 118 | } | ||
1008 | 119 | } | ||
1009 | 120 | |||
1010 | 121 | ItemListJob* MultiItemJobImpl::make_job(shared_ptr<AccountImpl> const& account, | ||
1011 | 122 | QString const& method, | ||
1012 | 123 | QList<QDBusPendingReply<storage::internal::ItemMetadata>> const& replies, | ||
1013 | 124 | std::function<void(storage::internal::ItemMetadata const&)> const& validate) | ||
1014 | 125 | { | ||
1015 | 126 | unique_ptr<MultiItemJobImpl> impl(new MultiItemJobImpl(account, method, replies, validate)); | ||
1016 | 127 | auto job = new ItemListJob(move(impl)); | ||
1017 | 128 | job->p_->set_public_instance(job); | ||
1018 | 129 | return job; | ||
1019 | 130 | } | ||
1020 | 131 | |||
1021 | 132 | } // namespace internal | ||
1022 | 133 | } // namespace qt | ||
1023 | 134 | } // namespace storage | ||
1024 | 135 | } // namespace unity | ||
1025 | 0 | 136 | ||
1026 | === modified file 'src/qt/internal/StorageErrorImpl.cpp' | |||
1027 | --- src/qt/internal/StorageErrorImpl.cpp 2016-09-16 06:25:08 +0000 | |||
1028 | +++ src/qt/internal/StorageErrorImpl.cpp 2016-10-10 01:18:55 +0000 | |||
1029 | @@ -35,27 +35,40 @@ | |||
1030 | 35 | namespace | 35 | namespace |
1031 | 36 | { | 36 | { |
1032 | 37 | 37 | ||
1034 | 38 | static char const * const ERROR_NAMES[StorageError::__LAST_STORAGE_ERROR] = | 38 | static const QString ERROR_NAMES[StorageError::__LAST_STORAGE_ERROR] = |
1035 | 39 | { | 39 | { |
1038 | 40 | "NoError", "LocalCommsError", "RemoteCommsError", "Deleted", "RuntimeDestroyed", "NotExists", | 40 | QStringLiteral("NoError"), |
1039 | 41 | "Exists", "Conflict", "PermissionDenied", "Cancelled", "LogicError", "InvalidArgument", "ResourceError" | 41 | QStringLiteral("LocalCommsError"), |
1040 | 42 | QStringLiteral("RemoteCommsError"), | ||
1041 | 43 | QStringLiteral("Deleted"), | ||
1042 | 44 | QStringLiteral("RuntimeDestroyed"), | ||
1043 | 45 | QStringLiteral("NotExists"), | ||
1044 | 46 | QStringLiteral("Exists"), | ||
1045 | 47 | QStringLiteral("Conflict"), | ||
1046 | 48 | QStringLiteral("PermissionDenied"), | ||
1047 | 49 | QStringLiteral("Cancelled"), | ||
1048 | 50 | QStringLiteral("LogicError"), | ||
1049 | 51 | QStringLiteral("InvalidArgument"), | ||
1050 | 52 | QStringLiteral("ResourceError") | ||
1051 | 42 | }; | 53 | }; |
1052 | 43 | 54 | ||
1053 | 44 | } // namespace | 55 | } // namespace |
1054 | 45 | 56 | ||
1055 | 57 | StorageErrorImpl::StorageErrorImpl(StorageError::Type type) | ||
1056 | 58 | : type_(type) | ||
1057 | 59 | , name_(ERROR_NAMES[type_]) | ||
1058 | 60 | , error_code_(0) | ||
1059 | 61 | { | ||
1060 | 62 | } | ||
1061 | 63 | |||
1062 | 46 | StorageErrorImpl::StorageErrorImpl() | 64 | StorageErrorImpl::StorageErrorImpl() |
1067 | 47 | : type_(StorageError::Type::NoError) | 65 | : StorageErrorImpl(StorageError::Type::NoError) |
1064 | 48 | , name_(ERROR_NAMES[type_]) | ||
1065 | 49 | , message_("No error") | ||
1066 | 50 | , error_code_(0) | ||
1068 | 51 | { | 66 | { |
1069 | 67 | message_ = "No error"; | ||
1070 | 52 | } | 68 | } |
1071 | 53 | 69 | ||
1072 | 54 | StorageErrorImpl::StorageErrorImpl(StorageError::Type type, QString const& msg) | 70 | StorageErrorImpl::StorageErrorImpl(StorageError::Type type, QString const& msg) |
1077 | 55 | : type_(type) | 71 | : StorageErrorImpl(type) |
1074 | 56 | , name_(ERROR_NAMES[type_]) | ||
1075 | 57 | , message_(msg) | ||
1076 | 58 | , error_code_(0) | ||
1078 | 59 | { | 72 | { |
1079 | 60 | assert( type == StorageError::Type::LocalCommsError | 73 | assert( type == StorageError::Type::LocalCommsError |
1080 | 61 | || type == StorageError::Type::RemoteCommsError | 74 | || type == StorageError::Type::RemoteCommsError |
1081 | @@ -66,18 +79,18 @@ | |||
1082 | 66 | || type == StorageError::Type::LogicError | 79 | || type == StorageError::Type::LogicError |
1083 | 67 | || type == StorageError::Type::InvalidArgument); | 80 | || type == StorageError::Type::InvalidArgument); |
1084 | 68 | assert(!msg.isEmpty()); | 81 | assert(!msg.isEmpty()); |
1085 | 82 | |||
1086 | 83 | message_ = msg; | ||
1087 | 69 | } | 84 | } |
1088 | 70 | 85 | ||
1089 | 71 | StorageErrorImpl::StorageErrorImpl(StorageError::Type type, QString const& msg, QString const& key) | 86 | StorageErrorImpl::StorageErrorImpl(StorageError::Type type, QString const& msg, QString const& key) |
1094 | 72 | : type_(type) | 87 | : StorageErrorImpl(type) |
1091 | 73 | , name_(ERROR_NAMES[type_]) | ||
1092 | 74 | , message_(msg) | ||
1093 | 75 | , error_code_(0) | ||
1095 | 76 | { | 88 | { |
1096 | 77 | assert( type == StorageError::Type::Deleted | 89 | assert( type == StorageError::Type::Deleted |
1097 | 78 | || type == StorageError::Type::NotExists); | 90 | || type == StorageError::Type::NotExists); |
1098 | 79 | assert(!msg.isEmpty()); | 91 | assert(!msg.isEmpty()); |
1099 | 80 | 92 | ||
1100 | 93 | message_ = msg; | ||
1101 | 81 | item_id_ = key; | 94 | item_id_ = key; |
1102 | 82 | if (type == StorageError::Type::NotExists) | 95 | if (type == StorageError::Type::NotExists) |
1103 | 83 | { | 96 | { |
1104 | @@ -89,26 +102,26 @@ | |||
1105 | 89 | QString const& msg, | 102 | QString const& msg, |
1106 | 90 | QString const& item_id, | 103 | QString const& item_id, |
1107 | 91 | QString const& item_name) | 104 | QString const& item_name) |
1114 | 92 | : type_(type) | 105 | : StorageErrorImpl(type) |
1109 | 93 | , name_(ERROR_NAMES[type_]) | ||
1110 | 94 | , message_(msg) | ||
1111 | 95 | , item_id_(item_id) | ||
1112 | 96 | , item_name_(item_name) | ||
1113 | 97 | , error_code_(0) | ||
1115 | 98 | { | 106 | { |
1116 | 99 | assert(type == StorageError::Type::Exists); | 107 | assert(type == StorageError::Type::Exists); |
1117 | 100 | assert(!msg.isEmpty()); | 108 | assert(!msg.isEmpty()); |
1118 | 101 | assert(!item_id.isEmpty()); | 109 | assert(!item_id.isEmpty()); |
1119 | 102 | assert(!item_name.isEmpty()); | 110 | assert(!item_name.isEmpty()); |
1120 | 111 | |||
1121 | 112 | message_ = msg; | ||
1122 | 113 | item_id_ = item_id; | ||
1123 | 114 | item_name_ = item_name; | ||
1124 | 103 | } | 115 | } |
1125 | 104 | 116 | ||
1126 | 105 | StorageErrorImpl::StorageErrorImpl(StorageError::Type type, QString const& msg, int error_code) | 117 | StorageErrorImpl::StorageErrorImpl(StorageError::Type type, QString const& msg, int error_code) |
1130 | 106 | : type_(type) | 118 | : StorageErrorImpl(type) |
1128 | 107 | , message_(msg) | ||
1129 | 108 | , error_code_(error_code) | ||
1131 | 109 | { | 119 | { |
1132 | 110 | assert(type == StorageError::Type::ResourceError); | 120 | assert(type == StorageError::Type::ResourceError); |
1133 | 111 | assert(!msg.isEmpty()); | 121 | assert(!msg.isEmpty()); |
1134 | 122 | |||
1135 | 123 | message_ = msg; | ||
1136 | 124 | error_code_ = error_code; | ||
1137 | 112 | } | 125 | } |
1138 | 113 | 126 | ||
1139 | 114 | StorageError::Type StorageErrorImpl::type() const | 127 | StorageError::Type StorageErrorImpl::type() const |
1140 | 115 | 128 | ||
1141 | === modified file 'src/qt/internal/VoidJobImpl.cpp' | |||
1142 | --- src/qt/internal/VoidJobImpl.cpp 2016-09-26 08:57:05 +0000 | |||
1143 | +++ src/qt/internal/VoidJobImpl.cpp 2016-10-10 01:18:55 +0000 | |||
1144 | @@ -89,9 +89,9 @@ | |||
1145 | 89 | return error_; | 89 | return error_; |
1146 | 90 | } | 90 | } |
1147 | 91 | 91 | ||
1151 | 92 | VoidJob* VoidJobImpl::make_void_job(shared_ptr<ItemImpl> const& item, | 92 | VoidJob* VoidJobImpl::make_job(shared_ptr<ItemImpl> const& item, |
1152 | 93 | QString const& method, | 93 | QString const& method, |
1153 | 94 | QDBusPendingReply<void> const& reply) | 94 | QDBusPendingReply<void> const& reply) |
1154 | 95 | { | 95 | { |
1155 | 96 | unique_ptr<VoidJobImpl> impl(new VoidJobImpl(item, method, reply)); | 96 | unique_ptr<VoidJobImpl> impl(new VoidJobImpl(item, method, reply)); |
1156 | 97 | auto job = new VoidJob(move(impl)); | 97 | auto job = new VoidJob(move(impl)); |
1157 | @@ -99,7 +99,7 @@ | |||
1158 | 99 | return job; | 99 | return job; |
1159 | 100 | } | 100 | } |
1160 | 101 | 101 | ||
1162 | 102 | VoidJob* VoidJobImpl::make_void_job(StorageError const& error) | 102 | VoidJob* VoidJobImpl::make_job(StorageError const& error) |
1163 | 103 | { | 103 | { |
1164 | 104 | unique_ptr<VoidJobImpl> impl(new VoidJobImpl(error)); | 104 | unique_ptr<VoidJobImpl> impl(new VoidJobImpl(error)); |
1165 | 105 | auto job = new VoidJob(move(impl)); | 105 | auto job = new VoidJob(move(impl)); |
1166 | 106 | 106 | ||
1167 | === modified file 'tests/provider-ProviderInterface/ProviderInterface_test.cpp' | |||
1168 | --- tests/provider-ProviderInterface/ProviderInterface_test.cpp 2016-09-26 02:37:03 +0000 | |||
1169 | +++ tests/provider-ProviderInterface/ProviderInterface_test.cpp 2016-10-10 01:18:55 +0000 | |||
1170 | @@ -91,7 +91,7 @@ | |||
1171 | 91 | EXPECT_EQ(1, reply.value().size()); | 91 | EXPECT_EQ(1, reply.value().size()); |
1172 | 92 | auto root = reply.value()[0]; | 92 | auto root = reply.value()[0]; |
1173 | 93 | EXPECT_EQ("root_id", root.item_id); | 93 | EXPECT_EQ("root_id", root.item_id); |
1175 | 94 | EXPECT_EQ(QVector<QString>(), root.parent_ids); | 94 | EXPECT_EQ(QList<QString>(), root.parent_ids); |
1176 | 95 | EXPECT_EQ("Root", root.name); | 95 | EXPECT_EQ("Root", root.name); |
1177 | 96 | EXPECT_EQ("etag", root.etag); | 96 | EXPECT_EQ("etag", root.etag); |
1178 | 97 | EXPECT_EQ(ItemType::root, root.type); | 97 | EXPECT_EQ(ItemType::root, root.type); |
1179 | @@ -146,7 +146,7 @@ | |||
1180 | 146 | ASSERT_EQ(1, items.size()); | 146 | ASSERT_EQ(1, items.size()); |
1181 | 147 | auto item = items[0]; | 147 | auto item = items[0]; |
1182 | 148 | EXPECT_EQ("child_id", item.item_id); | 148 | EXPECT_EQ("child_id", item.item_id); |
1184 | 149 | EXPECT_EQ(QVector<QString>{ "root_id"}, item.parent_ids); | 149 | EXPECT_EQ(QList<QString>{ "root_id"}, item.parent_ids); |
1185 | 150 | EXPECT_EQ("Filename", item.name); | 150 | EXPECT_EQ("Filename", item.name); |
1186 | 151 | EXPECT_EQ(ItemType::file, item.type); | 151 | EXPECT_EQ(ItemType::file, item.type); |
1187 | 152 | } | 152 | } |
1188 | @@ -160,7 +160,7 @@ | |||
1189 | 160 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); | 160 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); |
1190 | 161 | auto item = reply.value(); | 161 | auto item = reply.value(); |
1191 | 162 | EXPECT_EQ("root_id", item.item_id); | 162 | EXPECT_EQ("root_id", item.item_id); |
1193 | 163 | EXPECT_EQ(QVector<QString>(), item.parent_ids); | 163 | EXPECT_EQ(QList<QString>(), item.parent_ids); |
1194 | 164 | EXPECT_EQ("Root", item.name); | 164 | EXPECT_EQ("Root", item.name); |
1195 | 165 | EXPECT_EQ(ItemType::root, item.type); | 165 | EXPECT_EQ(ItemType::root, item.type); |
1196 | 166 | } | 166 | } |
1197 | @@ -174,7 +174,7 @@ | |||
1198 | 174 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); | 174 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); |
1199 | 175 | auto item = reply.value(); | 175 | auto item = reply.value(); |
1200 | 176 | EXPECT_EQ("new_folder_id", item.item_id); | 176 | EXPECT_EQ("new_folder_id", item.item_id); |
1202 | 177 | EXPECT_EQ(QVector<QString>{ "root_id" }, item.parent_ids); | 177 | EXPECT_EQ(QList<QString>{ "root_id" }, item.parent_ids); |
1203 | 178 | EXPECT_EQ("New Folder", item.name); | 178 | EXPECT_EQ("New Folder", item.name); |
1204 | 179 | EXPECT_EQ(ItemType::folder, item.type); | 179 | EXPECT_EQ(ItemType::folder, item.type); |
1205 | 180 | } | 180 | } |
1206 | @@ -224,7 +224,7 @@ | |||
1207 | 224 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); | 224 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); |
1208 | 225 | auto item = reply.value(); | 225 | auto item = reply.value(); |
1209 | 226 | EXPECT_EQ("new_file_id", item.item_id); | 226 | EXPECT_EQ("new_file_id", item.item_id); |
1211 | 227 | EXPECT_EQ(QVector<QString>{ "parent_id" }, item.parent_ids); | 227 | EXPECT_EQ(QList<QString>{ "parent_id" }, item.parent_ids); |
1212 | 228 | EXPECT_EQ("file name", item.name); | 228 | EXPECT_EQ("file name", item.name); |
1213 | 229 | } | 229 | } |
1214 | 230 | 230 | ||
1215 | @@ -761,7 +761,7 @@ | |||
1216 | 761 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); | 761 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); |
1217 | 762 | auto item = reply.value(); | 762 | auto item = reply.value(); |
1218 | 763 | EXPECT_EQ("child_id", item.item_id); | 763 | EXPECT_EQ("child_id", item.item_id); |
1220 | 764 | EXPECT_EQ(QVector<QString>{ "new_parent_id" }, item.parent_ids); | 764 | EXPECT_EQ(QList<QString>{ "new_parent_id" }, item.parent_ids); |
1221 | 765 | EXPECT_EQ("New name", item.name); | 765 | EXPECT_EQ("New name", item.name); |
1222 | 766 | EXPECT_EQ(ItemType::file, item.type); | 766 | EXPECT_EQ(ItemType::file, item.type); |
1223 | 767 | } | 767 | } |
1224 | @@ -775,7 +775,7 @@ | |||
1225 | 775 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); | 775 | ASSERT_TRUE(reply.isValid()) << reply.error().message().toStdString(); |
1226 | 776 | auto item = reply.value(); | 776 | auto item = reply.value(); |
1227 | 777 | EXPECT_EQ("new_id", item.item_id); | 777 | EXPECT_EQ("new_id", item.item_id); |
1229 | 778 | EXPECT_EQ(QVector<QString>{ "new_parent_id" }, item.parent_ids); | 778 | EXPECT_EQ(QList<QString>{ "new_parent_id" }, item.parent_ids); |
1230 | 779 | EXPECT_EQ("New name", item.name); | 779 | EXPECT_EQ("New name", item.name); |
1231 | 780 | EXPECT_EQ(ItemType::file, item.type); | 780 | EXPECT_EQ(ItemType::file, item.type); |
1232 | 781 | } | 781 | } |
1233 | 782 | 782 | ||
1234 | === modified file 'tests/remote-client/MockProvider.cpp' | |||
1235 | --- tests/remote-client/MockProvider.cpp 2016-09-26 08:57:05 +0000 | |||
1236 | +++ tests/remote-client/MockProvider.cpp 2016-10-10 01:18:55 +0000 | |||
1237 | @@ -58,6 +58,11 @@ | |||
1238 | 58 | }; | 58 | }; |
1239 | 59 | return make_ready_future<ItemList>(roots); | 59 | return make_ready_future<ItemList>(roots); |
1240 | 60 | } | 60 | } |
1241 | 61 | if (cmd_ == "roots_throw") | ||
1242 | 62 | { | ||
1243 | 63 | string msg = "roots(): I'm sorry Dave, I'm afraid I can't do that."; | ||
1244 | 64 | return make_exceptional_future<ItemList>(PermissionException(msg)); | ||
1245 | 65 | } | ||
1246 | 61 | 66 | ||
1247 | 62 | ItemList roots = | 67 | ItemList roots = |
1248 | 63 | { | 68 | { |
1249 | @@ -115,6 +120,8 @@ | |||
1250 | 115 | 120 | ||
1251 | 116 | boost::future<Item> MockProvider::metadata(string const& item_id, Context const&) | 121 | boost::future<Item> MockProvider::metadata(string const& item_id, Context const&) |
1252 | 117 | { | 122 | { |
1253 | 123 | static int num_calls = 0; | ||
1254 | 124 | |||
1255 | 118 | if (cmd_ == "slow_metadata") | 125 | if (cmd_ == "slow_metadata") |
1256 | 119 | { | 126 | { |
1257 | 120 | this_thread::sleep_for(chrono::seconds(1)); | 127 | this_thread::sleep_for(chrono::seconds(1)); |
1258 | @@ -124,13 +131,47 @@ | |||
1259 | 124 | Item metadata{"", {}, "Root", "etag", ItemType::root, {}}; | 131 | Item metadata{"", {}, "Root", "etag", ItemType::root, {}}; |
1260 | 125 | return make_ready_future<Item>(metadata); | 132 | return make_ready_future<Item>(metadata); |
1261 | 126 | } | 133 | } |
1262 | 134 | if (cmd_== "two_parents_throw") | ||
1263 | 135 | { | ||
1264 | 136 | ++num_calls; | ||
1265 | 137 | switch (num_calls) | ||
1266 | 138 | { | ||
1267 | 139 | case 3: | ||
1268 | 140 | return make_exceptional_future<Item>(ResourceException("metadata(): weird error", 42)); | ||
1269 | 141 | case 4: | ||
1270 | 142 | num_calls = 0; | ||
1271 | 143 | return make_exceptional_future<Item>(RemoteCommsException("metadata(): HTTP broken")); | ||
1272 | 144 | default: | ||
1273 | 145 | break; | ||
1274 | 146 | } | ||
1275 | 147 | } | ||
1276 | 127 | if (item_id == "root_id") | 148 | if (item_id == "root_id") |
1277 | 128 | { | 149 | { |
1278 | 150 | if (cmd_ == "bad_parent_metadata_from_child") | ||
1279 | 151 | { | ||
1280 | 152 | ++num_calls; | ||
1281 | 153 | if (num_calls == 2) | ||
1282 | 154 | { | ||
1283 | 155 | num_calls = 0; | ||
1284 | 156 | // On second call, we return type file for the root. | ||
1285 | 157 | Item metadata{"root_id", {}, "Root", "etag", ItemType::file, {}}; | ||
1286 | 158 | return make_ready_future<Item>(metadata); | ||
1287 | 159 | } | ||
1288 | 160 | } | ||
1289 | 129 | Item metadata{"root_id", {}, "Root", "etag", ItemType::root, {}}; | 161 | Item metadata{"root_id", {}, "Root", "etag", ItemType::root, {}}; |
1290 | 130 | return make_ready_future<Item>(metadata); | 162 | return make_ready_future<Item>(metadata); |
1291 | 131 | } | 163 | } |
1293 | 132 | else if (item_id == "child_id") | 164 | if (item_id == "child_id") |
1294 | 133 | { | 165 | { |
1295 | 166 | if (cmd_ == "two_parents" || cmd_ == "two_parents_throw") | ||
1296 | 167 | { | ||
1297 | 168 | Item metadata | ||
1298 | 169 | { | ||
1299 | 170 | "child_id", { "root_id", "child_folder_id" }, "Child", "etag", ItemType::file, | ||
1300 | 171 | { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } } | ||
1301 | 172 | }; | ||
1302 | 173 | return make_ready_future<Item>(metadata); | ||
1303 | 174 | } | ||
1304 | 134 | Item metadata | 175 | Item metadata |
1305 | 135 | { | 176 | { |
1306 | 136 | "child_id", { "root_id" }, "Child", "etag", ItemType::file, | 177 | "child_id", { "root_id" }, "Child", "etag", ItemType::file, |
1307 | @@ -138,7 +179,7 @@ | |||
1308 | 138 | }; | 179 | }; |
1309 | 139 | return make_ready_future<Item>(metadata); | 180 | return make_ready_future<Item>(metadata); |
1310 | 140 | } | 181 | } |
1312 | 141 | else if (item_id == "child_folder_id") | 182 | if (item_id == "child_folder_id") |
1313 | 142 | { | 183 | { |
1314 | 143 | Item metadata{"child_folder_id", { "root_id" }, "Child_Folder", "etag", ItemType::folder, {}}; | 184 | Item metadata{"child_folder_id", { "root_id" }, "Child_Folder", "etag", ItemType::folder, {}}; |
1315 | 144 | return make_ready_future<Item>(metadata); | 185 | return make_ready_future<Item>(metadata); |
1316 | 145 | 186 | ||
1317 | === modified file 'tests/remote-client/remote-client_test.cpp' | |||
1318 | --- tests/remote-client/remote-client_test.cpp 2016-09-29 13:09:00 +0000 | |||
1319 | +++ tests/remote-client/remote-client_test.cpp 2016-10-10 01:18:55 +0000 | |||
1320 | @@ -58,6 +58,7 @@ | |||
1321 | 58 | class DeleteTest : public RemoteClientTest {}; | 58 | class DeleteTest : public RemoteClientTest {}; |
1322 | 59 | class GetTest : public RemoteClientTest {}; | 59 | class GetTest : public RemoteClientTest {}; |
1323 | 60 | class ItemTest : public RemoteClientTest {}; | 60 | class ItemTest : public RemoteClientTest {}; |
1324 | 61 | class ParentsTest : public RemoteClientTest {}; | ||
1325 | 61 | class RootsTest : public RemoteClientTest {}; | 62 | class RootsTest : public RemoteClientTest {}; |
1326 | 62 | class RuntimeTest : public ProviderFixture {}; | 63 | class RuntimeTest : public ProviderFixture {}; |
1327 | 63 | 64 | ||
1328 | @@ -397,7 +398,7 @@ | |||
1329 | 397 | EXPECT_EQ("root_id", root.itemId()); | 398 | EXPECT_EQ("root_id", root.itemId()); |
1330 | 398 | EXPECT_EQ("Root", root.name()); | 399 | EXPECT_EQ("Root", root.name()); |
1331 | 399 | EXPECT_EQ("etag", root.etag()); | 400 | EXPECT_EQ("etag", root.etag()); |
1333 | 400 | EXPECT_EQ(QVector<QString>(), root.parentIds()); | 401 | EXPECT_EQ(QList<QString>(), root.parentIds()); |
1334 | 401 | EXPECT_FALSE(root.lastModifiedTime().isValid()); | 402 | EXPECT_FALSE(root.lastModifiedTime().isValid()); |
1335 | 402 | EXPECT_EQ(acc_, root.account()); | 403 | EXPECT_EQ(acc_, root.account()); |
1336 | 403 | } | 404 | } |
1337 | @@ -441,6 +442,46 @@ | |||
1338 | 441 | EXPECT_EQ("Account::roots(): Runtime was destroyed previously", j->error().message()); | 442 | EXPECT_EQ("Account::roots(): Runtime was destroyed previously", j->error().message()); |
1339 | 442 | } | 443 | } |
1340 | 443 | 444 | ||
1341 | 445 | TEST_F(RootsTest, invalid_account) | ||
1342 | 446 | { | ||
1343 | 447 | Account a; | ||
1344 | 448 | unique_ptr<ItemListJob> j(a.roots()); | ||
1345 | 449 | EXPECT_FALSE(j->isValid()); | ||
1346 | 450 | EXPECT_EQ(ItemListJob::Error, j->status()); | ||
1347 | 451 | EXPECT_EQ(StorageError::LogicError, j->error().type()); | ||
1348 | 452 | EXPECT_EQ("Account::roots(): cannot create job from invalid account", j->error().message()); | ||
1349 | 453 | |||
1350 | 454 | // Signal must be received. | ||
1351 | 455 | QSignalSpy spy(j.get(), &ItemListJob::statusChanged); | ||
1352 | 456 | spy.wait(SIGNAL_WAIT_TIME); | ||
1353 | 457 | ASSERT_EQ(1, spy.count()); | ||
1354 | 458 | auto arg = spy.takeFirst(); | ||
1355 | 459 | EXPECT_EQ(ItemListJob::Error, qvariant_cast<ItemListJob::Status>(arg.at(0))); | ||
1356 | 460 | |||
1357 | 461 | EXPECT_EQ("Account::roots(): cannot create job from invalid account", j->error().message()); | ||
1358 | 462 | } | ||
1359 | 463 | |||
1360 | 464 | TEST_F(RootsTest, exception) | ||
1361 | 465 | { | ||
1362 | 466 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("roots_throw"))); | ||
1363 | 467 | |||
1364 | 468 | unique_ptr<ItemListJob> j(acc_.roots()); | ||
1365 | 469 | EXPECT_TRUE(j->isValid()); | ||
1366 | 470 | EXPECT_EQ(ItemListJob::Loading, j->status()); | ||
1367 | 471 | EXPECT_EQ(StorageError::NoError, j->error().type()); | ||
1368 | 472 | EXPECT_EQ("No error", j->error().message()); | ||
1369 | 473 | |||
1370 | 474 | QSignalSpy spy(j.get(), &ItemListJob::statusChanged); | ||
1371 | 475 | spy.wait(SIGNAL_WAIT_TIME); | ||
1372 | 476 | ASSERT_EQ(1, spy.count()); | ||
1373 | 477 | auto arg = spy.takeFirst(); | ||
1374 | 478 | EXPECT_EQ(ItemListJob::Error, qvariant_cast<ItemListJob::Status>(arg.at(0))); | ||
1375 | 479 | |||
1376 | 480 | EXPECT_EQ(ItemListJob::Error, j->status()); | ||
1377 | 481 | EXPECT_EQ(StorageError::PermissionDenied, j->error().type()); | ||
1378 | 482 | EXPECT_EQ("PermissionDenied: roots(): I'm sorry Dave, I'm afraid I can't do that.", j->error().errorString()); | ||
1379 | 483 | } | ||
1380 | 484 | |||
1381 | 444 | TEST_F(RootsTest, not_a_root) | 485 | TEST_F(RootsTest, not_a_root) |
1382 | 445 | { | 486 | { |
1383 | 446 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("not_a_root"))); | 487 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("not_a_root"))); |
1384 | @@ -534,6 +575,25 @@ | |||
1385 | 534 | EXPECT_EQ("Account::get(): Runtime was destroyed previously", j->error().message()); | 575 | EXPECT_EQ("Account::get(): Runtime was destroyed previously", j->error().message()); |
1386 | 535 | } | 576 | } |
1387 | 536 | 577 | ||
1388 | 578 | TEST_F(GetTest, invalid_account) | ||
1389 | 579 | { | ||
1390 | 580 | Account a; | ||
1391 | 581 | unique_ptr<ItemJob> j(a.get("child_Id")); | ||
1392 | 582 | EXPECT_FALSE(j->isValid()); | ||
1393 | 583 | EXPECT_EQ(ItemJob::Error, j->status()); | ||
1394 | 584 | EXPECT_EQ(StorageError::LogicError, j->error().type()); | ||
1395 | 585 | EXPECT_EQ("Account::get(): cannot create job from invalid account", j->error().message()); | ||
1396 | 586 | |||
1397 | 587 | // Signal must be received. | ||
1398 | 588 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1399 | 589 | spy.wait(SIGNAL_WAIT_TIME); | ||
1400 | 590 | ASSERT_EQ(1, spy.count()); | ||
1401 | 591 | auto arg = spy.takeFirst(); | ||
1402 | 592 | EXPECT_EQ(ItemJob::Error, qvariant_cast<ItemJob::Status>(arg.at(0))); | ||
1403 | 593 | |||
1404 | 594 | EXPECT_EQ("Account::get(): cannot create job from invalid account", j->error().message()); | ||
1405 | 595 | } | ||
1406 | 596 | |||
1407 | 537 | TEST_F(GetTest, empty_id_from_provider) | 597 | TEST_F(GetTest, empty_id_from_provider) |
1408 | 538 | { | 598 | { |
1409 | 539 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("empty_id"))); | 599 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("empty_id"))); |
1410 | @@ -704,6 +764,25 @@ | |||
1411 | 704 | EXPECT_EQ("Item::deleteItem(): Runtime was destroyed previously", j->error().message()) << j->error().message().toStdString(); | 764 | EXPECT_EQ("Item::deleteItem(): Runtime was destroyed previously", j->error().message()) << j->error().message().toStdString(); |
1412 | 705 | } | 765 | } |
1413 | 706 | 766 | ||
1414 | 767 | TEST_F(DeleteTest, invalid_item) | ||
1415 | 768 | { | ||
1416 | 769 | Item i; | ||
1417 | 770 | unique_ptr<VoidJob> j(i.deleteItem()); | ||
1418 | 771 | EXPECT_FALSE(j->isValid()); | ||
1419 | 772 | EXPECT_EQ(VoidJob::Error, j->status()); | ||
1420 | 773 | EXPECT_EQ(StorageError::LogicError, j->error().type()); | ||
1421 | 774 | EXPECT_EQ("Item::deleteItem(): cannot create job from invalid item", j->error().message()); | ||
1422 | 775 | |||
1423 | 776 | // Signal must be received. | ||
1424 | 777 | QSignalSpy spy(j.get(), &unity::storage::qt::VoidJob::statusChanged); | ||
1425 | 778 | spy.wait(SIGNAL_WAIT_TIME); | ||
1426 | 779 | ASSERT_EQ(1, spy.count()); | ||
1427 | 780 | auto arg = spy.takeFirst(); | ||
1428 | 781 | EXPECT_EQ(VoidJob::Error, qvariant_cast<VoidJob::Status>(arg.at(0))); | ||
1429 | 782 | |||
1430 | 783 | EXPECT_EQ("Item::deleteItem(): cannot create job from invalid item", j->error().message()); | ||
1431 | 784 | } | ||
1432 | 785 | |||
1433 | 707 | #if 0 | 786 | #if 0 |
1434 | 708 | // TODO: need to make internal symbols available for testing. | 787 | // TODO: need to make internal symbols available for testing. |
1435 | 709 | TEST_F(ValidateTest, basic) | 788 | TEST_F(ValidateTest, basic) |
1436 | @@ -716,6 +795,112 @@ | |||
1437 | 716 | } | 795 | } |
1438 | 717 | #endif | 796 | #endif |
1439 | 718 | 797 | ||
1440 | 798 | TEST_F(ItemTest, basic) | ||
1441 | 799 | { | ||
1442 | 800 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); | ||
1443 | 801 | |||
1444 | 802 | { | ||
1445 | 803 | // Default constructor. | ||
1446 | 804 | Item i; | ||
1447 | 805 | EXPECT_FALSE(i.isValid()); | ||
1448 | 806 | EXPECT_EQ("", i.itemId()); | ||
1449 | 807 | EXPECT_EQ("", i.name()); | ||
1450 | 808 | EXPECT_EQ("", i.etag()); | ||
1451 | 809 | EXPECT_EQ(Item::File, i.type()); | ||
1452 | 810 | auto mtime = i.lastModifiedTime(); | ||
1453 | 811 | EXPECT_FALSE(mtime.isValid()); | ||
1454 | 812 | auto pids = i.parentIds(); | ||
1455 | 813 | EXPECT_EQ(0, pids.size()); | ||
1456 | 814 | } | ||
1457 | 815 | |||
1458 | 816 | { | ||
1459 | 817 | unique_ptr<ItemJob> j(acc_.get("child_id")); | ||
1460 | 818 | |||
1461 | 819 | { | ||
1462 | 820 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1463 | 821 | spy.wait(SIGNAL_WAIT_TIME); | ||
1464 | 822 | } | ||
1465 | 823 | Item i = j->item(); | ||
1466 | 824 | EXPECT_TRUE(i.isValid()); | ||
1467 | 825 | EXPECT_EQ("child_id", i.itemId()); | ||
1468 | 826 | EXPECT_EQ("Child", i.name()); | ||
1469 | 827 | EXPECT_TRUE(i.account().isValid()); | ||
1470 | 828 | EXPECT_EQ("etag", i.etag()); | ||
1471 | 829 | EXPECT_EQ(Item::File, i.type()); | ||
1472 | 830 | |||
1473 | 831 | // Copy constructor | ||
1474 | 832 | Item i2(i); | ||
1475 | 833 | EXPECT_EQ(i, i2); | ||
1476 | 834 | |||
1477 | 835 | // Move constructor | ||
1478 | 836 | Item i3(move(i2)); | ||
1479 | 837 | EXPECT_TRUE(i3.isValid()); | ||
1480 | 838 | EXPECT_EQ(i, i3); | ||
1481 | 839 | |||
1482 | 840 | // Moved-from object must be invalid | ||
1483 | 841 | EXPECT_FALSE(i2.isValid()); | ||
1484 | 842 | |||
1485 | 843 | // Moved-from object must be assignable | ||
1486 | 844 | j.reset(acc_.get("child_id")); | ||
1487 | 845 | { | ||
1488 | 846 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1489 | 847 | spy.wait(SIGNAL_WAIT_TIME); | ||
1490 | 848 | } | ||
1491 | 849 | auto i4 = j->item(); | ||
1492 | 850 | i2 = i4; | ||
1493 | 851 | EXPECT_EQ(i4, i2); | ||
1494 | 852 | } | ||
1495 | 853 | |||
1496 | 854 | { | ||
1497 | 855 | unique_ptr<ItemJob> j1(acc_.get("child_id")); | ||
1498 | 856 | unique_ptr<ItemJob> j2(acc_.get("root_id")); | ||
1499 | 857 | |||
1500 | 858 | QSignalSpy spy1(j1.get(), &ItemJob::statusChanged); | ||
1501 | 859 | QSignalSpy spy2(j2.get(), &ItemJob::statusChanged); | ||
1502 | 860 | spy2.wait(SIGNAL_WAIT_TIME); | ||
1503 | 861 | ASSERT_EQ(1, spy1.count()); | ||
1504 | 862 | |||
1505 | 863 | auto i1 = j1->item(); | ||
1506 | 864 | auto i2 = j2->item(); | ||
1507 | 865 | |||
1508 | 866 | // Copy assignment | ||
1509 | 867 | i1 = i2; | ||
1510 | 868 | EXPECT_TRUE(i2.isValid()); | ||
1511 | 869 | EXPECT_EQ(i2, i1); | ||
1512 | 870 | |||
1513 | 871 | // Self-assignment | ||
1514 | 872 | i2 = i2; | ||
1515 | 873 | EXPECT_TRUE(i2.isValid()); | ||
1516 | 874 | EXPECT_EQ("root_id", i2.itemId()); | ||
1517 | 875 | EXPECT_EQ("Root", i2.name()); | ||
1518 | 876 | EXPECT_TRUE(i2.account().isValid()); | ||
1519 | 877 | EXPECT_EQ("etag", i2.etag()); | ||
1520 | 878 | EXPECT_EQ(Item::Root, i2.type()); | ||
1521 | 879 | |||
1522 | 880 | // Move assignment | ||
1523 | 881 | unique_ptr<ItemJob> j3(acc_.get("child_folder_id")); | ||
1524 | 882 | QSignalSpy spy(j3.get(), &ItemJob::statusChanged); | ||
1525 | 883 | spy.wait(SIGNAL_WAIT_TIME); | ||
1526 | 884 | ASSERT_EQ(1, spy1.count()); | ||
1527 | 885 | |||
1528 | 886 | auto i3 = j3->item(); | ||
1529 | 887 | |||
1530 | 888 | i1 = move(i3); | ||
1531 | 889 | EXPECT_TRUE(i1.isValid()); | ||
1532 | 890 | EXPECT_EQ("child_folder_id", i1.itemId()); | ||
1533 | 891 | EXPECT_EQ("Child_Folder", i1.name()); | ||
1534 | 892 | EXPECT_EQ(i1.account(), i1.account()); | ||
1535 | 893 | EXPECT_EQ("etag", i1.etag()); | ||
1536 | 894 | EXPECT_EQ(Item::Folder, i1.type()); | ||
1537 | 895 | |||
1538 | 896 | // Moved-from object must be invalid | ||
1539 | 897 | EXPECT_FALSE(i3.isValid()); | ||
1540 | 898 | |||
1541 | 899 | // Moved-from object must be assignable | ||
1542 | 900 | i3 = i2; | ||
1543 | 901 | EXPECT_EQ(i2, i3); | ||
1544 | 902 | } | ||
1545 | 903 | } | ||
1546 | 719 | 904 | ||
1547 | 720 | TEST_F(ItemTest, comparison_and_hash) | 905 | TEST_F(ItemTest, comparison_and_hash) |
1548 | 721 | { | 906 | { |
1549 | @@ -851,6 +1036,292 @@ | |||
1550 | 851 | } | 1036 | } |
1551 | 852 | } | 1037 | } |
1552 | 853 | 1038 | ||
1553 | 1039 | TEST_F(ParentsTest, basic) | ||
1554 | 1040 | { | ||
1555 | 1041 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); | ||
1556 | 1042 | |||
1557 | 1043 | Item root; | ||
1558 | 1044 | { | ||
1559 | 1045 | unique_ptr<ItemJob> j(acc_.get("root_id")); | ||
1560 | 1046 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1561 | 1047 | spy.wait(SIGNAL_WAIT_TIME); | ||
1562 | 1048 | root = j->item(); | ||
1563 | 1049 | } | ||
1564 | 1050 | |||
1565 | 1051 | { | ||
1566 | 1052 | // Getting parents from root does not call the provider and returns | ||
1567 | 1053 | // no parents immediately. | ||
1568 | 1054 | unique_ptr<ItemListJob> j(root.parents()); | ||
1569 | 1055 | EXPECT_TRUE(j->isValid()); | ||
1570 | 1056 | EXPECT_EQ(ItemListJob::Finished, j->status()); | ||
1571 | 1057 | EXPECT_EQ(StorageError::NoError, j->error().type()); | ||
1572 | 1058 | |||
1573 | 1059 | // Signal must be received. | ||
1574 | 1060 | QSignalSpy spy(j.get(), &ItemListJob::statusChanged); | ||
1575 | 1061 | spy.wait(SIGNAL_WAIT_TIME); | ||
1576 | 1062 | ASSERT_EQ(1, spy.count()); | ||
1577 | 1063 | auto arg = spy.takeFirst(); | ||
1578 | 1064 | EXPECT_EQ(ItemListJob::Finished, qvariant_cast<ItemListJob::Status>(arg.at(0))); | ||
1579 | 1065 | } | ||
1580 | 1066 | |||
1581 | 1067 | Item child; | ||
1582 | 1068 | { | ||
1583 | 1069 | unique_ptr<ItemJob> j(acc_.get("child_id")); | ||
1584 | 1070 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1585 | 1071 | spy.wait(SIGNAL_WAIT_TIME); | ||
1586 | 1072 | child = j->item(); | ||
1587 | 1073 | } | ||
1588 | 1074 | |||
1589 | 1075 | QList<Item> parents; | ||
1590 | 1076 | { | ||
1591 | 1077 | unique_ptr<ItemListJob> j(child.parents()); | ||
1592 | 1078 | EXPECT_TRUE(j->isValid()); | ||
1593 | 1079 | EXPECT_EQ(ItemListJob::Loading, j->status()); | ||
1594 | 1080 | EXPECT_EQ(StorageError::NoError, j->error().type()); | ||
1595 | 1081 | |||
1596 | 1082 | QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady); | ||
1597 | 1083 | QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged); | ||
1598 | 1084 | ready_spy.wait(SIGNAL_WAIT_TIME); | ||
1599 | 1085 | ASSERT_EQ(1, ready_spy.count()); | ||
1600 | 1086 | auto list_arg = ready_spy.takeFirst(); | ||
1601 | 1087 | parents = qvariant_cast<QList<Item>>(list_arg.at(0)); | ||
1602 | 1088 | |||
1603 | 1089 | // When the signal for the final item arrives, status must be Finished. | ||
1604 | 1090 | EXPECT_EQ(ItemListJob::Finished, j->status()); | ||
1605 | 1091 | |||
1606 | 1092 | // Finished signal must be received. | ||
1607 | 1093 | if (status_spy.count() == 0) | ||
1608 | 1094 | { | ||
1609 | 1095 | status_spy.wait(SIGNAL_WAIT_TIME); | ||
1610 | 1096 | } | ||
1611 | 1097 | ASSERT_EQ(1, status_spy.count()); | ||
1612 | 1098 | auto status_arg = status_spy.takeFirst(); | ||
1613 | 1099 | EXPECT_EQ(ItemListJob::Finished, qvariant_cast<ItemListJob::Status>(status_arg.at(0))); | ||
1614 | 1100 | |||
1615 | 1101 | // Child must have one parent, namely the root. | ||
1616 | 1102 | ASSERT_EQ(1, parents.size()); | ||
1617 | 1103 | EXPECT_EQ(root, parents[0]); | ||
1618 | 1104 | } | ||
1619 | 1105 | } | ||
1620 | 1106 | |||
1621 | 1107 | TEST_F(ParentsTest, two_parents) | ||
1622 | 1108 | { | ||
1623 | 1109 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("two_parents"))); | ||
1624 | 1110 | |||
1625 | 1111 | Item root; | ||
1626 | 1112 | { | ||
1627 | 1113 | unique_ptr<ItemJob> j(acc_.get("root_id")); | ||
1628 | 1114 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1629 | 1115 | spy.wait(SIGNAL_WAIT_TIME); | ||
1630 | 1116 | root = j->item(); | ||
1631 | 1117 | } | ||
1632 | 1118 | |||
1633 | 1119 | Item child; | ||
1634 | 1120 | { | ||
1635 | 1121 | unique_ptr<ItemJob> j(acc_.get("child_id")); | ||
1636 | 1122 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1637 | 1123 | spy.wait(SIGNAL_WAIT_TIME); | ||
1638 | 1124 | child = j->item(); | ||
1639 | 1125 | } | ||
1640 | 1126 | |||
1641 | 1127 | QList<Item> parents; | ||
1642 | 1128 | { | ||
1643 | 1129 | unique_ptr<ItemListJob> j(child.parents()); | ||
1644 | 1130 | EXPECT_TRUE(j->isValid()); | ||
1645 | 1131 | |||
1646 | 1132 | QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady); | ||
1647 | 1133 | QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged); | ||
1648 | 1134 | |||
1649 | 1135 | ready_spy.wait(SIGNAL_WAIT_TIME); | ||
1650 | 1136 | auto list_arg = ready_spy.takeFirst(); | ||
1651 | 1137 | auto this_parent = qvariant_cast<QList<Item>>(list_arg.at(0)); | ||
1652 | 1138 | parents.append(this_parent); | ||
1653 | 1139 | while (ready_spy.count() < 1) | ||
1654 | 1140 | { | ||
1655 | 1141 | ready_spy.wait(SIGNAL_WAIT_TIME); | ||
1656 | 1142 | } | ||
1657 | 1143 | list_arg = ready_spy.takeFirst(); | ||
1658 | 1144 | this_parent = qvariant_cast<QList<Item>>(list_arg.at(0)); | ||
1659 | 1145 | parents.append(this_parent); | ||
1660 | 1146 | |||
1661 | 1147 | // Finished signal must be received. | ||
1662 | 1148 | if (status_spy.count() == 0) | ||
1663 | 1149 | { | ||
1664 | 1150 | status_spy.wait(SIGNAL_WAIT_TIME); | ||
1665 | 1151 | } | ||
1666 | 1152 | ASSERT_EQ(1, status_spy.count()); | ||
1667 | 1153 | auto status_arg = status_spy.takeFirst(); | ||
1668 | 1154 | EXPECT_EQ(ItemListJob::Finished, qvariant_cast<ItemListJob::Status>(status_arg.at(0))); | ||
1669 | 1155 | |||
1670 | 1156 | // Child must have two parents. | ||
1671 | 1157 | ASSERT_EQ(2, parents.size()); | ||
1672 | 1158 | EXPECT_EQ("root_id", parents[0].itemId()); | ||
1673 | 1159 | EXPECT_EQ("child_folder_id", parents[1].itemId()); | ||
1674 | 1160 | } | ||
1675 | 1161 | } | ||
1676 | 1162 | |||
1677 | 1163 | TEST_F(ParentsTest, two_parents_throw) | ||
1678 | 1164 | { | ||
1679 | 1165 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("two_parents_throw"))); | ||
1680 | 1166 | |||
1681 | 1167 | Item root; | ||
1682 | 1168 | { | ||
1683 | 1169 | unique_ptr<ItemJob> j(acc_.get("root_id")); | ||
1684 | 1170 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1685 | 1171 | spy.wait(SIGNAL_WAIT_TIME); | ||
1686 | 1172 | root = j->item(); | ||
1687 | 1173 | } | ||
1688 | 1174 | |||
1689 | 1175 | Item child; | ||
1690 | 1176 | { | ||
1691 | 1177 | unique_ptr<ItemJob> j(acc_.get("child_id")); | ||
1692 | 1178 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1693 | 1179 | spy.wait(SIGNAL_WAIT_TIME); | ||
1694 | 1180 | child = j->item(); | ||
1695 | 1181 | } | ||
1696 | 1182 | |||
1697 | 1183 | QList<Item> parents; | ||
1698 | 1184 | { | ||
1699 | 1185 | unique_ptr<ItemListJob> j(child.parents()); | ||
1700 | 1186 | EXPECT_TRUE(j->isValid()); | ||
1701 | 1187 | |||
1702 | 1188 | QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged); | ||
1703 | 1189 | QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady); | ||
1704 | 1190 | |||
1705 | 1191 | status_spy.wait(SIGNAL_WAIT_TIME); | ||
1706 | 1192 | ASSERT_EQ(1, status_spy.count()); | ||
1707 | 1193 | auto status_arg = status_spy.takeFirst(); | ||
1708 | 1194 | EXPECT_EQ(ItemListJob::Error, qvariant_cast<ItemListJob::Status>(status_arg.at(0))); | ||
1709 | 1195 | EXPECT_EQ(StorageError::ResourceError, j->error().type()); | ||
1710 | 1196 | EXPECT_EQ("ResourceError: metadata(): weird error", j->error().errorString()); | ||
1711 | 1197 | EXPECT_EQ(42, j->error().errorCode()); | ||
1712 | 1198 | |||
1713 | 1199 | // We wait here to allow the error return for the second parent to arrive in MultiItemJobImpl. | ||
1714 | 1200 | // This gives us coverage on the early return in the process_error lambda, when the job is | ||
1715 | 1201 | // already in the error state. | ||
1716 | 1202 | EXPECT_FALSE(ready_spy.wait(1000)); | ||
1717 | 1203 | } | ||
1718 | 1204 | } | ||
1719 | 1205 | |||
1720 | 1206 | TEST_F(ParentsTest, invalid_item) | ||
1721 | 1207 | { | ||
1722 | 1208 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); | ||
1723 | 1209 | |||
1724 | 1210 | Item invalid; | ||
1725 | 1211 | unique_ptr<ItemListJob> j(invalid.parents()); | ||
1726 | 1212 | EXPECT_FALSE(j->isValid()); | ||
1727 | 1213 | EXPECT_EQ(ItemListJob::Error, j->status()); | ||
1728 | 1214 | EXPECT_EQ(StorageError::LogicError, j->error().type()); | ||
1729 | 1215 | EXPECT_EQ("Item::parents(): cannot create job from invalid item", j->error().message()); | ||
1730 | 1216 | |||
1731 | 1217 | // Signal must be received. | ||
1732 | 1218 | QSignalSpy spy(j.get(), &ItemListJob::statusChanged); | ||
1733 | 1219 | spy.wait(SIGNAL_WAIT_TIME); | ||
1734 | 1220 | ASSERT_EQ(1, spy.count()); | ||
1735 | 1221 | auto arg = spy.takeFirst(); | ||
1736 | 1222 | EXPECT_EQ(ItemListJob::Error, qvariant_cast<ItemListJob::Status>(arg.at(0))); | ||
1737 | 1223 | } | ||
1738 | 1224 | |||
1739 | 1225 | TEST_F(ParentsTest, runtime_destroyed) | ||
1740 | 1226 | { | ||
1741 | 1227 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider())); | ||
1742 | 1228 | |||
1743 | 1229 | Item root; | ||
1744 | 1230 | { | ||
1745 | 1231 | unique_ptr<ItemJob> j(acc_.get("root_id")); | ||
1746 | 1232 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1747 | 1233 | spy.wait(SIGNAL_WAIT_TIME); | ||
1748 | 1234 | root = j->item(); | ||
1749 | 1235 | } | ||
1750 | 1236 | |||
1751 | 1237 | EXPECT_EQ(StorageError::NoError, runtime_->shutdown().type()); // Destroy runtime. | ||
1752 | 1238 | |||
1753 | 1239 | unique_ptr<ItemListJob> j(root.parents()); | ||
1754 | 1240 | EXPECT_FALSE(j->isValid()); | ||
1755 | 1241 | EXPECT_EQ(ItemJob::Error, j->status()); | ||
1756 | 1242 | EXPECT_EQ(StorageError::RuntimeDestroyed, j->error().type()); | ||
1757 | 1243 | EXPECT_EQ("Item::parents(): Runtime was destroyed previously", j->error().message()); | ||
1758 | 1244 | |||
1759 | 1245 | // Signal must be received. | ||
1760 | 1246 | QSignalSpy spy(j.get(), &ItemListJob::statusChanged); | ||
1761 | 1247 | spy.wait(SIGNAL_WAIT_TIME); | ||
1762 | 1248 | auto arg = spy.takeFirst(); | ||
1763 | 1249 | EXPECT_EQ(ItemListJob::Error, qvariant_cast<ItemListJob::Status>(arg.at(0))); | ||
1764 | 1250 | |||
1765 | 1251 | EXPECT_EQ("Item::parents(): Runtime was destroyed previously", j->error().message()); | ||
1766 | 1252 | } | ||
1767 | 1253 | |||
1768 | 1254 | TEST_F(ParentsTest, runtime_destroyed_while_item_list_job_running) | ||
1769 | 1255 | { | ||
1770 | 1256 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("slow_metadata"))); | ||
1771 | 1257 | |||
1772 | 1258 | Item root; | ||
1773 | 1259 | { | ||
1774 | 1260 | unique_ptr<ItemJob> j(acc_.get("root_id")); | ||
1775 | 1261 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1776 | 1262 | spy.wait(SIGNAL_WAIT_TIME); | ||
1777 | 1263 | root = j->item(); | ||
1778 | 1264 | } | ||
1779 | 1265 | |||
1780 | 1266 | Item child; | ||
1781 | 1267 | { | ||
1782 | 1268 | unique_ptr<ItemJob> j(acc_.get("child_id")); | ||
1783 | 1269 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1784 | 1270 | spy.wait(SIGNAL_WAIT_TIME); | ||
1785 | 1271 | child = j->item(); | ||
1786 | 1272 | } | ||
1787 | 1273 | |||
1788 | 1274 | unique_ptr<ItemListJob> j(child.parents()); | ||
1789 | 1275 | |||
1790 | 1276 | EXPECT_EQ(StorageError::NoError, runtime_->shutdown().type()); // Destroy runtime, provider still sleeping | ||
1791 | 1277 | |||
1792 | 1278 | // Signal must be received. | ||
1793 | 1279 | QSignalSpy spy(j.get(), &ItemListJob::statusChanged); | ||
1794 | 1280 | spy.wait(SIGNAL_WAIT_TIME); | ||
1795 | 1281 | ASSERT_EQ(1, spy.count()); | ||
1796 | 1282 | auto arg = spy.takeFirst(); | ||
1797 | 1283 | EXPECT_EQ(ItemListJob::Error, qvariant_cast<ItemListJob::Status>(arg.at(0))); | ||
1798 | 1284 | |||
1799 | 1285 | EXPECT_EQ("Item::parents(): Runtime was destroyed previously", j->error().message()); | ||
1800 | 1286 | } | ||
1801 | 1287 | |||
1802 | 1288 | TEST_F(ParentsTest, bad_metadata) | ||
1803 | 1289 | { | ||
1804 | 1290 | set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("bad_parent_metadata_from_child"))); | ||
1805 | 1291 | |||
1806 | 1292 | Item root; | ||
1807 | 1293 | { | ||
1808 | 1294 | unique_ptr<ItemJob> j(acc_.get("root_id")); | ||
1809 | 1295 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1810 | 1296 | spy.wait(SIGNAL_WAIT_TIME); | ||
1811 | 1297 | root = j->item(); | ||
1812 | 1298 | } | ||
1813 | 1299 | |||
1814 | 1300 | Item child; | ||
1815 | 1301 | { | ||
1816 | 1302 | unique_ptr<ItemJob> j(acc_.get("child_id")); | ||
1817 | 1303 | QSignalSpy spy(j.get(), &ItemJob::statusChanged); | ||
1818 | 1304 | spy.wait(SIGNAL_WAIT_TIME); | ||
1819 | 1305 | child = j->item(); | ||
1820 | 1306 | } | ||
1821 | 1307 | |||
1822 | 1308 | QList<Item> parents; | ||
1823 | 1309 | { | ||
1824 | 1310 | unique_ptr<ItemListJob> j(child.parents()); | ||
1825 | 1311 | EXPECT_TRUE(j->isValid()); | ||
1826 | 1312 | EXPECT_EQ(ItemListJob::Loading, j->status()); | ||
1827 | 1313 | EXPECT_EQ(StorageError::NoError, j->error().type()); | ||
1828 | 1314 | |||
1829 | 1315 | QSignalSpy spy(j.get(), &ItemListJob::statusChanged); | ||
1830 | 1316 | spy.wait(SIGNAL_WAIT_TIME); | ||
1831 | 1317 | ASSERT_EQ(1, spy.count()); | ||
1832 | 1318 | auto arg = spy.takeFirst(); | ||
1833 | 1319 | EXPECT_EQ(ItemListJob::Error, qvariant_cast<ItemListJob::Status>(arg.at(0))); | ||
1834 | 1320 | |||
1835 | 1321 | EXPECT_EQ("Item::parents(): provider returned a file as a parent", j->error().message()); | ||
1836 | 1322 | } | ||
1837 | 1323 | } | ||
1838 | 1324 | |||
1839 | 854 | #if 0 | 1325 | #if 0 |
1840 | 855 | TEST_F(RootTest, basic) | 1326 | TEST_F(RootTest, basic) |
1841 | 856 | { | 1327 | { |
PASSED: Continuous integration, rev:89 /jenkins. canonical. com/unity- api-1/job/ lp-storage- framework- ci/130/ /jenkins. canonical. com/unity- api-1/job/ build/781 /jenkins. canonical. com/unity- api-1/job/ build-0- fetch/787 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 595/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 595/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= yakkety/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= yakkety/ 595/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 595/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 595/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= yakkety/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= yakkety/ 595/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 595/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 595/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= yakkety/ 595 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= yakkety/ 595/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/unity- api-1/job/ lp-storage- framework- ci/130/ rebuild
https:/