From 0f763969b3aa492447d321eb4a04775039112132 Mon Sep 17 00:00:00 2001 From: Deepak Cherian Date: Mon, 1 Apr 2024 17:52:38 -0600 Subject: [PATCH] Add hypothesis workflow --- .github/workflows/ci-additional.yaml | 75 ++++++++++++++++++++++++++- properties/conftest.py | 21 ++++++++ properties/test_index_manipulation.py | 17 +++--- pyproject.toml | 1 + 4 files changed, 106 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-additional.yaml b/.github/workflows/ci-additional.yaml index 9aa3b17746f..4b90900568a 100644 --- a/.github/workflows/ci-additional.yaml +++ b/.github/workflows/ci-additional.yaml @@ -35,14 +35,13 @@ jobs: runs-on: "ubuntu-latest" needs: detect-ci-trigger if: needs.detect-ci-trigger.outputs.triggered == 'false' + defaults: run: shell: bash -l {0} - env: CONDA_ENV_FILE: ci/requirements/environment.yml PYTHON_VERSION: "3.11" - steps: - uses: actions/checkout@v4 with: @@ -82,6 +81,78 @@ jobs: # [MHS, 01/25/2024] Skip datatree_ documentation remove after #8572 python -m pytest --doctest-modules xarray --ignore xarray/tests --ignore xarray/datatree_ -Werror + hypothesis: + name: Doctests + runs-on: "ubuntu-latest" + needs: detect-ci-trigger + if: | + always() + && ( + (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') + || needs.detect-ci-trigger.outputs.triggered == 'true' + || contains( github.event.pull_request.labels.*.name, 'run-slow-hypothesis') + ) + defaults: + run: + shell: bash -l {0} + + env: + CONDA_ENV_FILE: ci/requirements/environment.yml + PYTHON_VERSION: "3.12" + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for all branches and tags. + + - name: set environment variables + run: | + echo "TODAY=$(date +'%Y-%m-%d')" >> $GITHUB_ENV + + - name: Setup micromamba + uses: mamba-org/setup-micromamba@v1 + with: + environment-file: ${{env.CONDA_ENV_FILE}} + environment-name: xarray-tests + create-args: >- + python=${{env.PYTHON_VERSION}} + conda + cache-environment: true + cache-environment-key: "${{runner.os}}-${{runner.arch}}-py${{env.PYTHON_VERSION}}-${{env.TODAY}}-${{hashFiles(env.CONDA_ENV_FILE)}}" + + - name: Install xarray + run: | + python -m pip install --no-deps -e . + - name: Version info + run: | + conda info -a + conda list + python xarray/util/print_versions.py + - name: Restore cached hypothesis directory + uses: actions/cache@v4 + with: + path: .hypothesis/ + key: cache-hypothesis + enableCrossOsArchive: true + save-always: true + - name: Run slow Hypothesis tests + if: success() + id: status + run: | + python -m pytest --hypothesis-show-statistics --run-slow-hypothesis properties/*.py \ + --report-log output-${{ matrix.python-version }}-log.jsonl + - name: Generate and publish the report + if: | + failure() + && steps.status.outcome == 'failure' + && github.event_name == 'schedule' + && github.repository_owner == 'pydata' + uses: xarray-contrib/issue-from-pytest-log@v1 + with: + log-path: output-${{ matrix.python-version }}-log.jsonl + issue-title: "Nightly Hypothesis tests failed" + issue-label: "topic-hypothesis" + mypy: name: Mypy runs-on: "ubuntu-latest" diff --git a/properties/conftest.py b/properties/conftest.py index 0a66d92ebc6..30e638161a1 100644 --- a/properties/conftest.py +++ b/properties/conftest.py @@ -1,3 +1,24 @@ +import pytest + + +def pytest_addoption(parser): + parser.addoption( + "--run-slow-hypothesis", + action="store_true", + default=False, + help="run slow hypothesis tests", + ) + + +def pytest_collection_modifyitems(config, items): + if config.getoption("--run-slow-hypothesis"): + return + skip_slow_hyp = pytest.mark.skip(reason="need --run-slow-hypothesis option to run") + for item in items: + if "slow_hypothesis" in item.keywords: + item.add_marker(skip_slow_hyp) + + try: from hypothesis import settings except ImportError: diff --git a/properties/test_index_manipulation.py b/properties/test_index_manipulation.py index 5a9fd54c041..2e20c2b490f 100644 --- a/properties/test_index_manipulation.py +++ b/properties/test_index_manipulation.py @@ -7,6 +7,7 @@ from xarray.testing import _assert_internal_invariants pytest.importorskip("hypothesis") +pytestmark = pytest.mark.slow_hypothesis import hypothesis.strategies as st from hypothesis import note, settings @@ -52,12 +53,7 @@ def __init__(self): self.multi_indexed_dims = [] # TODO: stacking with a timedelta64 index and unstacking converts it to object - @rule( - var=xrst.index_variables( - dims=DIM_NAME, - dtype=xrst.pandas_index_dtypes().filter(lambda x: x.kind != "m"), - ) - ) + @rule(var=xrst.index_variables(dims=DIM_NAME, dtype=xrst.pandas_index_dtypes())) def add_dim_coord(self, var): (name,) = var.dims note(f"adding dimension coordinate {name}") @@ -253,3 +249,12 @@ def test_unstack_object(): ds = xr.Dataset() ds["0"] = np.array(["", "\x000"], dtype=object) ds.stack({"1": ["0"]}).unstack() + + +@pytest.mark.skip(reason="failure detected by hypothesis") +def test_unstack_timedelta_index(): + import xarray as xr + + ds = xr.Dataset() + ds["0"] = np.array([0, 1, 2, 3], dtype="timedelta64[ns]") + ds.stack({"1": ["0"]}).unstack() diff --git a/pyproject.toml b/pyproject.toml index d2a5c6b8748..532dc40e859 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -295,6 +295,7 @@ markers = [ "flaky: flaky tests", "network: tests requiring a network connection", "slow: slow tests", + "slow_hypothesis: slow hypothesis tests", ] minversion = "7" python_files = "test_*.py"