From ebdf528c27f39a0c78efd3bca71e21ede0572803 Mon Sep 17 00:00:00 2001 From: Sasha Lopoukhine Date: Sat, 2 Nov 2024 18:25:33 +0000 Subject: [PATCH] misc: fix tests that secretly rely on optional dependencies (#3361) Also changes CI-Core to test only the core dev dependencies, letting CI-MLIR check the full coverage --- .github/workflows/ci-core.yml | 9 +--- .github/workflows/ci-mlir.yml | 4 +- Makefile | 52 ++++++++++++++------- docs/marimo/linalg_snitch.py | 2 +- docs/marimo/mlir/README.md | 4 -- docs/marimo/onnx/README.md | 4 ++ docs/marimo/{mlir => onnx}/onnx_demo.py | 0 tests/backend/test_jax_executable.py | 3 +- tests/frontend/jaxpr/test_build_jaxpr_ir.py | 3 +- tests/interactive/test_app.py | 14 ++++-- xdsl/interactive/_pasteboard.py | 12 ++++- 11 files changed, 69 insertions(+), 38 deletions(-) delete mode 100644 docs/marimo/mlir/README.md create mode 100644 docs/marimo/onnx/README.md rename docs/marimo/{mlir => onnx}/onnx_demo.py (100%) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index f8b7a06a26..db94dc090e 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -40,11 +40,6 @@ jobs: - name: Install the project run: uv sync --all-extras - - name: Test with pytest - run: uv run pytest -W error - - - name: Execute lit tests + - name: Run all tests run: | - export PYTHONPATH=$(pwd) - uv run lit -v tests/filecheck/ - uv run lit -v docs/Toy/examples/ + make tests-functional diff --git a/.github/workflows/ci-mlir.yml b/.github/workflows/ci-mlir.yml index c5f12bc8d2..49c4889954 100644 --- a/.github/workflows/ci-mlir.yml +++ b/.github/workflows/ci-mlir.yml @@ -115,12 +115,12 @@ jobs: export PATH=$PATH:${GITHUB_WORKSPACE}/llvm-project/build/bin/ uv run pytest --nbval docs/mlir_interoperation.ipynb --maxfail 1 -vv - - name: Test MLIR dependent marimo notebooks + - name: Test ONNX-dependent marimo notebooks run: | cd xdsl # Add mlir-opt to the path export PATH=$PATH:${GITHUB_WORKSPACE}/llvm-project/build/bin/ - uv run make tests-marimo-mlir + uv run make tests-marimo-onnx - name: Combine coverage data run: | diff --git a/Makefile b/Makefile index b2a4fae511..0f17b41361 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,7 @@ pytest: uv-installed pytest-nb: uv-installed uv run pytest -W error --nbval -vv docs \ --ignore=docs/mlir_interoperation.ipynb \ + --ignore=docs/Toy \ --nbval-current-env # run tests for Toy tutorial @@ -64,8 +65,16 @@ filecheck-toy: uv-installed pytest-toy: uv-installed uv run pytest docs/Toy/toy/tests +.PHONY: pytest-toy-nb +pytest-toy-nb: + @if uv run python -c "import riscemu" > /dev/null 2>&1; then \ + uv run pytest -W error --nbval -vv docs/Toy --nbval-current-env; \ + else \ + echo "riscemu is not installed, skipping tests."; \ + fi + .PHONY: tests-toy -tests-toy: filecheck-toy pytest-toy +tests-toy: filecheck-toy pytest-toy pytest-toy-nb .PHONY: tests-marimo tests-marimo: uv-installed @@ -79,26 +88,35 @@ tests-marimo: uv-installed done @echo "All marimo tests passed successfully." -.PHONY: tests-marimo-mlir -tests-marimo-mlir: uv-installed - @if ! command -v mlir-opt > /dev/null 2>&1; then \ - echo "MLIR is not installed, skipping tests."; \ - exit 0; \ +.PHONY: tests-marimo-onnx +tests-marimo-onnx: uv-installed + @if uv run python -c "import onnx" > /dev/null 2>&1; then \ + echo "onnx is installed, running tests."; \ + if ! command -v mlir-opt > /dev/null 2>&1; then \ + echo "MLIR is not installed, skipping tests."; \ + exit 0; \ + fi; \ + for file in docs/marimo/onnx/*.py; do \ + echo "Running $$file"; \ + error_message=$$(uv run python3 "$$file" 2>&1) || { \ + echo "Error running $$file"; \ + echo "$$error_message"; \ + exit 1; \ + }; \ + done; \ + echo "All marimo onnx tests passed successfully."; \ + else \ + echo "onnx is not installed, skipping tests."; \ fi - @echo "MLIR is installed, running tests." - @for file in docs/marimo/mlir/*.py; do \ - echo "Running $$file"; \ - error_message=$$(uv run python3 "$$file" 2>&1) || { \ - echo "Error running $$file"; \ - echo "$$error_message"; \ - exit 1; \ - }; \ - done - @echo "All marimo mlir tests passed successfully." + +# run all tests +.PHONY: tests-functional +tests-functional: pytest tests-toy filecheck pytest-nb tests-marimo tests-marimo-onnx + @echo All functional tests done. # run all tests .PHONY: tests -tests: pytest tests-toy filecheck pytest-nb tests-marimo tests-marimo-mlir pyright +tests: tests-functional pyright @echo All tests done. # re-generate the output from all jupyter notebooks in the docs directory diff --git a/docs/marimo/linalg_snitch.py b/docs/marimo/linalg_snitch.py index 55a600ad95..efb5efcb86 100644 --- a/docs/marimo/linalg_snitch.py +++ b/docs/marimo/linalg_snitch.py @@ -554,7 +554,7 @@ def __( snitch_c_shaped = ShapedArray(TypedPtr.new_float64([0.0] * c_len), c_shape) - register_implementations(snitch_interpreter, ctx, include_wgpu=False) + register_implementations(snitch_interpreter, ctx, include_wgpu=False, include_onnx=False) snitch_interpreter.call_op( "matmul", diff --git a/docs/marimo/mlir/README.md b/docs/marimo/mlir/README.md deleted file mode 100644 index d6e0d85842..0000000000 --- a/docs/marimo/mlir/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Marimo notebooks that depend on mlir-opt - -For these notebooks to run as intended, `mlir-opt` needs to be in the path. -Please see the [MLIR Interoperation](../../mlir_interoperation.md) document for more information. diff --git a/docs/marimo/onnx/README.md b/docs/marimo/onnx/README.md new file mode 100644 index 0000000000..648b1d0dc4 --- /dev/null +++ b/docs/marimo/onnx/README.md @@ -0,0 +1,4 @@ +# Marimo notebooks that depend on ONNX and mlir-opt + +For these notebooks to run as intended, the `onnx` package needs to be installed and `mlir-opt` needs to be in the path. +Please see the [MLIR Interoperation](../../mlir_interoperation.md) document for more information. diff --git a/docs/marimo/mlir/onnx_demo.py b/docs/marimo/onnx/onnx_demo.py similarity index 100% rename from docs/marimo/mlir/onnx_demo.py rename to docs/marimo/onnx/onnx_demo.py diff --git a/tests/backend/test_jax_executable.py b/tests/backend/test_jax_executable.py index 94416659ff..35a24b4e39 100644 --- a/tests/backend/test_jax_executable.py +++ b/tests/backend/test_jax_executable.py @@ -1,6 +1,5 @@ import re -import jax import pytest from xdsl.builder import ImplicitBuilder @@ -11,6 +10,8 @@ pytest.importorskip("jax") +import jax # noqa: E402 + from xdsl.backend.jax_executable import JaxExecutable, array # noqa: E402 diff --git a/tests/frontend/jaxpr/test_build_jaxpr_ir.py b/tests/frontend/jaxpr/test_build_jaxpr_ir.py index 6e64c0aa53..6529a01575 100644 --- a/tests/frontend/jaxpr/test_build_jaxpr_ir.py +++ b/tests/frontend/jaxpr/test_build_jaxpr_ir.py @@ -1,7 +1,5 @@ import pytest -from xdsl.frontend.jaxpr import IRGen - try: from jax import make_jaxpr # pyright: ignore[reportUnknownVariableType] from jax import numpy as jnp @@ -9,6 +7,7 @@ print(exc) pytest.skip("jax is an optional dependency", allow_module_level=True) +from xdsl.frontend.jaxpr import IRGen five_ones = jnp.ones(5, dtype=jnp.float32) # pyright: ignore[reportUnknownMemberType] diff --git a/tests/interactive/test_app.py b/tests/interactive/test_app.py index c0995abe67..fe951a160c 100644 --- a/tests/interactive/test_app.py +++ b/tests/interactive/test_app.py @@ -16,13 +16,12 @@ ModuleOp, UnrealizedConversionCastOp, ) +from xdsl.interactive import _pasteboard from xdsl.interactive.add_arguments_screen import AddArguments from xdsl.interactive.app import InputApp from xdsl.interactive.passes import AvailablePass, get_condensed_pass_list from xdsl.ir import Block, Region -from xdsl.transforms import ( - individual_rewrite, -) +from xdsl.transforms import individual_rewrite from xdsl.transforms.experimental.dmp import stencil_global_to_local from xdsl.utils.exceptions import ParseError from xdsl.utils.parse_pipeline import PipelinePassSpec, parse_pipeline @@ -198,6 +197,15 @@ async def test_buttons(): """ ) + # Test that the current pipeline command is correctly copied + def callback(x: str): + assert ( + x == "xdsl-opt -p 'convert-func-to-riscv-func,convert-arith-to-riscv'" + ) + + _pasteboard._test_pyclip_callback = callback # pyright: ignore[reportPrivateUsage] + await pilot.click("#copy_query_button") + current_pipeline = app.pass_pipeline # press "Remove Last Pass" button await pilot.click("#remove_last_pass_button") diff --git a/xdsl/interactive/_pasteboard.py b/xdsl/interactive/_pasteboard.py index 5971ab4c21..470e8439b4 100644 --- a/xdsl/interactive/_pasteboard.py +++ b/xdsl/interactive/_pasteboard.py @@ -3,8 +3,18 @@ annotations. We add our own mirror of the copy function here. """ -import pyclip # pyright: ignore[reportMissingTypeStubs] +from collections.abc import Callable + +_test_pyclip_callback: Callable[[str], None] | None = None +"""Used in tests.""" def pyclip_copy(text: str) -> None: + global _test_pyclip_callback + if _test_pyclip_callback is not None: + _test_pyclip_callback(text) + return + + import pyclip # pyright: ignore[reportMissingTypeStubs] + pyclip.copy(text) # pyright: ignore[reportUnknownMemberType]