зеркало из https://github.com/mozilla/gecko-dev.git
Bug 958897 - ssltunnel lives if mochitest killed. r=jmaher
[PATCH] Made Mochitest.runApp() clean up after itself in case of exception
This commit is contained in:
Родитель
b253190ddb
Коммит
a844a7ae48
|
@ -907,149 +907,152 @@ class Mochitest(MochitestUtilsMixin):
|
||||||
# copy env so we don't munge the caller's environment
|
# copy env so we don't munge the caller's environment
|
||||||
env = env.copy()
|
env = env.copy()
|
||||||
|
|
||||||
# set process log environment variable
|
# make sure we clean up after ourselves.
|
||||||
tmpfd, processLog = tempfile.mkstemp(suffix='pidlog')
|
try:
|
||||||
os.close(tmpfd)
|
# set process log environment variable
|
||||||
env["MOZ_PROCESS_LOG"] = processLog
|
tmpfd, processLog = tempfile.mkstemp(suffix='pidlog')
|
||||||
|
os.close(tmpfd)
|
||||||
|
env["MOZ_PROCESS_LOG"] = processLog
|
||||||
|
|
||||||
if self.runSSLTunnel:
|
if self.runSSLTunnel:
|
||||||
|
|
||||||
# create certificate database for the profile
|
# create certificate database for the profile
|
||||||
# TODO: this should really be upstreamed somewhere, maybe mozprofile
|
# TODO: this should really be upstreamed somewhere, maybe mozprofile
|
||||||
certificateStatus = self.fillCertificateDB(self.profile.profile,
|
certificateStatus = self.fillCertificateDB(self.profile.profile,
|
||||||
certPath,
|
certPath,
|
||||||
utilityPath,
|
utilityPath,
|
||||||
xrePath)
|
xrePath)
|
||||||
if certificateStatus:
|
if certificateStatus:
|
||||||
log.info("TEST-UNEXPECTED-FAIL | runtests.py | Certificate integration failed")
|
log.info("TEST-UNEXPECTED-FAIL | runtests.py | Certificate integration failed")
|
||||||
return certificateStatus
|
return certificateStatus
|
||||||
|
|
||||||
# start ssltunnel to provide https:// URLs capability
|
# start ssltunnel to provide https:// URLs capability
|
||||||
ssltunnel = os.path.join(utilityPath, "ssltunnel" + bin_suffix)
|
ssltunnel = os.path.join(utilityPath, "ssltunnel" + bin_suffix)
|
||||||
ssltunnel_cfg = os.path.join(self.profile.profile, "ssltunnel.cfg")
|
ssltunnel_cfg = os.path.join(self.profile.profile, "ssltunnel.cfg")
|
||||||
ssltunnelProcess = mozprocess.ProcessHandler([ssltunnel, ssltunnel_cfg],
|
ssltunnelProcess = mozprocess.ProcessHandler([ssltunnel, ssltunnel_cfg],
|
||||||
env=environment(xrePath=xrePath))
|
env=environment(xrePath=xrePath))
|
||||||
ssltunnelProcess.run()
|
ssltunnelProcess.run()
|
||||||
log.info("INFO | runtests.py | SSL tunnel pid: %d", ssltunnelProcess.pid)
|
log.info("INFO | runtests.py | SSL tunnel pid: %d", ssltunnelProcess.pid)
|
||||||
else:
|
else:
|
||||||
ssltunnelProcess = None
|
ssltunnelProcess = None
|
||||||
|
|
||||||
if interactive:
|
if interactive:
|
||||||
# If an interactive debugger is attached,
|
# If an interactive debugger is attached,
|
||||||
# don't use timeouts, and don't capture ctrl-c.
|
# don't use timeouts, and don't capture ctrl-c.
|
||||||
timeout = None
|
timeout = None
|
||||||
signal.signal(signal.SIGINT, lambda sigid, frame: None)
|
signal.signal(signal.SIGINT, lambda sigid, frame: None)
|
||||||
|
|
||||||
# build command line
|
# build command line
|
||||||
cmd = os.path.abspath(app)
|
cmd = os.path.abspath(app)
|
||||||
args = list(extraArgs)
|
args = list(extraArgs)
|
||||||
# TODO: mozrunner should use -foreground at least for mac
|
# TODO: mozrunner should use -foreground at least for mac
|
||||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=916512
|
# https://bugzilla.mozilla.org/show_bug.cgi?id=916512
|
||||||
args.append('-foreground')
|
args.append('-foreground')
|
||||||
if testUrl:
|
if testUrl:
|
||||||
if debuggerInfo and debuggerInfo['requiresEscapedArgs']:
|
if debuggerInfo and debuggerInfo['requiresEscapedArgs']:
|
||||||
testUrl = testUrl.replace("&", "\\&")
|
testUrl = testUrl.replace("&", "\\&")
|
||||||
args.append(testUrl)
|
args.append(testUrl)
|
||||||
|
|
||||||
if mozinfo.info["debug"] and not webapprtChrome:
|
if mozinfo.info["debug"] and not webapprtChrome:
|
||||||
shutdownLeaks = ShutdownLeaks(log.info)
|
shutdownLeaks = ShutdownLeaks(log.info)
|
||||||
else:
|
else:
|
||||||
shutdownLeaks = None
|
shutdownLeaks = None
|
||||||
|
|
||||||
# create an instance to process the output
|
# create an instance to process the output
|
||||||
outputHandler = self.OutputHandler(harness=self,
|
outputHandler = self.OutputHandler(harness=self,
|
||||||
utilityPath=utilityPath,
|
utilityPath=utilityPath,
|
||||||
symbolsPath=symbolsPath,
|
symbolsPath=symbolsPath,
|
||||||
dump_screen_on_timeout=not debuggerInfo,
|
dump_screen_on_timeout=not debuggerInfo,
|
||||||
hide_subtests=hide_subtests,
|
hide_subtests=hide_subtests,
|
||||||
shutdownLeaks=shutdownLeaks,
|
shutdownLeaks=shutdownLeaks,
|
||||||
)
|
)
|
||||||
|
|
||||||
def timeoutHandler():
|
def timeoutHandler():
|
||||||
outputHandler.log_output_buffer()
|
outputHandler.log_output_buffer()
|
||||||
browserProcessId = outputHandler.browserProcessId
|
browserProcessId = outputHandler.browserProcessId
|
||||||
self.handleTimeout(timeout, proc, utilityPath, debuggerInfo, browserProcessId)
|
self.handleTimeout(timeout, proc, utilityPath, debuggerInfo, browserProcessId)
|
||||||
kp_kwargs = {'kill_on_timeout': False,
|
kp_kwargs = {'kill_on_timeout': False,
|
||||||
'onTimeout': [timeoutHandler]}
|
'onTimeout': [timeoutHandler]}
|
||||||
kp_kwargs['processOutputLine'] = [outputHandler]
|
kp_kwargs['processOutputLine'] = [outputHandler]
|
||||||
|
|
||||||
# create mozrunner instance and start the system under test process
|
# create mozrunner instance and start the system under test process
|
||||||
self.lastTestSeen = self.test_name
|
self.lastTestSeen = self.test_name
|
||||||
startTime = datetime.now()
|
startTime = datetime.now()
|
||||||
|
|
||||||
# b2g desktop requires FirefoxRunner even though appname is b2g
|
# b2g desktop requires FirefoxRunner even though appname is b2g
|
||||||
if mozinfo.info.get('appname') == 'b2g' and mozinfo.info.get('toolkit') != 'gonk':
|
if mozinfo.info.get('appname') == 'b2g' and mozinfo.info.get('toolkit') != 'gonk':
|
||||||
runner_cls = mozrunner.FirefoxRunner
|
runner_cls = mozrunner.FirefoxRunner
|
||||||
else:
|
else:
|
||||||
runner_cls = mozrunner.runners.get(mozinfo.info.get('appname', 'firefox'),
|
runner_cls = mozrunner.runners.get(mozinfo.info.get('appname', 'firefox'),
|
||||||
mozrunner.Runner)
|
mozrunner.Runner)
|
||||||
runner = runner_cls(profile=self.profile,
|
runner = runner_cls(profile=self.profile,
|
||||||
binary=cmd,
|
binary=cmd,
|
||||||
cmdargs=args,
|
cmdargs=args,
|
||||||
env=env,
|
env=env,
|
||||||
process_class=mozprocess.ProcessHandlerMixin,
|
process_class=mozprocess.ProcessHandlerMixin,
|
||||||
kp_kwargs=kp_kwargs,
|
kp_kwargs=kp_kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
# XXX work around bug 898379 until mozrunner is updated for m-c; see
|
# XXX work around bug 898379 until mozrunner is updated for m-c; see
|
||||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=746243#c49
|
# https://bugzilla.mozilla.org/show_bug.cgi?id=746243#c49
|
||||||
runner.kp_kwargs = kp_kwargs
|
runner.kp_kwargs = kp_kwargs
|
||||||
|
|
||||||
# start the runner
|
# start the runner
|
||||||
runner.start(debug_args=debug_args,
|
runner.start(debug_args=debug_args,
|
||||||
interactive=interactive,
|
interactive=interactive,
|
||||||
outputTimeout=timeout)
|
outputTimeout=timeout)
|
||||||
proc = runner.process_handler
|
proc = runner.process_handler
|
||||||
log.info("INFO | runtests.py | Application pid: %d", proc.pid)
|
log.info("INFO | runtests.py | Application pid: %d", proc.pid)
|
||||||
|
|
||||||
if onLaunch is not None:
|
if onLaunch is not None:
|
||||||
# Allow callers to specify an onLaunch callback to be fired after the
|
# Allow callers to specify an onLaunch callback to be fired after the
|
||||||
# app is launched.
|
# app is launched.
|
||||||
# We call onLaunch for b2g desktop mochitests so that we can
|
# We call onLaunch for b2g desktop mochitests so that we can
|
||||||
# run a Marionette script after gecko has completed startup.
|
# run a Marionette script after gecko has completed startup.
|
||||||
onLaunch()
|
onLaunch()
|
||||||
|
|
||||||
# wait until app is finished
|
# wait until app is finished
|
||||||
# XXX copy functionality from
|
# XXX copy functionality from
|
||||||
# https://github.com/mozilla/mozbase/blob/master/mozrunner/mozrunner/runner.py#L61
|
# https://github.com/mozilla/mozbase/blob/master/mozrunner/mozrunner/runner.py#L61
|
||||||
# until bug 913970 is fixed regarding mozrunner `wait` not returning status
|
# until bug 913970 is fixed regarding mozrunner `wait` not returning status
|
||||||
# see https://bugzilla.mozilla.org/show_bug.cgi?id=913970
|
# see https://bugzilla.mozilla.org/show_bug.cgi?id=913970
|
||||||
status = proc.wait()
|
status = proc.wait()
|
||||||
runner.process_handler = None
|
runner.process_handler = None
|
||||||
|
|
||||||
if timeout is None:
|
if timeout is None:
|
||||||
didTimeout = False
|
didTimeout = False
|
||||||
else:
|
else:
|
||||||
didTimeout = proc.didTimeout
|
didTimeout = proc.didTimeout
|
||||||
|
|
||||||
# finalize output handler
|
# finalize output handler
|
||||||
outputHandler.finish(didTimeout)
|
outputHandler.finish(didTimeout)
|
||||||
|
|
||||||
# record post-test information
|
# record post-test information
|
||||||
if status:
|
if status:
|
||||||
log.info("TEST-UNEXPECTED-FAIL | %s | application terminated with exit code %s", self.lastTestSeen, status)
|
log.info("TEST-UNEXPECTED-FAIL | %s | application terminated with exit code %s", self.lastTestSeen, status)
|
||||||
else:
|
else:
|
||||||
self.lastTestSeen = 'Main app process exited normally'
|
self.lastTestSeen = 'Main app process exited normally'
|
||||||
|
|
||||||
log.info("INFO | runtests.py | Application ran for: %s", str(datetime.now() - startTime))
|
log.info("INFO | runtests.py | Application ran for: %s", str(datetime.now() - startTime))
|
||||||
|
|
||||||
# Do a final check for zombie child processes.
|
# Do a final check for zombie child processes.
|
||||||
zombieProcesses = self.checkForZombies(processLog, utilityPath, debuggerInfo)
|
zombieProcesses = self.checkForZombies(processLog, utilityPath, debuggerInfo)
|
||||||
|
|
||||||
# check for crashes
|
# check for crashes
|
||||||
minidump_path = os.path.join(self.profile.profile, "minidumps")
|
minidump_path = os.path.join(self.profile.profile, "minidumps")
|
||||||
crashed = mozcrash.check_for_crashes(minidump_path,
|
crashed = mozcrash.check_for_crashes(minidump_path,
|
||||||
symbolsPath,
|
symbolsPath,
|
||||||
test_name=self.lastTestSeen)
|
test_name=self.lastTestSeen)
|
||||||
|
|
||||||
if crashed or zombieProcesses:
|
if crashed or zombieProcesses:
|
||||||
status = 1
|
status = 1
|
||||||
|
|
||||||
# cleanup
|
finally:
|
||||||
if os.path.exists(processLog):
|
# cleanup
|
||||||
os.remove(processLog)
|
if os.path.exists(processLog):
|
||||||
if ssltunnelProcess:
|
os.remove(processLog)
|
||||||
ssltunnelProcess.kill()
|
if ssltunnelProcess:
|
||||||
|
ssltunnelProcess.kill()
|
||||||
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче