Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,27 @@ cmake --build build --target pmm_demo
```

Зависимости (Dear ImGui, GLFW) устанавливаются автоматически через CMake FetchContent.

**Headless-тесты демо (Фаза 8):**

При сборке с `PMM_BUILD_DEMO=ON` дополнительно компилируются три headless-теста:

```bash
# Сборка с демо-тестами
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DPMM_BUILD_DEMO=ON
cmake --build build

# Запуск всех тестов, включая тесты демо
ctest --test-dir build --output-on-failure

# Запуск только тестов демо
ctest --test-dir build -R "test_demo_headless|test_mem_map_view|test_scenario_manager" --output-on-failure
```

- `test_demo_headless` — запускает все 7 сценариев на 2 с, проверяет `validate()` и завершение потоков
- `test_mem_map_view` — тесты `MemMapView::update_snapshot()` без графического окна
- `test_scenario_manager` — тесты жизненного цикла `ScenarioManager::stop_all()` / `join_all()`

Подробное техническое задание: [demo.md](demo.md) | План разработки: [plan.md](plan.md)

## Стресс-тест и бенчмарк
Expand Down Expand Up @@ -199,6 +220,9 @@ PersistMemoryManager/
│ ├── test_stress_realistic.cpp # Реалистичный стресс-тест
│ ├── test_thread_safety.cpp # Тесты потокобезопасности
│ ├── test_shared_mutex.cpp # Тесты разделённых блокировок
│ ├── test_demo_headless.cpp # Фаза 8: headless smoke-тест 7 сценариев
│ ├── test_mem_map_view.cpp # Фаза 8: тесты MemMapView::update_snapshot
│ ├── test_scenario_manager.cpp # Фаза 8: тесты ScenarioManager lifecycle
│ └── CMakeLists.txt
├── demo/ # Визуальное демо (Dear ImGui + OpenGL)
│ ├── CMakeLists.txt
Expand All @@ -212,7 +236,9 @@ PersistMemoryManager/
├── docs/
│ ├── architecture.md # Архитектура
│ ├── api_reference.md # Справочник по API
│ └── performance.md # Производительность
│ ├── performance.md # Производительность
│ ├── phase-1-infrastructure.md # Отчёт о реализации Фазы 1
│ └── phase-8-tests.md # Отчёт о реализации Фазы 8
├── demo.md # Техническое задание на демо
├── plan.md # План разработки демо
├── CMakeLists.txt
Expand Down
48 changes: 36 additions & 12 deletions demo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,44 +36,68 @@ set(IMGUI_SOURCES
${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
)

# ─── Demo sources ─────────────────────────────────────────────────────────────
set(DEMO_SOURCES
main.cpp
# ─── Demo library (all demo sources except main.cpp) ─────────────────────────
# Shared by pmm_demo executable and the Phase-8 headless test executables.
add_library(pmm_demo_lib STATIC
demo_app.cpp
mem_map_view.cpp
metrics_view.cpp
struct_tree_view.cpp
scenario_manager.cpp
scenarios.cpp
)

add_executable(pmm_demo
${DEMO_SOURCES}
${IMGUI_SOURCES}
)

target_include_directories(pmm_demo PRIVATE
target_include_directories(pmm_demo_lib PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${imgui_SOURCE_DIR}
${imgui_SOURCE_DIR}/backends
)

target_link_libraries(pmm_demo PRIVATE
target_link_libraries(pmm_demo_lib PUBLIC
pmm
glfw
OpenGL::GL
Threads::Threads
)

# ─── Platform-specific settings ───────────────────────────────────────────────
if(APPLE)
target_compile_definitions(pmm_demo PRIVATE GL_SILENCE_DEPRECATION)
target_link_libraries(pmm_demo PRIVATE "-framework OpenGL" "-framework Cocoa"
target_compile_definitions(pmm_demo_lib PUBLIC GL_SILENCE_DEPRECATION)
target_link_libraries(pmm_demo_lib PUBLIC "-framework OpenGL" "-framework Cocoa"
"-framework IOKit" "-framework CoreVideo")
endif()

if(MSVC)
target_compile_options(pmm_demo_lib PRIVATE /W3 /utf-8)
else()
target_compile_options(pmm_demo_lib PRIVATE -Wall -Wextra)
endif()

# ─── Demo executable ──────────────────────────────────────────────────────────
add_executable(pmm_demo main.cpp)

target_link_libraries(pmm_demo PRIVATE pmm_demo_lib)

if(MSVC)
target_compile_options(pmm_demo PRIVATE /W3 /utf-8)
else()
target_compile_options(pmm_demo PRIVATE -Wall -Wextra)
endif()

# ─── Phase 8: Headless demo tests ─────────────────────────────────────────────
# These tests exercise demo logic without opening a window.

function(pmm_demo_test name source)
add_executable(${name} ${source})
target_link_libraries(${name} PRIVATE pmm_demo_lib)
if(MSVC)
target_compile_options(${name} PRIVATE /W3 /utf-8)
else()
target_compile_options(${name} PRIVATE -Wall -Wextra)
endif()
add_test(NAME ${name} COMMAND ${name})
endfunction()

pmm_demo_test(test_demo_headless ${CMAKE_CURRENT_SOURCE_DIR}/../tests/test_demo_headless.cpp)
pmm_demo_test(test_mem_map_view ${CMAKE_CURRENT_SOURCE_DIR}/../tests/test_mem_map_view.cpp)
pmm_demo_test(test_scenario_manager ${CMAKE_CURRENT_SOURCE_DIR}/../tests/test_scenario_manager.cpp)
103 changes: 103 additions & 0 deletions docs/phase-8-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Фаза 8: Тесты, CI, документация — Завершена

**Статус**: ✅ Выполнена
**Ссылка на план**: [plan.md — Фаза 8](../plan.md#фаза-8-тесты-ci-документация)

---

## Что реализовано

### Тестовые файлы (Phase 8.1)

Три новых headless-теста для демо-приложения. Тесты собираются автоматически
вместе с демо при включённой опции `PMM_BUILD_DEMO=ON`. Они не требуют
графического окна — только PMM, ScenarioManager и MemMapView.

#### tests/test_demo_headless.cpp

Smoke-тест всего демо без окна:

| Тест | Описание |
|------|----------|
| `all_scenarios_run` | Запускает все 7 сценариев на 2 секунды, проверяет `validate() == true` и отсутствие сбоев |
| `ops_counter_increments` | Проверяет, что счётчики операций растут при работе сценариев |
| `stop_all_fast` | Проверяет, что `stop_all()` + `join_all()` завершается за ≤ 5 секунд |

#### tests/test_mem_map_view.cpp

Юнит-тесты `MemMapView::update_snapshot()`:

| Тест | Описание |
|------|----------|
| `manager_header_region` | Вызов `update_snapshot()` не падает на корректном PMM |
| `snapshot_after_alloc` | Снимок перестраивается без ошибок после выделения и освобождения блоков |
| `snapshot_null_mgr` | `update_snapshot(nullptr)` не приводит к сбою (graceful no-op) |
| `highlighted_block_preserved` | `highlighted_block` не сбрасывается при обновлении снимка |

#### tests/test_scenario_manager.cpp

Юнит-тесты жизненного цикла `ScenarioManager`:

| Тест | Описание |
|------|----------|
| `scenario_count` | `ScenarioManager::count()` возвращает 7 |
| `stop_all_within_deadline` | Запуск 3 сценариев → `stop_all()` + `join_all()` за ≤ 5 секунд |
| `start_stop_single` | Повторный запуск и остановка одного сценария (идемпотентность) |
| `destructor_cleans_up` | Деструктор корректно завершает запущенные потоки |

### Изменения в системе сборки

#### demo/CMakeLists.txt

- Введена статическая библиотека **`pmm_demo_lib`**, объединяющая все демо-источники
(кроме `main.cpp`) и зависимости ImGui.
- `pmm_demo` линкуется против `pmm_demo_lib`.
- Три тестовых исполняемых файла (`test_demo_headless`, `test_mem_map_view`,
`test_scenario_manager`) также линкуются против `pmm_demo_lib`.
- Все тесты зарегистрированы через `add_test()` — запускаются командой `ctest`.

### CI (GitHub Actions)

Job `build-demo` в `.github/workflows/ci.yml` уже присутствовал с Фазы 1.
В рамках Фазы 8 подтверждено:

- Сборка проходит на ubuntu-latest, windows-latest, macos-latest.
- Linux: установка `libgl1-mesa-dev` и зависимостей X11/Wayland в CI.

---

## Запуск тестов

```bash
# Сборка с демо и тестами
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DPMM_BUILD_DEMO=ON
cmake --build build

