Skip to content

Commit

Permalink
Upgrade to tox v4.0 and adjust local testing default configurations (#…
Browse files Browse the repository at this point in the history
…1297)

### What kind of change does this PR introduce?

* Revises two environment variables (`XCLIM_TESTDATA_BRANCH` and
`XCLIM_PREFETCH_TESTING_DATA`) to better limit their scope and clarify
their purposes.
* Upgrades `tox` configuration to use version 4.0 by default
* Moves some configurations out of `pyproject.toml` to better facilitate
local development
* Removes several geojson files that are no longer used (previously used
for subset tools).

### Does this PR introduce a breaking change?

Yes. Environment variables and testing data have been modified.
  • Loading branch information
Zeitsperre committed Feb 24, 2023
2 parents 0610641 + 3e43ce9 commit 2b5e23d
Show file tree
Hide file tree
Showing 15 changed files with 61 additions and 507 deletions.
17 changes: 7 additions & 10 deletions .github/workflows/main.yml
Expand Up @@ -20,7 +20,7 @@ on:
- submitted

env:
MAIN_TESTDATA_BRANCH: main
XCLIM_TESTDATA_BRANCH: main

jobs:
black:
Expand All @@ -40,7 +40,7 @@ jobs:
with:
python-version: "3.8"
- name: Install tox
run: pip install tox~=3.0
run: pip install tox~=4.0
- name: Run linting suite
run: tox -e black

Expand All @@ -56,7 +56,7 @@ jobs:
with:
python-version: "3.8"
- name: Install tox
run: pip install tox~=3.0
run: pip install tox~=4.0
- name: Test with tox
run: tox -e py38
env:
Expand All @@ -76,7 +76,7 @@ jobs:
with:
python-version: "3.9"
- name: Install tox
run: pip install tox~=3.0
run: pip install tox~=4.0
- name: Test with tox
run: tox -e py39-upstream-lm3-coverage
env:
Expand Down Expand Up @@ -115,8 +115,9 @@ jobs:
python -m pip install --no-user .
- name: Test
run: |
pip list
pip check
pytest xclim --durations=10
pytest xclim --numprocesses=logical --durations=10 --cov=xclim --cov-report=term-missing
env:
CONDA_EXE: mamba
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -156,7 +157,7 @@ jobs:
with:
python-version: "3.8"
- name: Install tox
run: pip install tox~=3.0
run: pip install tox~=4.0
- name: Test with tox
run: tox -e py38-lm3-coverage
env:
Expand Down Expand Up @@ -184,10 +185,6 @@ jobs:
run: pylint --rcfile=pylintrc --disable=import-error --exit-zero xclim
- name: Test with tox
run: tox -e notebooks_doctests
- name: Report coverage
run: |
pip install --upgrade coveralls
coveralls
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_FLAG_NAME: run-notebooks_doctests-py38
Expand Down
14 changes: 13 additions & 1 deletion HISTORY.rst
Expand Up @@ -13,6 +13,18 @@ New indicators
* New indices and indicators for determining upwelling radiation (`shortwave_upwelling_radiation_from_net_downwelling` and `longwave_upwelling_radiation_from_net_downwelling`; CF variables `rsus` and `rlus`) from net and downwelling radiation (shortwave: `rss` and `rsds`; longwave: `rls` and `rlds`). (:pull:`1271`).
* New indice and indicator (``dryness_index``) for estimating soil humidity classifications for winegrowing regions (based on Riou et al. (1994)). (:issue:`355`, :pull:`1235`).

