blob: 41cea6d72fc49fc0b2051b57429be6a718a3da48 [file] [log] [blame]
# Copyright 2025 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Module for reporting test results to ResultDB."""
import sys
import base64
import constants
import metrics
import results
sys.path.insert(0, str(constants.CHROMIUM_SRC / 'build' / 'util'))
from lib.results import result_sink
from lib.results import result_types
class ResultDBReporter:
"""Encapsulates state necessary to upload results to ResultDB."""
def __init__(self):
self._result_sink_client = result_sink.TryInitClient()
def report_result(self, test_result: results.TestResult) -> None:
"""Reports data from a TestResult to ResultDB.
No-op if ResultDB integration is not available.
Args:
test_result: A TestResult instance containing the result to report.
"""
if not self._result_sink_client:
return
relative_path = test_result.config.test_file.relative_to(
constants.CHROMIUM_SRC)
posix_path = relative_path.as_posix()
for iteration_result in test_result.iteration_results:
tags = [(name.replace('.', '_').lower(), str(value))
for name, value in metrics.iterate_over_nested_metrics(
iteration_result.metrics)]
tags.extend([('tag', tag) for tag in test_result.config.tags])
owner = test_result.config.owner
if owner:
tags.append(('owner', owner))
artifacts = {}
prompt = iteration_result.prompt
if prompt:
b64_prompt = base64.b64encode(prompt.encode()).decode()
artifacts.update({
'Prompt': {
'contents': b64_prompt,
'content_type': 'text/plain',
}
})
response = iteration_result.response
if response:
b64_response = base64.b64encode(response.encode()).decode()
artifacts.update({
'Response': {
'contents': b64_response,
'content_type': 'text/plain',
}
})
self._result_sink_client.Post(
test_id=str(posix_path),
status=(result_types.PASS
if iteration_result.success else result_types.FAIL),
duration=iteration_result.duration * 1000,
test_log=iteration_result.test_log,
test_id_structured={
'coarseName': '', # Leave blank for scheme 'flat'.
'fineName': '', # Leave blank for scheme 'flat'.
'caseNameComponents': [str(posix_path)],
},
test_file=f'//{str(posix_path)}',
tags=tags,
artifacts=artifacts,
)