/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Application Update Service. * * The Initial Developer of the Original Code is * Robert Strong . * * Portions created by the Initial Developer are Copyright (C) 2008 * the Mozilla Foundation . All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ // const Cc, Ci, and Cr are defined in netwerk/test/httpserver/httpd.js so we // need to define unique ones. const AUS_Cc = Components.classes; const AUS_Ci = Components.interfaces; const AUS_Cr = Components.results; const NS_APP_PROFILE_DIR_STARTUP = "ProfDS"; const NS_APP_USER_PROFILE_50_DIR = "ProfD"; const NS_GRE_DIR = "GreD"; const NS_XPCOM_CURRENT_PROCESS_DIR = "XCurProcD" const XRE_UPDATE_ROOT_DIR = "UpdRootD"; const PREF_APP_UPDATE_URL_OVERRIDE = "app.update.url.override"; const PREF_APP_UPDATE_SHOW_INSTALLED_UI = "app.update.showInstalledUI"; const URI_UPDATES_PROPERTIES = "chrome://mozapps/locale/update/updates.properties"; const gUpdateBundle = AUS_Cc["@mozilla.org/intl/stringbundle;1"]. getService(AUS_Ci.nsIStringBundleService). createBundle(URI_UPDATES_PROPERTIES); const STATE_NONE = "null"; const STATE_DOWNLOADING = "downloading"; const STATE_PENDING = "pending"; const STATE_APPLYING = "applying"; const STATE_SUCCEEDED = "succeeded"; const STATE_DOWNLOAD_FAILED = "download-failed"; const STATE_FAILED = "failed"; const FILE_UPDATES_DB = "updates.xml"; const FILE_UPDATE_ACTIVE = "active-update.xml"; const MODE_RDONLY = 0x01; const MODE_WRONLY = 0x02; const MODE_CREATE = 0x08; const MODE_APPEND = 0x10; const MODE_TRUNCATE = 0x20; const PERMS_FILE = 0644; const PERMS_DIRECTORY = 0755; const URL_HOST = "http://localhost:4444/" const DIR_DATA = "data" const URL_PREFIX = URL_HOST + DIR_DATA + "/"; const REL_TEST_PATH = "toolkit/mozapps/update/test/unit/"; const POST_UPDATE_CONTRACTID = "@mozilla.org/updates/post-update;1"; var gDirSvc = AUS_Cc["@mozilla.org/file/directory_service;1"]. getService(AUS_Ci.nsIProperties); var gAUS; var gUpdateChecker; var gUpdateManager; var gTestserver; var gCheckFunc; var gResponseBody; var gRequestURL; var gUpdateCount; var gUpdates; var gStatusCode; var gStatusText; function getPrefBranch() { return AUS_Cc["@mozilla.org/preferences;1"].getService(AUS_Ci.nsIPrefBranch); } /** * Nulls out the most commonly used global vars used by tests as appropriate. * This was moved here from the tail file due to check-interactive executing * the tail file prior to _execute_test(); (bug 384339). It hasn't been moved * back since it is easier to comment out the call to cleanUp when needed. */ function cleanUp() { // Always call app update's observe method passing xpcom-shutdown to test that // the shutdown of app update runs without throwing or leaking. The observer // method is used directly instead of calling notifyObservers so components // outside of the scope of this test don't assert and thereby cause app update // tests to fail. if (gAUS) gAUS.observe(null, "xpcom-shutdown", ""); removeUpdateDirsAndFiles(); gDirSvc.unregisterProvider(gDirProvider); gUpdateManager = null; gUpdateChecker = null; gAUS = null; gTestserver = null; } /** * Initializes the most commonly used global vars used by tests and * nsIApplicationUpdateService */ function startAUS() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1.0", "2.0"); var pb = getPrefBranch(); // Don't display UI for a successful installation. Some apps may not set this // pref to false like Firefox does. pb.setBoolPref(PREF_APP_UPDATE_SHOW_INSTALLED_UI, false); // Enable Update logging pb.setBoolPref("app.update.log.all", true); // Lessens the noise in the logs when using Update Service logging pb.setBoolPref("app.update.enabled", false); pb.setBoolPref("extensions.blocklist.enabled", false); pb.setBoolPref("extensions.update.enabled", false); pb.setBoolPref("browser.search.update", false); pb.setBoolPref("browser.microsummary.updateGenerators", false); // Override nsPostUpdateWin if it exists to prevent errors in the test logs. if (POST_UPDATE_CONTRACTID in Components.classes) { var registrar = Components.manager.QueryInterface(AUS_Ci.nsIComponentRegistrar); registrar.registerFactory(gPostUpdateWin.classID, gPostUpdateWin.classDescription, gPostUpdateWin.contractID, gPostUpdateWin); } gAUS = AUS_Cc["@mozilla.org/updates/update-service;1"]. getService(AUS_Ci.nsIApplicationUpdateService). QueryInterface(AUS_Ci.nsIObserver); var os = AUS_Cc["@mozilla.org/observer-service;1"]. getService(AUS_Ci.nsIObserverService); os.notifyObservers(null, "profile-after-change", null); os.notifyObservers(null, "final-ui-startup", null); } /* Initializes nsIUpdateChecker */ function startUpdateChecker() { gUpdateChecker = AUS_Cc["@mozilla.org/updates/update-checker;1"]. createInstance(AUS_Ci.nsIUpdateChecker); } /* Initializes nsIUpdateManager */ function startUpdateManager() { gUpdateManager = AUS_Cc["@mozilla.org/updates/update-manager;1"]. getService(AUS_Ci.nsIUpdateManager); } /** * Constructs a string representing a remote update xml file. * @param aUpdates * The string representing the update elements. * @returns The string representing a remote update xml file. */ function getRemoteUpdatesXMLString(aUpdates) { return "\n" + "\n" + aUpdates + "\n"; } /** * Constructs a string representing an update element for a remote update xml * file. * See getUpdateString * @returns The string representing an update element for an update xml file. */ function getRemoteUpdateString(aPatches, aName, aType, aVersion, aPlatformVersion, aExtensionVersion, aBuildID, aLicenseURL, aDetailsURL) { return getUpdateString(aName, aType, aVersion, aPlatformVersion, aExtensionVersion, aBuildID, aLicenseURL, aDetailsURL) + ">\n" + aPatches + " \n"; } /** * Constructs a string representing a patch element for a remote update xml * file * See getPatchString * @returns The string representing a patch element for a remote update xml * file. */ function getRemotePatchString(aType, aURL, aHashFunction, aHashValue, aSize) { return getPatchString(aType, aURL, aHashFunction, aHashValue, aSize) + "/>\n"; } /** * Constructs a string representing a local update xml file. * @param aUpdates * The string representing the update elements. * @returns The string representing a local update xml file. */ function getLocalUpdatesXMLString(aUpdates) { if (!aUpdates || aUpdates == "") return "" return ("" + aUpdates + "").replace(/>\s+\n*<'); } /** * Constructs a string representing an update element for a local update xml * file. * See getUpdateString * @param aServiceURL * The update's xml url. * If null this will default to 'http://dummyservice/'. * @param aIsCompleteUpdate * The string 'true' if this update was a complete update or the string * 'false' if this update was a partial update. * If null this will default to 'true'. * @param aChannel * The update channel name. * If null this will default to 'bogus_channel'. * @param aForegroundDownload * The string 'true' if this update was manually downloaded or the * string 'false' if this update was automatically downloaded. * If null this will default to 'true'. * @returns The string representing an update element for an update xml file. */ function getLocalUpdateString(aPatches, aName, aType, aVersion, aPlatformVersion, aExtensionVersion, aBuildID, aLicenseURL, aDetailsURL, aServiceURL, aInstallDate, aStatusText, aIsCompleteUpdate, aChannel, aForegroundDownload) { var serviceURL = aServiceURL ? aServiceURL : "http://dummyservice/"; var installDate = aInstallDate ? aInstallDate : "1238441400314"; var statusText = aStatusText ? aStatusText : "Install Pending"; var isCompleteUpdate = typeof(aIsCompleteUpdate) == "string" ? aIsCompleteUpdate : "true"; var channel = aChannel ? aChannel : "bogus_channel"; var foregroundDownload = typeof(aForegroundDownload) == "string" ? aForegroundDownload : "true"; return getUpdateString(aName, aType, aVersion, aPlatformVersion, aExtensionVersion, aBuildID, aLicenseURL, aDetailsURL) + " " + "serviceURL=\"" + serviceURL + "\" " + "installDate=\"" + installDate + "\" " + "statusText=\"" + statusText + "\" " + "isCompleteUpdate=\"" + isCompleteUpdate + "\" " + "channel=\"" + channel + "\" " + "foregroundDownload=\"" + foregroundDownload + "\">" + aPatches + " "; } /** * Constructs a string representing a patch element for a local update xml file. * See getPatchString * @param aSelected * Whether this patch is selected represented or not. The string 'true' * denotes selected and the string 'false' denotes not selected. * If null this will default to the string 'true'. * @param aState * The patch's state. * If null this will default to STATE_SUCCEEDED (e.g. 'succeeded'). * @returns The string representing a patch element for a local update xml file. */ function getLocalPatchString(aType, aURL, aHashFunction, aHashValue, aSize, aSelected, aState) { var selected = typeof(aSelected) == "string" ? aSelected : "true"; var state = aState ? aState : STATE_SUCCEEDED; return getPatchString(aType, aURL, aHashFunction, aHashValue, aSize) + " " + "selected=\"" + selected + "\" " + "state=\"" + state + "\"/>\n"; } /** * Constructs a string representing an update element for a remote update xml * file. * @param aPatches * The string representing the update's patches. * @param aName * The update's name. * If null this will default to 'XPCShell App Update Test'. * @param aType * The update's type which should be major or minor. * If null this will default to 'major'. * @param aVersion * The update's app version. * If null this will default to '4.0'. * @param aPlatformVersion * The update's platform version. * If null this will default to '4.0'. * @param aExtensionVersion * The update's extension version. * If null this will default to '4.0'. * @param aBuildID * The update's build id. * If null this will default to '20080811053724'. * @param aLicenseURL * The update's license url. * If null this will default to 'http://dummylicense/'. * @param aDetailsURL * The update's details url. * If null this will default to 'http://dummydetails/'. * @returns The string representing an update element for an update xml file. */ function getUpdateString(aName, aType, aVersion, aPlatformVersion, aExtensionVersion, aBuildID, aLicenseURL, aDetailsURL) { var name = aName ? aName : "XPCShell App Update Test"; var type = aType ? aType : "major"; var version = aVersion ? aVersion : "4.0"; var platformVersion = aPlatformVersion ? aPlatformVersion : "4.0"; var extensionVersion = aExtensionVersion ? aExtensionVersion : "4.0"; var buildID = aBuildID ? aBuildID : "20080811053724"; var licenseURL = aLicenseURL ? aLicenseURL : "http://dummylicense/"; var detailsURL = aDetailsURL ? aDetailsURL : "http://dummydetails/"; return "