Skip to content

Commit

Permalink
Merge pull request #9 from SNEWS2/clean-up-test-and-models
Browse files Browse the repository at this point in the history
Clean up test and models
  • Loading branch information
justinvasel authored Aug 19, 2024
2 parents a7d577b + 4b1767b commit f29646d
Show file tree
Hide file tree
Showing 8 changed files with 1,173 additions and 1,044 deletions.
2,105 changes: 1,086 additions & 1,019 deletions poetry.lock

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ pydantic = "^2.4.2"
single-version = "^1.6.0"
pydantic-extra-types = "^2.1.0"
pycountry = "^22.3.5"
pytest-cov = "^4.1.0"
numpy = "^1.26.3"
jupyter = "^1.0.0"
ipykernel = "^6.29.4"


[tool.poetry.group.doc.dependencies]
Expand All @@ -29,8 +26,10 @@ mkdocs-section-index = "^0.3.8"

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.2"
pytest-cov = "^4.1.0"
hypothesis = {extras = ["cli"], version = "^6.88.1"}
ipykernel = "^6.29.0"
jupyter = "^1.0.0"
ipykernel = "^6.29.4"


[tool.poetry.group.test.dependencies]
Expand Down
File renamed without changes.
8 changes: 2 additions & 6 deletions snews/models/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,11 @@ class DetectorMessageBase(MessageBase):
description="Name of the detector that sent the message"
)

@model_validator(mode="after")
def _validate_detector_name(self) -> str:
def is_valid_detector(self):
"""
Ensure the detector name is in the list of supported detectors.
"""

if self.detector_name not in detectors.names and not self.is_test:
raise ValueError(f"Invalid detector name. Options are: {detectors.names}")
return self
return self.detector_name in detectors.names


# .................................................................................................
Expand Down
2 changes: 1 addition & 1 deletion snews/models/timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def to_datetime(self):
@field_validator("timestamp")
def _validate_and_cast_timestamp(cls, v):
if isinstance(v, datetime) and v.tzinfo is not None:
v = v.replace(tzinfo=None)
v = v.astimezone(UTC)

if not isinstance(v, np.datetime64):
v = np.datetime64(v)
Expand Down
35 changes: 22 additions & 13 deletions test/models/test_message_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
# Retraction message
strategy_required_fields_retraction = {
**strategy_required_fields_base,
"retract_message_uuid": st.uuids(version=4).map(lambda x: str(x)),
"retraction_reason": st.text(min_size=1),
}

Expand Down Expand Up @@ -138,12 +137,10 @@ def test_snews_message_model_heartbeat_required(**kwargs):

@given(**strategy_required_fields_heartbeat)
def test_snews_message_model_heartbeat_invalid_detector(**kwargs):
with pytest.raises(ValueError) as exc_info:
msg = HeartbeatMessage(**kwargs)
msg.is_test = False
msg.detector_name = "Super-Duper-K"
msg = HeartbeatMessage(**kwargs)
msg.detector_name = "Super-Duper-K"

assert "Invalid detector name" in str(exc_info.value)
assert msg.is_valid_detector() is False


@given(**strategy_required_fields_heartbeat)
Expand All @@ -158,15 +155,25 @@ def test_snews_message_model_heartbeat_invalid_detector_status(**kwargs):
# Retraction Tests
@given(**strategy_required_fields_retraction)
def test_snews_message_model_retraction_required(**kwargs):
RetractionMessage(**kwargs)
RetractionMessage(
retract_latest_n=3,
**kwargs,
)

RetractionMessage(
retract_message_uuid="1234567890",
**kwargs
)


@given(**strategy_required_fields_retraction)
def test_snews_message_model_retraction_validation_both_indicators(**kwargs):
with pytest.raises(ValueError) as exc_info:
msg = RetractionMessage(**kwargs)
msg.retract_latest_n = 3
msg.retract_message_uid = "1234567890"
RetractionMessage(
retract_latest_n=3,
retract_message_uuid="1234567890",
**kwargs,
)

assert "retract_message_uuid cannot be specified when retract_latest_n > 0" in str(
exc_info.value
Expand All @@ -176,9 +183,11 @@ def test_snews_message_model_retraction_validation_both_indicators(**kwargs):
@given(**strategy_required_fields_retraction)
def test_snews_message_model_retraction_validation_neither_indicator(**kwargs):
with pytest.raises(ValueError) as exc_info:
msg = RetractionMessage(**kwargs)
msg.retract_latest_n = 0
msg.retract_message_uuid = None
RetractionMessage(
retract_latest_n=0,
retract_message_uuid=None,
**kwargs,
)

assert "Must specify either retract_message_uuid or retract_latest_n > 0" in str(
exc_info.value
Expand Down
46 changes: 45 additions & 1 deletion test/unit/test_models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-

# Third-party modules
import pytest

# Local modules
from snews import models

Expand All @@ -18,7 +21,7 @@ def test_import_detector_models():


# .................................................................................................
def test_create_messages_function():
def test_create_messages_function_success():
inputs = {
"detector_name": "Super-K",
"neutrino_time_utc": "2012-06-09T15:31:08.109876",
Expand All @@ -32,6 +35,14 @@ def test_create_messages_function():
assert message_types == [models.messages.CoincidenceTierMessage]


# .................................................................................................
def test_create_messages_function_no_compatible_messages():
with pytest.raises(ValueError) as exc_info:
models.messages.create_messages()

assert "No compatible message types found" in str(exc_info.value)


# .................................................................................................
def test_create_messages_function_with_heartbeats():
inputs = {
Expand All @@ -48,3 +59,36 @@ def test_create_messages_function_with_heartbeats():
models.messages.CoincidenceTierMessage,
models.messages.HeartbeatMessage
]


# .................................................................................................
def test_get_message_fields():
inputs = {
"detector_name": "Super-K",
"detector_status": "ON",
}

msg = models.messages.HeartbeatMessage(**inputs)
fields = set(models.messages.get_fields(msg))
req_fields = set(models.messages.get_fields(msg, required=True))

expected_req_fields = set([
"detector_name",
"detector_status",
"tier"
])

expected_fields = set([
*expected_req_fields,
"id",
"uuid",
"sent_time_utc",
"machine_time_utc",
"is_pre_sn",
"is_test",
"is_firedrill",
"meta",
"schema_version"
])

assert fields == expected_fields and req_fields == expected_req_fields
14 changes: 14 additions & 0 deletions test/unit/test_timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ def test_precision_timestamp_datetime_output():
)


def test_precision_timestamp_tzinfo_conversion():
timestamp = datetime.datetime(
1987, 2, 24, 5, 31, 00,
tzinfo=datetime.timezone(datetime.timedelta(hours=-5), 'EST')
)

t = PrecisionTimestamp(timestamp=timestamp, precision="s")

t_datetime = t.to_datetime()
t_string = t.to_string()

assert t_datetime == timestamp.astimezone(datetime.UTC) and t_string == "1987-02-24T10:31:00Z"


def test_precision_timestamp_incompatible_subtraction():
with pytest.raises(TypeError) as exc_info:
PrecisionTimestamp(timestamp="1987-02-24T05:31:00Z") - 1
Expand Down

0 comments on commit f29646d

Please sign in to comment.