Bug 1438679 - [mozrunner] DeviceRunner has to override returncode and wait() to check for remote process status. r=gbrown

Without returncode and wait() being overridden the default
implementation of the Runner class takes precedence and will
run the check for the adb command but not the remote process.
This always returns 0 because adb runs or forks itself as daemon.

Instead the remote process has to be checked for existence.

MozReview-Commit-ID: GvuAaMSxBT2

--HG--
extra : rebase_source : e84b52fdc9ce48617102650d6d0ae73e90899538
This commit is contained in:
Henrik Skupin 2018-02-22 23:08:49 +01:00
Родитель e085aaa596
Коммит f5e866d199
1 изменённых файлов: 38 добавлений и 22 удалений

Просмотреть файл

@ -82,11 +82,9 @@ class DeviceRunner(BaseRunner):
pid = BaseRunner.start(self, *args, **kwargs) pid = BaseRunner.start(self, *args, **kwargs)
timeout = 10 # seconds timeout = 10 # seconds
starttime = datetime.datetime.now() end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
while datetime.datetime.now() - starttime < datetime.timedelta(seconds=timeout): while not self.is_running() and datetime.datetime.now() < end_time:
if self.is_running(): time.sleep(.1)
break
time.sleep(1)
else: else:
print("timed out waiting for '%s' process to start" % self.app_ctx.remote_process) print("timed out waiting for '%s' process to start" % self.app_ctx.remote_process)
@ -95,34 +93,52 @@ class DeviceRunner(BaseRunner):
return pid return pid
def stop(self, sig=None): def stop(self, sig=None):
def _wait_for_shutdown(pid, timeout=10): if self.is_running():
start_time = datetime.datetime.now() timeout = 10
end_time = datetime.timedelta(seconds=timeout)
while datetime.datetime.now() - start_time < end_time:
if self.is_running() != pid:
return True
time.sleep(1)
return False
remote_pid = self.is_running() self.app_ctx.dm.killProcess(self.app_ctx.remote_process, sig=sig)
if remote_pid: if self.wait(timeout) is None and sig is not None:
self.app_ctx.dm.killProcess(
self.app_ctx.remote_process, sig=sig)
if not _wait_for_shutdown(remote_pid) and sig is not None:
print("timed out waiting for '%s' process to exit, trying " print("timed out waiting for '%s' process to exit, trying "
"without signal {}".format( "without signal {}".format(
self.app_ctx.remote_process, sig)) self.app_ctx.remote_process, sig))
# need to call adb stop otherwise the system will attempt to # need to call adb stop otherwise the system will attempt to
# restart the process # restart the process
remote_pid = self.is_running() or remote_pid
self.app_ctx.stop_application() self.app_ctx.stop_application()
if not _wait_for_shutdown(remote_pid): if self.wait(timeout) is None:
print("timed out waiting for '%s' process to exit".format( print("timed out waiting for '%s' process to exit".format(
self.app_ctx.remote_process)) self.app_ctx.remote_process))
def is_running(self): @property
return self.app_ctx.dm.processExist(self.app_ctx.remote_process) def returncode(self):
"""The returncode of the remote process.
A value of None indicates the process is still running. Otherwise 0 is
returned, because there is no known way yet to retrieve the real exit code.
"""
if self.app_ctx.dm.processExist(self.app_ctx.remote_process) is None:
return 0
return None
def wait(self, timeout=None):
"""Wait for the remote process to exit.
:param timeout: if not None, will return after timeout seconds.
:returns: the process return code or None if timeout was reached
and the process is still running.
"""
end_time = None
if timeout is not None:
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
while self.is_running():
if end_time is not None and datetime.datetime.now() > end_time:
break
time.sleep(.1)
return self.returncode
def on_output(self, line): def on_output(self, line):
match = re.findall(r"TEST-START \| ([^\s]*)", line) match = re.findall(r"TEST-START \| ([^\s]*)", line)