Bug 452317 - FeedConverter.js: QueryInterface should throw NS_ERROR_NO_INTERFACE...
[wine-gecko.git] / toolkit / mozapps / update / test / unit / test_0110_general.js
blob4aee682fd256973eddb59c1901768be4397e27b7
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is the Application Update Service.
15  *
16  * The Initial Developer of the Original Code is
17  * Robert Strong <robert.bugzilla@gmail.com>.
18  *
19  * Portions created by the Initial Developer are Copyright (C) 2008
20  * the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
21  *
22  * Contributor(s):
23  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either the GNU General Public License Version 2 or later (the "GPL"), or
26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK *****
37  */
39 /* General MAR File Tests */
41 const DIR_DATA = "data"
42 const URL_PREFIX = "http://localhost:4444/" + DIR_DATA + "/";
44 const PREF_APP_UPDATE_URL_OVERRIDE = "app.update.url.override";
46 var gUpdates;
47 var gUpdateCount;
48 var gStatus;
49 var gExpectedStatus;
50 var gCheckFunc;
51 var gNextRunFunc;
53 var gTestDir;
54 var gUpdater;
55 var gUpdatesDir;
56 var gUpdatesDirPath;
58 function run_test() {
59   do_test_pending();
61   var fileLocator = AUS_Cc["@mozilla.org/file/directory_service;1"]
62                       .getService(AUS_Ci.nsIProperties);
64   // The directory the updates will be applied to is the current working
65   // directory (e.g. obj-dir/toolkit/mozapps/update/test) and not dist/bin
66   gTestDir = fileLocator.get("CurWorkD", AUS_Ci.nsIFile);
67   // The mar files were created with all files in a subdirectory named
68   // mar_test... clear it out of the way if it exists and recreate it.
69   gTestDir.append("mar_test");
70   if (gTestDir.exists())
71     gTestDir.remove(true);
72   gTestDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, 0755);
74   // Create an empty test file to test the complete mar's ability to replace an
75   // existing file.
76   var testFile = gTestDir.clone();
77   testFile.append("text1");
78   testFile.create(AUS_Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
80   var binDir = fileLocator.get("XCurProcD", AUS_Ci.nsIFile);
82   // The updater binary file
83   gUpdater = binDir.clone();
84   gUpdater.append("updater.app");
85   if (!gUpdater.exists()) {
86     gUpdater = binDir.clone();
87     gUpdater.append("updater.exe");
88     if (!gUpdater.exists()) {
89       gUpdater = binDir.clone();
90       gUpdater.append("updater");
91       if (!gUpdater.exists()) {
92         do_throw("Unable to find updater binary!");
93       }
94     }
95   }
97   // The dir where the mar file is located
98   gUpdatesDir = binDir.clone();
99   gUpdatesDir.append("updates");
100   gUpdatesDir.append("0");
102   // Quoted path to the dir where the mar file is located
103   gUpdatesDirPath = gUpdatesDir.path;
104   if (/ /.test(gUpdatesDirPath))
105     gUpdatesDirPath = '"' + gUpdatesDirPath + '"';
107   startAUS();
108   start_httpserver(DIR_DATA);
109   do_timeout(0, "run_test_pt1()");
112 function end_test() {
113   stop_httpserver();
114   if (gTestDir.exists())
115     gTestDir.remove(true);
116   do_test_finished();
119 // Helper functions for testing mar downloads that have the correct size
120 // specified in the update xml.
121 function run_test_helper(aUpdateXML, aMsg, aResult, aNextRunFunc) {
122   gUpdates = null;
123   gUpdateCount = null;
124   gStatus = null;
125   gCheckFunc = check_test_helper_pt1;
126   gNextRunFunc = aNextRunFunc;
127   gExpectedStatus = aResult;
128   var url = URL_PREFIX + aUpdateXML;
129   dump("Testing: " + aMsg + " - " + url + "\n");
130   gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
131   gUpdateChecker.checkForUpdates(updateCheckListener, true);
134 function check_test_helper_pt1() {
135   do_check_eq(gUpdateCount, 1);
136   gCheckFunc = check_test_helper_pt2;
137   var bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
138   var state = gAUS.downloadUpdate(bestUpdate, false);
139   if (state == "null" || state == "failed")
140     do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
141   gAUS.addDownloadListener(downloadListener);
144 function check_test_helper_pt2() {
145   do_check_eq(gStatus, gExpectedStatus);
146   gAUS.removeDownloadListener(downloadListener);
147   gNextRunFunc();
150 // Launches the updater binary to apply a mar file
151 function runUpdate() {
152   // Copy the updater binary to the update directory so the updater.ini is not
153   // in the same directory as it is. This prevents ui from displaying and the
154   // PostUpdate executable which is defined in the updater.ini from launching.
155   gUpdater.copyTo(gUpdatesDir, gUpdater.leafName);
156   var updateBin = gUpdatesDir.clone();
157   updateBin.append(gUpdater.leafName);
158   if (updateBin.leafName == "updater.app") {
159     updateBin.append("Contents");
160     updateBin.append("MacOS");
161     updateBin.append("updater");
162     if (!updateBin.exists())
163       do_throw("Unable to find the updater executable!");
164   }
166   var process = AUS_Cc["@mozilla.org/process/util;1"]
167                   .createInstance(AUS_Ci.nsIProcess);
168   process.init(updateBin);
169   var args = [gUpdatesDirPath];
170   process.run(true, args, args.length);
171   return process.exitValue;
174 // Gets a file in the directory (the current working directory) where the mar
175 // will be applied.
176 function getTestFile(leafName) {
177   var file = gTestDir.clone();
178   file.append(leafName);
179   if (!(file instanceof AUS_Ci.nsILocalFile))
180     do_throw("File must be a nsILocalFile for this test! File: " + leafName);
182   return file;
185 // Returns the binary contents of a file
186 function getFileBytes(file) {
187   var fis = AUS_Cc["@mozilla.org/network/file-input-stream;1"]
188               .createInstance(AUS_Ci.nsIFileInputStream);
189   fis.init(file, -1, -1, false);
190   var bis = AUS_Cc["@mozilla.org/binaryinputstream;1"]
191               .createInstance(AUS_Ci.nsIBinaryInputStream);
192   bis.setInputStream(fis);
193   var data = bis.readBytes(bis.available());
194   bis.close();
195   fis.close();
196   return data;
199 // applying a complete mar and replacing an existing file
200 function run_test_pt1() {
201   run_test_helper("aus-0110_general-1.xml", "applying a complete mar",
202                   AUS_Cr.NS_OK, run_test_pt2);
205 // apply the complete mar and check the innards of the files
206 function run_test_pt2() {
207   var exitValue = runUpdate();
208   do_check_eq(exitValue, 0);
210   dump("Testing: contents of files added\n");
211   do_check_eq(getFileBytes(getTestFile("text1")), "ToBeModified\n");
212   do_check_eq(getFileBytes(getTestFile("text2")), "ToBeDeleted\n");
214   var refImage = do_get_file("toolkit/mozapps/update/test/unit/data/aus-0110_general_ref_image1.png");
215   var srcImage = getTestFile("image1.png");
216   do_check_eq(getFileBytes(srcImage), getFileBytes(refImage));
218   remove_dirs_and_files();
219   run_test_pt3();
222 // applying a partial mar and remove an existing file
223 function run_test_pt3() {
224   run_test_helper("aus-0110_general-2.xml", "applying a partial mar",
225                   AUS_Cr.NS_OK, run_test_pt4);
228 // apply the partial mar and check the innards of the files
229 function run_test_pt4() {
230   var exitValue = runUpdate();
231   do_check_eq(exitValue, 0);
233   dump("Testing: removal of a file and contents of added / modified files\n");
234   do_check_eq(getFileBytes(getTestFile("text1")), "Modified\n");
235   do_check_false(getTestFile("text2").exists()); // file removed
236   do_check_eq(getFileBytes(getTestFile("text3")), "Added\n");
238   var refImage = do_get_file("toolkit/mozapps/update/test/unit/data/aus-0110_general_ref_image2.png");
239   var srcImage = getTestFile("image1.png");
240   do_check_eq(getFileBytes(srcImage), getFileBytes(refImage));
242   end_test();
245 // Update check listener
246 const updateCheckListener = {
247   onProgress: function(request, position, totalSize) {
248   },
250   onCheckComplete: function(request, updates, updateCount) {
251     gUpdateCount = updateCount;
252     gUpdates = updates;
253     dump("onCheckComplete url = " + request.channel.originalURI.spec + "\n\n");
254     // Use a timeout to allow the XHR to complete
255     do_timeout(0, "gCheckFunc()");
256   },
258   onError: function(request, update) {
259     dump("onError url = " + request.channel.originalURI.spec + "\n\n");
260     // Use a timeout to allow the XHR to complete
261     do_timeout(0, "gCheckFunc()");
262   },
264   QueryInterface: function(aIID) {
265     if (!aIID.equals(AUS_Ci.nsIUpdateCheckListener) &&
266         !aIID.equals(AUS_Ci.nsISupports))
267       throw AUS_Cr.NS_ERROR_NO_INTERFACE;
268     return this;
269   }
272 /* Update download listener - nsIRequestObserver */
273 const downloadListener = {
274   onStartRequest: function(request, context) {
275   },
277   onProgress: function(request, context, progress, maxProgress) {
278   },
280   onStatus: function(request, context, status, statusText) {
281   },
283   onStopRequest: function(request, context, status) {
284     gStatus = status;
285     // Use a timeout to allow the request to complete
286     do_timeout(0, "gCheckFunc()");
287   },
289   QueryInterface: function(iid) {
290     if (!iid.equals(AUS_Ci.nsIRequestObserver) &&
291         !iid.equals(AUS_Ci.nsIProgressEventSink) &&
292         !iid.equals(AUS_Ci.nsISupports))
293       throw AUS_Cr.NS_ERROR_NO_INTERFACE;
294     return this;
295   }