mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +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.
|
||||
process_support_files(defaults)
|
||||
|
||||
# We also copy the manifest into the output directory.
|
||||
out_path = mozpath.join(out_dir, mozpath.basename(manifest_path))
|
||||
obj.installs[path] = (out_path, False)
|
||||
# We also copy manifests into the output directory,
|
||||
# including manifests from [include:foo] directives.
|
||||
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
|
||||
# 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()])
|
||||
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):
|
||||
"""Ensure all metadata from test manifests is extracted."""
|
||||
reader = self.reader('test-manifest-keys-extracted')
|
||||
|
@ -320,7 +320,6 @@ class MochitestRunner(MozbuildObject):
|
||||
options.dumpAboutMemoryAfterTest = dump_about_memory_after_test
|
||||
options.dumpDMDAfterTest = dump_dmd_after_test
|
||||
options.dumpOutputDirectory = dump_output_directory
|
||||
mozinfo.update({"e10s": e10s}) # for test manifest parsing.
|
||||
|
||||
options.failureFile = failure_file_path
|
||||
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 (var obj of testManifest['tests']) {
|
||||
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");
|
||||
continue;
|
||||
}
|
||||
|
@ -404,6 +404,8 @@ class MochitestOptions(optparse.OptionParser):
|
||||
def verifyOptions(self, options, mochitest):
|
||||
""" verify correct options and cleanup paths """
|
||||
|
||||
mozinfo.update({"e10s": options.e10s}) # for test manifest parsing.
|
||||
|
||||
if options.app is None:
|
||||
if build_obj is not None:
|
||||
options.app = build_obj.get_binary_path()
|
||||
|
@ -362,24 +362,113 @@ class MochitestUtilsMixin(object):
|
||||
if options.dumpDMDAfterTest:
|
||||
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):
|
||||
""" 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)
|
||||
if options.manifestFile and os.path.isfile(options.manifestFile):
|
||||
manifest = TestManifest(strict=False)
|
||||
manifest.read(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)
|
||||
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
|
||||
tests = manifest.active_tests(disabled=True, **mozinfo.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
|
||||
tests = manifest.active_tests(disabled=True, **info)
|
||||
paths = []
|
||||
testPath = self.getTestPath(options)
|
||||
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
|
||||
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
|
||||
|
||||
testob = {'path': tp}
|
||||
@ -387,22 +476,20 @@ class MochitestUtilsMixin(object):
|
||||
testob['disabled'] = test['disabled']
|
||||
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
|
||||
with open('tests.json', 'w') as manifestFile:
|
||||
manifestFile.write(json.dumps({'tests': paths}))
|
||||
options.manifestFile = 'tests.json'
|
||||
|
||||
testHost = "http://mochi.test:8888"
|
||||
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
|
||||
return self.buildTestURL(options)
|
||||
|
||||
def startWebSocketServer(self, options, debuggerInfo):
|
||||
""" Launch the websocket server """
|
||||
@ -1298,19 +1385,6 @@ class Mochitest(MochitestUtilsMixin):
|
||||
with open(os.path.join(options.profilePath, "testConfig.js"), "w") as config:
|
||||
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):
|
||||
"""install an extension to options.profilePath"""
|
||||
|
||||
|
@ -65,6 +65,10 @@ class B2GMochitest(MochitestUtilsMixin):
|
||||
test_url += "?" + "&".join(self.urlOpts)
|
||||
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):
|
||||
# preferences
|
||||
prefs = {}
|
||||
|
@ -379,6 +379,14 @@ class MochiRemote(Mochitest):
|
||||
options.logFile = self.localLog
|
||||
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):
|
||||
parts = options.app.split('/')
|
||||
if (parts[0] == options.app):
|
||||
|
@ -603,7 +603,9 @@ class ManifestParser(object):
|
||||
return manifests in order in which they appear in the tests
|
||||
"""
|
||||
if tests is None:
|
||||
tests = self.tests
|
||||
# Make sure to return all the manifests, even ones without tests.
|
||||
return self.manifest_defaults.keys()
|
||||
|
||||
manifests = []
|
||||
for test in tests:
|
||||
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.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__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user