Bug 762908 - Rip enablePrivilege out of spidermonkey tests. r=ted
authorJoel Maher <jmaher@mozilla.com>
Thu, 20 Sep 2012 09:06:50 -0400
changeset 107617 e21f9042824fe071845302042b37b8b1200f6653
parent 107616 3cd3840dea0bea00978c13fc338642d0d401c385
child 107618 30ab4e1d48745b68392b493fc98ed97a6df476a1
push id15133
push userjmaher@mozilla.com
push dateThu, 20 Sep 2012 13:07:30 +0000
treeherdermozilla-inbound@e21f9042824f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs762908
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 762908 - Rip enablePrivilege out of spidermonkey tests. r=ted
build/macosx/universal/flight.mk
js/src/tests/browser.js
js/src/tests/e4x/QName/regress-619529.js
js/src/tests/ecma_5/Global/adding-global-var-nonextensible-error.js
js/src/tests/js1_5/extensions/regress-369696-02.js
js/src/tests/js1_8_5/extensions/set-property-non-extensible.js
js/src/tests/js1_8_5/regress/regress-633741.js
testing/marionette/jar.mn
testing/mochitest/Makefile.in
testing/mochitest/MockFilePicker.jsm
testing/mochitest/jar.mn
testing/mochitest/specialpowers/Makefile.in
testing/mochitest/specialpowers/chrome.manifest
testing/mochitest/specialpowers/components/SpecialPowersObserver.js
testing/mochitest/specialpowers/content/specialpowers.js
testing/mochitest/specialpowers/install.rdf
testing/mochitest/specialpowers/jar.mn
testing/mochitest/tests/SimpleTest/Makefile.in
testing/mochitest/tests/SimpleTest/MozillaLogger.js
testing/mochitest/tests/SimpleTest/SpecialPowersObserverAPI.js
testing/mochitest/tests/SimpleTest/specialpowersAPI.js
testing/specialpowers/Makefile.in
testing/specialpowers/chrome.manifest
testing/specialpowers/components/SpecialPowersObserver.js
testing/specialpowers/content/MockFilePicker.jsm
testing/specialpowers/content/MozillaLogger.js
testing/specialpowers/content/SpecialPowersObserverAPI.js
testing/specialpowers/content/specialpowers.js
testing/specialpowers/content/specialpowersAPI.js
testing/specialpowers/install.rdf
testing/specialpowers/jar.mn
toolkit/mozapps/downloads/tests/Makefile.in
toolkit/toolkit-makefiles.sh
toolkit/toolkit-tiers.mk
--- a/build/macosx/universal/flight.mk
+++ b/build/macosx/universal/flight.mk
@@ -88,17 +88,21 @@ ifdef ENABLE_TESTS
 	$(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= CHROME_JAR= package-tests
 	rm -rf $(DIST_UNI)/test-package-stage
 # automation.py differs because it hardcodes a path to
 # dist/bin. It doesn't matter which one we use.
 	if test -d $(DIST_ARCH_1)/test-package-stage -a                 \
                 -d $(DIST_ARCH_2)/test-package-stage; then              \
            cp $(DIST_ARCH_1)/test-package-stage/mochitest/automation.py \
              $(DIST_ARCH_2)/test-package-stage/mochitest/;              \
+           cp -RL $(DIST_ARCH_1)/test-package-stage/mochitest/extensions/specialpowers \
+             $(DIST_ARCH_2)/test-package-stage/mochitest/extensions/;              \
            cp $(DIST_ARCH_1)/test-package-stage/reftest/automation.py   \
              $(DIST_ARCH_2)/test-package-stage/reftest/;                \
+           cp -RL $(DIST_ARCH_1)/test-package-stage/reftest/specialpowers \
+             $(DIST_ARCH_2)/test-package-stage/reftest/;              \
            $(TOPSRCDIR)/build/macosx/universal/unify                 \
              --unify-with-sort "\.manifest$$" \
              --unify-with-sort "all-test-dirs\.list$$"               \
              $(DIST_ARCH_1)/test-package-stage                          \
              $(DIST_ARCH_2)/test-package-stage                          \
              $(DIST_UNI)/test-package-stage; fi
 endif
--- a/js/src/tests/browser.js
+++ b/js/src/tests/browser.js
@@ -158,31 +158,32 @@ function options(aOptionName)
     value = value.substring(0, value.length-1);
   }
 
   if (aOptionName === 'moar_xml')
     aOptionName = 'xml';
 
   if (aOptionName && aOptionName !== 'allow_xml') {
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-    if (!(aOptionName in Components.utils))
-    {
+    if (!(aOptionName in Components.utils)) {
+//    if (!(aOptionName in SpecialPowers.wrap(Components).utils)) {
       // This test is trying to flip an unsupported option, so it's
       // likely no longer testing what it was supposed to.  Fail it
       // hard.
       throw "Unsupported JSContext option '"+ aOptionName +"'";
     }
 
     if (options.currvalues.hasOwnProperty(aOptionName))
       // option is set, toggle it to unset
       delete options.currvalues[aOptionName];
     else
       // option is not set, toggle it to set
       options.currvalues[aOptionName] = true;
 
+//    SpecialPowers.wrap(Components).utils[aOptionName] = options.currvalues.hasOwnProperty(aOptionName);
     Components.utils[aOptionName] =
       options.currvalues.hasOwnProperty(aOptionName);
   }  
 
   return value;
 }
 
 function optionsInit() {
@@ -209,20 +210,22 @@ function optionsInit() {
 
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   for (var optionName in options.currvalues)
   {
     var propName = optionName;
     if (optionName === "moar_xml")
       propName = "xml";
 
+//    if (!(propName in SpecialPowers.wrap(Components).utils))
     if (!(propName in Components.utils))
     {
       throw "options.currvalues is out of sync with Components.utils";
     }
+//    if (!SpecialPowers.wrap(Components).utils[propName])
     if (!Components.utils[propName])
     {
       delete options.currvalues[optionName];
     }
     else
     {
       options.initvalues[optionName] = true;
     }
@@ -454,123 +457,70 @@ var dlog = (function (s) {});
 
 // dialog closer from http://bclary.com/projects/spider/spider/chrome/content/spider/dialog-closer.js
 
 var gDialogCloser;
 var gDialogCloserObserver;
 
 function registerDialogCloser()
 {
-  dlog('registerDialogCloser: start');
-  try
-  {
-    netscape.security.PrivilegeManager.
-      enablePrivilege('UniversalXPConnect');
-  }
-  catch(excp)
-  {
-    print('registerDialogCloser: ' + excp);
-    return;
-  }
-
+  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+//  gDialogCloser = SpecialPowers.wrap(Components).
   gDialogCloser = Components.
     classes['@mozilla.org/embedcomp/window-watcher;1'].
     getService(Components.interfaces.nsIWindowWatcher);
 
   gDialogCloserObserver = {observe: dialogCloser_observe};
 
   gDialogCloser.registerNotification(gDialogCloserObserver);
-
-  dlog('registerDialogCloser: complete');
 }
 
 function unregisterDialogCloser()
 {
-  dlog('unregisterDialogCloser: start');
-
   gczeal(0);
 
   if (!gDialogCloserObserver || !gDialogCloser)
   {
     return;
   }
-  try
-  {
-    netscape.security.PrivilegeManager.
-      enablePrivilege('UniversalXPConnect');
-  }
-  catch(excp)
-  {
-    print('unregisterDialogCloser: ' + excp);
-    return;
-  }
 
   gDialogCloser.unregisterNotification(gDialogCloserObserver);
 
   gDialogCloserObserver = null;
   gDialogCloser = null;
-
-  dlog('unregisterDialogCloser: stop');
 }
 
 // use an array to handle the case where multiple dialogs
 // appear at one time
 var gDialogCloserSubjects = [];
 
 function dialogCloser_observe(subject, topic, data)
 {
-  try
-  {
-    netscape.security.PrivilegeManager.
-      enablePrivilege('UniversalXPConnect');
-
-    dlog('dialogCloser_observe: ' +
-         'subject: ' + subject + 
-         ', topic=' + topic + 
-         ', data=' + data + 
-         ', subject.document.documentURI=' + subject.document.documentURI +
-         ', subjects pending=' + gDialogCloserSubjects.length);
-  }
-  catch(excp)
-  {
-    print('dialogCloser_observe: ' + excp);
-    return;
-  }
-
   if (subject instanceof ChromeWindow && topic == 'domwindowopened' )
   {
     gDialogCloserSubjects.push(subject);
     // timeout of 0 needed when running under reftest framework.
     subject.setTimeout(closeDialog, 0);
   }
-  dlog('dialogCloser_observe: subjects pending: ' + gDialogCloserSubjects.length);
 }
 
 function closeDialog()
 {
   var subject;
-  dlog('closeDialog: subjects pending: ' + gDialogCloserSubjects.length);
 
   while ( (subject = gDialogCloserSubjects.pop()) != null)
   {
-    dlog('closeDialog: subject=' + subject);
-
-    dlog('closeDialog: subject.document instanceof XULDocument: ' + (subject.document instanceof XULDocument));
-    dlog('closeDialog: subject.document.documentURI: ' + subject.document.documentURI);
-
     if (subject.document instanceof XULDocument && 
         subject.document.documentURI == 'chrome://global/content/commonDialog.xul')
     {
-      dlog('closeDialog: close XULDocument dialog?');
       subject.close();
     }
     else
     {
       // alerts inside of reftest framework are not XULDocument dialogs.
-      dlog('closeDialog: close chrome dialog?');
       subject.close();
     }
   }
 }
 
 registerDialogCloser();
 window.addEventListener('unload', unregisterDialogCloser, true);
 
--- a/js/src/tests/e4x/QName/regress-619529.js
+++ b/js/src/tests/e4x/QName/regress-619529.js
@@ -1,9 +1,10 @@
 // |reftest| pref(javascript.options.xml.content,true)
+// |reftest| skip
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/
  */
 
 var b = Proxy.create({ enumerateOwn: function () { @f; }});
 Object.freeze(this);
--- a/js/src/tests/ecma_5/Global/adding-global-var-nonextensible-error.js
+++ b/js/src/tests/ecma_5/Global/adding-global-var-nonextensible-error.js
@@ -1,9 +1,9 @@
-// |reftest| fails-if(!xulRuntime.shell)
+// |reftest| skip
 // Any copyright is dedicated to the Public Domain.
 // http://creativecommons.org/licenses/publicdomain/
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 621432;
 var summary =
   "If a var statement can't create a global property because the global " +
   "object isn't extensible, and an error is thrown while decompiling the " +
--- a/js/src/tests/js1_5/extensions/regress-369696-02.js
+++ b/js/src/tests/js1_5/extensions/regress-369696-02.js
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 369696;
 var summary = 'Do not assert: map->depth > 0" in js_LeaveSharpObject';
 var actual = '';
 var expect = '';
 
+// Bug 762908 requires us to set sp=null;
+window.SpecialPowers = null;
 
 //-----------------------------------------------------------------------------
 test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
--- a/js/src/tests/js1_8_5/extensions/set-property-non-extensible.js
+++ b/js/src/tests/js1_8_5/extensions/set-property-non-extensible.js
@@ -1,8 +1,9 @@
+// |reftest| skip
 // Any copyright is dedicated to the Public Domain.
 // http://creativecommons.org/licenses/publicdomain/
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 600128;
 var summary =
   "Properly handle attempted addition of properties to non-extensible objects";
 
--- a/js/src/tests/js1_8_5/regress/regress-633741.js
+++ b/js/src/tests/js1_8_5/regress/regress-633741.js
@@ -1,8 +1,9 @@
+// |reftest| skip
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/
  * Contributors: Jan de Mooij
  */
 
 Object.preventExtensions(this);
 delete Function;
--- a/testing/marionette/jar.mn
+++ b/testing/marionette/jar.mn
@@ -15,17 +15,17 @@ marionette.jar:
   content/ChromeUtils.js  (ChromeUtils.js)
 #ifdef ENABLE_TESTS
   content/test.xul  (client/marionette/chrome/test.xul)
   content/test2.xul  (client/marionette/chrome/test2.xul)
   content/test_nested_iframe.xul  (client/marionette/chrome/test_nested_iframe.xul)
 #endif
 
 % content specialpowers %content/
-  content/specialpowers.js (../mochitest/specialpowers/content/specialpowers.js)
-  content/SpecialPowersObserver.js (../mochitest/specialpowers/components/SpecialPowersObserver.js)
-  content/specialpowersAPI.js (../mochitest/tests/SimpleTest/specialpowersAPI.js)
-  content/SpecialPowersObserverAPI.js (../mochitest/tests/SimpleTest/SpecialPowersObserverAPI.js)
+  content/specialpowers.js (../specialpowers/content/specialpowers.js)
+  content/SpecialPowersObserver.js (../specialpowers/components/SpecialPowersObserver.js)
+  content/specialpowersAPI.js (../specialpowers/content/specialpowersAPI.js)
+  content/SpecialPowersObserverAPI.js (../specialpowers/content/SpecialPowersObserverAPI.js)
   content/ChromePowers.js (../mochitest/tests/SimpleTest/ChromePowers.js)
-  content/MozillaLogger.js (../mochitest/tests/SimpleTest/MozillaLogger.js)
+  content/MozillaLogger.js (../specialpowers/content/MozillaLogger.js)
 
-% resource mochikit %modules/
-  modules/MockFilePicker.jsm (../mochitest/MockFilePicker.jsm)
+% resource specialpowers %modules/
+  modules/MockFilePicker.jsm (../specialpowers/content/MockFilePicker.jsm)
--- a/testing/mochitest/Makefile.in
+++ b/testing/mochitest/Makefile.in
@@ -13,17 +13,16 @@ include $(DEPTH)/config/autoconf.mk
 
 DIRS = \
   MochiKit \
   static \
   dynamic \
   tests \
   chrome \
   ssltunnel \
-  specialpowers \
   $(NULL)
 
 ifeq ($(MOZ_BUILD_APP),mobile/android)
 DIRS += roboextender
 endif
 
 NO_JS_MANIFEST = 1
 MOZ_CHROME_FILE_FORMAT = jar
--- a/testing/mochitest/jar.mn
+++ b/testing/mochitest/jar.mn
@@ -7,25 +7,23 @@ mochikit.jar:
   content/chrome-harness.js (chrome-harness.js)
   content/harness-overlay.xul (harness-overlay.xul)
   content/harness.xul (harness.xul)
   content/redirect.html (redirect.html)
   content/server.js (server.js)
   content/dynamic/getMyDirectory.sjs (dynamic/getMyDirectory.sjs)
   content/static/harness.css (static/harness.css)
   content/tests/SimpleTest/ChromePowers.js (tests/SimpleTest/ChromePowers.js)
-  content/tests/SimpleTest/specialpowersAPI.js (tests/SimpleTest/specialpowersAPI.js)
-  content/tests/SimpleTest/SpecialPowersObserverAPI.js (tests/SimpleTest/SpecialPowersObserverAPI.js)
   content/tests/SimpleTest/EventUtils.js (tests/SimpleTest/EventUtils.js)
   content/tests/SimpleTest/ChromeUtils.js (tests/SimpleTest/ChromeUtils.js)
-  content/tests/SimpleTest/MozillaLogger.js (tests/SimpleTest/MozillaLogger.js)
   content/tests/SimpleTest/LogController.js (tests/SimpleTest/LogController.js)
+  content/tests/SimpleTest/MozillaLogger.js (../specialpowers/content/MozillaLogger.js)
+  content/tests/SimpleTest/SpecialPowersObserverAPI.js (../specialpowers/content/SpecialPowersObserverAPI.js)
+  content/tests/SimpleTest/specialpowersAPI.js (../specialpowers/content/specialpowersAPI.js)
   content/tests/SimpleTest/setup.js (tests/SimpleTest/setup.js)
   content/tests/SimpleTest/SimpleTest.js (tests/SimpleTest/SimpleTest.js)
   content/tests/SimpleTest/test.css (tests/SimpleTest/test.css)
   content/tests/SimpleTest/TestRunner.js (tests/SimpleTest/TestRunner.js)
   content/tests/SimpleTest/WindowSnapshot.js (tests/SimpleTest/WindowSnapshot.js)
   content/tests/SimpleTest/MockObjects.js (tests/SimpleTest/MockObjects.js)
   content/tests/SimpleTest/NativeKeyCodes.js (tests/SimpleTest/NativeKeyCodes.js)
   content/tests/SimpleTest/docshell_helpers.js (../../docshell/test/chrome/docshell_helpers.js)
 
-% resource mochikit %modules/
-  modules/MockFilePicker.jsm (MockFilePicker.jsm)
--- a/testing/mochitest/tests/SimpleTest/Makefile.in
+++ b/testing/mochitest/tests/SimpleTest/Makefile.in
@@ -5,27 +5,25 @@
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = @relativesrcdir@
 include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/rules.mk
-_SIMPLETEST_FILES =	MozillaLogger.js \
-			LogController.js \
+_SIMPLETEST_FILES =	LogController.js \
 			SimpleTest.js \
 			test.css \
 			TestRunner.js \
 			setup.js \
 			EventUtils.js \
 			ChromeUtils.js \
 			WindowSnapshot.js \
-			specialpowersAPI.js \
-			SpecialPowersObserverAPI.js \
 			MockObjects.js \
 			NativeKeyCodes.js \
+			$(DEPTH)/testing/specialpowers/content/MozillaLogger.js \
 			$(DEPTH)/docshell/test/chrome/docshell_helpers.js \
 			$(NULL)
 
 libs:: $(_SIMPLETEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/$(relativesrcdir)
 
rename from testing/mochitest/specialpowers/Makefile.in
rename to testing/specialpowers/Makefile.in
--- a/testing/mochitest/specialpowers/Makefile.in
+++ b/testing/specialpowers/Makefile.in
@@ -20,22 +20,27 @@ DIST_FILES = \
 
 EXTRA_COMPONENTS = components/SpecialPowersObserver.js
 
 XPI_NAME=specialpowers
 
 # Used in install.rdf
 USE_EXTENSION_MANIFEST=1
 
-TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions
+TEST_EXTENSIONS_DIR = $(DEPTH)/testing/specialpowers
 
 include $(topsrcdir)/config/rules.mk
 
 # JarMaker creates a chrome.manifest already, so the one from the source
 # directory is not copied if it's not forced to be.
 $(FINAL_TARGET)/chrome.manifest: FORCE
 
 libs-preqs = \
   $(call mkdir_deps,$(TEST_EXTENSIONS_DIR)) \
   $(NULL)
 
 libs:: $(libs-preqs)
 	(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - $(XPI_NAME)) | (cd $(TEST_EXTENSIONS_DIR) && tar -xf -)
+	$(NSINSTALL) -D $(DEPTH)/_tests/testing/mochitest/extensions/specialpowers
+	cp -RL $(DEPTH)/testing/specialpowers/specialpowers $(DEPTH)/_tests/testing/mochitest/extensions
+	$(NSINSTALL) -D $(DEPTH)/_tests/reftest/specialpowers
+	cp -RL $(DEPTH)/testing/specialpowers/specialpowers $(DEPTH)/_tests/reftest
+
rename from testing/mochitest/specialpowers/chrome.manifest
rename to testing/specialpowers/chrome.manifest
--- a/testing/mochitest/specialpowers/chrome.manifest
+++ b/testing/specialpowers/chrome.manifest
@@ -1,4 +1,5 @@
 content specialpowers chrome/specialpowers/content/
+resource specialpowers chrome/specialpowers/modules/
 component {59a52458-13e0-4d93-9d85-a637344f29a1} components/SpecialPowersObserver.js
 contract @mozilla.org/special-powers-observer;1 {59a52458-13e0-4d93-9d85-a637344f29a1}
 category profile-after-change @mozilla.org/special-powers-observer;1 @mozilla.org/special-powers-observer;1
rename from testing/mochitest/specialpowers/components/SpecialPowersObserver.js
rename to testing/specialpowers/components/SpecialPowersObserver.js
rename from testing/mochitest/MockFilePicker.jsm
rename to testing/specialpowers/content/MockFilePicker.jsm
rename from testing/mochitest/tests/SimpleTest/MozillaLogger.js
rename to testing/specialpowers/content/MozillaLogger.js
rename from testing/mochitest/tests/SimpleTest/SpecialPowersObserverAPI.js
rename to testing/specialpowers/content/SpecialPowersObserverAPI.js
rename from testing/mochitest/specialpowers/content/specialpowers.js
rename to testing/specialpowers/content/specialpowers.js
rename from testing/mochitest/tests/SimpleTest/specialpowersAPI.js
rename to testing/specialpowers/content/specialpowersAPI.js
--- a/testing/mochitest/tests/SimpleTest/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -4,17 +4,17 @@
 /* This code is loaded in every child process that is started by mochitest in
  * order to be used as a replacement for UniversalXPConnect
  */
 
 var Ci = Components.interfaces;
 var Cc = Components.classes;
 var Cu = Components.utils;
 
-Components.utils.import("resource://mochikit/MockFilePicker.jsm");
+Components.utils.import("resource://specialpowers/MockFilePicker.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function SpecialPowersAPI() { 
   this._consoleListeners = [];
   this._encounteredCrashDumpFiles = [];
   this._unexpectedCrashDumpFiles = { };
   this._crashDumpDir = null;
   this._mfl = null;
@@ -878,16 +878,20 @@ SpecialPowersAPI.prototype = {
       }
 
       Components.utils.schedulePreciseGC(scheduledGCCallback);
     }
 
     doPreciseGCandCC();
   },
 
+  setGCZeal: function(zeal) {
+    Components.utils.setGCZeal(zeal);
+  },
+
   isMainProcess: function() {
     try {
       return Cc["@mozilla.org/xre/app-info;1"].
                getService(Ci.nsIXULRuntime).
                processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
     } catch (e) { }
     return true;
   },
@@ -1194,10 +1198,10 @@ SpecialPowersAPI.prototype = {
       'isInBrowserElement': isInBrowserElement
     };
 
     this._sendSyncMessage('SPPermissionManager', msg);
   },
 
   getMozFullPath: function(file) {
     return file.mozFullPath;
-  }
+  },
 };
