Merge lp:~michihenning/storage-framework/use-qiodevice into lp:storage-framework/devel

Proposed by Michi Henning
Status: Merged
Approved by: James Henstridge
Approved revision: 96
Merged at revision: 90
Proposed branch: lp:~michihenning/storage-framework/use-qiodevice
Merge into: lp:storage-framework/devel
Prerequisite: lp:~michihenning/storage-framework/metadata-keys
Diff against target: 2011 lines (+568/-498)
16 files modified
include/unity/storage/qt/Downloader.h (+14/-5)
include/unity/storage/qt/Uploader.h (+15/-4)
include/unity/storage/qt/client/internal/remote_client/HandlerBase.h (+1/-0)
include/unity/storage/qt/internal/DownloaderImpl.h (+12/-1)
include/unity/storage/qt/internal/Handler.h (+6/-0)
include/unity/storage/qt/internal/HandlerBase.h (+0/-2)
include/unity/storage/qt/internal/ListJobImplBase.h (+1/-0)
include/unity/storage/qt/internal/UploaderImpl.h (+18/-1)
include/unity/storage/qt/internal/VoidJobImpl.h (+1/-0)
src/qt/Downloader.cpp (+48/-5)
src/qt/Uploader.cpp (+48/-5)
src/qt/internal/DownloaderImpl.cpp (+97/-41)
src/qt/internal/HandlerBase.cpp (+1/-0)
src/qt/internal/UploaderImpl.cpp (+171/-59)
tests/remote-client/MockProvider.cpp (+4/-10)
tests/remote-client/remote-client_test.cpp (+131/-365)
To merge this branch: bzr merge lp:~michihenning/storage-framework/use-qiodevice
Reviewer Review Type Date Requested Status
James Henstridge Approve
unity-api-1-bot continuous-integration Approve
Review via email: mp+309713@code.launchpad.net

Commit message

Changed Uploader and Downloader to derive from QIODevice.

Description of the change

Changed Uploader and Downloader to derive from QIODevice.

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:88
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/162/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/928
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/935
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/738/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/738/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/738/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/738/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/738/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/738/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/738/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/738/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/738
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/738/artifact/output/*zip*/output.zip

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

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

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

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

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

Merged dependent branch.

91. By Michi Henning

Merged dependent branch.

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

FAILED: Continuous integration, rev:90
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/169/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/947/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/954
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/757/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/757
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/757/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/757
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/757/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/757/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/757
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/757/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/757
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/757/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/757/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/757
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/757/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/757
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/757/artifact/output/*zip*/output.zip

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

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

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

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

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

I've noted a few small issues via inline comments

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

I removed the stale file from the merge conflict and got rid of the redundant Q_INVOKABLE, thanks!

For the uploader, my thinking was that the caller should not write to the uploader until it enters the Ready state.

I need to check what happens if a write is done before then. I would expect the write to return an error seeing that underlying socket isn't connected at that point. (If that isn't the case, we can easily arrange for the write to return -1.)

I think forcing the caller to wait until the socket is ready is better than buffering the data. After all, the socket may not ever become ready due to an error (such as the server side going belly-up for some reason) and, if the client is allowed to write regardless, all the data just ends up piling up in memory.

92. By Michi Henning

Got rid of merge conflict file and redundant Q_INVOKABLEs.

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

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

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

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

Merged devel.

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

The Uploader QIODevice is in its open state.

The expected semantics are that you can write to the device and those writes will be buffered, with the bytesWritten signal being used to notify when the write has completed.

While it is possible to signal an error, it seems that this is generally used for hard errors rather than simple "can't complete the write right now" errors. So if we throw away the early writes, we're effectively breaking the contract.

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

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

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

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

Added code to deal with synchronous wait on uploader.
Not tested yet, because we need to make changes to the mock provider harness for this.

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

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

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

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

This looks very close to ready. I've left a few inline comments. Some are just stylistic so could be ignored, so some could be left as is.

95. By Michi Henning

Review comments from James.

96. By Michi Henning