Breaking changes
^^^^^^^^^^^^^^^^
* `xclim` testing default behaviours have been changed (:issue:`1295`, :pull:`1297`):
* Running `$ pytest` will no longer use `pytest-xdist` distributed testing be default (can be set with ``-n auto|logical|#``. Coverage is also no longer gathered/reported by default.
* Running `$ tox` will now set `pytest-xdist` to use ``-n logical`` processes (with a max of 10).
* Default behaviour for testing is to no longer always fetch `xclim-testdata`. If testdata is found in ``$HOME/.xclim_testing_data``, files will be copied to individual processes, otherwise, will be fetched as needed.
* Environment variables evaluated when running pytest have been changed (:issue:`1295`, :pull:`1297`):
* For testing against specific branches of `xclim-testdata`: ``MAIN_TESTDATA_BRANCH`` -> ``XCLIM_TESTDATA_BRANCH``
* The option to skip fetching of testdata (``SKIP_TEST_DATA``) has been removed
* A new environment variable (``XCLIM_PREFETCH_TESTING_DATA``) is now available to gather `xclim-testdata` before running test ensemble (default: `False`).
* Environment variables are now passed to `tox` on execution.

Bug fixes
^^^^^^^^^
* ``build_indicator_module_from_yaml`` now accepts a ``reload`` argument. When re-building a module that already exists, ``reload=True`` removes all previous indicator before creating the new ones. (:issue:`1192`, :pull:`1284`).
Expand All @@ -27,7 +39,7 @@ Internal changes
* Coveralls GitHub Action removed as it did not support ``pyproject.toml``-based configurations. (:pull:`1278`).
* Add a remark about how `xclim`'s CFFWIS is different from the original 1982 implementation. (:issue:`1104`, :pull:`1284`).
* Update CI runs to use Python3.9 when examining upstream dependencies. Replace `setup-conda` action with `provision-with-micromamba` action. (:pull:`1286`).
* Update CI runs to always use `tox~=3.0` and the `latest` Ubuntu images (now `v22.04`). (:pull:`1288`).
* Update CI runs to always use `tox~=4.0` and the `latest` virtual machine images (now `ubuntu-22.04`). (:pull:`1288`, :pull:`1297`).
* `SBCK` installation command now points to the official development repository. (:pull:`1288`).
* Some references in the BibTeX were updated to point to better resources. (:pull:`1288`).
* Add a GitHub CI workflow for performing dependency security review scanning. (:pull:`1287`).
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Expand Up @@ -58,6 +58,7 @@ dependencies:
- statsmodels
- tokenize-rt
- tox
# - tox-conda # Will be added when a tox@v4.0+ compatible plugin is released.
- xdoctest
- yamale
- yamllint
7 changes: 3 additions & 4 deletions pyproject.toml
Expand Up @@ -70,6 +70,7 @@ dev = [
"pytest-xdist[psutil] >=3.2",
"tokenize-rt",
"tox",
# "tox-conda", # Will be added when a tox@v4.0+ compatible plugin is released.
"xdoctest",
"yamale",
"yamllint",
Expand Down Expand Up @@ -165,10 +166,8 @@ ignore_missing_imports = true
addopts = [
"--verbose",
"--color=yes",
"--cov=xclim",
"--cov-report=term-missing",
"--numprocesses=auto",
"--maxprocesses=6",
"--numprocesses=0",
"--maxprocesses=8",
"--dist=worksteal"
]
norecursedirs = ["docs/notebooks/*"]
Expand Down
27 changes: 16 additions & 11 deletions tox.ini
@@ -1,16 +1,15 @@
[tox]
min_version = 4.0
env_list =
black
docs
notebooks_doctests
notebooks_doctests{-coverage,}
; opt-slow
py38-lm3
py39-upstream-doctest
py310-slow
isolated_build = True
requires =
pip >= 21.0
tox ~=3.0
opts = -v

[testenv:black]
Expand All @@ -35,6 +34,7 @@ commands =
blackdoc --check docs
isort --check xclim
yamllint --config-file=.yamllint.yaml xclim
commands_post =

[testenv:docs]
description = Build the documentation with makefile under {basepython}
Expand All @@ -44,6 +44,7 @@ setenv =
READTHEDOCS = 1
commands =
make docs
commands_post =
allowlist_externals =
env
make
Expand All @@ -55,11 +56,11 @@ allowlist_externals =
;conda_env = environment-dev.yml
;extras =

[testenv:notebooks_doctests]
[testenv:notebooks_doctests{-coverage,}]
description = Run notebooks and doctests with pytest under {basepython}
commands =
pytest --no-cov --nbval --dist=loadscope docs/notebooks --durations=10 --ignore=docs/notebooks/example.ipynb
pytest --rootdir xclim/testing/tests/ --xdoctest xclim --ignore=xclim/testing/tests/ --durations=10
pytest --no-cov --nbval --dist=loadscope docs/notebooks --ignore=docs/notebooks/example.ipynb
pytest --rootdir xclim/testing/tests/ --xdoctest xclim --ignore=xclim/testing/tests/

# Requires tox-conda compatible with tox@v4.0
;[testenv:opt-{slow,not_slow}]
Expand All @@ -76,27 +77,31 @@ commands =
description = Run tests with pytest under {basepython}
setenv =
COV_CORE_SOURCE =
PYTEST_ADDOPTS = --numprocesses=logical --durations=10
coverage: PYTEST_ADDOPTS = --numprocesses=logical --durations=10 --cov=xclim --cov-report=term-missing
PYTHONPATH = {toxinidir}
passenv =
CI
CONDA_EXE
COVERALLS_*
GITHUB_*
LD_LIBRARY_PATH
MAIN_TESTDATA_BRANCH
XCLIM_*
extras = dev
deps =
coverage: coveralls
lm3: git+https://github.com/OpenHydrology/lmoments3.git@develop#egg=lmoments3
upstream: -rrequirements_upstream.txt
install_command = python -m pip install --no-user {opts} {packages}
download = True
commands =
commands_pre =
pip list
pip check
doctest: pytest --no-cov --rootdir xclim/testing/tests/ --xdoctest xclim --ignore=xclim/testing/tests/ --durations=10
!slow: pytest xclim -m "not slow" --durations=10
slow: pytest xclim --durations=10
commands =
doctest: pytest --no-cov --rootdir xclim/testing/tests/ --xdoctest xclim --ignore=xclim/testing/tests/
!slow: pytest xclim -m "not slow"
slow: pytest xclim
commands_post =
coverage: - coveralls
allowlist_externals =
git
27 changes: 15 additions & 12 deletions xclim/testing/tests/conftest.py
Expand Up @@ -22,8 +22,8 @@
from xclim.testing.utils import _default_cache_dir # noqa
from xclim.testing.utils import open_dataset as _open_dataset

MAIN_TESTDATA_BRANCH = os.getenv("MAIN_TESTDATA_BRANCH", "main")
SKIP_TEST_DATA = os.getenv("SKIP_TEST_DATA")
TESTDATA_BRANCH = os.getenv("XCLIM_TESTDATA_BRANCH", "main")
PREFETCH_TESTING_DATA = os.getenv("XCLIM_PREFETCH_TESTING_DATA")


@pytest.fixture
Expand Down Expand Up @@ -518,7 +518,7 @@ def cmip3_day_tas(threadsafe_data_dir):
ds = _open_dataset(
"cmip3/tas.sresb1.giss_model_e_r.run1.atm.da.nc",
cache_dir=threadsafe_data_dir,
branch=MAIN_TESTDATA_BRANCH,
branch=TESTDATA_BRANCH,
)
yield ds.tas
ds.close()
Expand All @@ -527,7 +527,7 @@ def cmip3_day_tas(threadsafe_data_dir):
@pytest.fixture(scope="session")
def open_dataset(threadsafe_data_dir):
def _open_session_scoped_file(
file: str | os.PathLike, branch: str = MAIN_TESTDATA_BRANCH, **xr_kwargs
file: str | os.PathLike, branch: str = TESTDATA_BRANCH, **xr_kwargs
):
return _open_dataset(
file, cache_dir=threadsafe_data_dir, branch=branch, **xr_kwargs
Expand All @@ -544,7 +544,7 @@ def add_imports(xdoctest_namespace, threadsafe_data_dir) -> None:
ns["xr"] = xclim.testing # xr.open_dataset(...) -> xclim.testing.open_dataset(...)
ns["xclim"] = xclim
ns["open_dataset"] = partial(
_open_dataset, cache_dir=threadsafe_data_dir, branch=MAIN_TESTDATA_BRANCH
_open_dataset, cache_dir=threadsafe_data_dir, branch=TESTDATA_BRANCH
) # Needed for modules where xarray is imported as `xr`


Expand Down Expand Up @@ -583,7 +583,7 @@ def atmosds(threadsafe_data_dir) -> xr.Dataset:
return _open_dataset(
threadsafe_data_dir.joinpath("atmosds.nc"),
cache_dir=threadsafe_data_dir,
branch=MAIN_TESTDATA_BRANCH,
branch=TESTDATA_BRANCH,
)


Expand All @@ -610,16 +610,19 @@ def gather_session_data(threadsafe_data_dir, worker_id, xdoctest_namespace):
When running pytest with multiple workers, one worker will copy data remotely to _default_cache_dir while
other workers wait using lockfile. Once the lock is released, all workers will copy data to their local
threadsafe_data_dir."""
if worker_id == "master":
if not SKIP_TEST_DATA:
populate_testing_data(branch=MAIN_TESTDATA_BRANCH)
else:
if not SKIP_TEST_DATA:

if (
not _default_cache_dir.joinpath(TESTDATA_BRANCH).exists()
or PREFETCH_TESTING_DATA
):
if worker_id in "master":
populate_testing_data(branch=TESTDATA_BRANCH)
else:
_default_cache_dir.mkdir(exist_ok=True)
test_data_being_written = FileLock(_default_cache_dir.joinpath(".lock"))
with test_data_being_written as fl:
# This flag prevents multiple calls from re-attempting to download testing data in the same pytest run
populate_testing_data(branch=MAIN_TESTDATA_BRANCH)
populate_testing_data(branch=TESTDATA_BRANCH)
_default_cache_dir.joinpath(".data_written").touch()
fl.acquire()
shutil.copytree(_default_cache_dir, threadsafe_data_dir)
Expand Down
12 changes: 4 additions & 8 deletions xclim/testing/tests/data.py
Expand Up @@ -17,7 +17,7 @@
from xclim.testing import open_dataset as _open_dataset
from xclim.testing.utils import _default_cache_dir # noqa

MAIN_TESTDATA_BRANCH = os.getenv("MAIN_TESTDATA_BRANCH", "main")
TESTDATA_BRANCH = os.getenv("XCLIM_TESTDATA_BRANCH", "main")
TD = Path(__file__).parent / "data"


Expand All @@ -34,7 +34,7 @@ def generate_atmos(cache_dir: Path):
with _open_dataset(
"ERA5/daily_surface_cancities_1990-1993.nc",
cache_dir=cache_dir,
branch=MAIN_TESTDATA_BRANCH,
branch=TESTDATA_BRANCH,
) as ds:
tn10 = calendar.percentile_doy(ds.tasmin, per=10)
t10 = calendar.percentile_doy(ds.tas, per=10)
Expand All @@ -60,7 +60,7 @@ def generate_atmos(cache_dir: Path):

def populate_testing_data(
temp_folder: Path | None = None,
branch: str = MAIN_TESTDATA_BRANCH,
branch: str = TESTDATA_BRANCH,
_local_cache: Path = _default_cache_dir,
):
"""Perform calls to GitHub for the relevant testing data."""
Expand Down Expand Up @@ -112,8 +112,6 @@ def add_example_file_paths(cache_dir: Path) -> dict[str]:
ns["path_to_tasmax_file"] = "NRCANdaily/nrcan_canada_daily_tasmax_1990.nc"
ns["path_to_tasmin_file"] = "NRCANdaily/nrcan_canada_daily_tasmin_1990.nc"
ns["path_to_tas_file"] = "ERA5/daily_surface_cancities_1990-1993.nc"
ns["path_to_multi_shape_file"] = str(TD / "multi_regions.json")
ns["path_to_shape_file"] = str(TD / "southern_qc_geojson.json")
ns["path_to_ensemble_file"] = "EnsembleReduce/TestEnsReduceCriteria.nc"

# For core.utils.load_module example
Expand Down Expand Up @@ -151,9 +149,7 @@ def add_example_file_paths(cache_dir: Path) -> dict[str]:
atmos_file = cache_dir.joinpath("atmosds.nc")

# Give access to dataset variables by name in xdoctest namespace
with _open_dataset(
atmos_file, branch=MAIN_TESTDATA_BRANCH, cache_dir=cache_dir
) as ds:
with _open_dataset(atmos_file, branch=TESTDATA_BRANCH, cache_dir=cache_dir) as ds:
for variable in ds.data_vars:
ns[f"{variable}_dataset"] = ds.get(variable)

Expand Down
40 changes: 0 additions & 40 deletions xclim/testing/tests/data/eastern_canada.json

This file was deleted.

0 comments on commit 2b5e23d

Please sign in to comment.