15 """Helps with running bazel with extra settings to generate structured test reports in CI."""
23 _ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]),
'../../..'))
29 _UPLOAD_RBE_RESULTS_DELAY_SECONDS = 60
33 """Detect current platform"""
34 if platform.system() ==
'Windows':
36 elif platform.system()[:7] ==
'MSYS_NT':
38 elif platform.system() ==
'Darwin':
40 elif platform.system() ==
'Linux':
47 """Kokoro can display "Bazel" result link on kokoro jobs if told so."""
50 kokoro_artifacts_dir = os.getenv(
'KOKORO_ARTIFACTS_DIR')
51 if kokoro_artifacts_dir:
53 with open(os.path.join(kokoro_artifacts_dir,
'bazel_invocation_ids'),
55 f.write(invocation_id +
'\n')
57 'Added invocation ID %s to kokoro "bazel_invocation_ids" artifact' %
62 'Skipped adding invocation ID %s to kokoro "bazel_invocation_ids" artifact'
69 success: bool) ->
None:
70 """Generate sponge_log.xml formatted report, that will make the bazel invocation reachable as a target in resultstore UI / sponge."""
71 bazel_invocation_url =
'https://source.cloud.google.com/results/invocations/%s' % invocation_id
72 package_name = report_suite_name
75 testcase_name = bazel_invocation_url
79 test_output_tag =
'<system-err>PASSED. See invocation results here: %s</system-err>' % bazel_invocation_url
82 test_output_tag =
'<failure message="Failure">FAILED. See bazel invocation results here: %s</failure>' % bazel_invocation_url
86 '<testsuite id="1" name="%s" package="%s">' %
87 (report_suite_name, package_name),
88 '<testcase name="%s">' % testcase_name,
94 return '\n'.join(lines)
98 invocation_id: str, upload_results: bool) ->
None:
99 """Create a "bazel wrapper" script that will execute bazel with extra settings and postprocessing."""
101 os.makedirs(report_path, exist_ok=
True)
103 bazel_wrapper_filename = os.path.join(report_path,
'bazel_wrapper')
104 bazel_wrapper_bat_filename = bazel_wrapper_filename +
'.bat'
105 bazel_rc_filename = os.path.join(report_path,
'bazel_wrapper.bazelrc')
108 report_base_dir = os.getenv(
'GRPC_TEST_REPORT_BASE_DIR',
None)
109 xml_report_path = os.path.abspath(
110 os.path.join(report_base_dir, report_path
111 )
if report_base_dir
else report_path)
112 os.makedirs(xml_report_path, exist_ok=
True)
114 failing_report_filename = os.path.join(xml_report_path,
'sponge_log.xml')
115 success_report_filename = os.path.join(xml_report_path,
116 'success_log_to_rename.xml')
119 workspace_status_command =
'tools/remote_build/workspace_status_kokoro.bat'
121 workspace_status_command =
'tools/remote_build/workspace_status_kokoro.sh'
126 with open(bazel_rc_filename,
'w')
as f:
127 f.write(
'build --invocation_id="%s"\n' % invocation_id)
128 f.write(
'build --workspace_status_command="%s"\n' %
129 workspace_status_command)
136 with open(failing_report_filename,
'w')
as f:
141 with open(success_report_filename,
'w')
as f:
148 with open(bazel_wrapper_filename,
'w')
as f:
153 'tools/bazel --bazelrc="%s" "$@" || FAILED=true' %
159 upload_results_lines = [
160 'sleep %s' % _UPLOAD_RBE_RESULTS_DELAY_SECONDS,
161 'PYTHONHTTPSVERIFY=0 python3 ./tools/run_tests/python_utils/upload_rbe_results.py --invocation_id="%s"'
166 upload_results_lines = []
169 'if [ "$FAILED" != "" ]',
173 ' # success: plant the pre-generated xml report that says "success"',
175 (success_report_filename, failing_report_filename),
181 for line
in intro_lines + upload_results_lines + outro_lines
184 os.chmod(bazel_wrapper_filename, 0o775)
187 with open(bazel_wrapper_bat_filename,
'w')
as f:
191 'bazel --bazelrc="%s" %%*' % bazel_rc_filename,
192 'set BAZEL_EXITCODE=%errorlevel%',
197 upload_results_lines = [
198 'sleep %s' % _UPLOAD_RBE_RESULTS_DELAY_SECONDS,
199 'python3 tools/run_tests/python_utils/upload_rbe_results.py --invocation_id="%s" || exit /b 1'
204 upload_results_lines = []
207 'if %BAZEL_EXITCODE% == 0 (',
208 ' @rem success: plant the pre-generated xml report that says "success"',
210 (success_report_filename, failing_report_filename),
212 'exit /b %BAZEL_EXITCODE%',
217 for line
in intro_lines + upload_results_lines + outro_lines
221 print(
'Bazel invocation ID: %s' % invocation_id, file=sys.stderr)
222 print(
'Upload test results to BigQuery after bazel runs: %s' %
225 print(
'Generated bazel wrapper: %s' % bazel_wrapper_filename,
227 print(
'Generated bazel wrapper: %s' % bazel_wrapper_bat_filename,
231 if __name__ ==
'__main__':
233 argp = argparse.ArgumentParser(
235 'Generate bazel wrapper to help with bazel test reports in CI.')
241 'Path under which the bazel wrapper and other files are going to be generated'
243 argp.add_argument(
'--report_suite_name',
244 default=
'bazel_invocations',
246 help=
'Test suite name to use in generated XML report')
247 args = argp.parse_args()
250 invocation_id =
str(uuid.uuid4())
252 report_path = args.report_path
253 report_suite_name = args.report_suite_name
254 upload_results =
True if os.getenv(
'UPLOAD_TEST_RESULTS')
else False