Skip to content

Commit 87dc4ba

Browse files
committed
Add more unit tests for PeriodicFeatureExtractor
Signed-off-by: cwasicki <[email protected]>
1 parent d81bd29 commit 87dc4ba

File tree

1 file changed

+109
-1
lines changed

1 file changed

+109
-1
lines changed

tests/timeseries/test_periodic_feature_extractor.py

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import List
88

99
import numpy as np
10+
import pytest
1011
from frequenz.channels import Broadcast
1112

1213
from frequenz.sdk.timeseries import (
@@ -102,7 +103,7 @@ async def test_interval_shifting() -> None:
102103
assert index_shifted == 1
103104

104105

105-
async def test_feature_extractor() -> None:
106+
async def test_feature_extractor() -> None: # pylint: disable=too-many-statements
106107
"""Test the feature extractor with a moving window that contains data."""
107108
start = UNIX_EPOCH + timedelta(seconds=1)
108109
end = start + timedelta(seconds=2)
@@ -120,6 +121,113 @@ async def test_feature_extractor() -> None:
120121
feature_extractor = await init_feature_extractor(data, timedelta(seconds=5))
121122
assert np.allclose(feature_extractor.avg(start, end), [1.5, 1.5])
122123

124+
async def _test_fun( # pylint: disable=too-many-arguments
125+
data: List[float],
126+
period: int,
127+
start: int,
128+
end: int,
129+
expected: List[float],
130+
weights: List[float] | None = None,
131+
) -> None:
132+
feature_extractor = await init_feature_extractor(
133+
data, timedelta(seconds=period)
134+
)
135+
ret = feature_extractor.avg(
136+
UNIX_EPOCH + timedelta(seconds=start),
137+
UNIX_EPOCH + timedelta(seconds=end),
138+
weights=weights,
139+
)
140+
assert np.allclose(ret, expected)
141+
142+
async def test_09(
143+
period: int,
144+
start: int,
145+
end: int,
146+
expected: List[float],
147+
weights: List[float] | None = None,
148+
) -> None:
149+
data: List[float] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
150+
await _test_fun(data, period, start, end, expected, weights)
151+
152+
async def test_011(
153+
period: int,
154+
start: int,
155+
end: int,
156+
expected: List[float],
157+
weights: List[float] | None = None,
158+
) -> None:
159+
data: List[float] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
160+
await _test_fun(data, period, start, end, expected, weights)
161+
162+
# empty time period
163+
with pytest.raises(ValueError):
164+
await test_09(period=5, start=1, end=1, expected=[4711])
165+
166+
# moving window not multiple of period
167+
with pytest.raises(ValueError):
168+
await test_09(period=3, start=1, end=1, expected=[4711])
169+
170+
# time period in moving window
171+
await test_09(period=2, start=0, end=1, expected=[5])
172+
await test_09(period=2, start=0, end=2, expected=[5, 6])
173+
await test_09(period=2, start=5, end=7, expected=[4, 5])
174+
await test_09(period=2, start=8, end=10, expected=[5, 6])
175+
await test_09(period=5, start=0, end=1, expected=[5])
176+
await test_09(period=5, start=5, end=6, expected=[5])
177+
178+
# time period outside of moving window in future
179+
await test_09(period=5, start=10, end=11, expected=[5])
180+
# time period outside of moving window in past
181+
await test_09(period=5, start=-5, end=-4, expected=[5])
182+
183+
await test_09(period=5, start=0, end=2, expected=[5, 6])
184+
await test_09(period=5, start=0, end=3, expected=[5, 6, 7])
185+
await test_09(period=5, start=0, end=4, expected=[5, 6, 7, 8])
186+
await test_09(period=5, start=1, end=5, expected=[6, 7, 8, 9])
187+
188+
# No full time period in moving window, expect to throw
189+
await test_09(period=5, start=0, end=5, expected=[5, 6, 7, 8, 9])
190+
with pytest.raises(Exception):
191+
await test_09(period=5, start=0, end=6, expected=[5])
192+
with pytest.raises(Exception):
193+
await test_09(period=5, start=0, end=7, expected=[5, 6])
194+
with pytest.raises(Exception):
195+
await test_09(period=5, start=0, end=8, expected=[5, 6, 7])
196+
with pytest.raises(Exception):
197+
await test_09(period=5, start=0, end=9, expected=[5, 6, 7, 8])
198+
with pytest.raises(Exception):
199+
await test_09(period=5, start=0, end=10, expected=[4711])
200+
with pytest.raises(Exception):
201+
await test_09(period=5, start=0, end=11, expected=[5])
202+
with pytest.raises(Exception):
203+
await test_09(period=5, start=0, end=12, expected=[5, 6])
204+
205+
# time period outside window but more matches
206+
await test_09(
207+
period=5, start=8, end=11, expected=[3, 4, 5]
208+
) # First occurence [-2, -1, 0] partly inside window
209+
210+
# time period larger than period
211+
with pytest.raises(Exception):
212+
await test_09(period=2, start=8, end=11, expected=[5])
213+
with pytest.raises(Exception):
214+
await test_09(period=2, start=0, end=3, expected=[5])
215+
216+
# Weights
217+
await test_011(period=4, start=0, end=2, expected=[6, 7])
218+
await test_011(period=4, start=0, end=2, expected=[6, 7], weights=None)
219+
await test_011(period=4, start=0, end=2, expected=[6, 7], weights=[1, 1])
220+
await test_011(
221+
period=4, start=0, end=2, expected=[4, 5], weights=[1, 0]
222+
) # oldest weight first
223+
await test_011(period=4, start=0, end=2, expected=[6, 7], weights=[1, 1])
224+
with pytest.raises(ValueError):
225+
await test_011(
226+
period=4, start=0, end=2, expected=[4711, 4711], weights=[1, 1, 1]
227+
)
228+
with pytest.raises(ValueError):
229+
await test_011(period=4, start=0, end=2, expected=[4711, 4711], weights=[1])
230+
123231

124232
async def test_profiler_calculate_np() -> None:
125233
"""

0 commit comments

Comments
 (0)