[FIX] core: skip marking completed tours as failed, restore had_failure
Succeeds #140464 Misunderstood `had_failure` and should not have reused it, its goal is to avoid eagerly aborting some JS tests -- specifically the unit test suites -- while still logging errors normally (useful when watching interactively, or for the runbot's own reporting). So the *checks* added on `had_failure` should in fact be checks on `_result.exception()`, and as it turns out on `_result.done()`: if a tour is already marked as successful we can't fail it either. So we should not, we should log an error (to notify the caller / runbot) and then bail. While #140464 did improve some things, we could still lose legit errors and get pages of unhelpful `InvalidStateError` if a tour would succeed *then* failures would occur, as the guard only checked that the tour had already failed. closes odoo/odoo#141815 X-original-commit: 87fcf66203dcbd281470285d648365d33d0e2fca Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
+20
-20
@@ -917,6 +917,7 @@ class ChromeBrowser:
|
||||
self._request_id = itertools.count()
|
||||
self._result = Future()
|
||||
self.error_checker = None
|
||||
self.had_failure = False
|
||||
# maps request_id to Futures
|
||||
self._responses = {}
|
||||
# maps frame ids to callbacks
|
||||
@@ -942,12 +943,6 @@ class ChromeBrowser:
|
||||
def screencasts_frames_dir(self):
|
||||
return os.path.join(self.screencasts_dir, 'frames')
|
||||
|
||||
@property
|
||||
def had_failure(self):
|
||||
with contextlib.suppress(concurrent.futures.TimeoutError, CancelledError):
|
||||
return self._result.exception(timeout=0) is not None
|
||||
return False
|
||||
|
||||
def signal_handler(self, sig, frame):
|
||||
if sig == signal.SIGXCPU:
|
||||
_logger.info('CPU time limit reached, stopping Chrome and shutting down')
|
||||
@@ -1243,13 +1238,17 @@ class ChromeBrowser:
|
||||
message += '\n' + stack
|
||||
|
||||
log_type = type
|
||||
self._logger.getChild('browser').log(
|
||||
_logger = self._logger.getChild('browser')
|
||||
_logger.log(
|
||||
self._TO_LEVEL.get(log_type, logging.INFO),
|
||||
"%s", message # might still have %<x> characters
|
||||
"%s%s",
|
||||
"Error received after termination: " if self._result.done() else "",
|
||||
message # might still have %<x> characters
|
||||
)
|
||||
|
||||
if log_type == 'error':
|
||||
if self.had_failure:
|
||||
self.had_failure = True
|
||||
if self._result.done():
|
||||
return
|
||||
if not self.error_checker or self.error_checker(message):
|
||||
self.take_screenshot()
|
||||
@@ -1283,23 +1282,23 @@ class ChromeBrowser:
|
||||
|
||||
if node_id:
|
||||
self.take_screenshot("unsaved_form_")
|
||||
self._result.set_exception(ChromeBrowserException("""\
|
||||
msg = """\
|
||||
Tour finished with an open form view in edition mode.
|
||||
|
||||
Form views in edition mode are automatically saved when the page is closed, \
|
||||
which leads to stray network requests and inconsistencies."""))
|
||||
which leads to stray network requests and inconsistencies."""
|
||||
if self._result.done():
|
||||
_logger.error("%s", msg)
|
||||
else:
|
||||
self._result.set_exception(ChromeBrowserException(msg))
|
||||
return
|
||||
|
||||
try:
|
||||
if not self._result.done():
|
||||
self._result.set_result(True)
|
||||
except Exception:
|
||||
elif self._result.exception() is None:
|
||||
# if the future was already failed, we're happy,
|
||||
# otherwise swap for a new failed
|
||||
if self._result.exception() is None:
|
||||
self._result = Future()
|
||||
self._result.set_exception(ChromeBrowserException(
|
||||
"Tried to make the tour successful twice."
|
||||
))
|
||||
_logger.error("Tried to make the tour successful twice.")
|
||||
|
||||
|
||||
def _handle_exception(self, exceptionDetails, timestamp):
|
||||
@@ -1312,8 +1311,9 @@ which leads to stray network requests and inconsistencies."""))
|
||||
if stack:
|
||||
message += '\n' + stack
|
||||
|
||||
if self.had_failure:
|
||||
self._logger.getChild('browser').error("%s", message)
|
||||
if self._result.done():
|
||||
self._logger.getChild('browser').error(
|
||||
"Exception received after termination: %s", message)
|
||||
return
|
||||
|
||||
self.take_screenshot()
|
||||
|
||||
Reference in New Issue
Block a user