Bug 503613 - Remove the tail file functionality from xpcshell. r?gps draft
authorMark Banner <standard8@mozilla.com>
Tue, 17 Jan 2017 15:27:55 +0000
changeset 463562 e268c51b9124cebdc7dd39999bc5ac9ad466b1d8
parent 463342 96cb95af530477edb66ae48d98c18533476e57bb
child 463563 daa8efb3409031fea553f4fd0c9d0746e38dc308
push id42107
push userbmo:standard8@mozilla.com
push dateThu, 19 Jan 2017 09:51:49 +0000
reviewersgps
bugs503613
milestone53.0a1
Bug 503613 - Remove the tail file functionality from xpcshell. r?gps MozReview-Commit-ID: JcglhFl89DX
python/mozbuild/mozbuild/frontend/emitter.py
python/mozbuild/mozbuild/test/frontend/data/test-manifest-keys-extracted/xpcshell.ini
python/mozbuild/mozbuild/test/frontend/test_emitter.py
python/mozbuild/mozbuild/test/test_testing.py
python/mozbuild/mozbuild/testing.py
testing/xpcshell/head.js
testing/xpcshell/remotexpcshelltests.py
testing/xpcshell/runxpcshelltests.py
testing/xpcshell/selftest.py
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -1392,17 +1392,16 @@ class TreeMetadataEmitter(LoggingMixin):
 
         for test, source_manifest in sorted(manifest.tests):
             obj.tests.append({
                 'path': test,
                 'here': mozpath.dirname(test),
                 'manifest': source_manifest,
                 'name': mozpath.basename(test),
                 'head': '',
-                'tail': '',
                 'support-files': '',
                 'subsuite': '',
             })
 
         yield obj
 
     def _process_web_platform_tests_manifest(self, context, paths, manifest):
         manifest_path, tests_root = paths
@@ -1427,17 +1426,16 @@ class TreeMetadataEmitter(LoggingMixin):
                     continue
 
                 obj.tests.append({
                     'path': path,
                     'here': mozpath.dirname(path),
                     'manifest': manifest_path,
                     'name': test.id,
                     'head': '',
-                    'tail': '',
                     'support-files': '',
                     'subsuite': '',
                 })
 
         yield obj
 
     def _process_jar_manifests(self, context):
         jar_manifests = context.get('JAR_MANIFESTS', [])
--- a/python/mozbuild/mozbuild/test/frontend/data/test-manifest-keys-extracted/xpcshell.ini
+++ b/python/mozbuild/mozbuild/test/frontend/data/test-manifest-keys-extracted/xpcshell.ini
@@ -1,6 +1,5 @@
 [DEFAULT]
 head = head1 head2
