From 347c052d641863f64c5879f98dd070c59effbd5e Mon Sep 17 00:00:00 2001 From: Alex Kerney Date: Fri, 2 Jun 2023 12:11:32 -0400 Subject: [PATCH] Debugging engine issues I've gotten testing setup so that we can spin up Xpublish in the background and test real clients against it. Works on #18 --- pyproject.toml | 4 ++-- requirements-dev.txt | 4 ++++ tests/conftest.py | 45 ++++++++++++++++++++++++++++++++++++++++++++ tests/server.py | 11 +++++++++++ tests/test_server.py | 25 ++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 tests/conftest.py create mode 100644 tests/server.py create mode 100644 tests/test_server.py diff --git a/pyproject.toml b/pyproject.toml index 5be40f2..150a9b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta" [project] name = "xpublish_opendap" -description = "" +description = "OpenDAP plugin for Xpublish" readme = "README.md" requires-python = ">=3.9" -keywords = [] +keywords = ["xarray", "xpublish", "wms"] license = { file = "LICENSE.txt" } classifiers = [ diff --git a/requirements-dev.txt b/requirements-dev.txt index ee01458..cf08456 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,17 +1,21 @@ black check-manifest doctr +h5netcdf +h5pyd httpx nbsphinx netCDF4 pooch pre-commit +pydap pylint pytest pytest-cov pytest-flake8 pytest-github-actions-annotate-failures pytest-xdist +pytest-xprocess recommonmark ruff setuptools_scm diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..fb2b386 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,45 @@ +"""Py.test configuration and shared fixtures.""" +from pathlib import Path + +import pytest +from xprocess import ProcessStarter + +server_path = Path(__file__).parent / "server.py" + + +@pytest.fixture +def xpublish_server(xprocess): + """Launch an Xpublish server in the background. + + Server has the air_temperature tutorial dataset + at `air` and has the OpenDAP plugin running with + defaults. + """ + + class Starter(ProcessStarter): + # Wait till the pattern is printed before + # considering things started + pattern = "Uvicorn running on" + + # server startup args + args = ["python", str(server_path)] + + # seconds before timing out on server startup + timeout = 30 + + # Try to cleanup if inturrupted + terminate_on_interrupt = True + + xprocess.ensure("xpublish", Starter) + yield "http://0.0.0.0:9000" + xprocess.getinfo("xpublish").terminate() + + +@pytest.fixture(scope="session") +def dataset(): + """Xarray air temperature tutorial dataset.""" + from xarray.tutorial import open_dataset + + ds = open_dataset("air_temperature") + + return ds diff --git a/tests/server.py b/tests/server.py new file mode 100644 index 0000000..2492001 --- /dev/null +++ b/tests/server.py @@ -0,0 +1,11 @@ +"""Test OpenDAP server with air temperature dataset.""" +import xarray.tutorial +import xpublish + +from xpublish_opendap import OpenDapPlugin + +ds = xarray.tutorial.open_dataset("air_temperature") + +rest = xpublish.Rest({"air": ds}, plugins={"opendap": OpenDapPlugin()}) + +rest.serve() diff --git a/tests/test_server.py b/tests/test_server.py new file mode 100644 index 0000000..acdfcae --- /dev/null +++ b/tests/test_server.py @@ -0,0 +1,25 @@ +"""Test OpenDAP clients against Xpublish OpenDAP plugin.""" +import netCDF4 +import pytest +import xarray as xr + + +def test_netcdf4(xpublish_server): + """Test opening OpenDAP dataset directly with NetCDF4 library.""" + url = f"{xpublish_server}/datasets/air/opendap" + netCDF4.Dataset(url) + + +def test_default_xarray_engine(xpublish_server, dataset): + """Test opening OpenDAP dataset with default Xarray engine.""" + url = f"{xpublish_server}/datasets/air/opendap" + ds = xr.open_dataset(url) + assert ds == dataset + + +@pytest.mark.parametrize("engine", ["netcdf4", "h5netcdf", "pydap"]) +def test_xarray_engines(xpublish_server, engine, dataset): + """Test opening OpenDAP dataset with specified engines.""" + url = f"{xpublish_server}/datasets/air/opendap" + ds = xr.open_dataset(url, engine=engine) + assert ds == dataset