diff --git a/tmt/steps/report/reportportal.py b/tmt/steps/report/reportportal.py index b4a692b0bb..00e8c38e42 100644 --- a/tmt/steps/report/reportportal.py +++ b/tmt/steps/report/reportportal.py @@ -16,6 +16,7 @@ JSON: 'TypeAlias' = Any DEFAULT_LOG_SIZE_LIMIT: int = 1024 * 1024 +DEFAULT_TRACEBACK_SIZE_LIMIT: int = 100 * 1024 def _flag_env_to_default(option: str, default: bool) -> bool: @@ -42,19 +43,31 @@ def _str_env_to_default(option: str, default: Optional[str]) -> Optional[str]: return str(os.getenv(env_var)) -def _filter_invalid_chars(data: str, step_data: 'ReportReportPortalData') -> str: +def _filter_invalid_chars(data: str, + step_data: 'ReportReportPortalData', + is_traceback: bool = False) -> str: return re.sub( '[^\u0020-\uD7FF\u0009\u000A\u000D\uE000-\uFFFD\U00010000-\U0010FFFF]+', '', data) -def _filter_log_per_size(data: str, step_data: 'ReportReportPortalData') -> str: +def _filter_log_per_size(data: str, + step_data: 'ReportReportPortalData', + is_traceback: bool = False) -> str: size = len(data) + if is_traceback: + limit = step_data.traceback_size_limit + variable = "TMT_PLUGIN_REPORT_REPORTPORTAL_LOG_SIZE_LIMIT" + option = "--traceback-size-limit" + else: + limit = step_data.log_size_limit + variable = "TMT_PLUGIN_REPORT_REPORTPORTAL_LOG_SIZE_LIMIT" + option = "--log-size-limit" header = (f"WARNING: Uploaded log has been truncated because its size {size} bytes " - f"exceeds tmt reportportal plugin limit of {step_data.log_size_limit} bytes." - "The limit is controlled with --log-size-limit plugin option or" - "TMT_PLUGIN_REPORT_REPORTPORTAL_LOG_SIZE_LIMIT environment variable.\n\n") + f"exceeds tmt reportportal plugin limit of {limit} bytes." + f"The limit is controlled with {option} plugin option or" + f"{variable} environment variable.\n\n") if size > step_data.log_size_limit: return f"{header}{data[:step_data.log_size_limit]}" return data @@ -66,9 +79,9 @@ def _filter_log_per_size(data: str, step_data: 'ReportReportPortalData') -> str: ] -def _filter_log(log: str, step_data: 'ReportReportPortalData') -> str: +def _filter_log(log: str, step_data: 'ReportReportPortalData', is_traceback: bool = False) -> str: for log_filter in _LOG_FILTERS: - log = log_filter(log, step_data) + log = log_filter(log, step_data, is_traceback = is_traceback) return log @@ -177,6 +190,17 @@ class ReportReportPortalData(tmt.steps.report.ReportStepData): ({DEFAULT_LOG_SIZE_LIMIT / 1024 / 1024} MB). """) + traceback_size_limit: int = field( + option="--traceback-size-limit", + metavar="TRACEBACK_SIZE_LIMIT", + default=int( + _str_env_to_default('traceback_size_limit', str(DEFAULT_TRACEBACK_SIZE_LIMIT))), + help=f""" + Size limit in bytes for traceback log upload to ReportPortal. + The default limit is {DEFAULT_TRACEBACK_SIZE_LIMIT} bytes + ({DEFAULT_TRACEBACK_SIZE_LIMIT / 1024 } kB). + """) + exclude_variables: str = field( option="--exclude-variables", metavar="PATTERN", @@ -653,7 +677,9 @@ def go(self, *, logger: Optional[tmt.log.Logger] = None) -> None: # Write out failures if index == 0 and status == "FAILED": - message = _filter_log(result.failures(log), self.data) + message = _filter_log(result.failures(log), + self.data, + is_traceback=True) response = self.rp_api_post( session=session, path="log/entry",