Initial commit
Deploy Solar Relay / deploy (push) Failing after 4s

This commit is contained in:
franzz committed 2026-11-01 22:33:32 +01:00
1 parent 36180dffd7
commit ec75ac15b0
30 files changed
+3042 -1

No files matched your search

+91
View File
@@ -0,0 +1,91 @@
"""Exercise the real recording loop with an advancing clock instead of real waits."""
from pathlib import Path
import tempfile
import unittest
from unittest.mock import Mock, patch
from solar_relay.cli import _run
from solar_relay.config import CollectorConfig, Config, HttpConfig, InverterConfig, UploadConfig, load_config
class Clock:
def __init__(self, now):
self.now = now
self.stopped = False
self.waits = []
def is_set(self):
return self.stopped
def set(self):
self.stopped = True
def wait(self, delay):
self.waits.append((self.now, delay))
if not self.stopped:
self.now += delay
return self.stopped
class ScheduleTests(unittest.TestCase):
def run_collector(self, start, count=3, duration=8, cancel=False):
clock = Clock(start)
recorded = []
config = Config(CollectorConfig("test-house", Path("unused")), InverterConfig(), UploadConfig(), HttpConfig(enabled=False))
store = Mock()
store.prune.return_value = 0
def record(*args):
recorded.append(clock.now)
clock.now += duration
if len(recorded) == count:
clock.set()
def cancel_wait(delay):
clock.set()
return True
if cancel:
clock.wait = cancel_wait
with patch("solar_relay.cli.threading.Event", return_value=clock), \
patch("solar_relay.cli.time.time", side_effect=lambda: clock.now), \
patch("solar_relay.cli.time.monotonic", side_effect=lambda: clock.now), \
patch("solar_relay.cli.signal.signal"), \
patch("solar_relay.cli.FroniusClient"), \
patch("solar_relay.cli._record", side_effect=record):
self.assertEqual(_run(config, store), 0)
return recorded, clock
def test_startup_waits_then_records_once_on_each_boundary(self):
recorded, clock = self.run_collector(301)
self.assertEqual(recorded, [600, 900, 1200])
self.assertEqual(clock.waits[0], (301, 299))
self.assertTrue(all(stamp % 300 == 0 for stamp in recorded))
def test_restart_in_the_same_interval_adds_no_extra_observation(self):
before, _ = self.run_collector(590, count=1)
after, _ = self.run_collector(615, count=2)
self.assertEqual(before + after, [600, 900, 1200])
def test_slow_collection_skips_missed_boundaries_without_catching_up(self):
recorded, _ = self.run_collector(301, count=2, duration=370)
self.assertEqual(recorded, [600, 1200])
def test_shutdown_while_waiting_does_not_take_a_final_observation(self):
recorded, _ = self.run_collector(301, cancel=True)
self.assertEqual(recorded, [])
def test_configuration_requires_exactly_five_minutes(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "config.toml"
for interval in (30, 60, 299, 301, 600):
path.write_text(f"[collector]\npoll_interval_seconds = {interval}\n")
with self.assertRaisesRegex(ValueError, "must be 300"):
load_config(path)
path.write_text("[collector]\npoll_interval_seconds = 300\n")
self.assertEqual(load_config(path).collector.poll_interval_seconds, 300)
if __name__ == "__main__":
unittest.main()