Skip to content

Commit

Permalink
Add utils tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JB Lovland committed Jan 10, 2024
1 parent 2c13a20 commit 7658616
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 29 deletions.
51 changes: 26 additions & 25 deletions src/fmu/dataio/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,15 @@ def detect_inside_rms() -> bool:
when using the Roxar API python, so that unit test outside of RMS behaves
properly
"""
inside_rms = False
try:
with contextlib.suppress(ModuleNotFoundError):
import roxar

inside_rms = True
logger.info("Roxar version is %s", roxar.__version__)
except ModuleNotFoundError:
pass
return True

# a special solution for testing mostly
if os.environ.get("INSIDE_RMS", 1) == "0":
inside_rms = False

inside_rms = os.environ.get("INSIDE_RMS", "0") != "0"
logger.info("Running truly in RMS GUI status: %s", inside_rms)

return inside_rms


Expand All @@ -82,31 +76,38 @@ def drop_nones(dinput: dict) -> dict:


def export_metadata_file(
yfile: Path,
file: Path,
metadata: dict,
savefmt: Literal["yaml", "json"] = "yaml",
verbosity: str = "WARNING",
) -> None:
"""Export genericly and ordered to the complementary metadata file."""
logger.setLevel(level=verbosity)
if metadata:
xdata = drop_nones(metadata)

if savefmt == "yaml":
yamlblock = oyaml.safe_dump(xdata, allow_unicode=True) # type: ignore
with open(yfile, "w", encoding="utf8") as stream:
stream.write(yamlblock)
else:
jfile = str(yfile).replace(".yml", ".json")
jsonblock = json.dumps(xdata, default=str, indent=2, ensure_ascii=False)
with open(jfile, "w") as stream:
stream.write(jsonblock)

else:
if not metadata:
raise RuntimeError(
"Export of metadata was requested, but no metadata are present."
)
logger.info("Yaml file on: %s", yfile)

if savefmt == "yaml":
with open(file, "w", encoding="utf8") as stream:
stream.write(
oyaml.safe_dump( # type: ignore
drop_nones(metadata),
allow_unicode=True,
)
)
else:
with open(file.replace(file.with_suffix(".json")), "w") as stream:
stream.write(
json.dumps(
drop_nones(metadata),
default=str,
indent=2,
ensure_ascii=False,
)
)

logger.info("Yaml file on: %s", file)


def export_file(
Expand Down
33 changes: 29 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""The conftest.py, providing magical fixtures to tests."""
import contextlib
import datetime
import inspect
import json
Expand Down Expand Up @@ -45,15 +46,39 @@ def pytest_configure():
cprint(80 * "=", "red", attrs=["blink"])


@contextlib.contextmanager
def set_export_data_inside_rms_flag():
old = ExportData._inside_rms
ExportData._inside_rms = True
try:
yield
finally:
ExportData._inside_rms = old


@contextlib.contextmanager
def set_environ_inside_rms_flag():
unset = object()
old = os.environ.get("INSIDE_RMS", unset)
os.environ["INSIDE_RMS"] = "1"
try:
yield
finally:
if old is unset:
del os.environ["INSIDE_RMS"]
else:
os.environ["INSIDE_RMS"] = old


def inside_rms(func):
"""Decorator for being inside RMS"""

@wraps(func)
def wrapper(*args, **kwargs):
ExportData._inside_rms = True
retval = func(*args, **kwargs)
ExportData._inside_rms = False
return retval
with contextlib.ExitStack() as exitstack:
exitstack.enter_context(set_environ_inside_rms_flag())
exitstack.enter_context(set_export_data_inside_rms_flag())
return func(*args, **kwargs)

return wrapper

Expand Down
148 changes: 148 additions & 0 deletions tests/test_units/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
"""Test the utils module"""

from pathlib import Path
from tempfile import NamedTemporaryFile

import numpy as np
import pytest
from conftest import set_environ_inside_rms_flag
from fmu.dataio import _utils as utils
from xtgeo import Grid, Polygons, RegularSurface


@pytest.mark.parametrize(
Expand All @@ -24,3 +30,145 @@
)
def test_check_if_number(value, result):
assert utils.check_if_number(value) == result


@pytest.mark.parametrize(
"given, expected, isoformat",
(
(
{},
(None, None),
True,
),
(
{"time": {"t0": {"value": "2022-08-02T00:00:00", "label": "base"}}},
("2022-08-02T00:00:00", None),
True,
),
(
{
"time": [
{"value": "2030-01-01T00:00:00", "label": "moni"},
{"value": "2010-02-03T00:00:00", "label": "base"},
]
},
("2030-01-01T00:00:00", "2010-02-03T00:00:00"),
True,
),
(
{},
(None, None),
False,
),
(
{"time": {"t0": {"value": "2022-08-02T00:00:00", "label": "base"}}},
("20220802", None),
False,
),
(
{
"time": [
{"value": "2030-01-01T00:00:00", "label": "moni"},
{"value": "2010-02-03T00:00:00", "label": "base"},
]
},
("20300101", "20100203"),
False,
),
),
)
def test_parse_timedata(given: dict, expected: tuple, isoformat: bool):
assert utils.parse_timedata(given, isoformat) == expected


def test_get_object_name():
assert utils.get_object_name(object()) is None

assert utils.get_object_name(RegularSurface(0, 0, 0, 0)) is None
assert (
utils.get_object_name(RegularSurface(0, 0, 0, 0, name="Not ukn")) == "Not ukn"
)

assert utils.get_object_name(Polygons()) is None
assert utils.get_object_name(Polygons(name="Not poly")) == "Not poly"

assert (
utils.get_object_name(
Grid(
np.random.randn(2, 2, 6).astype(np.float64),
np.random.randn(2, 2, 2, 4).astype(np.float32),
np.random.randn(1, 1, 1).astype(np.int32),
name="noname",
)
)
is None
)
assert (
utils.get_object_name(
Grid(
np.random.randn(2, 2, 6).astype(np.float64),
np.random.randn(2, 2, 2, 4).astype(np.float32),
np.random.randn(1, 1, 1).astype(np.int32),
name="Not noname",
)
)
== "Not noname"
)


def test_detect_inside_rms():
assert not utils.detect_inside_rms()
with set_environ_inside_rms_flag():
assert utils.detect_inside_rms()


def test_non_metadata_export_metadata_file():
with NamedTemporaryFile(buffering=0, suffix=".yaml") as tf, pytest.raises(
RuntimeError
):
utils.export_metadata_file(Path(tf.name), {}, savefmt="json")

with NamedTemporaryFile(buffering=0, suffix=".yaml") as tf, pytest.raises(
RuntimeError
):
utils.export_metadata_file(Path(tf.name), {}, savefmt="yaml")


def test_export_file_raises():
with NamedTemporaryFile() as tf, pytest.raises(TypeError):
utils.export_file(
object(),
Path(tf.name),
".placeholder",
)


def test_create_symlink():
with pytest.raises(OSError):
utils.create_symlink(
"hopefullythispathwillneverexist",
"norwillthispath",
)

with NamedTemporaryFile() as source, NamedTemporaryFile() as target, pytest.raises(
OSError
):
utils.create_symlink(
source.name,
target.name,
)


def test_generate_description():
assert utils.generate_description("") is None
assert utils.generate_description([]) is None
assert utils.generate_description(None) is None

assert utils.generate_description("str description") == ["str description"]
assert utils.generate_description(["str description"]) == ["str description"]

with pytest.raises(ValueError):
utils.generate_description({"key": "value"})

with pytest.raises(ValueError):
utils.generate_description(object())

0 comments on commit 7658616

Please sign in to comment.