Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 Components.utils.import("resource://gre/modules/NetUtil.jsm");
10 /*
11 * getChromeURI converts a URL to a URI
12 *
13 * url: string of a URL (http://mochi.test/test.html)
14 * returns: a nsiURI object representing the given URL
15 *
16 */
17 function getChromeURI(url) {
18 var ios = Components.classes["@mozilla.org/network/io-service;1"].
19 getService(Components.interfaces.nsIIOService);
20 return ios.newURI(url, null, null);
21 }
23 /*
24 * Convert a URL (string) into a nsIURI or NSIJARURI
25 * This is intended for URL's that are on a file system
26 * or in packaged up in an extension .jar file
27 *
28 * url: a string of a url on the local system(http://localhost/blah.html)
29 */
30 function getResolvedURI(url) {
31 var chromeURI = getChromeURI(url);
32 var resolvedURI = Components.classes["@mozilla.org/chrome/chrome-registry;1"].
33 getService(Components.interfaces.nsIChromeRegistry).
34 convertChromeURL(chromeURI);
36 try {
37 resolvedURI = resolvedURI.QueryInterface(Components.interfaces.nsIJARURI);
38 } catch (ex) {} //not a jar file
40 return resolvedURI;
41 }
43 /**
44 * getChromeDir is intended to be called after getResolvedURI and convert
45 * the input URI into a nsILocalFile (actually the directory containing the
46 * file). This can be used for copying or referencing the file or extra files
47 * required by the test. Usually we need to load a secondary html file or library
48 * and this will give us file system access to that.
49 *
50 * resolvedURI: nsIURI (from getResolvedURI) that points to a file:/// url
51 */
52 function getChromeDir(resolvedURI) {
54 var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
55 getService(Components.interfaces.nsIFileProtocolHandler);
56 var chromeDir = fileHandler.getFileFromURLSpec(resolvedURI.spec);
57 return chromeDir.parent.QueryInterface(Components.interfaces.nsILocalFile);
58 }
60 /*
61 * given a .jar file, we get all test files located inside the archive
62 *
63 * aBasePath: base URL to determine chrome location and search for tests
64 * aTestPath: passed in testPath value from command line such as: dom/tests/mochitest
65 * aDir: the test dir to append to the baseURL after getting a directory interface
66 *
67 * As a note, this is hardcoded to the .jar structure we use for mochitest.
68 * Please don't assume this works for all jar files.
69 */
70 function getMochitestJarListing(aBasePath, aTestPath, aDir)
71 {
72 var zReader = Components.classes["@mozilla.org/libjar/zip-reader;1"].
73 createInstance(Components.interfaces.nsIZipReader);
74 var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
75 getService(Components.interfaces.nsIFileProtocolHandler);
77 var fileName = fileHandler.getFileFromURLSpec(getResolvedURI(aBasePath).JARFile.spec);
78 zReader.open(fileName);
79 //hardcoded 'content' as that is the root dir in the mochikit.jar file
80 var idx = aBasePath.indexOf('/content');
81 var basePath = aBasePath.slice(0, idx);
83 var base = "content/" + aDir + "/";
85 if (aTestPath) {
86 var extraPath = aTestPath;
87 var pathToCheck = base + aTestPath;
88 if (zReader.hasEntry(pathToCheck)) {
89 var pathEntry = zReader.getEntry(pathToCheck);
90 if (pathEntry.isDirectory) {
91 base = pathToCheck;
92 } else {
93 var singleTestPath = basePath + '/' + base + aTestPath;
94 var singleObject = {};
95 singleObject[singleTestPath] = true;
96 return singleObject;
97 }
98 }
99 else if (zReader.hasEntry(pathToCheck + "/")) {
100 base = pathToCheck + "/";
101 }
102 else {
103 return null;
104 }
105 }
106 var [links, count] = zList(base, zReader, basePath, true);
107 return links;
108 }
110 /*
111 * Replicate the server.js list() function with a .jar file
112 *
113 * base: string value of base directory we are testing
114 * zReader: handle to opened nsIZipReader object
115 * recurse: true|false if we do subdirs
116 *
117 * returns:
118 * [json object of {dir:{subdir:{file:true, file:true, ...}}}, count of tests]
119 */
120 function zList(base, zReader, baseJarName, recurse) {
121 var dirs = zReader.findEntries(base + "*");
122 var links = {};
123 var count = 0;
124 var fileArray = [];
126 while(dirs.hasMore()) {
127 var entryName = dirs.getNext();
128 if (entryName.substr(-1) == '/' && entryName.split('/').length == (base.split('/').length + 1) ||
129 (entryName.substr(-1) != '/' && entryName.split('/').length == (base.split('/').length))) {
130 fileArray.push(entryName);
131 }
132 }
133 fileArray.sort();
134 count = fileArray.length;
135 for (var i=0; i < fileArray.length; i++) {
136 var myFile = fileArray[i];
137 if (myFile.substr(-1) === '/' && recurse) {
138 var childCount = 0;
139 [links[myFile], childCount] = zList(myFile, zReader, baseJarName, recurse);
140 count += childCount;
141 } else {
142 if (myFile.indexOf("SimpleTest") == -1) {
143 //we add the '/' so we don't try to run content/content/chrome
144 links[baseJarName + '/' + myFile] = true;
145 }
146 }
147 }
148 return [links, count];
149 }
151 /**
152 * basePath: the URL base path to search from such as chrome://mochikit/content/a11y
153 * testPath: the optional testPath passed into the test such as dom/tests/mochitest
154 * dir: the test dir to append to the uri after getting a directory interface
155 * srvScope: loaded javascript to server.js so we have aComponents.classesess to the list() function
156 *
157 * return value:
158 * single test: [json object, path to test]
159 * list of tests: [json object, null] <- directory [heirarchy]
160 */
161 function getFileListing(basePath, testPath, dir, srvScope)
162 {
163 var uri = getResolvedURI(basePath);
164 var chromeDir = getChromeDir(uri);
165 chromeDir.appendRelativePath(dir);
166 basePath += '/' + dir;
168 if (testPath == "false" || testPath == false) {
169 testPath = "";
170 }
172 var ioSvc = Components.classes["@mozilla.org/network/io-service;1"].
173 getService(Components.interfaces.nsIIOService);
174 var testsDirURI = ioSvc.newFileURI(chromeDir);
175 var testsDir = ioSvc.newURI(testPath, null, testsDirURI)
176 .QueryInterface(Components.interfaces.nsIFileURL).file;
178 if (testPath != undefined) {
179 var extraPath = testPath;
181 var fileNameRegexp = /(browser|test)_.+\.(xul|html|js)$/;
183 // Invalid testPath...
184 if (!testsDir.exists())
185 return null;
187 if (testsDir.isFile()) {
188 if (fileNameRegexp.test(testsDir.leafName)) {
189 var singlePath = basePath + '/' + testPath;
190 var links = {};
191 links[singlePath] = true;
192 return links;
193 }
194 // We were passed a file that's not a test...
195 return null;
196 }
198 // otherwise, we were passed a directory of tests
199 basePath += "/" + testPath;
200 }
201 var [links, count] = srvScope.list(basePath, testsDir, true);
202 return links;
203 }
206 //used by tests to determine their directory based off window.location.path
207 function getRootDirectory(path, chromeURI) {
208 if (chromeURI === undefined)
209 {
210 chromeURI = getChromeURI(path);
211 }
212 var myURL = chromeURI.QueryInterface(Components.interfaces.nsIURL);
213 var mydir = myURL.directory;
215 if (mydir.match('/$') != '/')
216 {
217 mydir += '/';
218 }
220 return chromeURI.prePath + mydir;
221 }
223 //used by tests to determine their directory based off window.location.path
224 function getChromePrePath(path, chromeURI) {
226 if (chromeURI === undefined) {
227 chromeURI = getChromeURI(path);
228 }
230 return chromeURI.prePath;
231 }
233 /*
234 * Given a URI, return nsIJARURI or null
235 */
236 function getJar(uri) {
237 var resolvedURI = getResolvedURI(uri);
238 var jar = null;
239 try {
240 if (resolvedURI.JARFile) {
241 jar = resolvedURI;
242 }
243 } catch (ex) {}
244 return jar;
245 }
247 /*
248 * input:
249 * jar: a nsIJARURI object with the jarfile and jarentry (path in jar file)
250 *
251 * output;
252 * all files and subdirectories inside jarentry will be extracted to TmpD/mochikit.tmp
253 * we will return the location of /TmpD/mochikit.tmp* so you can reference the files locally
254 */
255 function extractJarToTmp(jar) {
256 var tmpdir = Components.classes["@mozilla.org/file/directory_service;1"]
257 .getService(Components.interfaces.nsIProperties)
258 .get("ProfD", Components.interfaces.nsILocalFile);
259 tmpdir.append("mochikit.tmp");
260 // parseInt is used because octal escape sequences cause deprecation warnings
261 // in strict mode (which is turned on in debug builds)
262 tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8));
264 var zReader = Components.classes["@mozilla.org/libjar/zip-reader;1"].
265 createInstance(Components.interfaces.nsIZipReader);
267 var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
268 getService(Components.interfaces.nsIFileProtocolHandler);
270 var fileName = fileHandler.getFileFromURLSpec(jar.JARFile.spec);
271 zReader.open(fileName);
273 //filepath represents the path in the jar file without the filename
274 var filepath = "";
275 var parts = jar.JAREntry.split('/');
276 for (var i =0; i < parts.length - 1; i++) {
277 if (parts[i] != '') {
278 filepath += parts[i] + '/';
279 }
280 }
282 /* Create dir structure first, no guarantee about ordering of directories and
283 * files returned from findEntries.
284 */
285 var dirs = zReader.findEntries(filepath + '*/');
286 while (dirs.hasMore()) {
287 var targetDir = buildRelativePath(dirs.getNext(), tmpdir, filepath);
288 // parseInt is used because octal escape sequences cause deprecation warnings
289 // in strict mode (which is turned on in debug builds)
290 if (!targetDir.exists()) {
291 targetDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8));
292 }
293 }
295 //now do the files
296 var files = zReader.findEntries(filepath + "*");
297 while (files.hasMore()) {
298 var fname = files.getNext();
299 if (fname.substr(-1) != '/') {
300 var targetFile = buildRelativePath(fname, tmpdir, filepath);
301 zReader.extract(fname, targetFile);
302 }
303 }
304 return tmpdir;
305 }
307 /*
308 * Take a relative path from the current mochitest file
309 * and returns the absolute path for the given test data file.
310 */
311 function getTestFilePath(path) {
312 if (path[0] == "/") {
313 throw new Error("getTestFilePath only accepts relative path");
314 }
315 // Get the chrome/jar uri for the current mochitest file
316 // gTestPath being defined by the test harness in browser-chrome tests
317 // or window is being used for mochitest-browser
318 var baseURI = typeof(gTestPath) == "string" ? gTestPath : window.location.href;
319 var parentURI = getResolvedURI(getRootDirectory(baseURI));
320 var file;
321 if (parentURI.JARFile) {
322 // If it's a jar/zip, we have to extract it first
323 file = extractJarToTmp(parentURI);
324 } else {
325 // Otherwise, we can directly cast it to a file URI
326 var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
327 getService(Components.interfaces.nsIFileProtocolHandler);
328 file = fileHandler.getFileFromURLSpec(parentURI.spec);
329 }
330 // Then walk by the given relative path
331 path.split("/")
332 .forEach(function (p) {
333 if (p == "..") {
334 file = file.parent;
335 } else if (p != ".") {
336 file.append(p);
337 }
338 });
339 return file.path;
340 }
342 /*
343 * Simple utility function to take the directory structure in jarentryname and
344 * translate that to a path of a nsILocalFile.
345 */
346 function buildRelativePath(jarentryname, destdir, basepath)
347 {
348 var baseParts = basepath.split('/');
349 if (baseParts[baseParts.length-1] == '') {
350 baseParts.pop();
351 }
353 var parts = jarentryname.split('/');
355 var targetFile = Components.classes["@mozilla.org/file/local;1"]
356 .createInstance(Components.interfaces.nsILocalFile);
357 targetFile.initWithFile(destdir);
359 for (var i = baseParts.length; i < parts.length; i++) {
360 targetFile.append(parts[i]);
361 }
363 return targetFile;
364 }
366 function readConfig(filename) {
367 filename = filename || "testConfig.js";
369 var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].
370 getService(Components.interfaces.nsIProperties);
371 var configFile = fileLocator.get("ProfD", Components.interfaces.nsIFile);
372 configFile.append(filename);
374 if (!configFile.exists())
375 return {};
377 var fileInStream = Components.classes["@mozilla.org/network/file-input-stream;1"].
378 createInstance(Components.interfaces.nsIFileInputStream);
379 fileInStream.init(configFile, -1, 0, 0);
381 var str = NetUtil.readInputStreamToString(fileInStream, fileInStream.available());
382 fileInStream.close();
383 return JSON.parse(str);
384 }
386 function registerTests() {
387 var testsURI = Components.classes["@mozilla.org/file/directory_service;1"].
388 getService(Components.interfaces.nsIProperties).
389 get("ProfD", Components.interfaces.nsILocalFile);
390 testsURI.append("tests.manifest");
391 var ioSvc = Components.classes["@mozilla.org/network/io-service;1"].
392 getService(Components.interfaces.nsIIOService);
393 var manifestFile = ioSvc.newFileURI(testsURI).
394 QueryInterface(Components.interfaces.nsIFileURL).file;
396 Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar).
397 autoRegister(manifestFile);
398 }
400 function getTestList(params, callback) {
401 registerTests();
403 var baseurl = 'chrome://mochitests/content';
404 if (window.parseQueryString) {
405 params = parseQueryString(location.search.substring(1), true);
406 }
407 if (!params.baseurl) {
408 params.baseurl = baseurl;
409 }
411 var config = readConfig();
412 for (var p in params) {
413 if (params[p] == 1) {
414 config[p] = true;
415 } else if (params[p] == 0) {
416 config[p] = false;
417 } else {
418 config[p] = params[p];
419 }
420 }
421 params = config;
422 if (params.manifestFile) {
423 getTestManifest("http://mochi.test:8888/" + params.manifestFile, params, callback);
424 return;
425 }
427 var links = {};
428 // load server.js in so we can share template functions
429 var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
430 getService(Ci.mozIJSSubScriptLoader);
431 var srvScope = {};
432 scriptLoader.loadSubScript('chrome://mochikit/content/server.js',
433 srvScope);
435 if (getResolvedURI(baseurl).JARFile) {
436 links = getMochitestJarListing(baseurl, params.testPath, params.testRoot);
437 } else {
438 links = getFileListing(baseurl, params.testPath, params.testRoot, srvScope);
439 }
440 callback(links);
441 }