CB-8641 (Windows Phone 8.1) Some file-transfer plugin tests occasionally fail in mobilespec

Increases timeout for Windows case for spec.10, spec.21 (abort right away), spec.15 (unknown host)
Documents the latency quirk caused by BackgroundDownloader usage
[Windows] Mark an upload aborted to be cancelled right away as it did not have enough time to be created when abort was called in filetransfer.spec.21 (so that unexpected httpWin fired)
Extended test buffer to avoid unexpectedCallbacks.httpWin on Windows & local test server (filetransfer.spec.21)
This commit is contained in:
daserge 2015-12-03 20:59:03 +03:00
parent 0913325be5
commit a762f3fe58
3 changed files with 25 additions and 12 deletions

View File

@ -290,6 +290,10 @@ A `FileTransferError` object is passed to an error callback when an error occurs
- 4 = `FileTransferError.ABORT_ERR`
- 5 = `FileTransferError.NOT_MODIFIED_ERR`
## Windows Quirks
- The plugin implementation is based on [BackgroundDownloader](https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.backgrounddownloader.aspx)/[BackgroundUploader](https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.backgrounduploader.aspx), which entails the latency issues on Windows devices (creation/starting of an operation can take up to a few seconds). You can use XHR or [HttpClient](https://msdn.microsoft.com/en-us/library/windows/apps/windows.web.http.httpclient.aspx) as a quicker alternative for small downloads.
## Backwards Compatibility Notes
Previous versions of this plugin would only accept device-absolute-file-paths as the source for uploads, or as the target for downloads. These paths would typically be of the form

View File

@ -49,6 +49,11 @@ function nativePathToCordova(path) {
return String(path).replace(/\\/g, '/');
}
function alreadyCancelled(opId) {
var op = fileTransferOps[opId];
return op && op.state === FileTransferOperation.CANCELLED;
}
var fileTransferOps = [];
function FileTransferOperation(state, promise) {
@ -116,10 +121,7 @@ exec(win, fail, 'FileTransfer', 'upload',
mimeType = storageFile.contentType;
}
// check if download isn't already cancelled
var uploadOp = fileTransferOps[uploadId];
if (uploadOp && uploadOp.state === FileTransferOperation.CANCELLED) {
// Here we should call errorCB with ABORT_ERR error
if (alreadyCancelled(uploadId)) {
errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));
return;
}
@ -166,6 +168,11 @@ exec(win, fail, 'FileTransfer', 'upload',
createUploadOperation.then(
function (upload) {
if (alreadyCancelled(uploadId)) {
errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));
return;
}
// update internal TransferOperation object with newly created promise
var uploadOperation = upload.startAsync();
fileTransferOps[uploadId].promise = uploadOperation;
@ -298,10 +305,7 @@ exec(win, fail, 'FileTransfer', 'upload',
var downloadCallback = function(storageFolder) {
storageFolder.createFileAsync(tempFileName, Windows.Storage.CreationCollisionOption.replaceExisting).then(function (storageFile) {
// check if download isn't already cancelled
var downloadOp = fileTransferOps[downloadId];
if (downloadOp && downloadOp.state === FileTransferOperation.CANCELLED) {
// Here we should call errorCB with ABORT_ERR error
if (alreadyCancelled(downloadId)) {
errorCallback(new FTErr(FTErr.ABORT_ERR, source, target));
return;
}
@ -431,6 +435,9 @@ exec(win, fail, 'FileTransfer', 'upload',
if (currentOp) {
currentOp.state = FileTransferOperation.CANCELLED;
currentOp.promise && currentOp.promise.cancel();
} else if (typeof fileTransferOpId !== 'undefined') {
// Create the operation in cancelled state to be aborted right away
fileTransferOps[fileTransferOpId] = new FileTransferOperation(FileTransferOperation.CANCELLED, null);
}
}

View File

@ -31,9 +31,11 @@ exports.defineAutoTests = function () {
var ONE_SECOND = 1000; // in milliseconds
var GRACE_TIME_DELTA = 600; // in milliseconds
var DEFAULT_FILESYSTEM_SIZE = 1024 * 50; // filesystem size in bytes
var WINDOWS_GRACE_TIME_DELTA = 5 * ONE_SECOND; // Some Windows devices need a few seconds to create an upload/download operation.
var UNKNOWN_HOST = "http://foobar.apache.org";
var HEADERS_ECHO = "http://whatheaders.com"; // NOTE: this site is very useful!
var DOWNLOAD_TIMEOUT = 7 * ONE_SECOND;
var WINDOWS_UNKNOWN_HOST_TIMEOUT = 35 * ONE_SECOND;
var UPLOAD_TIMEOUT = 7 * ONE_SECOND;
var ABORT_DELAY = 100; // for abort() tests
@ -479,7 +481,7 @@ exports.defineAutoTests = function () {
var downloadFail = function (error) {
expect(error.code).toBe(FileTransferError.ABORT_ERR);
expect(new Date() - startTime).toBeLessThan(GRACE_TIME_DELTA);
expect(new Date() - startTime).toBeLessThan(isWindows ? WINDOWS_GRACE_TIME_DELTA : GRACE_TIME_DELTA);
// delay calling done() to wait for the bogus abort()
setTimeout(done, GRACE_TIME_DELTA * 2);
@ -566,7 +568,7 @@ exports.defineAutoTests = function () {
transfer.onprogress = function () {};
transfer.download(fileURL, localFilePath, unexpectedCallbacks.httpWin, downloadFail);
}, DOWNLOAD_TIMEOUT);
}, isWindows ? WINDOWS_UNKNOWN_HOST_TIMEOUT : DOWNLOAD_TIMEOUT);
it("filetransfer.spec.16 should handle bad file path", function (done) {
var fileURL = SERVER;
@ -830,7 +832,7 @@ exports.defineAutoTests = function () {
var uploadFail = function (e) {
expect(e.code).toBe(FileTransferError.ABORT_ERR);
expect(new Date() - startTime).toBeLessThan(GRACE_TIME_DELTA);
expect(new Date() - startTime).toBeLessThan(isWindows ? WINDOWS_GRACE_TIME_DELTA : GRACE_TIME_DELTA);
// delay calling done() to wait for the bogus abort()
setTimeout(done, GRACE_TIME_DELTA * 2);
@ -853,7 +855,7 @@ exports.defineAutoTests = function () {
}, GRACE_TIME_DELTA);
};
writeFile(root, fileName, new Array(100000).join("aborttest!"), fileWin);
writeFile(root, fileName, new Array(200000).join("aborttest!"), fileWin);
}, UPLOAD_TIMEOUT);
it("filetransfer.spec.22 should get http status and body on failure", function (done) {