blob: e70f841c835bcdd131a450d74e5f611f168c19cf [file] [log] [blame]
# 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()