Skip to content

Commit 38fad87

Browse files
committed
[IMP] odoo/tests: reporting & handling of chrome start issues
If we can't find the devtools port file after 10 seconds we skip the test, however - this is an invisible error because the runbot does not surface skipped tests, so this specific variant should also have a warning (also the skip from not finding a chrome executable) - if chrome started but got stuck before it managed to create the port file we don't `stop` the chromebrowser as it never finished starting, however this means we leave a chrome running in the void a `user_data_dir` littering the machine / vm's tempdir So improve the handling of that bit. Also have chrome write its stderr to a file (in the `user_data_dir`) so we can log that out in case it contains useful information as to why chrome didn't finish booting. While at it backport the spawn changes from odoo#206574 for consistency and simplicity: we don't need to test the platform for every single tour and the indirection makes updating the `Popen` parameters unnecessary complicated. closes odoo#232612 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
1 parent cc19c28 commit 38fad87

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

odoo/tests/common.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,17 @@ def save_test_file(test_name, content, prefix, extension='png', logger=_logger,
920920
logger.runbot(f'{document_type} in: {full_path}')
921921

922922

923+
if os.name == 'posix' and platform.system() != 'Darwin':
924+
# since the introduction of pointer compression in Chrome 80 (v8 v8.0),
925+
# the memory reservation algorithm requires more than 8GiB of
926+
# virtual mem for alignment this exceeds our default memory limits.
927+
def _preexec():
928+
import resource # noqa: PLC0415
929+
resource.setrlimit(resource.RLIMIT_AS, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
930+
else:
931+
_preexec = None
932+
933+
923934
class ChromeBrowser:
924935
""" Helper object to control a Chrome headless process. """
925936
remote_debugging_port = 0 # 9222, change it in a non-git-tracked file
@@ -1049,31 +1060,35 @@ def executable(self):
10491060
if os.path.exists(bin_):
10501061
return bin_
10511062

1063+
self._logger.warning('Chrome executable not found')
10521064
raise unittest.SkipTest("Chrome executable not found")
10531065

1054-
def _chrome_without_limit(self, cmd):
1055-
if os.name == 'posix' and platform.system() != 'Darwin':
1056-
# since the introduction of pointer compression in Chrome 80 (v8 v8.0),
1057-
# the memory reservation algorithm requires more than 8GiB of
1058-
# virtual mem for alignment this exceeds our default memory limits.
1059-
def preexec():
1060-
import resource
1061-
resource.setrlimit(resource.RLIMIT_AS, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
1062-
else:
1063-
preexec = None
1064-
1065-
# pylint: disable=subprocess-popen-preexec-fn
1066-
return subprocess.Popen(cmd, stderr=subprocess.DEVNULL, preexec_fn=preexec)
1067-
10681066
def _spawn_chrome(self, cmd):
1069-
proc = self._chrome_without_limit(cmd)
1067+
log_path = pathlib.Path(self.user_data_dir, 'err.log')
1068+
with log_path.open('wb') as log_file:
1069+
# pylint: disable=subprocess-popen-preexec-fn
1070+
proc = subprocess.Popen(cmd, stderr=log_file, preexec_fn=_preexec) # noqa: PLW1509
1071+
10701072
port_file = pathlib.Path(self.user_data_dir, 'DevToolsActivePort')
10711073
for _ in range(CHECK_BROWSER_ITERATIONS):
10721074
time.sleep(CHECK_BROWSER_SLEEP)
10731075
if port_file.is_file() and port_file.stat().st_size > 5:
10741076
with port_file.open('r', encoding='utf-8') as f:
10751077
self.devtools_port = int(f.readline())
10761078
return proc.pid
1079+
1080+
if proc.poll() is None:
1081+
proc.terminate()
1082+
try:
1083+
proc.wait(5)
1084+
except subprocess.TimeoutExpired:
1085+
proc.kill()
1086+
proc.wait()
1087+
self._logger.warning('Chrome headless failed to start:\n%s', log_path.read_text(encoding="utf-8"))
1088+
# since the chrome never started, it's not going to be `stop`-ed so we
1089+
# need to cleanup the directory here
1090+
shutil.rmtree(self.user_data_dir, ignore_errors=True)
1091+
10771092
raise unittest.SkipTest(f'Failed to detect chrome devtools port after {BROWSER_WAIT :.1f}s.')
10781093

10791094
def _chrome_start(self):

0 commit comments

Comments
 (0)