mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Bug 938019 - Run mochitests from manifests (r=ted,gps)
This commit is contained in:
parent
2dd8e3a0bb
commit
8bc8184542
@ -566,9 +566,12 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||||||
# If there are no tests, look for support-files under DEFAULT.
|
# If there are no tests, look for support-files under DEFAULT.
|
||||||
process_support_files(defaults)
|
process_support_files(defaults)
|
||||||
|
|
||||||
# We also copy the manifest into the output directory.
|
# We also copy manifests into the output directory,
|
||||||
out_path = mozpath.join(out_dir, mozpath.basename(manifest_path))
|
# including manifests from [include:foo] directives.
|
||||||
obj.installs[path] = (out_path, False)
|
for mpath in m.manifests():
|
||||||
|
mpath = mozpath.normpath(mpath)
|
||||||
|
out_path = mozpath.join(out_dir, mozpath.basename(mpath))
|
||||||
|
obj.installs[mpath] = (out_path, False)
|
||||||
|
|
||||||
# Some manifests reference files that are auto generated as
|
# Some manifests reference files that are auto generated as
|
||||||
# part of the build or shouldn't be installed for some
|
# part of the build or shouldn't be installed for some
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
[test_foo.html]
|
@ -0,0 +1,4 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
install-to-subdir = subdir
|
||||||
|
|
||||||
|
[include:common.ini]
|
@ -0,0 +1,4 @@
|
|||||||
|
# Any copyright is dedicated to the Public Domain.
|
||||||
|
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
MOCHITEST_MANIFESTS += ['mochitest.ini']
|
@ -0,0 +1 @@
|
|||||||
|
<html></html>
|
@ -366,6 +366,24 @@ class TestEmitterBasic(unittest.TestCase):
|
|||||||
paths = sorted([v[0] for v in o.installs.values()])
|
paths = sorted([v[0] for v in o.installs.values()])
|
||||||
self.assertEqual(paths, expected)
|
self.assertEqual(paths, expected)
|
||||||
|
|
||||||
|
def test_test_manifest_install_includes(self):
|
||||||
|
"""Ensure that any [include:foo.ini] are copied to the objdir."""
|
||||||
|
reader = self.reader('test-manifest-install-includes')
|
||||||
|
|
||||||
|
objs = self.read_topsrcdir(reader)
|
||||||
|
self.assertEqual(len(objs), 1)
|
||||||
|
o = objs[0]
|
||||||
|
self.assertEqual(len(o.installs), 3)
|
||||||
|
self.assertEqual(o.manifest_relpath, "mochitest.ini")
|
||||||
|
self.assertEqual(o.manifest_obj_relpath, "subdir/mochitest.ini")
|
||||||
|
expected = [
|
||||||
|
mozpath.normpath(mozpath.join(o.install_prefix, "subdir/common.ini")),
|
||||||
|
mozpath.normpath(mozpath.join(o.install_prefix, "subdir/mochitest.ini")),
|
||||||
|
mozpath.normpath(mozpath.join(o.install_prefix, "subdir/test_foo.html")),
|
||||||
|
]
|
||||||
|
paths = sorted([v[0] for v in o.installs.values()])
|
||||||
|
self.assertEqual(paths, expected)
|
||||||
|
|
||||||
def test_test_manifest_keys_extracted(self):
|
def test_test_manifest_keys_extracted(self):
|
||||||
"""Ensure all metadata from test manifests is extracted."""
|
"""Ensure all metadata from test manifests is extracted."""
|
||||||
reader = self.reader('test-manifest-keys-extracted')
|
reader = self.reader('test-manifest-keys-extracted')
|
||||||
|
@ -320,7 +320,6 @@ class MochitestRunner(MozbuildObject):
|
|||||||
options.dumpAboutMemoryAfterTest = dump_about_memory_after_test
|
options.dumpAboutMemoryAfterTest = dump_about_memory_after_test
|
||||||
options.dumpDMDAfterTest = dump_dmd_after_test
|
options.dumpDMDAfterTest = dump_dmd_after_test
|
||||||
options.dumpOutputDirectory = dump_output_directory
|
options.dumpOutputDirectory = dump_output_directory
|
||||||
mozinfo.update({"e10s": e10s}) # for test manifest parsing.
|
|
||||||
|
|
||||||
options.failureFile = failure_file_path
|
options.failureFile = failure_file_path
|
||||||
if install_extension != None:
|
if install_extension != None:
|
||||||
|
@ -19,7 +19,8 @@ function parseTestManifest(testManifest, params, callback) {
|
|||||||
// For mochitest-plain, we define lists as an array of testnames.
|
// For mochitest-plain, we define lists as an array of testnames.
|
||||||
for (var obj of testManifest['tests']) {
|
for (var obj of testManifest['tests']) {
|
||||||
var path = obj['path'];
|
var path = obj['path'];
|
||||||
if (obj.disabled) {
|
// Note that obj.disabled may be "". We still want to skip in that case.
|
||||||
|
if ("disabled" in obj) {
|
||||||
dump("TEST-SKIPPED | " + path + " | " + obj.disabled + "\n");
|
dump("TEST-SKIPPED | " + path + " | " + obj.disabled + "\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -404,6 +404,8 @@ class MochitestOptions(optparse.OptionParser):
|
|||||||
def verifyOptions(self, options, mochitest):
|
def verifyOptions(self, options, mochitest):
|
||||||
""" verify correct options and cleanup paths """
|
""" verify correct options and cleanup paths """
|
||||||
|
|
||||||
|
mozinfo.update({"e10s": options.e10s}) # for test manifest parsing.
|
||||||
|
|
||||||
if options.app is None:
|
if options.app is None:
|
||||||
if build_obj is not None:
|
if build_obj is not None:
|
||||||
options.app = build_obj.get_binary_path()
|
options.app = build_obj.get_binary_path()
|
||||||
|
@ -362,24 +362,113 @@ class MochitestUtilsMixin(object):
|
|||||||
if options.dumpDMDAfterTest:
|
if options.dumpDMDAfterTest:
|
||||||
self.urlOpts.append("dumpDMDAfterTest=true")
|
self.urlOpts.append("dumpDMDAfterTest=true")
|
||||||
|
|
||||||
|
def getTestFlavor(self, options):
|
||||||
|
if options.browserChrome:
|
||||||
|
return "browser-chrome"
|
||||||
|
elif options.chrome:
|
||||||
|
return "chrome"
|
||||||
|
elif options.a11y:
|
||||||
|
return "a11y"
|
||||||
|
elif options.webapprtChrome:
|
||||||
|
return "webapprt-chrome"
|
||||||
|
else:
|
||||||
|
return "mochitest"
|
||||||
|
|
||||||
|
# This check can be removed when bug 983867 is fixed.
|
||||||
|
def isTest(self, options, filename):
|
||||||
|
allow_js_css = False
|
||||||
|
if options.browserChrome:
|
||||||
|
allow_js_css = True
|
||||||
|
testPattern = re.compile(r"browser_.+\.js")
|
||||||
|
elif options.chrome or options.a11y:
|
||||||
|
testPattern = re.compile(r"(browser|test)_.+\.(xul|html|js|xhtml)")
|
||||||
|
elif options.webapprtChrome:
|
||||||
|
testPattern = re.compile(r"webapprt_")
|
||||||
|
else:
|
||||||
|
testPattern = re.compile(r"test_")
|
||||||
|
|
||||||
|
if not allow_js_css and (".js" in filename or ".css" in filename):
|
||||||
|
return False
|
||||||
|
|
||||||
|
pathPieces = filename.split("/")
|
||||||
|
|
||||||
|
return (testPattern.match(pathPieces[-1]) and
|
||||||
|
not re.search(r'\^headers\^$', filename))
|
||||||
|
|
||||||
|
def getTestPath(self, options):
|
||||||
|
if options.ipcplugins:
|
||||||
|
return "dom/plugins/test"
|
||||||
|
else:
|
||||||
|
return options.testPath
|
||||||
|
|
||||||
|
def getTestRoot(self, options):
|
||||||
|
if options.browserChrome:
|
||||||
|
if options.immersiveMode:
|
||||||
|
return 'metro'
|
||||||
|
return 'browser'
|
||||||
|
elif options.a11y:
|
||||||
|
return 'a11y'
|
||||||
|
elif options.webapprtChrome:
|
||||||
|
return 'webapprtChrome'
|
||||||
|
elif options.chrome:
|
||||||
|
return 'chrome'
|
||||||
|
return self.TEST_PATH
|
||||||
|
|
||||||
|
def buildTestURL(self, options):
|
||||||
|
testHost = "http://mochi.test:8888"
|
||||||
|
testPath = self.getTestPath(options)
|
||||||
|
testURL = "/".join([testHost, self.TEST_PATH, testPath])
|
||||||
|
if os.path.isfile(os.path.join(self.oldcwd, os.path.dirname(__file__), self.TEST_PATH, testPath)) and options.repeat > 0:
|
||||||
|
testURL = "/".join([testHost, self.TEST_PATH, os.path.dirname(testPath)])
|
||||||
|
if options.chrome or options.a11y:
|
||||||
|
testURL = "/".join([testHost, self.CHROME_PATH])
|
||||||
|
elif options.browserChrome:
|
||||||
|
testURL = "about:blank"
|
||||||
|
return testURL
|
||||||
|
|
||||||
def buildTestPath(self, options):
|
def buildTestPath(self, options):
|
||||||
""" Build the url path to the specific test harness and test file or directory
|
""" 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
|
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)
|
||||||
if options.manifestFile and os.path.isfile(options.manifestFile):
|
if options.manifestFile and os.path.isfile(options.manifestFile):
|
||||||
manifest = TestManifest(strict=False)
|
manifestFileAbs = os.path.abspath(options.manifestFile)
|
||||||
manifest.read(options.manifestFile)
|
assert manifestFileAbs.startswith(testRootAbs)
|
||||||
|
manifest = TestManifest([options.manifestFile], strict=False)
|
||||||
|
else:
|
||||||
|
masterName = self.getTestFlavor(options) + '.ini'
|
||||||
|
masterPath = os.path.join(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.
|
||||||
|
info = {}
|
||||||
|
for k, v in mozinfo.info.items():
|
||||||
|
if isinstance(k, unicode):
|
||||||
|
k = k.encode('ascii')
|
||||||
|
info[k] = v
|
||||||
|
|
||||||
# Bug 883858 - return all tests including disabled tests
|
# Bug 883858 - return all tests including disabled tests
|
||||||
tests = manifest.active_tests(disabled=True, **mozinfo.info)
|
tests = manifest.active_tests(disabled=True, **info)
|
||||||
# We need to ensure we match on a complete directory name matching the
|
|
||||||
# test root, and not a substring somewhere else in the path.
|
|
||||||
test_root = os.path.sep + self.getTestRoot(options) + os.path.sep
|
|
||||||
paths = []
|
paths = []
|
||||||
|
testPath = self.getTestPath(options)
|
||||||
for test in tests:
|
for test in tests:
|
||||||
tp = test['path'].split(test_root, 1)[1].replace('\\', '/').strip('/')
|
pathAbs = os.path.abspath(test['path'])
|
||||||
|
assert pathAbs.startswith(testRootAbs)
|
||||||
|
tp = pathAbs[len(testRootAbs):].replace('\\', '/').strip('/')
|
||||||
|
|
||||||
# Filter out tests if we are using --test-path
|
# Filter out tests if we are using --test-path
|
||||||
if options.testPath and not tp.startswith(options.testPath):
|
if testPath and not tp.startswith(testPath):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not self.isTest(options, tp):
|
||||||
|
print 'Warning: %s from manifest %s is not a valid test' % (test['name'], test['manifest'])
|
||||||
continue
|
continue
|
||||||
|
|
||||||
testob = {'path': tp}
|
testob = {'path': tp}
|
||||||
@ -387,22 +476,20 @@ class MochitestUtilsMixin(object):
|
|||||||
testob['disabled'] = test['disabled']
|
testob['disabled'] = test['disabled']
|
||||||
paths.append(testob)
|
paths.append(testob)
|
||||||
|
|
||||||
|
# Sort tests so they are run in a deterministic order.
|
||||||
|
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
|
# Bug 883865 - add this functionality into manifestDestiny
|
||||||
with open('tests.json', 'w') as manifestFile:
|
with open('tests.json', 'w') as manifestFile:
|
||||||
manifestFile.write(json.dumps({'tests': paths}))
|
manifestFile.write(json.dumps({'tests': paths}))
|
||||||
options.manifestFile = 'tests.json'
|
options.manifestFile = 'tests.json'
|
||||||
|
|
||||||
testHost = "http://mochi.test:8888"
|
return self.buildTestURL(options)
|
||||||
testURL = ("/").join([testHost, self.TEST_PATH, options.testPath])
|
|
||||||
if os.path.isfile(os.path.join(self.oldcwd, os.path.dirname(__file__), self.TEST_PATH, options.testPath)) and options.repeat > 0:
|
|
||||||
testURL = ("/").join([testHost, self.TEST_PATH, os.path.dirname(options.testPath)])
|
|
||||||
if options.chrome or options.a11y:
|
|
||||||
testURL = ("/").join([testHost, self.CHROME_PATH])
|
|
||||||
elif options.browserChrome:
|
|
||||||
testURL = "about:blank"
|
|
||||||
elif options.ipcplugins:
|
|
||||||
testURL = ("/").join([testHost, self.TEST_PATH, "dom/plugins/test"])
|
|
||||||
return testURL
|
|
||||||
|
|
||||||
def startWebSocketServer(self, options, debuggerInfo):
|
def startWebSocketServer(self, options, debuggerInfo):
|
||||||
""" Launch the websocket server """
|
""" Launch the websocket server """
|
||||||
@ -1298,19 +1385,6 @@ class Mochitest(MochitestUtilsMixin):
|
|||||||
with open(os.path.join(options.profilePath, "testConfig.js"), "w") as config:
|
with open(os.path.join(options.profilePath, "testConfig.js"), "w") as config:
|
||||||
config.write(content)
|
config.write(content)
|
||||||
|
|
||||||
def getTestRoot(self, options):
|
|
||||||
if (options.browserChrome):
|
|
||||||
if (options.immersiveMode):
|
|
||||||
return 'metro'
|
|
||||||
return 'browser'
|
|
||||||
elif (options.a11y):
|
|
||||||
return 'a11y'
|
|
||||||
elif (options.webapprtChrome):
|
|
||||||
return 'webapprtChrome'
|
|
||||||
elif (options.chrome):
|
|
||||||
return 'chrome'
|
|
||||||
return self.TEST_PATH
|
|
||||||
|
|
||||||
def installExtensionFromPath(self, options, path, extensionID = None):
|
def installExtensionFromPath(self, options, path, extensionID = None):
|
||||||
"""install an extension to options.profilePath"""
|
"""install an extension to options.profilePath"""
|
||||||
|
|
||||||
|
@ -65,6 +65,10 @@ class B2GMochitest(MochitestUtilsMixin):
|
|||||||
test_url += "?" + "&".join(self.urlOpts)
|
test_url += "?" + "&".join(self.urlOpts)
|
||||||
self.test_script_args.append(test_url)
|
self.test_script_args.append(test_url)
|
||||||
|
|
||||||
|
def buildTestPath(self, options):
|
||||||
|
# Skip over the manifest building that happens on desktop.
|
||||||
|
return self.buildTestURL(options)
|
||||||
|
|
||||||
def build_profile(self, options):
|
def build_profile(self, options):
|
||||||
# preferences
|
# preferences
|
||||||
prefs = {}
|
prefs = {}
|
||||||
|
@ -379,6 +379,14 @@ class MochiRemote(Mochitest):
|
|||||||
options.logFile = self.localLog
|
options.logFile = self.localLog
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
def buildTestPath(self, options):
|
||||||
|
if options.robocopIni != "":
|
||||||
|
# Skip over manifest building if we just want to run
|
||||||
|
# robocop tests.
|
||||||
|
return self.buildTestURL(options)
|
||||||
|
else:
|
||||||
|
return super(MochiRemote, self).buildTestPath(options)
|
||||||
|
|
||||||
def installChromeFile(self, filename, options):
|
def installChromeFile(self, filename, options):
|
||||||
parts = options.app.split('/')
|
parts = options.app.split('/')
|
||||||
if (parts[0] == options.app):
|
if (parts[0] == options.app):
|
||||||
|
@ -603,7 +603,9 @@ class ManifestParser(object):
|
|||||||
return manifests in order in which they appear in the tests
|
return manifests in order in which they appear in the tests
|
||||||
"""
|
"""
|
||||||
if tests is None:
|
if tests is None:
|
||||||
tests = self.tests
|
# Make sure to return all the manifests, even ones without tests.
|
||||||
|
return self.manifest_defaults.keys()
|
||||||
|
|
||||||
manifests = []
|
manifests = []
|
||||||
for test in tests:
|
for test in tests:
|
||||||
manifest = test.get('manifest')
|
manifest = test.get('manifest')
|
||||||
|
2
testing/mozbase/manifestdestiny/tests/no-tests.ini
Normal file
2
testing/mozbase/manifestdestiny/tests/no-tests.ini
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
foo = bar
|
@ -200,5 +200,17 @@ class TestManifestParser(unittest.TestCase):
|
|||||||
self.assertTrue(manifest in parser.manifest_defaults)
|
self.assertTrue(manifest in parser.manifest_defaults)
|
||||||
self.assertEquals(parser.manifest_defaults[manifest]['foo'], 'bar')
|
self.assertEquals(parser.manifest_defaults[manifest]['foo'], 'bar')
|
||||||
|
|
||||||
|
def test_manifest_list(self):
|
||||||
|
"""
|
||||||
|
Ensure a manifest with just a DEFAULT section still returns
|
||||||
|
itself from the manifests() method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
parser = ManifestParser()
|
||||||
|
manifest = os.path.join(here, 'no-tests.ini')
|
||||||
|
parser.read(manifest)
|
||||||
|
self.assertEqual(len(parser.tests), 0)
|
||||||
|
self.assertTrue(len(parser.manifests()) == 1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user