Files
Sprinter-SDCC/docs/host-tests-plan.md
T
2026-09-16 10:01:43 +03:00

8.2 KiB
Raw Blame History

План: модульные тесты libc и libbgi под ucsim_z80

Статус: не начато, задача на будущее. Обвязка уже готова и обкатана — testkit/ (см. testkit/README.md); первый потребитель — ../Applications/PoP-Archive/roomtest/tests-host/. Этот документ — про то, как накрыть тем же способом основной продукт репозитория.

Что это НЕ заменяет

В tests/ уже лежат 62 каталога — это интеграционные тесты: одна фича = одна программа, которая пакуется на дискету и гоняется в MAME (docs/mame-autotest.md). Они проверяют, что API работает на живой машине: ESTEX, BIOS, диск, экран, тайминги.

Модульные тесты их не отменяют, а дополняют с другой стороны:

tests/ (MAME) tests-host (ucsim)
что проверяет работает ли на машине верна ли логика
граничные случаи 12 на фичу десятки, дёшево
время прогона десятки секунд миллисекунды
ловит железо, тайминги, банки арифметику, краевые условия, регрессии

Правило разделения то же, что уже записано для PoP: что можно проверить без железа — проверять в ucsim, MAME оставить железу.

Три группы модулей

1. Чистая логика — тестируется как есть, швов не нужно

Здесь можно начинать в тот же день, когда задачу возьмут в работу.

libc:

  • time/_tm_is_leap, _tm_mdays, _tm_month_days, _tm_year_days, mktime, gmtime, localtime, asctime, ctime. Классическая календарная арифметика: високосные годы, границы месяцев, переходы через год, круговой прогон mktime(gmtime(t)) == t. Идеальный первый набор — много краевых случаев и ноль зависимостей.
  • stdio/dec_print, hex8/16/32, _scanf_core, sscanf. Формат и разбор: ширина, знак, переполнение, мусор на входе.
  • string/, stdlib/strlwr, strupr, max, min.

libbgi/common (115 модулей, почти всё mode-agnostic):

  • _bgi_isqrt, _bgi_trig — сверить с эталонной формулой на всём диапазоне, ровно как сделано для LCG в t_geom у PoP;
  • _bgi_lineseg, _bgi_styled_line, _bgi_poly_edge, _bgi_arc_draw — геометрия и отсечение: линия целиком вне окна, по диагонали через угол, вырожденная в точку;
  • _spr_ysort — порядок сортировки спрайтов;
  • _bgi_hspan, _bgi_fill_span — заливка: краевые span'ы, нулевая ширина.

2. Нужны швы — но швы дешёвые

Фейковый ESTEX и BIOS прямо в тестовом crt0. Оба вызываются через rst #0x10 и rst #0x08, то есть через фиксированные векторы в первых байтах памяти. В тестовом бинаре эти адреса наши: можно положить туда обработчик, который эмулирует крошечную файловую систему в ОЗУ и текстовый экран в буфере. Это открывает:

  • file/ (32 модуля) и io/ (21) — fopen/fread/fwrite/fseek, буферизация (docs/file-buffering-design.md), поведение на EOF и ошибках, errno;
  • conio/ (38) — вывод в буфер вместо экрана, проверка атрибутов, скроллинга, границ окна.

Отдельно ценно: гарды, которые обязаны быть в обеих сборках. _fd_guard (девятый OPEN вешает DSS) — это ровно тот случай, где нужен тест, а не вера в комментарий: открыть восемь, убедиться, что девятый вернул ошибку и не дошёл до ESTEX.

Кадровый буфер в ОЗУ для libbgi. Если рисующие ядра умеют писать в обычный буфер, а не только в видеопамять, растеризацию можно проверять снимком: нарисовать фигуру, сравнить с эталонным массивом. Начинать с маленьких (8×8, 16×16) — эталон читаемый прямо в исходнике.

3. Только MAME

Банки и W-окна, EMM, реальный ESTEX/DSS, клавиатурный трамплин и IM2, CBL-звук (cbl/), мышь (mouse/), mem/ (это банки и страницы, а не куча), тайминги и бюджет кадра, ускоритель.

Обе сборки: fast и safe

Библиотеки собираются в двух вариантах (-D*_NOCHECK вырезает валидацию параметров). Наборы стоит гонять против обоих:

  • в safe — что валидация ловит мусорные аргументы и ставит errno;
  • в fast — что вырезание валидации не поменяло поведение на корректных входах.

Это дешёвая параметризация Makefile (тот же набор, два OBJS_*), и она пресекает целый класс расхождений между вариантами.

Фазы

  1. Календарь и формат. time/, stdio/. Нулевые швы, максимальная плотность краевых случаев. Цель — обкатать поток работы на libc.
  2. Геометрия libbgi. common/: isqrt, тригонометрия, отсечение линий, рёбра полигонов. Тоже без швов.
  3. Фейковые ESTEX/BIOS в crt0. Открывает file/, io/, conio/ и гарды. Самый крупный кусок работы и самая большая отдача.
  4. Растр libbgi по снимкам — если окажется, что ядра можно нацелить на буфер в ОЗУ без правок продукта; иначе отложить.
  5. Параметризация fast/safe — после того, как наборов станет заметно.

Критерии

  • Тест не считается написанным, пока не проверен мутацией: сломать проверяемое место, убедиться, что набор краснеет. Пустые тесты хуже отсутствующих.
  • Каждый закрытый баг libc/libbgi получает регрессионный кейс, если он ловится без железа.
  • make host-tests остаётся быстрым: если суммарно перевалит за несколько секунд, делить на быстрый и полный прогон.

Организация

Наборы кладутся рядом с кодом, обвязка общая:

libc/tests-host/       наборы по областям: t_time.c, t_stdio.c, …
libbgi/tests-host/     t_geom.c, t_raster.c, …

Каждому — Makefile на пять строк (TESTKIT, ENGINE_DIR, OBJS_*, include), и добавить каталог в HOST_TEST_DIRS корневого Makefile. Подробности — testkit/README.md.