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.

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

mercurial