Renamed finishUpload() and finishDownload() to close().

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

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

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/187/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
=== modified file 'include/unity/storage/qt/Downloader.h'
--- include/unity/storage/qt/Downloader.h 2016-10-31 02:01:05 +0000
+++ include/unity/storage/qt/Downloader.h 2016-11-04 07:34:14 +0000
@@ -36,7 +36,7 @@
3636
37} // namespace internal37} // namespace internal
3838
39class Q_DECL_EXPORT Downloader final : public QLocalSocket39class Q_DECL_EXPORT Downloader final : public QIODevice
40{40{
41 Q_OBJECT41 Q_OBJECT
42 Q_PROPERTY(bool isValid READ isValid NOTIFY statusChanged FINAL)42 Q_PROPERTY(bool isValid READ isValid NOTIFY statusChanged FINAL)
@@ -51,15 +51,21 @@
51 Downloader();51 Downloader();
52 virtual ~Downloader();52 virtual ~Downloader();
5353
54 bool isValid() const; // Not nice, hides QLocalSocket::isValid()54 bool isValid() const;
55 Status status() const;55 Status status() const;
56 StorageError error() const; // Not nice, hides QLocalSocket::error()56 StorageError error() const;
57 Item item() const;57 Item item() const;
5858
59 Q_INVOKABLE void finishDownload();
60 Q_INVOKABLE void cancel();59 Q_INVOKABLE void cancel();
6160
62 // TODO: will probably need QML invokable methods for reading and writing to/from QIODevice61 // From QLocalSocket interface.
62 Q_INVOKABLE void close();
63 Q_INVOKABLE qint64 bytesAvailable() const override;
64 Q_INVOKABLE qint64 bytesToWrite() const override;
65 Q_INVOKABLE bool canReadLine() const override;
66 Q_INVOKABLE bool isSequential() const override;
67 Q_INVOKABLE bool waitForBytesWritten(int msecs = 30000) override;
68 Q_INVOKABLE bool waitForReadyRead(int msecs = 30000) override;
6369
64Q_SIGNALS:70Q_SIGNALS:
65 void statusChanged(unity::storage::qt::Downloader::Status status) const;71 void statusChanged(unity::storage::qt::Downloader::Status status) const;
@@ -67,6 +73,9 @@
67private:73private:
68 Downloader(std::unique_ptr<internal::DownloaderImpl> p);74 Downloader(std::unique_ptr<internal::DownloaderImpl> p);
6975
76 qint64 readData(char* data, qint64 c);
77 qint64 writeData(char const* data, qint64 c);
78
70 std::unique_ptr<internal::DownloaderImpl> p_;79 std::unique_ptr<internal::DownloaderImpl> p_;
7180
72 friend class internal::DownloaderImpl;81 friend class internal::DownloaderImpl;
7382
=== modified file 'include/unity/storage/qt/Uploader.h'
--- include/unity/storage/qt/Uploader.h 2016-10-12 05:25:20 +0000
+++ include/unity/storage/qt/Uploader.h 2016-11-04 07:34:14 +0000
@@ -39,7 +39,7 @@
39class Item;39class Item;
40class StorageError;40class StorageError;
4141
42class Q_DECL_EXPORT Uploader final : public QLocalSocket42class Q_DECL_EXPORT Uploader final : public QIODevice
43{43{
44 Q_OBJECT44 Q_OBJECT
45 Q_PROPERTY(bool isValid READ isValid NOTIFY statusChanged FINAL)45 Q_PROPERTY(bool isValid READ isValid NOTIFY statusChanged FINAL)
@@ -56,22 +56,33 @@
56 Uploader();56 Uploader();
57 virtual ~Uploader();57 virtual ~Uploader();
5858
59 bool isValid() const; // Not nice, hides QLocalSocket::isValid()59 bool isValid() const;
60 Status status() const;60 Status status() const;
61 StorageError error() const; // Not nice, hides QLocalSocket::error()61 StorageError error() const;
62 Item::ConflictPolicy policy() const;62 Item::ConflictPolicy policy() const;
63 qint64 sizeInBytes() const;63 qint64 sizeInBytes() const;
64 Item item() const;64 Item item() const;
6565
66 Q_INVOKABLE void finishUpload();
67 Q_INVOKABLE void cancel();66 Q_INVOKABLE void cancel();
6867
68 // From QLocalSocket interface.
69 Q_INVOKABLE void close() override;
70 Q_INVOKABLE qint64 bytesAvailable() const override;
71 Q_INVOKABLE qint64 bytesToWrite() const override;
72 Q_INVOKABLE bool canReadLine() const override;
73 Q_INVOKABLE bool isSequential() const override;
74 Q_INVOKABLE bool waitForBytesWritten(int msecs = 30000) override;
75 Q_INVOKABLE bool waitForReadyRead(int msecs = 30000) override;
76
69Q_SIGNALS:77Q_SIGNALS:
70 void statusChanged(unity::storage::qt::Uploader::Status status) const;78 void statusChanged(unity::storage::qt::Uploader::Status status) const;
7179
72private:80private:
73 Uploader(std::unique_ptr<internal::UploaderImpl> p);81 Uploader(std::unique_ptr<internal::UploaderImpl> p);
7482
83 qint64 readData(char* data, qint64 c);
84 qint64 writeData(char const* data, qint64 c);
85
75 std::unique_ptr<internal::UploaderImpl> p_;86 std::unique_ptr<internal::UploaderImpl> p_;
7687
77 friend class internal::UploaderImpl;88 friend class internal::UploaderImpl;
7889
=== modified file 'include/unity/storage/qt/client/internal/remote_client/HandlerBase.h'
--- include/unity/storage/qt/client/internal/remote_client/HandlerBase.h 2016-07-13 05:12:47 +0000
+++ include/unity/storage/qt/client/internal/remote_client/HandlerBase.h 2016-11-04 07:34:14 +0000
@@ -19,6 +19,7 @@
19#pragma once19#pragma once
2020
21#pragma GCC diagnostic push21#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-Wcast-align"
22#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"23#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
23#pragma GCC diagnostic ignored "-Wswitch-default"24#pragma GCC diagnostic ignored "-Wswitch-default"
24#include <QDBusPendingCallWatcher>25#include <QDBusPendingCallWatcher>
2526
=== modified file 'include/unity/storage/qt/internal/DownloaderImpl.h'
--- include/unity/storage/qt/internal/DownloaderImpl.h 2016-10-12 07:23:15 +0000
+++ include/unity/storage/qt/internal/DownloaderImpl.h 2016-11-04 07:34:14 +0000
@@ -47,9 +47,19 @@
47 StorageError error() const;47 StorageError error() const;
48 Item item() const;48 Item item() const;
4949
50 void finishDownload();
51 void cancel();50 void cancel();
5251
52 // From QLocalSocket interface.
53 void close();
54 qint64 bytesAvailable() const;
55 qint64 bytesToWrite() const;
56 bool canReadLine() const;
57 bool isSequential() const;
58 bool waitForBytesWritten(int msecs);
59 bool waitForReadyRead(int msecs);
60 qint64 readData(char* data, qint64 c);
61 qint64 writeData(char const* data, qint64 c);
62
53 static Downloader* make_job(std::shared_ptr<ItemImpl> const& item_impl,63 static Downloader* make_job(std::shared_ptr<ItemImpl> const& item_impl,
54 QString const& method,64 QString const& method,
55 QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply);65 QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply);
@@ -62,6 +72,7 @@
62 std::shared_ptr<ItemImpl> item_impl_;72 std::shared_ptr<ItemImpl> item_impl_;
63 QString download_id_;73 QString download_id_;
64 QDBusUnixFileDescriptor fd_;74 QDBusUnixFileDescriptor fd_;
75 QLocalSocket socket_;
65 bool finalizing_ = false;76 bool finalizing_ = false;
66};77};
6778
6879
=== modified file 'include/unity/storage/qt/internal/Handler.h'
--- include/unity/storage/qt/internal/Handler.h 2016-10-12 07:23:15 +0000
+++ include/unity/storage/qt/internal/Handler.h 2016-11-04 07:34:14 +0000
@@ -102,6 +102,12 @@
102 })102 })
103 {103 {
104 }104 }
105
106 void wait_and_process_now()
107 {
108 watcher_.waitForFinished();
109 finished(&watcher_);
110 }
105};111};
106112
107} // namespace internal113} // namespace internal
108114
=== modified file 'include/unity/storage/qt/internal/HandlerBase.h'
--- include/unity/storage/qt/internal/HandlerBase.h 2016-09-21 00:29:49 +0000
+++ include/unity/storage/qt/internal/HandlerBase.h 2016-11-04 07:34:14 +0000
@@ -53,8 +53,6 @@
5353
54protected:54protected:
55 QDBusPendingCallWatcher watcher_;55 QDBusPendingCallWatcher watcher_;
56
57private:
58 std::function<void(QDBusPendingCallWatcher&)> closure_;56 std::function<void(QDBusPendingCallWatcher&)> closure_;
59};57};
6058
6159
=== modified file 'include/unity/storage/qt/internal/ListJobImplBase.h'
--- include/unity/storage/qt/internal/ListJobImplBase.h 2016-10-12 05:25:20 +0000
+++ include/unity/storage/qt/internal/ListJobImplBase.h 2016-11-04 07:34:14 +0000
@@ -22,6 +22,7 @@
22#include <unity/storage/qt/StorageError.h>22#include <unity/storage/qt/StorageError.h>
2323
24#pragma GCC diagnostic push24#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Wcast-align"
25#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"26#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
26#include <QDBusPendingReply>27#include <QDBusPendingReply>
27#pragma GCC diagnostic pop28#pragma GCC diagnostic pop
2829
=== modified file 'include/unity/storage/qt/internal/UploaderImpl.h'
--- include/unity/storage/qt/internal/UploaderImpl.h 2016-11-03 03:41:24 +0000
+++ include/unity/storage/qt/internal/UploaderImpl.h 2016-11-04 07:34:14 +0000
@@ -18,10 +18,12 @@
1818
19#pragma once19#pragma once
2020
21#include <unity/storage/qt/internal/Handler.h>
21#include <unity/storage/qt/Uploader.h>22#include <unity/storage/qt/Uploader.h>
2223
23#include <QDBusPendingReply>24#include <QDBusPendingReply>
24#include <QDBusUnixFileDescriptor>25#include <QDBusUnixFileDescriptor>
26#include <QPointer>
2527
26namespace unity28namespace unity
27{29{
@@ -59,9 +61,19 @@
59 qint64 sizeInBytes() const;61 qint64 sizeInBytes() const;
60 Item item() const;62 Item item() const;
6163
62 void finishUpload();
63 void cancel();64 void cancel();
6465
66 // From QLocalSocket interface.
67 void close();
68 qint64 bytesAvailable() const;
69 qint64 bytesToWrite() const;
70 bool canReadLine() const;
71 bool isSequential() const;
72 bool waitForBytesWritten(int msecs);
73 bool waitForReadyRead(int msecs);
74 qint64 readData(char* data, qint64 c);
75 qint64 writeData(char const* data, qint64 c);
76
65 static Uploader* make_job(std::shared_ptr<ItemImpl> const& item_impl,77 static Uploader* make_job(std::shared_ptr<ItemImpl> const& item_impl,
66 QString const& method,78 QString const& method,
67 QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply,79 QDBusPendingReply<QString, QDBusUnixFileDescriptor>& reply,
@@ -70,6 +82,8 @@
70 qint64 size_in_bytes);82 qint64 size_in_bytes);
71 static Uploader* make_job(StorageError const& e);83 static Uploader* make_job(StorageError const& e);
7284
85 qint64 flush_buffer();
86
73private:87private:
74 Uploader* public_instance_;88 Uploader* public_instance_;
75 Uploader::Status status_;89 Uploader::Status status_;
@@ -79,8 +93,11 @@
79 std::function<void(storage::internal::ItemMetadata const&)> validate_;93 std::function<void(storage::internal::ItemMetadata const&)> validate_;
80 Item::ConflictPolicy policy_ = Item::ConflictPolicy::IgnoreConflict;94 Item::ConflictPolicy policy_ = Item::ConflictPolicy::IgnoreConflict;
81 qint64 size_in_bytes_ = 0;95 qint64 size_in_bytes_ = 0;
96 QPointer<Handler<QDBusPendingReply<QString, QDBusUnixFileDescriptor>>> handler_;
82 QString upload_id_;97 QString upload_id_;
83 QDBusUnixFileDescriptor fd_;98 QDBusUnixFileDescriptor fd_;
99 QLocalSocket socket_;
100 QByteArray buffer_;
84 bool finalizing_ = false;101 bool finalizing_ = false;
85};102};
86103
87104
=== modified file 'include/unity/storage/qt/internal/VoidJobImpl.h'
--- include/unity/storage/qt/internal/VoidJobImpl.h 2016-10-12 08:08:48 +0000
+++ include/unity/storage/qt/internal/VoidJobImpl.h 2016-11-04 07:34:14 +0000
@@ -23,6 +23,7 @@
23#include <unity/storage/qt/StorageError.h>23#include <unity/storage/qt/StorageError.h>
2424
25#pragma GCC diagnostic push25#pragma GCC diagnostic push
26#pragma GCC diagnostic ignored "-Wcast-align"
26#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"27#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
27#include <QDBusPendingReply>28#include <QDBusPendingReply>
28#pragma GCC diagnostic pop29#pragma GCC diagnostic pop
2930
=== modified file 'src/qt/Downloader.cpp'
--- src/qt/Downloader.cpp 2016-10-11 08:12:32 +0000
+++ src/qt/Downloader.cpp 2016-11-04 07:34:14 +0000
@@ -61,16 +61,59 @@
61 return p_->item();61 return p_->item();
62}62}
6363
64void Downloader::finishDownload()
65{
66 p_->finishDownload();
67}
68
69void Downloader::cancel()64void Downloader::cancel()
70{65{
71 p_->cancel();66 p_->cancel();
72}67}
7368
69void Downloader::close()
70{
71 p_->close();
72}
73
74qint64 Downloader::bytesAvailable() const
75{
76 return p_->bytesAvailable();
77}
78
79qint64 Downloader::bytesToWrite() const
80{
81 return p_->bytesToWrite();
82}
83
84bool Downloader::canReadLine() const
85{
86 return p_->canReadLine();
87}
88
89bool Downloader::isSequential() const
90{
91 return p_->isSequential();
92}
93
94bool Downloader::waitForBytesWritten(int msecs)
95{
96 return p_->waitForBytesWritten(msecs);
97}
98
99bool Downloader::waitForReadyRead(int msecs)
100{
101 return p_->waitForReadyRead(msecs);
102}
103
104qint64 Downloader::readData(char* data, qint64 c)
105{
106 return p_->readData(data, c);
107}
108
109// LCOV_EXCL_START
110// Never called by QIODevice because device is opened read-only.
111qint64 Downloader::writeData(char const* data, qint64 c)
112{
113 return p_->writeData(data, c);
114}
115// LCOV_EXCL_STOP
116
74} // namespace qt117} // namespace qt
75} // namespace storage118} // namespace storage
76} // namespace unity119} // namespace unity
77120
=== modified file 'src/qt/Uploader.cpp'
--- src/qt/Uploader.cpp 2016-10-12 05:25:20 +0000
+++ src/qt/Uploader.cpp 2016-11-04 07:34:14 +0000
@@ -71,16 +71,59 @@
71 return p_->item();71 return p_->item();
72}72}
7373
74void Uploader::finishUpload()
75{
76 p_->finishUpload();
77}
78
79void Uploader::cancel()74void Uploader::cancel()
80{75{
81 p_->cancel();76 p_->cancel();
82}77}
8378
79void Uploader::close()
80{
81 p_->close();
82}
83
84qint64 Uploader::bytesAvailable() const
85{
86 return p_->bytesAvailable();
87}
88
89qint64 Uploader::bytesToWrite() const
90{
91 return p_->bytesToWrite();
92}
93
94bool Uploader::canReadLine() const
95{
96 return p_->canReadLine();
97}
98
99bool Uploader::isSequential() const
100{
101 return p_->isSequential();
102}
103
104bool Uploader::waitForBytesWritten(int msecs)
105{
106 return p_->waitForBytesWritten(msecs);
107}
108
109bool Uploader::waitForReadyRead(int msecs)
110{
111 return p_->waitForReadyRead(msecs);
112}
113
114// LCOV_EXCL_START
115// Never called by QIODevice because device is opened write-only.
116qint64 Uploader::readData(char* data, qint64 c)
117{
118 return p_->readData(data, c);
119}
120// LCOV_EXCL_STOP
121
122qint64 Uploader::writeData(char const* data, qint64 c)
123{
124 return p_->writeData(data, c);
125}
126
84} // namespace qt127} // namespace qt
85} // namespace storage128} // namespace storage
86} // namespace unity129} // namespace unity
87130
=== modified file 'src/qt/internal/DownloaderImpl.cpp'
--- src/qt/internal/DownloaderImpl.cpp 2016-10-13 06:48:11 +0000
+++ src/qt/internal/DownloaderImpl.cpp 2016-11-04 07:34:14 +0000
@@ -58,7 +58,7 @@
58 {58 {
59 QString msg = method + ": Runtime was destroyed previously";59 QString msg = method + ": Runtime was destroyed previously";
60 error_ = StorageErrorImpl::runtime_destroyed_error(msg);60 error_ = StorageErrorImpl::runtime_destroyed_error(msg);
61 public_instance_->abort();61 socket_.abort();
62 public_instance_->setErrorString(msg);62 public_instance_->setErrorString(msg);
63 status_ = Downloader::Status::Error;63 status_ = Downloader::Status::Error;
64 Q_EMIT public_instance_->statusChanged(status_);64 Q_EMIT public_instance_->statusChanged(status_);
@@ -73,7 +73,7 @@
73 QString msg = method + ": invalid file descriptor returned by provider";73 QString msg = method + ": invalid file descriptor returned by provider";
74 qCritical().noquote() << msg;74 qCritical().noquote() << msg;
75 error_ = StorageErrorImpl::local_comms_error(msg);75 error_ = StorageErrorImpl::local_comms_error(msg);
76 public_instance_->abort();76 socket_.abort();
77 public_instance_->setErrorString(msg);77 public_instance_->setErrorString(msg);
78 status_ = Downloader::Status::Error;78 status_ = Downloader::Status::Error;
79 Q_EMIT public_instance_->statusChanged(status_);79 Q_EMIT public_instance_->statusChanged(status_);
@@ -81,7 +81,18 @@
81 // LCOV_EXCL_STOP81 // LCOV_EXCL_STOP
82 }82 }
8383
84 public_instance_->setSocketDescriptor(fd_.fileDescriptor(), QLocalSocket::ConnectedState, QIODevice::ReadOnly);84 // We forward any QIODevice signals emitted by the socket to the public instance.
85 connect(&socket_, &QIODevice::aboutToClose, public_instance_, &QIODevice::aboutToClose);
86 connect(&socket_, &QIODevice::bytesWritten, public_instance_, &QIODevice::bytesWritten);
87 connect(&socket_, &QIODevice::readChannelFinished, public_instance_, &QIODevice::readChannelFinished);
88 connect(&socket_, &QIODevice::readyRead, public_instance_, &QIODevice::readyRead);
89
90#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
91 connect(&socket_, &QIODevice::channelBytesWritten, public_instance_, &QIODevice::channelBytesWritten);
92 connect(&socket_, &QIODevice::channelReadyRead, public_instance_, &QIODevice::channelReadyRead);
93#endif
94
95 socket_.setSocketDescriptor(fd_.fileDescriptor(), QLocalSocket::ConnectedState, QIODevice::ReadOnly);
85 status_ = Downloader::Status::Ready;96 status_ = Downloader::Status::Ready;
86 Q_EMIT public_instance_->statusChanged(status_);97 Q_EMIT public_instance_->statusChanged(status_);
87 };98 };
@@ -91,12 +102,12 @@
91 // TODO: This does not set the method102 // TODO: This does not set the method
92 error_ = error;103 error_ = error;
93 status_ = Downloader::Status::Error;104 status_ = Downloader::Status::Error;
94 public_instance_->abort();105 socket_.abort();
95 public_instance_->setErrorString(error.errorString());106 public_instance_->setErrorString(error.errorString());
96 Q_EMIT public_instance_->statusChanged(status_);107 Q_EMIT public_instance_->statusChanged(status_);
97 };108 };
98109
99 new Handler<storage::internal::ItemMetadata>(this, reply, process_reply, process_error);110 new Handler<QDBusPendingReply<QString, QDBusUnixFileDescriptor>>(this, reply, process_reply, process_error);
100}111}
101112
102DownloaderImpl::DownloaderImpl(StorageError const& e)113DownloaderImpl::DownloaderImpl(StorageError const& e)
@@ -146,11 +157,40 @@
146 return Item(item_impl_);157 return Item(item_impl_);
147}158}
148159
149void DownloaderImpl::finishDownload()160void DownloaderImpl::cancel()
150{161{
151 static QString const method = "Downloader::finishDownload()";162 static QString const method = "Downloader::cancel()";
152163
153 // If we encountered an error earlier or were cancelled, or if finishDownload() was164 // If we are in a final state already, ignore the call.
165 if ( status_ == Downloader::Status::Error
166 || status_ == Downloader::Status::Finished
167 || status_ == Downloader::Status::Cancelled)
168 {
169 return;
170 }
171 auto runtime = item_impl_->runtime_impl();
172 if (!runtime || !runtime->isValid())
173 {
174 QString msg = method + ": Runtime was destroyed previously";
175 error_ = StorageErrorImpl::runtime_destroyed_error(msg);
176 status_ = Downloader::Status::Error;
177 Q_EMIT public_instance_->statusChanged(status_);
178 return;
179 }
180
181 QString msg = method + ": download was cancelled";
182 error_ = StorageErrorImpl::cancelled_error(msg);
183 socket_.abort();
184 public_instance_->setErrorString(msg);
185 status_ = Downloader::Status::Cancelled;
186 Q_EMIT public_instance_->statusChanged(status_);
187}
188
189void DownloaderImpl::close()
190{
191 static QString const method = "Downloader::close()";
192
193 // If we encountered an error earlier or were cancelled, or if close() was
154 // called already, we ignore the call.194 // called already, we ignore the call.
155 if (status_ == Downloader::Status::Error || status_ == Downloader::Status::Cancelled || finalizing_)195 if (status_ == Downloader::Status::Error || status_ == Downloader::Status::Cancelled || finalizing_)
156 {196 {
@@ -162,7 +202,7 @@
162 {202 {
163 QString msg = method + ": cannot finalize while Downloader is not in the Ready state";203 QString msg = method + ": cannot finalize while Downloader is not in the Ready state";
164 error_ = StorageErrorImpl::logic_error(msg);204 error_ = StorageErrorImpl::logic_error(msg);
165 public_instance_->abort();205 socket_.abort();
166 public_instance_->setErrorString(msg);206 public_instance_->setErrorString(msg);
167 status_ = Downloader::Status::Error;207 status_ = Downloader::Status::Error;
168 Q_EMIT public_instance_->statusChanged(status_);208 Q_EMIT public_instance_->statusChanged(status_);
@@ -194,7 +234,7 @@
194 {234 {
195 QString msg = method + ": Runtime was destroyed previously";235 QString msg = method + ": Runtime was destroyed previously";
196 error_ = StorageErrorImpl::runtime_destroyed_error(msg);236 error_ = StorageErrorImpl::runtime_destroyed_error(msg);
197 public_instance_->abort();237 socket_.abort();
198 public_instance_->setErrorString(msg);238 public_instance_->setErrorString(msg);
199 status_ = Downloader::Status::Error;239 status_ = Downloader::Status::Error;
200 Q_EMIT public_instance_->statusChanged(status_);240 Q_EMIT public_instance_->statusChanged(status_);
@@ -214,7 +254,7 @@
214254
215 // TODO: this doesn't set the method255 // TODO: this doesn't set the method
216 error_ = error;256 error_ = error;
217 public_instance_->abort();257 socket_.abort();
218 public_instance_->setErrorString(error.errorString());258 public_instance_->setErrorString(error.errorString());
219 status_ = Downloader::Status::Error;259 status_ = Downloader::Status::Error;
220 Q_EMIT public_instance_->statusChanged(status_);260 Q_EMIT public_instance_->statusChanged(status_);
@@ -223,34 +263,48 @@
223 new Handler<void>(this, reply, process_reply, process_error);263 new Handler<void>(this, reply, process_reply, process_error);
224}264}
225265
226void DownloaderImpl::cancel()266qint64 DownloaderImpl::bytesAvailable() const
227{267{
228 static QString const method = "Downloader::cancel()";268 return socket_.bytesAvailable();
229269}
230 // If we are in a final state already, ignore the call.270
231 if ( status_ == Downloader::Status::Error271qint64 DownloaderImpl::bytesToWrite() const
232 || status_ == Downloader::Status::Finished272{
233 || status_ == Downloader::Status::Cancelled)273 return socket_.bytesToWrite();
234 {274}
235 return;275
236 }276bool DownloaderImpl::canReadLine() const
237 auto runtime = item_impl_->runtime_impl();277{
238 if (!runtime || !runtime->isValid())278 return socket_.canReadLine();
239 {279}
240 QString msg = method + ": Runtime was destroyed previously";280
241 error_ = StorageErrorImpl::runtime_destroyed_error(msg);281bool DownloaderImpl::isSequential() const
242 status_ = Downloader::Status::Error;282{
243 Q_EMIT public_instance_->statusChanged(status_);283 return socket_.isSequential();
244 return;284}
245 }285
246286bool DownloaderImpl::waitForBytesWritten(int msecs)
247 QString msg = method + ": download was cancelled";287{
248 error_ = StorageErrorImpl::cancelled_error(msg);288 return socket_.waitForBytesWritten(msecs);
249 public_instance_->abort();289}
250 public_instance_->setErrorString(msg);290
251 status_ = Downloader::Status::Cancelled;291bool DownloaderImpl::waitForReadyRead(int msecs)
252 Q_EMIT public_instance_->statusChanged(status_);292{
253}293 return socket_.waitForReadyRead(msecs);
294}
295
296qint64 DownloaderImpl::readData(char* data, qint64 c)
297{
298 return socket_.read(data, c);
299}
300
301// LCOV_EXCL_START
302// Never called by QIODevice because device is opened read-only.
303qint64 DownloaderImpl::writeData(char const* data, qint64 c)
304{
305 return socket_.write(data, c);
306}
307// LCOV_EXCL_STOP
254308
255Downloader* DownloaderImpl::make_job(shared_ptr<ItemImpl> const& item_impl,309Downloader* DownloaderImpl::make_job(shared_ptr<ItemImpl> const& item_impl,
256 QString const& method,310 QString const& method,
@@ -258,6 +312,7 @@
258{312{
259 unique_ptr<DownloaderImpl> impl(new DownloaderImpl(item_impl, method, reply));313 unique_ptr<DownloaderImpl> impl(new DownloaderImpl(item_impl, method, reply));
260 auto downloader = new Downloader(move(impl));314 auto downloader = new Downloader(move(impl));
315 downloader->open(QIODevice::ReadOnly);
261 downloader->p_->public_instance_ = downloader;316 downloader->p_->public_instance_ = downloader;
262 return downloader;317 return downloader;
263}318}
@@ -266,6 +321,7 @@
266{321{
267 unique_ptr<DownloaderImpl> impl(new DownloaderImpl(e));322 unique_ptr<DownloaderImpl> impl(new DownloaderImpl(e));
268 auto downloader = new Downloader(move(impl));323 auto downloader = new Downloader(move(impl));
324 downloader->open(QIODevice::ReadOnly);
269 downloader->p_->public_instance_ = downloader;325 downloader->p_->public_instance_ = downloader;
270 QMetaObject::invokeMethod(downloader,326 QMetaObject::invokeMethod(downloader,
271 "statusChanged",327 "statusChanged",
272328
=== modified file 'src/qt/internal/HandlerBase.cpp'
--- src/qt/internal/HandlerBase.cpp 2016-09-20 04:53:49 +0000
+++ src/qt/internal/HandlerBase.cpp 2016-11-04 07:34:14 +0000
@@ -50,6 +50,7 @@
50void HandlerBase::finished(QDBusPendingCallWatcher* call)50void HandlerBase::finished(QDBusPendingCallWatcher* call)
51{51{
52 deleteLater();52 deleteLater();
53 disconnect(&watcher_, &QDBusPendingCallWatcher::finished, this, &HandlerBase::finished);
53 closure_(*call);54 closure_(*call);
54}55}
5556
5657
=== modified file 'src/qt/internal/UploaderImpl.cpp'
--- src/qt/internal/UploaderImpl.cpp 2016-10-13 07:59:12 +0000
+++ src/qt/internal/UploaderImpl.cpp 2016-11-04 07:34:14 +0000
@@ -19,7 +19,7 @@
19#include <unity/storage/qt/internal/UploaderImpl.h>19#include <unity/storage/qt/internal/UploaderImpl.h>
2020
21#include "ProviderInterface.h"21#include "ProviderInterface.h"
22#include <unity/storage/qt/internal/Handler.h>22//#include <unity/storage/qt/internal/Handler.h>
23#include <unity/storage/qt/internal/ItemImpl.h>23#include <unity/storage/qt/internal/ItemImpl.h>
24#include <unity/storage/qt/internal/VoidJobImpl.h>24#include <unity/storage/qt/internal/VoidJobImpl.h>
25#include <unity/storage/qt/ItemJob.h>25#include <unity/storage/qt/ItemJob.h>
@@ -55,7 +55,7 @@
55 assert(!method.isEmpty());55 assert(!method.isEmpty());
56 assert(size_in_bytes >= 0);56 assert(size_in_bytes >= 0);
5757
58 auto process_reply = [this, method](decltype(reply)& r)58 auto process_reply = [this, method](QDBusPendingReply<QString, QDBusUnixFileDescriptor>& r)
59 {59 {
60 if (status_ != Uploader::Status::Loading)60 if (status_ != Uploader::Status::Loading)
61 {61 {
@@ -67,7 +67,7 @@
67 {67 {
68 QString msg = method + ": Runtime was destroyed previously";68 QString msg = method + ": Runtime was destroyed previously";
69 error_ = StorageErrorImpl::runtime_destroyed_error(msg);69 error_ = StorageErrorImpl::runtime_destroyed_error(msg);
70 public_instance_->abort();70 socket_.abort();
71 public_instance_->setErrorString(msg);71 public_instance_->setErrorString(msg);
72 status_ = Uploader::Status::Error;72 status_ = Uploader::Status::Error;
73 Q_EMIT public_instance_->statusChanged(status_);73 Q_EMIT public_instance_->statusChanged(status_);
@@ -82,7 +82,7 @@
82 QString msg = method + ": invalid file descriptor returned by provider";82 QString msg = method + ": invalid file descriptor returned by provider";
83 qCritical().noquote() << msg;83 qCritical().noquote() << msg;
84 error_ = StorageErrorImpl::local_comms_error(msg);84 error_ = StorageErrorImpl::local_comms_error(msg);
85 public_instance_->abort();85 socket_.abort();
86 public_instance_->setErrorString(msg);86 public_instance_->setErrorString(msg);
87 status_ = Uploader::Status::Error;87 status_ = Uploader::Status::Error;
88 Q_EMIT public_instance_->statusChanged(status_);88 Q_EMIT public_instance_->statusChanged(status_);
@@ -90,7 +90,19 @@
90 // LCOV_EXCL_STOP90 // LCOV_EXCL_STOP
91 }91 }
9292
93 public_instance_->setSocketDescriptor(fd_.fileDescriptor(), QLocalSocket::ConnectedState, QIODevice::WriteOnly);93 // We forward any QIODevice signals emitted by the socket to the public instance.
94 connect(&socket_, &QIODevice::aboutToClose, public_instance_, &QIODevice::aboutToClose);
95 connect(&socket_, &QIODevice::bytesWritten, public_instance_, &QIODevice::bytesWritten);
96 connect(&socket_, &QIODevice::readChannelFinished, public_instance_, &QIODevice::readChannelFinished);
97 connect(&socket_, &QIODevice::readyRead, public_instance_, &QIODevice::readyRead);
98
99#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
100 connect(&socket_, &QIODevice::channelBytesWritten, public_instance_, &QIODevice::channelBytesWritten);
101 connect(&socket_, &QIODevice::channelReadyRead, public_instance_, &QIODevice::channelReadyRead);
102#endif
103
104 socket_.setSocketDescriptor(fd_.fileDescriptor(), QLocalSocket::ConnectedState, QIODevice::WriteOnly);
105 flush_buffer();
94 status_ = Uploader::Status::Ready;106 status_ = Uploader::Status::Ready;
95 Q_EMIT public_instance_->statusChanged(status_);107 Q_EMIT public_instance_->statusChanged(status_);
96 };108 };
@@ -100,12 +112,12 @@
100 // TODO: This does not set the method112 // TODO: This does not set the method
101 error_ = error;113 error_ = error;
102 status_ = Uploader::Status::Error;114 status_ = Uploader::Status::Error;
103 public_instance_->abort();115 socket_.abort();
104 public_instance_->setErrorString(error.errorString());116 public_instance_->setErrorString(error.errorString());
105 Q_EMIT public_instance_->statusChanged(status_);117 Q_EMIT public_instance_->statusChanged(status_);
106 };118 };
107119
108 new Handler<storage::internal::ItemMetadata>(this, reply, process_reply, process_error);120 handler_ = new Handler<QDBusPendingReply<QString, QDBusUnixFileDescriptor>>(this, reply, process_reply, process_error);
109}121}
110122
111UploaderImpl::UploaderImpl(StorageError const& e)123UploaderImpl::UploaderImpl(StorageError const& e)
@@ -165,11 +177,56 @@
165 return Item(item_impl_);177 return Item(item_impl_);
166}178}
167179
168void UploaderImpl::finishUpload()180void UploaderImpl::cancel()
169{181{
170 static QString const method = "Uploader::finishUpload()";182 static QString const method = "Uploader::cancel()";
171183
172 // If we encountered an error earlier or were cancelled, or if finishUpload() was184 // If we are in a final state already, ignore the call.
185 if ( status_ == Uploader::Status::Error
186 || status_ == Uploader::Status::Finished
187 || status_ == Uploader::Status::Cancelled)
188 {
189 return;
190 }
191 auto runtime = item_impl_->runtime_impl();
192 if (!runtime || !runtime->isValid())
193 {
194 QString msg = method + ": Runtime was destroyed previously";
195 error_ = StorageErrorImpl::runtime_destroyed_error(msg);
196 status_ = Uploader::Status::Error;
197 Q_EMIT public_instance_->statusChanged(status_);
198 return;
199 }
200
201 if (!upload_id_.isEmpty())
202 {
203 // We just send the cancel and ignore any reply because it is best-effort only.
204 auto reply = item_impl_->account_impl()->provider()->CancelUpload(upload_id_);
205
206 auto process_reply = [](decltype(reply)&)
207 {
208 };
209
210 auto process_error = [](StorageError const&)
211 {
212 };
213
214 new Handler<void>(this, reply, process_reply, process_error);
215 }
216
217 QString msg = method + ": upload was cancelled";
218 error_ = StorageErrorImpl::cancelled_error(msg);
219 socket_.abort();
220 public_instance_->setErrorString(msg);
221 status_ = Uploader::Status::Cancelled;
222 Q_EMIT public_instance_->statusChanged(status_);
223}
224
225void UploaderImpl::close()
226{
227 static QString const method = "Uploader::close()";
228
229 // If we encountered an error earlier or were cancelled, or if close() was
173 // called already, we ignore the call.230 // called already, we ignore the call.
174 if (status_ == Uploader::Status::Error || status_ == Uploader::Status::Cancelled || finalizing_)231 if (status_ == Uploader::Status::Error || status_ == Uploader::Status::Cancelled || finalizing_)
175 {232 {
@@ -181,7 +238,7 @@
181 {238 {
182 QString msg = method + ": cannot finalize while Uploader is not in the Ready state";239 QString msg = method + ": cannot finalize while Uploader is not in the Ready state";
183 error_ = StorageErrorImpl::logic_error(msg);240 error_ = StorageErrorImpl::logic_error(msg);
184 public_instance_->abort();241 socket_.abort();
185 public_instance_->setErrorString(msg);242 public_instance_->setErrorString(msg);
186 status_ = Uploader::Status::Error;243 status_ = Uploader::Status::Error;
187 Q_EMIT public_instance_->statusChanged(status_);244 Q_EMIT public_instance_->statusChanged(status_);
@@ -199,7 +256,8 @@
199 }256 }
200257
201 finalizing_ = true;258 finalizing_ = true;
202 public_instance_->disconnectFromServer();259 flush_buffer();
260 socket_.disconnectFromServer();
203 auto reply = item_impl_->account_impl()->provider()->FinishUpload(upload_id_);261 auto reply = item_impl_->account_impl()->provider()->FinishUpload(upload_id_);
204262
205 auto process_reply = [this](decltype(reply)& r)263 auto process_reply = [this](decltype(reply)& r)
@@ -214,7 +272,7 @@
214 {272 {
215 QString msg = method + ": Runtime was destroyed previously";273 QString msg = method + ": Runtime was destroyed previously";
216 error_ = StorageErrorImpl::runtime_destroyed_error(msg);274 error_ = StorageErrorImpl::runtime_destroyed_error(msg);
217 public_instance_->abort();275 socket_.abort();
218 public_instance_->setErrorString(msg);276 public_instance_->setErrorString(msg);
219 status_ = Uploader::Status::Error;277 status_ = Uploader::Status::Error;
220 Q_EMIT public_instance_->statusChanged(status_);278 Q_EMIT public_instance_->statusChanged(status_);
@@ -247,7 +305,7 @@
247305
248 // TODO: this doesn't set the method306 // TODO: this doesn't set the method
249 error_ = error;307 error_ = error;
250 public_instance_->abort();308 socket_.abort();
251 public_instance_->setErrorString(error.errorString());309 public_instance_->setErrorString(error.errorString());
252 status_ = Uploader::Status::Error;310 status_ = Uploader::Status::Error;
253 Q_EMIT public_instance_->statusChanged(status_);311 Q_EMIT public_instance_->statusChanged(status_);
@@ -256,49 +314,85 @@
256 new Handler<void>(this, reply, process_reply, process_error);314 new Handler<void>(this, reply, process_reply, process_error);
257}315}
258316
259void UploaderImpl::cancel()317qint64 UploaderImpl::bytesAvailable() const
260{318{
261 static QString const method = "Uploader::cancel()";319 return socket_.bytesAvailable();
262320}
263 // If we are in a final state already, ignore the call.321
264 if ( status_ == Uploader::Status::Error322qint64 UploaderImpl::bytesToWrite() const
265 || status_ == Uploader::Status::Finished323{
266 || status_ == Uploader::Status::Cancelled)324 return socket_.bytesToWrite();
267 {325}
268 return;326
269 }327bool UploaderImpl::canReadLine() const
270 auto runtime = item_impl_->runtime_impl();328{
271 if (!runtime || !runtime->isValid())329 return socket_.canReadLine();
272 {330}
273 QString msg = method + ": Runtime was destroyed previously";331
274 error_ = StorageErrorImpl::runtime_destroyed_error(msg);332bool UploaderImpl::isSequential() const
275 status_ = Uploader::Status::Error;333{
276 Q_EMIT public_instance_->statusChanged(status_);334 return socket_.isSequential();
277 return;335}
278 }336
279337bool UploaderImpl::waitForBytesWritten(int msecs)
280 if (!upload_id_.isEmpty())338{
281 {339 if (status_ == Uploader::Status::Loading)
282 // We just send the cancel and ignore any reply because it is best-effort only.340 {
283 auto reply = item_impl_->account_impl()->provider()->CancelUpload(upload_id_);341 // Unfortunately, QDBusPendingReply::waitForFinished() does not accept a timeout.
284342 // The next-best thing we can do is to simply wait without a timeout. The DBus
285 auto process_reply = [](decltype(reply)&)343 // method will finish eventually, even though it might take a lot longer than msecs.
286 {344 handler_->wait_and_process_now();
287 };345 }
288346 if (flush_buffer() == -1)
289 auto process_error = [](StorageError const&)347 {
290 {348 return false;
291 };349 }
292350 return socket_.waitForBytesWritten(msecs);
293 new Handler<void>(this, reply, process_reply, process_error);351}
294 }352
295353bool UploaderImpl::waitForReadyRead(int msecs)
296 QString msg = method + ": upload was cancelled";354{
297 error_ = StorageErrorImpl::cancelled_error(msg);355 return socket_.waitForReadyRead(msecs);
298 public_instance_->abort();356}
299 public_instance_->setErrorString(msg);357
300 status_ = Uploader::Status::Cancelled;358// LCOV_EXCL_START
301 Q_EMIT public_instance_->statusChanged(status_);359// Never called by QIODevice because device is opened write-only.
360qint64 UploaderImpl::readData(char* data, qint64 c)
361{
362 return socket_.read(data, c);
363}
364// LCOV_EXCL_STOP
365
366qint64 UploaderImpl::writeData(char const* data, qint64 c)
367{
368 switch (status_)
369 {
370 case Uploader::Status::Loading:
371 {
372 // Client is writing before we have received the file descriptor from the provider.
373 buffer_.append(data, c);
374 return c;
375 }
376 case Uploader::Status::Ready:
377 {
378 if (flush_buffer() == -1)
379 {
380 return -1;
381 }
382 return socket_.write(data, c);
383 }
384 case Uploader::Status::Cancelled:
385 case Uploader::Status::Finished:
386 case Uploader::Status::Error:
387 {
388 return -1; // Can't write to an already-finalized uploader.
389 }
390 default:
391 {
392 abort(); // Impossible // LCOV_EXCL_LINE
393 }
394 }
395 // NOTREACHED
302}396}
303397
304Uploader* UploaderImpl::make_job(shared_ptr<ItemImpl> const& item_impl,398Uploader* UploaderImpl::make_job(shared_ptr<ItemImpl> const& item_impl,
@@ -310,6 +404,7 @@
310{404{
311 unique_ptr<UploaderImpl> impl(new UploaderImpl(item_impl, method, reply, validate, policy, size_in_bytes));405 unique_ptr<UploaderImpl> impl(new UploaderImpl(item_impl, method, reply, validate, policy, size_in_bytes));
312 auto uploader = new Uploader(move(impl));406 auto uploader = new Uploader(move(impl));
407 uploader->open(QIODevice::WriteOnly);
313 uploader->p_->public_instance_ = uploader;408 uploader->p_->public_instance_ = uploader;
314 return uploader;409 return uploader;
315}410}
@@ -318,6 +413,7 @@
318{413{
319 unique_ptr<UploaderImpl> impl(new UploaderImpl(e));414 unique_ptr<UploaderImpl> impl(new UploaderImpl(e));
320 auto uploader = new Uploader(move(impl));415 auto uploader = new Uploader(move(impl));
416 uploader->open(QIODevice::WriteOnly);
321 uploader->p_->public_instance_ = uploader;417 uploader->p_->public_instance_ = uploader;
322 QMetaObject::invokeMethod(uploader,418 QMetaObject::invokeMethod(uploader,
323 "statusChanged",419 "statusChanged",
@@ -326,6 +422,22 @@
326 return uploader;422 return uploader;
327}423}
328424
425qint64 UploaderImpl::flush_buffer()
426{
427 qint64 bytes_written = 0;
428 auto bytes_to_write = buffer_.size();
429 if (bytes_to_write > 0)
430 {
431 auto bytes_written = socket_.write(buffer_.data(), bytes_to_write);
432 if (bytes_written != bytes_to_write)
433 {
434 return -1; // Not exactly detailed, but that's the best we can do. // LCOV_EXCL_LINE
435 }
436 buffer_.resize(0);
437 }
438 return bytes_written;
439}
440
329} // namespace internal441} // namespace internal
330} // namespace qt442} // namespace qt
331} // namespace storage443} // namespace storage
332444
=== modified file 'tests/remote-client/MockProvider.cpp'
--- tests/remote-client/MockProvider.cpp 2016-11-03 03:41:24 +0000
+++ tests/remote-client/MockProvider.cpp 2016-11-04 07:34:14 +0000
@@ -194,9 +194,9 @@
194 ++num_calls;194 ++num_calls;
195 switch (num_calls)195 switch (num_calls)
196 {196 {
197 case 2:
198 return make_exceptional_future<Item>(ResourceException("metadata(): weird error", 42));
197 case 3:199 case 3:
198 return make_exceptional_future<Item>(ResourceException("metadata(): weird error", 42));
199 case 4:
200 num_calls = 0;200 num_calls = 0;
201 return make_exceptional_future<Item>(RemoteCommsException("metadata(): HTTP broken"));201 return make_exceptional_future<Item>(RemoteCommsException("metadata(): HTTP broken"));
202 default:202 default:
@@ -207,14 +207,8 @@
207 {207 {
208 if (cmd_ == "bad_parent_metadata_from_child")208 if (cmd_ == "bad_parent_metadata_from_child")
209 {209 {
210 ++num_calls;210 Item metadata{"root_id", {}, "Root", "etag", ItemType::file, {}};
211 if (num_calls == 2)211 return make_ready_future<Item>(metadata);
212 {
213 num_calls = 0;
214 // On second call, we return type file for the root.
215 Item metadata{"root_id", {}, "Root", "etag", ItemType::file, {}};
216 return make_ready_future<Item>(metadata);
217 }
218 }212 }
219 if (cmd_ == "root_with_parent")213 if (cmd_ == "root_with_parent")
220 {214 {
221215
=== modified file 'tests/remote-client/remote-client_test.cpp'
--- tests/remote-client/remote-client_test.cpp 2016-11-03 07:33:40 +0000
+++ tests/remote-client/remote-client_test.cpp 2016-11-04 07:34:14 +0000
@@ -1310,14 +1310,6 @@
1310{1310{
1311 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("two_parents")));1311 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("two_parents")));
13121312
1313 Item root;
1314 {
1315 unique_ptr<ItemJob> j(acc_.get("root_id"));
1316 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1317 spy.wait(SIGNAL_WAIT_TIME);
1318 root = j->item();
1319 }
1320
1321 Item child;1313 Item child;
1322 {1314 {
1323 unique_ptr<ItemJob> j(acc_.get("child_id"));1315 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -1364,14 +1356,6 @@
1364{1356{
1365 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("two_parents_throw")));1357 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("two_parents_throw")));
13661358
1367 Item root;
1368 {
1369 unique_ptr<ItemJob> j(acc_.get("root_id"));
1370 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1371 spy.wait(SIGNAL_WAIT_TIME);
1372 root = j->item();
1373 }
1374
1375 Item child;1359 Item child;
1376 {1360 {
1377 unique_ptr<ItemJob> j(acc_.get("child_id"));1361 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -1455,14 +1439,6 @@
1455{1439{
1456 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("slow_metadata")));1440 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("slow_metadata")));
14571441
1458 Item root;
1459 {
1460 unique_ptr<ItemJob> j(acc_.get("root_id"));
1461 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1462 spy.wait(SIGNAL_WAIT_TIME);
1463 root = j->item();
1464 }
1465
1466 Item child;1442 Item child;
1467 {1443 {
1468 unique_ptr<ItemJob> j(acc_.get("child_id"));1444 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -1489,14 +1465,6 @@
1489{1465{
1490 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("bad_parent_metadata_from_child")));1466 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("bad_parent_metadata_from_child")));
14911467
1492 Item root;
1493 {
1494 unique_ptr<ItemJob> j(acc_.get("root_id"));
1495 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1496 spy.wait(SIGNAL_WAIT_TIME);
1497 root = j->item();
1498 }
1499
1500 Item child;1468 Item child;
1501 {1469 {
1502 unique_ptr<ItemJob> j(acc_.get("child_id"));1470 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -1600,14 +1568,6 @@
1600{1568{
1601 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));1569 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
16021570
1603 Item root;
1604 {
1605 unique_ptr<ItemJob> j(acc_.get("root_id"));
1606 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1607 spy.wait(SIGNAL_WAIT_TIME);
1608 root = j->item();
1609 }
1610
1611 Item child;1571 Item child;
1612 {1572 {
1613 unique_ptr<ItemJob> j(acc_.get("child_id"));1573 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -1731,14 +1691,6 @@
1731{1691{
1732 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));1692 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
17331693
1734 Item root;
1735 {
1736 unique_ptr<ItemJob> j(acc_.get("root_id"));
1737 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1738 spy.wait(SIGNAL_WAIT_TIME);
1739 root = j->item();
1740 }
1741
1742 Item child;1694 Item child;
1743 {1695 {
1744 unique_ptr<ItemJob> j(acc_.get("child_id"));1696 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2014,14 +1966,6 @@
2014{1966{
2015 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));1967 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
20161968
2017 Item root;
2018 {
2019 unique_ptr<ItemJob> j(acc_.get("root_id"));
2020 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2021 spy.wait(SIGNAL_WAIT_TIME);
2022 root = j->item();
2023 }
2024
2025 Item child;1969 Item child;
2026 {1970 {
2027 unique_ptr<ItemJob> j(acc_.get("child_id"));1971 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2102,14 +2046,6 @@
2102{2046{
2103 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2047 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
21042048
2105 Item root;
2106 {
2107 unique_ptr<ItemJob> j(acc_.get("root_id"));
2108 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2109 spy.wait(SIGNAL_WAIT_TIME);
2110 root = j->item();
2111 }
2112
2113 Item child;2049 Item child;
2114 {2050 {
2115 unique_ptr<ItemJob> j(acc_.get("child_id"));2051 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2320,14 +2256,6 @@
2320{2256{
2321 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2257 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
23222258
2323 Item root;
2324 {
2325 unique_ptr<ItemJob> j(acc_.get("root_id"));
2326 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2327 spy.wait(SIGNAL_WAIT_TIME);
2328 root = j->item();
2329 }
2330
2331 Item child;2259 Item child;
2332 {2260 {
2333 unique_ptr<ItemJob> j(acc_.get("child_id"));2261 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2434,14 +2362,6 @@
2434{2362{
2435 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2363 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
24362364
2437 Item root;
2438 {
2439 unique_ptr<ItemJob> j(acc_.get("root_id"));
2440 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2441 spy.wait(SIGNAL_WAIT_TIME);
2442 root = j->item();
2443 }
2444
2445 Item child;2365 Item child;
2446 {2366 {
2447 unique_ptr<ItemJob> j(acc_.get("child_id"));2367 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2468,10 +2388,17 @@
2468 read_spy.wait(SIGNAL_WAIT_TIME);2388 read_spy.wait(SIGNAL_WAIT_TIME);
2469 }2389 }
2470 }2390 }
2391
2392 EXPECT_EQ(11, downloader->bytesAvailable());
2393 EXPECT_EQ(0, downloader->bytesToWrite());
2394 EXPECT_EQ(-1, downloader->write("a", 1));
2395 EXPECT_FALSE(downloader->waitForBytesWritten(1));
2396 EXPECT_FALSE(downloader->waitForReadyRead(1));
2397
2471 auto data = downloader->readAll();2398 auto data = downloader->readAll();
2472 EXPECT_EQ(QByteArray("Hello world", -1), data);2399 EXPECT_EQ(QByteArray("Hello world", -1), data);
24732400
2474 downloader->finishDownload();2401 downloader->close();
2475 ASSERT_TRUE(status_spy.wait(SIGNAL_WAIT_TIME));2402 ASSERT_TRUE(status_spy.wait(SIGNAL_WAIT_TIME));
2476 auto arg = status_spy.takeFirst();2403 auto arg = status_spy.takeFirst();
2477 EXPECT_EQ(Downloader::Status::Finished, qvariant_cast<Downloader::Status>(arg.at(0)));2404 EXPECT_EQ(Downloader::Status::Finished, qvariant_cast<Downloader::Status>(arg.at(0)));
@@ -2496,14 +2423,6 @@
2496{2423{
2497 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2424 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
24982425
2499 Item root;
2500 {
2501 unique_ptr<ItemJob> j(acc_.get("root_id"));
2502 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2503 spy.wait(SIGNAL_WAIT_TIME);
2504 root = j->item();
2505 }
2506
2507 Item child;2426 Item child;
2508 {2427 {
2509 unique_ptr<ItemJob> j(acc_.get("child_id"));2428 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2521,20 +2440,14 @@
2521 auto arg = spy.takeFirst();2440 auto arg = spy.takeFirst();
2522 EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0)));2441 EXPECT_EQ(Downloader::Status::Ready, qvariant_cast<Downloader::Status>(arg.at(0)));
2523 }2442 }
2443
2444 EXPECT_TRUE(downloader->waitForReadyRead(SIGNAL_WAIT_TIME));
2524}2445}
25252446
2526TEST_F(DownloadTest, runtime_destroyed)2447TEST_F(DownloadTest, runtime_destroyed)
2527{2448{
2528 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2449 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
25292450
2530 Item root;
2531 {
2532 unique_ptr<ItemJob> j(acc_.get("root_id"));
2533 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2534 spy.wait(SIGNAL_WAIT_TIME);
2535 root = j->item();
2536 }
2537
2538 Item child;2451 Item child;
2539 {2452 {
2540 unique_ptr<ItemJob> j(acc_.get("child_id"));2453 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2566,14 +2479,6 @@
2566{2479{
2567 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("download_slow")));2480 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("download_slow")));
25682481
2569 Item root;
2570 {
2571 unique_ptr<ItemJob> j(acc_.get("root_id"));
2572 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2573 spy.wait(SIGNAL_WAIT_TIME);
2574 root = j->item();
2575 }
2576
2577 Item child;2482 Item child;
2578 {2483 {
2579 unique_ptr<ItemJob> j(acc_.get("child_id"));2484 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2607,14 +2512,6 @@
2607{2512{
2608 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("download_error")));2513 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("download_error")));
26092514
2610 Item root;
2611 {
2612 unique_ptr<ItemJob> j(acc_.get("root_id"));
2613 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2614 spy.wait(SIGNAL_WAIT_TIME);
2615 root = j->item();
2616 }
2617
2618 Item child;2515 Item child;
2619 {2516 {
2620 unique_ptr<ItemJob> j(acc_.get("child_id"));2517 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2641,10 +2538,10 @@
2641 EXPECT_EQ(42, downloader->error().errorCode());2538 EXPECT_EQ(42, downloader->error().errorCode());
2642 EXPECT_EQ(Item(), downloader->item());2539 EXPECT_EQ(Item(), downloader->item());
26432540
2644 // For coverage: call finishDownload() while in the Error state.2541 // For coverage: call close() while in the Error state.
2645 {2542 {
2646 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);2543 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);
2647 downloader->finishDownload();2544 downloader->close();
2648 EXPECT_FALSE(spy.wait(1000));2545 EXPECT_FALSE(spy.wait(1000));
2649 }2546 }
2650}2547}
@@ -2653,14 +2550,6 @@
2653{2550{
2654 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2551 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
26552552
2656 Item root;
2657 {
2658 unique_ptr<ItemJob> j(acc_.get("root_id"));
2659 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2660 spy.wait(SIGNAL_WAIT_TIME);
2661 root = j->item();
2662 }
2663
2664 Item child;2553 Item child;
2665 {2554 {
2666 unique_ptr<ItemJob> j(acc_.get("child_id"));2555 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2674,7 +2563,7 @@
26742563
2675 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);2564 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);
26762565
2677 downloader->finishDownload();2566 downloader->close();
26782567
2679 ASSERT_EQ(1, spy.count());2568 ASSERT_EQ(1, spy.count());
2680 auto arg = spy.takeFirst();2569 auto arg = spy.takeFirst();
@@ -2683,7 +2572,7 @@
2683 EXPECT_FALSE(downloader->isValid());2572 EXPECT_FALSE(downloader->isValid());
2684 EXPECT_EQ(Downloader::Status::Error, downloader->status());2573 EXPECT_EQ(Downloader::Status::Error, downloader->status());
2685 EXPECT_EQ(StorageError::LogicError, downloader->error().type());2574 EXPECT_EQ(StorageError::LogicError, downloader->error().type());
2686 EXPECT_EQ("LogicError: Downloader::finishDownload(): cannot finalize while Downloader is not in the Ready state",2575 EXPECT_EQ("LogicError: Downloader::close(): cannot finalize while Downloader is not in the Ready state",
2687 downloader->error().errorString());2576 downloader->error().errorString());
2688}2577}
26892578
@@ -2691,14 +2580,6 @@
2691{2580{
2692 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2581 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
26932582
2694 Item root;
2695 {
2696 unique_ptr<ItemJob> j(acc_.get("root_id"));
2697 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2698 spy.wait(SIGNAL_WAIT_TIME);
2699 root = j->item();
2700 }
2701
2702 Item child;2583 Item child;
2703 {2584 {
2704 unique_ptr<ItemJob> j(acc_.get("child_id"));2585 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2721,7 +2602,7 @@
27212602
2722 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime2603 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime
27232604
2724 downloader->finishDownload();2605 downloader->close();
27252606
2726 ASSERT_EQ(1, spy.count());2607 ASSERT_EQ(1, spy.count());
2727 auto arg = spy.takeFirst();2608 auto arg = spy.takeFirst();
@@ -2730,21 +2611,13 @@
2730 EXPECT_FALSE(downloader->isValid());2611 EXPECT_FALSE(downloader->isValid());
2731 EXPECT_EQ(Downloader::Status::Error, downloader->status());2612 EXPECT_EQ(Downloader::Status::Error, downloader->status());
2732 EXPECT_EQ(StorageError::RuntimeDestroyed, downloader->error().type());2613 EXPECT_EQ(StorageError::RuntimeDestroyed, downloader->error().type());
2733 EXPECT_EQ("Downloader::finishDownload(): Runtime was destroyed previously", downloader->error().message());2614 EXPECT_EQ("Downloader::close(): Runtime was destroyed previously", downloader->error().message());
2734}2615}
27352616
2736TEST_F(DownloadTest, finish_runtime_destroyed_while_reply_outstanding)2617TEST_F(DownloadTest, finish_runtime_destroyed_while_reply_outstanding)
2737{2618{
2738 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow")));2619 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow")));
27392620
2740 Item root;
2741 {
2742 unique_ptr<ItemJob> j(acc_.get("root_id"));
2743 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2744 spy.wait(SIGNAL_WAIT_TIME);
2745 root = j->item();
2746 }
2747
2748 Item child;2621 Item child;
2749 {2622 {
2750 unique_ptr<ItemJob> j(acc_.get("child_id"));2623 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2765,7 +2638,7 @@
27652638
2766 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);2639 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);
27672640
2768 downloader->finishDownload();2641 downloader->close();
27692642
2770 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime, provider still sleeping2643 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime, provider still sleeping
27712644
@@ -2776,21 +2649,13 @@
2776 EXPECT_FALSE(downloader->isValid());2649 EXPECT_FALSE(downloader->isValid());
2777 EXPECT_EQ(Downloader::Status::Error, downloader->status());2650 EXPECT_EQ(Downloader::Status::Error, downloader->status());
2778 EXPECT_EQ(StorageError::RuntimeDestroyed, downloader->error().type());2651 EXPECT_EQ(StorageError::RuntimeDestroyed, downloader->error().type());
2779 EXPECT_EQ("Downloader::finishDownload(): Runtime was destroyed previously", downloader->error().message());2652 EXPECT_EQ("Downloader::close(): Runtime was destroyed previously", downloader->error().message());
2780}2653}
27812654
2782TEST_F(DownloadTest, finish_twice)2655TEST_F(DownloadTest, finish_twice)
2783{2656{
2784 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2657 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
27852658
2786 Item root;
2787 {
2788 unique_ptr<ItemJob> j(acc_.get("root_id"));
2789 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2790 spy.wait(SIGNAL_WAIT_TIME);
2791 root = j->item();
2792 }
2793
2794 Item child;2659 Item child;
2795 {2660 {
2796 unique_ptr<ItemJob> j(acc_.get("child_id"));2661 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2811,8 +2676,8 @@
28112676
2812 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);2677 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);
28132678
2814 downloader->finishDownload();2679 downloader->close();
2815 downloader->finishDownload();2680 downloader->close();
28162681
2817 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));2682 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
2818 auto arg = spy.takeFirst();2683 auto arg = spy.takeFirst();
@@ -2825,14 +2690,6 @@
2825{2690{
2826 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_error")));2691 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_error")));
28272692
2828 Item root;
2829 {
2830 unique_ptr<ItemJob> j(acc_.get("root_id"));
2831 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2832 spy.wait(SIGNAL_WAIT_TIME);
2833 root = j->item();
2834 }
2835
2836 Item child;2693 Item child;
2837 {2694 {
2838 unique_ptr<ItemJob> j(acc_.get("child_id"));2695 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2853,7 +2710,7 @@
28532710
2854 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);2711 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);
28552712
2856 downloader->finishDownload();2713 downloader->close();
28572714
2858 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));2715 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
2859 auto arg = spy.takeFirst();2716 auto arg = spy.takeFirst();
@@ -2925,14 +2782,6 @@
2925{2782{
2926 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow_error")));2783 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow_error")));
29272784
2928 Item root;
2929 {
2930 unique_ptr<ItemJob> j(acc_.get("root_id"));
2931 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2932 spy.wait(SIGNAL_WAIT_TIME);
2933 root = j->item();
2934 }
2935
2936 Item child;2785 Item child;
2937 {2786 {
2938 unique_ptr<ItemJob> j(acc_.get("child_id"));2787 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -2953,12 +2802,12 @@
29532802
2954 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);2803 QSignalSpy spy(downloader.get(), &Downloader::statusChanged);
29552804
2956 downloader->finishDownload();2805 downloader->close();
29572806
2958 downloader->cancel();2807 downloader->cancel();
2959 downloader->cancel(); // Second time for coverage2808 downloader->cancel(); // Second time for coverage
29602809
2961 downloader->finishDownload(); // Second time for coverage2810 downloader->close(); // Second time for coverage
29622811
2963 EXPECT_EQ(1, spy.count());2812 EXPECT_EQ(1, spy.count());
2964 auto arg = spy.takeFirst();2813 auto arg = spy.takeFirst();
@@ -2968,7 +2817,7 @@
2968 EXPECT_EQ(StorageError::Type::Cancelled, downloader->error().type());2817 EXPECT_EQ(StorageError::Type::Cancelled, downloader->error().type());
2969 EXPECT_EQ("Downloader::cancel(): download was cancelled", downloader->error().message());2818 EXPECT_EQ("Downloader::cancel(): download was cancelled", downloader->error().message());
29702819
2971 // We wait here to get coverage for when the reply to a finishDownload() call2820 // We wait here to get coverage for when the reply to a FinishDownload() call
2972 // finds the downloader in a final state.2821 // finds the downloader in a final state.
2973 EXPECT_FALSE(spy.wait(2000));2822 EXPECT_FALSE(spy.wait(2000));
2974}2823}
@@ -2977,14 +2826,6 @@
2977{2826{
2978 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow_error")));2827 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_download_slow_error")));
29792828
2980 Item root;
2981 {
2982 unique_ptr<ItemJob> j(acc_.get("root_id"));
2983 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2984 spy.wait(SIGNAL_WAIT_TIME);
2985 root = j->item();
2986 }
2987
2988 Item child;2829 Item child;
2989 {2830 {
2990 unique_ptr<ItemJob> j(acc_.get("child_id"));2831 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3025,14 +2866,6 @@
3025{2866{
3026 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2867 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
30272868
3028 Item root;
3029 {
3030 unique_ptr<ItemJob> j(acc_.get("root_id"));
3031 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3032 spy.wait(SIGNAL_WAIT_TIME);
3033 root = j->item();
3034 }
3035
3036 Item child;2869 Item child;
3037 {2870 {
3038 unique_ptr<ItemJob> j(acc_.get("child_id"));2871 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3057,10 +2890,92 @@
3057 EXPECT_EQ(Uploader::Status::Ready, qvariant_cast<Uploader::Status>(arg.at(0)));2890 EXPECT_EQ(Uploader::Status::Ready, qvariant_cast<Uploader::Status>(arg.at(0)));
3058 }2891 }
30592892
3060 EXPECT_EQ(contents.size(), uploader->write(contents));2893 EXPECT_EQ(0, uploader->bytesAvailable());
30612894 EXPECT_EQ(0, uploader->bytesToWrite());
3062 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);2895 char buf;
3063 uploader->finishUpload();2896 EXPECT_EQ(-1, uploader->read(&buf, 1));
2897 EXPECT_FALSE(uploader->waitForReadyRead(1));
2898
2899 EXPECT_EQ(contents.size(), uploader->write(contents));
2900 EXPECT_TRUE(uploader->waitForBytesWritten(contents.size()));
2901
2902 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
2903 uploader->close();
2904 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
2905 auto arg = spy.takeFirst();
2906 EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0)));
2907
2908 EXPECT_EQ(Uploader::Status::Finished, uploader->status());
2909 EXPECT_EQ(child, uploader->item());
2910}
2911
2912#if 0
2913// TODO: This test is currently disabled because a synchronous wait in the client
2914// blocks the single event loop that is shared by the client and the mock provider.
2915// We need to change the test harness to run a separate event loop for the provider.
2916//
2917TEST_F(UploadTest, write_before_ready_and_wait)
2918{
2919 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_slow")));
2920
2921 Item child;
2922 {
2923 unique_ptr<ItemJob> j(acc_.get("child_id"));
2924 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2925 spy.wait(SIGNAL_WAIT_TIME);
2926 child = j->item();
2927 }
2928
2929 QByteArray contents("Hello world", -1);
2930 unique_ptr<Uploader> uploader(child.createUploader(Item::ConflictPolicy::IgnoreConflict, contents.size()));
2931 EXPECT_TRUE(uploader->isValid());
2932
2933 // Don't wait for ready state.
2934
2935 EXPECT_EQ(contents.size(), uploader->write(contents));
2936 EXPECT_TRUE(uploader->waitForBytesWritten(1000));
2937
2938 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
2939 uploader->close();
2940 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
2941 auto arg = spy.takeFirst();
2942 EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0)));
2943
2944 EXPECT_EQ(Uploader::Status::Finished, uploader->status());
2945 EXPECT_EQ(child, uploader->item());
2946}
2947#endif
2948
2949TEST_F(UploadTest, write_before_ready)
2950{
2951 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_slow")));
2952
2953 Item child;
2954 {
2955 unique_ptr<ItemJob> j(acc_.get("child_id"));
2956 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
2957 spy.wait(SIGNAL_WAIT_TIME);
2958 child = j->item();
2959 }
2960
2961 QByteArray contents("Hello world", -1);
2962 unique_ptr<Uploader> uploader(child.createUploader(Item::ConflictPolicy::IgnoreConflict, contents.size()));
2963 EXPECT_TRUE(uploader->isValid());
2964
2965 // Don't wait for ready state.
2966
2967 EXPECT_EQ(contents.size(), uploader->write(contents));
2968
2969 // Wait until we get confirmation that the contents were written.
2970 {
2971 QSignalSpy spy(uploader.get(), &Uploader::bytesWritten);
2972 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
2973 auto arg = spy.takeFirst();
2974 EXPECT_TRUE(qvariant_cast<bool>(arg.at(0)));
2975 }
2976
2977 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
2978 uploader->close();
3064 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));2979 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
3065 auto arg = spy.takeFirst();2980 auto arg = spy.takeFirst();
3066 EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0)));2981 EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0)));
@@ -3073,14 +2988,6 @@
3073{2988{
3074 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));2989 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
30752990
3076 Item root;
3077 {
3078 unique_ptr<ItemJob> j(acc_.get("root_id"));
3079 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3080 spy.wait(SIGNAL_WAIT_TIME);
3081 root = j->item();
3082 }
3083
3084 Item child;2991 Item child;
3085 {2992 {
3086 unique_ptr<ItemJob> j(acc_.get("child_id"));2993 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3098,20 +3005,15 @@
3098 auto arg = spy.takeFirst();3005 auto arg = spy.takeFirst();
3099 EXPECT_EQ(Uploader::Status::Ready, qvariant_cast<Uploader::Status>(arg.at(0)));3006 EXPECT_EQ(Uploader::Status::Ready, qvariant_cast<Uploader::Status>(arg.at(0)));
3100 }3007 }
3008
3009 EXPECT_EQ(1, uploader->write("a", 1));
3010 EXPECT_TRUE(uploader->waitForBytesWritten(SIGNAL_WAIT_TIME));
3101}3011}
31023012
3103TEST_F(UploadTest, runtime_destroyed)3013TEST_F(UploadTest, runtime_destroyed)
3104{3014{
3105 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));3015 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
31063016
3107 Item root;
3108 {
3109 unique_ptr<ItemJob> j(acc_.get("root_id"));
3110 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3111 spy.wait(SIGNAL_WAIT_TIME);
3112 root = j->item();
3113 }
3114
3115 Item child;3017 Item child;
3116 {3018 {
3117 unique_ptr<ItemJob> j(acc_.get("child_id"));3019 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3143,14 +3045,6 @@
3143{3045{
3144 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_slow")));3046 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_slow")));
31453047
3146 Item root;
3147 {
3148 unique_ptr<ItemJob> j(acc_.get("root_id"));
3149 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3150 spy.wait(SIGNAL_WAIT_TIME);
3151 root = j->item();
3152 }
3153
3154 Item child;3048 Item child;
3155 {3049 {
3156 unique_ptr<ItemJob> j(acc_.get("child_id"));3050 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3184,14 +3078,6 @@
3184{3078{
3185 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_error")));3079 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_error")));
31863080
3187 Item root;
3188 {
3189 unique_ptr<ItemJob> j(acc_.get("root_id"));
3190 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3191 spy.wait(SIGNAL_WAIT_TIME);
3192 root = j->item();
3193 }
3194
3195 Item child;3081 Item child;
3196 {3082 {
3197 unique_ptr<ItemJob> j(acc_.get("child_id"));3083 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3217,10 +3103,10 @@
3217 EXPECT_EQ("Conflict: version mismatch", uploader->error().errorString());3103 EXPECT_EQ("Conflict: version mismatch", uploader->error().errorString());
3218 EXPECT_EQ(Item(), uploader->item());3104 EXPECT_EQ(Item(), uploader->item());
32193105
3220 // For coverage: call finishUpload() while in the Error state.3106 // For coverage: call close() while in the Error state.
3221 {3107 {
3222 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3108 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
3223 uploader->finishUpload();3109 uploader->close();
3224 EXPECT_FALSE(spy.wait(1000));3110 EXPECT_FALSE(spy.wait(1000));
3225 }3111 }
3226}3112}
@@ -3229,14 +3115,6 @@
3229{3115{
3230 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));3116 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
32313117
3232 Item root;
3233 {
3234 unique_ptr<ItemJob> j(acc_.get("root_id"));
3235 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3236 spy.wait(SIGNAL_WAIT_TIME);
3237 root = j->item();
3238 }
3239
3240 Item child;3118 Item child;
3241 {3119 {
3242 unique_ptr<ItemJob> j(acc_.get("child_id"));3120 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3250,7 +3128,7 @@
32503128
3251 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3129 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
32523130
3253 uploader->finishUpload();3131 uploader->close();
32543132
3255 ASSERT_EQ(1, spy.count());3133 ASSERT_EQ(1, spy.count());
3256 auto arg = spy.takeFirst();3134 auto arg = spy.takeFirst();
@@ -3259,7 +3137,7 @@
3259 EXPECT_FALSE(uploader->isValid());3137 EXPECT_FALSE(uploader->isValid());
3260 EXPECT_EQ(Uploader::Status::Error, uploader->status());3138 EXPECT_EQ(Uploader::Status::Error, uploader->status());
3261 EXPECT_EQ(StorageError::LogicError, uploader->error().type());3139 EXPECT_EQ(StorageError::LogicError, uploader->error().type());
3262 EXPECT_EQ("LogicError: Uploader::finishUpload(): cannot finalize while Uploader is not in the Ready state",3140 EXPECT_EQ("LogicError: Uploader::close(): cannot finalize while Uploader is not in the Ready state",
3263 uploader->error().errorString());3141 uploader->error().errorString());
3264}3142}
32653143
@@ -3267,14 +3145,6 @@
3267{3145{
3268 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));3146 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
32693147
3270 Item root;
3271 {
3272 unique_ptr<ItemJob> j(acc_.get("root_id"));
3273 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3274 spy.wait(SIGNAL_WAIT_TIME);
3275 root = j->item();
3276 }
3277
3278 Item child;3148 Item child;
3279 {3149 {
3280 unique_ptr<ItemJob> j(acc_.get("child_id"));3150 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3297,7 +3167,7 @@
32973167
3298 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime3168 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime
32993169
3300 uploader->finishUpload();3170 uploader->close();
33013171
3302 ASSERT_EQ(1, spy.count());3172 ASSERT_EQ(1, spy.count());
3303 auto arg = spy.takeFirst();3173 auto arg = spy.takeFirst();
@@ -3306,21 +3176,13 @@
3306 EXPECT_FALSE(uploader->isValid());3176 EXPECT_FALSE(uploader->isValid());
3307 EXPECT_EQ(Uploader::Status::Error, uploader->status());3177 EXPECT_EQ(Uploader::Status::Error, uploader->status());
3308 EXPECT_EQ(StorageError::RuntimeDestroyed, uploader->error().type());3178 EXPECT_EQ(StorageError::RuntimeDestroyed, uploader->error().type());
3309 EXPECT_EQ("Uploader::finishUpload(): Runtime was destroyed previously", uploader->error().message());3179 EXPECT_EQ("Uploader::close(): Runtime was destroyed previously", uploader->error().message());
3310}3180}
33113181
3312TEST_F(UploadTest, finish_runtime_destroyed_while_reply_outstanding)3182TEST_F(UploadTest, finish_runtime_destroyed_while_reply_outstanding)
3313{3183{
3314 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_upload_slow")));3184 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_upload_slow")));
33153185
3316 Item root;
3317 {
3318 unique_ptr<ItemJob> j(acc_.get("root_id"));
3319 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3320 spy.wait(SIGNAL_WAIT_TIME);
3321 root = j->item();
3322 }
3323
3324 Item child;3186 Item child;
3325 {3187 {
3326 unique_ptr<ItemJob> j(acc_.get("child_id"));3188 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3341,7 +3203,7 @@
33413203
3342 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3204 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
33433205
3344 uploader->finishUpload();3206 uploader->close();
33453207
3346 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime, provider still sleeping3208 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime, provider still sleeping
33473209
@@ -3352,21 +3214,13 @@
3352 EXPECT_FALSE(uploader->isValid());3214 EXPECT_FALSE(uploader->isValid());
3353 EXPECT_EQ(Uploader::Status::Error, uploader->status());3215 EXPECT_EQ(Uploader::Status::Error, uploader->status());
3354 EXPECT_EQ(StorageError::RuntimeDestroyed, uploader->error().type());3216 EXPECT_EQ(StorageError::RuntimeDestroyed, uploader->error().type());
3355 EXPECT_EQ("Uploader::finishUpload(): Runtime was destroyed previously", uploader->error().message());3217 EXPECT_EQ("Uploader::close(): Runtime was destroyed previously", uploader->error().message());
3356}3218}
33573219
3358TEST_F(UploadTest, finish_twice)3220TEST_F(UploadTest, finish_twice)
3359{3221{
3360 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));3222 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
33613223
3362 Item root;
3363 {
3364 unique_ptr<ItemJob> j(acc_.get("root_id"));
3365 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3366 spy.wait(SIGNAL_WAIT_TIME);
3367 root = j->item();
3368 }
3369
3370 Item child;3224 Item child;
3371 {3225 {
3372 unique_ptr<ItemJob> j(acc_.get("child_id"));3226 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3387,8 +3241,8 @@
33873241
3388 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3242 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
33893243
3390 uploader->finishUpload();3244 uploader->close();
3391 uploader->finishUpload();3245 uploader->close();
33923246
3393 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));3247 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
3394 auto arg = spy.takeFirst();3248 auto arg = spy.takeFirst();
@@ -3401,14 +3255,6 @@
3401{3255{
3402 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_upload_error")));3256 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_upload_error")));
34033257
3404 Item root;
3405 {
3406 unique_ptr<ItemJob> j(acc_.get("root_id"));
3407 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3408 spy.wait(SIGNAL_WAIT_TIME);
3409 root = j->item();
3410 }
3411
3412 Item child;3258 Item child;
3413 {3259 {
3414 unique_ptr<ItemJob> j(acc_.get("child_id"));3260 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3429,7 +3275,7 @@
34293275
3430 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3276 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
34313277
3432 uploader->finishUpload();3278 uploader->close();
34333279
3434 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));3280 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
3435 auto arg = spy.takeFirst();3281 auto arg = spy.takeFirst();
@@ -3472,14 +3318,6 @@
3472{3318{
3473 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));3319 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
34743320
3475 Item root;
3476 {
3477 unique_ptr<ItemJob> j(acc_.get("root_id"));
3478 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3479 spy.wait(SIGNAL_WAIT_TIME);
3480 root = j->item();
3481 }
3482
3483 Item child;3321 Item child;
3484 {3322 {
3485 unique_ptr<ItemJob> j(acc_.get("child_id"));3323 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3506,14 +3344,6 @@
3506{3344{
3507 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_returns_dir")));3345 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("upload_returns_dir")));
35083346
3509 Item root;
3510 {
3511 unique_ptr<ItemJob> j(acc_.get("root_id"));
3512 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3513 spy.wait(SIGNAL_WAIT_TIME);
3514 root = j->item();
3515 }
3516
3517 Item child;3347 Item child;
3518 {3348 {
3519 unique_ptr<ItemJob> j(acc_.get("child_id"));3349 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3533,7 +3363,7 @@
3533 }3363 }
35343364
3535 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3365 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
3536 uploader->finishUpload();3366 uploader->close();
3537 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));3367 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
3538 auto arg = spy.takeFirst();3368 auto arg = spy.takeFirst();
3539 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));3369 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
@@ -3547,14 +3377,6 @@
3547{3377{
3548 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));3378 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
35493379
3550 Item root;
3551 {
3552 unique_ptr<ItemJob> j(acc_.get("root_id"));
3553 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3554 spy.wait(SIGNAL_WAIT_TIME);
3555 root = j->item();
3556 }
3557
3558 Item child;3380 Item child;
3559 {3381 {
3560 unique_ptr<ItemJob> j(acc_.get("child_id"));3382 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3592,14 +3414,6 @@
3592{3414{
3593 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_upload_slow_error")));3415 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_upload_slow_error")));
35943416
3595 Item root;
3596 {
3597 unique_ptr<ItemJob> j(acc_.get("root_id"));
3598 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3599 spy.wait(SIGNAL_WAIT_TIME);
3600 root = j->item();
3601 }
3602
3603 Item child;3417 Item child;
3604 {3418 {
3605 unique_ptr<ItemJob> j(acc_.get("child_id"));3419 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3620,12 +3434,12 @@
36203434
3621 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3435 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
36223436
3623 uploader->finishUpload();3437 uploader->close();
36243438
3625 uploader->cancel();3439 uploader->cancel();
3626 uploader->cancel(); // Second time for coverage3440 uploader->cancel(); // Second time for coverage
36273441
3628 uploader->finishUpload(); // Second time for coverage3442 uploader->close(); // Second time for coverage
36293443
3630 EXPECT_EQ(1, spy.count());3444 EXPECT_EQ(1, spy.count());
3631 auto arg = spy.takeFirst();3445 auto arg = spy.takeFirst();
@@ -3635,7 +3449,7 @@
3635 EXPECT_EQ(StorageError::Type::Cancelled, uploader->error().type());3449 EXPECT_EQ(StorageError::Type::Cancelled, uploader->error().type());
3636 EXPECT_EQ("Uploader::cancel(): upload was cancelled", uploader->error().message());3450 EXPECT_EQ("Uploader::cancel(): upload was cancelled", uploader->error().message());
36373451
3638 // We wait here to get coverage for when the reply to a finishUpload() call3452 // We wait here to get coverage for when the reply to a FinishUpload() call
3639 // finds the uploader in a final state.3453 // finds the uploader in a final state.
3640 EXPECT_FALSE(spy.wait(2000));3454 EXPECT_FALSE(spy.wait(2000));
3641}3455}
@@ -3644,14 +3458,6 @@
3644{3458{
3645 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_upload_slow_error")));3459 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("finish_upload_slow_error")));
36463460
3647 Item root;
3648 {
3649 unique_ptr<ItemJob> j(acc_.get("root_id"));
3650 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3651 spy.wait(SIGNAL_WAIT_TIME);
3652 root = j->item();
3653 }
3654
3655 Item child;3461 Item child;
3656 {3462 {
3657 unique_ptr<ItemJob> j(acc_.get("child_id"));3463 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3730,7 +3536,7 @@
3730 EXPECT_EQ(contents.size(), uploader->write(contents));3536 EXPECT_EQ(contents.size(), uploader->write(contents));
37313537
3732 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3538 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
3733 uploader->finishUpload();3539 uploader->close();
3734 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));3540 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
3735 auto arg = spy.takeFirst();3541 auto arg = spy.takeFirst();
3736 EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0)));3542 EXPECT_EQ(Uploader::Status::Finished, qvariant_cast<Uploader::Status>(arg.at(0)));
@@ -3751,14 +3557,6 @@
3751 root = j->item();3557 root = j->item();
3752 }3558 }
37533559
3754 Item child;
3755 {
3756 unique_ptr<ItemJob> j(acc_.get("child_id"));
3757 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3758 spy.wait(SIGNAL_WAIT_TIME);
3759 child = j->item();
3760 }
3761
3762 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime3560 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime
37633561
3764 QByteArray contents("Hello world", -1);3562 QByteArray contents("Hello world", -1);
@@ -3783,14 +3581,6 @@
3783{3581{
3784 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));3582 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
37853583
3786 Item root;
3787 {
3788 unique_ptr<ItemJob> j(acc_.get("root_id"));
3789 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3790 spy.wait(SIGNAL_WAIT_TIME);
3791 root = j->item();
3792 }
3793
3794 Item child;3584 Item child;
3795 {3585 {
3796 unique_ptr<ItemJob> j(acc_.get("child_id"));3586 unique_ptr<ItemJob> j(acc_.get("child_id"));
@@ -3829,14 +3619,6 @@
3829 root = j->item();3619 root = j->item();
3830 }3620 }
38313621
3832 Item child;
3833 {
3834 unique_ptr<ItemJob> j(acc_.get("child_id"));
3835 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3836 spy.wait(SIGNAL_WAIT_TIME);
3837 child = j->item();
3838 }
3839
3840 QByteArray contents("Hello world", -1);3622 QByteArray contents("Hello world", -1);
3841 unique_ptr<Uploader> uploader(root.createFile("",3623 unique_ptr<Uploader> uploader(root.createFile("",
3842 Item::ConflictPolicy::IgnoreConflict,3624 Item::ConflictPolicy::IgnoreConflict,
@@ -3867,14 +3649,6 @@
3867 root = j->item();3649 root = j->item();
3868 }3650 }
38693651
3870 Item child;
3871 {
3872 unique_ptr<ItemJob> j(acc_.get("child_id"));
3873 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3874 spy.wait(SIGNAL_WAIT_TIME);
3875 child = j->item();
3876 }
3877
3878 QByteArray contents("Hello world", -1);3652 QByteArray contents("Hello world", -1);
3879 unique_ptr<Uploader> uploader(root.createFile("some_file",3653 unique_ptr<Uploader> uploader(root.createFile("some_file",
3880 Item::ConflictPolicy::IgnoreConflict,3654 Item::ConflictPolicy::IgnoreConflict,
@@ -3905,14 +3679,6 @@
3905 root = j->item();3679 root = j->item();
3906 }3680 }
39073681
3908 Item child;
3909 {
3910 unique_ptr<ItemJob> j(acc_.get("child_id"));
3911 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
3912 spy.wait(SIGNAL_WAIT_TIME);
3913 child = j->item();
3914 }
3915
3916 QByteArray contents("Hello world", -1);3682 QByteArray contents("Hello world", -1);
3917 unique_ptr<Uploader> uploader(root.createFile("some_file",3683 unique_ptr<Uploader> uploader(root.createFile("some_file",
3918 Item::ConflictPolicy::IgnoreConflict,3684 Item::ConflictPolicy::IgnoreConflict,
@@ -3930,7 +3696,7 @@
3930 EXPECT_EQ(contents.size(), uploader->write(contents));3696 EXPECT_EQ(contents.size(), uploader->write(contents));
39313697
3932 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3698 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
3933 uploader->finishUpload();3699 uploader->close();
3934 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));3700 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
3935 auto arg = spy.takeFirst();3701 auto arg = spy.takeFirst();
3936 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));3702 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
@@ -3968,7 +3734,7 @@
3968 EXPECT_EQ(contents.size(), uploader->write(contents));3734 EXPECT_EQ(contents.size(), uploader->write(contents));
39693735
3970 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);3736 QSignalSpy spy(uploader.get(), &Uploader::statusChanged);
3971 uploader->finishUpload();3737 uploader->close();
3972 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));3738 ASSERT_TRUE(spy.wait(SIGNAL_WAIT_TIME));
3973 auto arg = spy.takeFirst();3739 auto arg = spy.takeFirst();
3974 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));3740 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));

Subscribers

People subscribed via source and target branches

to all changes: