diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 7600df05a1b..a540918ff78 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -5,26 +5,29 @@ on: push: branches: [main] + +# Tests are split into multiple jobs to accelerate the CI. +# Different jobs should be organized to take approximately the same +# time to complete (and not be prohibitely slow). +# Because GitHub Actions don't support YAML anchors, we have to place the +# splitting of testfiles into groups in the strategy/matrix/test-subset +# and can't re-use the groups across jobs. +# A pre-commit hook (scripts/check_all_tests_are_covered.py) +# enforces that test run just once per OS / floatX setting. + jobs: - pytest: + ubuntu: strategy: matrix: os: [ubuntu-18.04] floatx: [float32, float64] test-subset: - # Tests are split into multiple jobs to accelerate the CI. - # Different jobs should be organized to take approximately the same - # time to complete (and not be prohibitely slow) - # # How this works: # 1st block: Only passes --ignore parameters to pytest. # → pytest will run all test_*.py files that are NOT ignored. + # # Subsequent blocks: Only pass paths to test files. # → pytest will run only these files - # - # Any test that was not ignored runs in the first job. - # A pre-commit hook (scripts/check_all_tests_are_covered.py) - # enforces that test run just once. - | --ignore=pymc3/tests/test_distributions_timeseries.py --ignore=pymc3/tests/test_mixture.py @@ -128,3 +131,71 @@ jobs: env_vars: OS,PYTHON name: codecov-umbrella fail_ci_if_error: false + windows: + strategy: + matrix: + os: [windows-latest] + floatx: [float32, float64] + test-subset: + - | + pymc3/tests/test_distributions_random.py + - | + pymc3/tests/test_sampling.py + pymc3/tests/test_shared.py + - | + pymc3/tests/test_gp.py + pymc3/tests/test_ode.py + - | + pymc3/tests/test_model.py + pymc3/tests/test_model_func.py + pymc3/tests/test_modelcontext.py + pymc3/tests/test_pickling.py + + fail-fast: false + runs-on: ${{ matrix.os }} + env: + TEST_SUBSET: ${{ matrix.test-subset }} + AESARA_FLAGS: floatX=${{ matrix.floatx }},gcc__cxxflags='-march=core2' + defaults: + run: + shell: cmd + steps: + - uses: actions/checkout@v2 + - name: Cache conda + uses: actions/cache@v1 + env: + # Increase this value to reset cache if conda-envs/environment-dev-py38.yml has not changed + CACHE_NUMBER: 0 + with: + path: ~/conda_pkgs_dir + key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ + hashFiles('conda-envs/windows-environment-dev-py38.yml') }} + - name: Cache multiple paths + uses: actions/cache@v2 + env: + # Increase this value to reset cache if requirements.txt has not changed + CACHE_NUMBER: 0 + with: + path: | + ~/.cache/pip + $RUNNER_TOOL_CACHE/Python/* + ~\AppData\Local\pip\Cache + key: ${{ runner.os }}-build-${{ matrix.python-version }}-${{ + hashFiles('requirements.txt') }} + - uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: pymc3-dev-py38 + channel-priority: strict + environment-file: conda-envs/windows-environment-dev-py38.yml + use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly! + - name: Install-pymc3 + run: | + conda activate pymc3-dev-py38 + pip install -e . + python --version + - name: Run tests + # This job uses a cmd shell, therefore the environment variable syntax is different! + # The ">-" in the next line replaces newlines with spaces (see https://stackoverflow.com/a/66809682). + run: >- + conda activate pymc3-dev-py38 && + python -m pytest -vv --cov=pymc3 --cov-report=xml --cov-report term --durations=50 %TEST_SUBSET% diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index b5727829e72..00000000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: windows - -on: - pull_request: - push: - branches: [main] - -jobs: - pytest: - strategy: - matrix: - os: [windows-latest] - floatx: [float64] - test-subset: - - pymc3/tests/test_distributions_random.py - - pymc3/tests/test_sampling.py - runs-on: ${{ matrix.os }} - env: - TEST_SUBSET: ${{ matrix.test-subset }} - AESARA_FLAGS: floatX=${{ matrix.floatx }},gcc__cxxflags='-march=core2' - defaults: - run: - shell: bash -l {0} - steps: - - uses: actions/checkout@v2 - - name: Cache conda - uses: actions/cache@v1 - env: - # Increase this value to reset cache if conda-envs/environment-dev-py38.yml has not changed - CACHE_NUMBER: 0 - with: - path: ~/conda_pkgs_dir - key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ - hashFiles('conda-envs/windows-environment-dev-py38.yml') }} - - name: Cache multiple paths - uses: actions/cache@v2 - env: - # Increase this value to reset cache if requirements.txt has not changed - CACHE_NUMBER: 0 - with: - path: | - ~/.cache/pip - $RUNNER_TOOL_CACHE/Python/* - ~\AppData\Local\pip\Cache - key: ${{ runner.os }}-build-${{ matrix.python-version }}-${{ - hashFiles('requirements.txt') }} - - uses: conda-incubator/setup-miniconda@v2 - with: - activate-environment: pymc3-dev-py38 - channel-priority: strict - environment-file: conda-envs/windows-environment-dev-py38.yml - use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly! - - name: Install-pymc3 - run: | - conda activate pymc3-dev-py38 - pip install -e . - python --version - - run: | - conda activate pymc3-dev-py38 - python -m pytest -vv --cov=pymc3 --cov-report=xml --cov-report term --durations=50 $TEST_SUBSET diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 47399807658..cef12c6d4b5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,7 @@ repos: - repo: local hooks: - id: check-no-tests-are-ignored + additional_dependencies: [pandas,pyyaml] entry: python scripts/check_all_tests_are_covered.py files: ^\.github/workflows/pytest\.yml$ language: python diff --git a/scripts/check_all_tests_are_covered.py b/scripts/check_all_tests_are_covered.py index 4076ef552a3..69752465a5a 100644 --- a/scripts/check_all_tests_are_covered.py +++ b/scripts/check_all_tests_are_covered.py @@ -6,38 +6,93 @@ This is intended to be used as a pre-commit hook, see `.pre-commit-config.yaml`. You can run it manually with `pre-commit run check-no-tests-are-ignored --all`. """ +import itertools import logging -import re +import os from pathlib import Path +import pandas +import yaml + _log = logging.getLogger(__file__) +logging.basicConfig(level=logging.DEBUG) -if __name__ == "__main__": - testing_workflows = ["jaxtests.yml", "pytest.yml"] - ignored = set() - non_ignored = set() - for wfyml in testing_workflows: - pytest_ci_job = Path(".github") / "workflows" / wfyml - txt = pytest_ci_job.read_text() - ignored = set(re.findall(r"(?<=--ignore=)(pymc3/tests.*\.py)", txt)) - non_ignored = non_ignored.union(set(re.findall(r"(?