rename from testing/mochitest/specialpowers/install.rdf
rename to testing/specialpowers/install.rdf
rename from testing/mochitest/specialpowers/jar.mn
rename to testing/specialpowers/jar.mn
--- a/testing/mochitest/specialpowers/jar.mn
+++ b/testing/specialpowers/jar.mn
@@ -1,6 +1,9 @@
 specialpowers.jar:
 % content specialpowers %content/
   content/specialpowers.js (content/specialpowers.js)
-  content/specialpowersAPI.js (../tests/SimpleTest/specialpowersAPI.js)
-  content/SpecialPowersObserverAPI.js (../tests/SimpleTest/SpecialPowersObserverAPI.js)
-  content/MozillaLogger.js (../tests/SimpleTest/MozillaLogger.js)
+  content/specialpowersAPI.js (content/specialpowersAPI.js)
+  content/SpecialPowersObserverAPI.js (content/SpecialPowersObserverAPI.js)
+  content/MozillaLogger.js (content/MozillaLogger.js)
+
+% resource specialpowers %modules/
+  modules/MockFilePicker.jsm (content/MockFilePicker.jsm)
--- a/toolkit/mozapps/downloads/tests/Makefile.in
+++ b/toolkit/mozapps/downloads/tests/Makefile.in
@@ -17,9 +17,9 @@ XPCSHELL_TESTS = \
   unit \
   $(NULL)
 
 DIRS += chrome
 
 include $(topsrcdir)/config/rules.mk
 
 libs:: 
