Merge lp:~michihenning/storage-framework/bug1644577 into lp:storage-framework/devel

Proposed by Michi Henning
Status: Merged
Approved by: Michi Henning
Approved revision: 97
Merged at revision: 96
Proposed branch: lp:~michihenning/storage-framework/bug1644577
Merge into: lp:storage-framework/devel
Diff against target: 537 lines (+161/-118)
6 files modified
src/qt/internal/AccountImpl.cpp (+2/-1)
src/qt/internal/ItemImpl.cpp (+10/-8)
src/qt/internal/ItemListJobImpl.cpp (+4/-6)
src/qt/internal/MultiItemListJobImpl.cpp (+1/-4)
src/qt/internal/validate.cpp (+75/-63)
tests/remote-client/remote-client_test.cpp (+69/-36)
To merge this branch: bzr merge lp:~michihenning/storage-framework/bug1644577
Reviewer Review Type Date Requested Status
unity-api-1-bot continuous-integration Approve
James Henstridge Approve
Review via email: mp+311788@code.launchpad.net

Commit message

Fix for bug 1644577, fail list job if metadata for any item is incorrect.
Always emit itemsReady(), even if list is empty.
validate() failures now log the error.
Lots of improvements to log messages to provide more detail.

Description of the change

Fix for bug 1644577, fail list job if metadata for any item is incorrect.
Always emit itemsReady(), even if list is empty.
validate() failures now log the error.
Lots of improvements to log messages to provide more detail.

To post a comment you must log in.
Revision history for this message
James Henstridge (jamesh) wrote :

I've left a few inline comments.

Also, do we want to make the "unconditionally emit itemsReady" change to MultiItemListJob too?

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

FAILED: Continuous integration, rev:96
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/220/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1159/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1166
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/953
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/953/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/953/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/953
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/953/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/953/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/953
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/953/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/953/console

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

review: Needs Fixing (continuous-integration)
97. By Michi Henning

Review comments from James.

Revision history for this message
Michi Henning (michihenning) wrote :

Good catch, thanks!

Revision history for this message
James Henstridge (jamesh) wrote :

Looks good!

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

FAILED: Continuous integration, rev:97
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/221/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1164/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1171
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/957
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/957/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/957/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/957
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/957/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/957/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/957
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/957/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/957/console

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

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