-tail = tail1 tail2
 dupe-manifest =
 
 [test_xpcshell.js]
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -597,18 +597,16 @@ class TestEmitterBasic(unittest.TestCase
             'xpcshell.ini': {
                 'flavor': 'xpcshell',
                 'dupe': True,
                 'installs': {
                     'xpcshell.ini': False,
                     'test_xpcshell.js': True,
                     'head1': False,
                     'head2': False,
-                    'tail1': False,
-                    'tail2': False,
                 },
             },
             'reftest.list': {
                 'flavor': 'reftest',
                 'installs': {},
             },
             'crashtest.list': {
                 'flavor': 'crashtest',
--- a/python/mozbuild/mozbuild/test/test_testing.py
+++ b/python/mozbuild/mozbuild/test/test_testing.py
@@ -43,32 +43,30 @@ ALL_TESTS = {
             "firefox-appdir": "browser",
             "flavor": "xpcshell",
             "head": "head_global.js head_helpers.js head_http.js",
             "here": "/Users/gps/src/firefox/services/common/tests/unit",
             "manifest": "/Users/gps/src/firefox/services/common/tests/unit/xpcshell.ini",
             "name": "test_async_chain.js",
             "path": "/Users/gps/src/firefox/services/common/tests/unit/test_async_chain.js",
             "relpath": "test_async_chain.js",
-            "tail": ""
         }
     ],
     "services/common/tests/unit/test_async_querySpinningly.js": [
         {
             "dir_relpath": "services/common/tests/unit",
             "file_relpath": "services/common/tests/unit/test_async_querySpinningly.js",
             "firefox-appdir": "browser",
             "flavor": "xpcshell",
             "head": "head_global.js head_helpers.js head_http.js",
             "here": "/Users/gps/src/firefox/services/common/tests/unit",
             "manifest": "/Users/gps/src/firefox/services/common/tests/unit/xpcshell.ini",
             "name": "test_async_querySpinningly.js",
             "path": "/Users/gps/src/firefox/services/common/tests/unit/test_async_querySpinningly.js",
             "relpath": "test_async_querySpinningly.js",
-            "tail": ""
         }
     ],
    "toolkit/mozapps/update/test/unit/test_0201_app_launch_apply_update.js": [
         {
             "dir_relpath": "toolkit/mozapps/update/test/unit",
             "file_relpath": "toolkit/mozapps/update/test/unit/test_0201_app_launch_apply_update.js",
             "flavor": "xpcshell",
             "generated-files": "head_update.js",
@@ -76,33 +74,31 @@ ALL_TESTS = {
             "here": "/Users/gps/src/firefox/toolkit/mozapps/update/test/unit",
             "manifest": "/Users/gps/src/firefox/toolkit/mozapps/update/test/unit/xpcshell_updater.ini",
             "name": "test_0201_app_launch_apply_update.js",
             "path": "/Users/gps/src/firefox/toolkit/mozapps/update/test/unit/test_0201_app_launch_apply_update.js",
             "reason": "bug 820380",
             "relpath": "test_0201_app_launch_apply_update.js",
             "run-sequentially": "Launches application.",
             "skip-if": "toolkit == 'gonk' || os == 'android'",
-            "tail": ""
         },
         {
             "dir_relpath": "toolkit/mozapps/update/test/unit",
             "file_relpath": "toolkit/mozapps/update/test/unit/test_0201_app_launch_apply_update.js",
             "flavor": "xpcshell",
             "generated-files": "head_update.js",
             "head": "head_update.js head2.js",
             "here": "/Users/gps/src/firefox/toolkit/mozapps/update/test/unit",
             "manifest": "/Users/gps/src/firefox/toolkit/mozapps/update/test/unit/xpcshell_updater.ini",
             "name": "test_0201_app_launch_apply_update.js",
             "path": "/Users/gps/src/firefox/toolkit/mozapps/update/test/unit/test_0201_app_launch_apply_update.js",
             "reason": "bug 820380",
             "relpath": "test_0201_app_launch_apply_update.js",
             "run-sequentially": "Launches application.",
             "skip-if": "toolkit == 'gonk' || os == 'android'",
-            "tail": ""
         }
     ],
     "mobile/android/tests/background/junit3/src/common/TestAndroidLogWriters.java": [
         {
             "dir_relpath": "mobile/android/tests/background/junit3/src/common",
             "file_relpath": "mobile/android/tests/background/junit3/src/common/TestAndroidLogWriters.java",
             "flavor": "instrumentation",
             "here": "/Users/nalexander/Mozilla/gecko-dev/mobile/android/tests/background/junit3",
--- a/python/mozbuild/mozbuild/testing.py
+++ b/python/mozbuild/mozbuild/testing.py
@@ -335,17 +335,16 @@ class SupportFilesConverter(object):
     moz.build and returns the installs to perform for this test object.
 
     Processing the same support files multiple times will not have any further
     effect, and the structure of the parsed objects from manifests will have a
     lot of repeated entries, so this class takes care of memoizing.
     """
     def __init__(self):
         self._fields = (('head', set()),
-                        ('tail', set()),
                         ('support-files', set()),
                         ('generated-files', set()))
 
     def convert_support_files(self, test, install_root, manifest_dir, out_dir):
         # Arguments:
         #  test - The test object to process.
         #  install_root - The directory under $objdir/_tests that will contain
         #                 the tests for this harness (examples are "testing/mochitest",
@@ -377,17 +376,17 @@ class SupportFilesConverter(object):
 
                 if field == 'generated-files':
                     info.external_installs.add(mozpath.normpath(mozpath.join(out_dir, pattern)))
                 # '!' indicates our syntax for inter-directory support file
                 # dependencies. These receive special handling in the backend.
                 elif pattern[0] == '!':
                     info.deferred_installs.add(pattern)
                 # We only support globbing on support-files because
-                # the harness doesn't support * for head and tail.
+                # the harness doesn't support * for head.
                 elif '*' in pattern and field == 'support-files':
                     info.pattern_installs.append((manifest_dir, pattern, out_dir))
                 # "absolute" paths identify files that are to be
                 # placed in the install_root directory (no globs)
                 elif pattern[0] == '/':
                     full = mozpath.normpath(mozpath.join(manifest_dir,
                                                          mozpath.basename(pattern)))
                     info.installs.append((full, mozpath.join(install_root, pattern[1:])))
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -572,19 +572,16 @@ function _execute_test() {
       _testLogger.error(message, extra);
     }
   }
 
   if (coverageCollector != null) {
     coverageCollector.finalize();
   }
 
-  // _TAIL_FILES is dynamically defined by <runxpcshelltests.py>.
-  _load_files(_TAIL_FILES);
-
   // Execute all of our cleanup functions.
   let reportCleanupError = function(ex) {
     let stack, filename;
     if (ex && typeof ex == "object" && "stack" in ex) {
       stack = ex.stack;
     } else {
       stack = Components.stack.caller;
     }
@@ -1259,17 +1256,16 @@ function do_load_child_test_harness()
   do_load_child_test_harness.alreadyRun = 1;
 
   _XPCSHELL_PROCESS = "parent";
 
   let command =
         "const _HEAD_JS_PATH=" + uneval(_HEAD_JS_PATH) + "; "
       + "const _HEAD_FILES=" + uneval(_HEAD_FILES) + "; "
       + "const _MOZINFO_JS_PATH=" + uneval(_MOZINFO_JS_PATH) + "; "
-      + "const _TAIL_FILES=" + uneval(_TAIL_FILES) + "; "
       + "const _TEST_NAME=" + uneval(_TEST_NAME) + "; "
       // We'll need more magic to get the debugger working in the child
       + "const _JSDEBUGGER_PORT=0; "
       + "const _XPCSHELL_PROCESS='child';";
 
   if (typeof _JSCOV_DIR === 'string') {
     command += " const _JSCOV_DIR=" + uneval(_JSCOV_DIR) + ";";
   }
--- a/testing/xpcshell/remotexpcshelltests.py
+++ b/testing/xpcshell/remotexpcshelltests.py
@@ -82,21 +82,20 @@ class RemoteXPCShellTestThread(xpcshell.
         os.remove(local)
         return mozInfoJSPath
 
     def logCommand(self, name, completeCmd, testdir):
         self.log.info("%s | full command: %r" % (name, completeCmd))
         self.log.info("%s | current directory: %r" % (name, self.remoteHere))
         self.log.info("%s | environment: %s" % (name, self.env))
 
-    def getHeadAndTailFiles(self, test):
+    def getHeadFiles(self, test):
         """Override parent method to find files on remote device.
 
-        Obtains lists of head- and tail files.  Returns a tuple containing
-        a list of head files and a list of tail files.
+        Obtains lists of head- files.  Returns a list of head files.
         """
         def sanitize_list(s, kind):
             for f in s.strip().split(' '):
                 f = f.strip()
                 if len(f) < 1:
                     continue
 
                 path = remoteJoin(self.remoteHere, f)
@@ -104,19 +103,17 @@ class RemoteXPCShellTestThread(xpcshell.
                 # skip check for file existence: the convenience of discovering
                 # a missing file does not justify the time cost of the round trip
                 # to the device
                 yield path
 
         self.remoteHere = self.remoteForLocal(test['here'])
 
         headlist = test.get('head', '')
-        taillist = test.get('tail', '')
-        return (list(sanitize_list(headlist, 'head')),
-                list(sanitize_list(taillist, 'tail')))
+        return list(sanitize_list(headlist, 'head'))
 
     def buildXpcsCmd(self):
         # change base class' paths to remote paths and use base class to build command
         self.xpcshell = remoteJoin(self.remoteBinDir, "xpcw")
         self.headJSPath = remoteJoin(self.remoteScriptsDir, 'head.js')
         self.httpdJSPath = remoteJoin(self.remoteComponentsDir, 'httpd.js')
         self.httpdManifest = remoteJoin(self.remoteComponentsDir, 'httpd.manifest')
         self.testingModulesDir = self.remoteModulesDir
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -371,40 +371,36 @@ class XPCShellTestThread(Thread):
         return profileDir
 
     def setupMozinfoJS(self):
         mozInfoJSPath = os.path.join(self.profileDir, 'mozinfo.json')
         mozInfoJSPath = mozInfoJSPath.replace('\\', '\\\\')
         mozinfo.output_to_file(mozInfoJSPath)
         return mozInfoJSPath
 
-    def buildCmdHead(self, headfiles, tailfiles, xpcscmd):
+    def buildCmdHead(self, headfiles, xpcscmd):
         """
-          Build the command line arguments for the head and tail files,
+          Build the command line arguments for the head files,
           along with the address of the webserver which some tests require.
 
           On a remote system, this is overloaded to resolve quoting issues over a secondary command line.
         """
         cmdH = ", ".join(['"' + f.replace('\\', '/') + '"'
                        for f in headfiles])
-        cmdT = ", ".join(['"' + f.replace('\\', '/') + '"'
-                       for f in tailfiles])
 
         dbgport = 0 if self.jsDebuggerInfo is None else self.jsDebuggerInfo.port
 
         return xpcscmd + \
                 ['-e', 'const _SERVER_ADDR = "localhost"',
                  '-e', 'const _HEAD_FILES = [%s];' % cmdH,
-                 '-e', 'const _TAIL_FILES = [%s];' % cmdT,
                  '-e', 'const _JSDEBUGGER_PORT = %d;' % dbgport,
                 ]
 
-    def getHeadAndTailFiles(self, test):
-        """Obtain lists of head- and tail files.  Returns a tuple
-        containing a list of head files and a list of tail files.
+    def getHeadFiles(self, test):
+        """Obtain lists of head- files.  Returns a list of head files.
         """
         def sanitize_list(s, kind):
             for f in s.strip().split(' '):
                 f = f.strip()
                 if len(f) < 1:
                     continue
 
                 path = os.path.normpath(os.path.join(test['here'], f))
@@ -412,23 +408,21 @@ class XPCShellTestThread(Thread):
                     raise Exception('%s file does not exist: %s' % (kind, path))
 
                 if not os.path.isfile(path):
                     raise Exception('%s file is not a file: %s' % (kind, path))
 
                 yield path
 
         headlist = test.get('head', '')
-        taillist = test.get('tail', '')
-        return (list(sanitize_list(headlist, 'head')),
-                list(sanitize_list(taillist, 'tail')))
+        return list(sanitize_list(headlist, 'head'))
 
     def buildXpcsCmd(self):
         """
-          Load the root head.js file as the first file in our test path, before other head, test, and tail files.
+          Load the root head.js file as the first file in our test path, before other head, and test files.
           On a remote system, we overload this to add additional command line arguments, so this gets overloaded.
         """
         # - NOTE: if you rename/add any of the constants set here, update
         #   do_load_child_test_harness() in head.js
         if not self.appPath:
             self.appPath = self.xrePath
 
         self.xpcsCmd = [
@@ -618,18 +612,18 @@ class XPCShellTestThread(Thread):
 
         # Create a profile and a temp dir that the JS harness can stick
         # a profile and temporary data in
         self.profileDir = self.setupProfileDir()
         self.tempDir = self.setupTempDir()
         self.mozInfoJSPath = self.setupMozinfoJS()
 
         self.buildXpcsCmd()
-        head_files, tail_files = self.getHeadAndTailFiles(self.test_object)
-        cmdH = self.buildCmdHead(head_files, tail_files, self.xpcsCmd)
+        head_files = self.getHeadFiles(self.test_object)
+        cmdH = self.buildCmdHead(head_files, self.xpcsCmd)
 
         # The test file will have to be loaded after the head files.
         cmdT = self.buildCmdTestFile(path)
 
         args = self.xpcsRunArgs[:]
         if 'debug' in self.test_object:
             args.insert(0, '-d')
 
--- a/testing/xpcshell/selftest.py
+++ b/testing/xpcshell/selftest.py
@@ -1042,33 +1042,16 @@ add_test({
             # The actual return value is never checked because we raise.
             self.assertTestResult(True)
         except Exception, ex:
             raised = True
             self.assertEquals(ex.message[0:9], "head file")
 
         self.assertTrue(raised)
 
-    def testMissingTailFile(self):
-        """
-        Ensure that missing tail file results in fatal error.
-        """
-        self.writeFile("test_basic.js", SIMPLE_PASSING_TEST)
-        self.writeManifest([("test_basic.js", "tail = missing.js")])
-
-        raised = False
-
-        try:
-            self.assertTestResult(True)
-        except Exception, ex:
-            raised = True
-            self.assertEquals(ex.message[0:9], "tail file")
-
-        self.assertTrue(raised)
-
     def testRandomExecution(self):
         """
         Check that random execution doesn't break.
         """
         manifest = []
         for i in range(0, 10):
             filename = "test_pass_%d.js" % i
             self.writeFile(filename, SIMPLE_PASSING_TEST)