Merge lp:~jamesh/storage-provider-webdav/client-v2-tests into lp:storage-provider-webdav/devel

Proposed by James Henstridge
Status: Merged
Approved by: Michi Henning
Approved revision: 25
Merged at revision: 22
Proposed branch: lp:~jamesh/storage-provider-webdav/client-v2-tests
Merge into: lp:storage-provider-webdav/devel
Diff against target: 1766 lines (+489/-931)
7 files modified
CMakeLists.txt (+1/-1)
debian/control (+1/-0)
src/DavProvider.cpp (+1/-0)
tests/CMakeLists.txt (+0/-6)
tests/davprovider/davprovider_test.cpp (+475/-915)
tests/utils/ProviderEnvironment.cpp (+5/-5)
tests/utils/ProviderEnvironment.h (+6/-4)
To merge this branch: bzr merge lp:~jamesh/storage-provider-webdav/client-v2-tests
Reviewer Review Type Date Requested Status
Michi Henning (community) Approve
unity-api-1-bot continuous-integration Approve
Review via email: mp+311787@code.launchpad.net

Commit message

Update the test suite to use the v2 client API.

Description of the change

Update the test suite to use the v2 client API.

To post a comment you must log in.
24. By James Henstridge

Trim 2 seconds off the test suite's run time by replacing sleeps with
explicit manipulation of file time stamps.

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

PASSED: Continuous integration, rev:24
https://jenkins.canonical.com/unity-api-1/job/lp-storage-provider-webdav-ci/34/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1160
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1167
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/954
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/954/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/954
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/954/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/954
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/954/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/954
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/954/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/954
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/954/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/954
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/954/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-provider-webdav-ci/34/rebuild

review: Approve (continuous-integration)
25. By James Henstridge

Don't bother trying to change cxx flags for GMock: the cmake-extras has
been doing this itself for ages now.

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

PASSED: Continuous integration, rev:25
https://jenkins.canonical.com/unity-api-1/job/lp-storage-provider-webdav-ci/35/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1163
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1170
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/956
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/956/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/956
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/956/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/956
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/956/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/956
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/956/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/956
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/956/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/956
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/956/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-provider-webdav-ci/35/rebuild

review: Approve (continuous-integration)
Revision history for this message
Michi Henning (michihenning) wrote :

