| # Copyright 2024 The IREE Authors |
| # |
| # Licensed under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| import io |
| import os |
| from pathlib import Path |
| import tempfile |
| import unittest |
| |
| from iree.build import * |
| from iree.build.executor import BuildContext |
| from iree.build.test_actions import ExecuteOutOfProcessThunkAction |
| |
| |
| @entrypoint |
| def write_out_of_process_pid(): |
| context = BuildContext.current() |
| output_file = context.allocate_file("pid.txt") |
| action = ExecuteOutOfProcessThunkAction( |
| _write_pid_file, |
| args=[output_file.get_fs_path()], |
| desc="Writing pid file", |
| executor=context.executor, |
| ) |
| output_file.deps.add(action) |
| return output_file |
| |
| |
| @entrypoint |
| def exception_in_action(): |
| context = BuildContext.current() |
| output_file = context.allocate_file("pid.txt") |
| action = ExecuteOutOfProcessThunkAction( |
| _raise_error, |
| args=[], |
| desc="Writing pid file", |
| executor=context.executor, |
| ) |
| output_file.deps.add(action) |
| return output_file |
| |
| |
| def _write_pid_file(output_path: Path): |
| pid = os.getpid() |
| print(f"Running action out of process: pid={pid}") |
| output_path.write_text(str(pid)) |
| |
| |
| def _raise_error(): |
| raise RuntimeError("Failure in action") |
| |
| |
| class BasicTest(unittest.TestCase): |
| def setUp(self): |
| self._temp_dir = tempfile.TemporaryDirectory(ignore_cleanup_errors=True) |
| self._temp_dir.__enter__() |
| self.output_path = Path(self._temp_dir.name) |
| |
| def tearDown(self) -> None: |
| self._temp_dir.__exit__(None, None, None) |
| |
| def testProcessConcurrency(self): |
| parent_pid = os.getpid() |
| print(f"Testing out of process concurrency: pid={parent_pid}") |
| iree_build_main( |
| args=["write_out_of_process_pid", "--output-dir", str(self.output_path)] |
| ) |
| pid_file = ( |
| self.output_path / "genfiles" / "write_out_of_process_pid" / "pid.txt" |
| ) |
| child_pid = int(pid_file.read_text()) |
| print(f"Got child pid={child_pid}") |
| self.assertNotEqual(parent_pid, child_pid) |
| |
| def test_rich_console(self): |
| # This just does a sanity check that rich console mode does not crash. Actual |
| # behavior can really only be completely verified visually. |
| out_io = io.StringIO() |
| err_io = io.StringIO() |
| iree_build_main( |
| args=[ |
| "write_out_of_process_pid", |
| "--output-dir", |
| str(self.output_path), |
| "--test-force-console", |
| ], |
| stderr=err_io, |
| stdout=out_io, |
| ) |
| err = err_io.getvalue() |
| print(f"test_rich_console output: {err!r}") |
| self.assertIn("\x1b[A", err) |
| |
| def test_exception_in_action(self): |
| # Tests that an exception in an action causes an abort and proper error |
| # reporting. |
| out_io = io.StringIO() |
| err_io = io.StringIO() |
| with self.assertRaises(SystemExit): |
| iree_build_main( |
| args=[ |
| "exception_in_action", |
| "--output-dir", |
| str(self.output_path), |
| "--test-force-console", |
| ], |
| stderr=err_io, |
| stdout=out_io, |
| ) |
| |
| err = err_io.getvalue() |
| print(f"test_exception_in_action output: {err!r}") |
| self.assertIn("\x1b[A", err) |
| self.assertIn("ERROR: Building", err) |
| self.assertIn("Root causes:\n * Writing pid file\n", err) |
| |
| def test_non_tty(self): |
| # Verifies that the non-tty path reports. |
| out_io = io.StringIO() |
| err_io = io.StringIO() |
| iree_build_main( |
| args=["write_out_of_process_pid", "--output-dir", str(self.output_path)], |
| stderr=err_io, |
| stdout=out_io, |
| ) |
| err = err_io.getvalue() |
| print(f"test_non_tty output: {err!r}") |
| self.assertNotIn("\x1b[A", err) |
| |
| def test_long_summary(self): |
| # Verifies that the rich console long summary path reports. |
| out_io = io.StringIO() |
| err_io = io.StringIO() |
| iree_build_main( |
| args=[ |
| "write_out_of_process_pid", |
| "--output-dir", |
| str(self.output_path), |
| "--test-force-console", |
| "--test-long-display-time-threshold=-1", |
| ], |
| stderr=err_io, |
| stdout=out_io, |
| ) |
| err = err_io.getvalue() |
| print(f"test_long_summary output: {err!r}") |
| self.assertIn("Waiting for long running actions:", err) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |