Merge lp:~michihenning/storage-framework/create-file into lp:storage-framework/devel

Proposed by Michi Henning
Status: Merged
Approved by: James Henstridge
Approved revision: 112
Merged at revision: 81
Proposed branch: lp:~michihenning/storage-framework/create-file
Merge into: lp:storage-framework/devel
Diff against target: 534 lines (+364/-15)
7 files modified
include/unity/storage/qt/Item.h (+4/-1)
include/unity/storage/qt/internal/ItemImpl.h (+4/-0)
src/qt/Item.cpp (+5/-2)
src/qt/internal/ItemImpl.cpp (+45/-5)
src/qt/internal/UploaderImpl.cpp (+1/-1)
tests/remote-client/MockProvider.cpp (+7/-2)
tests/remote-client/remote-client_test.cpp (+298/-4)
To merge this branch: bzr merge lp:~michihenning/storage-framework/create-file
Reviewer Review Type Date Requested Status
James Henstridge Approve
unity-api-1-bot continuous-integration Approve
Review via email: mp+308342@code.launchpad.net

Commit message

Added createFile().

Description of the change

Added createFile().

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

PASSED: Continuous integration, rev:109
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/155/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/879
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/886
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/692/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/692/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/692/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/692/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/692/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/692/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/692/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/692/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/692
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/692/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
112. By Michi Henning

Check policy for exists error.

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

PASSED: Continuous integration, rev:110
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/156/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/893
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/900
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/706/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/706/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/706/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/706/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/706/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/706/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/706/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/706/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/706
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/706/artifact/output/*zip*/output.zip

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

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

