def extract_unittests_from_args(args, environ, manifest_path): """Extract unittests from args, expanding directories as needed""" mp = manifestparser.TestManifest(strict=True) tests = [] binary_path = None if manifest_path: mp.read(manifest_path) binary_path = os.path.abspath(args[0]) else: for p in args: if os.path.isdir(p): try: mp.read(os.path.join(p, 'cppunittest.ini')) except IOError: tests.extend([(os.path.abspath(os.path.join(p, x)), 1) for x in os.listdir(p)]) else: tests.append((os.path.abspath(p), 1)) # we skip the existence check here because not all tests are built # for all platforms (and it will fail on Windows anyway) active_tests = mp.active_tests(exists=False, disabled=False, **environ) suffix = '.exe' if mozinfo.isWin else '' if binary_path: tests.extend([(os.path.join(binary_path, test['relpath'] + suffix), int(test.get('requesttimeoutfactor', 1))) for test in active_tests]) else: tests.extend([(test['path'] + suffix, int(test.get('requesttimeoutfactor', 1))) for test in active_tests]) # skip non-existing tests tests = [test for test in tests if os.path.isfile(test[0])] return tests
def main(args=sys.argv[1:]): # read the manifest if args: manifests = args else: manifests = [os.path.join(here, 'test-manifest.ini')] missing = [] for manifest in manifests: # ensure manifests exist if not os.path.exists(manifest): missing.append(manifest) assert not missing, 'manifest%s not found: %s' % ( (len(manifests) == 1 and '' or 's'), ', '.join(missing)) manifest = manifestparser.TestManifest(manifests=manifests) # gather the tests tests = manifest.active_tests() unittestlist = [] for test in tests: unittestlist.extend(unittests(test['path'])) # run the tests suite = unittest.TestSuite(unittestlist) runner = unittest.TextTestRunner( verbosity=2) # default=1 does not show success of unittests unittest_results = runner.run(suite) results = TestResultCollection.from_unittest_results( None, unittest_results) # exit according to results sys.exit(1 if results.num_failures else 0)
def do_test(self, test_path=None, manifest_path=None, passes=0, fails=0, skips=0): abspath = os.path.dirname(os.path.abspath(__file__)) if manifest_path: manifestpath = os.path.join(abspath, manifest_path) manifest = manifestparser.TestManifest(manifests=[manifestpath], strict=False) tests = manifest.active_tests() elif test_path: testpath = os.path.join(abspath, test_path) tests = [{'path': testpath}] m = mozmill.MozMill.create() m.run(tests) results = m.finish(()) # From the first test, there is one passing test self.assertEqual(len(results.passes), passes, "Passes should match") self.assertEqual(len(results.fails), fails, "Fails should match") self.assertEqual(len(results.skipped), skips, "Skips should match") return (results, m.persisted)
def main(args=sys.argv[1:]): # read the manifest if args: manifests = args else: manifests = [os.path.join(here, 'test-manifest.ini')] missing = [] for manifest in manifests: # ensure manifests exist if not os.path.exists(manifest): missing.append(manifest) assert not missing, 'manifest%s not found: %s' % ( (len(manifests) == 1 and '' or 's'), ', '.join(missing)) manifest = manifestparser.TestManifest(manifests=manifests) # gather the tests tests = manifest.active_tests() unittestlist = [] for test in tests: unittestlist.extend(unittests(test['path'])) # run the tests suite = unittest.TestSuite(unittestlist) runner = unittest.TextTestRunner() results = runner.run(suite) # exit according to results sys.exit((results.failures or results.errors) and 1 or 0)
def extract_unittests_from_args(args, environ): """Extract unittests from args, expanding directories as needed""" mp = manifestparser.TestManifest(strict=True) tests = [] for p in args: if os.path.isdir(p): try: mp.read(os.path.join(p, 'cppunittest.ini')) except IOError: tests.extend([ os.path.abspath(os.path.join(p, x)) for x in os.listdir(p) ]) else: tests.append(os.path.abspath(p)) # we skip the existence check here because not all tests are built # for all platforms (and it will fail on Windows anyway) if mozinfo.isWin: tests.extend([ test['path'] + '.exe' for test in mp.active_tests( exists=False, disabled=False, **environ) ]) else: tests.extend([ test['path'] for test in mp.active_tests( exists=False, disabled=False, **environ) ]) # skip non-existing tests tests = [test for test in tests if os.path.isfile(test)] return tests
def read_manifestparser_manifest(context, manifest_path): path = manifest_path.full_path return manifestparser.TestManifest(manifests=[path], strict=True, rootdir=context.config.topsrcdir, finder=context._finder, handle_defaults=False)
def write_to_ini_file(manifest_file, filename): # Insert a new test in the right place within a given manifest file manifest = manifestparser.TestManifest(manifests=[manifest_file]) insert_before = None if any(t["name"] == filename for t in manifest.tests): print("{} is already in the manifest.".format(filename)) return for test in manifest.tests: if test.get("name") > filename: insert_before = test.get("name") break with open(manifest_file, "r") as f: contents = f.readlines() filename = "[{}]\n".format(filename) if not insert_before: contents.append(filename) else: insert_before = "[{}]".format(insert_before) for i in range(len(contents)): if contents[i].startswith(insert_before): contents.insert(i, filename) break with io.open(manifest_file, "w", newline="\n") as f: f.write("".join(contents))
def main(args=sys.argv[1:]): logging.basicConfig(filename='test.log', filemode='w', level=logging.DEBUG, format='%(asctime)s|%(levelname)s|%(message)s') # read the manifest if args: manifests = args else: manifests = [os.path.join(here, 'selftest', 'manifest.ini')] missing = [] for manifest in manifests: # ensure manifests exist if not os.path.exists(manifest): missing.append(manifest) assert not missing, 'manifest%s not found: %s' % ( (len(manifests) == 1 and '' or 's'), ', '.join(missing)) manifest = manifestparser.TestManifest(manifests=manifests) sys.path.insert(0, here) # gather the tests tests = manifest.active_tests() unittestlist = [] for test in tests: unittestlist.extend(unittests(test['path'])) # run the tests suite = unittest.TestSuite(unittestlist) runner = unittest.TextTestRunner() results = runner.run(suite) # exit according to results sys.exit((results.failures or results.errors) and 1 or 0)
def run_tests(self): """ Start the execution of the tests. """ manifest = manifestparser.TestManifest( manifests=[os.path.join(self.repository.path, self.manifest_path)], strict=False) tests = manifest.active_tests(**mozinfo.info) # instantiate handlers logger = mozmill.logger.LoggerListener(log_file=self.options.logfile, console_level=self.debug and 'DEBUG' or 'INFO', file_level=self.debug and 'DEBUG' or 'INFO', debug=self.debug) handlers = [logger] if self.options.report_url: self.report = reports.DashboardReport(self.options.report_url, self) handlers.append(self.report) if self.options.junit_file: filename = files.get_unique_filename(self.options.junit_file, self.testrun_index) self.junit_report = reports.JUnitReport(filename, self) handlers.append(self.junit_report) # instantiate MozMill profile_path = os.path.join(self.workspace, 'profile') self.mozlogger.info('Creating profile: %s' % profile_path) profile_args = dict(profile=profile_path, addons=self.addon_list, preferences=self.preferences, ) mozmill_args = dict(app=self.options.application, binary=self._application, handlers=handlers, profile_args=profile_args, ) if self.timeout: mozmill_args['jsbridge_timeout'] = self.timeout self._mozmill = mozmill.MozMill.create(**mozmill_args) self.graphics = None for listener in self.listeners: self._mozmill.add_listener(listener[0], eventType=listener[1]) self._mozmill.persisted.update(self.persisted) try: self._mozmill.run(tests, self.options.restart) finally: self.results = self._mozmill.finish() self.mozlogger.info('Removing profile: %s' % profile_path) mozfile.remove(profile_path) # Whenever a test fails it has to be marked, so we quit with the correct exit code self.last_failed_tests = self.last_failed_tests or self.results.fails self.testrun_index += 1
def main(args=sys.argv[1:]): # parse command line options usage = '%prog [options] manifest.ini <manifest.ini> <...>' parser = optparse.OptionParser(usage=usage, description=__doc__) parser.add_option('-b', "--binary", dest="binary", help="Binary path", metavar=None, default=None) parser.add_option('--list', dest='list_tests', action='store_true', default=False, help="list paths of tests to be run") options, args = parser.parse_args(args) # read the manifest if args: manifests = args else: manifests = [os.path.join(here, 'test-manifest.ini')] missing = [] for manifest in manifests: # ensure manifests exist if not os.path.exists(manifest): missing.append(manifest) assert not missing, 'manifest(s) not found: %s' % ', '.join(missing) manifest = manifestparser.TestManifest(manifests=manifests) if options.binary: # A specified binary should override the environment variable os.environ['BROWSER_PATH'] = options.binary # gather the tests tests = manifest.active_tests(disabled=False, **mozinfo.info) tests = [test['path'] for test in tests] if options.list_tests: # print test paths print '\n'.join(tests) sys.exit(0) # create unittests unittestlist = [] for test in tests: unittestlist.extend(unittests(test)) # run the tests suite = unittest.TestSuite(unittestlist) runner = unittest.TextTestRunner( verbosity=2, # default=1 does not show success of unittests resultclass=TBPLTextTestResult) unittest_results = runner.run(suite) results = TestResultCollection.from_unittest_results( None, unittest_results) # exit according to results sys.exit(1 if results.num_failures else 0)
def __init__(self, args): # event handler plugin names self.handlers = {} for handler_class in handlers.handlers(): name = getattr(handler_class, 'name', handler_class.__name__) self.handlers[name] = handler_class # add and parse options mozrunner.CLI.__init__(self, args) # read tests from manifests (if any) self.manifest = manifestparser.TestManifest(manifests=self.options.manifests, strict=False) # expand user directory and check existence for the test for test in self.options.tests: testpath = os.path.expanduser(test) realpath = os.path.realpath(testpath) if not os.path.exists(testpath): raise Exception("Not a valid test file/directory: %s" % test) # collect the tests def testname(t): if os.path.isdir(realpath): return os.path.join(test, os.path.relpath(t, testpath)) return test tests = [{'name': testname(t), 'path': t} for t in collect_tests(testpath)] self.manifest.tests.extend(tests) # list the tests and exit if specified if self.options.list_tests: for test in self.manifest.tests: print test['path'] self.parser.exit() # instantiate event handler plugins self.event_handlers = [] for name, handler_class in self.handlers.items(): if name in self.options.disable: continue handler = handlers.instantiate_handler(handler_class, self.options) if handler is not None: self.event_handlers.append(handler) for handler in self.options.handlers: # user handlers try: handler_class = handlers.load_handler(handler) except BaseException, e: self.parser.error(str(e)) _handler = handlers.instantiate_handler(handler_class, self.options) if _handler is not None: self.event_handlers.append(_handler)
def test_modules(self): manifest = manifestparser.TestManifest(manifests=[ os.path.join(os.path.dirname(os.path.abspath(__file__)), "js-tests", "restart_endtest", "tests.ini") ], strict=False) m = mozmill.MozMill.create() m.run(manifest.active_tests()) results = m.finish() # From the first test, there is one passing test self.assertEqual(len(results.passes), 3, "Passes should match") self.assertEqual(len(results.fails), 0, "Fails should match") self.assertEqual(len(results.skipped), 0, "Skips should match")
def extract_unittests_from_args(args, environ, manifest_path): """Extract unittests from args, expanding directories as needed""" mp = manifestparser.TestManifest(strict=True) tests = [] binary_path = None if manifest_path: mp.read(manifest_path) binary_path = os.path.abspath(args[0]) else: for p in args: if os.path.isdir(p): try: mp.read(os.path.join(p, "cppunittest.ini")) except IOError: files = [ os.path.abspath(os.path.join(p, x)) for x in os.listdir(p) ] tests.extend((f, 1) for f in files if os.access(f, os.R_OK | os.X_OK)) else: tests.append((os.path.abspath(p), 1)) # we skip the existence check here because not all tests are built # for all platforms (and it will fail on Windows anyway) active_tests = mp.active_tests(exists=False, disabled=False, **environ) suffix = ".exe" if mozinfo.isWin else "" if binary_path: tests.extend([( os.path.join(binary_path, test["relpath"] + suffix), int(test.get("requesttimeoutfactor", 1)), ) for test in active_tests]) else: tests.extend([(test["path"] + suffix, int(test.get("requesttimeoutfactor", 1))) for test in active_tests]) # skip and warn for any tests in the manifest that are not found final_tests = [] log = mozlog.get_default_logger() for test in tests: if os.path.isfile(test[0]): final_tests.append(test) else: log.warning("test file not found: %s - skipped" % test[0]) return final_tests
def do_test(self, relative_manifest_path, passes=0, fails=0, skips=0): manifestpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), relative_manifest_path) manifest = manifestparser.TestManifest(manifests=[manifestpath], strict=False) tests = manifest.active_tests() m = mozmill.MozMill.create() m.run(tests) results = m.finish(()) self.assertEqual(len(results.passes), passes, "Passes should match") self.assertEqual(len(results.fails), fails, "Fails should match") self.assertEqual(len(results.skipped), skips, "Skips should match") return results
def do_test(self, relative_manifest_path, passes=0, fails=0, skips=0): manifestpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), relative_manifest_path) manifest = manifestparser.TestManifest( manifests=[manifestpath], strict=False) tests = manifest.active_tests() runner_args = {'cmdargs': ['http://www.nbc.com']} m = mozmill.MozMill.create(runner_args=runner_args) m.run(tests) results = m.finish(()) # From the first test, there is one passing test self.assertEqual(len(results.passes), passes, "Passes should match") self.assertEqual(len(results.fails), fails, "Fails should match") self.assertEqual(len(results.skipped), skips, "Skips should match")
def buildTestList(self): """ read the xpcshell.ini manifest and set self.alltests to be an array of test objects. if we are chunking tests, it will be done here as well """ mp = manifestparser.TestManifest(strict=False) if self.manifest is None: for testdir in self.testdirs: if testdir: mp.read(os.path.join(testdir, 'xpcshell.ini')) else: mp.read(self.manifest) self.buildTestPath() self.alltests = mp.active_tests(**mozinfo.info) if self.singleFile is None and self.totalChunks > 1: self.chunkTests()
def __init__(self, *args, **kwargs): jsbridge.CLI.__init__(self, *args, **kwargs) self.mozmill = self.mozmill_class(runner_class=mozrunner.FirefoxRunner, profile_class=mozrunner.FirefoxProfile, jsbridge_port=int(self.options.port), jsbridge_timeout=self.options.timeout, ) self.tests = [] # read tests from manifests if self.options.manifests: manifest_parser = manifestparser.TestManifest(manifests=self.options.manifests) self.tests.extend(manifest_parser.test_paths()) # expand user directory for individual tests for test in self.options.test: test = os.path.expanduser(test) self.tests.append(test) # check existence for the tests missing = [ test for test in self.tests if not os.path.exists(test) ] if missing: raise IOError("Not a valid test file/directory: %s" % ', '.join(["'%s'" % test for test in missing])) # setup log formatting self.mozmill.add_global_listener(LoggerListener()) log_options = { 'format': "%(levelname)s | %(message)s", 'level': logging.CRITICAL } if self.options.showerrors: log_options['level'] = logging.ERROR if self.options.logfile: log_options['filename'] = self.options.logfile log_options['filemode'] = 'w' log_options['level'] = logging.DEBUG if self.options.test and self.options.showall: log_options['level'] = logging.DEBUG logging.basicConfig(**log_options)
def get_test_manifest(): return manifestparser.TestManifest( manifests=[os.path.join(TEST_DIR, 'manifest.ini')])
def main(): scriptdir = os.path.abspath(os.path.realpath(os.path.dirname(__file__))) auto = RemoteAutomation(None, "fennec") parser = RemoteOptions(auto, scriptdir) options, args = parser.parse_args() if (options.dm_trans == "adb"): if (options.deviceIP): dm = devicemanagerADB.DeviceManagerADB(options.deviceIP, options.devicePort) else: dm = devicemanagerADB.DeviceManagerADB() else: dm = devicemanagerSUT.DeviceManagerSUT(options.deviceIP, options.devicePort) auto.setDeviceManager(dm) options = parser.verifyRemoteOptions(options, auto) if (options == None): print "ERROR: Invalid options specified, use --help for a list of valid options" sys.exit(1) productPieces = options.remoteProductName.split('.') if (productPieces != None): auto.setProduct(productPieces[0]) else: auto.setProduct(options.remoteProductName) mochitest = MochiRemote(auto, dm, options) options = parser.verifyOptions(options, mochitest) if (options == None): sys.exit(1) logParent = os.path.dirname(options.remoteLogFile) dm.mkDir(logParent) auto.setRemoteLog(options.remoteLogFile) auto.setServerInfo(options.webServer, options.httpPort, options.sslPort) print dm.getInfo() procName = options.app.split('/')[-1] if (dm.processExist(procName)): dm.killProcess(procName) if options.robocop != "": mp = manifestparser.TestManifest(strict=False) # TODO: pull this in dynamically mp.read(options.robocop) robocop_tests = mp.active_tests(exists=False) deviceRoot = dm.getDeviceRoot() dm.removeFile(os.path.join(deviceRoot, "fennec_ids.txt")) fennec_ids = os.path.abspath("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('robocop.logfile="%s/robocop.log"' % deviceRoot) options.extraPrefs.append('browser.search.suggest.enabled=true') options.extraPrefs.append('browser.search.suggest.prompted=true') if (options.dm_trans == 'adb' and options.robocopPath): dm._checkCmd([ "install", "-r", os.path.join(options.robocopPath, "robocop.apk") ]) appname = options.app retVal = None for test in robocop_tests: if options.testPath and options.testPath != test['name']: continue options.app = "am" options.browserArgs = [ "instrument", "-w", "-e", "deviceroot", deviceRoot, "-e", "class" ] options.browserArgs.append("%s.tests.%s" % (appname, test['name'])) options.browserArgs.append( "org.mozilla.roboexample.test/%s.FennecInstrumentationTestRunner" % appname) try: dm.recordLogcat() result = mochitest.runTests(options) if result != 0: print "ERROR: runTests() exited with code %s" % result # Ensure earlier failures aren't overwritten by success on this run if retVal is None or retVal == 0: retVal = result mochitest.addLogData() except: print "Automation Error: Exception caught while running tests" traceback.print_exc() mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: mochitest.cleanup(None, options) except devicemanager.DMError: # device error cleaning up... oh well! pass retVal = 1 break if retVal is None: print "No tests run. Did you pass an invalid TEST_PATH?" retVal = 1 else: # if we didn't have some kind of error running the tests, make # sure the tests actually passed overallResult = mochitest.printLog() if retVal == 0: retVal = overallResult else: try: dm.recordLogcat() retVal = mochitest.runTests(options) except: print "Automation Error: Exception caught while running tests" traceback.print_exc() mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: mochitest.cleanup(None, options) except devicemanager.DMError: # device error cleaning up... oh well! pass retVal = 1 try: logcat = dm.getLogcat(filterOutRegexps=fennecLogcatFilters) print ''.join(logcat) print dm.getInfo() except devicemanager.DMError: print "WARNING: Error getting device information at end of test" sys.exit(retVal)
def main(): scriptdir = os.path.abspath(os.path.realpath(os.path.dirname(__file__))) auto = RemoteAutomation(None, "fennec") parser = RemoteOptions(auto, scriptdir) options, args = parser.parse_args() if (options.dm_trans == "adb"): if (options.deviceIP): dm = devicemanagerADB.DeviceManagerADB(options.deviceIP, options.devicePort) else: dm = devicemanagerADB.DeviceManagerADB() else: dm = devicemanagerSUT.DeviceManagerSUT(options.deviceIP, options.devicePort) auto.setDeviceManager(dm) options = parser.verifyRemoteOptions(options, auto) if (options == None): print "ERROR: Invalid options specified, use --help for a list of valid options" sys.exit(1) productPieces = options.remoteProductName.split('.') if (productPieces != None): auto.setProduct(productPieces[0]) else: auto.setProduct(options.remoteProductName) mochitest = MochiRemote(auto, dm, options) options = parser.verifyOptions(options, mochitest) if (options == None): sys.exit(1) logParent = os.path.dirname(options.remoteLogFile) dm.mkDir(logParent) auto.setRemoteLog(options.remoteLogFile) auto.setServerInfo(options.webServer, options.httpPort, options.sslPort) print dm.getInfo() procName = options.app.split('/')[-1] if (dm.processExist(procName)): dm.killProcess(procName) if options.robocop != "": mp = manifestparser.TestManifest(strict=False) # TODO: pull this in dynamically mp.read(options.robocop) robocop_tests = mp.active_tests(exists=False) fHandle = open("robotium.config", "w") fHandle.write("profile=%s\n" % (mochitest.remoteProfile)) fHandle.write("logfile=%s\n" % (options.remoteLogFile)) fHandle.write("host=http://mochi.test:8888/tests\n") fHandle.write("rawhost=http://%s:%s/tests\n" % (options.remoteWebServer, options.httpPort)) fHandle.close() deviceRoot = dm.getDeviceRoot() dm.removeFile(os.path.join(deviceRoot, "fennec_ids.txt")) dm.removeFile(os.path.join(deviceRoot, "robotium.config")) dm.pushFile("robotium.config", os.path.join(deviceRoot, "robotium.config")) fennec_ids = os.path.abspath("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('robocop.logfile="%s/robocop.log"' % deviceRoot) if (options.dm_trans == 'adb' and options.robocopPath): dm.checkCmd([ "install", "-r", os.path.join(options.robocopPath, "robocop.apk") ]) appname = options.app retVal = None logcat = [] for test in robocop_tests: if options.testPath and options.testPath != test['name']: continue options.app = "am" options.browserArgs = [ "instrument", "-w", "-e", "deviceroot", deviceRoot, "-e", "class" ] options.browserArgs.append("%s.tests.%s" % (appname, test['name'])) options.browserArgs.append( "org.mozilla.roboexample.test/%s.FennecInstrumentationTestRunner" % appname) try: dm.recordLogcat() retVal = mochitest.runTests(options) logcat = dm.getLogcat() mochitest.addLogData() except: print "TEST-UNEXPECTED-FAIL | %s | Exception caught while running robocop tests." % sys.exc_info( )[1] mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: self.cleanup(None, options) except: pass sys.exit(1) if retVal is None: print "No tests run. Did you pass an invalid TEST_PATH?" retVal = 1 retVal = mochitest.printLog() else: try: dm.recordLogcat() retVal = mochitest.runTests(options) logcat = dm.getLogcat() except: print "TEST-UNEXPECTED-FAIL | %s | Exception caught while running tests." % sys.exc_info( )[1] mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: self.cleanup(None, options) except: pass sys.exit(1) print ''.join(logcat[-500:-1]) print dm.getInfo() sys.exit(retVal)
def main(): scriptdir = os.path.abspath(os.path.realpath(os.path.dirname(__file__))) dm_none = devicemanagerADB.DeviceManagerADB() auto = RemoteAutomation(dm_none, "fennec") parser = RemoteOptions(auto, scriptdir) options, args = parser.parse_args() if (options.dm_trans == "adb"): if (options.deviceIP): dm = devicemanagerADB.DeviceManagerADB(options.deviceIP, options.devicePort) else: dm = dm_none else: dm = devicemanagerSUT.DeviceManagerSUT(options.deviceIP, options.devicePort) auto.setDeviceManager(dm) options = parser.verifyRemoteOptions(options, auto) if (options == None): print "ERROR: Invalid options specified, use --help for a list of valid options" sys.exit(1) productPieces = options.remoteProductName.split('.') if (productPieces != None): auto.setProduct(productPieces[0]) else: auto.setProduct(options.remoteProductName) mochitest = MochiRemote(auto, dm, options) options = parser.verifyOptions(options, mochitest) if (options == None): sys.exit(1) logParent = os.path.dirname(options.remoteLogFile) dm.mkDir(logParent) auto.setRemoteLog(options.remoteLogFile) auto.setServerInfo(options.webServer, options.httpPort, options.sslPort) procName = options.app.split('/')[-1] if (dm.processExist(procName)): dm.killProcess(procName) if options.robocop != "": mp = manifestparser.TestManifest(strict=False) # TODO: pull this in dynamically mp.read(options.robocop) robocop_tests = mp.active_tests(exists=False) fHandle = open("robotium.config", "w") fHandle.write("profile=%s\n" % (mochitest.remoteProfile)) fHandle.write("logfile=%s\n" % (options.remoteLogFile)) fHandle.close() deviceRoot = dm.getDeviceRoot() # Note, we are pushing to /sdcard since we have this location hard coded in robocop dm.removeFile("/sdcard/fennec_ids.txt") dm.removeFile("/sdcard/robotium.config") dm.pushFile("robotium.config", "/sdcard/robotium.config") fennec_ids = os.path.abspath("fennec_ids.txt") if not os.path.exists(fennec_ids) and options.robocopPath: fennec_ids = os.path.abspath( os.path.join(options.robocopPath, "fennec_ids.txt")) dm.pushFile(fennec_ids, "/sdcard/fennec_ids.txt") options.extraPrefs.append('robocop.logfile="%s/robocop.log"' % deviceRoot) if (options.dm_trans == 'adb' and options.robocopPath): dm.checkCmd([ "install", "-r", os.path.join(options.robocopPath, "robocop.apk") ]) appname = options.app for test in robocop_tests: if options.testPath and options.testPath != test['name']: continue options.app = "am" options.browserArgs = ["instrument", "-w", "-e", "class"] options.browserArgs.append("%s.tests.%s" % (appname, test['name'])) options.browserArgs.append( "org.mozilla.roboexample.test/android.test.InstrumentationTestRunner" ) try: retVal = mochitest.runTests(options) except: print "TEST-UNEXPECTED-ERROR | %s | Exception caught while running robocop tests." % sys.exc_info( )[1] mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: self.cleanup(None, options) except: pass sys.exit(1) else: try: retVal = mochitest.runTests(options) except: print "TEST-UNEXPECTED-ERROR | %s | Exception caught while running tests." % sys.exc_info( )[1] mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: self.cleanup(None, options) except: pass sys.exit(1) sys.exit(retVal)
def main(): message_logger = MessageLogger(logger=None) process_args = {'messageLogger': message_logger} auto = RemoteAutomation(None, "fennec", processArgs=process_args) parser = RemoteOptions(auto) structured.commandline.add_logging_group(parser) options, args = parser.parse_args() if (options.dm_trans == "adb"): if (options.deviceIP): dm = droid.DroidADB(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot) else: dm = droid.DroidADB(deviceRoot=options.remoteTestRoot) else: dm = droid.DroidSUT(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot) auto.setDeviceManager(dm) options = parser.verifyRemoteOptions(options, auto) mochitest = MochiRemote(auto, dm, options) log = mochitest.log structured_logger = mochitest.structured_logger message_logger.logger = mochitest.structured_logger mochitest.message_logger = message_logger if (options == None): log.error("Invalid options specified, use --help for a list of valid options") sys.exit(1) productPieces = options.remoteProductName.split('.') if (productPieces != None): auto.setProduct(productPieces[0]) else: auto.setProduct(options.remoteProductName) auto.setAppName(options.remoteappname) options = parser.verifyOptions(options, mochitest) if (options == None): sys.exit(1) logParent = os.path.dirname(options.remoteLogFile) dm.mkDir(logParent); auto.setRemoteLog(options.remoteLogFile) auto.setServerInfo(options.webServer, options.httpPort, options.sslPort) mochitest.printDeviceInfo() # Add Android version (SDK level) to mozinfo so that manifest entries # can be conditional on android_version. androidVersion = dm.shellCheckOutput(['getprop', 'ro.build.version.sdk']) log.info("Android sdk version '%s'; will use this to filter manifests" % str(androidVersion)) mozinfo.info['android_version'] = androidVersion deviceRoot = dm.deviceRoot if options.dmdPath: dmdLibrary = "libdmd.so" dmdPathOnDevice = os.path.join(deviceRoot, dmdLibrary) dm.removeFile(dmdPathOnDevice) dm.pushFile(os.path.join(options.dmdPath, dmdLibrary), dmdPathOnDevice) options.dmdPath = deviceRoot options.dumpOutputDirectory = deviceRoot procName = options.app.split('/')[-1] dm.killProcess(procName) if options.robocopIni != "": # turning buffering off as it's not used in robocop message_logger.buffering = False # sut may wait up to 300 s for a robocop am process before returning dm.default_timeout = 320 mp = manifestparser.TestManifest(strict=False) # TODO: pull this in dynamically mp.read(options.robocopIni) robocop_tests = mp.active_tests(exists=False, **mozinfo.info) tests = [] my_tests = tests for test in robocop_tests: tests.append(test['name']) if options.totalChunks: tests_per_chunk = math.ceil(len(tests) / (options.totalChunks * 1.0)) 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(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') options.extraPrefs.append('browser.casting.enabled=true') if (options.dm_trans == 'adb' and options.robocopApk): dm._checkCmd(["install", "-r", options.robocopApk]) retVal = None # Filtering tests active_tests = [] for test in robocop_tests: if options.testPath and options.testPath != test['name']: continue if not test['name'] in my_tests: continue if 'disabled' in test: log.info('TEST-INFO | skipping %s | %s' % (test['name'], test['disabled'])) continue active_tests.append(test) structured_logger.suite_start([t['name'] for t in active_tests]) for test in active_tests: # When running in a loop, we need to create a fresh profile for each cycle if mochitest.localProfile: options.profilePath = mochitest.localProfile os.system("rm -Rf %s" % options.profilePath) options.profilePath = None mochitest.localProfile = options.profilePath options.app = "am" options.browserArgs = ["instrument", "-w", "-e", "deviceroot", deviceRoot, "-e", "class"] options.browserArgs.append("org.mozilla.gecko.tests.%s" % test['name']) options.browserArgs.append("org.mozilla.roboexample.test/org.mozilla.gecko.FennecInstrumentationTestRunner") # If the test is for checking the import from bookmarks then make sure there is data to import if test['name'] == "testImportFromAndroid": # Get the OS so we can run the insert in the apropriate database and following the correct table schema osInfo = dm.getInfo("os") devOS = " ".join(osInfo['os']) if ("pandaboard" in devOS): delete = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db \'delete from bookmarks where _id > 14;\'"] else: delete = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db \'delete from bookmarks where _id > 14;\'"] if (options.dm_trans == "sut"): dm._runCmds([{"cmd": " ".join(delete)}]) # Insert the bookmarks log.info("Insert bookmarks in the default android browser database") for i in range(20): if ("pandaboard" in devOS): cmd = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db 'insert or replace into bookmarks(_id,title,url,folder,parent,position) values (" + str(30 + i) + ",\"Bookmark"+ str(i) + "\",\"http://www.bookmark" + str(i) + ".com\",0,1," + str(100 + i) + ");'"] else: cmd = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db 'insert into bookmarks(title,url,bookmark) values (\"Bookmark"+ str(i) + "\",\"http://www.bookmark" + str(i) + ".com\",1);'"] if (options.dm_trans == "sut"): dm._runCmds([{"cmd": " ".join(cmd)}]) try: screenShotDir = "/mnt/sdcard/Robotium-Screenshots" dm.removeDir(screenShotDir) dm.recordLogcat() result = mochitest.runTests(options) if result != 0: log.error("runTests() exited with code %s" % result) log_result = mochitest.addLogData() if result != 0 or log_result != 0: mochitest.printDeviceInfo(printLogcat=True) mochitest.printScreenshots(screenShotDir) # Ensure earlier failures aren't overwritten by success on this run if retVal is None or retVal == 0: retVal = result except: log.error("Automation Error: Exception caught while running tests") traceback.print_exc() mochitest.stopServers() try: mochitest.cleanup(options) except devicemanager.DMError: # device error cleaning up... oh well! pass retVal = 1 break finally: # Clean-up added bookmarks if test['name'] == "testImportFromAndroid": if ("pandaboard" in devOS): cmd_del = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db \'delete from bookmarks where _id > 14;\'"] else: cmd_del = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db \'delete from bookmarks where _id > 14;\'"] if (options.dm_trans == "sut"): dm._runCmds([{"cmd": " ".join(cmd_del)}]) if retVal is None: log.warning("No tests run. Did you pass an invalid TEST_PATH?") retVal = 1 else: # if we didn't have some kind of error running the tests, make # sure the tests actually passed print "INFO | runtests.py | Test summary: start." overallResult = mochitest.printLog() print "INFO | runtests.py | Test summary: end." if retVal == 0: retVal = overallResult else: try: dm.recordLogcat() retVal = mochitest.runTests(options) except: log.error("Automation Error: Exception caught while running tests") traceback.print_exc() mochitest.stopServers() try: mochitest.cleanup(options) except devicemanager.DMError: # device error cleaning up... oh well! pass retVal = 1 message_logger.finish() mochitest.printDeviceInfo(printLogcat=True) sys.exit(retVal)
def _process_test_manifest(self, sandbox, info, manifest_path): flavor, install_prefix, filter_inactive = info manifest_path = mozpath.normpath(manifest_path) path = mozpath.normpath(mozpath.join(sandbox['SRCDIR'], manifest_path)) manifest_dir = mozpath.dirname(path) manifest_reldir = mozpath.dirname( mozpath.relpath(path, sandbox['TOPSRCDIR'])) try: m = manifestparser.TestManifest(manifests=[path], strict=True) if not m.tests: raise SandboxValidationError('Empty test manifest: %s' % path) obj = TestManifest(sandbox, path, m, flavor=flavor, install_prefix=install_prefix, relpath=mozpath.join(manifest_reldir, mozpath.basename(path)), dupe_manifest='dupe-manifest' in m.tests[0]) filtered = m.tests if filter_inactive: filtered = m.active_tests(disabled=False, **self.mozinfo) out_dir = mozpath.join(install_prefix, manifest_reldir) # "head" and "tail" lists. # All manifests support support-files. # # Keep a set of already seen support file patterns, because # repeatedly processing the patterns from the default section # for every test is quite costly (see bug 922517). extras = (('head', set()), ('tail', set()), ('support-files', set())) for test in filtered: obj.tests.append(test) obj.installs[mozpath.normpath(test['path'])] = \ mozpath.join(out_dir, test['relpath']) for thing, seen in extras: value = test.get(thing, '') if value in seen: continue seen.add(value) for pattern in value.split(): # We only support globbing on support-files because # the harness doesn't support * for head and tail. if '*' in pattern and thing == 'support-files': obj.pattern_installs.append( (manifest_dir, pattern, out_dir)) else: full = mozpath.normpath( mozpath.join(manifest_dir, pattern)) # Only install paths in our directory. This # rule is somewhat arbitrary and could be lifted. if not full.startswith(manifest_dir): continue obj.installs[full] = mozpath.join(out_dir, pattern) # We also copy the manifest into the output directory. out_path = mozpath.join(out_dir, mozpath.basename(manifest_path)) obj.installs[path] = out_path # Some manifests reference files that are auto generated as # part of the build or shouldn't be installed for some # reason. Here, we prune those files from the install set. # FUTURE we should be able to detect autogenerated files from # other build metadata. Once we do that, we can get rid of this. for f in m.tests[0].get('generated-files', '').split(): # We re-raise otherwise the stack trace isn't informative. try: del obj.installs[mozpath.join(manifest_dir, f)] except KeyError: raise SandboxValidationError( 'Error processing test ' 'manifest %s: entry in generated-files not present ' 'elsewhere in manifest: %s' % (path, f)) obj.external_installs.add(mozpath.join(out_dir, f)) yield obj except (AssertionError, Exception): raise SandboxValidationError( 'Error processing test ' 'manifest file %s: %s' % (path, '\n'.join(traceback.format_exception(*sys.exc_info()))))
def read_manifestparser_manifest(context, manifest_path): path = mozpath.normpath(mozpath.join(context.srcdir, manifest_path)) return manifestparser.TestManifest(manifests=[path], strict=True, rootdir=context.config.topsrcdir, finder=context._finder)
def _process_test_manifest(self, context, info, manifest_path): flavor, install_root, install_subdir, package_tests = info manifest_path = mozpath.normpath(manifest_path) path = mozpath.normpath(mozpath.join(context.srcdir, manifest_path)) manifest_dir = mozpath.dirname(path) manifest_reldir = mozpath.dirname( mozpath.relpath(path, context.config.topsrcdir)) install_prefix = mozpath.join(install_root, install_subdir) try: m = manifestparser.TestManifest(manifests=[path], strict=True) defaults = m.manifest_defaults[os.path.normpath(path)] if not m.tests and not 'support-files' in defaults: raise SandboxValidationError('Empty test manifest: %s' % path, context) obj = TestManifest(context, path, m, flavor=flavor, install_prefix=install_prefix, relpath=mozpath.join(manifest_reldir, mozpath.basename(path)), dupe_manifest='dupe-manifest' in defaults) filtered = m.tests # Jetpack add-on tests are expected to be generated during the # build process so they won't exist here. if flavor != 'jetpack-addon': missing = [ t['name'] for t in filtered if not os.path.exists(t['path']) ] if missing: raise SandboxValidationError( 'Test manifest (%s) lists ' 'test that does not exist: %s' % (path, ', '.join(missing)), context) out_dir = mozpath.join(install_prefix, manifest_reldir) if 'install-to-subdir' in defaults: # This is terrible, but what are you going to do? out_dir = mozpath.join(out_dir, defaults['install-to-subdir']) obj.manifest_obj_relpath = mozpath.join( manifest_reldir, defaults['install-to-subdir'], mozpath.basename(path)) # "head" and "tail" lists. # All manifests support support-files. # # Keep a set of already seen support file patterns, because # repeatedly processing the patterns from the default section # for every test is quite costly (see bug 922517). extras = (('head', set()), ('tail', set()), ('support-files', set())) def process_support_files(test): for thing, seen in extras: value = test.get(thing, '') if value in seen: continue seen.add(value) for pattern in value.split(): # We only support globbing on support-files because # the harness doesn't support * for head and tail. if '*' in pattern and thing == 'support-files': obj.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))) obj.installs[full] = (mozpath.join( install_root, pattern[1:]), False) else: full = mozpath.normpath( mozpath.join(manifest_dir, pattern)) dest_path = mozpath.join(out_dir, pattern) # If the path resolves to a different directory # tree, we take special behavior depending on the # entry type. if not full.startswith(manifest_dir): # If it's a support file, we install the file # into the current destination directory. # This implementation makes installing things # with custom prefixes impossible. If this is # needed, we can add support for that via a # special syntax later. if thing == 'support-files': dest_path = mozpath.join( out_dir, os.path.basename(pattern)) # If it's not a support file, we ignore it. # This preserves old behavior so things like # head files doesn't get installed multiple # times. else: continue obj.installs[full] = (mozpath.normpath(dest_path), False) for test in filtered: obj.tests.append(test) # Some test files are compiled and should not be copied into the # test package. They function as identifiers rather than files. if package_tests: obj.installs[mozpath.normpath(test['path'])] = \ (mozpath.join(out_dir, test['relpath']), True) process_support_files(test) if not filtered: # If there are no tests, look for support-files under DEFAULT. process_support_files(defaults) # 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 # reason. Here, we prune those files from the install set. # FUTURE we should be able to detect autogenerated files from # other build metadata. Once we do that, we can get rid of this. for f in defaults.get('generated-files', '').split(): # We re-raise otherwise the stack trace isn't informative. try: del obj.installs[mozpath.join(manifest_dir, f)] except KeyError: raise SandboxValidationError( 'Error processing test ' 'manifest %s: entry in generated-files not present ' 'elsewhere in manifest: %s' % (path, f), context) obj.external_installs.add(mozpath.join(out_dir, f)) yield obj except (AssertionError, Exception): raise SandboxValidationError( 'Error processing test ' 'manifest file %s: %s' % (path, '\n'.join(traceback.format_exception(*sys.exc_info()))), context)
def main(): auto = RemoteAutomation(None, "fennec") parser = RemoteOptions(auto) options, args = parser.parse_args() if (options.dm_trans == "adb"): if (options.deviceIP): dm = droid.DroidADB(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot) else: dm = droid.DroidADB(deviceRoot=options.remoteTestRoot) else: dm = droid.DroidSUT(options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot) auto.setDeviceManager(dm) options = parser.verifyRemoteOptions(options, auto) if (options == None): print "ERROR: Invalid options specified, use --help for a list of valid options" sys.exit(1) productPieces = options.remoteProductName.split('.') if (productPieces != None): auto.setProduct(productPieces[0]) else: auto.setProduct(options.remoteProductName) mochitest = MochiRemote(auto, dm, options) options = parser.verifyOptions(options, mochitest) if (options == None): sys.exit(1) logParent = os.path.dirname(options.remoteLogFile) dm.mkDir(logParent); auto.setRemoteLog(options.remoteLogFile) auto.setServerInfo(options.webServer, options.httpPort, options.sslPort) mochitest.printDeviceInfo() procName = options.app.split('/')[-1] if (dm.processExist(procName)): dm.killProcess(procName) if options.robocopIni != "": # sut may wait up to 300 s for a robocop am process before returning dm.default_timeout = 320 mp = manifestparser.TestManifest(strict=False) # TODO: pull this in dynamically mp.read(options.robocopIni) robocop_tests = mp.active_tests(exists=False) tests = [] my_tests = tests for test in robocop_tests: tests.append(test['name']) if options.totalChunks: tests_per_chunk = math.ceil(len(tests) / (options.totalChunks * 1.0)) 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] print "Running tests %d-%d/%d" % ((start+1), end, len(tests)) deviceRoot = dm.getDeviceRoot() dm.removeFile(os.path.join(deviceRoot, "fennec_ids.txt")) fennec_ids = os.path.abspath("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('robocop.logfile="%s/robocop.log"' % deviceRoot) 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') if (options.dm_trans == 'adb' and options.robocopApk): dm._checkCmd(["install", "-r", options.robocopApk]) retVal = None for test in robocop_tests: if options.testPath and options.testPath != test['name']: continue if not test['name'] in my_tests: continue # When running in a loop, we need to create a fresh profile for each cycle if mochitest.localProfile: options.profilePath = mochitest.localProfile os.system("rm -Rf %s" % options.profilePath) options.profilePath = tempfile.mkdtemp() mochitest.localProfile = options.profilePath options.app = "am" options.browserArgs = ["instrument", "-w", "-e", "deviceroot", deviceRoot, "-e", "class"] options.browserArgs.append("%s.tests.%s" % (options.remoteappname, test['name'])) options.browserArgs.append("org.mozilla.roboexample.test/%s.FennecInstrumentationTestRunner" % options.remoteappname) # If the test is for checking the import from bookmarks then make sure there is data to import if test['name'] == "testImportFromAndroid": # Get the OS so we can run the insert in the apropriate database and following the correct table schema osInfo = dm.getInfo("os") devOS = " ".join(osInfo['os']) if ("pandaboard" in devOS): delete = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db \'delete from bookmarks where _id > 14;\'"] else: delete = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db \'delete from bookmarks where _id > 14;\'"] if (options.dm_trans == "sut"): dm._runCmds([{"cmd": " ".join(delete)}]) # Insert the bookmarks print "Insert bookmarks in the default android browser database" for i in range(20): if ("pandaboard" in devOS): cmd = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db 'insert or replace into bookmarks(_id,title,url,folder,parent,position) values (" + str(30 + i) + ",\"Bookmark"+ str(i) + "\",\"http://www.bookmark" + str(i) + ".com\",0,1," + str(100 + i) + ");'"] else: cmd = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db 'insert into bookmarks(title,url,bookmark) values (\"Bookmark"+ str(i) + "\",\"http://www.bookmark" + str(i) + ".com\",1);'"] if (options.dm_trans == "sut"): dm._runCmds([{"cmd": " ".join(cmd)}]) try: dm.removeDir("/mnt/sdcard/Robotium-Screenshots") dm.recordLogcat() result = mochitest.runTests(options) if result != 0: print "ERROR: runTests() exited with code %s" % result log_result = mochitest.addLogData() if result != 0 or log_result != 0: mochitest.printDeviceInfo(printLogcat=True) mochitest.printScreenshot() # Ensure earlier failures aren't overwritten by success on this run if retVal is None or retVal == 0: retVal = result except: print "Automation Error: Exception caught while running tests" traceback.print_exc() mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: mochitest.cleanup(None, options) except devicemanager.DMError: # device error cleaning up... oh well! pass retVal = 1 break finally: # Clean-up added bookmarks if test['name'] == "testImportFromAndroid": if ("pandaboard" in devOS): cmd_del = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser2.db \'delete from bookmarks where _id > 14;\'"] else: cmd_del = ['execsu', 'sqlite3', "/data/data/com.android.browser/databases/browser.db \'delete from bookmarks where _id > 14;\'"] if (options.dm_trans == "sut"): dm._runCmds([{"cmd": " ".join(cmd_del)}]) if retVal is None: print "No tests run. Did you pass an invalid TEST_PATH?" retVal = 1 else: # if we didn't have some kind of error running the tests, make # sure the tests actually passed print "INFO | runtests.py | Test summary: start." overallResult = mochitest.printLog() print "INFO | runtests.py | Test summary: end." if retVal == 0: retVal = overallResult else: try: dm.recordLogcat() retVal = mochitest.runTests(options) except: print "Automation Error: Exception caught while running tests" traceback.print_exc() mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: mochitest.cleanup(None, options) except devicemanager.DMError: # device error cleaning up... oh well! pass retVal = 1 mochitest.printDeviceInfo(printLogcat=True) sys.exit(retVal)
def _process_test_manifest(self, sandbox, info, manifest_path): flavor, install_prefix, filter_inactive = info manifest_path = os.path.normpath(manifest_path) path = mozpath.normpath(mozpath.join(sandbox['SRCDIR'], manifest_path)) manifest_dir = mozpath.dirname(path) manifest_reldir = mozpath.dirname( mozpath.relpath(path, self.config.topsrcdir)) try: m = manifestparser.TestManifest(manifests=[path], strict=True) if not m.tests: raise SandboxValidationError('Empty test manifest: %s' % path) obj = TestManifest(sandbox, path, m, flavor=flavor, install_prefix=install_prefix, relpath=mozpath.join(manifest_reldir, mozpath.basename(path)), dupe_manifest='dupe-manifest' in m.tests[0]) filtered = m.tests if filter_inactive: filtered = m.active_tests(**self.mozinfo) out_dir = mozpath.join(install_prefix, manifest_reldir) finder = FileFinder(base=manifest_dir, find_executables=False) for test in filtered: obj.installs[mozpath.normpath(test['path'])] = \ mozpath.join(out_dir, test['relpath']) # xpcshell defines extra files to install in the # "head" and "tail" lists. # All manifests support support-files. for thing in ('head', 'tail', 'support-files'): for pattern in test.get(thing, '').split(): # We only support globbing on support-files because # the harness doesn't support * for head and tail. # # While we could feed everything through the finder, we # don't because we want explicitly listed files that # no longer exist to raise an error. The finder is also # slower than simple lookup. if '*' in pattern and thing == 'support-files': paths = [f[0] for f in finder.find(pattern)] if not paths: raise SandboxValidationError( '%s support-files ' 'wildcard in %s returns no results.' % (pattern, path)) for f in paths: full = mozpath.normpath( mozpath.join(manifest_dir, f)) obj.installs[full] = mozpath.join(out_dir, f) else: full = mozpath.normpath( mozpath.join(manifest_dir, pattern)) # Only install paths in our directory. This # rule is somewhat arbitrary and could be lifted. if not full.startswith(manifest_dir): continue obj.installs[full] = mozpath.join(out_dir, pattern) # We also copy the manifest into the output directory. out_path = mozpath.join(out_dir, os.path.basename(manifest_path)) obj.installs[path] = out_path # Some manifests reference files that are auto generated as # part of the build or shouldn't be installed for some # reason. Here, we prune those files from the install set. # FUTURE we should be able to detect autogenerated files from # other build metadata. Once we do that, we can get rid of this. for f in m.tests[0].get('generated-files', '').split(): # We re-raise otherwise the stack trace isn't informative. try: del obj.installs[mozpath.join(manifest_dir, f)] except KeyError: raise SandboxValidationError( 'Error processing test ' 'manifest %s: entry in generated-files not present ' 'elsewhere in manifest: %s' % (path, f)) obj.external_installs.add(mozpath.join(out_dir, f)) yield obj except (AssertionError, Exception): raise SandboxValidationError( 'Error processing test ' 'manifest file %s: %s' % (path, '\n'.join(traceback.format_exception(*sys.exc_info()))))
def main(): scriptdir = os.path.abspath(os.path.realpath(os.path.dirname(__file__))) auto = RemoteAutomation(None, "fennec") parser = RemoteOptions(auto, scriptdir) options, args = parser.parse_args() if (options.dm_trans == "adb"): if (options.deviceIP): dm = devicemanagerADB.DeviceManagerADB( options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot) else: dm = devicemanagerADB.DeviceManagerADB( deviceRoot=options.remoteTestRoot) else: dm = devicemanagerSUT.DeviceManagerSUT( options.deviceIP, options.devicePort, deviceRoot=options.remoteTestRoot) auto.setDeviceManager(dm) options = parser.verifyRemoteOptions(options, auto) if (options == None): print "ERROR: Invalid options specified, use --help for a list of valid options" sys.exit(1) productPieces = options.remoteProductName.split('.') if (productPieces != None): auto.setProduct(productPieces[0]) else: auto.setProduct(options.remoteProductName) mochitest = MochiRemote(auto, dm, options) options = parser.verifyOptions(options, mochitest) if (options == None): sys.exit(1) logParent = os.path.dirname(options.remoteLogFile) dm.mkDir(logParent) auto.setRemoteLog(options.remoteLogFile) auto.setServerInfo(options.webServer, options.httpPort, options.sslPort) print dm.getInfo() procName = options.app.split('/')[-1] if (dm.processExist(procName)): dm.killProcess(procName) if options.robocop != "": # sut may wait up to 300 s for a robocop am process before returning dm.default_timeout = 320 mp = manifestparser.TestManifest(strict=False) # TODO: pull this in dynamically mp.read(options.robocop) robocop_tests = mp.active_tests(exists=False) tests = [] my_tests = tests for test in robocop_tests: tests.append(test['name']) if options.totalChunks: tests_per_chunk = math.ceil( len(tests) / (options.totalChunks * 1.0)) 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] print "Running tests %d-%d/%d" % ((start + 1), end, len(tests)) deviceRoot = dm.getDeviceRoot() dm.removeFile(os.path.join(deviceRoot, "fennec_ids.txt")) fennec_ids = os.path.abspath("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('robocop.logfile="%s/robocop.log"' % deviceRoot) options.extraPrefs.append('browser.search.suggest.enabled=true') options.extraPrefs.append('browser.search.suggest.prompted=true') options.extraPrefs.append('browser.viewport.scaleRatio=100') options.extraPrefs.append('browser.chrome.dynamictoolbar=false') if (options.dm_trans == 'adb' and options.robocopPath): dm._checkCmd([ "install", "-r", os.path.join(options.robocopPath, "robocop.apk") ]) retVal = None for test in robocop_tests: if options.testPath and options.testPath != test['name']: continue if not test['name'] in my_tests: continue options.app = "am" options.browserArgs = [ "instrument", "-w", "-e", "deviceroot", deviceRoot, "-e", "class" ] options.browserArgs.append("%s.tests.%s" % (options.remoteappname, test['name'])) options.browserArgs.append( "org.mozilla.roboexample.test/%s.FennecInstrumentationTestRunner" % options.remoteappname) try: dm.removeDir("/mnt/sdcard/Robotium-Screenshots") dm.recordLogcat() result = mochitest.runTests(options) if result != 0: print "ERROR: runTests() exited with code %s" % result log_result = mochitest.addLogData() if result != 0 or log_result != 0: mochitest.printDeviceInfo() mochitest.printScreenshot() # Ensure earlier failures aren't overwritten by success on this run if retVal is None or retVal == 0: retVal = result except: print "Automation Error: Exception caught while running tests" traceback.print_exc() mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: mochitest.cleanup(None, options) except devicemanager.DMError: # device error cleaning up... oh well! pass retVal = 1 break if retVal is None: print "No tests run. Did you pass an invalid TEST_PATH?" retVal = 1 else: # if we didn't have some kind of error running the tests, make # sure the tests actually passed print "INFO | runtests.py | Test summary: start." overallResult = mochitest.printLog() print "INFO | runtests.py | Test summary: end." if retVal == 0: retVal = overallResult else: try: dm.recordLogcat() retVal = mochitest.runTests(options) except: print "Automation Error: Exception caught while running tests" traceback.print_exc() mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) try: mochitest.cleanup(None, options) except devicemanager.DMError: # device error cleaning up... oh well! pass retVal = 1 mochitest.printDeviceInfo() sys.exit(retVal)
def run(self): # read tests from manifests if self.options.manifests: manifest_parser = manifestparser.TestManifest( manifests=self.options.manifests) self.tests.extend(manifest_parser.test_paths()) # expand user directory for individual tests for test in self.options.test: test = os.path.expanduser(test) self.tests.append(test) # check existence for the tests missing = [test for test in self.tests if not os.path.exists(test)] if missing: raise IOError("Not a valid test file/directory: %s" % ', '.join(["'%s'" % test for test in missing])) # create a Mozrunner runner = self.create_runner() runner.cmdargs.extend(self.options.appArgs) # make sure the application starts in the foreground if '-foreground' not in runner.cmdargs: runner.cmdargs.append('-foreground') try: self.mozmill.start(runner=runner, profile=runner.profile) except: runner.cleanup() raise if self.tests: # run the tests disconnected = False try: self.mozmill.run_tests(self.tests) except JSBridgeDisconnectError: disconnected = True if not self.mozmill.userShutdownEnabled: self.mozmill.report_disconnect() print 'TEST-UNEXPECTED-FAIL | Disconnect Error: Application unexpectedly closed' runner.cleanup() except: runner.cleanup() raise # shutdown the test harness self.mozmill.stop(fatal=disconnected) # print statistics and send the JSON report self.mozmill.report(self.options.report) if self.mozmill.fails or disconnected: sys.exit(1) else: if self.options.shell: self.start_shell(runner) else: try: if not hasattr(runner, 'process_handler'): runner.start() runner.wait() except KeyboardInterrupt: runner.stop() if self.mozmill.runner is not None: self.mozmill.runner.cleanup()