This commit is contained in:
1 parent
cd7ddd3cf6
commit
89621bc7c3
15 files changed
+289
-74
No files matched your search
+29
-5
@@ -68,13 +68,13 @@ class HistoryTests(unittest.TestCase):
|
||||
self.assertEqual(self.recover(), 0)
|
||||
self.assertEqual(len(self.client.requests), 2)
|
||||
|
||||
def test_cloud_energy_does_not_mark_boiler_or_meter_history_complete(self):
|
||||
def test_cloud_energy_does_not_mark_boiler_history_complete(self):
|
||||
self.assertEqual(self.recover(), 3)
|
||||
rows = self.store.coverage(self.source, "UTC", 1, self.when + timedelta(days=1))
|
||||
day = rows[1]
|
||||
self.assertEqual(day["energy_complete"], 3)
|
||||
self.assertEqual(day["boiler_complete"], 0)
|
||||
self.assertEqual(day["meter_complete"], 0)
|
||||
self.assertNotIn("meter_complete", day)
|
||||
self.assertEqual(day["complete"], 0)
|
||||
row = pq.ParquetFile(next(self.store.path.glob("date=*/samples.parquet"))).read().to_pylist()[0]
|
||||
self.assertEqual(row["record_kind"], "history")
|
||||
@@ -148,7 +148,7 @@ class HistoryTests(unittest.TestCase):
|
||||
|
||||
def test_automatic_recovery_checks_retention_before_first_observation_and_respects_cutoff(self):
|
||||
now = datetime(2026, 11, 2, 12, 2, 17, tzinfo=timezone.utc)
|
||||
cutoff = datetime(2026, 10, 3, 12, 5, tzinfo=timezone.utc)
|
||||
cutoff = datetime(2026, 10, 3, tzinfo=ZoneInfo("Europe/Zurich")).astimezone(timezone.utc)
|
||||
latest = datetime(2026, 11, 2, 10, tzinfo=timezone.utc)
|
||||
recoverable = [cutoff, now.replace(minute=0, second=0) - timedelta(days=25), latest - timedelta(minutes=5)]
|
||||
points = {int(when.timestamp() * 1000): 1200 for when in
|
||||
@@ -158,7 +158,31 @@ class HistoryTests(unittest.TestCase):
|
||||
self.assertEqual(self.recovery.recover(now=now), 3)
|
||||
recovered = [record for record in self.store.records() if "history_interval" in record]
|
||||
self.assertEqual([record["observed_at"] for record in recovered], [utc_text(when) for when in recoverable])
|
||||
self.assertEqual(min(day for _, _, day in self.client.requests), cutoff.date())
|
||||
self.assertEqual(min(day for _, _, day in self.client.requests), cutoff.astimezone(self.recovery.zone).date())
|
||||
|
||||
def test_oldest_retained_day_recovers_all_288_intervals_including_midnight(self):
|
||||
zone = ZoneInfo("Europe/Zurich")
|
||||
start = datetime(2026, 10, 3, tzinfo=zone)
|
||||
end = start + timedelta(days=1)
|
||||
points = {stamp: 1200 for stamp in range(int(start.timestamp() * 1000), int(end.timestamp() * 1000), 300_000)}
|
||||
self.client.points = {"production": points, "consumption": points}
|
||||
self.assertEqual(self.recovery.recover(now=datetime(2026, 11, 2, 22, 30, tzinfo=zone)), 288)
|
||||
records = list(self.store.records())
|
||||
self.assertEqual(records[0]["observed_at"], utc_text(start))
|
||||
self.assertEqual(records[-1]["observed_at"], utc_text(end - timedelta(minutes=5)))
|
||||
|
||||
def test_retention_uses_the_configured_timezone_instead_of_utc(self):
|
||||
now = datetime(2026, 11, 2, 1, 30, tzinfo=timezone.utc)
|
||||
recovery = HistoryRecovery(self.config, self.source, self.store, timezone_name="America/New_York", client=self.client)
|
||||
recovery.recover(now=now)
|
||||
self.assertEqual(min(day for _, _, day in self.client.requests).isoformat(), "2026-10-02")
|
||||
|
||||
def test_thirty_calendar_day_manual_range_can_cross_a_25_hour_dst_day(self):
|
||||
zone = ZoneInfo("Europe/Zurich")
|
||||
self.client.points = {"production": {}, "consumption": {}}
|
||||
self.assertEqual(self.recovery.recover(utc_text(datetime(2026, 10, 3, tzinfo=zone)),
|
||||
utc_text(datetime(2026, 11, 2, tzinfo=zone)),
|
||||
now=datetime(2026, 11, 3, tzinfo=zone)), 0)
|
||||
|
||||
def test_automatic_recovery_checks_entirely_empty_days_and_archives(self):
|
||||
self.store.retention_days = 2
|
||||
@@ -176,7 +200,7 @@ class HistoryTests(unittest.TestCase):
|
||||
|
||||
def test_complete_retention_window_does_not_request_solarweb(self):
|
||||
now = self.when + timedelta(days=1)
|
||||
lower = int(self.when.timestamp())
|
||||
lower = int(datetime(2026, 10, 30, tzinfo=ZoneInfo("Europe/Zurich")).timestamp())
|
||||
upper = int((now - timedelta(seconds=self.config.lag_seconds)).timestamp())
|
||||
store = Mock(retention_days=1)
|
||||
store.energy_slots.return_value = set(range(lower, upper, 300))
|
||||
|
||||
Reference in new issue
Block a user