PASSED: Continuous integration, rev:97
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/223/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1174
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1181
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/967
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/967/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/967
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/967/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/967
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/967/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/967
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/967/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/967
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/967/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/967
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/967/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/qt/internal/AccountImpl.cpp'
--- src/qt/internal/AccountImpl.cpp 2016-11-03 06:41:00 +0000
+++ src/qt/internal/AccountImpl.cpp 2016-11-25 04:22:53 +0000
@@ -101,7 +101,8 @@
101 {101 {
102 if (md.type != ItemType::root)102 if (md.type != ItemType::root)
103 {103 {
104 QString msg = method + ": provider returned non-root item type: " + QString::number(int(md.type));104 QString msg = method + ": provider returned non-root item type: " + QString::number(int(md.type)) +
105 " (id = " + md.item_id + ")";
105 qCritical().noquote() << msg;106 qCritical().noquote() << msg;
106 throw StorageErrorImpl::local_comms_error(msg);107 throw StorageErrorImpl::local_comms_error(msg);
107 }108 }
108109
=== modified file 'src/qt/internal/ItemImpl.cpp'
--- src/qt/internal/ItemImpl.cpp 2016-11-03 03:41:24 +0000
+++ src/qt/internal/ItemImpl.cpp 2016-11-25 04:22:53 +0000
@@ -153,7 +153,7 @@
153 {153 {
154 if (md.type == ItemType::file)154 if (md.type == ItemType::file)
155 {155 {
156 QString msg = method + ": provider returned a file as a parent";156 QString msg = method + ": provider returned a file as a parent (id = " + md.item_id + ")";
157 qCritical().noquote() << msg;157 qCritical().noquote() << msg;
158 throw StorageErrorImpl::local_comms_error(msg);158 throw StorageErrorImpl::local_comms_error(msg);
159 }159 }
@@ -178,7 +178,8 @@
178 ||178 ||
179 (md_.type != ItemType::file && md.type == ItemType::file))179 (md_.type != ItemType::file && md.type == ItemType::file))
180 {180 {
181 QString msg = method + ": source and target item type differ";181 QString msg = method + "provider error: source and target item type differ (source id = " +
182 md_.item_id + ", target id = " + md.item_id + ")";
182 qCritical().noquote() << msg;183 qCritical().noquote() << msg;
183 throw StorageErrorImpl::local_comms_error(msg);184 throw StorageErrorImpl::local_comms_error(msg);
184 }185 }
@@ -203,7 +204,7 @@
203 {204 {
204 if (md.type == ItemType::root)205 if (md.type == ItemType::root)
205 {206 {
206 QString msg = method + ": impossible root item returned by provider";207 QString msg = method + ": impossible root item returned by provider (id = " + md.item_id + ")";
207 qCritical().noquote() << msg;208 qCritical().noquote() << msg;
208 throw StorageErrorImpl::local_comms_error(msg);209 throw StorageErrorImpl::local_comms_error(msg);
209 }210 }
@@ -211,7 +212,8 @@
211 ||212 ||
212 (md_.type != ItemType::file && md.type == ItemType::file))213 (md_.type != ItemType::file && md.type == ItemType::file))
213 {214 {
214 QString msg = method + ": provider error: source and target item type differ";215 QString msg = method + ": provider error: source and target item type differ (source id = " +
216 md_.item_id + ", target id = " + md.item_id + ")";
215 qCritical().noquote() << msg;217 qCritical().noquote() << msg;
216 throw StorageErrorImpl::local_comms_error(msg);218 throw StorageErrorImpl::local_comms_error(msg);
217 }219 }
@@ -266,7 +268,7 @@
266 {268 {
267 if (md.type != storage::ItemType::file)269 if (md.type != storage::ItemType::file)
268 {270 {
269 QString msg = method + ": impossible folder item returned by provider";271 QString msg = method + ": impossible folder item returned by provider (id = " + md.item_id + ")";
270 qCritical().noquote() << msg;272 qCritical().noquote() << msg;
271 throw StorageErrorImpl::local_comms_error(msg);273 throw StorageErrorImpl::local_comms_error(msg);
272 }274 }
@@ -318,7 +320,7 @@
318 {320 {
319 if (md.type == storage::ItemType::root)321 if (md.type == storage::ItemType::root)
320 {322 {
321 QString msg = method + ": impossible root item returned by provider";323 QString msg = method + ": impossible root item returned by provider (id = " + md.item_id + ")";
322 qCritical().noquote() << msg;324 qCritical().noquote() << msg;
323 throw StorageErrorImpl::local_comms_error(msg);325 throw StorageErrorImpl::local_comms_error(msg);
324 }326 }
@@ -379,7 +381,7 @@
379 {381 {
380 return;382 return;
381 }383 }
382 QString msg = method + ": impossible file item returned by provider";384 QString msg = method + ": impossible file item returned by provider (id = " + md.item_id + ")";
383 qCritical().noquote() << msg;385 qCritical().noquote() << msg;
384 throw StorageErrorImpl::local_comms_error(msg);386 throw StorageErrorImpl::local_comms_error(msg);
385 };387 };
@@ -423,7 +425,7 @@
423 {425 {
424 if (md.type != storage::ItemType::file)426 if (md.type != storage::ItemType::file)
425 {427 {
426 QString msg = method + ": impossible folder item returned by provider";428 QString msg = method + ": impossible folder item returned by provider (id = " + md.item_id + ")";
427 qCritical().noquote() << msg;429 qCritical().noquote() << msg;
428 throw StorageErrorImpl::local_comms_error(msg);430 throw StorageErrorImpl::local_comms_error(msg);
429 }431 }
430432
=== modified file 'src/qt/internal/ItemListJobImpl.cpp'
--- src/qt/internal/ItemListJobImpl.cpp 2016-10-12 07:23:15 +0000
+++ src/qt/internal/ItemListJobImpl.cpp 2016-11-25 04:22:53 +0000
@@ -62,16 +62,14 @@
62 auto item = ItemImpl::make_item(method_, md, account_impl_);62 auto item = ItemImpl::make_item(method_, md, account_impl_);
63 items.append(item);63 items.append(item);
64 }64 }
65 catch (StorageError const&)65 catch (StorageError const& e)
66 {66 {
67 // Bad metadata received from provider, validate_() or make_item() have logged it.67 // Bad metadata received from provider, validate_() or make_item() have logged it.
68 error_ = e;
68 }69 }
69 }70 }
70 status_ = ItemListJob::Status::Finished;71 status_ = error_.type() == StorageError::NoError ? ItemListJob::Finished : ItemListJob::Error;
71 if (!items.isEmpty())72 Q_EMIT public_instance_->itemsReady(items);
72 {
73 Q_EMIT public_instance_->itemsReady(items);
74 }
75 Q_EMIT public_instance_->statusChanged(status_);73 Q_EMIT public_instance_->statusChanged(status_);
76 };74 };
7775
7876
=== modified file 'src/qt/internal/MultiItemListJobImpl.cpp'
--- src/qt/internal/MultiItemListJobImpl.cpp 2016-10-12 07:23:15 +0000
+++ src/qt/internal/MultiItemListJobImpl.cpp 2016-11-25 04:22:53 +0000
@@ -86,10 +86,7 @@
86 {86 {
87 status_ = ItemListJob::Status::Finished;87 status_ = ItemListJob::Status::Finished;
88 }88 }
89 if (!items.isEmpty())89 Q_EMIT public_instance_->itemsReady(items);
90 {
91 Q_EMIT public_instance_->itemsReady(items);
92 }
93 if (token.isEmpty())90 if (token.isEmpty())
94 {91 {
95 Q_EMIT public_instance_->statusChanged(status_);92 Q_EMIT public_instance_->statusChanged(status_);
9693
=== modified file 'src/qt/internal/validate.cpp'
--- src/qt/internal/validate.cpp 2016-11-02 06:06:32 +0000
+++ src/qt/internal/validate.cpp 2016-11-25 04:22:53 +0000
@@ -110,69 +110,81 @@
110{110{
111 using namespace unity::storage::metadata;111 using namespace unity::storage::metadata;
112112
113 QString prefix = method + ": received invalid metadata from provider: ";113 QString prefix = method + ": received invalid metadata from provider";
114114 if (!md.item_id.isEmpty())
115 // Basic sanity checks for mandatory fields.115 {
116 if (md.item_id.isEmpty())116 prefix += " (id = " + md.item_id + ")";
117 {117 }
118 throw StorageErrorImpl::local_comms_error(prefix + "item_id cannot be empty");118 prefix += ": ";
119 }119
120 if (md.type != ItemType::root)120 try
121 {121 {
122 if (md.parent_ids.isEmpty())122 // Basic sanity checks for mandatory fields.
123 {123 if (md.item_id.isEmpty())
124 throw StorageErrorImpl::local_comms_error(prefix + "file or folder must have at least one parent ID");124 {
125 }125 throw StorageErrorImpl::local_comms_error(prefix + "item_id cannot be empty");
126 for (int i = 0; i < md.parent_ids.size(); ++i)126 }
127 {127 if (md.type != ItemType::root)
128 if (md.parent_ids.at(i).isEmpty())128 {
129 {129 if (md.parent_ids.isEmpty())
130 throw StorageErrorImpl::local_comms_error(prefix + "parent_id of file or folder cannot be empty");130 {
131 }131 throw StorageErrorImpl::local_comms_error(prefix + "file or folder must have at least one parent ID");
132 }132 }
133 }133 for (int i = 0; i < md.parent_ids.size(); ++i)
134 if (md.type == ItemType::root && !md.parent_ids.isEmpty())134 {
135 {135 if (md.parent_ids.at(i).isEmpty())
136 throw StorageErrorImpl::local_comms_error(prefix + "parent_ids of root must be empty");136 {
137 }137 throw StorageErrorImpl::local_comms_error(prefix + "parent_id of file or folder cannot be empty");
138 if (md.type != ItemType::root) // Dropbox does not support metadata for roots.138 }
139 {139 }
140 if (md.name.isEmpty())140 }
141 {141 if (md.type == ItemType::root && !md.parent_ids.isEmpty())
142 throw StorageErrorImpl::local_comms_error(prefix + "name cannot be empty");142 {
143 }143 throw StorageErrorImpl::local_comms_error(prefix + "parent_ids of root must be empty");
144 }144 }
145 if (md.type == ItemType::file && md.etag.isEmpty()) // WebDav doesn't do etag for folders.145 if (md.type != ItemType::root) // Dropbox does not support metadata for roots.
146 {146 {
147 throw StorageErrorImpl::local_comms_error(prefix + "etag of a file cannot be empty");147 if (md.name.isEmpty())
148 }148 {
149149 throw StorageErrorImpl::local_comms_error(prefix + "name cannot be empty");
150 // Sanity check metadata to make sure only known metadata keys appear.150 }
151 QMapIterator<QString, QVariant> actual(md.metadata);151 }
152 while (actual.hasNext())152 if (md.type == ItemType::file && md.etag.isEmpty()) // WebDav doesn't do etag for folders.
153 {153 {
154 actual.next();154 throw StorageErrorImpl::local_comms_error(prefix + "etag of a file cannot be empty");
155 auto known = known_metadata.find(actual.key().toStdString());155 }
156 if (known == known_metadata.end())156
157 {157 // Sanity check metadata to make sure only known metadata keys appear.
158 qWarning().noquote().nospace() << prefix << "unknown metadata key: \"" << actual.key() << "\"";158 QMapIterator<QString, QVariant> actual(md.metadata);
159 }159 while (actual.hasNext())
160 else160 {
161 {161 actual.next();
162 validate_type_and_value(prefix, actual, known);162 auto known = known_metadata.find(actual.key().toStdString());
163 }163 if (known == known_metadata.end())
164 }164 {
165165 qWarning().noquote().nospace() << prefix << "unknown metadata key: \"" << actual.key() << "\"";
166 // Sanity check metadata to make sure that mandatory fields are present.166 }
167 if (md.type == ItemType::file)167 else
168 {168 {
169 if (!md.metadata.contains(metadata::SIZE_IN_BYTES) ||169 validate_type_and_value(prefix, actual, known);
170 !md.metadata.contains(metadata::LAST_MODIFIED_TIME))170 }
171 {171 }
172 QString msg = prefix + "missing key \"" + metadata::SIZE_IN_BYTES + "\" "172
173 "in metadata for \"" + md.item_id + "\"";173 // Sanity check metadata to make sure that mandatory fields are present.
174 throw StorageErrorImpl::local_comms_error(msg);174 if (md.type == ItemType::file)
175 }175 {
176 if (!md.metadata.contains(metadata::SIZE_IN_BYTES) ||
177 !md.metadata.contains(metadata::LAST_MODIFIED_TIME))
178 {
179 QString msg = prefix + "missing key \"" + metadata::SIZE_IN_BYTES + "\" in metadata";
180 throw StorageErrorImpl::local_comms_error(msg);
181 }
182 }
183 }
184 catch (StorageError const& e)
185 {
186 qCritical().noquote() << e.errorString();
187 throw;
176 }188 }
177}189}
178190
179191
=== modified file 'tests/remote-client/remote-client_test.cpp'
--- tests/remote-client/remote-client_test.cpp 2016-11-04 07:33:07 +0000
+++ tests/remote-client/remote-client_test.cpp 2016-11-25 04:22:53 +0000
@@ -504,11 +504,23 @@
504 QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady);504 QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady);
505 QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged);505 QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged);
506 status_spy.wait(SIGNAL_WAIT_TIME);506 status_spy.wait(SIGNAL_WAIT_TIME);
507 auto arg = status_spy.takeFirst();507 {
508508 auto arg = status_spy.takeFirst();
509 // Bad metadata is ignored, so status is finished, and itemsReady was never called.509 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));
510 EXPECT_EQ(ItemListJob::Status::Finished, qvariant_cast<ItemListJob::Status>(arg.at(0)));510 }
511 EXPECT_EQ(0, status_spy.count());511
512 if (ready_spy.count() != 1)
513 {
514 ready_spy.wait(SIGNAL_WAIT_TIME);
515 }
516 auto arg = ready_spy.takeFirst();
517 auto items = qvariant_cast<QList<Item>>(arg.at(0));
518 EXPECT_EQ(0, items.size());
519
520 EXPECT_EQ(ItemListJob::Status::Error, j->status());
521 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());
522 EXPECT_EQ("LocalCommsError: Account::roots(): provider returned non-root item type: 0 (id = root_id)",
523 j->error().errorString());
512}524}
513525
514TEST_F(GetTest, basic)526TEST_F(GetTest, basic)
@@ -679,8 +691,9 @@
679 spy.wait(SIGNAL_WAIT_TIME);691 spy.wait(SIGNAL_WAIT_TIME);
680692
681 EXPECT_EQ(ItemJob::Status::Error, j->status());693 EXPECT_EQ(ItemJob::Status::Error, j->status());
682 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "694 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
683 "file or folder must have at least one parent ID", j->error().errorString());695 "file or folder must have at least one parent ID"
696 , j->error().errorString());
684}697}
685698
686TEST_F(MetadataTest, empty_parent)699TEST_F(MetadataTest, empty_parent)
@@ -693,8 +706,9 @@
693 spy.wait(SIGNAL_WAIT_TIME);706 spy.wait(SIGNAL_WAIT_TIME);
694707
695 EXPECT_EQ(ItemJob::Status::Error, j->status());708 EXPECT_EQ(ItemJob::Status::Error, j->status());
696 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "709 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
697 "parent_id of file or folder cannot be empty", j->error().errorString());710 "parent_id of file or folder cannot be empty",
711 j->error().errorString());
698}712}
699713
700TEST_F(MetadataTest, root_with_parent)714TEST_F(MetadataTest, root_with_parent)
@@ -707,8 +721,9 @@
707 spy.wait(SIGNAL_WAIT_TIME);721 spy.wait(SIGNAL_WAIT_TIME);
708722
709 EXPECT_EQ(ItemJob::Status::Error, j->status());723 EXPECT_EQ(ItemJob::Status::Error, j->status());
710 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "724 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = root_id): "
711 "parent_ids of root must be empty", j->error().errorString());725 "parent_ids of root must be empty",
726 j->error().errorString());
712}727}
713728
714TEST_F(MetadataTest, empty_name)729TEST_F(MetadataTest, empty_name)
@@ -721,8 +736,9 @@
721 spy.wait(SIGNAL_WAIT_TIME);736 spy.wait(SIGNAL_WAIT_TIME);
722737
723 EXPECT_EQ(ItemJob::Status::Error, j->status());738 EXPECT_EQ(ItemJob::Status::Error, j->status());
724 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "739 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
725 "name cannot be empty", j->error().errorString());740 "name cannot be empty",
741 j->error().errorString());
726}742}
727743
728TEST_F(MetadataTest, empty_etag)744TEST_F(MetadataTest, empty_etag)
@@ -735,8 +751,9 @@
735 spy.wait(SIGNAL_WAIT_TIME);751 spy.wait(SIGNAL_WAIT_TIME);
736752
737 EXPECT_EQ(ItemJob::Status::Error, j->status());753 EXPECT_EQ(ItemJob::Status::Error, j->status());
738 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "754 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
739 "etag of a file cannot be empty", j->error().errorString());755 "etag of a file cannot be empty",
756 j->error().errorString());
740}757}
741758
742TEST_F(MetadataTest, unknown_key)759TEST_F(MetadataTest, unknown_key)
@@ -762,8 +779,9 @@
762 spy.wait(SIGNAL_WAIT_TIME);779 spy.wait(SIGNAL_WAIT_TIME);
763780
764 EXPECT_EQ(ItemJob::Status::Error, j->status());781 EXPECT_EQ(ItemJob::Status::Error, j->status());
765 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "782 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
766 "missing key \"size_in_bytes\" in metadata for \"child_id\"", j->error().errorString());783 "missing key \"size_in_bytes\" in metadata",
784 j->error().errorString());
767}785}
768786
769TEST_F(MetadataTest, wrong_type_for_time)787TEST_F(MetadataTest, wrong_type_for_time)
@@ -776,8 +794,9 @@
776 spy.wait(SIGNAL_WAIT_TIME);794 spy.wait(SIGNAL_WAIT_TIME);
777795
778 EXPECT_EQ(ItemJob::Status::Error, j->status());796 EXPECT_EQ(ItemJob::Status::Error, j->status());
779 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "797 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
780 "expected value of type QString, but received value of type qlonglong", j->error().errorString());798 "last_modified_time: expected value of type QString, but received value of type qlonglong",
799 j->error().errorString());
781}800}
782801
783TEST_F(MetadataTest, bad_parse_for_time)802TEST_F(MetadataTest, bad_parse_for_time)
@@ -790,8 +809,9 @@
790 spy.wait(SIGNAL_WAIT_TIME);809 spy.wait(SIGNAL_WAIT_TIME);
791810
792 EXPECT_EQ(ItemJob::Status::Error, j->status());811 EXPECT_EQ(ItemJob::Status::Error, j->status());
793 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "812 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
794 "value \"xyz\" does not parse as ISO-8601 date", j->error().errorString());813 "last_modified_time: value \"xyz\" does not parse as ISO-8601 date",
814 j->error().errorString());
795}815}
796816
797TEST_F(MetadataTest, missing_timezone)817TEST_F(MetadataTest, missing_timezone)
@@ -804,8 +824,9 @@
804 spy.wait(SIGNAL_WAIT_TIME);824 spy.wait(SIGNAL_WAIT_TIME);
805825
806 EXPECT_EQ(ItemJob::Status::Error, j->status());826 EXPECT_EQ(ItemJob::Status::Error, j->status());
807 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "827 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
808 "value \"2007-04-05T14:30\" lacks a time zone specification", j->error().errorString());828 "last_modified_time: value \"2007-04-05T14:30\" lacks a time zone specification",
829 j->error().errorString());
809}830}
810831
811TEST_F(MetadataTest, wrong_type_for_size)832TEST_F(MetadataTest, wrong_type_for_size)
@@ -818,8 +839,9 @@
818 spy.wait(SIGNAL_WAIT_TIME);839 spy.wait(SIGNAL_WAIT_TIME);
819840
820 EXPECT_EQ(ItemJob::Status::Error, j->status());841 EXPECT_EQ(ItemJob::Status::Error, j->status());
821 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: size_in_bytes: "842 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
822 "expected value of type qlonglong, but received value of type QString", j->error().errorString());843 "size_in_bytes: expected value of type qlonglong, but received value of type QString",
844 j->error().errorString());
823}845}
824846
825TEST_F(MetadataTest, negative_size)847TEST_F(MetadataTest, negative_size)
@@ -832,8 +854,9 @@
832 spy.wait(SIGNAL_WAIT_TIME);854 spy.wait(SIGNAL_WAIT_TIME);
833855
834 EXPECT_EQ(ItemJob::Status::Error, j->status());856 EXPECT_EQ(ItemJob::Status::Error, j->status());
835 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: size_in_bytes: "857 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
836 "expected value >= 0, but received -1", j->error().errorString());858 "size_in_bytes: expected value >= 0, but received -1",
859 j->error().errorString());
837}860}
838861
839TEST_F(DeleteTest, basic)862TEST_F(DeleteTest, basic)
@@ -1485,7 +1508,7 @@
1485 auto arg = spy.takeFirst();1508 auto arg = spy.takeFirst();
1486 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));1509 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));
14871510
1488 EXPECT_EQ("Item::parents(): provider returned a file as a parent", j->error().message());1511 EXPECT_EQ("Item::parents(): provider returned a file as a parent (id = root_id)", j->error().message());
1489 }1512 }
1490}1513}
14911514
@@ -1751,7 +1774,9 @@
1751 EXPECT_FALSE(j->isValid());1774 EXPECT_FALSE(j->isValid());
1752 EXPECT_EQ(ItemJob::Status::Error, j->status());1775 EXPECT_EQ(ItemJob::Status::Error, j->status());
1753 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());1776 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());
1754 EXPECT_EQ("LocalCommsError: Item::copy(): source and target item type differ", j->error().errorString());1777 EXPECT_EQ("LocalCommsError: Item::copy()provider error: source and target item type differ "
1778 "(source id = child_id, target id = new_item_id)",
1779 j->error().errorString());
1755}1780}
17561781
1757TEST_F(MoveTest, basic)1782TEST_F(MoveTest, basic)
@@ -1863,7 +1888,8 @@
1863 EXPECT_EQ(ItemJob::Status::Error, j->status());1888 EXPECT_EQ(ItemJob::Status::Error, j->status());
1864 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());1889 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());
1865 EXPECT_EQ("LocalCommsError", j->error().name());1890 EXPECT_EQ("LocalCommsError", j->error().name());
1866 EXPECT_EQ("LocalCommsError: Item::move(): impossible root item returned by provider", j->error().errorString());1891 EXPECT_EQ("LocalCommsError: Item::move(): impossible root item returned by provider (id = root_id)",
1892 j->error().errorString());
1867}1893}
18681894
1869TEST_F(MoveTest, type_mismatch)1895TEST_F(MoveTest, type_mismatch)
@@ -1899,7 +1925,8 @@
1899 EXPECT_FALSE(j->isValid());1925 EXPECT_FALSE(j->isValid());
1900 EXPECT_EQ(ItemJob::Status::Error, j->status());1926 EXPECT_EQ(ItemJob::Status::Error, j->status());
1901 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());1927 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());
1902 EXPECT_EQ("LocalCommsError: Item::move(): provider error: source and target item type differ",1928 EXPECT_EQ("LocalCommsError: Item::move(): provider error: source and target item type differ "
1929 "(source id = child_id, target id = child_id)",
1903 j->error().errorString());1930 j->error().errorString());
1904}1931}
19051932
@@ -2094,7 +2121,7 @@
2094 auto status = qvariant_cast<ItemJob::Status>(arg.at(0));2121 auto status = qvariant_cast<ItemJob::Status>(arg.at(0));
2095 EXPECT_EQ(ItemJob::Status::Error, status);2122 EXPECT_EQ(ItemJob::Status::Error, status);
20962123
2097 EXPECT_EQ("LocalCommsError: Item::createFolder(): impossible file item returned by provider",2124 EXPECT_EQ("LocalCommsError: Item::createFolder(): impossible file item returned by provider (id = new_folder_id)",
2098 j->error().errorString());2125 j->error().errorString());
2099}2126}
21002127
@@ -2157,7 +2184,10 @@
2157 QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady);2184 QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady);
2158 QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged);2185 QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged);
2159 status_spy.wait(SIGNAL_WAIT_TIME);2186 status_spy.wait(SIGNAL_WAIT_TIME);
2160 ASSERT_EQ(0, ready_spy.count());2187 if (ready_spy.count() == 0)
2188 {
2189 ASSERT_TRUE(ready_spy.wait(SIGNAL_WAIT_TIME));
2190 }
21612191
2162 EXPECT_EQ(ItemListJob::Status::Finished, j->status());2192 EXPECT_EQ(ItemListJob::Status::Finished, j->status());
21632193
@@ -2303,7 +2333,8 @@
2303 auto arg = spy.takeFirst();2333 auto arg = spy.takeFirst();
2304 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));2334 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));
23052335
2306 EXPECT_EQ("LocalCommsError: Item::list(): impossible root item returned by provider", j->error().errorString());2336 EXPECT_EQ("LocalCommsError: Item::list(): impossible root item returned by provider (id = child_id)",
2337 j->error().errorString());
2307}2338}
23082339
2309TEST_F(ListTest, runtime_destroyed_while_item_list_job_running)2340TEST_F(ListTest, runtime_destroyed_while_item_list_job_running)
@@ -3370,7 +3401,8 @@
33703401
3371 EXPECT_EQ(Uploader::Status::Error, uploader->status());3402 EXPECT_EQ(Uploader::Status::Error, uploader->status());
3372 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());3403 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());
3373 EXPECT_EQ("Item::createUploader(): impossible folder item returned by provider", uploader->error().message());3404 EXPECT_EQ("Item::createUploader(): impossible folder item returned by provider (id = some_id)",
3405 uploader->error().message());
3374}3406}
33753407
3376TEST_F(UploadTest, cancel_success)3408TEST_F(UploadTest, cancel_success)
@@ -3702,7 +3734,8 @@
3702 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));3734 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
37033735
3704 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());3736 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());
3705 EXPECT_EQ("Item::createFile(): impossible folder item returned by provider", uploader->error().message());3737 EXPECT_EQ("Item::createFile(): impossible folder item returned by provider (id = some_id)",
3738 uploader->error().message());
3706}3739}
37073740
3708TEST_F(CreateFileTest, exists)3741TEST_F(CreateFileTest, exists)

Subscribers

People subscribed via source and target branches

to all changes: