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.
Files changed (90) hide show
  1. shepherd_core/__init__.py +3 -2
  2. shepherd_core/data_models/base/calibration.py +3 -1
  3. shepherd_core/data_models/base/content.py +11 -4
  4. shepherd_core/data_models/base/shepherd.py +2 -0
  5. shepherd_core/data_models/content/energy_environment.py +1 -1
  6. shepherd_core/data_models/content/virtual_harvester.py +1 -1
  7. shepherd_core/data_models/content/virtual_source.py +18 -13
  8. shepherd_core/data_models/experiment/experiment.py +10 -10
  9. shepherd_core/data_models/experiment/observer_features.py +5 -6
  10. shepherd_core/data_models/task/observer_tasks.py +1 -1
  11. shepherd_core/data_models/task/testbed_tasks.py +7 -3
  12. shepherd_core/data_models/testbed/cape.py +1 -1
  13. shepherd_core/data_models/testbed/gpio.py +1 -1
  14. shepherd_core/data_models/testbed/mcu.py +1 -1
  15. shepherd_core/data_models/testbed/observer.py +1 -1
  16. shepherd_core/data_models/testbed/target.py +1 -1
  17. shepherd_core/data_models/testbed/testbed.py +1 -1
  18. shepherd_core/decoder_waveform/uart.py +1 -0
  19. shepherd_core/fw_tools/validation.py +1 -2
  20. shepherd_core/inventory/__init__.py +51 -1
  21. shepherd_core/inventory/system.py +8 -0
  22. shepherd_core/reader.py +19 -16
  23. shepherd_core/testbed_client/cache_path.py +15 -0
  24. shepherd_core/testbed_client/client.py +2 -3
  25. shepherd_core/testbed_client/fixtures.py +4 -1
  26. shepherd_core/testbed_client/user_model.py +6 -4
  27. shepherd_core/vsource/virtual_converter_model.py +1 -1
  28. shepherd_core/vsource/virtual_harvester_model.py +1 -0
  29. shepherd_core/vsource/virtual_source_model.py +1 -0
  30. shepherd_core/writer.py +5 -2
  31. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.1.dist-info}/METADATA +49 -34
  32. shepherd_core-2024.4.1.dist-info/RECORD +64 -0
  33. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.1.dist-info}/WHEEL +1 -1
  34. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.1.dist-info}/top_level.txt +0 -1
  35. shepherd_core/data_models/content/_external_fixtures.yaml +0 -394
  36. shepherd_core/data_models/content/energy_environment_fixture.yaml +0 -50
  37. shepherd_core/data_models/content/virtual_harvester_fixture.yaml +0 -159
  38. shepherd_core/data_models/content/virtual_source_fixture.yaml +0 -229
  39. shepherd_core/data_models/testbed/cape_fixture.yaml +0 -94
  40. shepherd_core/data_models/testbed/gpio_fixture.yaml +0 -166
  41. shepherd_core/data_models/testbed/mcu_fixture.yaml +0 -19
  42. shepherd_core/data_models/testbed/observer_fixture.yaml +0 -220
  43. shepherd_core/data_models/testbed/target_fixture.yaml +0 -137
  44. shepherd_core/data_models/testbed/testbed_fixture.yaml +0 -25
  45. shepherd_core-2023.12.1.dist-info/RECORD +0 -117
  46. tests/__init__.py +0 -0
  47. tests/conftest.py +0 -64
  48. tests/data_models/__init__.py +0 -0
  49. tests/data_models/conftest.py +0 -14
  50. tests/data_models/example_cal_data.yaml +0 -31
  51. tests/data_models/example_cal_data_faulty.yaml +0 -29
  52. tests/data_models/example_cal_meas.yaml +0 -178
  53. tests/data_models/example_cal_meas_faulty1.yaml +0 -142
  54. tests/data_models/example_cal_meas_faulty2.yaml +0 -136
  55. tests/data_models/example_config_emulator.yaml +0 -41
  56. tests/data_models/example_config_experiment.yaml +0 -16
  57. tests/data_models/example_config_experiment_alternative.yaml +0 -14
  58. tests/data_models/example_config_harvester.yaml +0 -15
  59. tests/data_models/example_config_testbed.yaml +0 -26
  60. tests/data_models/example_config_virtsource.yaml +0 -78
  61. tests/data_models/test_base_models.py +0 -205
  62. tests/data_models/test_content_fixtures.py +0 -41
  63. tests/data_models/test_content_models.py +0 -282
  64. tests/data_models/test_examples.py +0 -48
  65. tests/data_models/test_experiment_models.py +0 -277
  66. tests/data_models/test_task_generation.py +0 -52
  67. tests/data_models/test_task_models.py +0 -131
  68. tests/data_models/test_testbed_fixtures.py +0 -47
  69. tests/data_models/test_testbed_models.py +0 -187
  70. tests/decoder_waveform/__init__.py +0 -0
  71. tests/decoder_waveform/test_decoder.py +0 -34
  72. tests/fw_tools/__init__.py +0 -0
  73. tests/fw_tools/conftest.py +0 -5
  74. tests/fw_tools/test_converter.py +0 -76
  75. tests/fw_tools/test_patcher.py +0 -66
  76. tests/fw_tools/test_validation.py +0 -56
  77. tests/inventory/__init__.py +0 -0
  78. tests/inventory/test_inventory.py +0 -20
  79. tests/test_cal_hw.py +0 -34
  80. tests/test_examples.py +0 -40
  81. tests/test_logger.py +0 -15
  82. tests/test_reader.py +0 -283
  83. tests/test_writer.py +0 -169
  84. tests/testbed_client/__init__.py +0 -0
  85. tests/vsource/__init__.py +0 -0
  86. tests/vsource/conftest.py +0 -49
  87. tests/vsource/test_converter.py +0 -161
  88. tests/vsource/test_harvester.py +0 -73
  89. tests/vsource/test_z.py +0 -5
  90. {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
File without changes
@@ -1,5 +0,0 @@
1
- from pathlib import Path
2
-
3
- names_elf = ["build_msp.elf", "build_nrf.elf"]
4
-
5
- files_elf = [Path(__file__).resolve().with_name(name) for name in names_elf]
@@ -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
@@ -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"
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() == {}