diff --git a/envsetup.sh b/envsetup.sh index ab43ada1f6..1ef9a54803 100644 --- a/envsetup.sh +++ b/envsetup.sh @@ -1134,8 +1134,9 @@ function run_tool_with_logging() { --tool_tag "${tool_tag}" \ --start_timestamp "${start_time}" \ --end_timestamp "$(date +%s.%N)" \ - --tool_args \""${@}"\" \ + --tool_args "$*" \ --exit_code "${exit_code}" \ + ${ANDROID_TOOL_LOGGER_EXTRA_ARGS} \ > /dev/null 2>&1 & exit ${exit_code} ' SIGINT SIGTERM SIGQUIT EXIT diff --git a/tests/Android.bp b/tests/Android.bp index d3964e5aee..39debf5c6d 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -29,6 +29,7 @@ python_test_host { }, data: [ ":envsetup_minimum.zip", + ":tool_event_logger", ], test_suites: [ "general-tests", diff --git a/tests/run_tool_with_logging_test.py b/tests/run_tool_with_logging_test.py index 1eb78f14ba..215d992cf0 100644 --- a/tests/run_tool_with_logging_test.py +++ b/tests/run_tool_with_logging_test.py @@ -13,20 +13,22 @@ # limitations under the License. import dataclasses +import glob from importlib import resources import logging import os from pathlib import Path import re +import shutil import signal import stat import subprocess +import sys import tempfile import textwrap import time import unittest import zipfile -import sys EXII_RETURN_CODE = 0 INTERRUPTED_RETURN_CODE = 130 @@ -40,7 +42,7 @@ class RunToolWithLoggingTest(unittest.TestCase): # Configure to print logging to stdout. logging.basicConfig(filename=None, level=logging.DEBUG) console = logging.StreamHandler(sys.stdout) - logging.getLogger('').addHandler(console) + logging.getLogger("").addHandler(console) def setUp(self): super().setUp() @@ -49,7 +51,7 @@ class RunToolWithLoggingTest(unittest.TestCase): os.chdir(self.working_dir.name) # Extract envsetup.zip which contains the envsetup.sh and other dependent # scripts required to set up the build environments. - with resources.files("testdata").joinpath("envsetup.zip").open('rb') as p: + with resources.files("testdata").joinpath("envsetup.zip").open("rb") as p: with zipfile.ZipFile(p, "r") as zip_f: zip_f.extractall() @@ -118,7 +120,7 @@ class RunToolWithLoggingTest(unittest.TestCase): test_tool.assert_called_once_with_args("arg1 arg2") expected_logger_args = ( "--tool_tag FAKE_TOOL --start_timestamp \d+\.\d+ --end_timestamp" - ' \d+\.\d+ --tool_args "arg1 arg2" --exit_code 0' + " \d+\.\d+ --tool_args arg1 arg2 --exit_code 0" ) test_logger.assert_called_once_with_args(expected_logger_args) @@ -196,7 +198,7 @@ class RunToolWithLoggingTest(unittest.TestCase): expected_logger_args = ( "--tool_tag FAKE_TOOL --start_timestamp \d+\.\d+ --end_timestamp" - ' \d+\.\d+ --tool_args "arg1 arg2" --exit_code 130' + " \d+\.\d+ --tool_args arg1 arg2 --exit_code 130" ) test_logger.assert_called_once_with_args(expected_logger_args) @@ -226,6 +228,37 @@ class RunToolWithLoggingTest(unittest.TestCase): test_logger.assert_not_called() + def test_integration_tool_event_logger_dry_run(self): + test_tool = TestScript.create(self.working_dir) + logger_path = self._import_logger() + + self._run_script_and_wait(f""" + TMPDIR="{self.working_dir.name}" + ANDROID_ENABLE_TOOL_LOGGING=true + ANDROID_TOOL_LOGGER="{logger_path}" + ANDROID_TOOL_LOGGER_EXTRA_ARGS="--dry_run" + run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 + """) + + self._assert_logger_dry_run() + + def _import_logger(self) -> Path: + logger = "tool_event_logger" + logger_path = Path(self.working_dir.name).joinpath(logger) + with resources.as_file(resources.files("testdata").joinpath(logger)) as p: + shutil.copy(p, logger_path) + Path.chmod(logger_path, 0o755) + return logger_path + + def _assert_logger_dry_run(self): + log_files = glob.glob(self.working_dir.name + "/tool_event_logger_*/*.log") + self.assertEqual(len(log_files), 1) + + with open(log_files[0], "r") as f: + lines = f.readlines() + self.assertEqual(len(lines), 1) + self.assertIn("dry run", lines[0]) + def _create_build_env_script(self) -> str: return f""" source {Path(self.working_dir.name).joinpath("build/make/envsetup.sh")} @@ -248,7 +281,7 @@ class RunToolWithLoggingTest(unittest.TestCase): stderr=subprocess.PIPE, text=True, start_new_session=True, - executable='/bin/bash' + executable="/bin/bash", ) def _wait_for_process( @@ -301,7 +334,7 @@ class TestScript: """) f.write(executable_contents.encode("utf-8")) - os.chmod(f.name, os.stat(f.name).st_mode | stat.S_IEXEC) + Path.chmod(f.name, os.stat(f.name).st_mode | stat.S_IEXEC) return TestScript(executable, output_file)