shepherd-core 2023.12.1__py3-none-any.whl → 2024.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shepherd_core/__init__.py +3 -2
- shepherd_core/data_models/base/calibration.py +3 -1
- shepherd_core/data_models/base/content.py +11 -4
- shepherd_core/data_models/base/shepherd.py +2 -0
- shepherd_core/data_models/content/energy_environment.py +1 -1
- shepherd_core/data_models/content/virtual_harvester.py +1 -1
- shepherd_core/data_models/content/virtual_source.py +18 -13
- shepherd_core/data_models/experiment/experiment.py +10 -10
- shepherd_core/data_models/experiment/observer_features.py +5 -6
- shepherd_core/data_models/task/observer_tasks.py +1 -1
- shepherd_core/data_models/task/testbed_tasks.py +7 -3
- shepherd_core/data_models/testbed/cape.py +1 -1
- shepherd_core/data_models/testbed/gpio.py +1 -1
- shepherd_core/data_models/testbed/mcu.py +1 -1
- shepherd_core/data_models/testbed/observer.py +1 -1
- shepherd_core/data_models/testbed/target.py +1 -1
- shepherd_core/data_models/testbed/testbed.py +1 -1
- shepherd_core/decoder_waveform/uart.py +1 -0
- shepherd_core/fw_tools/validation.py +1 -2
- shepherd_core/inventory/__init__.py +51 -1
- shepherd_core/inventory/system.py +8 -0
- shepherd_core/reader.py +19 -16
- shepherd_core/testbed_client/cache_path.py +15 -0
- shepherd_core/testbed_client/client.py +2 -3
- shepherd_core/testbed_client/fixtures.py +4 -1
- shepherd_core/testbed_client/user_model.py +6 -4
- shepherd_core/vsource/virtual_converter_model.py +1 -1
- shepherd_core/vsource/virtual_harvester_model.py +1 -0
- shepherd_core/vsource/virtual_source_model.py +1 -0
- shepherd_core/writer.py +5 -2
- {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.1.dist-info}/METADATA +49 -34
- shepherd_core-2024.4.1.dist-info/RECORD +64 -0
- {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.1.dist-info}/WHEEL +1 -1
- {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.1.dist-info}/top_level.txt +0 -1
- shepherd_core/data_models/content/_external_fixtures.yaml +0 -394
- shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -50
- shepherd_core/data_models/content/virtual_harvester_fixture.yaml +0 -159
- shepherd_core/data_models/content/virtual_source_fixture.yaml +0 -229
- shepherd_core/data_models/testbed/cape_fixture.yaml +0 -94
- shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -166
- shepherd_core/data_models/testbed/mcu_fixture.yaml +0 -19
- shepherd_core/data_models/testbed/observer_fixture.yaml +0 -220
- shepherd_core/data_models/testbed/target_fixture.yaml +0 -137
- shepherd_core/data_models/testbed/testbed_fixture.yaml +0 -25
- shepherd_core-2023.12.1.dist-info/RECORD +0 -117
- tests/__init__.py +0 -0
- tests/conftest.py +0 -64
- tests/data_models/__init__.py +0 -0
- tests/data_models/conftest.py +0 -14
- tests/data_models/example_cal_data.yaml +0 -31
- tests/data_models/example_cal_data_faulty.yaml +0 -29
- tests/data_models/example_cal_meas.yaml +0 -178
- tests/data_models/example_cal_meas_faulty1.yaml +0 -142
- tests/data_models/example_cal_meas_faulty2.yaml +0 -136
- tests/data_models/example_config_emulator.yaml +0 -41
- tests/data_models/example_config_experiment.yaml +0 -16
- tests/data_models/example_config_experiment_alternative.yaml +0 -14
- tests/data_models/example_config_harvester.yaml +0 -15
- tests/data_models/example_config_testbed.yaml +0 -26
- tests/data_models/example_config_virtsource.yaml +0 -78
- tests/data_models/test_base_models.py +0 -205
- tests/data_models/test_content_fixtures.py +0 -41
- tests/data_models/test_content_models.py +0 -282
- tests/data_models/test_examples.py +0 -48
- tests/data_models/test_experiment_models.py +0 -277
- tests/data_models/test_task_generation.py +0 -52
- tests/data_models/test_task_models.py +0 -131
- tests/data_models/test_testbed_fixtures.py +0 -47
- tests/data_models/test_testbed_models.py +0 -187
- tests/decoder_waveform/__init__.py +0 -0
- tests/decoder_waveform/test_decoder.py +0 -34
- tests/fw_tools/__init__.py +0 -0
- tests/fw_tools/conftest.py +0 -5
- tests/fw_tools/test_converter.py +0 -76
- tests/fw_tools/test_patcher.py +0 -66
- tests/fw_tools/test_validation.py +0 -56
- tests/inventory/__init__.py +0 -0
- tests/inventory/test_inventory.py +0 -20
- tests/test_cal_hw.py +0 -34
- tests/test_examples.py +0 -40
- tests/test_logger.py +0 -15
- tests/test_reader.py +0 -283
- tests/test_writer.py +0 -169
- tests/testbed_client/__init__.py +0 -0
- tests/vsource/__init__.py +0 -0
- tests/vsource/conftest.py +0 -49
- tests/vsource/test_converter.py +0 -161
- tests/vsource/test_harvester.py +0 -73
- tests/vsource/test_z.py +0 -5
- {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.1.dist-info}/zip-safe +0 -0
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from shepherd_core.decoder_waveform import Uart
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@pytest.fixture
|
|
9
|
-
def example_path() -> Path:
|
|
10
|
-
return Path(__file__).resolve().parent.parent.parent / "examples"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def test_decode_uart(example_path: Path) -> None:
|
|
14
|
-
uwd = Uart(example_path / "uart_raw2.csv")
|
|
15
|
-
_ = uwd.get_symbols()
|
|
16
|
-
_ = uwd.get_lines()
|
|
17
|
-
_ = uwd.get_text()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def test_decode_speedup(example_path: Path) -> None:
|
|
21
|
-
uwd = Uart(example_path / "uart_raw2.csv")
|
|
22
|
-
_ = uwd.get_symbols(force_redo=True)
|
|
23
|
-
_ = uwd.get_lines(force_redo=True)
|
|
24
|
-
_ = uwd.get_text(force_redo=True)
|
|
25
|
-
|
|
26
|
-
# these now have cached the result
|
|
27
|
-
_ = uwd.get_symbols()
|
|
28
|
-
_ = uwd.get_lines()
|
|
29
|
-
_ = uwd.get_text()
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def test_decode_chained(example_path: Path) -> None:
|
|
33
|
-
uwd = Uart(example_path / "uart_raw2.csv")
|
|
34
|
-
_ = uwd.get_text() # get_symbols() and get_lines() is executed automatically
|
tests/fw_tools/__init__.py
DELETED
|
File without changes
|
tests/fw_tools/conftest.py
DELETED
tests/fw_tools/test_converter.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from shepherd_core import fw_tools
|
|
6
|
-
|
|
7
|
-
from .conftest import files_elf
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@pytest.fixture()
|
|
11
|
-
def path_hex(tmp_path: Path) -> Path:
|
|
12
|
-
path_elf = files_elf[0]
|
|
13
|
-
path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
|
|
14
|
-
return fw_tools.elf_to_hex(path_elf, path_hex)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@pytest.mark.converter
|
|
18
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
19
|
-
def test_elf_to_hex(path_elf: Path, tmp_path: Path) -> None:
|
|
20
|
-
path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
|
|
21
|
-
path_gen = fw_tools.elf_to_hex(path_elf, path_hex)
|
|
22
|
-
assert path_hex.exists()
|
|
23
|
-
assert path_hex.as_posix() == path_gen.as_posix()
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@pytest.mark.elf
|
|
27
|
-
@pytest.mark.converter
|
|
28
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
29
|
-
def test_firmware_to_hex_w_elf(path_elf: Path) -> None:
|
|
30
|
-
path_gen = fw_tools.firmware_to_hex(path_elf)
|
|
31
|
-
assert path_gen.exists
|
|
32
|
-
assert path_gen.suffix.lower() == ".hex"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@pytest.mark.elf
|
|
36
|
-
@pytest.mark.converter
|
|
37
|
-
def test_firmware_to_hex_w_hex(path_hex: Path) -> None:
|
|
38
|
-
path_gen = fw_tools.firmware_to_hex(path_hex)
|
|
39
|
-
assert path_gen.exists
|
|
40
|
-
assert path_gen.suffix.lower() == ".hex"
|
|
41
|
-
assert path_gen.as_posix() == path_hex.as_posix()
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@pytest.mark.elf
|
|
45
|
-
@pytest.mark.converter
|
|
46
|
-
def test_firmware_to_hex_w_fail() -> None:
|
|
47
|
-
path_some = Path(__file__).parent / "conftest.py"
|
|
48
|
-
with pytest.raises(ValueError):
|
|
49
|
-
_ = fw_tools.firmware_to_hex(path_some)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@pytest.mark.elf
|
|
53
|
-
@pytest.mark.converter
|
|
54
|
-
def test_hash() -> None:
|
|
55
|
-
hash_a = fw_tools.file_to_hash(files_elf[0])
|
|
56
|
-
hash_b = fw_tools.file_to_hash(files_elf[1])
|
|
57
|
-
hash_c = fw_tools.file_to_hash(files_elf[1])
|
|
58
|
-
assert hash_a != hash_b
|
|
59
|
-
assert hash_b == hash_c
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
@pytest.mark.elf
|
|
63
|
-
@pytest.mark.converter
|
|
64
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
65
|
-
def test_base64(path_elf: Path, tmp_path: Path) -> None:
|
|
66
|
-
b64_a = fw_tools.file_to_base64(path_elf)
|
|
67
|
-
path_b = (tmp_path / path_elf.name).resolve()
|
|
68
|
-
fw_tools.base64_to_file(b64_a, path_b)
|
|
69
|
-
b64_b = fw_tools.file_to_base64(path_b)
|
|
70
|
-
assert b64_a == b64_b
|
|
71
|
-
hash_a = fw_tools.file_to_hash(path_elf)
|
|
72
|
-
hash_b = fw_tools.file_to_hash(path_b)
|
|
73
|
-
assert hash_a == hash_b
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
# extract_firmware() is indirectly tested with Firmware-Class
|
tests/fw_tools/test_patcher.py
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import shutil
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
import pytest
|
|
5
|
-
|
|
6
|
-
from shepherd_core import fw_tools
|
|
7
|
-
|
|
8
|
-
from .conftest import files_elf
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@pytest.mark.elf
|
|
12
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
13
|
-
def test_sym_finding(path_elf: Path) -> None:
|
|
14
|
-
assert fw_tools.find_symbol(path_elf, "SHEPHERD_NODE_ID")
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@pytest.mark.elf
|
|
18
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
19
|
-
def test_sym_reading(path_elf: Path) -> None:
|
|
20
|
-
assert fw_tools.read_symbol(path_elf, "SHEPHERD_NODE_ID")
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@pytest.mark.elf
|
|
24
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
25
|
-
def test_sym_mod(path_elf: Path, tmp_path: Path) -> None:
|
|
26
|
-
value = 0xCAFE
|
|
27
|
-
sym = "SHEPHERD_NODE_ID"
|
|
28
|
-
path_new = tmp_path / path_elf.name
|
|
29
|
-
shutil.copy(path_elf, path_new)
|
|
30
|
-
path_gen = fw_tools.modify_symbol_value(path_new, sym, value, overwrite=False)
|
|
31
|
-
assert path_gen.is_file()
|
|
32
|
-
assert path_gen.as_posix() != path_new.as_posix()
|
|
33
|
-
value_new = fw_tools.read_symbol(path_gen, sym)
|
|
34
|
-
assert value == value_new
|
|
35
|
-
value_old = fw_tools.read_symbol(path_elf, sym)
|
|
36
|
-
assert value_new != value_old
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@pytest.mark.elf
|
|
40
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
41
|
-
def test_sym_mod_overwrite(path_elf: Path, tmp_path: Path) -> None:
|
|
42
|
-
value = 0xCAFE
|
|
43
|
-
sym = "SHEPHERD_NODE_ID"
|
|
44
|
-
path_new = tmp_path / path_elf.name
|
|
45
|
-
shutil.copy(path_elf, path_new)
|
|
46
|
-
path_gen = fw_tools.modify_symbol_value(
|
|
47
|
-
path_new, sym, value, overwrite=True
|
|
48
|
-
) # TODO: WinOS-trouble
|
|
49
|
-
assert path_gen.is_file()
|
|
50
|
-
assert path_gen.as_posix() == path_new.as_posix()
|
|
51
|
-
value_new = fw_tools.read_symbol(path_gen, sym)
|
|
52
|
-
assert value == value_new
|
|
53
|
-
value_old = fw_tools.read_symbol(path_elf, sym)
|
|
54
|
-
assert value_new != value_old
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@pytest.mark.elf
|
|
58
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
59
|
-
def test_id_mod(path_elf: Path, tmp_path: Path) -> None:
|
|
60
|
-
value = 0xCAFE
|
|
61
|
-
path_new = tmp_path / path_elf.name
|
|
62
|
-
shutil.copy(path_elf, path_new)
|
|
63
|
-
path_gen = fw_tools.modify_uid(path_new, value)
|
|
64
|
-
assert path_gen.as_posix() == path_new.as_posix()
|
|
65
|
-
value_new = fw_tools.read_symbol(path_gen, "SHEPHERD_NODE_ID")
|
|
66
|
-
assert value == value_new
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from shepherd_core import fw_tools
|
|
6
|
-
from shepherd_core.data_models import FirmwareDType
|
|
7
|
-
|
|
8
|
-
from .conftest import files_elf
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@pytest.mark.elf
|
|
12
|
-
@pytest.mark.converter
|
|
13
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
14
|
-
def test_elf_detection(path_elf: Path) -> None:
|
|
15
|
-
assert fw_tools.is_elf(path_elf)
|
|
16
|
-
if "nrf" in path_elf.name:
|
|
17
|
-
assert fw_tools.is_elf_nrf52(path_elf)
|
|
18
|
-
elif "msp" in path_elf.name:
|
|
19
|
-
assert fw_tools.is_elf_msp430(path_elf)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@pytest.mark.elf
|
|
23
|
-
@pytest.mark.converter
|
|
24
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
25
|
-
def test_elf_determination(path_elf: Path) -> None:
|
|
26
|
-
assert fw_tools.determine_type(path_elf) == FirmwareDType.path_elf
|
|
27
|
-
if "nrf" in path_elf.name:
|
|
28
|
-
assert fw_tools.determine_arch(path_elf) == "nrf52"
|
|
29
|
-
elif "msp" in path_elf.name:
|
|
30
|
-
assert fw_tools.determine_arch(path_elf) == "msp430"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@pytest.mark.elf
|
|
34
|
-
@pytest.mark.converter
|
|
35
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
36
|
-
def test_hex_detection(path_elf: Path, tmp_path: Path) -> None:
|
|
37
|
-
path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
|
|
38
|
-
path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
|
|
39
|
-
assert fw_tools.is_hex(path_hex)
|
|
40
|
-
if "nrf" in path_elf.name:
|
|
41
|
-
assert fw_tools.is_hex_nrf52(path_hex)
|
|
42
|
-
elif "msp" in path_elf.name:
|
|
43
|
-
assert fw_tools.is_hex_msp430(path_hex)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@pytest.mark.elf
|
|
47
|
-
@pytest.mark.converter
|
|
48
|
-
@pytest.mark.parametrize("path_elf", files_elf)
|
|
49
|
-
def test_hex_determination(path_elf: Path, tmp_path: Path) -> None:
|
|
50
|
-
path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
|
|
51
|
-
path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
|
|
52
|
-
assert fw_tools.determine_type(path_hex) == FirmwareDType.path_hex
|
|
53
|
-
if "nrf" in path_elf.name:
|
|
54
|
-
assert fw_tools.determine_arch(path_hex) == "nrf52"
|
|
55
|
-
elif "msp" in path_elf.name:
|
|
56
|
-
assert fw_tools.determine_arch(path_hex) == "msp430"
|
tests/inventory/__init__.py
DELETED
|
File without changes
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from shepherd_core.inventory import Inventory
|
|
6
|
-
from shepherd_core.inventory import InventoryList
|
|
7
|
-
from shepherd_core.inventory import PythonInventory
|
|
8
|
-
from shepherd_core.inventory import SystemInventory
|
|
9
|
-
from shepherd_core.inventory import TargetInventory
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@pytest.mark.parametrize("inv", [PythonInventory, SystemInventory, TargetInventory, Inventory])
|
|
13
|
-
def test_collect_data(inv: Inventory) -> None:
|
|
14
|
-
inv.collect()
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def test_inventorize(tmp_path: Path) -> None:
|
|
18
|
-
inv = Inventory.collect()
|
|
19
|
-
inl = InventoryList(elements=[inv])
|
|
20
|
-
inl.to_csv(tmp_path / "some.csv")
|
tests/test_cal_hw.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
from typing import Callable
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from shepherd_core.calibration_hw_def import adc_current_to_raw
|
|
6
|
-
from shepherd_core.calibration_hw_def import adc_raw_to_current
|
|
7
|
-
from shepherd_core.calibration_hw_def import adc_raw_to_voltage
|
|
8
|
-
from shepherd_core.calibration_hw_def import adc_voltage_to_raw
|
|
9
|
-
from shepherd_core.calibration_hw_def import dac_raw_to_voltage
|
|
10
|
-
from shepherd_core.calibration_hw_def import dac_voltage_to_raw
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@pytest.mark.parametrize("fn", [adc_current_to_raw, adc_voltage_to_raw, dac_voltage_to_raw])
|
|
14
|
-
def test_convert_to_raw(fn: Callable) -> None:
|
|
15
|
-
values = [-1, -1e-6, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e-0]
|
|
16
|
-
value_prev = -1
|
|
17
|
-
for value in values:
|
|
18
|
-
value_raw = fn(value)
|
|
19
|
-
assert value_raw >= 0
|
|
20
|
-
assert value_raw < 2**18
|
|
21
|
-
assert value_raw >= value_prev
|
|
22
|
-
value_prev = value_raw
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@pytest.mark.parametrize("fn", [adc_raw_to_current, adc_raw_to_voltage, dac_raw_to_voltage])
|
|
26
|
-
def test_convert_to_si(fn: Callable) -> None:
|
|
27
|
-
values = [-100, -1, 0, 1, 2**6, 2**12, 2**18, 2**24]
|
|
28
|
-
value_prev = -1
|
|
29
|
-
for value in values:
|
|
30
|
-
value_si = fn(value)
|
|
31
|
-
assert value_si >= 0
|
|
32
|
-
assert value_si <= 6
|
|
33
|
-
assert value_si >= value_prev
|
|
34
|
-
value_prev = value_si
|
tests/test_examples.py
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import subprocess
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
import pytest
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@pytest.fixture
|
|
9
|
-
def example_path() -> Path:
|
|
10
|
-
path = Path(__file__).resolve().parent.parent / "examples"
|
|
11
|
-
os.chdir(path)
|
|
12
|
-
return path
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
examples = [
|
|
16
|
-
"experiment_generic_var1.py",
|
|
17
|
-
"experiment_models.py",
|
|
18
|
-
"inventory.py",
|
|
19
|
-
"uart_decode_waveform.py",
|
|
20
|
-
"vharvester_simulation.py",
|
|
21
|
-
"vsource_simulation.py",
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@pytest.mark.parametrize("file", examples)
|
|
26
|
-
def test_example_scripts(example_path: Path, file: str) -> None:
|
|
27
|
-
subprocess.check_call(f"python {example_path / file}", shell=True)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
examples_fw = [
|
|
31
|
-
"firmware_model.py",
|
|
32
|
-
"firmware_modification.py",
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@pytest.mark.converter
|
|
37
|
-
@pytest.mark.elf
|
|
38
|
-
@pytest.mark.parametrize("file", examples_fw)
|
|
39
|
-
def test_example_scripts_fw(example_path: Path, file: str) -> None:
|
|
40
|
-
subprocess.check_call(f"python {example_path / file}", shell=True)
|
tests/test_logger.py
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from shepherd_core import get_verbose_level
|
|
4
|
-
from shepherd_core import increase_verbose_level
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@pytest.mark.parametrize("log_level", range(-5, 10))
|
|
8
|
-
def test_log_levels(log_level: int) -> None:
|
|
9
|
-
increase_verbose_level(log_level)
|
|
10
|
-
if log_level <= 2:
|
|
11
|
-
assert get_verbose_level() == 2
|
|
12
|
-
elif log_level <= 3:
|
|
13
|
-
assert get_verbose_level() == log_level
|
|
14
|
-
else:
|
|
15
|
-
assert get_verbose_level() == 3
|
tests/test_reader.py
DELETED
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
import h5py
|
|
5
|
-
import pytest
|
|
6
|
-
import yaml
|
|
7
|
-
|
|
8
|
-
from shepherd_core import Reader
|
|
9
|
-
from shepherd_core import Writer
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def test_reader_metadata(data_h5: Path) -> None:
|
|
13
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
14
|
-
assert sfr.energy() > 0
|
|
15
|
-
assert sfr.is_valid()
|
|
16
|
-
|
|
17
|
-
meta_data_a = sfr.save_metadata()
|
|
18
|
-
meta_path = data_h5.resolve().with_suffix(".yaml")
|
|
19
|
-
assert meta_path.exists()
|
|
20
|
-
with meta_path.open() as meta_file:
|
|
21
|
-
meta_data_b = yaml.safe_load(meta_file)
|
|
22
|
-
assert len(meta_data_b) == len(meta_data_a)
|
|
23
|
-
assert sys.getsizeof(meta_data_b) == sys.getsizeof(meta_data_a)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def test_reader_items(data_h5: Path) -> None:
|
|
27
|
-
"""Access internal"""
|
|
28
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
29
|
-
_ = sfr["data"] # group
|
|
30
|
-
_ = sfr["mode"] # attribute
|
|
31
|
-
with pytest.raises(KeyError):
|
|
32
|
-
_ = sfr["non-existing"]
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def test_reader_open(tmp_path: Path) -> None:
|
|
36
|
-
with pytest.raises(TypeError):
|
|
37
|
-
Reader(file_path=None)
|
|
38
|
-
|
|
39
|
-
tmp_file = (tmp_path / "data.h5").resolve()
|
|
40
|
-
|
|
41
|
-
with pytest.raises(FileNotFoundError):
|
|
42
|
-
Reader(file_path=tmp_file)
|
|
43
|
-
|
|
44
|
-
with tmp_file.open("w") as tf:
|
|
45
|
-
tf.write("abc def ghi")
|
|
46
|
-
with pytest.raises(TypeError):
|
|
47
|
-
Reader(file_path=tmp_file)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def test_reader_meta_repr(data_h5: Path) -> None:
|
|
51
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
52
|
-
print(sfr)
|
|
53
|
-
print(sfr.get_calibration_data())
|
|
54
|
-
print(sfr.get_hrv_config())
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def test_reader_read_open_end(data_h5: Path) -> None:
|
|
58
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
59
|
-
for buf in sfr.read_buffers():
|
|
60
|
-
print(len(buf[0]))
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def test_reader_read_5(data_h5: Path) -> None:
|
|
64
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
65
|
-
for buf in sfr.read_buffers(end_n=5):
|
|
66
|
-
print(len(buf[0]))
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def test_reader_read_start_late(data_h5: Path) -> None:
|
|
70
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
71
|
-
for buf in sfr.read_buffers(start_n=2):
|
|
72
|
-
print(len(buf[0]))
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def test_reader_read_raw(data_h5: Path) -> None:
|
|
76
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
77
|
-
for buf in sfr.read_buffers(is_raw=True):
|
|
78
|
-
print(len(buf[0]))
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def test_reader_non_valid(tmp_path: Path) -> None:
|
|
82
|
-
data_h5 = tmp_path / "data.h5"
|
|
83
|
-
with h5py.File(data_h5, "w") as h5f:
|
|
84
|
-
grp_data = h5f.create_group("data")
|
|
85
|
-
grp_data.create_dataset("time", (0,))
|
|
86
|
-
grp_data.create_dataset("current", (0,))
|
|
87
|
-
grp_data.create_dataset("voltage", (0,))
|
|
88
|
-
grp_data["time"].attrs["gain"] = 1
|
|
89
|
-
grp_data["current"].attrs["gain"] = 1
|
|
90
|
-
grp_data["voltage"].attrs["gain"] = 1
|
|
91
|
-
grp_data["time"].attrs["offset"] = 0
|
|
92
|
-
grp_data["current"].attrs["offset"] = 0
|
|
93
|
-
grp_data["voltage"].attrs["offset"] = 0
|
|
94
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
95
|
-
# try getting metadata -> no exception but safe defaults
|
|
96
|
-
sfr.get_window_samples()
|
|
97
|
-
sfr.get_mode()
|
|
98
|
-
sfr.get_mode()
|
|
99
|
-
sfr.get_hostname()
|
|
100
|
-
sfr.get_datatype()
|
|
101
|
-
assert not sfr.is_valid()
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def test_reader_fault_path(tmp_path: Path) -> None:
|
|
105
|
-
with pytest.raises(FileNotFoundError):
|
|
106
|
-
Reader(tmp_path, verbose=True)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def test_reader_fault_no_data(data_h5: Path) -> None:
|
|
110
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
111
|
-
del sfw.h5file["data"]
|
|
112
|
-
with pytest.raises(KeyError):
|
|
113
|
-
Reader(data_h5, verbose=True)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def test_reader_fault_no_mode(data_h5: Path) -> None:
|
|
117
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
118
|
-
del sfw.h5file.attrs["mode"]
|
|
119
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
120
|
-
assert not sfr.is_valid()
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def test_reader_fault_fake_mode(data_h5: Path) -> None:
|
|
124
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
125
|
-
sfw.h5file.attrs["mode"] = "burning"
|
|
126
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
127
|
-
assert not sfr.is_valid()
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def test_reader_fault_no_window_samples(data_h5: Path) -> None:
|
|
131
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
132
|
-
del sfw.h5file["data"].attrs["window_samples"]
|
|
133
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
134
|
-
assert not sfr.is_valid()
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def test_reader_fault_no_datatype(data_h5: Path) -> None:
|
|
138
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
139
|
-
del sfw.h5file["data"].attrs["datatype"]
|
|
140
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
141
|
-
assert not sfr.is_valid()
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def test_reader_fault_wrong_datatype(data_h5: Path) -> None:
|
|
145
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
146
|
-
sfw.h5file["data"].attrs["datatype"] = "apples"
|
|
147
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
148
|
-
assert not sfr.is_valid()
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def test_reader_fault_wrong_window1(data_h5: Path) -> None:
|
|
152
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
153
|
-
sfw["data"].attrs["datatype"] = "ivcurve"
|
|
154
|
-
sfw["data"].attrs["window_samples"] = 0
|
|
155
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
156
|
-
assert not sfr.is_valid()
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def test_reader_fault_wrong_window2(data_h5: Path) -> None:
|
|
160
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
161
|
-
sfw["data"].attrs["datatype"] = "ivsample"
|
|
162
|
-
sfw["data"].attrs["window_samples"] = 1111
|
|
163
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
164
|
-
# only triggers warning
|
|
165
|
-
assert sfr.is_valid()
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
def test_reader_fault_no_current(data_h5: Path) -> None:
|
|
169
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
170
|
-
del sfw.h5file["data"]["current"]
|
|
171
|
-
with pytest.raises(KeyError):
|
|
172
|
-
Reader(data_h5, verbose=True)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def test_reader_fault_no_voltage(data_h5: Path) -> None:
|
|
176
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
177
|
-
del sfw.h5file["data"]["voltage"]
|
|
178
|
-
with pytest.raises(KeyError):
|
|
179
|
-
Reader(data_h5, verbose=True)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
def test_reader_fault_no_gain(data_h5: Path) -> None:
|
|
183
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
184
|
-
del sfw.h5file["data"]["time"].attrs["gain"]
|
|
185
|
-
with pytest.raises(KeyError):
|
|
186
|
-
Reader(data_h5, verbose=True)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def test_reader_fault_no_offset(data_h5: Path) -> None:
|
|
190
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
191
|
-
del sfw.h5file["data"]["time"].attrs["offset"]
|
|
192
|
-
with pytest.raises(KeyError):
|
|
193
|
-
Reader(data_h5, verbose=True)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def test_reader_fault_non_eq_time(data_h5: Path) -> None:
|
|
197
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
198
|
-
sfw.h5file["data"]["time"].resize((0,))
|
|
199
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
200
|
-
assert sfr.is_valid()
|
|
201
|
-
# soft-criteria ... reader just complains
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def test_reader_fault_unaligned(data_h5: Path) -> None:
|
|
205
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
206
|
-
new_size = sfw.samples_per_buffer / 2
|
|
207
|
-
sfw.h5file["data"]["time"].resize((new_size,))
|
|
208
|
-
sfw.h5file["data"]["voltage"].resize((new_size,))
|
|
209
|
-
sfw.h5file["data"]["current"].resize((new_size,))
|
|
210
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
211
|
-
assert sfr.is_valid()
|
|
212
|
-
# soft-criteria ... reader just complains
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
def test_reader_fault_strange_compression(data_h5: Path) -> None:
|
|
216
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
217
|
-
time = sfw.h5file["data"]["time"][:]
|
|
218
|
-
del sfw.h5file["data"]["time"]
|
|
219
|
-
sfw.h5file["data"].create_dataset(
|
|
220
|
-
"time",
|
|
221
|
-
(0,),
|
|
222
|
-
dtype="u8",
|
|
223
|
-
maxshape=(None,),
|
|
224
|
-
compression="lzf", # something like szip wanted
|
|
225
|
-
)
|
|
226
|
-
sfw.h5file["data"]["time"].resize(time.shape)
|
|
227
|
-
sfw.h5file["data"]["time"][0 : time.shape[0]] = time[: time.shape[0]]
|
|
228
|
-
sfw.h5file["data"]["time"].attrs["gain"] = 1
|
|
229
|
-
sfw.h5file["data"]["time"].attrs["offset"] = 0
|
|
230
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
231
|
-
assert sfr.is_valid()
|
|
232
|
-
# soft-criteria ... reader just complains
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
def test_reader_fault_slow_compression(data_h5: Path) -> None:
|
|
236
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
237
|
-
time = sfw.h5file["data"]["time"][:]
|
|
238
|
-
del sfw.h5file["data"]["time"]
|
|
239
|
-
sfw.h5file["data"].create_dataset(
|
|
240
|
-
"time",
|
|
241
|
-
(0,),
|
|
242
|
-
dtype="u8",
|
|
243
|
-
maxshape=(None,),
|
|
244
|
-
compression="gzip",
|
|
245
|
-
compression_opts=9,
|
|
246
|
-
)
|
|
247
|
-
sfw.h5file["data"]["time"].resize(time.shape)
|
|
248
|
-
sfw.h5file["data"]["time"][0 : time.shape[0]] = time[: time.shape[0]]
|
|
249
|
-
sfw.h5file["data"]["time"].attrs["gain"] = 1
|
|
250
|
-
sfw.h5file["data"]["time"].attrs["offset"] = 0
|
|
251
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
252
|
-
assert sfr.is_valid()
|
|
253
|
-
# soft-criteria ... reader just complains
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
def test_reader_fault_no_hostname(data_h5: Path) -> None:
|
|
257
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
258
|
-
sfw.h5file.attrs["hostname"] = "unknown"
|
|
259
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
260
|
-
assert sfr.is_valid()
|
|
261
|
-
# soft-criteria ... reader just complains
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
def test_reader_fault_jumps_timestamp(data_h5: Path) -> None:
|
|
265
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
266
|
-
assert sfr.check_timediffs()
|
|
267
|
-
with Writer(data_h5, modify_existing=True) as sfw:
|
|
268
|
-
sfw.h5file["data"]["time"][sfw.samples_per_buffer] = 0
|
|
269
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
270
|
-
assert not sfr.check_timediffs()
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
def test_reader_save_meta(data_h5: Path) -> None:
|
|
274
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
275
|
-
assert sfr.save_metadata() != {}
|
|
276
|
-
# yaml now already exists
|
|
277
|
-
assert sfr.save_metadata() == {}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
def test_reader_save_meta_fail(data_h5: Path) -> None:
|
|
281
|
-
with Reader(data_h5, verbose=True) as sfr:
|
|
282
|
-
sfr.file_path = None
|
|
283
|
-
assert sfr.save_metadata() == {}
|