-	$(INSTALL) $(topsrcdir)/testing/mochitest/MockFilePicker.jsm $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit
+	$(INSTALL) $(topsrcdir)/testing/specialpowers/content/MockFilePicker.jsm $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit
--- a/toolkit/toolkit-makefiles.sh
+++ b/toolkit/toolkit-makefiles.sh
@@ -849,16 +849,17 @@ if [ "$ENABLE_TESTS" ]; then
     intl/uconv/tests/Makefile
     intl/unicharutil/tests/Makefile
     js/xpconnect/tests/Makefile
     js/xpconnect/tests/chrome/Makefile
     js/xpconnect/tests/components/js/Makefile
     js/xpconnect/tests/components/native/Makefile
     js/xpconnect/tests/idl/Makefile
     js/xpconnect/tests/mochitest/Makefile
+    testing/specialpowers/Makefile
     layout/base/tests/Makefile
     layout/base/tests/chrome/Makefile
     layout/base/tests/cpp-tests/Makefile
     layout/forms/test/Makefile
     layout/generic/test/Makefile
     layout/inspector/tests/Makefile
     layout/inspector/tests/chrome/Makefile
     layout/mathml/tests/Makefile
@@ -891,17 +892,16 @@ if [ "$ENABLE_TESTS" ]; then
     services/crypto/component/tests/Makefile
     startupcache/test/Makefile
     storage/test/Makefile
     testing/firebug/Makefile
     testing/mochitest/Makefile
     testing/mochitest/MochiKit/Makefile
     testing/mochitest/chrome/Makefile
     testing/mochitest/dynamic/Makefile
-    testing/mochitest/specialpowers/Makefile
     testing/mochitest/ssltunnel/Makefile
     testing/mochitest/static/Makefile
     testing/mochitest/tests/Makefile
     testing/mochitest/tests/MochiKit-1.4.2/Makefile
     testing/mochitest/tests/MochiKit-1.4.2/MochiKit/Makefile
     testing/mochitest/tests/MochiKit-1.4.2/tests/Makefile
     testing/mochitest/tests/MochiKit-1.4.2/tests/SimpleTest/Makefile
     testing/mochitest/tests/SimpleTest/Makefile
--- a/toolkit/toolkit-tiers.mk
+++ b/toolkit/toolkit-tiers.mk
@@ -156,16 +156,20 @@ tier_platform_dirs += \
 		media/omx-plugin \
 		$(NULL)
 endif
 
 ifndef MOZ_NATIVE_PNG
 tier_platform_dirs += media/libpng
 endif
 
+ifdef ENABLE_TESTS
+tier_platform_dirs += testing/specialpowers
+endif
+
 tier_platform_dirs	+= \
 		uriloader \
 		caps \
 		parser \
 		gfx \
 		image \
 		dom \
 		view \