def test_server_locations_callback(self): class CallbackTest(object): last_locations = None def callback(self, locations): self.last_locations = locations c = CallbackTest() f = self.create_temp_file(self.locations) locations = ServerLocations(f.name, c.callback) # callback should be for all locations in file self.assertEqual(len(c.last_locations), 6) # validate arbitrary one self.compare_location(c.last_locations[2], 'http', '127.0.0.1', '8888', ['privileged']) locations.add_host('a.b.c') # callback should be just for one location self.assertEqual(len(c.last_locations), 1) self.compare_location(c.last_locations[0], 'http', 'a.b.c', '80', ['privileged']) # read a second file, which should generate a callback with both # locations. f = self.create_temp_file(self.locations_no_primary) locations.read(f.name) self.assertEqual(len(c.last_locations), 2)
def test_server_locations(self): # write a permissions file f = self.create_temp_file(self.locations) # read the locations locations = ServerLocations(f.name) # ensure that they're what we expect self.assertEqual(len(locations), 6) i = iter(locations) self.compare_location(i.next(), 'http', 'mochi.test', '8888', ['primary', 'privileged']) self.compare_location(i.next(), 'http', '127.0.0.1', '80', ['privileged']) self.compare_location(i.next(), 'http', '127.0.0.1', '8888', ['privileged']) self.compare_location(i.next(), 'https', 'test', '80', ['privileged']) self.compare_location(i.next(), 'http', 'example.org', '80', ['privileged']) self.compare_location(i.next(), 'http', 'test1.example.org', '8888', ['privileged']) locations.add_host('mozilla.org') self.assertEqual(len(locations), 7) self.compare_location(i.next(), 'http', 'mozilla.org', '80', ['privileged']) # test some errors self.assertRaises(MultiplePrimaryLocationsError, locations.add_host, 'primary.test', options='primary') # We no longer throw these DuplicateLocation Error try: locations.add_host('127.0.0.1') except DuplicateLocationError: self.assertTrue(False, "Should no longer throw DuplicateLocationError") self.assertRaises(BadPortLocationError, locations.add_host, '127.0.0.1', port='abc') # test some errors in locations file f = self.create_temp_file(self.locations_no_primary) exc = None try: ServerLocations(f.name) except LocationsSyntaxError, e: exc = e
def start(self): self.marionette_port = get_free_port(2828, exclude=self.used_ports) env = os.environ.copy() env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1" locations = ServerLocations(filename=os.path.join(here, "server-locations.txt")) preferences = self.load_prefs() self.profile = FirefoxProfile(locations=locations, preferences=preferences) self.profile.set_preferences({"marionette.defaultPrefs.enabled": True, "marionette.defaultPrefs.port": self.marionette_port, "dom.disable_open_during_load": False, "network.dns.localDomains": ",".join(hostnames)}) if self.ca_certificate_path is not None: self.setup_ssl() debug_args, cmd = browser_command(self.binary, [cmd_arg("marionette"), "about:blank"], self.debug_info) self.runner = FirefoxRunner(profile=self.profile, binary=cmd[0], cmdargs=cmd[1:], env=env, process_class=ProcessHandler, process_args={"processOutputLine": [self.on_output]}) self.logger.debug("Starting Firefox") self.runner.start(debug_args=debug_args, interactive=self.debug_info and self.debug_info.interactive) self.logger.debug("Firefox Started")
def start(self): self.marionette_port = get_free_port(2828, exclude=self.used_ports) env = os.environ.copy() env["MOZ_CRASHREPORTER"] = "1" env["MOZ_CRASHREPORTER_SHUTDOWN"] = "1" env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1" locations = ServerLocations( filename=os.path.join(here, "server-locations.txt")) preferences = self.load_prefs() self.profile = FirefoxProfile(locations=locations, proxy=True, preferences=preferences) self.profile.set_preferences({ "marionette.defaultPrefs.enabled": True, "marionette.defaultPrefs.port": self.marionette_port, "dom.disable_open_during_load": False }) self.runner = FirefoxRunner( profile=self.profile, binary=self.binary, cmdargs=[cmd_arg("marionette"), "about:blank"], env=env, process_class=ProcessHandler, process_args={"processOutputLine": [self.on_output]}) self.logger.debug("Starting Firefox") self.runner.start(debug_args=self.debug_args, interactive=self.interactive) self.logger.debug("Firefox Started")
def writeCertspecForServerLocations(fd): locations = ServerLocations( os.path.join(build.topsrcdir, "build", "pgo", "server-locations.txt")) SAN = [] for loc in [ i for i in iter(locations) if i.scheme == "https" and "nocert" not in i.options ]: customCertOption = False customCertRE = re.compile("^cert=(?:\w+)") for _ in [i for i in loc.options if customCertRE.match(i)]: customCertOption = True break if "ipV4Address" in loc.options: loc.host = "ip4:" + loc.host if not customCertOption: SAN.append(loc.host) fd.write( "issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization\n" ) # NOQA: E501 fd.write("subject:{}\n".format(SAN[0])) fd.write("extension:subjectAlternativeName:{}\n".format(",".join(SAN)))
def start(self): self.marionette_port = get_free_port(2828, exclude=self.used_ports) self.used_ports.add(self.marionette_port) env = os.environ.copy() env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1" locations = ServerLocations( filename=os.path.join(here, "server-locations.txt")) preferences = self.load_prefs() self.profile = FirefoxProfile(locations=locations, preferences=preferences) self.profile.set_preferences({ "marionette.enabled": True, "marionette.port": self.marionette_port, "dom.disable_open_during_load": False, "network.dns.localDomains": ",".join(hostnames), "network.proxy.type": 0, "places.history.enabled": False }) if self.e10s: self.profile.set_preferences( {"browser.tabs.remote.autostart": True}) # Bug 1262954: winxp + e10s, disable hwaccel if (self.e10s and platform.system() in ("Windows", "Microsoft") and '5.1' in platform.version()): self.profile.set_preferences( {"layers.acceleration.disabled": True}) if self.ca_certificate_path is not None: self.setup_ssl() debug_args, cmd = browser_command( self.binary, [cmd_arg("marionette"), "about:blank"], self.debug_info) self.runner = FirefoxRunner( profile=self.profile, binary=cmd[0], cmdargs=cmd[1:], env=env, process_class=ProcessHandler, process_args={"processOutputLine": [self.on_output]}) self.logger.debug("Starting Firefox") self.runner.start(debug_args=debug_args, interactive=self.debug_info and self.debug_info.interactive) self.logger.debug("Firefox Started")
def test_server_locations_callback(create_temp_file): class CallbackTest(object): last_locations = None def callback(self, locations): self.last_locations = locations c = CallbackTest() f = create_temp_file(LOCATIONS) locations = ServerLocations(f, c.callback) # callback should be for all locations in file assert len(c.last_locations) == 6 # validate arbitrary one compare_location(c.last_locations[2], 'http', '127.0.0.1', '8888', ['privileged']) locations.add_host('a.b.c') # callback should be just for one location assert len(c.last_locations) == 1 compare_location(c.last_locations[0], 'http', 'a.b.c', '80', ['privileged']) # read a second file, which should generate a callback with both # locations. f = create_temp_file(LOCATIONS_NO_PRIMARY) locations.read(f) assert len(c.last_locations) == 2
def test_server_locations(self): # write a permissions file f = self.create_temp_file(self.locations) # read the locations locations = ServerLocations(f.name) # ensure that they're what we expect self.assertEqual(len(locations), 6) i = iter(locations) self.compare_location(i.next(), 'http', 'mochi.test', '8888', ['primary', 'privileged']) self.compare_location(i.next(), 'http', '127.0.0.1', '80', ['privileged']) self.compare_location(i.next(), 'http', '127.0.0.1', '8888', ['privileged']) self.compare_location(i.next(), 'https', 'test', '80', ['privileged']) self.compare_location(i.next(), 'http', 'example.org', '80', ['privileged']) self.compare_location(i.next(), 'http', 'test1.example.org', '80', ['privileged']) locations.add_host('mozilla.org') self.assertEqual(len(locations), 7) self.compare_location(i.next(), 'http', 'mozilla.org', '80', ['privileged']) # test some errors self.assertRaises(MultiplePrimaryLocationsError, locations.add_host, 'primary.test', options='primary') # We no longer throw these DuplicateLocation Error try: locations.add_host('127.0.0.1') except DuplicateLocationError: self.assertTrue(False, "Should no longer throw DuplicateLocationError") self.assertRaises(BadPortLocationError, locations.add_host, '127.0.0.1', port='abc') # test some errors in locations file f = self.create_temp_file(self.locations_no_primary) exc = None try: ServerLocations(f.name) except LocationsSyntaxError, e: exc = e
def valgrind_test(self, suppressions): from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath from six import string_types from valgrind.output_handler import OutputHandler build_dir = os.path.join(self.topsrcdir, 'build') # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, 'pgo')) httpd.start(block=False) with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile profile_data_dir = os.path.join(self.topsrcdir, 'testing', 'profiles') with open(os.path.join(profile_data_dir, 'profiles.json'), 'r') as fh: base_profiles = json.load(fh)['valgrind'] prefpaths = [ os.path.join(profile_data_dir, profile, 'user.js') for profile in base_profiles ] prefs = {} for path in prefpaths: prefs.update(Preferences.read_prefs(path)) interpolation = { 'server': '%s:%d' % httpd.httpd.server_address, } for k, v in prefs.items(): if isinstance(v, string_types): v = v.format(**interpolation) prefs[k] = Preferences.cast(v) quitter = os.path.join(self.topsrcdir, 'tools', 'quitter', '*****@*****.**') locations = ServerLocations() locations.add_host(host='127.0.0.1', port=httpd.httpd.server_port, options='primary') profile = FirefoxProfile(profile=profilePath, preferences=prefs, addons=[quitter], locations=locations) firefox_args = [httpd.get_url()] env = os.environ.copy() env['G_SLICE'] = 'always-malloc' env['MOZ_CC_RUN_DURING_SHUTDOWN'] = '1' env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1' env['XPCOM_DEBUG_BREAK'] = 'warn' env.update(self.extra_environment_variables) outputHandler = OutputHandler(self.log) kp_kwargs = {'processOutputLine': [outputHandler]} valgrind = 'valgrind' if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, '--sym-offsets=yes', '--smc-check=all-non-file', '--vex-iropt-register-updates=allregs-at-mem-access', '--gen-suppressions=all', '--num-callers=36', '--leak-check=full', '--show-possibly-lost=no', '--track-origins=yes', '--trace-children=yes', '-v', # Enable verbosity to get the list of used suppressions # Avoid excessive delays in the presence of spinlocks. # See bug 1309851. '--fair-sched=yes', # Keep debuginfo after library unmap. See bug 1382280. '--keep-debuginfo=yes', # Reduce noise level on rustc and/or LLVM compiled code. # See bug 1365915 '--expensive-definedness-checks=yes', ] for s in suppressions: valgrind_args.append('--suppressions=' + s) supps_dir = os.path.join(build_dir, 'valgrind') supps_file1 = os.path.join(supps_dir, 'cross-architecture.sup') valgrind_args.append('--suppressions=' + supps_file1) if mozinfo.os == 'linux': machtype = { 'x86_64': 'x86_64-pc-linux-gnu', 'x86': 'i386-pc-linux-gnu', }.get(mozinfo.processor) if machtype: supps_file2 = os.path.join(supps_dir, machtype + '.sup') if os.path.isfile(supps_file2): valgrind_args.append('--suppressions=' + supps_file2) exitcode = None timeout = 1800 try: runner = FirefoxRunner(profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, process_args=kp_kwargs) runner.start(debug_args=valgrind_args) exitcode = runner.wait(timeout=timeout) finally: errs = outputHandler.error_count supps = outputHandler.suppression_count if errs != supps: status = 1 # turns the TBPL job orange self.log( logging.ERROR, 'valgrind-fail-parsing', { 'errs': errs, 'supps': supps }, 'TEST-UNEXPECTED-FAIL | valgrind-test | error parsing: {errs} errors ' 'seen, but {supps} generated suppressions seen') elif errs == 0: status = 0 self.log( logging.INFO, 'valgrind-pass', {}, 'TEST-PASS | valgrind-test | valgrind found no errors') else: status = 1 # turns the TBPL job orange # We've already printed details of the errors. if exitcode is None: status = 2 # turns the TBPL job red self.log( logging.ERROR, 'valgrind-fail-timeout', {'timeout': timeout}, 'TEST-UNEXPECTED-FAIL | valgrind-test | Valgrind timed out ' '(reached {timeout} second limit)') elif exitcode != 0: status = 2 # turns the TBPL job red self.log( logging.ERROR, 'valgrind-fail-errors', {'exitcode': exitcode}, 'TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code ' 'from Valgrind: {exitcode}') httpd.stop() return status
def test_server_locations(create_temp_file): # write a permissions file f = create_temp_file(LOCATIONS) # read the locations locations = ServerLocations(f) # ensure that they're what we expect assert len(locations) == 6 i = iter(locations) compare_location(next(i), 'http', 'mochi.test', '8888', ['primary', 'privileged']) compare_location(next(i), 'http', '127.0.0.1', '80', ['privileged']) compare_location(next(i), 'http', '127.0.0.1', '8888', ['privileged']) compare_location(next(i), 'https', 'test', '80', ['privileged']) compare_location(next(i), 'http', 'example.org', '80', ['privileged']) compare_location(next(i), 'http', 'test1.example.org', '8888', ['privileged']) locations.add_host('mozilla.org') assert len(locations) == 7 compare_location(next(i), 'http', 'mozilla.org', '80', ['privileged']) # test some errors with pytest.raises(MultiplePrimaryLocationsError): locations.add_host('primary.test', options='primary') # assert we don't throw DuplicateLocationError locations.add_host('127.0.0.1') with pytest.raises(BadPortLocationError): locations.add_host('127.0.0.1', port='abc') # test some errors in locations file f = create_temp_file(LOCATIONS_NO_PRIMARY) exc = None try: ServerLocations(f) except LocationsSyntaxError as e: exc = e assert exc is not None assert exc.err.__class__ == MissingPrimaryLocationError assert exc.lineno == 3 # test bad port in a locations file to ensure lineno calculated # properly. f = create_temp_file(LOCATIONS_BAD_PORT) exc = None try: ServerLocations(f) except LocationsSyntaxError as e: exc = e assert exc is not None assert exc.err.__class__ == BadPortLocationError assert exc.lineno == 4
def test_server_locations(create_temp_file): # write a permissions file f = create_temp_file(LOCATIONS) # read the locations locations = ServerLocations(f) # ensure that they're what we expect assert len(locations) == 6 i = iter(locations) compare_location(next(i), "http", "mochi.test", "8888", ["primary", "privileged"]) compare_location(next(i), "http", "127.0.0.1", "80", ["privileged"]) compare_location(next(i), "http", "127.0.0.1", "8888", ["privileged"]) compare_location(next(i), "https", "test", "80", ["privileged"]) compare_location(next(i), "http", "example.org", "80", ["privileged"]) compare_location(next(i), "http", "test1.example.org", "8888", ["privileged"]) locations.add_host("mozilla.org") assert len(locations) == 7 compare_location(next(i), "http", "mozilla.org", "80", ["privileged"]) # test some errors with pytest.raises(MultiplePrimaryLocationsError): locations.add_host("primary.test", options="primary") # assert we don't throw DuplicateLocationError locations.add_host("127.0.0.1") with pytest.raises(BadPortLocationError): locations.add_host("127.0.0.1", port="abc") # test some errors in locations file f = create_temp_file(LOCATIONS_NO_PRIMARY) exc = None try: ServerLocations(f) except LocationsSyntaxError as e: exc = e assert exc is not None assert exc.err.__class__ == MissingPrimaryLocationError assert exc.lineno == 3 # test bad port in a locations file to ensure lineno calculated # properly. f = create_temp_file(LOCATIONS_BAD_PORT) exc = None try: ServerLocations(f) except LocationsSyntaxError as e: exc = e assert exc is not None assert exc.err.__class__ == BadPortLocationError assert exc.lineno == 4
def __init__(self, options, **kwargs): self.options = options self.server = None self.logger = mozlog.getLogger("PEP") # create the profile enable_proxy = False locations = ServerLocations() if self.options.proxyLocations: if not self.options.serverPath: self.logger.warning("Can't set up proxy without server path") else: enable_proxy = True locations.read(self.options.proxyLocations, False) locations.add_host(host="127.0.0.1", port=self.options.serverPort, options="primary,privileged") self.profile = self.profile_class( profile=self.options.profilePath, addons=[os.path.join(here, "extension")], locations=locations, proxy=enable_proxy, ) # fork a server to serve the test related files if self.options.serverPath: self.runServer() tests = [] # TODO is there a better way of doing this? if self.options.testPath.endswith(".js"): # a single test file was passed in testObj = {} testObj["path"] = os.path.realpath(self.options.testPath) testObj["name"] = os.path.basename(self.options.testPath) testObj["here"] = os.path.dirname(testObj["path"]) tests.append(testObj) else: # a test manifest was passed in # open and convert the manifest to json manifest = TestManifest() manifest.read(self.options.testPath) tests = manifest.get() # create a manifest object to be read by the JS side manifestObj = {} manifestObj["tests"] = tests manifestObj["options"] = options.__dict__ # write manifest to a JSON file jsonManifest = open(os.path.join(here, "manifest.json"), "w") jsonManifest.write(json.dumps(manifestObj)) jsonManifest.close() # setup environment env = os.environ.copy() env["MOZ_INSTRUMENT_EVENT_LOOP"] = "1" env["MOZ_INSTRUMENT_EVENT_LOOP_THRESHOLD"] = str(options.tracerThreshold) env["MOZ_INSTRUMENT_EVENT_LOOP_INTERVAL"] = str(options.tracerInterval) env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" # construct the browser arguments cmdargs = [] # TODO Make browserArgs a list cmdargs.extend(self.options.browserArgs) cmdargs.extend(["-pep-start", os.path.realpath(jsonManifest.name)]) # run with managed process handler self.runner = self.runner_class( profile=self.profile, binary=self.options.binary, cmdargs=cmdargs, env=env, process_class=PepProcess )
def run(self): if self.options.remote_webserver: httpd_host = self.options.remote_webserver.split(':')[0] else: httpd_host = self.httpd.host httpd_port = self.httpd.httpd.server_port locations = ServerLocations() locations.add_host(host=httpd_host, port=httpd_port, options='primary,privileged') #TODO: use Preferences.read when prefs_general.js has been updated prefpath = self.options.prefs prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = { "server": "%s:%d" % (httpd_host, httpd_port), "OOP": "false" } prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs: prefs[pref] = Preferences.cast(prefs[pref]) prefs[ "steeplechase.signalling_server"] = self.options.signalling_server prefs["steeplechase.signalling_room"] = str(uuid.uuid4()) if self.options.timeout is None: prefs["steeplechase.timeout"] = 30000 else: prefs["steeplechase.timeout"] = self.options.timeout prefs["media.navigator.permission.disabled"] = True prefs["media.navigator.streams.fake"] = True specialpowers_path = self.options.specialpowers threads = [] results = [] cond = threading.Condition() for info in self.remote_info: with mozfile.TemporaryDirectory() as profile_path: # Create and push profile print "Writing profile for %s..." % info['name'] prefs["steeplechase.is_initiator"] = info['is_initiator'] profile = FirefoxProfile(profile=profile_path, preferences=prefs, addons=[specialpowers_path], locations=locations) print "Pushing profile to %s..." % info['name'] remote_profile_path = posixpath.join(info['test_root'], "profile") info['dm'].mkDir(remote_profile_path) info['dm'].pushDir(profile_path, remote_profile_path) info['remote_profile_path'] = remote_profile_path env = {} env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" env["XPCOM_DEBUG_BREAK"] = "warn" env["DISPLAY"] = self.options.remote_xdisplay cmd = [ info['remote_app_path'], "-no-remote", "-profile", info['remote_profile_path'], 'http://%s:%d/index.html' % (httpd_host, httpd_port) ] print "cmd: %s" % (cmd, ) t = RunThread(name=info['name'], args=(info['dm'], cmd, env, cond, results)) threads.append(t) for t in threads: t.start() self.log.info("Waiting for results...") pass_count, fail_count = 0, 0 outputs = {} while threads: cond.acquire() while not results: cond.wait() thread, result, output = results.pop(0) cond.release() outputs[thread.name] = output passes, failures = result #XXX: double-counting tests from both clients. Ok? pass_count += passes fail_count += failures if failures: self.log.error("Error in %s" % thread.name) threads.remove(thread) self.log.info("All clients finished") for info in self.remote_info: if self.options.log_dest: with open( os.path.join(self.options.log_dest, "%s.log" % info['name']), "wb") as f: f.write(outputs[info['name']]) if fail_count: self.log.info("Log output for %s:", info["name"]) self.log.info(">>>>>>>") for line in outputs[info['name']].splitlines(): #TODO: make structured log messages human-readable self.log.info(line) self.log.info("<<<<<<<") return pass_count, fail_count
def valgrind_test(self, suppressions): from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath from six import string_types from valgrind.output_handler import OutputHandler build_dir = os.path.join(self.topsrcdir, "build") # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, "pgo")) httpd.start(block=False) with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile profile_data_dir = os.path.join(self.topsrcdir, "testing", "profiles") with open(os.path.join(profile_data_dir, "profiles.json"), "r") as fh: base_profiles = json.load(fh)["valgrind"] prefpaths = [ os.path.join(profile_data_dir, profile, "user.js") for profile in base_profiles ] prefs = {} for path in prefpaths: prefs.update(Preferences.read_prefs(path)) interpolation = { "server": "%s:%d" % httpd.httpd.server_address, } for k, v in prefs.items(): if isinstance(v, string_types): v = v.format(**interpolation) prefs[k] = Preferences.cast(v) quitter = os.path.join(self.topsrcdir, "tools", "quitter", "*****@*****.**") locations = ServerLocations() locations.add_host(host="127.0.0.1", port=httpd.httpd.server_port, options="primary") profile = FirefoxProfile( profile=profilePath, preferences=prefs, addons=[quitter], locations=locations, ) firefox_args = [httpd.get_url()] env = os.environ.copy() env["G_SLICE"] = "always-malloc" env["MOZ_CC_RUN_DURING_SHUTDOWN"] = "1" env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1" env["XPCOM_DEBUG_BREAK"] = "warn" outputHandler = OutputHandler(self.log) kp_kwargs = { "processOutputLine": [outputHandler], "universal_newlines": True, } valgrind = "valgrind" if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, "--sym-offsets=yes", "--smc-check=all-non-file", "--vex-iropt-register-updates=allregs-at-mem-access", "--gen-suppressions=all", "--num-callers=36", "--leak-check=full", "--show-possibly-lost=no", "--track-origins=yes", "--trace-children=yes", "-v", # Enable verbosity to get the list of used suppressions # Avoid excessive delays in the presence of spinlocks. # See bug 1309851. "--fair-sched=yes", # Keep debuginfo after library unmap. See bug 1382280. "--keep-debuginfo=yes", # Reduce noise level on rustc and/or LLVM compiled code. # See bug 1365915 "--expensive-definedness-checks=yes", # Compensate for the compiler inlining `new` but not `delete` # or vice versa. "--show-mismatched-frees=no", ] for s in suppressions: valgrind_args.append("--suppressions=" + s) supps_dir = os.path.join(build_dir, "valgrind") supps_file1 = os.path.join(supps_dir, "cross-architecture.sup") valgrind_args.append("--suppressions=" + supps_file1) if mozinfo.os == "linux": machtype = { "x86_64": "x86_64-pc-linux-gnu", "x86": "i386-pc-linux-gnu", }.get(mozinfo.processor) if machtype: supps_file2 = os.path.join(supps_dir, machtype + ".sup") if os.path.isfile(supps_file2): valgrind_args.append("--suppressions=" + supps_file2) exitcode = None timeout = 1800 binary_not_found_exception = None try: runner = FirefoxRunner( profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, process_args=kp_kwargs, ) runner.start(debug_args=valgrind_args) exitcode = runner.wait(timeout=timeout) except BinaryNotFoundException as e: binary_not_found_exception = e finally: errs = outputHandler.error_count supps = outputHandler.suppression_count if errs != supps: status = 1 # turns the TBPL job orange self.log( logging.ERROR, "valgrind-fail-parsing", { "errs": errs, "supps": supps }, "TEST-UNEXPECTED-FAIL | valgrind-test | error parsing: {errs} errors " "seen, but {supps} generated suppressions seen", ) elif errs == 0: status = 0 self.log( logging.INFO, "valgrind-pass", {}, "TEST-PASS | valgrind-test | valgrind found no errors", ) else: status = 1 # turns the TBPL job orange # We've already printed details of the errors. if binary_not_found_exception: status = 2 # turns the TBPL job red self.log( logging.ERROR, "valgrind-fail-errors", {"error": str(binary_not_found_exception)}, "TEST-UNEXPECTED-FAIL | valgrind-test | {error}", ) self.log( logging.INFO, "valgrind-fail-errors", {"help": binary_not_found_exception.help()}, "{help}", ) elif exitcode is None: status = 2 # turns the TBPL job red self.log( logging.ERROR, "valgrind-fail-timeout", {"timeout": timeout}, "TEST-UNEXPECTED-FAIL | valgrind-test | Valgrind timed out " "(reached {timeout} second limit)", ) elif exitcode != 0: status = 2 # turns the TBPL job red self.log( logging.ERROR, "valgrind-fail-errors", {"exitcode": exitcode}, "TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code " "from Valgrind: {exitcode}", ) httpd.stop() return status
def __init__(self, options, **kwargs): self.options = options self.server = None self.logger = mozlog.getLogger('PEP') # create the profile enable_proxy = False locations = ServerLocations() if self.options.proxyLocations: if not self.options.serverPath: self.logger.warning('Can\'t set up proxy without server path') else: enable_proxy = True for proxyLocation in self.options.proxyLocations: locations.read(proxyLocation, False) locations.add_host(host='127.0.0.1', port=self.options.serverPort, options='primary,privileged') self.profile = self.profile_class(profile=self.options.profilePath, addons=[os.path.join(here, 'extension')], locations=locations, proxy=enable_proxy) # fork a server to serve the test related files if self.options.serverPath: self.runServer() tests = [] # TODO is there a better way of doing this? if self.options.testPath.endswith('.js'): # a single test file was passed in testObj = {} testObj['path'] = os.path.realpath(self.options.testPath) testObj['name'] = os.path.basename(self.options.testPath) testObj['here'] = os.path.dirname(testObj['path']) tests.append(testObj) else: # a test manifest was passed in # open and convert the manifest to json manifest = TestManifest() manifest.read(self.options.testPath) tests = manifest.get() # create a manifest object to be read by the JS side manifestObj = {} manifestObj['tests'] = tests manifestObj['options'] = options.__dict__ # write manifest to a JSON file jsonManifest = open(os.path.join(here, 'manifest.json'), 'w') jsonManifest.write(json.dumps(manifestObj)) jsonManifest.close() # setup environment env = os.environ.copy() env['MOZ_INSTRUMENT_EVENT_LOOP'] = '1' env['MOZ_INSTRUMENT_EVENT_LOOP_THRESHOLD'] = str(options.tracerThreshold) env['MOZ_INSTRUMENT_EVENT_LOOP_INTERVAL'] = str(options.tracerInterval) env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' # construct the browser arguments cmdargs = [] # TODO Make browserArgs a list cmdargs.extend(self.options.browserArgs) cmdargs.extend(['-pep-start', os.path.realpath(jsonManifest.name)]) # run with managed process handler self.runner = self.runner_class(profile=self.profile, binary=self.options.binary, cmdargs=cmdargs, env=env, process_class=PepProcess)
def valgrind_test(self, suppressions): import json import re import sys import tempfile from mozbuild.base import MozbuildObject from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath build_dir = os.path.join(self.topsrcdir, "build") # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, "pgo")) httpd.start(block=False) with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile prefpath = os.path.join(self.topsrcdir, "testing", "profiles", "prefs_general.js") prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = {"server": "%s:%d" % httpd.httpd.server_address, "OOP": "false"} prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs: prefs[pref] = Preferences.cast(prefs[pref]) quitter = os.path.join(self.distdir, "xpi-stage", "quitter") locations = ServerLocations() locations.add_host(host="127.0.0.1", port=httpd.httpd.server_port, options="primary") profile = FirefoxProfile(profile=profilePath, preferences=prefs, addons=[quitter], locations=locations) firefox_args = [httpd.get_url()] env = os.environ.copy() env["G_SLICE"] = "always-malloc" env["XPCOM_CC_RUN_DURING_SHUTDOWN"] = "1" env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" env["XPCOM_DEBUG_BREAK"] = "warn" class OutputHandler(object): def __init__(self): self.found_errors = False def __call__(self, line): print(line) m = re.match(r".*ERROR SUMMARY: [1-9]\d* errors from \d+ contexts", line) if m: self.found_errors = True outputHandler = OutputHandler() kp_kwargs = {"processOutputLine": [outputHandler]} valgrind = "valgrind" if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, "--smc-check=all-non-file", "--vex-iropt-register-updates=allregs-at-mem-access", "--gen-suppressions=all", "--num-callers=20", "--leak-check=full", "--show-possibly-lost=no", "--track-origins=yes", ] for s in suppressions: valgrind_args.append("--suppressions=" + s) supps_dir = os.path.join(build_dir, "valgrind") supps_file1 = os.path.join(supps_dir, "cross-architecture.sup") valgrind_args.append("--suppressions=" + supps_file1) # MACHTYPE is an odd bash-only environment variable that doesn't # show up in os.environ, so we have to get it another way. machtype = subprocess.check_output(["bash", "-c", "echo $MACHTYPE"]).rstrip() supps_file2 = os.path.join(supps_dir, machtype + ".sup") if os.path.isfile(supps_file2): valgrind_args.append("--suppressions=" + supps_file2) exitcode = None try: runner = FirefoxRunner( profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, kp_kwargs=kp_kwargs ) runner.start(debug_args=valgrind_args) exitcode = runner.wait() finally: if not outputHandler.found_errors: status = 0 print("TEST-PASS | valgrind-test | valgrind found no errors") else: status = 1 # turns the TBPL job orange print("TEST-UNEXPECTED-FAIL | valgrind-test | valgrind found errors") if exitcode != 0: status = 2 # turns the TBPL job red print("TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code from Valgrind") httpd.stop() return status
def valgrind_test(self, suppressions): import json import sys import tempfile from mozbuild.base import MozbuildObject from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath from valgrind.output_handler import OutputHandler build_dir = os.path.join(self.topsrcdir, 'build') # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, 'pgo')) httpd.start(block=False) with TemporaryDirectory() as profilePath: #TODO: refactor this into mozprofile prefpath = os.path.join(self.topsrcdir, 'testing', 'profiles', 'prefs_general.js') prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = { 'server': '%s:%d' % httpd.httpd.server_address, 'OOP': 'false'} prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs: prefs[pref] = Preferences.cast(prefs[pref]) quitter = os.path.join(self.topsrcdir, 'tools', 'quitter', '*****@*****.**') locations = ServerLocations() locations.add_host(host='127.0.0.1', port=httpd.httpd.server_port, options='primary') profile = FirefoxProfile(profile=profilePath, preferences=prefs, addons=[quitter], locations=locations) firefox_args = [httpd.get_url()] env = os.environ.copy() env['G_SLICE'] = 'always-malloc' env['MOZ_CC_RUN_DURING_SHUTDOWN'] = '1' env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' env['XPCOM_DEBUG_BREAK'] = 'warn' env.update(self.extra_environment_variables) outputHandler = OutputHandler(self.log) kp_kwargs = {'processOutputLine': [outputHandler]} valgrind = 'valgrind' if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, '--smc-check=all-non-file', '--vex-iropt-register-updates=allregs-at-mem-access', '--gen-suppressions=all', '--num-callers=36', '--leak-check=full', '--show-possibly-lost=no', '--track-origins=yes', '--trace-children=yes', '-v', # Enable verbosity to get the list of used suppressions ] for s in suppressions: valgrind_args.append('--suppressions=' + s) supps_dir = os.path.join(build_dir, 'valgrind') supps_file1 = os.path.join(supps_dir, 'cross-architecture.sup') valgrind_args.append('--suppressions=' + supps_file1) # MACHTYPE is an odd bash-only environment variable that doesn't # show up in os.environ, so we have to get it another way. machtype = subprocess.check_output(['bash', '-c', 'echo $MACHTYPE']).rstrip() supps_file2 = os.path.join(supps_dir, machtype + '.sup') if os.path.isfile(supps_file2): valgrind_args.append('--suppressions=' + supps_file2) exitcode = None timeout = 1800 try: runner = FirefoxRunner(profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, process_args=kp_kwargs) runner.start(debug_args=valgrind_args) exitcode = runner.wait(timeout=timeout) finally: errs = outputHandler.error_count supps = outputHandler.suppression_count if errs != supps: status = 1 # turns the TBPL job orange self.log(logging.ERROR, 'valgrind-fail-parsing', {'errs': errs, 'supps': supps}, 'TEST-UNEXPECTED-FAIL | valgrind-test | error parsing: {errs} errors seen, but {supps} generated suppressions seen') elif errs == 0: status = 0 self.log(logging.INFO, 'valgrind-pass', {}, 'TEST-PASS | valgrind-test | valgrind found no errors') else: status = 1 # turns the TBPL job orange # We've already printed details of the errors. if exitcode == None: status = 2 # turns the TBPL job red self.log(logging.ERROR, 'valgrind-fail-timeout', {'timeout': timeout}, 'TEST-UNEXPECTED-FAIL | valgrind-test | Valgrind timed out (reached {timeout} second limit)') elif exitcode != 0: status = 2 # turns the TBPL job red self.log(logging.ERROR, 'valgrind-fail-errors', {}, 'TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code from Valgrind') httpd.stop() return status
def valgrind_test(self, suppressions): import json import sys import tempfile from mozbuild.base import MozbuildObject from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath from valgrind.output_handler import OutputHandler build_dir = os.path.join(self.topsrcdir, 'build') # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, 'pgo')) httpd.start(block=False) with TemporaryDirectory() as profilePath: #TODO: refactor this into mozprofile prefpath = os.path.join(self.topsrcdir, 'testing', 'profiles', 'prefs_general.js') prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = { 'server': '%s:%d' % httpd.httpd.server_address, 'OOP': 'false'} prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs: prefs[pref] = Preferences.cast(prefs[pref]) quitter = os.path.join(self.distdir, 'xpi-stage', 'quitter') locations = ServerLocations() locations.add_host(host='127.0.0.1', port=httpd.httpd.server_port, options='primary') profile = FirefoxProfile(profile=profilePath, preferences=prefs, addons=[quitter], locations=locations) firefox_args = [httpd.get_url()] env = os.environ.copy() env['G_SLICE'] = 'always-malloc' env['XPCOM_CC_RUN_DURING_SHUTDOWN'] = '1' env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' env['XPCOM_DEBUG_BREAK'] = 'warn' outputHandler = OutputHandler() kp_kwargs = {'processOutputLine': [outputHandler]} valgrind = 'valgrind' if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, '--smc-check=all-non-file', '--vex-iropt-register-updates=allregs-at-mem-access', '--gen-suppressions=all', '--num-callers=20', '--leak-check=full', '--show-possibly-lost=no', '--track-origins=yes' ] for s in suppressions: valgrind_args.append('--suppressions=' + s) supps_dir = os.path.join(build_dir, 'valgrind') supps_file1 = os.path.join(supps_dir, 'cross-architecture.sup') valgrind_args.append('--suppressions=' + supps_file1) # MACHTYPE is an odd bash-only environment variable that doesn't # show up in os.environ, so we have to get it another way. machtype = subprocess.check_output(['bash', '-c', 'echo $MACHTYPE']).rstrip() supps_file2 = os.path.join(supps_dir, machtype + '.sup') if os.path.isfile(supps_file2): valgrind_args.append('--suppressions=' + supps_file2) exitcode = None try: runner = FirefoxRunner(profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, kp_kwargs=kp_kwargs) runner.start(debug_args=valgrind_args) exitcode = runner.wait() finally: errs = outputHandler.error_count supps = outputHandler.suppression_count if errs != supps: status = 1 # turns the TBPL job orange print('TEST-UNEXPECTED-FAILURE | valgrind-test | error parsing:', errs, "errors seen, but", supps, "generated suppressions seen") elif errs == 0: status = 0 print('TEST-PASS | valgrind-test | valgrind found no errors') else: status = 1 # turns the TBPL job orange # We've already printed details of the errors. if exitcode != 0: status = 2 # turns the TBPL job red print('TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code from Valgrind') httpd.stop() return status
def valgrind_test(self, suppressions): import json import sys import tempfile from mozbuild.base import MozbuildObject from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath from valgrind.output_handler import OutputHandler build_dir = os.path.join(self.topsrcdir, "build") # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, "pgo")) httpd.start(block=False) with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile prefpath = os.path.join(self.topsrcdir, "testing", "profiles", "prefs_general.js") prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = {"server": "%s:%d" % httpd.httpd.server_address, "OOP": "false"} prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs: prefs[pref] = Preferences.cast(prefs[pref]) quitter = os.path.join(self.topsrcdir, "tools", "quitter", "*****@*****.**") locations = ServerLocations() locations.add_host(host="127.0.0.1", port=httpd.httpd.server_port, options="primary") profile = FirefoxProfile(profile=profilePath, preferences=prefs, addons=[quitter], locations=locations) firefox_args = [httpd.get_url()] env = os.environ.copy() env["G_SLICE"] = "always-malloc" env["MOZ_CC_RUN_DURING_SHUTDOWN"] = "1" env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" env["XPCOM_DEBUG_BREAK"] = "warn" env.update(self.extra_environment_variables) outputHandler = OutputHandler(self.log) kp_kwargs = {"processOutputLine": [outputHandler]} valgrind = "valgrind" if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, "--smc-check=all-non-file", "--vex-iropt-register-updates=allregs-at-mem-access", "--gen-suppressions=all", "--num-callers=36", "--leak-check=full", "--show-possibly-lost=no", "--track-origins=yes", "--trace-children=yes", "-v", # Enable verbosity to get the list of used suppressions ] for s in suppressions: valgrind_args.append("--suppressions=" + s) supps_dir = os.path.join(build_dir, "valgrind") supps_file1 = os.path.join(supps_dir, "cross-architecture.sup") valgrind_args.append("--suppressions=" + supps_file1) # MACHTYPE is an odd bash-only environment variable that doesn't # show up in os.environ, so we have to get it another way. machtype = subprocess.check_output(["bash", "-c", "echo $MACHTYPE"]).rstrip() supps_file2 = os.path.join(supps_dir, machtype + ".sup") if os.path.isfile(supps_file2): valgrind_args.append("--suppressions=" + supps_file2) exitcode = None timeout = 1800 try: runner = FirefoxRunner( profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, process_args=kp_kwargs, ) runner.start(debug_args=valgrind_args) exitcode = runner.wait(timeout=timeout) finally: errs = outputHandler.error_count supps = outputHandler.suppression_count if errs != supps: status = 1 # turns the TBPL job orange self.log( logging.ERROR, "valgrind-fail-parsing", {"errs": errs, "supps": supps}, "TEST-UNEXPECTED-FAIL | valgrind-test | error parsing: {errs} errors seen, but {supps} generated suppressions seen", ) elif errs == 0: status = 0 self.log(logging.INFO, "valgrind-pass", {}, "TEST-PASS | valgrind-test | valgrind found no errors") else: status = 1 # turns the TBPL job orange # We've already printed details of the errors. if exitcode == None: status = 2 # turns the TBPL job red self.log( logging.ERROR, "valgrind-fail-timeout", {"timeout": timeout}, "TEST-UNEXPECTED-FAIL | valgrind-test | Valgrind timed out (reached {timeout} second limit)", ) elif exitcode != 0: status = 2 # turns the TBPL job red self.log( logging.ERROR, "valgrind-fail-errors", {}, "TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code from Valgrind", ) httpd.stop() return status
def start(self, **kwargs): if self.marionette_port is None: self.marionette_port = get_free_port(2828, exclude=self.used_ports) self.used_ports.add(self.marionette_port) env = os.environ.copy() env["MOZ_CRASHREPORTER"] = "1" env["MOZ_CRASHREPORTER_SHUTDOWN"] = "1" env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1" env["STYLO_THREADS"] = str(self.stylo_threads) if self.chaos_mode_flags is not None: env["MOZ_CHAOSMODE"] = str(self.chaos_mode_flags) locations = ServerLocations( filename=os.path.join(here, "server-locations.txt")) preferences = self.load_prefs() self.profile = FirefoxProfile(locations=locations, preferences=preferences) self.profile.set_preferences({ "marionette.port": self.marionette_port, "dom.disable_open_during_load": False, "network.dns.localDomains": ",".join(hostnames), "network.proxy.type": 0, "places.history.enabled": False, "dom.send_after_paint_to_content": True, "network.preload": True }) if self.e10s: self.profile.set_preferences( {"browser.tabs.remote.autostart": True}) if self.test_type == "reftest": self.profile.set_preferences( {"layout.interruptible-reflow.enabled": False}) if self.leak_check and kwargs.get("check_leaks", True): self.leak_report_file = os.path.join(self.profile.profile, "runtests_leaks.log") if os.path.exists(self.leak_report_file): os.remove(self.leak_report_file) env["XPCOM_MEM_BLOAT_LOG"] = self.leak_report_file else: self.leak_report_file = None # Bug 1262954: winxp + e10s, disable hwaccel if (self.e10s and platform.system() in ("Windows", "Microsoft") and '5.1' in platform.version()): self.profile.set_preferences( {"layers.acceleration.disabled": True}) if self.ca_certificate_path is not None: self.setup_ssl() debug_args, cmd = browser_command( self.binary, self.binary_args if self.binary_args else [] + [cmd_arg("marionette"), "about:blank"], self.debug_info) self.runner = FirefoxRunner( profile=self.profile, binary=cmd[0], cmdargs=cmd[1:], env=env, process_class=ProcessHandler, process_args={"processOutputLine": [self.on_output]}) self.logger.debug("Starting Firefox") self.runner.start(debug_args=debug_args, interactive=self.debug_info and self.debug_info.interactive) self.logger.debug("Firefox Started")
class ServerLocationsTest(unittest.TestCase): """test server locations""" locations = """# This is the primary location from which tests run. # http://mochi.test:8888 primary,privileged # a few test locations http://127.0.0.1:80 privileged http://127.0.0.1:8888 privileged https://test:80 privileged http://example.org:80 privileged http://test1.example.org privileged """ locations_no_primary = """http://secondary.test:80 privileged http://tertiary.test:8888 privileged """ locations_bad_port = """http://mochi.test:8888 primary,privileged http://127.0.0.1:80 privileged http://127.0.0.1:8888 privileged http://test:badport privileged http://example.org:80 privileged """ def compare_location(self, location, scheme, host, port, options): self.assertEqual(location.scheme, scheme) self.assertEqual(location.host, host) self.assertEqual(location.port, port) self.assertEqual(location.options, options) def create_temp_file(self, contents): f = tempfile.NamedTemporaryFile() f.write(contents) f.flush() return f def test_server_locations(self): # write a permissions file f = self.create_temp_file(self.locations) # read the locations locations = ServerLocations(f.name) # ensure that they're what we expect self.assertEqual(len(locations), 6) i = iter(locations) self.compare_location(i.next(), 'http', 'mochi.test', '8888', ['primary', 'privileged']) self.compare_location(i.next(), 'http', '127.0.0.1', '80', ['privileged']) self.compare_location(i.next(), 'http', '127.0.0.1', '8888', ['privileged']) self.compare_location(i.next(), 'https', 'test', '80', ['privileged']) self.compare_location(i.next(), 'http', 'example.org', '80', ['privileged']) self.compare_location(i.next(), 'http', 'test1.example.org', '80', ['privileged']) locations.add_host('mozilla.org') self.assertEqual(len(locations), 7) self.compare_location(i.next(), 'http', 'mozilla.org', '80', ['privileged']) # test some errors self.assertRaises(MultiplePrimaryLocationsError, locations.add_host, 'primary.test', options='primary') # We no longer throw these DuplicateLocation Error try: locations.add_host('127.0.0.1') except DuplicateLocationError: self.assertTrue(False, "Should no longer throw DuplicateLocationError") self.assertRaises(BadPortLocationError, locations.add_host, '127.0.0.1', port='abc') # test some errors in locations file f = self.create_temp_file(self.locations_no_primary) exc = None try: ServerLocations(f.name) except LocationsSyntaxError, e: exc = e self.assertNotEqual(exc, None) self.assertEqual(exc.err.__class__, MissingPrimaryLocationError) self.assertEqual(exc.lineno, 3) # test bad port in a locations file to ensure lineno calculated # properly. f = self.create_temp_file(self.locations_bad_port) exc = None try: ServerLocations(f.name) except LocationsSyntaxError, e: exc = e
from datetime import datetime from mozbuild.base import MozbuildObject from buildconfig import substs PORT = 8888 if __name__ == '__main__': cli = CLI() debug_args, interactive = cli.debugger_arguments() build = MozbuildObject.from_environment() httpd = MozHttpd(port=PORT, docroot=os.path.join(build.topsrcdir, "build", "pgo")) httpd.start(block=False) locations = ServerLocations() locations.add_host(host='127.0.0.1', port=PORT, options='primary,privileged') #TODO: mozfile.TemporaryDirectory profilePath = tempfile.mkdtemp() try: #TODO: refactor this into mozprofile prefpath = os.path.join(build.topsrcdir, "testing", "profiles", "prefs_general.js") prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = { "server": "%s:%d" % httpd.httpd.server_address, "OOP": "false"} prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs:
def valgrind_test(self, suppressions): from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath from six import string_types from valgrind.output_handler import OutputHandler build_dir = os.path.join(self.topsrcdir, 'build') # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, 'pgo')) httpd.start(block=False) with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile profile_data_dir = os.path.join( self.topsrcdir, 'testing', 'profiles') with open(os.path.join(profile_data_dir, 'profiles.json'), 'r') as fh: base_profiles = json.load(fh)['valgrind'] prefpaths = [os.path.join(profile_data_dir, profile, 'user.js') for profile in base_profiles] prefs = {} for path in prefpaths: prefs.update(Preferences.read_prefs(path)) interpolation = { 'server': '%s:%d' % httpd.httpd.server_address, } for k, v in prefs.items(): if isinstance(v, string_types): v = v.format(**interpolation) prefs[k] = Preferences.cast(v) quitter = os.path.join( self.topsrcdir, 'tools', 'quitter', '*****@*****.**') locations = ServerLocations() locations.add_host(host='127.0.0.1', port=httpd.httpd.server_port, options='primary') profile = FirefoxProfile(profile=profilePath, preferences=prefs, addons=[quitter], locations=locations) firefox_args = [httpd.get_url()] env = os.environ.copy() env['G_SLICE'] = 'always-malloc' env['MOZ_CC_RUN_DURING_SHUTDOWN'] = '1' env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' env['XPCOM_DEBUG_BREAK'] = 'warn' env.update(self.extra_environment_variables) outputHandler = OutputHandler(self.log) kp_kwargs = {'processOutputLine': [outputHandler]} valgrind = 'valgrind' if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, '--smc-check=all-non-file', '--vex-iropt-register-updates=allregs-at-mem-access', '--gen-suppressions=all', '--num-callers=36', '--leak-check=full', '--show-possibly-lost=no', '--track-origins=yes', '--trace-children=yes', '-v', # Enable verbosity to get the list of used suppressions # Avoid excessive delays in the presence of spinlocks. # See bug 1309851. '--fair-sched=yes', # Keep debuginfo after library unmap. See bug 1382280. '--keep-debuginfo=yes', # Reduce noise level on rustc and/or LLVM compiled code. # See bug 1365915 '--expensive-definedness-checks=yes', ] for s in suppressions: valgrind_args.append('--suppressions=' + s) supps_dir = os.path.join(build_dir, 'valgrind') supps_file1 = os.path.join(supps_dir, 'cross-architecture.sup') valgrind_args.append('--suppressions=' + supps_file1) if mozinfo.os == 'linux': machtype = { 'x86_64': 'x86_64-pc-linux-gnu', 'x86': 'i386-pc-linux-gnu', }.get(mozinfo.processor) if machtype: supps_file2 = os.path.join(supps_dir, machtype + '.sup') if os.path.isfile(supps_file2): valgrind_args.append('--suppressions=' + supps_file2) exitcode = None timeout = 1800 try: runner = FirefoxRunner(profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, process_args=kp_kwargs) runner.start(debug_args=valgrind_args) exitcode = runner.wait(timeout=timeout) finally: errs = outputHandler.error_count supps = outputHandler.suppression_count if errs != supps: status = 1 # turns the TBPL job orange self.log(logging.ERROR, 'valgrind-fail-parsing', {'errs': errs, 'supps': supps}, 'TEST-UNEXPECTED-FAIL | valgrind-test | error parsing: {errs} errors ' 'seen, but {supps} generated suppressions seen') elif errs == 0: status = 0 self.log(logging.INFO, 'valgrind-pass', {}, 'TEST-PASS | valgrind-test | valgrind found no errors') else: status = 1 # turns the TBPL job orange # We've already printed details of the errors. if exitcode is None: status = 2 # turns the TBPL job red self.log(logging.ERROR, 'valgrind-fail-timeout', {'timeout': timeout}, 'TEST-UNEXPECTED-FAIL | valgrind-test | Valgrind timed out ' '(reached {timeout} second limit)') elif exitcode != 0: status = 2 # turns the TBPL job red self.log(logging.ERROR, 'valgrind-fail-errors', {}, 'TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code' 'from Valgrind') httpd.stop() return status
def run(self): if self.options.remote_webserver: httpd_host = self.options.remote_webserver.split(':')[0] else: httpd_host = self.httpd.host httpd_port = self.httpd.httpd.server_port locations = ServerLocations() locations.add_host(host=httpd_host, port=httpd_port, options='primary,privileged') #TODO: use Preferences.read when prefs_general.js has been updated prefpath = self.options.prefs prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = { "server": "%s:%d" % (httpd_host, httpd_port), "OOP": "false"} prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs: prefs[pref] = Preferences.cast(prefs[pref]) prefs["steeplechase.signalling_server"] = self.options.signalling_server prefs["steeplechase.signalling_room"] = str(uuid.uuid4()) prefs["media.navigator.permission.disabled"] = True prefs["media.navigator.streams.fake"] = True specialpowers_path = self.options.specialpowers threads = [] results = [] cond = threading.Condition() for info in self.remote_info: with mozfile.TemporaryDirectory() as profile_path: # Create and push profile print "Writing profile for %s..." % info['name'] prefs["steeplechase.is_initiator"] = info['is_initiator'] profile = FirefoxProfile(profile=profile_path, preferences=prefs, addons=[specialpowers_path], locations=locations) print "Pushing profile to %s..." % info['name'] remote_profile_path = posixpath.join(info['test_root'], "profile") info['dm'].mkDir(remote_profile_path) info['dm'].pushDir(profile_path, remote_profile_path) info['remote_profile_path'] = remote_profile_path env = {} env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" env["XPCOM_DEBUG_BREAK"] = "warn" env["DISPLAY"] = self.options.remote_xdisplay cmd = [info['remote_app_path'], "-no-remote", "-profile", info['remote_profile_path'], 'http://%s:%d/index.html' % (httpd_host, httpd_port)] print "cmd: %s" % (cmd, ) t = RunThread(name=info['name'], args=(info['dm'], cmd, env, cond, results)) threads.append(t) for t in threads: t.start() self.log.info("Waiting for results...") pass_count, fail_count = 0, 0 outputs = {} while threads: cond.acquire() while not results: cond.wait() thread, result, output = results.pop(0) cond.release() outputs[thread.name] = output passes, failures = result #XXX: double-counting tests from both clients. Ok? pass_count += passes fail_count += failures if failures: self.log.error("Error in %s" % thread.name) threads.remove(thread) self.log.info("All clients finished") for info in self.remote_info: if self.options.log_dest: with open(os.path.join(self.options.log_dest, "%s.log" % info['name']), "wb") as f: f.write(outputs[info['name']]) if fail_count: self.log.info("Log output for %s:", info["name"]) self.log.info(">>>>>>>") for line in outputs[info['name']].splitlines(): #TODO: make structured log messages human-readable self.log.info(line) self.log.info("<<<<<<<") return pass_count, fail_count
def createSSLServerCertificate(build, srcDir): certutil = build.get_binary_path(what="certutil") pk12util = build.get_binary_path(what="pk12util") with NamedTemporaryFile() as pwfile, NamedTemporaryFile() as rndfile: pgoCAPath = os.path.join(srcDir, "pgoca.p12") pwfile.write("\n") if not dbFilesExist(srcDir): # Make sure all DB files from src are really deleted unlinkDbFiles(srcDir) # Create certification database for ssltunnel status = runUtil(certutil, ["-N", "-d", srcDir, "-f", pwfile.name]) if status: return status status = runUtil(pk12util, [ "-i", pgoCAPath, "-w", pwfile.name, "-d", srcDir, "-k", pwfile.name ]) if status: return status # Generate automatic certificate locations = ServerLocations( os.path.join(build.topsrcdir, "build", "pgo", "server-locations.txt")) iterator = iter(locations) # Skips the first entry, I don't know why: bug 879740 iterator.next() locationsParam = "" firstLocation = "" for loc in iterator: if loc.scheme == "https" and "nocert" not in loc.options: customCertOption = False customCertRE = re.compile("^cert=(?:\w+)") for option in loc.options: match = customCertRE.match(option) if match: customCertOption = True break if not customCertOption: if len(locationsParam) > 0: locationsParam += "," locationsParam += loc.host if firstLocation == "": firstLocation = loc.host if not firstLocation: print "Nothing to generate, no automatic secure hosts specified" else: createRandomFile(rndfile) runUtil(certutil, [ "-D", "-n", "pgo server certificate", "-d", srcDir, "-z", rndfile.name, "-f", pwfile.name ]) # Ignore the result, the certificate may not be present when new database is being built status = runUtil(certutil, [ "-S", "-s", "CN=%s" % firstLocation, "-t", "Pu,,", "-c", "pgo temporary ca", "-m", "2", "-8", locationsParam, "-v", "120", "-n", "pgo server certificate", "-d", srcDir, "-z", rndfile.name, "-f", pwfile.name ]) if status: return status status = runUtil(certutil, [ "-S", "-s", "CN=Imminently Distrusted End Entity", "-t", "P,,", "-c", "pgo temporary ca", "-k", "rsa", "-g", "2048", "-Z", "SHA256", "-m", "1519140221", "-n", "imminently_distrusted", "-v", "120", "-8", "imminently-distrusted.example.com", "-d", srcDir, "-z", rndfile.name, "-f", pwfile.name ]) if status: return status """ As of February 2018, there are 15 more certificates which are not created by this script. See bug 1441338: selfsigned Pu,u,u Unknown CA Cu,u,u escapeattack1 Pu,u,u untrustedandexpired Pu,u,u alternateTrustedAuthority Cu,u,u dynamicPinningGood Pu,u,u staticPinningBad Pu,u,u sha1_end_entity Pu,u,u bug413909cert u,u,u untrusted Pu,u,u escapeattack2 Pu,u,u expired Pu,u,u dynamicPinningBad Pu,u,u sha256_end_entity Pu,u,u """ return 0
print("{}\n\n{}\n".format(e, e.help())) sys.exit(1) binary = os.path.normpath(os.path.abspath(binary)) path_mappings = { k: os.path.join(build.topsrcdir, v) for k, v in PATH_MAPPINGS.items() } httpd = MozHttpd( port=PORT, docroot=os.path.join(build.topsrcdir, "build", "pgo"), path_mappings=path_mappings, ) httpd.start(block=False) locations = ServerLocations() locations.add_host(host="127.0.0.1", port=PORT, options="primary,privileged") old_profraw_files = glob.glob("*.profraw") for f in old_profraw_files: os.remove(f) with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile profile_data_dir = os.path.join(build.topsrcdir, "testing", "profiles") with open(os.path.join(profile_data_dir, "profiles.json"), "r") as fh: base_profiles = json.load(fh)["profileserver"] prefpaths = [
def __init__(self, options, **kwargs): self.options = options self.server = None self.logger = mozlog.getLogger('PEP') # create the profile enable_proxy = False locations = ServerLocations() if self.options.proxyLocations: if not self.options.serverPath: self.logger.warning('Can\'t set up proxy without server path') else: enable_proxy = True for proxyLocation in self.options.proxyLocations: locations.read(proxyLocation, False) locations.add_host(host='127.0.0.1', port=self.options.serverPort, options='primary,privileged') self.profile = self.profile_class( profile=self.options.profilePath, addons=[os.path.join(here, 'extension')], locations=locations, proxy=enable_proxy) # fork a server to serve the test related files if self.options.serverPath: self.runServer() tests = [] # TODO is there a better way of doing this? if self.options.testPath.endswith('.js'): # a single test file was passed in testObj = {} testObj['path'] = os.path.realpath(self.options.testPath) testObj['name'] = os.path.basename(self.options.testPath) testObj['here'] = os.path.dirname(testObj['path']) tests.append(testObj) else: # a test manifest was passed in # open and convert the manifest to json manifest = TestManifest() manifest.read(self.options.testPath) tests = manifest.get() # create a manifest object to be read by the JS side manifestObj = {} manifestObj['tests'] = tests manifestObj['options'] = options.__dict__ # write manifest to a JSON file jsonManifest = open(os.path.join(here, 'manifest.json'), 'w') jsonManifest.write(json.dumps(manifestObj)) jsonManifest.close() # setup environment env = os.environ.copy() env['MOZ_INSTRUMENT_EVENT_LOOP'] = '1' env['MOZ_INSTRUMENT_EVENT_LOOP_THRESHOLD'] = str( options.tracerThreshold) env['MOZ_INSTRUMENT_EVENT_LOOP_INTERVAL'] = str(options.tracerInterval) env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' # construct the browser arguments cmdargs = [] # TODO Make browserArgs a list cmdargs.extend(self.options.browserArgs) cmdargs.extend(['-pep-start', os.path.realpath(jsonManifest.name)]) # run with managed process handler self.runner = self.runner_class(profile=self.profile, binary=self.options.binary, cmdargs=cmdargs, env=env, process_class=PepProcess)
def valgrind_test(self, suppressions): import json import re import sys import tempfile from mozbuild.base import MozbuildObject from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath build_dir = os.path.join(self.topsrcdir, 'build') # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, 'pgo')) httpd.start(block=False) with TemporaryDirectory() as profilePath: #TODO: refactor this into mozprofile prefpath = os.path.join(self.topsrcdir, 'testing', 'profiles', 'prefs_general.js') prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = { 'server': '%s:%d' % httpd.httpd.server_address, 'OOP': 'false' } prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs: prefs[pref] = Preferences.cast(prefs[pref]) quitter = os.path.join(self.distdir, 'xpi-stage', 'quitter') locations = ServerLocations() locations.add_host(host='127.0.0.1', port=httpd.httpd.server_port, options='primary') profile = FirefoxProfile(profile=profilePath, preferences=prefs, addons=[quitter], locations=locations) firefox_args = [httpd.get_url()] env = os.environ.copy() env['G_SLICE'] = 'always-malloc' env['XPCOM_CC_RUN_DURING_SHUTDOWN'] = '1' env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' env['XPCOM_DEBUG_BREAK'] = 'warn' class OutputHandler(object): def __init__(self): self.found_errors = False def __call__(self, line): print(line) m = re.match( r'.*ERROR SUMMARY: [1-9]\d* errors from \d+ contexts', line) if m: self.found_errors = True outputHandler = OutputHandler() kp_kwargs = {'processOutputLine': [outputHandler]} valgrind = 'valgrind' if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, '--smc-check=all-non-file', '--vex-iropt-register-updates=allregs-at-mem-access', '--gen-suppressions=all', '--num-callers=20', '--leak-check=full', '--show-possibly-lost=no', '--track-origins=yes' ] for s in suppressions: valgrind_args.append('--suppressions=' + s) supps_dir = os.path.join(build_dir, 'valgrind') supps_file1 = os.path.join(supps_dir, 'cross-architecture.sup') valgrind_args.append('--suppressions=' + supps_file1) # MACHTYPE is an odd bash-only environment variable that doesn't # show up in os.environ, so we have to get it another way. machtype = subprocess.check_output( ['bash', '-c', 'echo $MACHTYPE']).rstrip() supps_file2 = os.path.join(supps_dir, machtype + '.sup') if os.path.isfile(supps_file2): valgrind_args.append('--suppressions=' + supps_file2) exitcode = None try: runner = FirefoxRunner(profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, kp_kwargs=kp_kwargs) runner.start(debug_args=valgrind_args) exitcode = runner.wait() finally: if not outputHandler.found_errors: status = 0 print( 'TEST-PASS | valgrind-test | valgrind found no errors') else: status = 1 # turns the TBPL job orange print( 'TEST-UNEXPECTED-FAIL | valgrind-test | valgrind found errors' ) if exitcode != 0: status = 2 # turns the TBPL job red print( 'TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code from Valgrind' ) httpd.stop() return status
build = MozbuildObject.from_environment() binary = runner_args.get('binary') if not binary: binary = build.get_binary_path(where="staged-package") path_mappings = { k: os.path.join(build.topsrcdir, v) for k, v in PATH_MAPPINGS.items() } httpd = MozHttpd(port=PORT, docroot=os.path.join(build.topsrcdir, "build", "pgo"), path_mappings=path_mappings) httpd.start(block=False) locations = ServerLocations() locations.add_host(host='127.0.0.1', port=PORT, options='primary,privileged') with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile profile_data_dir = os.path.join(build.topsrcdir, 'testing', 'profiles') with open(os.path.join(profile_data_dir, 'profiles.json'), 'r') as fh: base_profiles = json.load(fh)['profileserver'] prefpaths = [os.path.join(profile_data_dir, profile, 'user.js') for profile in base_profiles] prefs = {} for path in prefpaths:
def locations(self): if self._locations is not None: return self._locations locations_file = os.path.join(here, "server-locations.txt") self._locations = ServerLocations(locations_file) return self._locations
def valgrind_test(self, suppressions): import json import sys import tempfile from mozbuild.base import MozbuildObject from mozfile import TemporaryDirectory from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import findInPath from valgrind.output_handler import OutputHandler build_dir = os.path.join(self.topsrcdir, 'build') # XXX: currently we just use the PGO inputs for Valgrind runs. This may # change in the future. httpd = MozHttpd(docroot=os.path.join(build_dir, 'pgo')) httpd.start(block=False) with TemporaryDirectory() as profilePath: #TODO: refactor this into mozprofile prefpath = os.path.join(self.topsrcdir, 'testing', 'profiles', 'prefs_general.js') prefs = {} prefs.update(Preferences.read_prefs(prefpath)) interpolation = { 'server': '%s:%d' % httpd.httpd.server_address, 'OOP': 'false'} prefs = json.loads(json.dumps(prefs) % interpolation) for pref in prefs: prefs[pref] = Preferences.cast(prefs[pref]) quitter = os.path.join(self.distdir, 'xpi-stage', 'quitter') locations = ServerLocations() locations.add_host(host='127.0.0.1', port=httpd.httpd.server_port, options='primary') profile = FirefoxProfile(profile=profilePath, preferences=prefs, addons=[quitter], locations=locations) firefox_args = [httpd.get_url()] env = os.environ.copy() env['G_SLICE'] = 'always-malloc' env['MOZ_CC_RUN_DURING_SHUTDOWN'] = '1' env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' env['XPCOM_DEBUG_BREAK'] = 'warn' env.update(self.extra_environment_variables) outputHandler = OutputHandler() kp_kwargs = {'processOutputLine': [outputHandler]} valgrind = 'valgrind' if not os.path.exists(valgrind): valgrind = findInPath(valgrind) valgrind_args = [ valgrind, '--smc-check=all-non-file', '--vex-iropt-register-updates=allregs-at-mem-access', '--gen-suppressions=all', '--num-callers=36', '--leak-check=full', '--show-possibly-lost=no', '--track-origins=yes', '--trace-children=yes', # The gstreamer plugin scanner can run as part of executing # firefox, but is an external program. In some weird cases, # valgrind finds errors while executing __libc_freeres when # it runs, but those are not relevant, as it's related to # executing third party code. So don't trace # gst-plugin-scanner. '--trace-children-skip=*/gst-plugin-scanner', '-v', # Enable verbosity to get the list of used suppressions ] for s in suppressions: valgrind_args.append('--suppressions=' + s) supps_dir = os.path.join(build_dir, 'valgrind') supps_file1 = os.path.join(supps_dir, 'cross-architecture.sup') valgrind_args.append('--suppressions=' + supps_file1) # MACHTYPE is an odd bash-only environment variable that doesn't # show up in os.environ, so we have to get it another way. machtype = subprocess.check_output(['bash', '-c', 'echo $MACHTYPE']).rstrip() supps_file2 = os.path.join(supps_dir, machtype + '.sup') if os.path.isfile(supps_file2): valgrind_args.append('--suppressions=' + supps_file2) exitcode = None timeout = 1100 try: runner = FirefoxRunner(profile=profile, binary=self.get_binary_path(), cmdargs=firefox_args, env=env, process_args=kp_kwargs) runner.start(debug_args=valgrind_args) # This timeout is slightly less than the no-output timeout on # TBPL, so we'll timeout here first and give an informative # message. exitcode = runner.wait(timeout=timeout) finally: errs = outputHandler.error_count supps = outputHandler.suppression_count if errs != supps: status = 1 # turns the TBPL job orange print('TEST-UNEXPECTED-FAIL | valgrind-test | error parsing: {} errors seen, but {} generated suppressions seen'.format(errs, supps)) elif errs == 0: status = 0 print('TEST-PASS | valgrind-test | valgrind found no errors') else: status = 1 # turns the TBPL job orange # We've already printed details of the errors. if exitcode == None: status = 2 # turns the TBPL job red print('TEST-UNEXPECTED-FAIL | valgrind-test | Valgrind timed out (reached {} second limit)'.format(timeout)) elif exitcode != 0: status = 2 # turns the TBPL job red print('TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code from Valgrind') httpd.stop() return status
def createSSLServerCertificate(build, srcDir): certutil = build.get_binary_path(what="certutil") pk12util = build.get_binary_path(what="pk12util") with NamedTemporaryFile() as pwfile, NamedTemporaryFile() as rndfile: pgoCAPath = os.path.join(srcDir, "pgoca.p12") pwfile.write("\n") if not dbFilesExist(srcDir): # Make sure all DB files from src are really deleted unlinkDbFiles(srcDir) # Create certification database for ssltunnel status = runUtil(certutil, ["-N", "-d", srcDir, "-f", pwfile.name]) if status: return status status = runUtil(pk12util, [ "-i", pgoCAPath, "-w", pwfile.name, "-d", srcDir, "-k", pwfile.name ]) if status: return status # Generate automatic certificate locations = ServerLocations( os.path.join(build.topsrcdir, "build", "pgo", "server-locations.txt")) iterator = iter(locations) # Skips the first entry, I don't know why: bug 879740 iterator.next() locationsParam = "" firstLocation = "" for loc in iterator: if loc.scheme == "https" and "nocert" not in loc.options: customCertOption = False customCertRE = re.compile("^cert=(?:\w+)") for option in loc.options: match = customCertRE.match(option) if match: customCertOption = True break if not customCertOption: if len(locationsParam) > 0: locationsParam += "," locationsParam += loc.host if firstLocation == "": firstLocation = loc.host if not firstLocation: print "Nothing to generate, no automatic secure hosts specified" else: createRandomFile(rndfile) runUtil(certutil, [ "-D", "-n", "pgo server certificate", "-d", srcDir, "-z", rndfile.name, "-f", pwfile.name ]) # Ignore the result, the certificate may not be present when new database is being built status = runUtil(certutil, [ "-S", "-s", "CN=%s" % firstLocation, "-t", "Pu,,", "-c", "pgo temporary ca", "-m", "2", "-8", locationsParam, "-v", "120", "-n", "pgo server certificate", "-d", srcDir, "-z", rndfile.name, "-f", pwfile.name ]) if status: return status return 0