Looks great!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-11-15 13:34:40 +0000
3+++ CMakeLists.txt 2016-11-25 04:11:48 +0000
4@@ -17,7 +17,7 @@
5 find_package(Qt5Test REQUIRED)
6 find_package(Qt5Xml REQUIRED)
7 pkg_check_modules(SF_PROVIDER REQUIRED storage-framework-provider-1>=0.2)
8-pkg_check_modules(SF_CLIENT REQUIRED storage-framework-qt-client-1)
9+pkg_check_modules(SF_CLIENT REQUIRED storage-framework-qt-client-2>=0.2)
10
11 add_definitions(-DQT_NO_KEYWORDS)
12
13
14=== modified file 'debian/control'
15--- debian/control 2016-11-18 04:34:55 +0000
16+++ debian/control 2016-11-25 04:11:48 +0000
17@@ -12,6 +12,7 @@
18 libgtest-dev,
19 libonline-accounts-qt-dev,
20 libqtdbustest1-dev,
21+ libstorage-framework-qt-client-2-0,
22 storage-framework-provider-dev (>= 0.2),
23 storage-framework-client-dev (>= 0.2),
24 php-cli | php5-cli <!nocheck>,
25
26=== modified file 'src/DavProvider.cpp'
27--- src/DavProvider.cpp 2016-11-18 04:34:55 +0000
28+++ src/DavProvider.cpp 2016-11-25 04:11:48 +0000
29@@ -240,6 +240,7 @@
30 {
31 item.type = ItemType::root;
32 item.name = "Root";
33+ item.parent_ids.clear();
34 }
35 return item;
36 }
37
38=== modified file 'tests/CMakeLists.txt'
39--- tests/CMakeLists.txt 2016-11-14 10:33:56 +0000
40+++ tests/CMakeLists.txt 2016-11-25 04:11:48 +0000
41@@ -1,10 +1,4 @@
42-# We add -g so we get debug info for the gtest stack frames with gdb.
43-# The warnings are suppressed so we get a noise-free build for gtest and gmock.
44-
45-set(old_cxx_flags ${CMAKE_CXX_FLAGS})
46-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wno-old-style-cast -Wno-missing-field-initializers")
47 find_package(GMock)
48-set(CMAKE_CXX_FLAGS ${old_cxx_flags})
49
50 configure_file(testsetup.h.in testsetup.h @ONLY)
51 include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
52
53=== modified file 'tests/davprovider/davprovider_test.cpp'
54--- tests/davprovider/davprovider_test.cpp 2016-11-24 06:31:11 +0000
55+++ tests/davprovider/davprovider_test.cpp 2016-11-25 04:11:48 +0000
56@@ -22,31 +22,31 @@
57 #include <utils/ProviderEnvironment.h>
58 #include <testsetup.h>
59
60+#include <gtest/gtest.h>
61 #include <QCoreApplication>
62-#include <QFutureWatcher>
63 #include <QNetworkAccessManager>
64 #include <QNetworkRequest>
65 #include <QSignalSpy>
66 #include <QTemporaryDir>
67 #include <QTimer>
68-#include <unity/storage/qt/client/Account.h>
69-#include <unity/storage/qt/client/Downloader.h>
70-#include <unity/storage/qt/client/Exceptions.h>
71-#include <unity/storage/qt/client/Root.h>
72-#include <unity/storage/qt/client/Uploader.h>
73-
74-#include <gtest/gtest.h>
75+#include <unity/storage/qt/Account.h>
76+#include <unity/storage/qt/Downloader.h>
77+#include <unity/storage/qt/Item.h>
78+#include <unity/storage/qt/ItemJob.h>
79+#include <unity/storage/qt/ItemListJob.h>
80+#include <unity/storage/qt/StorageError.h>
81+#include <unity/storage/qt/Uploader.h>
82+#include <unity/storage/qt/VoidJob.h>
83
84 #include <fcntl.h>
85 #include <sys/stat.h>
86 #include <sys/types.h>
87 #include <unistd.h>
88+#include <utime.h>
89 #include <algorithm>
90
91 using namespace std;
92-using namespace unity::storage::qt::client;
93-using unity::storage::ConflictPolicy;
94-using unity::storage::ItemType;
95+using namespace unity::storage::qt;
96 namespace provider = unity::storage::provider;
97
98 void PrintTo(QString const& str, std::ostream* os)
99@@ -125,7 +125,7 @@
100 dbus_env_.reset();
101 }
102
103- shared_ptr<Account> get_client() const
104+ Account get_client() const
105 {
106 return provider_env_->get_client();
107 }
108@@ -152,7 +152,18 @@
109 void touch_file(string const& path)
110 {
111 string full_path = local_file(path);
112- ASSERT_EQ(0, utimes(full_path.c_str(), nullptr));
113+ ASSERT_EQ(0, utime(full_path.c_str(), nullptr));
114+ }
115+
116+ void offset_mtime(string const& path, int offset_seconds)
117+ {
118+ string full_path = local_file(path);
119+ struct stat buf;
120+ ASSERT_EQ(0, stat(full_path.c_str(), &buf));
121+ struct utimbuf times;
122+ times.actime = buf.st_atime + offset_seconds;
123+ times.modtime = buf.st_mtime + offset_seconds;
124+ ASSERT_EQ(0, utime(full_path.c_str(), &times));
125 }
126
127 private:
128@@ -162,26 +173,74 @@
129 std::unique_ptr<ProviderEnvironment> provider_env_;
130 };
131
132+namespace
133+{
134+
135+template <typename Job>
136+void wait_for(Job* job)
137+{
138+ QSignalSpy spy(job, &Job::statusChanged);
139+ while (job->status() == Job::Loading)
140+ {
141+ if (!spy.wait(SIGNAL_WAIT_TIME))
142+ {
143+ throw runtime_error("Wait for statusChanged signal timed out");
144+ }
145+ }
146+}
147+
148+QList<Item> get_items(ItemListJob *job)
149+{
150+ QList<Item> items;
151+ auto connection = QObject::connect(
152+ job, &ItemListJob::itemsReady,
153+ [&](QList<Item> const& new_items)
154+ {
155+ items.append(new_items);
156+ });
157+ try
158+ {
159+ wait_for(job);
160+ }
161+ catch (...)
162+ {
163+ QObject::disconnect(connection);
164+ throw;
165+ }
166+ QObject::disconnect(connection);
167+ return items;
168+}
169+
170+Item get_root(Account const& account)
171+{
172+ unique_ptr<ItemListJob> job(account.roots());
173+ QList<Item> roots = get_items(job.get());
174+ if (job->status() != ItemListJob::Finished)
175+ {
176+ throw runtime_error("Account.roots(): " +
177+ job->error().errorString().toStdString());
178+ }
179+ return roots.at(0);
180+}
181+
182+}
183+
184 TEST_F(DavProviderTests, roots)
185 {
186 auto account = get_client();
187
188- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
189- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
190- watcher.setFuture(account->roots());
191- if (spy.count() == 0)
192- {
193- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
194- }
195+ unique_ptr<ItemListJob> job(account.roots());
196+ QList<Item> roots = get_items(job.get());
197+ ASSERT_EQ(ItemListJob::Finished, job->status())
198+ << job->error().errorString().toStdString();
199
200- auto roots = watcher.result();
201 ASSERT_EQ(1, roots.size());
202 auto item = roots[0];
203- EXPECT_EQ(".", item->native_identity());
204- EXPECT_EQ("Root", item->name());
205- EXPECT_EQ(ItemType::root, item->type());
206- EXPECT_TRUE(item->parent_ids().isEmpty());
207- EXPECT_TRUE(item->last_modified_time().isValid());
208+ EXPECT_EQ(".", item.itemId());
209+ EXPECT_EQ("Root", item.name());
210+ EXPECT_EQ(Item::Root, item.type());
211+ EXPECT_TRUE(item.parentIds().isEmpty());
212+ EXPECT_TRUE(item.lastModifiedTime().isValid());
213 }
214
215 TEST_F(DavProviderTests, list)
216@@ -192,57 +251,38 @@
217 make_dir("folder");
218 make_file("I\u00F1t\u00EBrn\u00E2ti\u00F4n\u00E0liz\u00E6ti\u00F8n");
219
220- shared_ptr<Root> root;
221- {
222- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
223- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
224- watcher.setFuture(account->roots());
225- if (spy.count() == 0)
226- {
227- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
228- }
229- auto roots = watcher.result();
230- ASSERT_EQ(1, roots.size());
231- root = roots[0];
232- }
233-
234- vector<shared_ptr<Item>> items;
235- {
236- QFutureWatcher<QVector<shared_ptr<Item>>> watcher;
237- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
238- watcher.setFuture(root->list());
239- if (spy.count() == 0)
240- {
241- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
242- }
243- auto res = watcher.result();
244- items.assign(res.begin(), res.end());
245- }
246- ASSERT_EQ(4u, items.size());
247+ Item root = get_root(account);
248+
249+ unique_ptr<ItemListJob> job(root.list());
250+ QList<Item> items = get_items(job.get());
251+ ASSERT_EQ(ItemListJob::Finished, job->status())
252+ << job->error().errorString().toStdString();
253+
254+ ASSERT_EQ(4, items.size());
255 sort(items.begin(), items.end(),
256- [](shared_ptr<Item> const& a, shared_ptr<Item> const& b) -> bool {
257- return a->native_identity() < b->native_identity();
258+ [](Item const& a, Item const& b) -> bool {
259+ return a.itemId() < b.itemId();
260 });
261
262- EXPECT_EQ("I%C3%B1t%C3%ABrn%C3%A2ti%C3%B4n%C3%A0liz%C3%A6ti%C3%B8n", items[0]->native_identity());
263- EXPECT_EQ(".", items[0]->parent_ids().at(0));
264- EXPECT_EQ("I\u00F1t\u00EBrn\u00E2ti\u00F4n\u00E0liz\u00E6ti\u00F8n", items[0]->name());
265- EXPECT_EQ(ItemType::file, items[0]->type());
266-
267- EXPECT_EQ("bar.txt", items[1]->native_identity());
268- EXPECT_EQ(".", items[1]->parent_ids().at(0));
269- EXPECT_EQ("bar.txt", items[1]->name());
270- EXPECT_EQ(ItemType::file, items[1]->type());
271-
272- EXPECT_EQ("folder/", items[2]->native_identity());
273- EXPECT_EQ(".", items[2]->parent_ids().at(0));
274- EXPECT_EQ("folder", items[2]->name());
275- EXPECT_EQ(ItemType::folder, items[2]->type());
276-
277- EXPECT_EQ("foo.txt", items[3]->native_identity());
278- EXPECT_EQ(".", items[3]->parent_ids().at(0));
279- EXPECT_EQ("foo.txt", items[3]->name());
280- EXPECT_EQ(ItemType::file, items[3]->type());
281+ EXPECT_EQ("I%C3%B1t%C3%ABrn%C3%A2ti%C3%B4n%C3%A0liz%C3%A6ti%C3%B8n", items[0].itemId());
282+ EXPECT_EQ(".", items[0].parentIds().at(0));
283+ EXPECT_EQ("I\u00F1t\u00EBrn\u00E2ti\u00F4n\u00E0liz\u00E6ti\u00F8n", items[0].name());
284+ EXPECT_EQ(Item::File, items[0].type());
285+
286+ EXPECT_EQ("bar.txt", items[1].itemId());
287+ EXPECT_EQ(".", items[1].parentIds().at(0));
288+ EXPECT_EQ("bar.txt", items[1].name());
289+ EXPECT_EQ(Item::File, items[1].type());
290+
291+ EXPECT_EQ("folder/", items[2].itemId());
292+ EXPECT_EQ(".", items[2].parentIds().at(0));
293+ EXPECT_EQ("folder", items[2].name());
294+ EXPECT_EQ(Item::Folder, items[2].type());
295+
296+ EXPECT_EQ("foo.txt", items[3].itemId());
297+ EXPECT_EQ(".", items[3].parentIds().at(0));
298+ EXPECT_EQ("foo.txt", items[3].name());
299+ EXPECT_EQ(Item::File, items[3].type());
300 }
301
302 TEST_F(DavProviderTests, lookup)
303@@ -250,37 +290,18 @@
304 auto account = get_client();
305 make_file("foo.txt");
306
307- shared_ptr<Root> root;
308- {
309- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
310- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
311- watcher.setFuture(account->roots());
312- if (spy.count() == 0)
313- {
314- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
315- }
316- auto roots = watcher.result();
317- ASSERT_EQ(1, roots.size());
318- root = roots[0];
319- }
320-
321- vector<shared_ptr<Item>> items;
322- {
323- QFutureWatcher<QVector<shared_ptr<Item>>> watcher;
324- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
325- watcher.setFuture(root->lookup("foo.txt"));
326- if (spy.count() == 0)
327- {
328- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
329- }
330- auto res = watcher.result();
331- items.assign(res.begin(), res.end());
332- }
333- ASSERT_EQ(1u, items.size());
334- EXPECT_EQ("foo.txt", items[0]->native_identity());
335- EXPECT_EQ(".", items[0]->parent_ids().at(0));
336- EXPECT_EQ("foo.txt", items[0]->name());
337- EXPECT_EQ(ItemType::file, items[0]->type());
338+ Item root = get_root(account);
339+
340+ unique_ptr<ItemListJob> job(root.lookup("foo.txt"));
341+ QList<Item> items = get_items(job.get());
342+ ASSERT_EQ(ItemListJob::Finished, job->status())
343+ << job->error().errorString().toStdString();
344+
345+ ASSERT_EQ(1, items.size());
346+ EXPECT_EQ("foo.txt", items[0].itemId());
347+ EXPECT_EQ(".", items[0].parentIds().at(0));
348+ EXPECT_EQ("foo.txt", items[0].name());
349+ EXPECT_EQ(Item::File, items[0].type());
350 }
351
352 TEST_F(DavProviderTests, metadata)
353@@ -288,148 +309,64 @@
354 auto account = get_client();
355 make_file("foo.txt");
356
357- shared_ptr<Root> root;
358- {
359- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
360- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
361- watcher.setFuture(account->roots());
362- if (spy.count() == 0)
363- {
364- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
365- }
366- auto roots = watcher.result();
367- ASSERT_EQ(1, roots.size());
368- root = roots[0];
369- }
370-
371- shared_ptr<Item> item;
372- {
373- QFutureWatcher<shared_ptr<Item>> watcher;
374- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
375- watcher.setFuture(root->get("foo.txt"));
376- if (spy.count() == 0)
377- {
378- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
379- }
380- item = watcher.result();
381- }
382-
383- EXPECT_EQ("foo.txt", item->native_identity());
384- EXPECT_EQ(".", item->parent_ids().at(0));
385- EXPECT_EQ("foo.txt", item->name());
386- EXPECT_EQ(ItemType::file, item->type());
387+ unique_ptr<ItemJob> job(account.get("foo.txt"));
388+ wait_for(job.get());
389+ ASSERT_EQ(ItemJob::Finished, job->status())
390+ << job->error().errorString().toStdString();
391+
392+ Item item = job->item();
393+ EXPECT_EQ("foo.txt", item.itemId());
394+ EXPECT_EQ(".", item.parentIds().at(0));
395+ EXPECT_EQ("foo.txt", item.name());
396+ EXPECT_EQ(Item::File, item.type());
397 }
398
399 TEST_F(DavProviderTests, metadata_not_found)
400 {
401 auto account = get_client();
402
403- shared_ptr<Root> root;
404- {
405- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
406- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
407- watcher.setFuture(account->roots());
408- if (spy.count() == 0)
409- {
410- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
411- }
412- auto roots = watcher.result();
413- ASSERT_EQ(1, roots.size());
414- root = roots[0];
415- }
416+ unique_ptr<ItemJob> job(account.get("foo.txt"));
417+ wait_for(job.get());
418+ ASSERT_EQ(ItemJob::Error, job->status());
419
420- shared_ptr<Item> item;
421- {
422- QFutureWatcher<shared_ptr<Item>> watcher;
423- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
424- watcher.setFuture(root->get("foo.txt"));
425- if (spy.count() == 0)
426- {
427- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
428- }
429- try
430- {
431- watcher.result();
432- FAIL();
433- }
434- catch (NotExistsException const& e)
435- {
436- EXPECT_TRUE(e.error_message().startsWith("Sabre\\DAV\\Exception\\NotFound: "))
437- << e.error_message().toStdString();
438- }
439- }
440+ auto error = job->error();
441+ EXPECT_EQ(StorageError::NotExists, error.type());
442+ EXPECT_TRUE(error.message().startsWith("Sabre\\DAV\\Exception\\NotFound: "))
443+ << error.message().toStdString();
444 }
445
446 TEST_F(DavProviderTests, create_folder)
447 {
448 auto account = get_client();
449
450- shared_ptr<Root> root;
451- {
452- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
453- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
454- watcher.setFuture(account->roots());
455- if (spy.count() == 0)
456- {
457- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
458- }
459- auto roots = watcher.result();
460- ASSERT_EQ(1, roots.size());
461- root = roots[0];
462- }
463-
464- shared_ptr<Folder> folder;
465- {
466- QFutureWatcher<shared_ptr<Folder>> watcher;
467- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
468- watcher.setFuture(root->create_folder("folder"));
469- if (spy.count() == 0)
470- {
471- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
472- }
473- folder = watcher.result();
474- }
475-
476- EXPECT_EQ("folder/", folder->native_identity());
477- EXPECT_EQ(".", folder->parent_ids().at(0));
478- EXPECT_EQ("folder", folder->name());
479- EXPECT_EQ(ItemType::folder, folder->type());
480+ Item root = get_root(account);
481+ unique_ptr<ItemJob> job(root.createFolder("folder"));
482+ wait_for(job.get());
483+ ASSERT_EQ(ItemJob::Finished, job->status())
484+ << job->error().errorString().toStdString();
485+
486+ Item folder = job->item();
487+ EXPECT_EQ("folder/", folder.itemId());
488+ EXPECT_EQ(".", folder.parentIds().at(0));
489+ EXPECT_EQ("folder", folder.name());
490+ EXPECT_EQ(Item::Folder, folder.type());
491 }
492
493 TEST_F(DavProviderTests, create_folder_reserved_chars)
494 {
495 auto account = get_client();
496
497- shared_ptr<Root> root;
498- {
499- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
500- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
501- watcher.setFuture(account->roots());
502- if (spy.count() == 0)
503- {
504- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
505- }
506- auto roots = watcher.result();
507- ASSERT_EQ(1, roots.size());
508- root = roots[0];
509- }
510-
511- shared_ptr<Folder> folder;
512- {
513- QFutureWatcher<shared_ptr<Folder>> watcher;
514- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
515- watcher.setFuture(root->create_folder("14:19"));
516- if (spy.count() == 0)
517- {
518- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
519- }
520- folder = watcher.result();
521- }
522-
523- EXPECT_EQ("14:19/", folder->native_identity());
524- EXPECT_EQ(".", folder->parent_ids().at(0));
525- EXPECT_EQ("14:19", folder->name());
526- EXPECT_EQ(ItemType::folder, folder->type());
527+ Item root = get_root(account);
528+ unique_ptr<ItemJob> job(root.createFolder("14:19"));
529+ wait_for(job.get());
530+ ASSERT_EQ(ItemJob::Finished, job->status())
531+ << job->error().errorString().toStdString();
532+
533+ Item folder = job->item();
534+ EXPECT_EQ("14:19/", folder.itemId());
535+ EXPECT_EQ(".", folder.parentIds().at(0));
536+ EXPECT_EQ("14:19", folder.name());
537+ EXPECT_EQ(Item::Folder, folder.type());
538 }
539
540 TEST_F(DavProviderTests, create_folder_overwrite_file)
541@@ -437,38 +374,14 @@
542 auto account = get_client();
543 make_file("folder");
544
545- shared_ptr<Root> root;
546- {
547- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
548- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
549- watcher.setFuture(account->roots());
550- if (spy.count() == 0)
551- {
552- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
553- }
554- auto roots = watcher.result();
555- ASSERT_EQ(1, roots.size());
556- root = roots[0];
557- }
558+ Item root = get_root(account);
559+ unique_ptr<ItemJob> job(root.createFolder("folder"));
560+ wait_for(job.get());
561+ ASSERT_EQ(ItemJob::Error, job->status());
562
563- {
564- QFutureWatcher<shared_ptr<Folder>> watcher;
565- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
566- watcher.setFuture(root->create_folder("folder"));
567- if (spy.count() == 0)
568- {
569- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
570- }
571- try
572- {
573- watcher.result();
574- FAIL();
575- }
576- catch (ExistsException const& e)
577- {
578- EXPECT_EQ("Sabre\\DAV\\Exception\\MethodNotAllowed: The resource you tried to create already exists", e.error_message());
579- }
580- }
581+ auto error = job->error();
582+ EXPECT_EQ(StorageError::Exists, error.type());
583+ EXPECT_EQ("Sabre\\DAV\\Exception\\MethodNotAllowed: The resource you tried to create already exists", error.message());
584 }
585
586 TEST_F(DavProviderTests, create_folder_overwrite_folder)
587@@ -476,38 +389,14 @@
588 auto account = get_client();
589 ASSERT_EQ(0, mkdir(local_file("folder").c_str(), 0755));
590
591- shared_ptr<Root> root;
592- {
593- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
594- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
595- watcher.setFuture(account->roots());
596- if (spy.count() == 0)
597- {
598- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
599- }
600- auto roots = watcher.result();
601- ASSERT_EQ(1, roots.size());
602- root = roots[0];
603- }
604+ Item root = get_root(account);
605+ unique_ptr<ItemJob> job(root.createFolder("folder"));
606+ wait_for(job.get());
607+ ASSERT_EQ(ItemJob::Error, job->status());
608
609- {
610- QFutureWatcher<shared_ptr<Folder>> watcher;
611- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
612- watcher.setFuture(root->create_folder("folder"));
613- if (spy.count() == 0)
614- {
615- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
616- }
617- try
618- {
619- watcher.result();
620- FAIL();
621- }
622- catch (ExistsException const& e)
623- {
624- EXPECT_EQ("Sabre\\DAV\\Exception\\MethodNotAllowed: The resource you tried to create already exists", e.error_message());
625- }
626- }
627+ auto error = job->error();
628+ EXPECT_EQ(StorageError::Exists, error.type());
629+ EXPECT_EQ("Sabre\\DAV\\Exception\\MethodNotAllowed: The resource you tried to create already exists", error.message());
630 }
631
632 TEST_F(DavProviderTests, create_file)
633@@ -515,59 +404,43 @@
634 int const segments = 50;
635
636 auto account = get_client();
637- shared_ptr<Root> root;
638- {
639- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
640- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
641- watcher.setFuture(account->roots());
642- if (spy.count() == 0)
643- {
644- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
645- }
646- auto roots = watcher.result();
647- ASSERT_EQ(1, roots.size());
648- root = roots[0];
649- }
650-
651- shared_ptr<Uploader> uploader;
652- {
653- QFutureWatcher<shared_ptr<Uploader>> watcher;
654- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
655- watcher.setFuture(root->create_file("filename.txt", file_contents.size() * segments));
656- if (spy.count() == 0)
657- {
658- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
659- }
660- uploader = watcher.result();
661- }
662-
663- auto socket = uploader->socket();
664+ Item root = get_root(account);
665+
666+ unique_ptr<Uploader> uploader(
667+ root.createFile("filename.txt", Item::ErrorIfConflict,
668+ file_contents.size() * segments, "text/plain"));
669+
670 int count = 0;
671 QTimer timer;
672 timer.setSingleShot(false);
673 timer.setInterval(10);
674- QFutureWatcher<shared_ptr<File>> watcher;
675 QObject::connect(&timer, &QTimer::timeout, [&] {
676- socket->write(&file_contents[0], file_contents.size());
677+ uploader->write(&file_contents[0], file_contents.size());
678 count++;
679 if (count == segments)
680 {
681- watcher.setFuture(uploader->finish_upload());
682+ uploader->close();
683 }
684 });
685
686- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
687+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
688 timer.start();
689- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
690- auto file = watcher.result();
691+ while (uploader->status() == Uploader::Loading ||
692+ uploader->status() == Uploader::Ready)
693+ {
694+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
695+ }
696+ ASSERT_EQ(Uploader::Finished, uploader->status())
697+ << uploader->error().errorString().toStdString();
698
699- EXPECT_EQ("filename.txt", file->native_identity());
700- ASSERT_EQ(1, file->parent_ids().size());
701- EXPECT_EQ(".", file->parent_ids().at(0));
702- EXPECT_EQ("filename.txt", file->name());
703- EXPECT_NE(0, file->etag().size());
704- EXPECT_EQ(ItemType::file, file->type());
705- EXPECT_EQ(int64_t(file_contents.size() * segments), file->size());
706+ auto file = uploader->item();
707+ EXPECT_EQ("filename.txt", file.itemId());
708+ ASSERT_EQ(1, file.parentIds().size());
709+ EXPECT_EQ(".", file.parentIds().at(0));
710+ EXPECT_EQ("filename.txt", file.name());
711+ EXPECT_NE(0, file.etag().size());
712+ EXPECT_EQ(Item::File, file.type());
713+ EXPECT_EQ(int64_t(file_contents.size() * segments), file.sizeInBytes());
714
715 string full_path = local_file("filename.txt");
716 struct stat buf;
717@@ -580,58 +453,49 @@
718 auto account = get_client();
719 make_file("foo.txt");
720
721- shared_ptr<Root> root;
722- {
723- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
724- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
725- watcher.setFuture(account->roots());
726- if (spy.count() == 0)
727- {
728- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
729- }
730- auto roots = watcher.result();
731- ASSERT_EQ(1, roots.size());
732- root = roots[0];
733- }
734-
735- shared_ptr<Uploader> uploader;
736- {
737- QFutureWatcher<shared_ptr<Uploader>> watcher;
738- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
739- watcher.setFuture(root->create_file("foo.txt", 0));
740- if (spy.count() == 0)
741- {
742- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
743- }
744- uploader = watcher.result();
745- }
746-
747- {
748- QFutureWatcher<shared_ptr<File>> watcher;
749- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
750- watcher.setFuture(uploader->finish_upload());
751- if (spy.count() == 0)
752- {
753- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
754- }
755- try
756- {
757- watcher.result();
758- FAIL();
759- }
760- catch (ConflictException const& e)
761- {
762- EXPECT_EQ("Sabre\\DAV\\Exception\\PreconditionFailed: An If-None-Match header was specified, but the ETag matched (or * was specified).", e.error_message());
763- }
764- }
765+ Item root = get_root(account);
766+ unique_ptr<Uploader> uploader(
767+ root.createFile("foo.txt", Item::ErrorIfConflict, 0, "text/plain"));
768+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
769+ while (uploader->status() == Uploader::Loading)
770+ {
771+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
772+ }
773+
774+ uploader->close();
775+ while (uploader->status() == Uploader::Ready)
776+ {
777+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
778+ }
779+ ASSERT_EQ(Uploader::Error, uploader->status());
780+
781+ auto error = uploader->error();
782+ EXPECT_EQ(StorageError::Conflict, error.type());
783+ EXPECT_EQ("Sabre\\DAV\\Exception\\PreconditionFailed: An If-None-Match header was specified, but the ETag matched (or * was specified).", error.message());
784 }
785
786-#if 0
787-// v1 client API doesn't let us do this. Revisit for v2 API.
788 TEST_F(DavProviderTests, create_file_overwrite_existing)
789 {
790+ auto account = get_client();
791+ make_file("foo.txt");
792+
793+ Item root = get_root(account);
794+ unique_ptr<Uploader> uploader(
795+ root.createFile("foo.txt", Item::IgnoreConflict, 0, "text/plain"));
796+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
797+ while (uploader->status() == Uploader::Loading)
798+ {
799+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
800+ }
801+
802+ uploader->close();
803+ while (uploader->status() == Uploader::Ready)
804+ {
805+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
806+ }
807+ ASSERT_EQ(Uploader::Finished, uploader->status())
808+ << uploader->error().errorString().toStdString();
809 }
810-#endif
811
812 TEST_F(DavProviderTests, update)
813 {
814@@ -639,233 +503,133 @@
815
816 auto account = get_client();
817 make_file("foo.txt");
818- // Sleep to ensure modification time changes
819- sleep(1);
820-
821- shared_ptr<Root> root;
822- {
823- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
824- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
825- watcher.setFuture(account->roots());
826- if (spy.count() == 0)
827- {
828- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
829- }
830- auto roots = watcher.result();
831- ASSERT_EQ(1, roots.size());
832- root = roots[0];
833- }
834-
835- shared_ptr<File> file;
836- {
837- QFutureWatcher<shared_ptr<Item>> watcher;
838- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
839- watcher.setFuture(root->get("foo.txt"));
840- if (spy.count() == 0)
841- {
842- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
843- }
844- file = dynamic_pointer_cast<File>(watcher.result());
845- }
846- ASSERT_NE(nullptr, file.get());
847- QString old_etag = file->etag();
848-
849- shared_ptr<Uploader> uploader;
850- {
851- QFutureWatcher<shared_ptr<Uploader>> watcher;
852- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
853- watcher.setFuture(file->create_uploader(ConflictPolicy::error_if_conflict, file_contents.size() * segments));
854- if (spy.count() == 0)
855- {
856- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
857- }
858- uploader = watcher.result();
859- }
860-
861- auto socket = uploader->socket();
862+ // Offset to ensure modification time changes
863+ offset_mtime("foo.txt", -10);
864+
865+ unique_ptr<ItemJob> job(account.get("foo.txt"));
866+ wait_for(job.get());
867+ ASSERT_EQ(ItemJob::Finished, job->status())
868+ << job->error().errorString().toStdString();
869+
870+ auto file = job->item();
871+ QString old_etag = file.etag();
872+
873+ unique_ptr<Uploader> uploader(
874+ file.createUploader(Item::ErrorIfConflict,
875+ file_contents.size() * segments));
876+
877 int count = 0;
878 QTimer timer;
879 timer.setSingleShot(false);
880 timer.setInterval(10);
881- QFutureWatcher<shared_ptr<File>> watcher;
882 QObject::connect(&timer, &QTimer::timeout, [&] {
883- socket->write(&file_contents[0], file_contents.size());
884+ uploader->write(&file_contents[0], file_contents.size());
885 count++;
886 if (count == segments)
887 {
888- watcher.setFuture(uploader->finish_upload());
889+ uploader->close();
890 }
891 });
892
893- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
894+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
895 timer.start();
896- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
897- file = watcher.result();
898+ while (uploader->status() == Uploader::Loading ||
899+ uploader->status() == Uploader::Ready)
900+ {
901+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
902+ }
903+ ASSERT_EQ(Uploader::Finished, uploader->status())
904+ << uploader->error().errorString().toStdString();
905
906- EXPECT_NE(old_etag, file->etag());
907- EXPECT_EQ(int64_t(file_contents.size() * segments), file->size());
908+ file = uploader->item();
909+ EXPECT_NE(old_etag, file.etag());
910+ EXPECT_EQ(int64_t(file_contents.size() * segments), file.sizeInBytes());
911 }
912
913 TEST_F(DavProviderTests, update_conflict)
914 {
915 auto account = get_client();
916 make_file("foo.txt");
917- // Sleep to ensure modification time changes
918- sleep(1);
919-
920- shared_ptr<Root> root;
921- {
922- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
923- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
924- watcher.setFuture(account->roots());
925- if (spy.count() == 0)
926- {
927- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
928- }
929- auto roots = watcher.result();
930- ASSERT_EQ(1, roots.size());
931- root = roots[0];
932- }
933-
934- shared_ptr<File> file;
935- {
936- QFutureWatcher<shared_ptr<Item>> watcher;
937- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
938- watcher.setFuture(root->get("foo.txt"));
939- if (spy.count() == 0)
940- {
941- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
942- }
943- file = dynamic_pointer_cast<File>(watcher.result());
944- }
945- ASSERT_NE(nullptr, file.get());
946+ // Offset to ensure modification time changes
947+ offset_mtime("foo.txt", -10);
948+
949+ unique_ptr<ItemJob> job(account.get("foo.txt"));
950+ wait_for(job.get());
951+ ASSERT_EQ(ItemJob::Finished, job->status())
952+ << job->error().errorString().toStdString();
953
954 // Change the file after metadata has been looked up
955 touch_file("foo.txt");
956
957- shared_ptr<Uploader> uploader;
958- {
959- QFutureWatcher<shared_ptr<Uploader>> watcher;
960- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
961- watcher.setFuture(file->create_uploader(ConflictPolicy::error_if_conflict, 0));
962- if (spy.count() == 0)
963- {
964- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
965- }
966- uploader = watcher.result();
967- }
968-
969- {
970- QFutureWatcher<shared_ptr<File>> watcher;
971- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
972- watcher.setFuture(uploader->finish_upload());
973- if (spy.count() == 0)
974- {
975- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
976- }
977- try
978- {
979- watcher.result();
980- FAIL();
981- }
982- catch (ConflictException const& e)
983- {
984- EXPECT_EQ("Sabre\\DAV\\Exception\\PreconditionFailed: An If-Match header was specified, but none of the specified the ETags matched.", e.error_message());
985- }
986- }
987+ auto file = job->item();
988+ unique_ptr<Uploader> uploader(
989+ file.createUploader(Item::ErrorIfConflict, 0));
990+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
991+ while (uploader->status() == Uploader::Loading)
992+ {
993+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
994+ }
995+
996+ uploader->close();
997+ while (uploader->status() == Uploader::Ready)
998+ {
999+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1000+ }
1001+ ASSERT_EQ(Uploader::Error, uploader->status());
1002+
1003+ auto error = uploader->error();
1004+ EXPECT_EQ(StorageError::Conflict, error.type());
1005+ EXPECT_EQ("Sabre\\DAV\\Exception\\PreconditionFailed: An If-Match header was specified, but none of the specified the ETags matched.", error.message());
1006 }
1007
1008 TEST_F(DavProviderTests, upload_short_write)
1009 {
1010 auto account = get_client();
1011
1012- shared_ptr<Root> root;
1013- {
1014- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1015- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1016- watcher.setFuture(account->roots());
1017- if (spy.count() == 0)
1018- {
1019- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1020- }
1021- auto roots = watcher.result();
1022- ASSERT_EQ(1, roots.size());
1023- root = roots[0];
1024- }
1025-
1026- shared_ptr<Uploader> uploader;
1027- {
1028- QFutureWatcher<shared_ptr<Uploader>> watcher;
1029- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1030- watcher.setFuture(root->create_file("foo.txt", 1000));
1031- if (spy.count() == 0)
1032- {
1033- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1034- }
1035- uploader = watcher.result();
1036- }
1037-
1038- {
1039- QFutureWatcher<shared_ptr<File>> watcher;
1040- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1041- watcher.setFuture(uploader->finish_upload());
1042- if (spy.count() == 0)
1043- {
1044- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1045- }
1046- try
1047- {
1048- watcher.result();
1049- FAIL();
1050- }
1051- catch (RemoteCommsException const& e)
1052- {
1053- EXPECT_EQ("Unknown error", e.error_message());
1054- }
1055- }
1056+ Item root = get_root(account);
1057+ unique_ptr<Uploader> uploader(
1058+ root.createFile("foo.txt", Item::ErrorIfConflict, 1000, "text/plain"));
1059+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
1060+ while (uploader->status() == Uploader::Loading)
1061+ {
1062+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1063+ }
1064+
1065+ uploader->close();
1066+ while (uploader->status() == Uploader::Ready)
1067+ {
1068+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1069+ }
1070+ ASSERT_EQ(Uploader::Error, uploader->status());
1071+
1072+ auto error = uploader->error();
1073+ EXPECT_EQ(StorageError::RemoteCommsError, error.type());
1074+ EXPECT_EQ("Unknown error", error.message());
1075 }
1076
1077 TEST_F(DavProviderTests, upload_cancel)
1078 {
1079 auto account = get_client();
1080- shared_ptr<Root> root;
1081- {
1082- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1083- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1084- watcher.setFuture(account->roots());
1085- if (spy.count() == 0)
1086- {
1087- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1088- }
1089- auto roots = watcher.result();
1090- ASSERT_EQ(1, roots.size());
1091- root = roots[0];
1092- }
1093-
1094- shared_ptr<Uploader> uploader;
1095- {
1096- QFutureWatcher<shared_ptr<Uploader>> watcher;
1097- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1098- watcher.setFuture(root->create_file("filename.txt", 1000));
1099- if (spy.count() == 0)
1100- {
1101- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1102- }
1103- uploader = watcher.result();
1104- }
1105-
1106- {
1107- QFutureWatcher<void> watcher;
1108- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1109- watcher.setFuture(uploader->cancel());
1110- if (spy.count() == 0)
1111- {
1112- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1113- }
1114- // QFuture<void> doesn't have result, but exceptions will be
1115- // thrown from waitForFinished().
1116- watcher.waitForFinished();
1117- }
1118+
1119+ Item root = get_root(account);
1120+ unique_ptr<Uploader> uploader(
1121+ root.createFile("foo.txt", Item::ErrorIfConflict, 1000, "text/plain"));
1122+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
1123+ while (uploader->status() == Uploader::Loading)
1124+ {
1125+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1126+ }
1127+
1128+ uploader->cancel();
1129+ while (uploader->status() == Uploader::Ready)
1130+ {
1131+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1132+ }
1133+ ASSERT_EQ(Uploader::Cancelled, uploader->status());
1134+
1135+ auto error = uploader->error();
1136+ EXPECT_EQ(StorageError::Cancelled, error.type());
1137+ EXPECT_EQ("Uploader::cancel(): upload was cancelled", error.message());
1138 }
1139
1140 TEST_F(DavProviderTests, download)
1141@@ -886,70 +650,38 @@
1142 }
1143
1144 auto account = get_client();
1145- shared_ptr<Root> root;
1146- {
1147- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1148- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1149- watcher.setFuture(account->roots());
1150- if (spy.count() == 0)
1151- {
1152- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1153- }
1154- auto roots = watcher.result();
1155- ASSERT_EQ(1, roots.size());
1156- root = roots[0];
1157- }
1158-
1159- shared_ptr<File> file;
1160- {
1161- QFutureWatcher<shared_ptr<Item>> watcher;
1162- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1163- watcher.setFuture(root->get("foo.txt"));
1164- if (spy.count() == 0)
1165- {
1166- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1167- }
1168- file = dynamic_pointer_cast<File>(watcher.result());
1169- }
1170- ASSERT_NE(nullptr, file.get());
1171-
1172- shared_ptr<Downloader> downloader;
1173- {
1174- QFutureWatcher<shared_ptr<Downloader>> watcher;
1175- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1176- watcher.setFuture(file->create_downloader());
1177- if (spy.count() == 0)
1178- {
1179- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1180- }
1181- downloader = watcher.result();
1182- }
1183+
1184+ unique_ptr<ItemJob> job(account.get("foo.txt"));
1185+ wait_for(job.get());
1186+ ASSERT_EQ(ItemJob::Finished, job->status())
1187+ << job->error().errorString().toStdString();
1188+
1189+ auto file = job->item();
1190+
1191+ unique_ptr<Downloader> downloader(
1192+ file.createDownloader(Item::ErrorIfConflict));
1193
1194 int64_t n_read = 0;
1195- auto socket = downloader->socket();
1196- QObject::connect(socket.get(), &QIODevice::readyRead,
1197- [socket, &large_contents, &n_read]() {
1198- auto bytes = socket->readAll();
1199+ QObject::connect(downloader.get(), &QIODevice::readyRead,
1200+ [&]() {
1201+ auto bytes = downloader->readAll();
1202 string const expected = large_contents.substr(
1203 n_read, bytes.size());
1204 EXPECT_EQ(expected, bytes.toStdString());
1205 n_read += bytes.size();
1206 });
1207- {
1208- QSignalSpy spy(socket.get(), &QIODevice::readChannelFinished);
1209- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1210- }
1211+ QSignalSpy read_finished_spy(
1212+ downloader.get(), &QIODevice::readChannelFinished);
1213+ ASSERT_TRUE(read_finished_spy.wait(SIGNAL_WAIT_TIME));
1214
1215+ QSignalSpy status_spy(downloader.get(), &Downloader::statusChanged);
1216+ downloader->close();
1217+ while (downloader->status() == Downloader::Ready)
1218 {
1219- QFutureWatcher<void> watcher;
1220- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1221- watcher.setFuture(downloader->finish_download());
1222- if (spy.count() == 0)
1223- {
1224- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1225- }
1226- watcher.waitForFinished(); // to check for errors
1227+ ASSERT_TRUE(status_spy.wait(SIGNAL_WAIT_TIME));
1228 }
1229+ ASSERT_EQ(Downloader::Finished, downloader->status())
1230+ << downloader->error().errorString().toStdString();
1231
1232 EXPECT_EQ(int64_t(large_contents.size()), n_read);
1233 }
1234@@ -969,64 +701,32 @@
1235 }
1236
1237 auto account = get_client();
1238- shared_ptr<Root> root;
1239- {
1240- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1241- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1242- watcher.setFuture(account->roots());
1243- if (spy.count() == 0)
1244- {
1245- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1246- }
1247- auto roots = watcher.result();
1248- ASSERT_EQ(1, roots.size());
1249- root = roots[0];
1250- }
1251-
1252- shared_ptr<File> file;
1253- {
1254- QFutureWatcher<shared_ptr<Item>> watcher;
1255- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1256- watcher.setFuture(root->get("foo.txt"));
1257- if (spy.count() == 0)
1258- {
1259- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1260- }
1261- file = dynamic_pointer_cast<File>(watcher.result());
1262- }
1263- ASSERT_NE(nullptr, file.get());
1264-
1265- shared_ptr<Downloader> downloader;
1266- {
1267- QFutureWatcher<shared_ptr<Downloader>> watcher;
1268- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1269- watcher.setFuture(file->create_downloader());
1270- if (spy.count() == 0)
1271- {
1272- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1273- }
1274- downloader = watcher.result();
1275- }
1276-
1277- {
1278- QFutureWatcher<void> watcher;
1279- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1280- watcher.setFuture(downloader->finish_download());
1281- if (spy.count() == 0)
1282- {
1283- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1284- }
1285-
1286- try
1287- {
1288- watcher.waitForFinished(); // to check for errors
1289- FAIL();
1290- }
1291- catch (LogicException const& e)
1292- {
1293- EXPECT_EQ("finish called before all data sent", e.error_message());
1294- }
1295- }
1296+
1297+ unique_ptr<ItemJob> job(account.get("foo.txt"));
1298+ wait_for(job.get());
1299+ ASSERT_EQ(ItemJob::Finished, job->status())
1300+ << job->error().errorString().toStdString();
1301+
1302+ auto file = job->item();
1303+ unique_ptr<Downloader> downloader(
1304+ file.createDownloader(Item::ErrorIfConflict));
1305+
1306+ QSignalSpy spy(downloader.get(), &Downloader::statusChanged);
1307+ while (downloader->status() == Downloader::Loading)
1308+ {
1309+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1310+ }
1311+
1312+ downloader->close();
1313+ while (downloader->status() == Downloader::Ready)
1314+ {
1315+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1316+ }
1317+ ASSERT_EQ(Downloader::Error, downloader->status());
1318+
1319+ auto error = downloader->error();
1320+ EXPECT_EQ(StorageError::LogicError, error.type());
1321+ EXPECT_EQ("finish called before all data sent", error.message());
1322 }
1323
1324 TEST_F(DavProviderTests, download_not_found)
1325@@ -1034,77 +734,38 @@
1326 auto account = get_client();
1327 make_file("foo.txt");
1328
1329- shared_ptr<Root> root;
1330- {
1331- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1332- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1333- watcher.setFuture(account->roots());
1334- if (spy.count() == 0)
1335- {
1336- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1337- }
1338- auto roots = watcher.result();
1339- ASSERT_EQ(1, roots.size());
1340- root = roots[0];
1341- }
1342+ unique_ptr<ItemJob> job(account.get("foo.txt"));
1343+ wait_for(job.get());
1344+ ASSERT_EQ(ItemJob::Finished, job->status())
1345+ << job->error().errorString().toStdString();
1346
1347- shared_ptr<File> file;
1348- {
1349- QFutureWatcher<shared_ptr<Item>> watcher;
1350- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1351- watcher.setFuture(root->get("foo.txt"));
1352- if (spy.count() == 0)
1353- {
1354- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1355- }
1356- file = dynamic_pointer_cast<File>(watcher.result());
1357- }
1358- ASSERT_NE(nullptr, file.get());
1359+ auto file = job->item();
1360
1361 ASSERT_EQ(0, unlink(local_file("foo.txt").c_str()));
1362
1363- shared_ptr<Downloader> downloader;
1364- {
1365- QFutureWatcher<shared_ptr<Downloader>> watcher;
1366- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1367- watcher.setFuture(file->create_downloader());
1368- if (spy.count() == 0)
1369- {
1370- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1371- }
1372- downloader = watcher.result();
1373- }
1374+ unique_ptr<Downloader> downloader(
1375+ file.createDownloader(Item::ErrorIfConflict));
1376
1377- auto socket = downloader->socket();
1378- QObject::connect(socket.get(), &QIODevice::readyRead,
1379- [socket]() {
1380- socket->readAll();
1381+ QObject::connect(downloader.get(), &QIODevice::readyRead,
1382+ [&]() {
1383+ downloader->readAll();
1384 });
1385- {
1386- QSignalSpy spy(socket.get(), &QIODevice::readChannelFinished);
1387- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1388- }
1389-
1390- {
1391- QFutureWatcher<void> watcher;
1392- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1393- watcher.setFuture(downloader->finish_download());
1394- if (spy.count() == 0)
1395- {
1396- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1397- }
1398-
1399- try
1400- {
1401- watcher.waitForFinished(); // to check for errors
1402- FAIL();
1403- }
1404- catch (NotExistsException const& e)
1405- {
1406- EXPECT_TRUE(e.error_message().startsWith("Sabre\\DAV\\Exception\\NotFound: "))
1407- << e.error_message().toStdString();
1408- }
1409- }
1410+ QSignalSpy read_finished_spy(
1411+ downloader.get(), &QIODevice::readChannelFinished);
1412+ ASSERT_TRUE(read_finished_spy.wait(SIGNAL_WAIT_TIME));
1413+
1414+ QSignalSpy status_spy(downloader.get(), &Downloader::statusChanged);
1415+ downloader->close();
1416+ while (downloader->status() == Downloader::Ready)
1417+ {
1418+ ASSERT_TRUE(status_spy.wait(SIGNAL_WAIT_TIME));
1419+ }
1420+ ASSERT_EQ(Downloader::Error, downloader->status());
1421+
1422+ auto error = downloader->error();
1423+ EXPECT_EQ(StorageError::NotExists, error.type());
1424+ EXPECT_TRUE(error.message().startsWith("Sabre\\DAV\\Exception\\NotFound: "))
1425+ << error.message().toStdString();
1426 }
1427
1428 TEST_F(DavProviderTests, delete_item)
1429@@ -1112,42 +773,16 @@
1430 auto account = get_client();
1431 make_file("foo.txt");
1432
1433- shared_ptr<Root> root;
1434- {
1435- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1436- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1437- watcher.setFuture(account->roots());
1438- if (spy.count() == 0)
1439- {
1440- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1441- }
1442- auto roots = watcher.result();
1443- ASSERT_EQ(1, roots.size());
1444- root = roots[0];
1445- }
1446-
1447- shared_ptr<Item> item;
1448- {
1449- QFutureWatcher<shared_ptr<Item>> watcher;
1450- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1451- watcher.setFuture(root->get("foo.txt"));
1452- if (spy.count() == 0)
1453- {
1454- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1455- }
1456- item = watcher.result();
1457- }
1458-
1459- {
1460- QFutureWatcher<void> watcher;
1461- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1462- watcher.setFuture(item->delete_item());
1463- if (spy.count() == 0)
1464- {
1465- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1466- }
1467- watcher.waitForFinished(); // to catch any errors
1468- }
1469+ unique_ptr<ItemJob> job(account.get("foo.txt"));
1470+ wait_for(job.get());
1471+ ASSERT_EQ(ItemJob::Finished, job->status())
1472+ << job->error().errorString().toStdString();
1473+
1474+ Item item = job->item();
1475+ unique_ptr<VoidJob> delete_job(item.deleteItem());
1476+ wait_for(delete_job.get());
1477+ ASSERT_EQ(VoidJob::Finished, delete_job->status())
1478+ << delete_job->error().errorString().toStdString();
1479
1480 struct stat buf;
1481 EXPECT_EQ(-1, stat(local_file("foo.txt").c_str(), &buf));
1482@@ -1159,54 +794,23 @@
1483 auto account = get_client();
1484 make_file("foo.txt");
1485
1486- shared_ptr<Root> root;
1487- {
1488- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1489- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1490- watcher.setFuture(account->roots());
1491- if (spy.count() == 0)
1492- {
1493- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1494- }
1495- auto roots = watcher.result();
1496- ASSERT_EQ(1, roots.size());
1497- root = roots[0];
1498- }
1499+ unique_ptr<ItemJob> job(account.get("foo.txt"));
1500+ wait_for(job.get());
1501+ ASSERT_EQ(ItemJob::Finished, job->status())
1502+ << job->error().errorString().toStdString();
1503
1504- shared_ptr<Item> item;
1505- {
1506- QFutureWatcher<shared_ptr<Item>> watcher;
1507- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1508- watcher.setFuture(root->get("foo.txt"));
1509- if (spy.count() == 0)
1510- {
1511- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1512- }
1513- item = watcher.result();
1514- }
1515+ Item item = job->item();
1516
1517 ASSERT_EQ(0, unlink(local_file("foo.txt").c_str()));
1518
1519- {
1520- QFutureWatcher<void> watcher;
1521- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1522- watcher.setFuture(item->delete_item());
1523- if (spy.count() == 0)
1524- {
1525- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1526- }
1527- try
1528- {
1529- watcher.waitForFinished(); // to catch any errors
1530- FAIL();
1531- }
1532- catch (NotExistsException const& e)
1533- {
1534- EXPECT_TRUE(e.error_message().startsWith(
1535- "Sabre\\DAV\\Exception\\NotFound: "))
1536- << e.error_message().toStdString();
1537- }
1538- }
1539+ unique_ptr<VoidJob> delete_job(item.deleteItem());
1540+ wait_for(delete_job.get());
1541+ ASSERT_EQ(VoidJob::Error, delete_job->status());
1542+
1543+ auto error = delete_job->error();
1544+ EXPECT_EQ(StorageError::NotExists, error.type());
1545+ EXPECT_TRUE(error.message().startsWith("Sabre\\DAV\\Exception\\NotFound: "))
1546+ << error.message().toStdString();
1547 }
1548
1549 TEST_F(DavProviderTests, move)
1550@@ -1220,50 +824,28 @@
1551 }
1552
1553 auto account = get_client();
1554- shared_ptr<Root> root;
1555- {
1556- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1557- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1558- watcher.setFuture(account->roots());
1559- if (spy.count() == 0)
1560- {
1561- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1562- }
1563- auto roots = watcher.result();
1564- ASSERT_EQ(1, roots.size());
1565- root = roots[0];
1566- }
1567-
1568- shared_ptr<Item> item;
1569- {
1570- QFutureWatcher<shared_ptr<Item>> watcher;
1571- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1572- watcher.setFuture(root->get("foo.txt"));
1573- if (spy.count() == 0)
1574- {
1575- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1576- }
1577- item = watcher.result();
1578- }
1579-
1580- {
1581- QFutureWatcher<shared_ptr<Item>> watcher;
1582- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1583- watcher.setFuture(item->move(root, "new-name.txt"));
1584- if (spy.count() == 0)
1585- {
1586- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1587- }
1588- item = watcher.result();
1589- }
1590-
1591- EXPECT_EQ("new-name.txt", item->native_identity());
1592- ASSERT_EQ(1, item->parent_ids().size());
1593- EXPECT_EQ(".", item->parent_ids().at(0));
1594- EXPECT_EQ("new-name.txt", item->name());
1595- EXPECT_NE(0, item->etag().size());
1596- EXPECT_EQ(ItemType::file, item->type());
1597- EXPECT_EQ(int64_t(file_contents.size()), dynamic_pointer_cast<File>(item)->size());
1598+ Item root = get_root(account);
1599+
1600+ unique_ptr<ItemJob> job(account.get("foo.txt"));
1601+ wait_for(job.get());
1602+ ASSERT_EQ(ItemJob::Finished, job->status())
1603+ << job->error().errorString().toStdString();
1604+
1605+ Item item = job->item();
1606+
1607+ job.reset(item.move(root, "new-name.txt"));
1608+ wait_for(job.get());
1609+ ASSERT_EQ(ItemJob::Finished, job->status())
1610+ << job->error().errorString().toStdString();
1611+
1612+ item = job->item();
1613+ EXPECT_EQ("new-name.txt", item.itemId());
1614+ ASSERT_EQ(1, item.parentIds().size());
1615+ EXPECT_EQ(".", item.parentIds().at(0));
1616+ EXPECT_EQ("new-name.txt", item.name());
1617+ EXPECT_NE(0, item.etag().size());
1618+ EXPECT_EQ(Item::File, item.type());
1619+ EXPECT_EQ(int64_t(file_contents.size()), item.sizeInBytes());
1620
1621 // The old file no longer exists
1622 struct stat buf;
1623@@ -1297,50 +879,28 @@
1624 }
1625
1626 auto account = get_client();
1627- shared_ptr<Root> root;
1628- {
1629- QFutureWatcher<QVector<shared_ptr<Root>>> watcher;
1630- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1631- watcher.setFuture(account->roots());
1632- if (spy.count() == 0)
1633- {
1634- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1635- }
1636- auto roots = watcher.result();
1637- ASSERT_EQ(1, roots.size());
1638- root = roots[0];
1639- }
1640-
1641- shared_ptr<Item> item;
1642- {
1643- QFutureWatcher<shared_ptr<Item>> watcher;
1644- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1645- watcher.setFuture(root->get("foo.txt"));
1646- if (spy.count() == 0)
1647- {
1648- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1649- }
1650- item = watcher.result();
1651- }
1652-
1653- {
1654- QFutureWatcher<shared_ptr<Item>> watcher;
1655- QSignalSpy spy(&watcher, &decltype(watcher)::finished);
1656- watcher.setFuture(item->copy(root, "new-name.txt"));
1657- if (spy.count() == 0)
1658- {
1659- ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
1660- }
1661- item = watcher.result();
1662- }
1663-
1664- EXPECT_EQ("new-name.txt", item->native_identity());
1665- ASSERT_EQ(1, item->parent_ids().size());
1666- EXPECT_EQ(".", item->parent_ids().at(0));
1667- EXPECT_EQ("new-name.txt", item->name());
1668- EXPECT_NE(0, item->etag().size());
1669- EXPECT_EQ(ItemType::file, item->type());
1670- EXPECT_EQ(int64_t(file_contents.size()), dynamic_pointer_cast<File>(item)->size());
1671+ Item root = get_root(account);
1672+
1673+ unique_ptr<ItemJob> job(account.get("foo.txt"));
1674+ wait_for(job.get());
1675+ ASSERT_EQ(ItemJob::Finished, job->status())
1676+ << job->error().errorString().toStdString();
1677+
1678+ Item item = job->item();
1679+
1680+ job.reset(item.copy(root, "new-name.txt"));
1681+ wait_for(job.get());
1682+ ASSERT_EQ(ItemJob::Finished, job->status())
1683+ << job->error().errorString().toStdString();
1684+
1685+ item = job->item();
1686+ EXPECT_EQ("new-name.txt", item.itemId());
1687+ ASSERT_EQ(1, item.parentIds().size());
1688+ EXPECT_EQ(".", item.parentIds().at(0));
1689+ EXPECT_EQ("new-name.txt", item.name());
1690+ EXPECT_NE(0, item.etag().size());
1691+ EXPECT_EQ(Item::File, item.type());
1692+ EXPECT_EQ(int64_t(file_contents.size()), item.sizeInBytes());
1693
1694 // The old file still exists
1695 struct stat buf;
1696
1697=== modified file 'tests/utils/ProviderEnvironment.cpp'
1698--- tests/utils/ProviderEnvironment.cpp 2016-11-18 04:34:55 +0000
1699+++ tests/utils/ProviderEnvironment.cpp 2016-11-25 04:11:48 +0000
1700@@ -24,7 +24,7 @@
1701
1702 using namespace std;
1703 using namespace unity::storage::provider;
1704-using namespace unity::storage::qt::client;
1705+using namespace unity::storage::qt;
1706
1707 namespace
1708 {
1709@@ -51,13 +51,13 @@
1710 *server_connection_,
1711 OBJECT_PATH.toStdString()));
1712
1713- client_runtime_ = Runtime::create(*client_connection_);
1714- client_account_ = client_runtime_->make_test_account(server_connection_->baseService(), OBJECT_PATH);
1715+ client_runtime_.reset(new Runtime(*client_connection_));
1716+ client_account_ = client_runtime_->make_test_account(
1717+ server_connection_->baseService(), OBJECT_PATH);
1718 }
1719
1720 ProviderEnvironment::~ProviderEnvironment()
1721 {
1722- client_account_.reset();
1723 client_runtime_->shutdown();
1724 client_runtime_.reset();
1725
1726@@ -69,7 +69,7 @@
1727 client_connection_.reset();
1728 }
1729
1730-shared_ptr<Account> ProviderEnvironment::get_client() const
1731+Account ProviderEnvironment::get_client() const
1732 {
1733 return client_account_;
1734 }
1735
1736=== modified file 'tests/utils/ProviderEnvironment.h'
1737--- tests/utils/ProviderEnvironment.h 2016-11-18 04:34:55 +0000
1738+++ tests/utils/ProviderEnvironment.h 2016-11-25 04:11:48 +0000
1739@@ -23,7 +23,8 @@
1740 #include <OnlineAccounts/Manager>
1741 #include <QDBusConnection>
1742 #include <unity/storage/provider/testing/TestServer.h>
1743-#include <unity/storage/qt/client/Runtime.h>
1744+#include <unity/storage/qt/Account.h>
1745+#include <unity/storage/qt/Runtime.h>
1746
1747 #include <memory>
1748
1749@@ -35,13 +36,14 @@
1750 DBusEnvironment const& dbus_env);
1751 ~ProviderEnvironment();
1752
1753- std::shared_ptr<unity::storage::qt::client::Account> get_client() const;
1754+ unity::storage::qt::Account get_client() const;
1755
1756 private:
1757 std::unique_ptr<QDBusConnection> client_connection_;
1758 std::unique_ptr<QDBusConnection> server_connection_;
1759 std::unique_ptr<OnlineAccounts::Manager> account_manager_;
1760 std::unique_ptr<unity::storage::provider::testing::TestServer> server_;
1761- std::shared_ptr<unity::storage::qt::client::Runtime> client_runtime_;
1762- std::shared_ptr<unity::storage::qt::client::Account> client_account_;
1763+
1764+ std::unique_ptr<unity::storage::qt::Runtime> client_runtime_;
1765+ unity::storage::qt::Account client_account_;
1766 };

Subscribers

People subscribed via source and target branches