Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions test/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,14 @@ def is_firefox():
return EMTEST_BROWSER and 'firefox' in EMTEST_BROWSER.lower()


def get_browser_config():
if is_chrome():
return ChromeConfig()
elif is_firefox():
return FirefoxConfig()
return None


def compiler_for(filename, force_c=False):
if shared.suffix(filename) in ('.cc', '.cxx', '.cpp') and not force_c:
return EMXX
Expand Down Expand Up @@ -2413,11 +2421,7 @@ def configure_test_browser():
EMTEST_BROWSER = '"' + EMTEST_BROWSER.replace("\\", "\\\\") + '"'

if EMTEST_BROWSER_AUTO_CONFIG:
config = None
if is_chrome():
config = ChromeConfig()
elif is_firefox():
config = FirefoxConfig()
config = get_browser_config()
if config:
EMTEST_BROWSER += ' ' + ' '.join(config.default_flags)
if EMTEST_HEADLESS == 1:
Expand All @@ -2438,6 +2442,22 @@ def list_processes_by_name(exe_name):
return pids


def terminate_list_of_processes(proc_list):
for proc in proc_list:
try:
proc.terminate()
# If the browser doesn't shut down gracefully (in response to SIGTERM)
# after 2 seconds kill it with force (SIGKILL).
try:
proc.wait(2)
except (subprocess.TimeoutExpired, psutil.TimeoutExpired):
logger.info('Browser did not respond to `terminate`. Using `kill`')
proc.kill()
proc.wait()
except (psutil.NoSuchProcess, ProcessLookupError):
pass


class FileLock:
"""Implements a filesystem-based mutex, with an additional feature that it
returns an integer counter denoting how many times the lock has been locked
Expand Down Expand Up @@ -2522,19 +2542,7 @@ def __init__(self, *args, **kwargs):

@classmethod
def browser_terminate(cls):
for proc in cls.browser_procs:
try:
proc.terminate()
# If the browser doesn't shut down gracefully (in response to SIGTERM)
# after 2 seconds kill it with force (SIGKILL).
try:
proc.wait(2)
except (subprocess.TimeoutExpired, psutil.TimeoutExpired):
logger.info('Browser did not respond to `terminate`. Using `kill`')
proc.kill()
proc.wait()
except (psutil.NoSuchProcess, ProcessLookupError):
pass
terminate_list_of_processes(cls.browser_procs)

@classmethod
def browser_restart(cls):
Expand Down Expand Up @@ -2567,11 +2575,8 @@ def browser_open(cls, url):
# Recreate the new data directory.
os.mkdir(browser_data_dir)

if is_chrome():
config = ChromeConfig()
elif is_firefox():
config = FirefoxConfig()
else:
config = get_browser_config()
if not config:
exit_with_error(f'EMTEST_BROWSER_AUTO_CONFIG only currently works with firefox or chrome. EMTEST_BROWSER was "{EMTEST_BROWSER}"')
if WINDOWS:
# Escape directory delimiter backslashes for shlex.split.
Expand Down
13 changes: 13 additions & 0 deletions test/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ def parse_args():
'Useful when combined with --failfast')
parser.add_argument('--force64', action='store_true')
parser.add_argument('--crossplatform-only', action='store_true')
parser.add_argument('--force-browser-process-termination', action='store_true', help='If true, a fail-safe method is used to ensure that all browser processes are terminated before and after the test suite run. Note that this option will terminate all browser processes, not just those launched by the harness, so will result in loss of all open browsing sessions.')
parser.add_argument('--repeat', type=int, default=1,
help='Repeat each test N times (default: 1).')
parser.add_argument('--bell', action='store_true', help='Play a sound after the test suite finishes.')
Expand Down Expand Up @@ -566,6 +567,18 @@ def set_env(name, option_value):
utils.delete_file(common.flaky_tests_log_filename)
utils.delete_file(common.browser_spawn_lock_filename)
utils.delete_file(f'{common.browser_spawn_lock_filename}_counter')
if options.force_browser_process_termination or os.getenv('EMTEST_FORCE_BROWSER_PROCESS_TERMINATION'):
config = common.get_browser_config()

def terminate_all_browser_processes():
procs = common.list_processes_by_name(config.executable_name)
if len(procs) > 0:
print(f'Terminating {len(procs)} stray browser processes.')
common.terminate_list_of_processes(procs)

if config and hasattr(config, 'executable_name'):
atexit.register(terminate_all_browser_processes)
terminate_all_browser_processes()

def prepend_default(arg):
if arg.startswith('test_'):
Expand Down