1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadAndHashCheckMar.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,213 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + */ 1.8 + 1.9 +var gNextRunFunc; 1.10 +var gExpectedStatusResult; 1.11 + 1.12 +function run_test() { 1.13 + // This test needs access to omni.ja to read the update.locale file so don't 1.14 + // use a custom directory for the application directory. 1.15 + gUseTestAppDir = false; 1.16 + setupTestCommon(); 1.17 + 1.18 + logTestInfo("testing mar download and mar hash verification"); 1.19 + 1.20 + Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false); 1.21 + // The HTTP server is only used for the mar file downloads since it is slow 1.22 + start_httpserver(); 1.23 + setUpdateURLOverride(gURLData + "update.xml"); 1.24 + // The mock XMLHttpRequest is MUCH faster 1.25 + overrideXHR(callHandleEvent); 1.26 + standardInit(); 1.27 + do_execute_soon(run_test_pt1); 1.28 +} 1.29 + 1.30 +// The HttpServer must be stopped before calling do_test_finished 1.31 +function finish_test() { 1.32 + stop_httpserver(doTestFinish); 1.33 +} 1.34 + 1.35 +// Callback function used by the custom XMLHttpRequest implementation to 1.36 +// call the nsIDOMEventListener's handleEvent method for onload. 1.37 +function callHandleEvent() { 1.38 + gXHR.status = 400; 1.39 + gXHR.responseText = gResponseBody; 1.40 + try { 1.41 + var parser = AUS_Cc["@mozilla.org/xmlextras/domparser;1"]. 1.42 + createInstance(AUS_Ci.nsIDOMParser); 1.43 + gXHR.responseXML = parser.parseFromString(gResponseBody, "application/xml"); 1.44 + } catch(e) { 1.45 + } 1.46 + var e = { target: gXHR }; 1.47 + gXHR.onload(e); 1.48 +} 1.49 + 1.50 +// Helper function for testing mar downloads that have the correct size 1.51 +// specified in the update xml. 1.52 +function run_test_helper_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) { 1.53 + gUpdates = null; 1.54 + gUpdateCount = null; 1.55 + gStatusResult = null; 1.56 + gCheckFunc = check_test_helper_pt1_1; 1.57 + gNextRunFunc = aNextRunFunc; 1.58 + gExpectedStatusResult = aExpectedStatusResult; 1.59 + logTestInfo(aMsg, Components.stack.caller); 1.60 + gUpdateChecker.checkForUpdates(updateCheckListener, true); 1.61 +} 1.62 + 1.63 +function check_test_helper_pt1_1() { 1.64 + do_check_eq(gUpdateCount, 1); 1.65 + gCheckFunc = check_test_helper_pt1_2; 1.66 + var bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount); 1.67 + var state = gAUS.downloadUpdate(bestUpdate, false); 1.68 + if (state == STATE_NONE || state == STATE_FAILED) 1.69 + do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state); 1.70 + gAUS.addDownloadListener(downloadListener); 1.71 +} 1.72 + 1.73 +function check_test_helper_pt1_2() { 1.74 + do_check_eq(gStatusResult, gExpectedStatusResult); 1.75 + gAUS.removeDownloadListener(downloadListener); 1.76 + gNextRunFunc(); 1.77 +} 1.78 + 1.79 +// The following 3 functions are a workaround for GONK due to Bug 828858 and 1.80 +// can be removed after it is fixed and the callers are changed to use the 1.81 +// regular helper functions. 1.82 +function run_test_helper_bug828858_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) { 1.83 + gUpdates = null; 1.84 + gUpdateCount = null; 1.85 + gStatusResult = null; 1.86 + gCheckFunc = check_test_helper_bug828858_pt1_1; 1.87 + gNextRunFunc = aNextRunFunc; 1.88 + gExpectedStatusResult = aExpectedStatusResult; 1.89 + logTestInfo(aMsg, Components.stack.caller); 1.90 + gUpdateChecker.checkForUpdates(updateCheckListener, true); 1.91 +} 1.92 + 1.93 +function check_test_helper_bug828858_pt1_1() { 1.94 + do_check_eq(gUpdateCount, 1); 1.95 + gCheckFunc = check_test_helper_bug828858_pt1_2; 1.96 + var bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount); 1.97 + var state = gAUS.downloadUpdate(bestUpdate, false); 1.98 + if (state == STATE_NONE || state == STATE_FAILED) 1.99 + do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state); 1.100 + gAUS.addDownloadListener(downloadListener); 1.101 +} 1.102 + 1.103 +function check_test_helper_bug828858_pt1_2() { 1.104 + if (gStatusResult == AUS_Cr.NS_ERROR_CONTENT_CORRUPTED) { 1.105 + do_check_eq(gStatusResult, AUS_Cr.NS_ERROR_CONTENT_CORRUPTED); 1.106 + } else { 1.107 + do_check_eq(gStatusResult, gExpectedStatusResult); 1.108 + } 1.109 + gAUS.removeDownloadListener(downloadListener); 1.110 + gNextRunFunc(); 1.111 +} 1.112 + 1.113 +function setResponseBody(aHashFunction, aHashValue, aSize) { 1.114 + var patches = getRemotePatchString(null, null, 1.115 + aHashFunction, aHashValue, aSize); 1.116 + var updates = getRemoteUpdateString(patches); 1.117 + gResponseBody = getRemoteUpdatesXMLString(updates); 1.118 +} 1.119 + 1.120 +// mar download with a valid MD5 hash 1.121 +function run_test_pt1() { 1.122 + setResponseBody("MD5", MD5_HASH_SIMPLE_MAR); 1.123 + run_test_helper_pt1("mar download with a valid MD5 hash", 1.124 + AUS_Cr.NS_OK, run_test_pt2); 1.125 +} 1.126 + 1.127 +// mar download with an invalid MD5 hash 1.128 +function run_test_pt2() { 1.129 + setResponseBody("MD5", MD5_HASH_SIMPLE_MAR + "0"); 1.130 + run_test_helper_pt1("mar download with an invalid MD5 hash", 1.131 + AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt3); 1.132 +} 1.133 + 1.134 +// mar download with a valid SHA1 hash 1.135 +function run_test_pt3() { 1.136 + setResponseBody("SHA1", SHA1_HASH_SIMPLE_MAR); 1.137 + run_test_helper_pt1("mar download with a valid SHA1 hash", 1.138 + AUS_Cr.NS_OK, run_test_pt4); 1.139 +} 1.140 + 1.141 +// mar download with an invalid SHA1 hash 1.142 +function run_test_pt4() { 1.143 + setResponseBody("SHA1", SHA1_HASH_SIMPLE_MAR + "0"); 1.144 + run_test_helper_pt1("mar download with an invalid SHA1 hash", 1.145 + AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt5); 1.146 +} 1.147 + 1.148 +// mar download with a valid SHA256 hash 1.149 +function run_test_pt5() { 1.150 + setResponseBody("SHA256", SHA256_HASH_SIMPLE_MAR); 1.151 + run_test_helper_pt1("mar download with a valid SHA256 hash", 1.152 + AUS_Cr.NS_OK, run_test_pt6); 1.153 +} 1.154 + 1.155 +// mar download with an invalid SHA256 hash 1.156 +function run_test_pt6() { 1.157 + setResponseBody("SHA256", SHA256_HASH_SIMPLE_MAR + "0"); 1.158 + run_test_helper_pt1("mar download with an invalid SHA256 hash", 1.159 + AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt7); 1.160 +} 1.161 + 1.162 +// mar download with a valid SHA384 hash 1.163 +function run_test_pt7() { 1.164 + setResponseBody("SHA384", SHA384_HASH_SIMPLE_MAR); 1.165 + run_test_helper_pt1("mar download with a valid SHA384 hash", 1.166 + AUS_Cr.NS_OK, run_test_pt8); 1.167 +} 1.168 + 1.169 +// mar download with an invalid SHA384 hash 1.170 +function run_test_pt8() { 1.171 + setResponseBody("SHA384", SHA384_HASH_SIMPLE_MAR + "0"); 1.172 + run_test_helper_pt1("mar download with an invalid SHA384 hash", 1.173 + AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt9); 1.174 +} 1.175 + 1.176 +// mar download with a valid SHA512 hash 1.177 +function run_test_pt9() { 1.178 + setResponseBody("SHA512", SHA512_HASH_SIMPLE_MAR); 1.179 + run_test_helper_pt1("mar download with a valid SHA512 hash", 1.180 + AUS_Cr.NS_OK, run_test_pt10); 1.181 +} 1.182 + 1.183 +// mar download with an invalid SHA512 hash 1.184 +function run_test_pt10() { 1.185 + setResponseBody("SHA512", SHA512_HASH_SIMPLE_MAR + "0"); 1.186 + run_test_helper_pt1("mar download with an invalid SHA512 hash", 1.187 + AUS_Cr.NS_ERROR_CORRUPTED_CONTENT, run_test_pt11); 1.188 +} 1.189 + 1.190 +// mar download with the mar not found 1.191 +function run_test_pt11() { 1.192 + var patches = getRemotePatchString(null, gURLData + "missing.mar"); 1.193 + var updates = getRemoteUpdateString(patches); 1.194 + gResponseBody = getRemoteUpdatesXMLString(updates); 1.195 + run_test_helper_pt1("mar download with the mar not found", 1.196 + AUS_Cr.NS_ERROR_UNEXPECTED, run_test_pt12); 1.197 +} 1.198 + 1.199 +// mar download with a valid MD5 hash but invalid file size 1.200 +function run_test_pt12() { 1.201 + const arbitraryFileSize = 1024000; 1.202 + setResponseBody("MD5", MD5_HASH_SIMPLE_MAR, arbitraryFileSize); 1.203 + if (IS_TOOLKIT_GONK) { 1.204 + // There seems to be a race on the web server side when the patchFile is 1.205 + // stored on the SDCard. Sometimes, the webserver will serve up an error 1.206 + // 416 and the contents of the file, and sometimes it will serve up an error 1.207 + // 200 and no contents. This can cause either NS_ERROR_UNEXPECTED or 1.208 + // NS_ERROR_CONTENT_CORRUPTED. 1.209 + // Bug 828858 was filed to follow up on this issue. 1.210 + run_test_helper_bug828858_pt1("mar download with a valid MD5 hash but invalid file size", 1.211 + AUS_Cr.NS_ERROR_UNEXPECTED, finish_test); 1.212 + } else { 1.213 + run_test_helper_pt1("mar download with a valid MD5 hash but invalid file size", 1.214 + AUS_Cr.NS_ERROR_UNEXPECTED, finish_test); 1.215 + } 1.216 +}