toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedRecovery.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 4 */
michael@0 5
michael@0 6 /* General MAR File Download Tests */
michael@0 7
michael@0 8 const INC_CONTRACT_ID = "@mozilla.org/network/incremental-download;1";
michael@0 9
michael@0 10 var gIncrementalDownloadClassID, gIncOldFactory;
michael@0 11 // gIncrementalDownloadErrorType is used to loop through each of the connection
michael@0 12 // error types in the Mock incremental downloader.
michael@0 13 var gIncrementalDownloadErrorType = 0;
michael@0 14
michael@0 15 var gNextRunFunc;
michael@0 16 var gExpectedStatusResult;
michael@0 17
michael@0 18 function run_test() {
michael@0 19 setupTestCommon();
michael@0 20
michael@0 21 logTestInfo("testing mar downloads, mar hash verification, and " +
michael@0 22 "mar download interrupted recovery");
michael@0 23
michael@0 24 Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
michael@0 25 // The HTTP server is only used for the mar file downloads since it is slow
michael@0 26 start_httpserver();
michael@0 27 setUpdateURLOverride(gURLData + "update.xml");
michael@0 28 // The mock XMLHttpRequest is MUCH faster
michael@0 29 overrideXHR(callHandleEvent);
michael@0 30 standardInit();
michael@0 31 do_execute_soon(run_test_pt1);
michael@0 32 }
michael@0 33
michael@0 34 // The HttpServer must be stopped before calling do_test_finished
michael@0 35 function finish_test() {
michael@0 36 stop_httpserver(doTestFinish);
michael@0 37 }
michael@0 38
michael@0 39 function end_test() {
michael@0 40 cleanupMockIncrementalDownload();
michael@0 41 }
michael@0 42
michael@0 43 // Callback function used by the custom XMLHttpRequest implementation to
michael@0 44 // call the nsIDOMEventListener's handleEvent method for onload.
michael@0 45 function callHandleEvent() {
michael@0 46 gXHR.status = 400;
michael@0 47 gXHR.responseText = gResponseBody;
michael@0 48 try {
michael@0 49 var parser = AUS_Cc["@mozilla.org/xmlextras/domparser;1"].
michael@0 50 createInstance(AUS_Ci.nsIDOMParser);
michael@0 51 gXHR.responseXML = parser.parseFromString(gResponseBody, "application/xml");
michael@0 52 } catch (e) {
michael@0 53 }
michael@0 54 var e = { target: gXHR };
michael@0 55 gXHR.onload(e);
michael@0 56 }
michael@0 57
michael@0 58 // Helper function for testing mar downloads that have the correct size
michael@0 59 // specified in the update xml.
michael@0 60 function run_test_helper_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
michael@0 61 gUpdates = null;
michael@0 62 gUpdateCount = null;
michael@0 63 gStatusResult = null;
michael@0 64 gCheckFunc = check_test_helper_pt1_1;
michael@0 65 gNextRunFunc = aNextRunFunc;
michael@0 66 gExpectedStatusResult = aExpectedStatusResult;
michael@0 67 logTestInfo(aMsg, Components.stack.caller);
michael@0 68 gUpdateChecker.checkForUpdates(updateCheckListener, true);
michael@0 69 }
michael@0 70
michael@0 71 function check_test_helper_pt1_1() {
michael@0 72 do_check_eq(gUpdateCount, 1);
michael@0 73 gCheckFunc = check_test_helper_pt1_2;
michael@0 74 var bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
michael@0 75 var state = gAUS.downloadUpdate(bestUpdate, false);
michael@0 76 if (state == STATE_NONE || state == STATE_FAILED)
michael@0 77 do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
michael@0 78 gAUS.addDownloadListener(downloadListener);
michael@0 79 }
michael@0 80
michael@0 81 function check_test_helper_pt1_2() {
michael@0 82 do_check_eq(gStatusResult, gExpectedStatusResult);
michael@0 83 gAUS.removeDownloadListener(downloadListener);
michael@0 84 gNextRunFunc();
michael@0 85 }
michael@0 86
michael@0 87 function setResponseBody(aHashFunction, aHashValue, aSize) {
michael@0 88 var patches = getRemotePatchString(null, null,
michael@0 89 aHashFunction, aHashValue, aSize);
michael@0 90 var updates = getRemoteUpdateString(patches);
michael@0 91 gResponseBody = getRemoteUpdatesXMLString(updates);
michael@0 92 }
michael@0 93
michael@0 94 var newFactory = {
michael@0 95 createInstance: function(aOuter, aIID) {
michael@0 96 if (aOuter)
michael@0 97 throw Components.results.NS_ERROR_NO_AGGREGATION;
michael@0 98 return new IncrementalDownload().QueryInterface(aIID);
michael@0 99 },
michael@0 100 lockFactory: function(aLock) {
michael@0 101 throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
michael@0 102 },
michael@0 103 QueryInterface: XPCOMUtils.generateQI([AUS_Ci.nsIFactory])
michael@0 104 };
michael@0 105
michael@0 106 function initMockIncrementalDownload() {
michael@0 107 var registrar = AUS_Cm.QueryInterface(AUS_Ci.nsIComponentRegistrar);
michael@0 108 gIncrementalDownloadClassID = registrar.contractIDToCID(INC_CONTRACT_ID);
michael@0 109 gIncOldFactory = AUS_Cm.getClassObject(AUS_Cc[INC_CONTRACT_ID],
michael@0 110 AUS_Ci.nsIFactory);
michael@0 111 registrar.unregisterFactory(gIncrementalDownloadClassID, gIncOldFactory);
michael@0 112 var components = [IncrementalDownload];
michael@0 113 registrar.registerFactory(gIncrementalDownloadClassID, "",
michael@0 114 INC_CONTRACT_ID, newFactory);
michael@0 115 }
michael@0 116
michael@0 117 function cleanupMockIncrementalDownload() {
michael@0 118 if (gIncOldFactory) {
michael@0 119 var registrar = AUS_Cm.QueryInterface(AUS_Ci.nsIComponentRegistrar);
michael@0 120 registrar.unregisterFactory(gIncrementalDownloadClassID, newFactory);
michael@0 121 registrar.registerFactory(gIncrementalDownloadClassID, "",
michael@0 122 INC_CONTRACT_ID, gIncOldFactory);
michael@0 123 }
michael@0 124 gIncOldFactory = null;
michael@0 125 }
michael@0 126
michael@0 127 /* This Mock incremental downloader is used to verify that connection
michael@0 128 * interrupts work correctly in updater code. The implementation of
michael@0 129 * the mock incremental downloader is very simple, it simply copies
michael@0 130 * the file to the destination location.
michael@0 131 */
michael@0 132
michael@0 133 function IncrementalDownload() {
michael@0 134 this.wrappedJSObject = this;
michael@0 135 }
michael@0 136
michael@0 137 IncrementalDownload.prototype = {
michael@0 138 QueryInterface: XPCOMUtils.generateQI([AUS_Ci.nsIIncrementalDownload]),
michael@0 139
michael@0 140 /* nsIIncrementalDownload */
michael@0 141 init: function(uri, file, chunkSize, intervalInSeconds) {
michael@0 142 this._destination = file;
michael@0 143 this._URI = uri;
michael@0 144 this._finalURI = uri;
michael@0 145 },
michael@0 146
michael@0 147 start: function(observer, ctxt) {
michael@0 148 var tm = Components.classes["@mozilla.org/thread-manager;1"].
michael@0 149 getService(AUS_Ci.nsIThreadManager);
michael@0 150 // Do the actual operation async to give a chance for observers
michael@0 151 // to add themselves.
michael@0 152 tm.mainThread.dispatch(function() {
michael@0 153 this._observer = observer.QueryInterface(AUS_Ci.nsIRequestObserver);
michael@0 154 this._ctxt = ctxt;
michael@0 155 this._observer.onStartRequest(this, this.ctxt);
michael@0 156 let mar = getTestDirFile(FILE_SIMPLE_MAR);
michael@0 157 mar.copyTo(this._destination.parent, this._destination.leafName);
michael@0 158 var status = AUS_Cr.NS_OK
michael@0 159 switch (gIncrementalDownloadErrorType++) {
michael@0 160 case 0:
michael@0 161 status = AUS_Cr.NS_ERROR_NET_RESET;
michael@0 162 break;
michael@0 163 case 1:
michael@0 164 status = AUS_Cr.NS_ERROR_CONNECTION_REFUSED;
michael@0 165 break;
michael@0 166 case 2:
michael@0 167 status = AUS_Cr.NS_ERROR_NET_RESET;
michael@0 168 break;
michael@0 169 case 3:
michael@0 170 status = AUS_Cr.NS_OK;
michael@0 171 break;
michael@0 172 case 4:
michael@0 173 status = AUS_Cr.NS_ERROR_OFFLINE;
michael@0 174 // After we report offline, we want to eventually show offline
michael@0 175 // status being changed to online.
michael@0 176 var tm = Components.classes["@mozilla.org/thread-manager;1"].
michael@0 177 getService(AUS_Ci.nsIThreadManager);
michael@0 178 tm.mainThread.dispatch(function() {
michael@0 179 Services.obs.notifyObservers(gAUS,
michael@0 180 "network:offline-status-changed",
michael@0 181 "online");
michael@0 182 }, AUS_Ci.nsIThread.DISPATCH_NORMAL);
michael@0 183 break;
michael@0 184 }
michael@0 185 this._observer.onStopRequest(this, this._ctxt, status);
michael@0 186 }.bind(this), AUS_Ci.nsIThread.DISPATCH_NORMAL);
michael@0 187 },
michael@0 188
michael@0 189 get URI() {
michael@0 190 return this._URI;
michael@0 191 },
michael@0 192
michael@0 193 get currentSize() {
michael@0 194 throw AUS_Cr.NS_ERROR_NOT_IMPLEMENTED;
michael@0 195 },
michael@0 196
michael@0 197 get destination() {
michael@0 198 return this._destination;
michael@0 199 },
michael@0 200
michael@0 201 get finalURI() {
michael@0 202 return this._finalURI;
michael@0 203 },
michael@0 204
michael@0 205 get totalSize() {
michael@0 206 throw AUS_Cr.NS_ERROR_NOT_IMPLEMENTED;
michael@0 207 },
michael@0 208
michael@0 209 /* nsIRequest */
michael@0 210 cancel: function(aStatus) {
michael@0 211 throw AUS_Cr.NS_ERROR_NOT_IMPLEMENTED;
michael@0 212 },
michael@0 213 suspend: function() {
michael@0 214 throw AUS_Cr.NS_ERROR_NOT_IMPLEMENTED;
michael@0 215 },
michael@0 216 isPending: function() {
michael@0 217 throw AUS_Cr.NS_ERROR_NOT_IMPLEMENTED;
michael@0 218 },
michael@0 219 _loadFlags: 0,
michael@0 220 get loadFlags() {
michael@0 221 return this._loadFlags;
michael@0 222 },
michael@0 223 set loadFlags(val) {
michael@0 224 this._loadFlags = val;
michael@0 225 },
michael@0 226
michael@0 227 _loadGroup: null,
michael@0 228 get loadGroup() {
michael@0 229 return this._loadGroup;
michael@0 230 },
michael@0 231 set loadGroup(val) {
michael@0 232 this._loadGroup = val;
michael@0 233 },
michael@0 234
michael@0 235 _name: "",
michael@0 236 get name() {
michael@0 237 return this._name;
michael@0 238 },
michael@0 239
michael@0 240 _status: 0,
michael@0 241 get status() {
michael@0 242 return this._status;
michael@0 243 }
michael@0 244 }
michael@0 245
michael@0 246 // Test disconnecting during an update
michael@0 247 function run_test_pt1() {
michael@0 248 initMockIncrementalDownload();
michael@0 249 setResponseBody("MD5", MD5_HASH_SIMPLE_MAR);
michael@0 250 run_test_helper_pt1("mar download with connection interruption",
michael@0 251 AUS_Cr.NS_OK, run_test_pt2);
michael@0 252 }
michael@0 253
michael@0 254 // Test disconnecting during an update
michael@0 255 function run_test_pt2() {
michael@0 256 gIncrementalDownloadErrorType = 0;
michael@0 257 Services.prefs.setIntPref(PREF_APP_UPDATE_SOCKET_ERRORS, 2);
michael@0 258 Services.prefs.setIntPref(PREF_APP_UPDATE_RETRY_TIMEOUT, 0);
michael@0 259 setResponseBody("MD5", MD5_HASH_SIMPLE_MAR);
michael@0 260
michael@0 261 var expectedResult;
michael@0 262 if (IS_TOOLKIT_GONK) {
michael@0 263 // Gonk treats interrupted downloads differently. For gonk, if the state
michael@0 264 // is pending, this means that the download has completed and only the
michael@0 265 // staging needs to occur. So gonk will skip the download portion which
michael@0 266 // results in an NS_OK return.
michael@0 267 expectedResult = AUS_Cr.NS_OK;
michael@0 268 } else {
michael@0 269 expectedResult = AUS_Cr.NS_ERROR_NET_RESET;
michael@0 270 }
michael@0 271 run_test_helper_pt1("mar download with connection interruption without recovery",
michael@0 272 expectedResult, run_test_pt3);
michael@0 273 }
michael@0 274
michael@0 275 // Test entering offline mode while downloading
michael@0 276 function run_test_pt3() {
michael@0 277 gIncrementalDownloadErrorType = 4;
michael@0 278 setResponseBody("MD5", MD5_HASH_SIMPLE_MAR);
michael@0 279 run_test_helper_pt1("mar download with offline mode",
michael@0 280 AUS_Cr.NS_OK, finish_test);
michael@0 281 }

mercurial