Skip to content
Snippets Groups Projects
  • Em Zhan's avatar
    102da6b5
    Add SIPSANC_DATA_DIR and SIPSANC_LOG_DIR env vars · 102da6b5
    Em Zhan authored
    Allows changing where `sipsanc init` saves its files and where any
    errors in all `sipsanc` subcommands are saved, respectively
    
    Uses these variables in tests to separate the test instance of `sipsanc`
    from the local install
    102da6b5
    History
    Add SIPSANC_DATA_DIR and SIPSANC_LOG_DIR env vars
    Em Zhan authored
    Allows changing where `sipsanc init` saves its files and where any
    errors in all `sipsanc` subcommands are saved, respectively
    
    Uses these variables in tests to separate the test instance of `sipsanc`
    from the local install
test_output.py 2.42 KiB
import os
from importlib import import_module
from subprocess import run

import numpy as np
import pytest
import xarray as xr
import xxhash
from mvcm import get_expected, requires_docker

from sipsanc.cli import INIT_DIR, PRODUCTS, InitProduct

pytestmark = pytest.mark.skipif(
    os.environ.get("CI") is not None,
    reason="files not available yet in CI",
)


@pytest.fixture(
    scope="module",
    params=[
        ("VNP03MOD", "3.1.0", "2019-01-01T06:06"),
        ("VNP03IMG", "3.1.0", "2019-07-20T18:36"),
        ("VNP03IMG", "3.1.0", "2024-11-01T13:42"),
        ("VNP03IMG", "3.1.0", "2024-11-02T13:24"),  # North Pole
        ("VNP03IMG", "3.1.0", "2024-12-25T00:54"),  # South Pole
    ],
)
def truth_data(request, tmp_path_factory):
    product, version, date = request.param
    tmp_path = tmp_path_factory.mktemp("mcvm")
    cmd = ["asipscli", "files"]
    opts = ["-p", product, "-v", version, "-s", date, "-e", date, "-d", str(tmp_path)]
    result = run(cmd + opts, capture_output=True, text=True)
    files = [
        tmp_path / s.split(" ")[0].split("/")[-1] for s in result.stdout.splitlines()
    ]
    assert len(files) == 1
    l1b_file = files[0]

    return l1b_file, get_expected(tmp_path, l1b_file.name)


@requires_docker
@pytest.mark.parametrize("p", PRODUCTS)
def test_truth(truth_data, tmp_path, p):
    l1b_file, truth = truth_data
    l1b = xr.open_datatree(l1b_file, decode_timedelta=False)

    m = import_module(f"sipsanc.products.{p.name}")

    if hasattr(m, "get_files"):
        input = m.get_files(l1b, tmp_path)
    else:
        input = []

    if isinstance(p, InitProduct):
        input.append(INIT_DIR / p.init_output)

    actual = m.regrid(l1b, *input)
    expected = truth[p.name].values

    # special case where expected output is non-deterministic, so replace those
    # values with nans, see comment in geos_sst
    if p.name == "geos_sst":
        expected[np.isnan(actual)] = np.nan

    okay = np.array_equal(actual, expected, equal_nan=True)

    if not okay:
        os.makedirs("tests/fails/", exist_ok=True)
        actual_file = xxhash.xxh32_hexdigest(actual.data)
        np.save(f"tests/fails/{actual_file}", actual)
        expected_file = xxhash.xxh32_hexdigest(expected.data)
        np.save(f"tests/fails/{expected_file}", expected)
        print(f"Run the following to see differences ({m.__name__}):\n")
        print(f"uv run tests/plot-fail.py {actual_file} {expected_file} & disown\n")

    assert okay