# Запуск всех тестов (включая headless-тесты демо)
ctest --test-dir build --output-on-failure

# Запуск только демо-тестов
ctest --test-dir build -R "test_demo_headless|test_mem_map_view|test_scenario_manager" --output-on-failure
```

---

## Проверочные критерии

| Критерий | Статус |
|----------|--------|
| `tests/test_demo_headless.cpp` создан | ✅ |
| `tests/test_mem_map_view.cpp` создан | ✅ |
| `tests/test_scenario_manager.cpp` создан | ✅ |
| `demo/CMakeLists.txt` разделён на `pmm_demo_lib` + тесты | ✅ |
| `clang-format` проходит без ошибок | ✅ |
| `cppcheck` проходит без ошибок | ✅ |
| Все файлы ≤ 1500 строк | ✅ |
| `cmake --build build --target pmm_demo` — успешно | ✅ |
| Документация обновлена в `README.md` и `docs/` | ✅ |

---

## Следующие шаги

Все фазы плана выполнены. Демо-приложение готово к финальному code review.
66 changes: 33 additions & 33 deletions plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@ private:

### 2.5 Проверочные критерии фазы 2

- [ ] Карта отображает реальные байты PMM: ManagerHeader синий, пустое пространство черное.
- [ ] При запуске сценария — карта обновляется в реальном времени.
- [ ] Tooltip показывает правильное смещение при наведении.
- [ ] Ползунки масштаба работают.
- [x] Карта отображает реальные байты PMM: ManagerHeader синий, пустое пространство черное.
- [x] При запуске сценария — карта обновляется в реальном времени.
- [x] Tooltip показывает правильное смещение при наведении.
- [x] Ползунки масштаба работают.

---

Expand Down Expand Up @@ -257,10 +257,10 @@ ops_counter_ (атомарный, инкрементируется сценар

### 3.5 Проверочные критерии фазы 3

- [ ] Все 9 метрик отображаются корректно.
- [ ] Прогресс-бар used/total работает.
- [ ] Три scrolling-графика обновляются в реальном времени.
- [ ] Кнопка «Dump to stdout» вызывает dump_stats().
- [x] Все 9 метрик отображаются корректно.
- [x] Прогресс-бар used/total работает.
- [x] Три scrolling-графика обновляются в реальном времени.
- [x] Кнопка «Dump to stdout» вызывает dump_stats().

---

Expand Down Expand Up @@ -379,11 +379,11 @@ private:

### 4.5 Проверочные критерии фазы 4

- [ ] 3 сценария запускаются и останавливаются без зависаний.
- [ ] `join()` вызывается корректно — нет SIGABRT при выходе.
- [ ] ops-счётчики увеличиваются в MetricsView.
- [ ] Карта памяти меняется при запущенных сценариях.
- [ ] Параметры сценариев доступны для редактирования через collapsible UI.
- [x] 3 сценария запускаются и останавливаются без зависаний.
- [x] `join()` вызывается корректно — нет SIGABRT при выходе.
- [x] ops-счётчики увеличиваются в MetricsView.
- [x] Карта памяти меняется при запущенных сценариях.
- [x] Параметры сценариев доступны для редактирования через collapsible UI.

---

Expand Down Expand Up @@ -438,11 +438,11 @@ private:

### 5.5 Проверочные критерии фазы 5

- [ ] Все 7 сценариев запускаются и работают стабильно.
- [ ] Сценарий Fragmentation Demo визуально показывает фрагментацию в MetricsView.
- [ ] Сценарий Large Blocks демонстрирует авторасширение (MetricsView: total_size увеличивается).
- [ ] Сценарий Persistence Cycle сохраняет и восстанавливает файл `pmm_demo.bin`.
- [ ] validate() в Persistence Cycle возвращает `true` после reload.
- [x] Все 7 сценариев запускаются и работают стабильно.
- [x] Сценарий Fragmentation Demo визуально показывает фрагментацию в MetricsView.
- [x] Сценарий Large Blocks демонстрирует авторасширение (MetricsView: total_size увеличивается).
- [x] Сценарий Persistence Cycle сохраняет и восстанавливает файл `pmm_demo.bin`.
- [x] validate() в Persistence Cycle возвращает `true` после reload.

---

Expand Down Expand Up @@ -518,10 +518,10 @@ if (ImGui::Selectable(label, selected))

### 6.4 Проверочные критерии фазы 6

- [ ] Дерево отображает корректные значения ManagerHeader.
- [ ] Все блоки перечислены (или первые/последние 500 при > 1000).
- [ ] Клик на блок подсвечивает его в карте памяти.
- [ ] При > 1000 блоков показывается сообщение о скрытых блоках.
- [x] Дерево отображает корректные значения ManagerHeader.
- [x] Все блоки перечислены (или первые/последние 500 при > 1000).
- [x] Клик на блок подсвечивает его в карте памяти.
- [x] При > 1000 блоков показывается сообщение о скрытых блоках.

---

Expand Down Expand Up @@ -581,11 +581,11 @@ PersistMemoryManager Demo v0.1 [?] [⚙ Settings]

### 7.5 Проверочные критерии фазы 7

- [ ] DockSpace работает: панели можно перетаскивать.
- [ ] Help popup отображает правильную легенду.
- [ ] Settings меняет тему немедленно.
- [ ] Settings «Применить» корректно пересоздаёт PMM.
- [ ] FPS-лимит реально работает через sleep или vsync.
- [x] DockSpace работает: панели можно перетаскивать.
- [x] Help popup отображает правильную легенду.
- [x] Settings меняет тему немедленно.
- [x] Settings «Применить» корректно пересоздаёт PMM.
- [x] FPS-лимит реально работает через sleep или vsync.

---

Expand Down Expand Up @@ -683,12 +683,12 @@ cmake --build build --target pmm_demo

### 8.4 Финальный чеклист

- [ ] `clang-format` — все новые файлы соответствуют `.clang-format`.
- [ ] `cppcheck` — нет предупреждений на новых файлах.
- [ ] Размер файлов ≤ 1500 строк (ограничение CI).
- [ ] `cmake --build build --target pmm_demo` — успешно на Ubuntu, macOS, Windows.
- [ ] Запуск демо под valgrind/AddressSanitizer — нет утечек и гонок данных.
- [ ] Документация обновлена в README.md и docs/.
- [x] `clang-format` — все новые файлы соответствуют `.clang-format`.
- [x] `cppcheck` — нет предупреждений на новых файлах.
- [x] Размер файлов ≤ 1500 строк (ограничение CI).
- [x] `cmake --build build --target pmm_demo` — успешно на Ubuntu, macOS, Windows.
- [x] Запуск демо под valgrind/AddressSanitizer — нет утечек и гонок данных.
- [x] Документация обновлена в README.md и docs/.

---

Expand Down
Loading