Skip to content

Commit

Permalink
Tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
cipherself committed Feb 16, 2024
1 parent ca49a89 commit b05d900
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/enlyze/api_clients/timeseries/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def merge(self, other: "TimeseriesData") -> "TimeseriesData":
f" with {slen} records."
)

self.columns.extend(other.columns)
self.columns.extend(other.columns[1:])

for s, o in zip(self.records, other.records):
if s[0] != o[0]:
Expand Down
11 changes: 7 additions & 4 deletions src/enlyze/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def _get_variables_sequence_and_query_parameter_list(
validate_resampling_interval(resampling_interval)
variables_sequence = []
variables_query_parameter_list = []
for variable, resampling_method in variables.items():
for variable, resampling_method in variables.items(): # type: ignore
variables_sequence.append(variable)
variables_query_parameter_list.append(
f"{variable.uuid}"
Expand All @@ -72,7 +72,7 @@ def _get_variables_sequence_and_query_parameter_list(
)
return variables_sequence, variables_query_parameter_list

return variables, [str(v.uuid) for v in variables]
return variables, [str(v.uuid) for v in variables] # type: ignore


class EnlyzeClient:
Expand Down Expand Up @@ -254,9 +254,12 @@ def _get_timeseries(
if not timeseries_data_chunked or None in timeseries_data_chunked:
return None

timeseries_data = reduce(lambda x, y: x.merge(y), timeseries_data_chunked)
try:
timeseries_data = reduce(lambda x, y: x.merge(y), timeseries_data_chunked) # type: ignore # noqa
except ValueError as e:
raise EnlyzeError from e

return timeseries_data.to_user_model(
return timeseries_data.to_user_model( # type: ignore
start=start,
end=end,
variables=variables_sequence,
Expand Down
82 changes: 82 additions & 0 deletions tests/enlyze/api_clients/timeseries/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from datetime import datetime, timedelta, timezone

import pytest

from enlyze.api_clients.timeseries.models import TimeseriesData


# We use this to skip columns that contain the timestamp assuming
# it starts at the beginning of the sequence. We also use it
# when computing lengths to account for a timestamp column.
TIMESTAMP_OFFSET = 1


@pytest.fixture
def timestamp():
return datetime.now(tz=timezone.utc)


@pytest.fixture
def timeseries_data_1(timestamp):
return TimeseriesData(
columns=["time", "var1", "var2"],
records=[
[timestamp.isoformat(), 1, 2],
[(timestamp - timedelta(minutes=10)).isoformat(), 3, 4],
],
)


@pytest.fixture
def timeseries_data_2(timestamp):
return TimeseriesData(
columns=["time", "var3"],
records=[
[timestamp.isoformat(), 5],
[(timestamp - timedelta(minutes=10)).isoformat(), 6],
],
)


class TestTimeseriesData:
def test_merge(self, timeseries_data_1, timeseries_data_2):
timeseries_data_1_records_len = len(timeseries_data_1.records)
timeseries_data_1_columns_len = len(timeseries_data_1.columns)
timeseries_data_2_records_len = len(timeseries_data_2.records)
timeseries_data_2_columns_len = len(timeseries_data_2.columns)
expected_merged_record_len = len(timeseries_data_1.records[0]) + len(
timeseries_data_2.records[0][TIMESTAMP_OFFSET:]
)

merged = timeseries_data_1.merge(timeseries_data_2)

assert merged is timeseries_data_1
assert (
len(merged.records)
== timeseries_data_1_records_len
== timeseries_data_2_records_len
)
assert (
len(merged.columns)
== timeseries_data_1_columns_len + timeseries_data_2_columns_len - TIMESTAMP_OFFSET
)

for r in merged.records:
assert len(r) == expected_merged_record_len

def test_merge_raises_number_of_records_mismatch(
self, timeseries_data_1, timeseries_data_2
):
timeseries_data_2.records = timeseries_data_2.records[1:]
with pytest.raises(
ValueError, match="Number of records in both instances has to be the same"
):
timeseries_data_1.merge(timeseries_data_2)

def test_merge_raises_mismatched_timestamps(
self, timeseries_data_1, timeseries_data_2, timestamp
):
timeseries_data_2.records[0][0] = (timestamp - timedelta(days=1)).isoformat()

with pytest.raises(ValueError, match="mismatched timestamps"):
timeseries_data_1.merge(timeseries_data_2)
74 changes: 74 additions & 0 deletions tests/enlyze/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,80 @@ def test_get_timeseries_raises_api_returned_no_timestamps(
client.get_timeseries(start_datetime, end_datetime, [variable])


@given(
variable=st.builds(user_models.Variable),
)
@settings(suppress_health_check=[HealthCheck.function_scoped_fixture])
def test__get_timeseries_raises_variables_without_resampling_method(
start_datetime, end_datetime, variable
):
"""
Test that `get_timeseries` will raise an `EnlyzeError` when a
`resampling_interval` is specified but variables don't have
resampling methods.
"""
client = make_client()
with pytest.raises(EnlyzeError) as exc_info:
client._get_timeseries(start_datetime, end_datetime, [variable], 30)
assert isinstance(exc_info.value.__cause__, ValueError)


@given(
variable=st.builds(user_models.Variable),
)
@settings(suppress_health_check=[HealthCheck.function_scoped_fixture])
def test__get_timeseries_raises_on_chunk_value_error(
start_datetime, end_datetime, variable, monkeypatch
):
monkeypatch.setattr(
"enlyze.client.MAXIMUM_NUMBER_OF_VARIABLES_PER_TIMESERIES_REQUEST", 0
)
client = make_client()
with pytest.raises(EnlyzeError) as exc_info:
client._get_timeseries(start_datetime, end_datetime, [variable])
assert isinstance(exc_info.value.__cause__, ValueError)


@given(
start=datetime_before_today_strategy,
end=datetime_today_until_now_strategy,
variable=st.builds(
user_models.Variable,
data_type=st.just("INTEGER"),
machine=st.builds(timeseries_api_models.Machine),
),
records=st.lists(
st.tuples(
datetime_today_until_now_strategy.map(datetime.isoformat),
st.integers(),
),
min_size=2,
),
)
@settings(suppress_health_check=[HealthCheck.function_scoped_fixture])
def test__get_timeseries_raises_on_merge_value_error(
start, end, variable, records, monkeypatch
):
client = make_client()

def f(*args, **kwargs):
raise ValueError

monkeypatch.setattr("enlyze.client.reduce", f)

with respx_mock_with_base_url(TIMESERIES_API_SUB_PATH) as mock:
mock.get("timeseries").mock(
PaginatedTimeseriesApiResponse(
data=timeseries_api_models.TimeseriesData(
columns=["time", str(variable.uuid)],
records=records,
).model_dump()
)
)
with pytest.raises(EnlyzeError):
client._get_timeseries(start, end, [variable])


@given(
production_order=st.just(PRODUCTION_ORDER),
product=st.one_of(
Expand Down

0 comments on commit b05d900

Please sign in to comment.