mirror of
https://github.com/OMGeeky/flucto-heisskleber.git
synced 2025-12-27 23:08:08 +01:00
* WIP: Added async file reader. * Async resampling and synchronization refactored. * Add async mqtt publisher. Remove queue from joint. * Add async zmq publisher and subscriber. * Modify integration tests for streaming. * Name refactoring resampler. * Added async source/sink to factory. * Refactor joint and add integration tests. * Add termcolor dev dependency * Add conosole source and sink * Add cli interface for different protocols * Removed files unfit for merge. * Fix review requests. * Restore use of $MSB_CONFIG_DIR for now. It seems that the default behaviour is not looking for .config/heisskleber * Remove version test, causing unnecessary failures.
104 lines
3.5 KiB
Python
104 lines
3.5 KiB
Python
from datetime import datetime, timedelta
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
from heisskleber.mqtt import AsyncMqttSubscriber
|
|
from heisskleber.stream import Resampler, ResamplerConf
|
|
from heisskleber.stream.resampler import floor_dt, timestamp_generator
|
|
|
|
|
|
class EndofData(Exception):
|
|
pass
|
|
|
|
|
|
# Mocking the MQTT Subscriber
|
|
@pytest.fixture
|
|
def mock_subscriber():
|
|
mock = MagicMock(spec=AsyncMqttSubscriber)
|
|
return mock
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"time_in,expected",
|
|
[
|
|
(datetime.fromtimestamp(0.1), datetime.fromtimestamp(0.0)),
|
|
(datetime.fromtimestamp(0.6), datetime.fromtimestamp(0.5)),
|
|
(datetime.fromtimestamp(0.9), datetime.fromtimestamp(0.5)),
|
|
(datetime.fromtimestamp(1.1), datetime.fromtimestamp(1.0)),
|
|
],
|
|
)
|
|
def test_round_dt(time_in, expected):
|
|
delta_t = timedelta(milliseconds=500)
|
|
assert floor_dt(time_in, delta_t) == expected
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"start,frequency,expected",
|
|
[
|
|
(0.1, 500, [0.25, 0.75, 1.25]),
|
|
(0.6, 1000, [0.5, 1.5, 2.5]),
|
|
(0.9, 2000, [1.0, 3.0, 5.0]),
|
|
(0.04, 50, [0.025, 0.075, 0.125]),
|
|
],
|
|
)
|
|
def test_timestamp_generator(start, frequency, expected):
|
|
"""Test the timestamp generator.
|
|
Expectation is that it will generate timestamps with the frequency as stride length and
|
|
start at the floow value of the start timestamp with half the stride length offset.
|
|
"""
|
|
generator = timestamp_generator(start, frequency)
|
|
for ts, exp in zip(generator, expected):
|
|
assert ts == exp
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resampler_multiple_modes(mock_subscriber):
|
|
mock_subscriber.receive = AsyncMock(
|
|
side_effect=[
|
|
("topic1", {"epoch": 0.05, "data": 1}), # 1st interval
|
|
("topic1", {"epoch": 0.10, "data": 2}), # 1st interval
|
|
("topic1", {"epoch": 0.90, "data": 3}), # 2nd inverval
|
|
("topic1", {"epoch": 1.10, "data": 4}), # 2nd interval
|
|
("topic1", {"epoch": 1.51, "data": 6}), # 3rd interval
|
|
("topic1", {"epoch": 2.51, "data": 7}), # 4th interval
|
|
("topic1", {"epoch": 4.00, "data": 10}), # 5th interval
|
|
EndofData(),
|
|
]
|
|
)
|
|
|
|
config = ResamplerConf(resample_rate=1000) # Fill in your MQTT configuration
|
|
resampler = Resampler(config, mock_subscriber)
|
|
|
|
# Test the resample method
|
|
resampled_data = [await resampler.receive() for _ in range(3)]
|
|
|
|
assert resampled_data[0] == {"epoch": 0.0, "data": 1.5}
|
|
assert resampled_data[1] == {"epoch": 1.0, "data": 3.5}
|
|
assert resampled_data[2] == {"epoch": 2.0, "data": 6}
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resampler_upsampling(mock_subscriber):
|
|
mock_subscriber.receive = AsyncMock(
|
|
side_effect=[
|
|
("topic1", {"epoch": 0.0, "data": 1}), # 1st interval
|
|
("topic1", {"epoch": 1.0, "data": 2}), # 2st interval
|
|
("topic1", {"epoch": 2.0, "data": 3}), # 3nd inverval
|
|
EndofData(),
|
|
]
|
|
)
|
|
|
|
config = ResamplerConf(resample_rate=250) # Fill in your MQTT configuration
|
|
resampler = Resampler(config, mock_subscriber)
|
|
|
|
# Test the resample method
|
|
resampled_data = [await resampler.receive() for _ in range(7)]
|
|
|
|
assert resampled_data[0] == {"epoch": 0.0, "data": 1.0}
|
|
assert resampled_data[1] == {"epoch": 0.25, "data": 1.25}
|
|
assert resampled_data[2] == {"epoch": 0.5, "data": 1.5}
|
|
assert resampled_data[3] == {"epoch": 0.75, "data": 1.75}
|
|
assert resampled_data[4] == {"epoch": 1.0, "data": 2.0}
|
|
assert resampled_data[5] == {"epoch": 1.25, "data": 2.25}
|