Split experiments from tests
The tests/ directory held 50 laboratory programs and no tests. They model channels, run hundreds of repetitions and write CSV, PNG and reports; calling that a test suite blocked introducing a real one, because any pytest run would have collected the labs and re-executed every experiment. - move all 50 lab programs to experiments/ with git mv, preserving history - rewrite the 38 cross-imports between labs from tests.labNNN to experiments.labNNN - leave tests/ empty for actual fast checks of protocol/ - point quick_gate and the hook at the new layout and add experiments/ to the syntax sweep - update the paths quoted in the Lab042 specification and the verifier agent definition This also defuses the import-time work finding without touching 41 files: the labs still create directories and write files on import, but nothing imports them now except the gate, which does so deliberately. Gate passes: syntax clean, protocol imports, 15 lab modules import, 2 functional suites run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ model: sonnet
|
|||||||
|
|
||||||
Ты проверяешь чужую работу в проекте SDR Rover Link: учебно-исследовательский
|
Ты проверяешь чужую работу в проекте SDR Rover Link: учебно-исследовательский
|
||||||
цифровой радиоканал для наземного ровера. Python, модули протокола в `protocol/`,
|
цифровой радиоканал для наземного ровера. Python, модули протокола в `protocol/`,
|
||||||
лабораторные работы в `tests/labNNN_*.py`, журнал проекта в `PROJECT_LOG.md`.
|
лабораторные работы в `experiments/labNNN_*.py`, журнал проекта в `PROJECT_LOG.md`.
|
||||||
|
|
||||||
Ты не автор кода. Твоя ценность именно в том, что ты не участвовал в его написании.
|
Ты не автор кода. Твоя ценность именно в том, что ты не участвовал в его написании.
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ model: sonnet
|
|||||||
Если пересказ расходится с первоисточником — это находка, и часто самая важная.
|
Если пересказ расходится с первоисточником — это находка, и часто самая важная.
|
||||||
|
|
||||||
2. **Запусти сам.** Быстрая проверка: `python tools/quick_gate.py`.
|
2. **Запусти сам.** Быстрая проверка: `python tools/quick_gate.py`.
|
||||||
Полный прогон лабы: `python tests/labNNN_имя.py`. Не верь чужому «тесты проходят».
|
Полный прогон лабы: `python experiments/labNNN_имя.py`. Не верь чужому «тесты проходят».
|
||||||
|
|
||||||
3. **Пересчитай ключевые числа независимым способом.** Это главный инструмент.
|
3. **Пересчитай ключевые числа независимым способом.** Это главный инструмент.
|
||||||
Симуляция BER проверяется аналитической формулой, счётчик отброшенных пакетов —
|
Симуляция BER проверяется аналитической формулой, счётчик отброшенных пакетов —
|
||||||
|
|||||||
@@ -22,16 +22,16 @@
|
|||||||
|
|
||||||
| Звено | Где взять |
|
| Звено | Где взять |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Разбиение JPEG на фрагменты и сборка обратно | `protocol/image_fragments.py`, примеры в `tests/lab007_image_fragmentation.py` |
|
| Разбиение JPEG на фрагменты и сборка обратно | `protocol/image_fragments.py`, примеры в `experiments/lab007_image_fragmentation.py` |
|
||||||
| Пакет с CRC32, кодирование и разбор | `protocol/packet.py` |
|
| Пакет с CRC32, кодирование и разбор | `protocol/packet.py` |
|
||||||
| Подбор размера и качества JPEG | `tests/lab010_image_optimization.py`, готовые профили в `data/processed/lab010` |
|
| Подбор размера и качества JPEG | `experiments/lab010_image_optimization.py`, готовые профили в `data/processed/lab010` |
|
||||||
| Формирование радиокадра с преамбулой и маркером | `build_radio_frame` в `tests/lab018_bpsk_radio_frame.py` |
|
| Формирование радиокадра с преамбулой и маркером | `build_radio_frame` в `experiments/lab018_bpsk_radio_frame.py` |
|
||||||
| Фильтр приподнятого косинуса | `root_raised_cosine_taps` там же |
|
| Фильтр приподнятого косинуса | `root_raised_cosine_taps` там же |
|
||||||
| Модуляция BPSK | `bpsk_modulate` там же |
|
| Модуляция BPSK | `bpsk_modulate` там же |
|
||||||
| Поиск кадра в потоке отсчётов | `find_radio_frame` в `tests/lab019_bpsk_receiver.py` |
|
| Поиск кадра в потоке отсчётов | `find_radio_frame` в `experiments/lab019_bpsk_receiver.py` |
|
||||||
| Оценка и коррекция ухода частоты | `estimate_carrier_parameters`, `correct_phase_and_frequency` там же |
|
| Оценка и коррекция ухода частоты | `estimate_carrier_parameters`, `correct_phase_and_frequency` там же |
|
||||||
| Демодуляция и разбор кадра | `bpsk_demodulate`, `decode_radio_frame` там же |
|
| Демодуляция и разбор кадра | `bpsk_demodulate`, `decode_radio_frame` там же |
|
||||||
| Работа с Pluto на приём | `tests/lab024a_pluto_rx_capture.py` |
|
| Работа с Pluto на приём | `experiments/lab024a_pluto_rx_capture.py` |
|
||||||
|
|
||||||
**Единственное, чего нет в проекте — передача.** Это и есть основной объём работы.
|
**Единственное, чего нет в проекте — передача.** Это и есть основной объём работы.
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
- Параметры тракта из раздела 5 не менять.
|
- Параметры тракта из раздела 5 не менять.
|
||||||
- Все константы вынести в начало файла с указанием источника, как это сделано в Lab041.
|
- Все константы вынести в начало файла с указанием источника, как это сделано в Lab041.
|
||||||
- Никаких вписанных руками результатов: каждое число в отчёте должно вычисляться из измерений текущего запуска. Это отдельно проверяется при приёмке.
|
- Никаких вписанных руками результатов: каждое число в отчёте должно вычисляться из измерений текущего запуска. Это отдельно проверяется при приёмке.
|
||||||
- Файл лабораторной: `tests/lab042_pluto_image_loopback.py`, запуск через `python -m tests.lab042_pluto_image_loopback` из корня проекта.
|
- Файл лабораторной: `experiments/lab042_pluto_image_loopback.py`, запуск через `python -m experiments.lab042_pluto_image_loopback` из корня проекта.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
0
experiments/__init__.py
Normal file
0
experiments/__init__.py
Normal file
@@ -27,7 +27,7 @@ from protocol.video_packet import (
|
|||||||
PacketCRCError,
|
PacketCRCError,
|
||||||
VideoPacketError,
|
VideoPacketError,
|
||||||
)
|
)
|
||||||
from tests.lab028_video_packetization import (
|
from experiments.lab028_video_packetization import (
|
||||||
EncodedComposite,
|
EncodedComposite,
|
||||||
SOURCE_VIDEO_PATH,
|
SOURCE_VIDEO_PATH,
|
||||||
VideoMetadata,
|
VideoMetadata,
|
||||||
@@ -32,14 +32,14 @@ from protocol.video_packet import (
|
|||||||
ObjectType,
|
ObjectType,
|
||||||
decode_packet,
|
decode_packet,
|
||||||
)
|
)
|
||||||
from tests.lab028_video_packetization import (
|
from experiments.lab028_video_packetization import (
|
||||||
COMPOSITE_FPS,
|
COMPOSITE_FPS,
|
||||||
EncodedComposite,
|
EncodedComposite,
|
||||||
SOURCE_VIDEO_PATH,
|
SOURCE_VIDEO_PATH,
|
||||||
VideoMetadata,
|
VideoMetadata,
|
||||||
load_video_profile,
|
load_video_profile,
|
||||||
)
|
)
|
||||||
from tests.lab029_packet_channel_simulation import (
|
from experiments.lab029_packet_channel_simulation import (
|
||||||
PAYLOAD_SIZES,
|
PAYLOAD_SIZES,
|
||||||
PreparedProfile,
|
PreparedProfile,
|
||||||
prepare_profiles,
|
prepare_profiles,
|
||||||
@@ -44,18 +44,18 @@ from protocol.video_packet import (
|
|||||||
ObjectType,
|
ObjectType,
|
||||||
decode_packet as decode_inner_packet,
|
decode_packet as decode_inner_packet,
|
||||||
)
|
)
|
||||||
from tests.lab028_video_packetization import (
|
from experiments.lab028_video_packetization import (
|
||||||
COMPOSITE_FPS,
|
COMPOSITE_FPS,
|
||||||
SOURCE_VIDEO_PATH,
|
SOURCE_VIDEO_PATH,
|
||||||
EncodedComposite,
|
EncodedComposite,
|
||||||
VideoMetadata,
|
VideoMetadata,
|
||||||
load_video_profile,
|
load_video_profile,
|
||||||
)
|
)
|
||||||
from tests.lab029_packet_channel_simulation import (
|
from experiments.lab029_packet_channel_simulation import (
|
||||||
PreparedProfile,
|
PreparedProfile,
|
||||||
prepare_profiles,
|
prepare_profiles,
|
||||||
)
|
)
|
||||||
from tests.lab029b_time_based_burst_simulation import (
|
from experiments.lab029b_time_based_burst_simulation import (
|
||||||
BAD_TIME_FRACTION,
|
BAD_TIME_FRACTION,
|
||||||
CONTROL_STREAM_BITRATE_BPS,
|
CONTROL_STREAM_BITRATE_BPS,
|
||||||
CONTROL_STREAM_BITRATE_KBPS,
|
CONTROL_STREAM_BITRATE_KBPS,
|
||||||
@@ -36,18 +36,18 @@ from protocol.video_packet import (
|
|||||||
CompositeReassembler,
|
CompositeReassembler,
|
||||||
decode_packet as decode_inner_packet,
|
decode_packet as decode_inner_packet,
|
||||||
)
|
)
|
||||||
from tests.lab028_video_packetization import (
|
from experiments.lab028_video_packetization import (
|
||||||
COMPOSITE_FPS,
|
COMPOSITE_FPS,
|
||||||
SOURCE_VIDEO_PATH,
|
SOURCE_VIDEO_PATH,
|
||||||
EncodedComposite,
|
EncodedComposite,
|
||||||
VideoMetadata,
|
VideoMetadata,
|
||||||
load_video_profile,
|
load_video_profile,
|
||||||
)
|
)
|
||||||
from tests.lab029_packet_channel_simulation import (
|
from experiments.lab029_packet_channel_simulation import (
|
||||||
PreparedProfile,
|
PreparedProfile,
|
||||||
prepare_profiles,
|
prepare_profiles,
|
||||||
)
|
)
|
||||||
from tests.lab029b_time_based_burst_simulation import (
|
from experiments.lab029b_time_based_burst_simulation import (
|
||||||
BAD_TIME_FRACTION,
|
BAD_TIME_FRACTION,
|
||||||
CONTROL_STREAM_BITRATE_BPS,
|
CONTROL_STREAM_BITRATE_BPS,
|
||||||
CONTROL_STREAM_BITRATE_KBPS,
|
CONTROL_STREAM_BITRATE_KBPS,
|
||||||
@@ -55,7 +55,7 @@ from tests.lab029b_time_based_burst_simulation import (
|
|||||||
generate_bad_intervals,
|
generate_bad_intervals,
|
||||||
percentile,
|
percentile,
|
||||||
)
|
)
|
||||||
from tests.lab030_packet_erasure_fec import (
|
from experiments.lab030_packet_erasure_fec import (
|
||||||
FECBlockPlan,
|
FECBlockPlan,
|
||||||
FECMode,
|
FECMode,
|
||||||
FunctionalTestResult,
|
FunctionalTestResult,
|
||||||
@@ -34,18 +34,18 @@ from protocol.video_packet import (
|
|||||||
CompositeReassembler,
|
CompositeReassembler,
|
||||||
decode_packet as decode_inner_packet,
|
decode_packet as decode_inner_packet,
|
||||||
)
|
)
|
||||||
from tests.lab028_video_packetization import (
|
from experiments.lab028_video_packetization import (
|
||||||
COMPOSITE_FPS,
|
COMPOSITE_FPS,
|
||||||
SOURCE_VIDEO_PATH,
|
SOURCE_VIDEO_PATH,
|
||||||
EncodedComposite,
|
EncodedComposite,
|
||||||
VideoMetadata,
|
VideoMetadata,
|
||||||
load_video_profile,
|
load_video_profile,
|
||||||
)
|
)
|
||||||
from tests.lab029_packet_channel_simulation import (
|
from experiments.lab029_packet_channel_simulation import (
|
||||||
PreparedProfile,
|
PreparedProfile,
|
||||||
prepare_profiles,
|
prepare_profiles,
|
||||||
)
|
)
|
||||||
from tests.lab029b_time_based_burst_simulation import (
|
from experiments.lab029b_time_based_burst_simulation import (
|
||||||
BAD_TIME_FRACTION,
|
BAD_TIME_FRACTION,
|
||||||
CONTROL_STREAM_BITRATE_BPS,
|
CONTROL_STREAM_BITRATE_BPS,
|
||||||
CONTROL_STREAM_BITRATE_KBPS,
|
CONTROL_STREAM_BITRATE_KBPS,
|
||||||
@@ -53,7 +53,7 @@ from tests.lab029b_time_based_burst_simulation import (
|
|||||||
generate_bad_intervals,
|
generate_bad_intervals,
|
||||||
percentile,
|
percentile,
|
||||||
)
|
)
|
||||||
from tests.lab030_packet_erasure_fec import (
|
from experiments.lab030_packet_erasure_fec import (
|
||||||
FECBlockPlan,
|
FECBlockPlan,
|
||||||
FECMode,
|
FECMode,
|
||||||
FunctionalTestResult,
|
FunctionalTestResult,
|
||||||
@@ -47,21 +47,21 @@ from protocol.video_packet import (
|
|||||||
CompositeReassembler,
|
CompositeReassembler,
|
||||||
decode_packet as decode_inner_packet,
|
decode_packet as decode_inner_packet,
|
||||||
)
|
)
|
||||||
from tests.lab028_video_packetization import (
|
from experiments.lab028_video_packetization import (
|
||||||
COMPOSITE_FPS,
|
COMPOSITE_FPS,
|
||||||
SOURCE_VIDEO_PATH,
|
SOURCE_VIDEO_PATH,
|
||||||
EncodedComposite,
|
EncodedComposite,
|
||||||
VideoMetadata,
|
VideoMetadata,
|
||||||
load_video_profile,
|
load_video_profile,
|
||||||
)
|
)
|
||||||
from tests.lab029_packet_channel_simulation import prepare_profiles
|
from experiments.lab029_packet_channel_simulation import prepare_profiles
|
||||||
from tests.lab030_packet_erasure_fec import (
|
from experiments.lab030_packet_erasure_fec import (
|
||||||
FECBlockPlan,
|
FECBlockPlan,
|
||||||
SourcePacket,
|
SourcePacket,
|
||||||
TransmissionUnit,
|
TransmissionUnit,
|
||||||
prepare_source_packets,
|
prepare_source_packets,
|
||||||
)
|
)
|
||||||
from tests.lab032_fec_parameter_sweep import (
|
from experiments.lab032_fec_parameter_sweep import (
|
||||||
SweepMode,
|
SweepMode,
|
||||||
build_parameter_units,
|
build_parameter_units,
|
||||||
)
|
)
|
||||||
@@ -994,7 +994,7 @@ def write_report(
|
|||||||
"8. Созданные файлы и итоговый Git status",
|
"8. Созданные файлы и итоговый Git status",
|
||||||
"- protocol/link_packet.py",
|
"- protocol/link_packet.py",
|
||||||
"- protocol/priority_scheduler.py",
|
"- protocol/priority_scheduler.py",
|
||||||
"- tests/lab033_priority_channel_scheduler.py",
|
"- experiments/lab033_priority_channel_scheduler.py",
|
||||||
"- data/processed/lab033/lab033_summary.csv",
|
"- data/processed/lab033/lab033_summary.csv",
|
||||||
"- data/processed/lab033/lab033_class_metrics.csv",
|
"- data/processed/lab033/lab033_class_metrics.csv",
|
||||||
"- data/processed/lab033/lab033_report.txt",
|
"- data/processed/lab033/lab033_report.txt",
|
||||||
@@ -34,10 +34,10 @@ from protocol.video_age_policy import (
|
|||||||
schedule_with_video_age,
|
schedule_with_video_age,
|
||||||
)
|
)
|
||||||
from protocol.video_packet import CompositeReassembler, decode_packet as decode_inner_packet
|
from protocol.video_packet import CompositeReassembler, decode_packet as decode_inner_packet
|
||||||
from tests.lab028_video_packetization import COMPOSITE_FPS
|
from experiments.lab028_video_packetization import COMPOSITE_FPS
|
||||||
from tests.lab029_packet_channel_simulation import prepare_profiles
|
from experiments.lab029_packet_channel_simulation import prepare_profiles
|
||||||
from tests.lab030_packet_erasure_fec import SourcePacket, prepare_source_packets
|
from experiments.lab030_packet_erasure_fec import SourcePacket, prepare_source_packets
|
||||||
from tests.lab033_priority_channel_scheduler import (
|
from experiments.lab033_priority_channel_scheduler import (
|
||||||
CHANNEL_RATES_KBPS,
|
CHANNEL_RATES_KBPS,
|
||||||
STREAM_VIDEO,
|
STREAM_VIDEO,
|
||||||
VIDEO_PAYLOAD_SIZE,
|
VIDEO_PAYLOAD_SIZE,
|
||||||
@@ -982,7 +982,7 @@ def write_report(lab033, continuous, aligned, results, tests):
|
|||||||
])
|
])
|
||||||
lines.extend(f"- {'PASS' if item.passed else 'FAIL'} {item.name}: {item.detail}" for item in tests)
|
lines.extend(f"- {'PASS' if item.passed else 'FAIL'} {item.name}: {item.detail}" for item in tests)
|
||||||
lines.extend(["", "8. Созданные файлы"])
|
lines.extend(["", "8. Созданные файлы"])
|
||||||
lines.extend(f"- {path.as_posix()}" for path in (Path("protocol/video_age_policy.py"), Path("tests/lab034_stale_video_drop.py"), SUMMARY_CSV_PATH, VIDEO_CSV_PATH, CONTROL_CSV_PATH, REPORT_PATH, *PLOT_PATHS))
|
lines.extend(f"- {path.as_posix()}" for path in (Path("protocol/video_age_policy.py"), Path("experiments/lab034_stale_video_drop.py"), SUMMARY_CSV_PATH, VIDEO_CSV_PATH, CONTROL_CSV_PATH, REPORT_PATH, *PLOT_PATHS))
|
||||||
lines.extend([
|
lines.extend([
|
||||||
"",
|
"",
|
||||||
"9. Итоговый Git status",
|
"9. Итоговый Git status",
|
||||||
@@ -25,8 +25,8 @@ from protocol.video_frame_scheduler import (
|
|||||||
schedule_video_frames,
|
schedule_video_frames,
|
||||||
)
|
)
|
||||||
from protocol.video_packet import CompositeReassembler, decode_packet as decode_inner_packet
|
from protocol.video_packet import CompositeReassembler, decode_packet as decode_inner_packet
|
||||||
from tests.lab028_video_packetization import COMPOSITE_FPS
|
from experiments.lab028_video_packetization import COMPOSITE_FPS
|
||||||
from tests.lab034_stale_video_drop import (
|
from experiments.lab034_stale_video_drop import (
|
||||||
PolicyDefinition as Lab034Policy,
|
PolicyDefinition as Lab034Policy,
|
||||||
build_aligned_workload,
|
build_aligned_workload,
|
||||||
build_lab033_workload,
|
build_lab033_workload,
|
||||||
@@ -721,7 +721,7 @@ def write_report(aligned,results,tests):
|
|||||||
lines.extend(["","5. Интерпретация","- Реактивная Lab034 начинает кадр без гарантии завершения, затем удаляет остаток: уже переданные байты становятся бесполезными, а обновление не публикуется.","- Удаление до первого пакета исключает бесполезную передачу; обслуживание целыми кадрами гарантирует, что начатый кадр будет опубликован.","- Политика самого свежего уменьшает задержку ожидающих данных, но удаляет больше промежуточных кадров; очередь из двух кадров сохраняет больше последовательных обновлений ценой возраста.","- Прогноз полного завершения учитывает весь размер кадра и будущую периодическую высокоприоритетную нагрузку, поэтому полезнее проверки только текущего возраста.","- В модели точно известны команды 20 Гц, телеметрия 10 Гц и аварийная команда 10,0 с; неизвестные будущие дискретные события не моделируются и в реальной системе потребовали бы запаса.","- При устойчивой перегрузке невозможно одновременно сохранить все кадры, исходное JPEG-качество и малую задержку; требуется уменьшить частоту, качество или заранее пропускать кадры.","- Частота обновления, возраст изображения и длительность отсутствия нового изображения оцениваются одновременно: оптимизация одного показателя может ухудшить остальные.","","6. Допущения","- Ошибки и помехи отсутствуют; один общий абстрактный ресурс, форматы Lab028-Lab034 неизменны, активный пакет не прерывается.","- Прогноз не изменяет настоящую очередь; для допущенных кадров сохраняются только агрегированные ошибки, без подробного журнала.","- Политика автоматически не выбирается.","","7. Функциональные проверки"])
|
lines.extend(["","5. Интерпретация","- Реактивная Lab034 начинает кадр без гарантии завершения, затем удаляет остаток: уже переданные байты становятся бесполезными, а обновление не публикуется.","- Удаление до первого пакета исключает бесполезную передачу; обслуживание целыми кадрами гарантирует, что начатый кадр будет опубликован.","- Политика самого свежего уменьшает задержку ожидающих данных, но удаляет больше промежуточных кадров; очередь из двух кадров сохраняет больше последовательных обновлений ценой возраста.","- Прогноз полного завершения учитывает весь размер кадра и будущую периодическую высокоприоритетную нагрузку, поэтому полезнее проверки только текущего возраста.","- В модели точно известны команды 20 Гц, телеметрия 10 Гц и аварийная команда 10,0 с; неизвестные будущие дискретные события не моделируются и в реальной системе потребовали бы запаса.","- При устойчивой перегрузке невозможно одновременно сохранить все кадры, исходное JPEG-качество и малую задержку; требуется уменьшить частоту, качество или заранее пропускать кадры.","- Частота обновления, возраст изображения и длительность отсутствия нового изображения оцениваются одновременно: оптимизация одного показателя может ухудшить остальные.","","6. Допущения","- Ошибки и помехи отсутствуют; один общий абстрактный ресурс, форматы Lab028-Lab034 неизменны, активный пакет не прерывается.","- Прогноз не изменяет настоящую очередь; для допущенных кадров сохраняются только агрегированные ошибки, без подробного журнала.","- Политика автоматически не выбирается.","","7. Функциональные проверки"])
|
||||||
lines.extend(f"- {'PASS' if item.passed else 'FAIL'} {item.name}: {item.detail}" for item in tests)
|
lines.extend(f"- {'PASS' if item.passed else 'FAIL'} {item.name}: {item.detail}" for item in tests)
|
||||||
lines.extend(["","8. Созданные файлы"])
|
lines.extend(["","8. Созданные файлы"])
|
||||||
lines.extend(f"- {path.as_posix()}" for path in (Path("protocol/video_frame_scheduler.py"),Path("tests/lab035_video_frame_admission.py"),SUMMARY_CSV_PATH,VIDEO_CSV_PATH,CONTROL_CSV_PATH,PREDICTION_CSV_PATH,REPORT_PATH,*PLOT_PATHS))
|
lines.extend(f"- {path.as_posix()}" for path in (Path("protocol/video_frame_scheduler.py"),Path("experiments/lab035_video_frame_admission.py"),SUMMARY_CSV_PATH,VIDEO_CSV_PATH,CONTROL_CSV_PATH,PREDICTION_CSV_PATH,REPORT_PATH,*PLOT_PATHS))
|
||||||
lines.extend(["","9. Итоговый Git status","- Lab035 не добавлена в индекс и не закоммичена.","",git_status])
|
lines.extend(["","9. Итоговый Git status","- Lab035 не добавлена в индекс и не закоммичена.","",git_status])
|
||||||
REPORT_PATH.write_text("\n".join(lines)+"\n",encoding="utf-8")
|
REPORT_PATH.write_text("\n".join(lines)+"\n",encoding="utf-8")
|
||||||
|
|
||||||
@@ -31,12 +31,12 @@ from protocol.packet_erasure_fec import (
|
|||||||
from protocol.video_age_policy import AgePolicyPacket
|
from protocol.video_age_policy import AgePolicyPacket
|
||||||
from protocol.video_frame_scheduler import FramePolicy, VideoFrameGroup
|
from protocol.video_frame_scheduler import FramePolicy, VideoFrameGroup
|
||||||
from protocol.video_packet import decode_packet as decode_inner_packet
|
from protocol.video_packet import decode_packet as decode_inner_packet
|
||||||
from tests.lab028_video_packetization import (
|
from experiments.lab028_video_packetization import (
|
||||||
COMPOSITE_FPS,
|
COMPOSITE_FPS,
|
||||||
EncodedComposite,
|
EncodedComposite,
|
||||||
packets_for_composite,
|
packets_for_composite,
|
||||||
)
|
)
|
||||||
from tests.lab033_priority_channel_scheduler import (
|
from experiments.lab033_priority_channel_scheduler import (
|
||||||
STREAM_CONTROL,
|
STREAM_CONTROL,
|
||||||
STREAM_EMERGENCY,
|
STREAM_EMERGENCY,
|
||||||
STREAM_TELEMETRY,
|
STREAM_TELEMETRY,
|
||||||
@@ -44,7 +44,7 @@ from tests.lab033_priority_channel_scheduler import (
|
|||||||
build_workload as build_lab033_workload,
|
build_workload as build_lab033_workload,
|
||||||
deterministic_payload,
|
deterministic_payload,
|
||||||
)
|
)
|
||||||
from tests.lab034_stale_video_drop import parity_for_partial
|
from experiments.lab034_stale_video_drop import parity_for_partial
|
||||||
|
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = Path("data/processed/lab036")
|
OUTPUT_DIRECTORY = Path("data/processed/lab036")
|
||||||
@@ -1318,7 +1318,7 @@ def write_report(
|
|||||||
f"- CRC-проверено общих пакетов: {workload.crc_packets_checked}; FEC-блоков: {workload.crc_blocks_checked}.",
|
f"- CRC-проверено общих пакетов: {workload.crc_packets_checked}; FEC-блоков: {workload.crc_blocks_checked}.",
|
||||||
"",
|
"",
|
||||||
"7. Созданные файлы",
|
"7. Созданные файлы",
|
||||||
"- tests/lab036_long_duration_scheduler.py",
|
"- experiments/lab036_long_duration_scheduler.py",
|
||||||
"- data/processed/lab036/lab036_summary.csv",
|
"- data/processed/lab036/lab036_summary.csv",
|
||||||
"- data/processed/lab036/lab036_video_metrics.csv",
|
"- data/processed/lab036/lab036_video_metrics.csv",
|
||||||
"- data/processed/lab036/lab036_control_metrics.csv",
|
"- data/processed/lab036/lab036_control_metrics.csv",
|
||||||
@@ -42,8 +42,8 @@ from protocol.packet_erasure_fec import (
|
|||||||
from protocol.video_packet import decode_packet as decode_inner_packet
|
from protocol.video_packet import decode_packet as decode_inner_packet
|
||||||
from protocol.video_frame_scheduler import VideoFrameGroup
|
from protocol.video_frame_scheduler import VideoFrameGroup
|
||||||
from protocol.video_age_policy import AgePolicyPacket
|
from protocol.video_age_policy import AgePolicyPacket
|
||||||
from tests.lab028_video_packetization import COMPOSITE_FPS, EncodedComposite, packets_for_composite
|
from experiments.lab028_video_packetization import COMPOSITE_FPS, EncodedComposite, packets_for_composite
|
||||||
from tests.lab033_priority_channel_scheduler import (
|
from experiments.lab033_priority_channel_scheduler import (
|
||||||
STREAM_CONTROL,
|
STREAM_CONTROL,
|
||||||
STREAM_EMERGENCY,
|
STREAM_EMERGENCY,
|
||||||
STREAM_TELEMETRY,
|
STREAM_TELEMETRY,
|
||||||
@@ -51,7 +51,7 @@ from tests.lab033_priority_channel_scheduler import (
|
|||||||
build_workload as build_lab033_workload,
|
build_workload as build_lab033_workload,
|
||||||
deterministic_payload,
|
deterministic_payload,
|
||||||
)
|
)
|
||||||
from tests.lab034_stale_video_drop import parity_for_partial
|
from experiments.lab034_stale_video_drop import parity_for_partial
|
||||||
|
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = Path("data/processed/lab037")
|
OUTPUT_DIRECTORY = Path("data/processed/lab037")
|
||||||
@@ -1186,13 +1186,13 @@ def write_report(
|
|||||||
"",
|
"",
|
||||||
"Созданные файлы",
|
"Созданные файлы",
|
||||||
"- protocol/control_repetition.py",
|
"- protocol/control_repetition.py",
|
||||||
"- tests/lab037_lossy_full_link.py",
|
"- experiments/lab037_lossy_full_link.py",
|
||||||
*[f"- {path.as_posix()}" for path in (SUMMARY_CSV_PATH, COMMAND_CSV_PATH, VIDEO_CSV_PATH, EMERGENCY_CSV_PATH, REPORT_PATH, *PLOT_PATHS)],
|
*[f"- {path.as_posix()}" for path in (SUMMARY_CSV_PATH, COMMAND_CSV_PATH, VIDEO_CSV_PATH, EMERGENCY_CSV_PATH, REPORT_PATH, *PLOT_PATHS)],
|
||||||
"",
|
"",
|
||||||
"Итоговый git status",
|
"Итоговый git status",
|
||||||
"?? data/processed/lab037/",
|
"?? data/processed/lab037/",
|
||||||
"?? protocol/control_repetition.py",
|
"?? protocol/control_repetition.py",
|
||||||
"?? tests/lab037_lossy_full_link.py",
|
"?? experiments/lab037_lossy_full_link.py",
|
||||||
"",
|
"",
|
||||||
"Двоичные пакеты, JPEG, подробные пакетные журналы и дампы не сохранялись.",
|
"Двоичные пакеты, JPEG, подробные пакетные журналы и дампы не сохранялись.",
|
||||||
"Режим защиты автоматически не выбирается: все три режима представлены отдельно.",
|
"Режим защиты автоматически не выбирается: все три режима представлены отдельно.",
|
||||||
@@ -43,12 +43,12 @@ from protocol.packet_erasure_fec import (
|
|||||||
decode_outer_symbol,
|
decode_outer_symbol,
|
||||||
)
|
)
|
||||||
from protocol.video_packet import decode_packet as decode_inner_packet
|
from protocol.video_packet import decode_packet as decode_inner_packet
|
||||||
from tests.lab033_priority_channel_scheduler import (
|
from experiments.lab033_priority_channel_scheduler import (
|
||||||
STREAM_CONTROL,
|
STREAM_CONTROL,
|
||||||
STREAM_EMERGENCY,
|
STREAM_EMERGENCY,
|
||||||
deterministic_payload,
|
deterministic_payload,
|
||||||
)
|
)
|
||||||
from tests.lab037_lossy_full_link import (
|
from experiments.lab037_lossy_full_link import (
|
||||||
BAD_TIME_FRACTION,
|
BAD_TIME_FRACTION,
|
||||||
CHANNEL_RATES_KBPS,
|
CHANNEL_RATES_KBPS,
|
||||||
DURATION_SECONDS,
|
DURATION_SECONDS,
|
||||||
@@ -1577,7 +1577,7 @@ def write_report(
|
|||||||
created = (
|
created = (
|
||||||
Path("protocol/control_failsafe.py"),
|
Path("protocol/control_failsafe.py"),
|
||||||
Path("protocol/emergency_ack.py"),
|
Path("protocol/emergency_ack.py"),
|
||||||
Path("tests/lab038_control_failsafe.py"),
|
Path("experiments/lab038_control_failsafe.py"),
|
||||||
SUMMARY_CSV_PATH,
|
SUMMARY_CSV_PATH,
|
||||||
COMMAND_CSV_PATH,
|
COMMAND_CSV_PATH,
|
||||||
EMERGENCY_CSV_PATH,
|
EMERGENCY_CSV_PATH,
|
||||||
@@ -1596,8 +1596,8 @@ def write_report(
|
|||||||
"?? protocol/control_failsafe.py",
|
"?? protocol/control_failsafe.py",
|
||||||
"?? protocol/control_repetition.py",
|
"?? protocol/control_repetition.py",
|
||||||
"?? protocol/emergency_ack.py",
|
"?? protocol/emergency_ack.py",
|
||||||
"?? tests/lab037_lossy_full_link.py",
|
"?? experiments/lab037_lossy_full_link.py",
|
||||||
"?? tests/lab038_control_failsafe.py",
|
"?? experiments/lab038_control_failsafe.py",
|
||||||
"",
|
"",
|
||||||
"Lab038 не добавлен в Git и не закоммичен. Двоичные пакеты, JPEG, дампы и подробные пакетные журналы не сохранялись.",
|
"Lab038 не добавлен в Git и не закоммичен. Двоичные пакеты, JPEG, дампы и подробные пакетные журналы не сохранялись.",
|
||||||
]
|
]
|
||||||
@@ -24,9 +24,9 @@ from protocol.two_stage_failsafe import (
|
|||||||
forced_stop,
|
forced_stop,
|
||||||
integrate_kinematics,
|
integrate_kinematics,
|
||||||
)
|
)
|
||||||
from tests.lab033_priority_channel_scheduler import STREAM_EMERGENCY
|
from experiments.lab033_priority_channel_scheduler import STREAM_EMERGENCY
|
||||||
from tests.lab037_lossy_full_link import bad_intervals
|
from experiments.lab037_lossy_full_link import bad_intervals
|
||||||
from tests.lab038_control_failsafe import (
|
from experiments.lab038_control_failsafe import (
|
||||||
DURATION_SECONDS,
|
DURATION_SECONDS,
|
||||||
EMERGENCY_SPREAD_US,
|
EMERGENCY_SPREAD_US,
|
||||||
MASTER_SEED,
|
MASTER_SEED,
|
||||||
@@ -1776,7 +1776,7 @@ def write_report(
|
|||||||
lines.extend(f"- {'PASS' if item.passed else 'FAIL'} {item.name}: {item.detail}" for item in tests)
|
lines.extend(f"- {'PASS' if item.passed else 'FAIL'} {item.name}: {item.detail}" for item in tests)
|
||||||
created = (
|
created = (
|
||||||
Path("protocol/two_stage_failsafe.py"),
|
Path("protocol/two_stage_failsafe.py"),
|
||||||
Path("tests/lab039_two_stage_braking.py"),
|
Path("experiments/lab039_two_stage_braking.py"),
|
||||||
SUMMARY_CSV_PATH,
|
SUMMARY_CSV_PATH,
|
||||||
WATCHDOG_CSV_PATH,
|
WATCHDOG_CSV_PATH,
|
||||||
DISTANCE_CSV_PATH,
|
DISTANCE_CSV_PATH,
|
||||||
@@ -37,9 +37,9 @@ from protocol.two_stage_failsafe import (
|
|||||||
TwoStageFailsafe,
|
TwoStageFailsafe,
|
||||||
integrate_kinematics,
|
integrate_kinematics,
|
||||||
)
|
)
|
||||||
from tests.lab033_priority_channel_scheduler import STREAM_CONTROL, STREAM_EMERGENCY
|
from experiments.lab033_priority_channel_scheduler import STREAM_CONTROL, STREAM_EMERGENCY
|
||||||
from tests.lab037_lossy_full_link import bad_intervals
|
from experiments.lab037_lossy_full_link import bad_intervals
|
||||||
from tests.lab038_control_failsafe import DURATION_SECONDS, Frame, Unit, Workload, build_workload, packet_is_lost
|
from experiments.lab038_control_failsafe import DURATION_SECONDS, Frame, Unit, Workload, build_workload, packet_is_lost
|
||||||
|
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = Path("data/processed/lab040")
|
OUTPUT_DIRECTORY = Path("data/processed/lab040")
|
||||||
@@ -1650,7 +1650,7 @@ def write_report(
|
|||||||
created = (
|
created = (
|
||||||
Path("protocol/persistent_emergency.py"),
|
Path("protocol/persistent_emergency.py"),
|
||||||
Path("protocol/safe_reset.py"),
|
Path("protocol/safe_reset.py"),
|
||||||
Path("tests/lab040_persistent_emergency.py"),
|
Path("experiments/lab040_persistent_emergency.py"),
|
||||||
SUMMARY_CSV,
|
SUMMARY_CSV,
|
||||||
EMERGENCY_CSV,
|
EMERGENCY_CSV,
|
||||||
RESET_CSV,
|
RESET_CSV,
|
||||||
@@ -94,7 +94,7 @@ VIDEO_OFFERED_LOAD_KBPS = 243.39286666666666
|
|||||||
TELEMETRY_OFFERED_LOAD_KBPS = 7.68
|
TELEMETRY_OFFERED_LOAD_KBPS = 7.68
|
||||||
|
|
||||||
# Параметры торможения взяты из профиля "nominal" Lab039, а не подобраны заново.
|
# Параметры торможения взяты из профиля "nominal" Lab039, а не подобраны заново.
|
||||||
# tests/lab039_two_stage_braking.py: DecelerationProfile("nominal", 1.0, 3.0).
|
# experiments/lab039_two_stage_braking.py: DecelerationProfile("nominal", 1.0, 3.0).
|
||||||
# Оценка пути ниже одноступенчатая и потому консервативнее двухступенчатой
|
# Оценка пути ниже одноступенчатая и потому консервативнее двухступенчатой
|
||||||
# модели Lab039: она не учитывает предварительное замедление Stage1.
|
# модели Lab039: она не учитывает предварительное замедление Stage1.
|
||||||
LAB039_NOMINAL_STAGE2_MPS2 = 3.0
|
LAB039_NOMINAL_STAGE2_MPS2 = 3.0
|
||||||
@@ -1417,7 +1417,7 @@ def write_report(
|
|||||||
created = (
|
created = (
|
||||||
Path("protocol/control_messages.py"),
|
Path("protocol/control_messages.py"),
|
||||||
Path("protocol/session_state.py"),
|
Path("protocol/session_state.py"),
|
||||||
Path("tests/lab041_session_restart_safety.py"),
|
Path("experiments/lab041_session_restart_safety.py"),
|
||||||
SUMMARY_CSV,
|
SUMMARY_CSV,
|
||||||
SESSION_CSV,
|
SESSION_CSV,
|
||||||
REJECTION_CSV,
|
REJECTION_CSV,
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"""Быстрые автоматические проверки ядра протокола."""
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import sys
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||||
CHECKED_DIRECTORIES = ("protocol", "tests", "tools")
|
CHECKED_DIRECTORIES = ("protocol", "tests", "experiments", "tools")
|
||||||
|
|
||||||
|
|
||||||
def check_syntax() -> list[str]:
|
def check_syntax() -> list[str]:
|
||||||
@@ -81,13 +81,13 @@ def check_functional_tests() -> tuple[list[str], int, int]:
|
|||||||
executed = 0
|
executed = 0
|
||||||
skipped = 0
|
skipped = 0
|
||||||
|
|
||||||
for path in sorted((PROJECT_ROOT / "tests").glob("lab*.py")):
|
for path in sorted((PROJECT_ROOT / "experiments").glob("lab*.py")):
|
||||||
source = path.read_text(encoding="utf-8")
|
source = path.read_text(encoding="utf-8")
|
||||||
|
|
||||||
if "def run_functional_tests" not in source:
|
if "def run_functional_tests" not in source:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
module_name = f"tests.{path.stem}"
|
module_name = f"experiments.{path.stem}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
module = importlib.import_module(module_name)
|
module = importlib.import_module(module_name)
|
||||||
|
|||||||
Reference in New Issue
Block a user