Bug 912243 - Mochitest shouldnt chdir in __init__. r=jmaher
authorVaibhav Agrawal <vaibhavmagarwal@gmail.com>
Wed, 16 Apr 2014 10:29:39 -0400
changeset 179226 03e9ce5758cb3753181fb30929518f358fb3f2e5
parent 179225 9c402f8b74fc10a517c03d2d1eb035cdf5499268
child 179227 c1ac0cb853b9d5c1f892567a167a58abb2965364
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersjmaher
bugs912243
milestone31.0a1
Bug 912243 - Mochitest shouldnt chdir in __init__. r=jmaher
testing/mochitest/mochitest_options.py
testing/mochitest/runtests.py
testing/mochitest/runtestsremote.py
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -489,17 +489,17 @@ class MochitestOptions(optparse.OptionPa
             if not os.path.exists(mochitest.vmwareHelperPath):
                 self.error("%s not found, cannot automate VMware recording." %
                            mochitest.vmwareHelperPath)
 
         if options.testManifest and options.runOnlyTests:
             self.error("Please use --test-manifest only and not --run-only-tests")
 
         if options.runOnlyTests:
-            if not os.path.exists(os.path.abspath(options.runOnlyTests)):
+            if not os.path.exists(os.path.abspath(os.path.join(here, options.runOnlyTests))):
                 self.error("unable to find --run-only-tests file '%s'" % options.runOnlyTests)
             options.runOnly = True
             options.testManifest = options.runOnlyTests
             options.runOnlyTests = None
 
         if options.manifestFile and options.testManifest:
             self.error("Unable to support both --manifest and --test-manifest/--run-only-tests at the same time")
 
@@ -520,17 +520,17 @@ class MochitestOptions(optparse.OptionPa
 
         # Try to guess the testing modules directory.
         # This somewhat grotesque hack allows the buildbot machines to find the
         # modules directory without having to configure the buildbot hosts. This
         # code should never be executed in local runs because the build system
         # should always set the flag that populates this variable. If buildbot ever
         # passes this argument, this code can be deleted.
         if options.testingModulesDir is None:
-            possible = os.path.join(os.getcwd(), os.path.pardir, 'modules')
+            possible = os.path.join(here, os.path.pardir, 'modules')
 
             if os.path.isdir(possible):
                 options.testingModulesDir = possible
 
         # Even if buildbot is updated, we still want this, as the path we pass in
         # to the app must be absolute and have proper slashes.
         if options.testingModulesDir is not None:
             options.testingModulesDir = os.path.normpath(options.testingModulesDir)
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -133,17 +133,17 @@ class MochitestServer(object):
     self.webServer = options['webServer']
     self.httpPort = options['httpPort']
     self.shutdownURL = "http://%(server)s:%(port)s/server/shutdown" % { "server" : self.webServer, "port" : self.httpPort }
     self.testPrefix = "'webapprt_'" if options.get('webapprtContent') else "undefined"
 
     if options.get('httpdPath'):
         self._httpdPath = options['httpdPath']
     else:
-        self._httpdPath = '.'
+        self._httpdPath = SCRIPT_DIR
     self._httpdPath = os.path.abspath(self._httpdPath)
 
   def start(self):
     "Run the Mochitest server, returning the process ID of the server."
 
     # get testing environment
     env = environment(xrePath=self._xrePath)
     env["XPCOM_DEBUG_BREAK"] = "warn"
@@ -154,26 +154,26 @@ class MochitestServer(object):
     # features.
     env["ASAN_OPTIONS"] = "quarantine_size=1:redzone=32:malloc_context_size=5"
 
     if mozinfo.isWin:
       env["PATH"] = env["PATH"] + ";" + str(self._xrePath)
 
     args = ["-g", self._xrePath,
             "-v", "170",
-            "-f", self._httpdPath + "/httpd.js",
+            "-f", os.path.join(self._httpdPath, "httpd.js"),
             "-e", """const _PROFILE_PATH = '%(profile)s'; const _SERVER_PORT = '%(port)s'; const _SERVER_ADDR = '%(server)s'; const _TEST_PREFIX = %(testPrefix)s; const _DISPLAY_RESULTS = %(displayResults)s;""" %
                    {"profile" : self._profileDir.replace('\\', '\\\\'), "port" : self.httpPort, "server" : self.webServer,
                     "testPrefix" : self.testPrefix, "displayResults" : str(not self._closeWhenDone).lower() },
-            "-f", "./" + "server.js"]
+            "-f", os.path.join(SCRIPT_DIR, "server.js")]
 
     xpcshell = os.path.join(self._utilityPath,
                             "xpcshell" + mozinfo.info['bin_suffix'])
     command = [xpcshell] + args
-    self._process = mozprocess.ProcessHandler(command, env=env)
+    self._process = mozprocess.ProcessHandler(command, cwd=SCRIPT_DIR, env=env)
     self._process.run()
     log.info("%s : launching %s", self.__class__.__name__, command)
     pid = self._process.pid
     log.info("runtests.py | Server pid: %d", pid)
 
   def ensureReady(self, timeout):
     assert timeout >= 0
 
@@ -228,17 +228,17 @@ class WebSocketServer(object):
 
     cmd = [sys.executable, script]
     if self.debuggerInfo and self.debuggerInfo['interactive']:
         cmd += ['--interactive']
     cmd += ['-p', str(self.port), '-w', self._scriptdir, '-l',      \
            os.path.join(self._scriptdir, "websock.log"),            \
            '--log-level=debug', '--allow-handlers-outside-root-dir']
     # start the process
-    self._process = mozprocess.ProcessHandler(cmd)
+    self._process = mozprocess.ProcessHandler(cmd, cwd=SCRIPT_DIR)
     self._process.run()
     pid = self._process.pid
     log.info("runtests.py | Websocket server pid: %d", pid)
 
   def stop(self):
     self._process.kill()
 
 class MochitestUtilsMixin(object):
@@ -256,17 +256,16 @@ class MochitestUtilsMixin(object):
   jarDir = 'mochijar'
 
   # Path to the test script on the server
   TEST_PATH = "tests"
   CHROME_PATH = "redirect.html"
   urlOpts = []
 
   def __init__(self):
-    os.chdir(SCRIPT_DIR)
     self.update_mozinfo()
 
   def update_mozinfo(self):
     """walk up directories to find mozinfo.json update the info"""
     # TODO: This should go in a more generic place, e.g. mozinfo
 
     path = SCRIPT_DIR
     dirs = set()
@@ -436,26 +435,29 @@ class MochitestUtilsMixin(object):
 
   def buildTestPath(self, options):
     """ Build the url path to the specific test harness and test file or directory
         Build a manifest of tests to run and write out a json file for the harness to read
     """
     manifest = None
 
     testRoot = self.getTestRoot(options)
-    testRootAbs = os.path.abspath(testRoot)
+    # testdir refers to 'mochitest' here.
+    testdir = SCRIPT_DIR.split(os.getcwd())[-1]
+    testdir = testdir.strip(os.sep)
+    testRootAbs = os.path.abspath(os.path.join(testdir, testRoot))
     if isinstance(options.manifestFile, TestManifest):
         manifest = options.manifestFile
     elif options.manifestFile and os.path.isfile(options.manifestFile):
       manifestFileAbs = os.path.abspath(options.manifestFile)
       assert manifestFileAbs.startswith(testRootAbs)
       manifest = TestManifest([options.manifestFile], strict=False)
     else:
       masterName = self.getTestFlavor(options) + '.ini'
-      masterPath = os.path.join(testRoot, masterName)
+      masterPath = os.path.join(testdir, testRoot, masterName)
 
       if os.path.exists(masterPath):
         manifest = TestManifest([masterPath], strict=False)
 
     if manifest:
       # Python 2.6 doesn't allow unicode keys to be used for keyword
       # arguments. This gross hack works around the problem until we
       # rid ourselves of 2.6.
@@ -492,17 +494,17 @@ class MochitestUtilsMixin(object):
       def path_sort(ob1, ob2):
         path1 = ob1['path'].split('/')
         path2 = ob2['path'].split('/')
         return cmp(path1, path2)
 
       paths.sort(path_sort)
 
       # Bug 883865 - add this functionality into manifestDestiny
-      with open('tests.json', 'w') as manifestFile:
+      with open(os.path.join(testdir, 'tests.json'), 'w') as manifestFile:
         manifestFile.write(json.dumps({'tests': paths}))
       options.manifestFile = 'tests.json'
 
     return self.buildTestURL(options)
 
   def startWebSocketServer(self, options, debuggerInfo):
     """ Launch the websocket server """
     if options.webServer != '127.0.0.1':
@@ -582,17 +584,17 @@ toolbar#nav-bar {
 }
 """
     with open(os.path.join(options.profilePath, "userChrome.css"), "a") as chromeFile:
       chromeFile.write(chrome)
 
     manifest = os.path.join(options.profilePath, "tests.manifest")
     with open(manifest, "w") as manifestFile:
       # Register chrome directory.
-      chrometestDir = os.path.abspath(".") + "/"
+      chrometestDir = os.path.join(os.path.abspath("."), SCRIPT_DIR) + "/"
       if mozinfo.isWin:
         chrometestDir = "file:///" + chrometestDir.replace("\\", "/")
       manifestFile.write("content mochitests %s contentaccessible=yes\n" % chrometestDir)
 
       if options.testingModulesDir is not None:
         manifestFile.write("resource testing-common file:///%s\n" %
           options.testingModulesDir)
 
@@ -942,17 +944,17 @@ class Mochitest(MochitestUtilsMixin):
                                                    xrePath)
         if certificateStatus:
           log.info("TEST-UNEXPECTED-FAIL | runtests.py | Certificate integration failed")
           return certificateStatus
 
         # start ssltunnel to provide https:// URLs capability
         ssltunnel = os.path.join(utilityPath, "ssltunnel" + bin_suffix)
         ssltunnel_cfg = os.path.join(self.profile.profile, "ssltunnel.cfg")
-        ssltunnelProcess = mozprocess.ProcessHandler([ssltunnel, ssltunnel_cfg],
+        ssltunnelProcess = mozprocess.ProcessHandler([ssltunnel, ssltunnel_cfg], cwd=SCRIPT_DIR,
                                                       env=environment(xrePath=xrePath))
         ssltunnelProcess.run()
         log.info("INFO | runtests.py | SSL tunnel pid: %d", ssltunnelProcess.pid)
       else:
         ssltunnelProcess = None
 
       if interactive:
         # If an interactive debugger is attached,
@@ -986,16 +988,17 @@ class Mochitest(MochitestUtilsMixin):
                                          shutdownLeaks=shutdownLeaks,
         )
 
       def timeoutHandler():
         outputHandler.log_output_buffer()
         browserProcessId = outputHandler.browserProcessId
         self.handleTimeout(timeout, proc, utilityPath, debuggerInfo, browserProcessId)
       kp_kwargs = {'kill_on_timeout': False,
+                   'cwd': SCRIPT_DIR,
                    'onTimeout': [timeoutHandler]}
       kp_kwargs['processOutputLine'] = [outputHandler]
 
       # create mozrunner instance and start the system under test process
       self.lastTestSeen = self.test_name
       startTime = datetime.now()
 
       # b2g desktop requires FirefoxRunner even though appname is b2g
--- a/testing/mochitest/runtestsremote.py
+++ b/testing/mochitest/runtestsremote.py
@@ -21,16 +21,17 @@ from runtests import MochitestServer
 from mochitest_options import MochitestOptions
 
 import devicemanager
 import droid
 import manifestparser
 import mozinfo
 import mozlog
 
+SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
 log = mozlog.getLogger('Mochi-Remote')
 
 class RemoteOptions(MochitestOptions):
 
     def __init__(self, automation, **kwargs):
         defaults = {}
         self._automation = automation or Automation()
         MochitestOptions.__init__(self)
@@ -622,17 +623,17 @@ def main():
             start = int(round((options.thisChunk-1) * tests_per_chunk))
             end = int(round(options.thisChunk * tests_per_chunk))
             if end > len(tests):
                 end = len(tests)
             my_tests = tests[start:end]
             log.info("Running tests %d-%d/%d", start+1, end, len(tests))
 
         dm.removeFile(os.path.join(deviceRoot, "fennec_ids.txt"))
-        fennec_ids = os.path.abspath("fennec_ids.txt")
+        fennec_ids = os.path.abspath(os.path.join(SCRIPT_DIR, "fennec_ids.txt"))
         if not os.path.exists(fennec_ids) and options.robocopIds:
             fennec_ids = options.robocopIds
         dm.pushFile(fennec_ids, os.path.join(deviceRoot, "fennec_ids.txt"))
         options.extraPrefs.append('browser.search.suggest.enabled=true')
         options.extraPrefs.append('browser.search.suggest.prompted=true')
         options.extraPrefs.append('layout.css.devPixelsPerPx=1.0')
         options.extraPrefs.append('browser.chrome.dynamictoolbar=false')
         options.extraPrefs.append('browser.snippets.enabled=false')