shepherd-core 2023.12.1__py3-none-any.whl → 2024.4.2__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 (116) hide show
  1. shepherd_core/__init__.py +5 -4
  2. shepherd_core/calibration_hw_def.py +9 -1
  3. shepherd_core/commons.py +2 -0
  4. shepherd_core/data_models/__init__.py +11 -0
  5. shepherd_core/data_models/base/__init__.py +4 -1
  6. shepherd_core/data_models/base/cal_measurement.py +18 -6
  7. shepherd_core/data_models/base/calibration.py +41 -16
  8. shepherd_core/data_models/base/content.py +20 -5
  9. shepherd_core/data_models/base/shepherd.py +23 -12
  10. shepherd_core/data_models/base/timezone.py +5 -0
  11. shepherd_core/data_models/base/wrapper.py +3 -3
  12. shepherd_core/data_models/content/__init__.py +5 -4
  13. shepherd_core/data_models/content/_external_fixtures.yaml +32 -16
  14. shepherd_core/data_models/content/energy_environment.py +7 -5
  15. shepherd_core/data_models/content/energy_environment_fixture.yaml +3 -0
  16. shepherd_core/data_models/content/firmware.py +12 -5
  17. shepherd_core/data_models/content/firmware_datatype.py +7 -0
  18. shepherd_core/data_models/content/virtual_harvester.py +25 -20
  19. shepherd_core/data_models/content/virtual_harvester_fixture.yaml +1 -0
  20. shepherd_core/data_models/content/virtual_source.py +40 -23
  21. shepherd_core/data_models/content/virtual_source_fixture.yaml +1 -0
  22. shepherd_core/data_models/experiment/__init__.py +5 -4
  23. shepherd_core/data_models/experiment/experiment.py +16 -15
  24. shepherd_core/data_models/experiment/observer_features.py +18 -12
  25. shepherd_core/data_models/experiment/target_config.py +11 -7
  26. shepherd_core/data_models/readme.md +88 -0
  27. shepherd_core/data_models/task/__init__.py +10 -3
  28. shepherd_core/data_models/task/emulation.py +9 -6
  29. shepherd_core/data_models/task/firmware_mod.py +4 -2
  30. shepherd_core/data_models/task/harvest.py +5 -4
  31. shepherd_core/data_models/task/observer_tasks.py +4 -2
  32. shepherd_core/data_models/task/programming.py +3 -1
  33. shepherd_core/data_models/task/testbed_tasks.py +10 -4
  34. shepherd_core/data_models/testbed/__init__.py +5 -2
  35. shepherd_core/data_models/testbed/cape.py +8 -6
  36. shepherd_core/data_models/testbed/gpio.py +11 -9
  37. shepherd_core/data_models/testbed/mcu.py +10 -10
  38. shepherd_core/data_models/testbed/observer.py +10 -5
  39. shepherd_core/data_models/testbed/observer_fixture.yaml +23 -22
  40. shepherd_core/data_models/testbed/target.py +5 -3
  41. shepherd_core/data_models/testbed/target_fixture.yaml +11 -11
  42. shepherd_core/data_models/testbed/testbed.py +6 -3
  43. shepherd_core/decoder_waveform/__init__.py +2 -0
  44. shepherd_core/decoder_waveform/uart.py +44 -25
  45. shepherd_core/fw_tools/__init__.py +2 -0
  46. shepherd_core/fw_tools/converter.py +20 -9
  47. shepherd_core/fw_tools/converter_elf.py +3 -0
  48. shepherd_core/fw_tools/patcher.py +16 -4
  49. shepherd_core/fw_tools/validation.py +25 -5
  50. shepherd_core/inventory/__init__.py +66 -6
  51. shepherd_core/inventory/python.py +4 -0
  52. shepherd_core/inventory/system.py +13 -1
  53. shepherd_core/inventory/target.py +4 -0
  54. shepherd_core/logger.py +5 -0
  55. shepherd_core/reader.py +44 -26
  56. shepherd_core/testbed_client/__init__.py +2 -0
  57. shepherd_core/testbed_client/cache_path.py +17 -0
  58. shepherd_core/testbed_client/client.py +14 -8
  59. shepherd_core/testbed_client/fixtures.py +30 -11
  60. shepherd_core/testbed_client/user_model.py +13 -6
  61. shepherd_core/vsource/__init__.py +2 -0
  62. shepherd_core/vsource/virtual_converter_model.py +11 -4
  63. shepherd_core/vsource/virtual_harvester_model.py +8 -1
  64. shepherd_core/vsource/virtual_source_model.py +10 -5
  65. shepherd_core/writer.py +28 -20
  66. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/METADATA +50 -34
  67. shepherd_core-2024.4.2.dist-info/RECORD +75 -0
  68. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/WHEEL +1 -1
  69. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/top_level.txt +0 -1
  70. shepherd_core-2023.12.1.dist-info/RECORD +0 -117
  71. tests/__init__.py +0 -0
  72. tests/conftest.py +0 -64
  73. tests/data_models/__init__.py +0 -0
  74. tests/data_models/conftest.py +0 -14
  75. tests/data_models/example_cal_data.yaml +0 -31
  76. tests/data_models/example_cal_data_faulty.yaml +0 -29
  77. tests/data_models/example_cal_meas.yaml +0 -178
  78. tests/data_models/example_cal_meas_faulty1.yaml +0 -142
  79. tests/data_models/example_cal_meas_faulty2.yaml +0 -136
  80. tests/data_models/example_config_emulator.yaml +0 -41
  81. tests/data_models/example_config_experiment.yaml +0 -16
  82. tests/data_models/example_config_experiment_alternative.yaml +0 -14
  83. tests/data_models/example_config_harvester.yaml +0 -15
  84. tests/data_models/example_config_testbed.yaml +0 -26
  85. tests/data_models/example_config_virtsource.yaml +0 -78
  86. tests/data_models/test_base_models.py +0 -205
  87. tests/data_models/test_content_fixtures.py +0 -41
  88. tests/data_models/test_content_models.py +0 -282
  89. tests/data_models/test_examples.py +0 -48
  90. tests/data_models/test_experiment_models.py +0 -277
  91. tests/data_models/test_task_generation.py +0 -52
  92. tests/data_models/test_task_models.py +0 -131
  93. tests/data_models/test_testbed_fixtures.py +0 -47
  94. tests/data_models/test_testbed_models.py +0 -187
  95. tests/decoder_waveform/__init__.py +0 -0
  96. tests/decoder_waveform/test_decoder.py +0 -34
  97. tests/fw_tools/__init__.py +0 -0
  98. tests/fw_tools/conftest.py +0 -5
  99. tests/fw_tools/test_converter.py +0 -76
  100. tests/fw_tools/test_patcher.py +0 -66
  101. tests/fw_tools/test_validation.py +0 -56
  102. tests/inventory/__init__.py +0 -0
  103. tests/inventory/test_inventory.py +0 -20
  104. tests/test_cal_hw.py +0 -34
  105. tests/test_examples.py +0 -40
  106. tests/test_logger.py +0 -15
  107. tests/test_reader.py +0 -283
  108. tests/test_writer.py +0 -169
  109. tests/testbed_client/__init__.py +0 -0
  110. tests/vsource/__init__.py +0 -0
  111. tests/vsource/conftest.py +0 -49
  112. tests/vsource/test_converter.py +0 -161
  113. tests/vsource/test_harvester.py +0 -73
  114. tests/vsource/test_z.py +0 -5
  115. /shepherd_core/data_models/{doc_virtual_source.py → virtual_source_doc.txt} +0 -0
  116. {shepherd_core-2023.12.1.dist-info → shepherd_core-2024.4.2.dist-info}/zip-safe +0 -0
@@ -1,41 +0,0 @@
1
- from shepherd_core.data_models.content.energy_environment import EnergyEnvironment
2
- from shepherd_core.data_models.content.firmware import Firmware
3
- from shepherd_core.data_models.content.virtual_harvester import HarvesterPRUConfig
4
- from shepherd_core.data_models.content.virtual_harvester import VirtualHarvesterConfig
5
- from shepherd_core.data_models.content.virtual_source import ConverterPRUConfig
6
- from shepherd_core.data_models.content.virtual_source import VirtualSourceConfig
7
- from shepherd_core.testbed_client.fixtures import Fixtures
8
-
9
-
10
- def test_testbed_fixture_energy_environment() -> None:
11
- for fix in Fixtures()["EnergyEnvironment"]:
12
- EnergyEnvironment(name=fix["name"])
13
- EnergyEnvironment(id=fix["id"])
14
-
15
-
16
- def test_testbed_fixture_firmware() -> None:
17
- for fix in Fixtures()["Firmware"]:
18
- _id = fix["id"]
19
- if _id in {1001, 1002}:
20
- continue
21
- Firmware(name=fix["name"])
22
- Firmware(id=fix["id"])
23
-
24
-
25
- def test_experiment_fixture_vsrc() -> None:
26
- for fix in Fixtures()["VirtualSourceConfig"]:
27
- vsrc = VirtualSourceConfig(name=fix["name"])
28
- VirtualSourceConfig(id=fix["id"])
29
- ConverterPRUConfig.from_vsrc(vsrc, log_intermediate_node=False)
30
- ConverterPRUConfig.from_vsrc(vsrc, log_intermediate_node=True)
31
-
32
-
33
- def test_experiment_fixture_vhrv() -> None:
34
- for fix in Fixtures()["VirtualHarvesterConfig"]:
35
- if fix["name"] == "neutral":
36
- continue
37
- vhrv = VirtualHarvesterConfig(name=fix["name"])
38
- VirtualHarvesterConfig(id=fix["id"])
39
- HarvesterPRUConfig.from_vhrv(vhrv, for_emu=False)
40
- if int(fix["id"]) >= 1030:
41
- HarvesterPRUConfig.from_vhrv(vhrv, for_emu=True)
@@ -1,282 +0,0 @@
1
- from pathlib import Path
2
-
3
- import pytest
4
- from pydantic import ValidationError
5
-
6
- from shepherd_core import fw_tools
7
- from shepherd_core.data_models.content import EnergyDType
8
- from shepherd_core.data_models.content import EnergyEnvironment
9
- from shepherd_core.data_models.content import Firmware
10
- from shepherd_core.data_models.content import FirmwareDType
11
- from shepherd_core.data_models.content import VirtualHarvesterConfig
12
- from shepherd_core.data_models.content import VirtualSourceConfig
13
- from shepherd_core.data_models.content.virtual_source import ConverterPRUConfig
14
- from shepherd_core.data_models.testbed import MCU
15
-
16
- from .conftest import files_elf
17
-
18
-
19
- def test_content_model_ee_min1() -> None:
20
- EnergyEnvironment(
21
- id=9999,
22
- name="some",
23
- data_path="./file",
24
- data_type="isc_voc",
25
- duration=1,
26
- energy_Ws=0.1,
27
- owner="jane",
28
- group="wayne",
29
- )
30
-
31
-
32
- def test_content_model_ee_min2() -> None:
33
- EnergyEnvironment(
34
- id="98765",
35
- name="some",
36
- data_path="./file",
37
- data_type=EnergyDType.ivcurve,
38
- duration=999,
39
- energy_Ws=3.1,
40
- owner="jane",
41
- group="wayne",
42
- )
43
-
44
-
45
- def test_content_model_fw_faulty() -> None:
46
- with pytest.raises(ValueError):
47
- Firmware(
48
- id=9999,
49
- name="dome",
50
- mcu=MCU(name="nRF52"),
51
- data="xyz",
52
- data_type=FirmwareDType.base64_hex,
53
- owner="Obelix",
54
- group="Gaul",
55
- )
56
-
57
-
58
- @pytest.mark.elf
59
- @pytest.mark.converter
60
- @pytest.mark.parametrize("path_elf", files_elf)
61
- def test_content_model_fw_min(path_elf: Path, tmp_path: Path) -> None:
62
- path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
63
- path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
64
- Firmware(
65
- id=9999,
66
- name="dome",
67
- mcu=MCU(name="nRF52"),
68
- data=fw_tools.file_to_base64(path_hex),
69
- data_type=FirmwareDType.base64_hex,
70
- owner="Obelix",
71
- group="Gaul",
72
- )
73
-
74
-
75
- @pytest.mark.elf
76
- @pytest.mark.converter
77
- @pytest.mark.parametrize("path_elf", files_elf)
78
- def test_content_model_fw_from_elf(path_elf: Path) -> None:
79
- Firmware.from_firmware(
80
- file=path_elf,
81
- name="dome",
82
- owner="Obelix",
83
- group="Gaul",
84
- )
85
-
86
-
87
- @pytest.mark.elf
88
- @pytest.mark.converter
89
- @pytest.mark.parametrize("path_elf", files_elf)
90
- def test_content_model_fw_from_hex(path_elf: Path, tmp_path: Path) -> None:
91
- path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
92
- path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
93
- Firmware.from_firmware(
94
- file=path_hex,
95
- name="dome",
96
- owner="Obelix",
97
- group="Gaul",
98
- )
99
-
100
-
101
- def test_content_model_fw_from_hex_failing(tmp_path: Path) -> None:
102
- path_hex = tmp_path / "some.hex"
103
- with path_hex.open("w") as fd:
104
- fd.write("something")
105
- with pytest.raises(ValueError):
106
- Firmware.from_firmware(
107
- file=path_hex,
108
- name="dome",
109
- owner="Obelix",
110
- group="Gaul",
111
- )
112
-
113
-
114
- @pytest.mark.elf
115
- @pytest.mark.converter
116
- @pytest.mark.parametrize("path_elf", files_elf)
117
- def test_content_model_fw_extract_elf_to_dir(path_elf: Path, tmp_path: Path) -> None:
118
- fw = Firmware.from_firmware(
119
- file=path_elf,
120
- name="dome",
121
- owner="Obelix",
122
- group="Gaul",
123
- )
124
- file = fw.extract_firmware(tmp_path)
125
- assert file.exists()
126
- assert file.is_file()
127
-
128
-
129
- @pytest.mark.elf
130
- @pytest.mark.converter
131
- @pytest.mark.parametrize("path_elf", files_elf)
132
- def test_content_model_fw_extract_hex_to_dir(path_elf: Path, tmp_path: Path) -> None:
133
- path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
134
- path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
135
- fw = Firmware.from_firmware(
136
- file=path_hex,
137
- name="dome",
138
- owner="Obelix",
139
- group="Gaul",
140
- )
141
- file = fw.extract_firmware(tmp_path)
142
- assert file.exists()
143
- assert file.is_file()
144
-
145
-
146
- @pytest.mark.parametrize("path_elf", files_elf)
147
- def test_content_model_fw_extract_path_elf_to_dir(path_elf: Path, tmp_path: Path) -> None:
148
- assert path_elf.exists()
149
- fw = Firmware(
150
- data=path_elf,
151
- data_type=FirmwareDType.path_elf,
152
- mcu={"name": "MSP430FR"},
153
- name="dome",
154
- owner="Obelix",
155
- group="Gaul",
156
- )
157
- file = fw.extract_firmware(tmp_path)
158
- assert file.exists()
159
- assert file.is_file()
160
-
161
-
162
- @pytest.mark.elf
163
- @pytest.mark.converter
164
- @pytest.mark.parametrize("path_elf", files_elf)
165
- def test_content_model_fw_extract_path_hex_to_dir(path_elf: Path, tmp_path: Path) -> None:
166
- path_hex = (tmp_path / (path_elf.stem + ".hex")).resolve()
167
- path_hex = fw_tools.elf_to_hex(path_elf, path_hex)
168
- assert path_hex.exists()
169
- fw = Firmware(
170
- data=path_hex,
171
- data_type=FirmwareDType.path_hex,
172
- mcu={"name": "MSP430FR"},
173
- name="dome",
174
- owner="Obelix",
175
- group="Gaul",
176
- )
177
- file = fw.extract_firmware(tmp_path)
178
- assert file.exists()
179
- assert file.is_file()
180
-
181
-
182
- def test_content_model_hrv_min() -> None:
183
- hrv = VirtualHarvesterConfig(
184
- id=9999,
185
- name="whatever",
186
- owner="jane",
187
- group="wayne",
188
- algorithm="mppt_opt",
189
- )
190
- assert hrv.get_datatype() == "ivsample"
191
-
192
-
193
- def test_content_model_hrv_neutral() -> None:
194
- with pytest.raises(ValueError):
195
- _ = VirtualHarvesterConfig(name="neutral")
196
-
197
-
198
- @pytest.mark.parametrize("name", ["iv110", "cv24", "mppt_voc", "mppt_po"])
199
- def test_content_model_hrv_by_name(name: str) -> None:
200
- _ = VirtualHarvesterConfig(name=name)
201
-
202
-
203
- @pytest.mark.parametrize("uid", [1013, 1020, 1032, 1044, 1045, 1046])
204
- def test_content_model_hrv_by_id(uid: int) -> None:
205
- _ = VirtualHarvesterConfig(id=uid)
206
-
207
-
208
- def test_content_model_hrv_steps() -> None:
209
- hrv = VirtualHarvesterConfig(
210
- name="ivcurves", voltage_min_mV=1000, voltage_max_mV=4000, samples_n=11
211
- )
212
- assert hrv.voltage_step_mV == 300
213
-
214
-
215
- def test_content_model_hrv_faulty_voltage0() -> None:
216
- with pytest.raises(ValidationError):
217
- _ = VirtualHarvesterConfig(name="iv110", voltage_max_mV=5001)
218
- with pytest.raises(ValidationError):
219
- _ = VirtualHarvesterConfig(name="iv110", voltage_min_mV=-1)
220
-
221
-
222
- def test_content_model_hrv_faulty_voltage1() -> None:
223
- with pytest.raises(ValueError):
224
- _ = VirtualHarvesterConfig(name="iv110", voltage_min_mV=4001, voltage_max_mV=4000)
225
-
226
-
227
- def test_content_model_hrv_faulty_voltage2() -> None:
228
- with pytest.raises(ValueError):
229
- _ = VirtualHarvesterConfig(name="iv110", voltage_mV=4001, voltage_max_mV=4000)
230
-
231
-
232
- def test_content_model_hrv_faulty_voltage3() -> None:
233
- with pytest.raises(ValueError):
234
- _ = VirtualHarvesterConfig(name="iv110", voltage_mV=4000, voltage_min_mV=4001)
235
-
236
-
237
- @pytest.mark.parametrize("name", ["ivcurves", "iv1000", "isc_voc"])
238
- def test_content_model_hrv_faulty_emu(name: str) -> None:
239
- hrv = VirtualHarvesterConfig(name=name)
240
- with pytest.raises(ValueError):
241
- _ = VirtualSourceConfig(name="dio_cap", harvester=hrv)
242
-
243
-
244
- def test_content_model_src_min() -> None:
245
- VirtualSourceConfig(
246
- id=9999,
247
- name="new_src",
248
- owner="jane",
249
- group="wayne",
250
- )
251
-
252
-
253
- def test_content_model_src_force_warning() -> None:
254
- src = VirtualSourceConfig(
255
- name="BQ25570",
256
- C_output_uF=200,
257
- C_intermediate_uF=100,
258
- )
259
- ConverterPRUConfig.from_vsrc(src)
260
- # -> triggers warning currently
261
-
262
-
263
- def test_content_model_src_force_other_hysteresis1() -> None:
264
- src = VirtualSourceConfig(
265
- name="BQ25570",
266
- V_intermediate_enable_threshold_mV=4000,
267
- V_intermediate_disable_threshold_mV=3999,
268
- V_output_mV=2000,
269
- V_buck_drop_mV=100,
270
- )
271
- ConverterPRUConfig.from_vsrc(src)
272
-
273
-
274
- def test_content_model_src_force_other_hysteresis2() -> None:
275
- src = VirtualSourceConfig(
276
- name="BQ25570",
277
- V_intermediate_enable_threshold_mV=1000,
278
- V_intermediate_disable_threshold_mV=999,
279
- V_output_mV=2000,
280
- V_buck_drop_mV=100,
281
- )
282
- ConverterPRUConfig.from_vsrc(src)
@@ -1,48 +0,0 @@
1
- from pathlib import Path
2
-
3
- from shepherd_core.data_models.content import VirtualSourceConfig
4
- from shepherd_core.data_models.experiment import Experiment
5
- from shepherd_core.data_models.task import EmulationTask
6
- from shepherd_core.data_models.task import HarvestTask
7
- from shepherd_core.data_models.testbed.testbed import Testbed as TasteBad
8
-
9
- from .conftest import load_yaml
10
-
11
- # ⤷ TasteBad avoids pytest-warning
12
-
13
-
14
- def test_example_emu() -> None:
15
- data_dict = load_yaml("example_config_emulator.yaml")
16
- assert data_dict["mode"] == "emulator"
17
- emu = EmulationTask(**data_dict["parameters"])
18
- print(emu)
19
-
20
-
21
- def test_example_hrv() -> None:
22
- data_dict = load_yaml("example_config_harvester.yaml")
23
- assert data_dict["mode"] == "harvester"
24
- emu = HarvestTask(**data_dict["parameters"])
25
- print(emu)
26
-
27
-
28
- def test_example_exp_recommended() -> None:
29
- # new way
30
- path = Path(__file__).with_name("example_config_experiment.yaml")
31
- Experiment.from_file(path)
32
-
33
-
34
- def test_example_exp() -> None:
35
- # non-optimal / old way
36
- data_dict = load_yaml("example_config_experiment_alternative.yaml")
37
- Experiment(**data_dict)
38
-
39
-
40
- def test_example_tb() -> None:
41
- data_dict = load_yaml("example_config_testbed.yaml")
42
- print(data_dict)
43
- TasteBad(**data_dict)
44
-
45
-
46
- def test_example_vsrc() -> None:
47
- data_dict = load_yaml("example_config_virtsource.yaml")
48
- VirtualSourceConfig(**data_dict["VirtualSource"])
@@ -1,277 +0,0 @@
1
- from datetime import timedelta
2
-
3
- import pytest
4
- from pydantic import ValidationError
5
-
6
- from shepherd_core import local_now
7
- from shepherd_core.data_models import VirtualHarvesterConfig
8
- from shepherd_core.data_models import VirtualSourceConfig
9
- from shepherd_core.data_models.content import EnergyEnvironment
10
- from shepherd_core.data_models.content import Firmware
11
- from shepherd_core.data_models.experiment import Experiment
12
- from shepherd_core.data_models.experiment import GpioActuation
13
- from shepherd_core.data_models.experiment import GpioEvent
14
- from shepherd_core.data_models.experiment import GpioLevel
15
- from shepherd_core.data_models.experiment import GpioTracing
16
- from shepherd_core.data_models.experiment import PowerTracing
17
- from shepherd_core.data_models.experiment import SystemLogging
18
- from shepherd_core.data_models.experiment import TargetConfig
19
- from shepherd_core.data_models.testbed import GPIO
20
- from shepherd_core.data_models.testbed import Target
21
-
22
- from .conftest import load_yaml
23
-
24
-
25
- def test_experiment_model_exp_min() -> None:
26
- Experiment(
27
- name="mex per",
28
- target_configs=[
29
- TargetConfig(
30
- target_IDs=[1],
31
- energy_env=EnergyEnvironment(name="SolarSunny"),
32
- firmware1=Firmware(name="nrf52_demo_rf"),
33
- )
34
- ],
35
- )
36
-
37
-
38
- def test_experiment_model_exp_yaml_load() -> None:
39
- exp1_data = load_yaml("example_config_experiment_alternative.yaml")
40
- Experiment(**exp1_data)
41
-
42
-
43
- def test_experiment_model_exp_yaml_comparison() -> None:
44
- exp1_data = load_yaml("example_config_experiment_alternative.yaml")
45
- exp1 = Experiment(**exp1_data)
46
-
47
- target_cfgs = TargetConfig(
48
- target_IDs=list(range(1, 5)),
49
- custom_IDs=list(range(4)),
50
- energy_env={"name": "SolarSunny"},
51
- virtual_source={"name": "diode+capacitor"},
52
- firmware1={"name": "nrf52_demo_rf"},
53
- )
54
- exp2 = Experiment(
55
- id=4567,
56
- name="meaningful Test-Name",
57
- created="2023-11-11 11:11:11",
58
- time_start="2023-12-12 12:12:12",
59
- target_configs=[target_cfgs],
60
- )
61
- assert exp1.get_hash() == exp2.get_hash()
62
-
63
-
64
- def test_experiment_model_exp_collision_target_id() -> None:
65
- hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
66
- target_cfgs = [
67
- TargetConfig(
68
- target_IDs=[1, 2, 3], # <- collision
69
- custom_IDs=[0, 1, 2, 3],
70
- energy_env={"name": "SolarSunny"},
71
- virtual_source={"name": "diode+capacitor"},
72
- firmware1={"name": "nrf52_demo_rf"},
73
- ),
74
- TargetConfig(
75
- target_IDs=list(range(1, 5)), # <- collision
76
- custom_IDs=list(range(7, 18)), # note: longer list is OK
77
- energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
78
- virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
79
- firmware1=Firmware(name="nrf52_demo_rf"),
80
- firmware2=Firmware(name="msp430_deep_sleep"),
81
- ),
82
- ]
83
- with pytest.raises(ValueError):
84
- _ = Experiment(
85
- id="4567",
86
- name="meaningful Test-Name",
87
- time_start=local_now() + timedelta(minutes=30),
88
- target_configs=target_cfgs,
89
- )
90
-
91
-
92
- def test_experiment_model_exp_collision_custom_id() -> None:
93
- hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
94
- target_cfgs = [
95
- TargetConfig(
96
- target_IDs=[1, 2, 3],
97
- custom_IDs=[0, 1, 7], # <- collision
98
- energy_env={"name": "SolarSunny"},
99
- virtual_source={"name": "diode+capacitor"},
100
- firmware1={"name": "nrf52_demo_rf"},
101
- ),
102
- TargetConfig(
103
- target_IDs=list(range(1, 5)),
104
- custom_IDs=list(range(7, 18)), # <- collision
105
- energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
106
- virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
107
- firmware1=Firmware(name="nrf52_demo_rf"),
108
- firmware2=Firmware(name="msp430_deep_sleep"),
109
- ),
110
- ]
111
- with pytest.raises(ValueError):
112
- _ = Experiment(
113
- id="4567",
114
- name="meaningful Test-Name",
115
- time_start=local_now() + timedelta(minutes=30),
116
- target_configs=target_cfgs,
117
- )
118
-
119
-
120
- def test_experiment_model_exp_collision_observer() -> None:
121
- hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
122
- target_cfgs = [
123
- TargetConfig(
124
- target_IDs=[1, 1001], # <- both on same observer
125
- custom_IDs=list(range(7, 18)),
126
- energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
127
- virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
128
- firmware1=Firmware(name="nrf52_demo_rf"),
129
- firmware2=Firmware(name="msp430_deep_sleep"),
130
- ),
131
- ]
132
- with pytest.raises(ValueError):
133
- _ = Experiment(
134
- id="4567",
135
- name="meaningful Test-Name",
136
- time_start=local_now() + timedelta(minutes=30),
137
- target_configs=target_cfgs,
138
- )
139
-
140
-
141
- def test_experiment_model_exp_missing_target() -> None:
142
- hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
143
- with pytest.raises(ValidationError):
144
- # should raise ValueError in Experiment
145
- # buts gets already caught in target_config
146
- _ = [
147
- TargetConfig(
148
- target_IDs=[1234567], # <- not existent
149
- custom_IDs=list(range(7, 18)),
150
- energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
151
- virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
152
- firmware1=Firmware(name="nrf52_demo_rf"),
153
- firmware2=Firmware(name="msp430_deep_sleep"),
154
- ),
155
- ]
156
- # experiment (like above) removed
157
-
158
-
159
- def test_experiment_model_pwrtracing_min() -> None:
160
- PowerTracing()
161
-
162
-
163
- def test_experiment_model_pwrtracing_fault_post() -> None:
164
- with pytest.raises(ValueError):
165
- PowerTracing(calculate_power=True)
166
-
167
-
168
- def test_experiment_model_pwrtracing_fault_discard_all() -> None:
169
- with pytest.raises(ValueError):
170
- PowerTracing(calculate_power=False, discard_current=True, discard_voltage=True)
171
-
172
-
173
- def test_experiment_model_gpiotracing_min() -> None:
174
- GpioTracing()
175
-
176
-
177
- def test_experiment_model_gpiotracing_fault_mask() -> None:
178
- with pytest.raises(ValueError):
179
- GpioTracing(mask=0)
180
-
181
-
182
- def test_experiment_model_gpioevent_min() -> None:
183
- gevt = GpioEvent(
184
- delay=300,
185
- gpio=GPIO(name="GPIO3"),
186
- level=GpioLevel.high,
187
- )
188
- gevt.get_events()
189
-
190
-
191
- def test_experiment_model_gpioevent_fault_readonly() -> None:
192
- with pytest.raises(ValueError):
193
- GpioEvent(
194
- delay=300,
195
- gpio=GPIO(name="BAT_OK"),
196
- level=GpioLevel.high,
197
- )
198
-
199
-
200
- def test_experiment_model_gpioactuation_min() -> None:
201
- gact = GpioActuation(
202
- events=[
203
- GpioEvent(
204
- delay=300,
205
- gpio=GPIO(name="GPIO2"),
206
- level=GpioLevel.high,
207
- )
208
- ]
209
- )
210
- gact.get_gpios()
211
-
212
-
213
- def test_experiment_model_syslogging_min() -> None:
214
- SystemLogging()
215
-
216
-
217
- def test_experiment_model_tgt_cfg_min1() -> None:
218
- cfg = TargetConfig(
219
- target_IDs=[1],
220
- energy_env=EnergyEnvironment(name="SolarSunny"),
221
- firmware1=Firmware(name="nrf52_demo_rf"),
222
- )
223
- for _id in cfg.target_IDs:
224
- Target(id=_id)
225
- assert cfg.get_custom_id(1) is None
226
-
227
-
228
- def test_experiment_model_tgt_cfg_min2() -> None:
229
- cfg = TargetConfig(
230
- target_IDs=[1, 2],
231
- custom_IDs=[7, 9],
232
- energy_env=EnergyEnvironment(name="SolarSunny"),
233
- firmware1=Firmware(name="nrf52_demo_rf"),
234
- )
235
- for _id in cfg.target_IDs:
236
- Target(id=_id)
237
- assert cfg.get_custom_id(1) == 7
238
- assert cfg.get_custom_id(2) == 9
239
- assert cfg.get_custom_id(3) is None
240
-
241
-
242
- def test_experiment_model_tgt_cfg_fault_valid_ee() -> None:
243
- with pytest.raises(ValueError):
244
- _ = TargetConfig(
245
- target_IDs=[1],
246
- energy_env=EnergyEnvironment(name="nuclear"),
247
- firmware1=Firmware(name="nrf52_demo_rf"),
248
- )
249
-
250
-
251
- def test_experiment_model_tgt_cfg_fault_firmware1() -> None:
252
- with pytest.raises(ValueError):
253
- _ = TargetConfig(
254
- target_IDs=[1], # is nRF
255
- energy_env=EnergyEnvironment(name="SolarSunny"),
256
- firmware1=Firmware(name="msp430_spi_fram"),
257
- )
258
-
259
-
260
- def test_experiment_model_tgt_cfg_fault_firmware2() -> None:
261
- with pytest.raises(ValueError):
262
- _ = TargetConfig(
263
- target_IDs=[1], # is nRF
264
- energy_env=EnergyEnvironment(name="SolarSunny"),
265
- firmware1=Firmware(name="nrf52_demo_rf"),
266
- firmware2=Firmware(name="nrf52_demo_rf"),
267
- )
268
-
269
-
270
- def test_experiment_model_tgt_cfg_fault_custom_ids() -> None:
271
- with pytest.raises(ValueError):
272
- _ = TargetConfig(
273
- target_IDs=[1, 2, 3],
274
- custom_IDs=[0, 1], # not enough
275
- energy_env=EnergyEnvironment(name="SolarSunny"),
276
- firmware1=Firmware(name="nrf52_demo_rf"),
277
- )
@@ -1,52 +0,0 @@
1
- from datetime import timedelta
2
- from pathlib import Path
3
-
4
- from shepherd_core import local_now
5
- from shepherd_core.data_models import EnergyEnvironment
6
- from shepherd_core.data_models import Experiment
7
- from shepherd_core.data_models import Firmware
8
- from shepherd_core.data_models import TargetConfig
9
- from shepherd_core.data_models import VirtualHarvesterConfig
10
- from shepherd_core.data_models import VirtualSourceConfig
11
- from shepherd_core.data_models.task import TestbedTasks as TasteBadTasks
12
-
13
-
14
- def test_task_generation_file(tmp_path: Path) -> None:
15
- path = Path(__file__).with_name("example_config_experiment.yaml")
16
- xp1 = Experiment.from_file(path)
17
- tb_tasks = TasteBadTasks.from_xp(xp1)
18
- tb_tasks.to_file(tmp_path / "tbt1.yaml")
19
-
20
-
21
- def test_task_generation_script(tmp_path: Path) -> None:
22
- hrv = VirtualHarvesterConfig(name="mppt_bq_thermoelectric")
23
-
24
- target_cfgs = [
25
- # first init similar to yaml
26
- TargetConfig(
27
- target_IDs=list(range(1, 4)),
28
- custom_IDs=list(range(3)),
29
- energy_env={"name": "SolarSunny"},
30
- virtual_source={"name": "diode+capacitor"},
31
- firmware1={"name": "nrf52_demo_rf"},
32
- ),
33
- # second Instance fully object-oriented
34
- TargetConfig(
35
- target_IDs=list(range(6, 9)),
36
- custom_IDs=list(range(7, 18)),
37
- energy_env=EnergyEnvironment(name="ThermoelectricWashingMachine"),
38
- virtual_source=VirtualSourceConfig(name="BQ25570-Schmitt", harvester=hrv),
39
- firmware1=Firmware(name="nrf52_demo_rf"),
40
- firmware2=Firmware(name="msp430_deep_sleep"),
41
- ),
42
- ]
43
-
44
- xperi = Experiment(
45
- id="4567",
46
- name="meaningful Test-Name",
47
- time_start=local_now() + timedelta(minutes=30),
48
- target_configs=target_cfgs,
49
- )
50
-
51
- tb_tasks = TasteBadTasks.from_xp(xperi)
52
- tb_tasks.to_file(tmp_path / "tbt2.yaml")