PASSED: Continuous integration, rev:112
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/157/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/894
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/901
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/707/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/707/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/707/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/707/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/707/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/707/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/707/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/707/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/707
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/707/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
James Henstridge (jamesh) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/unity/storage/qt/Item.h'
2--- include/unity/storage/qt/Item.h 2016-10-12 05:25:20 +0000
3+++ include/unity/storage/qt/Item.h 2016-10-17 13:01:35 +0000
4@@ -108,7 +108,10 @@
5 Q_INVOKABLE ItemListJob* list() const;
6 Q_INVOKABLE ItemListJob* lookup(QString const& name) const;
7 Q_INVOKABLE ItemJob* createFolder(QString const& name) const;
8- Q_INVOKABLE Uploader* createFile(QString const& name) const;
9+ Q_INVOKABLE Uploader* createFile(QString const& name,
10+ ConflictPolicy policy,
11+ qint64 sizeInBytes,
12+ QString const& contentType) const;
13
14 Q_INVOKABLE IntJob* freeSpaceBytes() const;
15 Q_INVOKABLE IntJob* usedSpaceBytes() const;
16
17=== modified file 'include/unity/storage/qt/internal/ItemImpl.h'
18--- include/unity/storage/qt/internal/ItemImpl.h 2016-10-12 05:25:20 +0000
19+++ include/unity/storage/qt/internal/ItemImpl.h 2016-10-17 13:01:35 +0000
20@@ -68,6 +68,10 @@
21 ItemListJob* lookup(QString const& name) const;
22 ItemJob* createFolder(QString const& name) const;
23 Uploader* createFile(QString const& name) const;
24+ Uploader* createFile(QString const& name,
25+ Item::ConflictPolicy policy,
26+ qint64 sizeInBytes,
27+ QString const& contentType) const;
28 IntJob* freeSpaceBytes() const;
29 IntJob* usedSpaceBytes() const;
30
31
32=== modified file 'src/qt/Item.cpp'
33--- src/qt/Item.cpp 2016-10-10 06:27:12 +0000
34+++ src/qt/Item.cpp 2016-10-17 13:01:35 +0000
35@@ -162,9 +162,12 @@
36 return p_->createFolder(name);
37 }
38
39-Uploader* Item::createFile(QString const& name) const
40+Uploader* Item::createFile(QString const& name,
41+ ConflictPolicy policy,
42+ qint64 sizeInBytes,
43+ QString const& contentType) const
44 {
45- return p_->createFile(name);
46+ return p_->createFile(name, policy, sizeInBytes, contentType);
47 }
48
49 IntJob* Item::freeSpaceBytes() const
50
51=== modified file 'src/qt/internal/ItemImpl.cpp'
52--- src/qt/internal/ItemImpl.cpp 2016-10-13 06:48:11 +0000
53+++ src/qt/internal/ItemImpl.cpp 2016-10-17 13:01:35 +0000
54@@ -243,7 +243,7 @@
55 }
56 if (md_.type != storage::ItemType::file)
57 {
58- auto e = StorageErrorImpl::logic_error(method + ": cannot upload to a directory");
59+ auto e = StorageErrorImpl::logic_error(method + ": cannot upload to a folder");
60 return UploaderImpl::make_job(e);
61 }
62 if (sizeInBytes < 0)
63@@ -256,7 +256,7 @@
64 {
65 if (md.type != storage::ItemType::file)
66 {
67- QString msg = method + ": impossible directory item returned by provider";
68+ QString msg = method + ": impossible folder item returned by provider";
69 qCritical().noquote() << msg;
70 throw StorageErrorImpl::local_comms_error(msg);
71 }
72@@ -279,7 +279,7 @@
73 }
74 if (md_.type != storage::ItemType::file)
75 {
76- auto e = StorageErrorImpl::logic_error(method + ": cannot download a directory");
77+ auto e = StorageErrorImpl::logic_error(method + ": cannot download a folder");
78 return DownloaderImpl::make_job(e);
79 }
80
81@@ -378,9 +378,49 @@
82 return ItemJobImpl::make_job(This, method, reply, validate);
83 }
84
85-Uploader* ItemImpl::createFile(QString const& name) const
86+Uploader* ItemImpl::createFile(QString const& name,
87+ Item::ConflictPolicy policy,
88+ qint64 sizeInBytes,
89+ QString const& contentType) const
90 {
91- return nullptr; // TODO
92+ QString const method = "Item::createFile()";
93+
94+ auto invalid_job = check_invalid_or_destroyed<UploaderImpl>(method);
95+ if (invalid_job)
96+ {
97+ return invalid_job;
98+ }
99+ if (md_.type == storage::ItemType::file)
100+ {
101+ auto e = StorageErrorImpl::logic_error(method + ": cannot create a file with a file as the parent");
102+ return UploaderImpl::make_job(e);
103+ }
104+ if (sizeInBytes < 0)
105+ {
106+ auto e = StorageErrorImpl::invalid_argument_error(method + ": size must be >= 0");
107+ return UploaderImpl::make_job(e);
108+ }
109+ if (name.isEmpty())
110+ {
111+ auto e = StorageErrorImpl::invalid_argument_error(method + ": name cannot be empty");
112+ return UploaderImpl::make_job(e);
113+ }
114+ // contentType can be empty, so not checked here.
115+
116+ auto validate = [method](storage::internal::ItemMetadata const& md)
117+ {
118+ if (md.type != storage::ItemType::file)
119+ {
120+ QString msg = method + ": impossible folder item returned by provider";
121+ qCritical().noquote() << msg;
122+ throw StorageErrorImpl::local_comms_error(msg);
123+ }
124+ };
125+
126+ bool allow_overwrite = policy == Item::ConflictPolicy::Overwrite;
127+ auto reply = account_impl_->provider()->CreateFile(md_.item_id, name, sizeInBytes, contentType, allow_overwrite);
128+ auto This = const_pointer_cast<ItemImpl>(shared_from_this());
129+ return UploaderImpl::make_job(This, method, reply, validate, policy, sizeInBytes);
130 }
131
132 IntJob* ItemImpl::freeSpaceBytes() const
133
134=== modified file 'src/qt/internal/UploaderImpl.cpp'
135--- src/qt/internal/UploaderImpl.cpp 2016-10-13 06:48:11 +0000
136+++ src/qt/internal/UploaderImpl.cpp 2016-10-17 13:01:35 +0000
137@@ -158,7 +158,7 @@
138
139 Item UploaderImpl::item() const
140 {
141- if (status_ == Uploader::Status::Error || status_ == Uploader::Status::Cancelled)
142+ if (status_ != Uploader::Status::Finished)
143 {
144 return Item();
145 }
146
147=== modified file 'tests/remote-client/MockProvider.cpp'
148--- tests/remote-client/MockProvider.cpp 2016-10-13 06:48:11 +0000
149+++ tests/remote-client/MockProvider.cpp 2016-10-17 13:01:35 +0000
150@@ -262,7 +262,7 @@
151 string const&, string const&,
152 int64_t, string const&, bool, Context const&)
153 {
154- return make_ready_future<unique_ptr<UploadJob>>(new MockUploadJob());
155+ return make_ready_future<unique_ptr<UploadJob>>(new MockUploadJob(cmd_));
156 }
157
158 boost::future<unique_ptr<UploadJob>> MockProvider::update(
159@@ -403,6 +403,11 @@
160 {
161 return make_exceptional_future<Item>(ResourceException("out of memory", 99));
162 }
163+ if (cmd_ == "create_file_exists")
164+ {
165+ ExistsException e("file exists", "child_id", "Child");
166+ return make_exceptional_future<Item>(e);
167+ }
168 if (cmd_ == "upload_returns_dir")
169 {
170 Item metadata{"some_id", { "root_id" }, "some_upload", "etag", ItemType::folder, {}};
171@@ -410,7 +415,7 @@
172 }
173 Item metadata
174 {
175- "some_id", { "root_id" }, "some_upload", "etag", ItemType::file,
176+ "child_id", { "root_id" }, "some_upload", "etag", ItemType::file,
177 { { SIZE_IN_BYTES, 10 }, { LAST_MODIFIED_TIME, "2011-04-05T14:30:10.005Z" } }
178 };
179 return make_ready_future(metadata);
180
181=== modified file 'tests/remote-client/remote-client_test.cpp'
182--- tests/remote-client/remote-client_test.cpp 2016-10-13 06:48:11 +0000
183+++ tests/remote-client/remote-client_test.cpp 2016-10-17 13:01:35 +0000
184@@ -58,6 +58,7 @@
185
186 class AccountTest : public RemoteClientTest {};
187 class CopyTest : public RemoteClientTest {};
188+class CreateFileTest : public RemoteClientTest {};
189 class CreateFolderTest : public RemoteClientTest {};
190 class DeleteTest : public RemoteClientTest {};
191 class DownloadTest : public RemoteClientTest {};
192@@ -2691,7 +2692,7 @@
193 EXPECT_FALSE(downloader->isValid());
194 EXPECT_EQ(Downloader::Status::Error, downloader->status());
195 EXPECT_EQ(StorageError::Type::LogicError, downloader->error().type());
196- EXPECT_EQ("Item::createDownloader(): cannot download a directory", downloader->error().message());
197+ EXPECT_EQ("Item::createDownloader(): cannot download a folder", downloader->error().message());
198
199 {
200 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);
201@@ -2826,7 +2827,7 @@
202 EXPECT_TRUE(uploader->isValid());
203 EXPECT_EQ(Uploader::Status::Loading, uploader->status());
204 EXPECT_EQ(StorageError::NoError, uploader->error().type());
205- EXPECT_EQ(child, uploader->item());
206+ EXPECT_EQ(Item(), uploader->item());
207 EXPECT_EQ(Item::ConflictPolicy::Overwrite, uploader->policy());
208 EXPECT_EQ(contents.size(), uploader->sizeInBytes());
209
210@@ -2846,6 +2847,7 @@
211 EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0)));
212
213 EXPECT_EQ(Uploader::Status::Finished, uploader->status());
214+ EXPECT_EQ(child, uploader->item());
215 }
216
217 TEST_F(UploadTest, abandoned)
218@@ -3237,7 +3239,7 @@
219 EXPECT_FALSE(uploader->isValid());
220 EXPECT_EQ(Uploader::Status::Error, uploader->status());
221 EXPECT_EQ(StorageError::Type::LogicError, uploader->error().type());
222- EXPECT_EQ("Item::createUploader(): cannot upload to a directory", uploader->error().message());
223+ EXPECT_EQ("Item::createUploader(): cannot upload to a folder", uploader->error().message());
224
225 {
226 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
227@@ -3319,7 +3321,7 @@
228
229 EXPECT_EQ(Uploader::Status::Error, uploader->status());
230 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());
231- EXPECT_EQ("Item::createUploader(): impossible directory item returned by provider", uploader->error().message());
232+ EXPECT_EQ("Item::createUploader(): impossible folder item returned by provider", uploader->error().message());
233 }
234
235 TEST_F(UploadTest, cancel_success)
236@@ -3467,6 +3469,298 @@
237 EXPECT_EQ("Uploader::cancel(): Runtime was destroyed previously", uploader->error().message());
238 }
239
240+TEST_F(CreateFileTest, basic)
241+{
242+ set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
243+
244+ Item root;
245+ {
246+ unique_ptr<ItemJob> j(acc_.get("root_id"));
247+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
248+ spy.wait(SIGNAL_WAIT_TIME);
249+ root = j->item();
250+ }
251+
252+ Item child;
253+ {
254+ unique_ptr<ItemJob> j(acc_.get("child_id"));
255+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
256+ spy.wait(SIGNAL_WAIT_TIME);
257+ child = j->item();
258+ }
259+
260+ QByteArray contents("Hello world", -1);
261+ unique_ptr<Uploader> uploader(root.createFile("Child",
262+ Item::ConflictPolicy::Overwrite,
263+ contents.size(),
264+ ""));
265+ EXPECT_TRUE(uploader->isValid());
266+ EXPECT_EQ(Uploader::Status::Loading, uploader->status());
267+ EXPECT_EQ(StorageError::NoError, uploader->error().type());
268+ EXPECT_EQ(Item(), uploader->item());
269+ EXPECT_EQ(Item::ConflictPolicy::Overwrite, uploader->policy());
270+ EXPECT_EQ(contents.size(), uploader->sizeInBytes());
271+
272+ {
273+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
274+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
275+ auto arg = spy.takeFirst();
276+ EXPECT_EQ(Uploader::Status::Ready, qvariant_cast<Uploader::Status>(arg.at(0)));
277+ }
278+
279+ EXPECT_EQ(contents.size(), uploader->write(contents));
280+
281+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
282+ uploader->finishUpload();
283+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
284+ auto arg = spy.takeFirst();
285+ EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0)));
286+
287+ EXPECT_EQ(Uploader::Status::Finished, uploader->status());
288+ EXPECT_EQ(child, uploader->item());
289+}
290+
291+TEST_F(CreateFileTest, runtime_destroyed)
292+{
293+ set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
294+
295+ Item root;
296+ {
297+ unique_ptr<ItemJob> j(acc_.get("root_id"));
298+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
299+ spy.wait(SIGNAL_WAIT_TIME);
300+ root = j->item();
301+ }
302+
303+ Item child;
304+ {
305+ unique_ptr<ItemJob> j(acc_.get("child_id"));
306+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
307+ spy.wait(SIGNAL_WAIT_TIME);
308+ child = j->item();
309+ }
310+
311+ EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime
312+
313+ QByteArray contents("Hello world", -1);
314+ unique_ptr<Uploader> uploader(root.createFile("Child",
315+ Item::ConflictPolicy::Overwrite,
316+ contents.size(),
317+ ""));
318+ EXPECT_FALSE(uploader->isValid());
319+ EXPECT_EQ(Uploader::Status::Error, uploader->status());
320+ EXPECT_EQ(StorageError::Type::RuntimeDestroyed, uploader->error().type());
321+ EXPECT_EQ("Item::createFile(): Runtime was destroyed previously", uploader->error().message());
322+
323+ // Signal must be received.
324+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
325+ spy.wait(SIGNAL_WAIT_TIME);
326+ ASSERT_EQ(1, spy.count());
327+ auto arg = spy.takeFirst();
328+ EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
329+}
330+
331+TEST_F(CreateFileTest, wrong_type)
332+{
333+ set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
334+
335+ Item root;
336+ {
337+ unique_ptr<ItemJob> j(acc_.get("root_id"));
338+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
339+ spy.wait(SIGNAL_WAIT_TIME);
340+ root = j->item();
341+ }
342+
343+ Item child;
344+ {
345+ unique_ptr<ItemJob> j(acc_.get("child_id"));
346+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
347+ spy.wait(SIGNAL_WAIT_TIME);
348+ child = j->item();
349+ }
350+
351+ QByteArray contents("Hello world", -1);
352+ unique_ptr<Uploader> uploader(child.createFile("somefile",
353+ Item::ConflictPolicy::Overwrite,
354+ contents.size(),
355+ ""));
356+ EXPECT_FALSE(uploader->isValid());
357+ EXPECT_EQ(Uploader::Status::Error, uploader->status());
358+ EXPECT_EQ(StorageError::Type::LogicError, uploader->error().type());
359+ EXPECT_EQ("Item::createFile(): cannot create a file with a file as the parent", uploader->error().message());
360+
361+ // Signal must be received.
362+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
363+ spy.wait(SIGNAL_WAIT_TIME);
364+ ASSERT_EQ(1, spy.count());
365+ auto arg = spy.takeFirst();
366+ EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
367+}
368+
369+TEST_F(CreateFileTest, bad_name)
370+{
371+ set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
372+
373+ Item root;
374+ {
375+ unique_ptr<ItemJob> j(acc_.get("root_id"));
376+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
377+ spy.wait(SIGNAL_WAIT_TIME);
378+ root = j->item();
379+ }
380+
381+ Item child;
382+ {
383+ unique_ptr<ItemJob> j(acc_.get("child_id"));
384+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
385+ spy.wait(SIGNAL_WAIT_TIME);
386+ child = j->item();
387+ }
388+
389+ QByteArray contents("Hello world", -1);
390+ unique_ptr<Uploader> uploader(root.createFile("",
391+ Item::ConflictPolicy::Overwrite,
392+ contents.size(),
393+ ""));
394+ EXPECT_FALSE(uploader->isValid());
395+ EXPECT_EQ(Uploader::Status::Error, uploader->status());
396+ EXPECT_EQ(StorageError::Type::InvalidArgument, uploader->error().type());
397+ EXPECT_EQ("Item::createFile(): name cannot be empty", uploader->error().message());
398+
399+ // Signal must be received.
400+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
401+ spy.wait(SIGNAL_WAIT_TIME);
402+ ASSERT_EQ(1, spy.count());
403+ auto arg = spy.takeFirst();
404+ EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
405+}
406+
407+TEST_F(CreateFileTest, bad_size)
408+{
409+ set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
410+
411+ Item root;
412+ {
413+ unique_ptr<ItemJob> j(acc_.get("root_id"));
414+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
415+ spy.wait(SIGNAL_WAIT_TIME);
416+ root = j->item();
417+ }
418+
419+ Item child;
420+ {
421+ unique_ptr<ItemJob> j(acc_.get("child_id"));
422+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
423+ spy.wait(SIGNAL_WAIT_TIME);
424+ child = j->item();
425+ }
426+
427+ QByteArray contents("Hello world", -1);
428+ unique_ptr<Uploader> uploader(root.createFile("some_file",
429+ Item::ConflictPolicy::Overwrite,
430+ -1,
431+ ""));
432+ EXPECT_FALSE(uploader->isValid());
433+ EXPECT_EQ(Uploader::Status::Error, uploader->status());
434+ EXPECT_EQ(StorageError::Type::InvalidArgument, uploader->error().type());
435+ EXPECT_EQ("Item::createFile(): size must be >= 0", uploader->error().message());
436+
437+ // Signal must be received.
438+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
439+ spy.wait(SIGNAL_WAIT_TIME);
440+ ASSERT_EQ(1, spy.count());
441+ auto arg = spy.takeFirst();
442+ EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
443+}
444+
445+TEST_F(CreateFileTest, bad_return_type)
446+{
447+ set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_returns_dir")));
448+
449+ Item root;
450+ {
451+ unique_ptr<ItemJob> j(acc_.get("root_id"));
452+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
453+ spy.wait(SIGNAL_WAIT_TIME);
454+ root = j->item();
455+ }
456+
457+ Item child;
458+ {
459+ unique_ptr<ItemJob> j(acc_.get("child_id"));
460+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
461+ spy.wait(SIGNAL_WAIT_TIME);
462+ child = j->item();
463+ }
464+
465+ QByteArray contents("Hello world", -1);
466+ unique_ptr<Uploader> uploader(root.createFile("some_file",
467+ Item::ConflictPolicy::Overwrite,
468+ contents.size(),
469+ ""));
470+ EXPECT_TRUE(uploader->isValid());
471+
472+ {
473+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
474+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
475+ auto arg = spy.takeFirst();
476+ EXPECT_EQ(Uploader::Status::Ready, qvariant_cast<Uploader::Status>(arg.at(0)));
477+ }
478+
479+ EXPECT_EQ(contents.size(), uploader->write(contents));
480+
481+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
482+ uploader->finishUpload();
483+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
484+ auto arg = spy.takeFirst();
485+ EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
486+
487+ EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());
488+ EXPECT_EQ("Item::createFile(): impossible folder item returned by provider", uploader->error().message());
489+}
490+
491+TEST_F(CreateFileTest, exists)
492+{
493+ set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("create_file_exists")));
494+
495+ Item root;
496+ {
497+ unique_ptr<ItemJob> j(acc_.get("root_id"));
498+ QSignalSpy spy(j.get(), &ItemJob::statusChanged);
499+ spy.wait(SIGNAL_WAIT_TIME);
500+ root = j->item();
501+ }
502+
503+ QByteArray contents("Hello world", -1);
504+ unique_ptr<Uploader> uploader(root.createFile("Child",
505+ Item::ConflictPolicy::ErrorIfConflict,
506+ contents.size(),
507+ ""));
508+ EXPECT_TRUE(uploader->isValid());
509+
510+ {
511+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
512+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
513+ auto arg = spy.takeFirst();
514+ EXPECT_EQ(Uploader::Status::Ready, qvariant_cast<Uploader::Status>(arg.at(0)));
515+ }
516+
517+ EXPECT_EQ(contents.size(), uploader->write(contents));
518+
519+ QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
520+ uploader->finishUpload();
521+ ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
522+ auto arg = spy.takeFirst();
523+ EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
524+
525+ EXPECT_EQ(StorageError::Type::Exists, uploader->error().type());
526+ EXPECT_EQ("file exists", uploader->error().message());
527+ EXPECT_EQ("child_id", uploader->error().itemId());
528+ EXPECT_EQ("Child", uploader->error().itemName());
529+ EXPECT_EQ(Item::ConflictPolicy::ErrorIfConflict, uploader->policy());
530+}
531+
532 int main(int argc, char** argv)
533 {
534 QCoreApplication app(argc, argv);

Subscribers

People subscribed via source and target branches

to all changes: