docs: завершить LDD baseline и release evidence
This commit is contained in:
@@ -50,6 +50,9 @@
|
||||
|
||||
# 6. Браузерный E2E (Playwright + Chromium)
|
||||
./scripts/ldd-browser.sh
|
||||
|
||||
# 7. Полный release gate
|
||||
./scripts/ldd-release.sh
|
||||
```
|
||||
|
||||
Для E2E один раз установите зависимости и браузер: `cd e2e && npm install && npx playwright install chromium`.
|
||||
@@ -78,14 +81,14 @@ Platform 6 из Spring Boot 4.
|
||||
|
||||
Первый LDD-цикл выполнен 2026-10-27/28:
|
||||
|
||||
- **273 автоматических теста**, 0 failures/errors;
|
||||
- **34 claims**: 19 P0 + 15 P1. P0 — доступы, повышение, жизненный цикл,
|
||||
- **276 автоматических тестов**, 0 failures/errors;
|
||||
- **37 claims**: 20 P0 + 17 P1. P0 — доступы, повышение, жизненный цикл,
|
||||
профиль/скачивание, материалы/активы, миграция V13, аудит; P1 — группы,
|
||||
авторство, UI, контракты, импорт, копирование лаб, runtime, mutation и
|
||||
browser E2E;
|
||||
- mutation testing: `CourseAccessService` 75% test strength,
|
||||
`PromotionPlanner` 69%;
|
||||
- Playwright: 3 сценария (admin, teacher, student/anonymous), все зелёные;
|
||||
- Playwright: 4 сценария (admin, teacher, student/anonymous, сдача+mobile), все зелёные;
|
||||
- runtime-smoke, master-upgrade, mutation и browser E2E вынесены в отдельные
|
||||
скрипты.
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
|
||||
## 1. Что проверялось
|
||||
|
||||
Реестр: `docs/evidence/claims.json`, **34 утверждения**.
|
||||
Реестр: `docs/evidence/claims.json`, **37 утверждений**.
|
||||
|
||||
| Критичность | Claims | Proven | Gaps |
|
||||
|---|---:|---:|---:|
|
||||
| P0 | 19 | 19 | 0 |
|
||||
| P1 | 15 | 15 | 0 |
|
||||
| **Итого** | **34** | **34** | **0** |
|
||||
| P0 | 20 | 20 | 0 |
|
||||
| P1 | 17 | 17 | 0 |
|
||||
| **Итого** | **37** | **37** | **0** |
|
||||
|
||||
Домены:
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
./gradlew test --rerun-tasks
|
||||
```
|
||||
|
||||
Результат: **273 теста, 0 failures, 0 errors, 0 skipped**.
|
||||
Результат: **276 тестов, 0 failures, 0 errors, 0 skipped**.
|
||||
`ktlintCheck` и `detekt` — зелёные.
|
||||
|
||||
### 2.2. LDD gate
|
||||
@@ -46,7 +46,7 @@
|
||||
./gradlew evidenceCheck
|
||||
```
|
||||
|
||||
Результат: **34/34 claims proven, P0 gaps = 0**.
|
||||
Результат: **37/37 claims proven, P0 gaps = 0**.
|
||||
Отчёт: `build/reports/evidence/index.md`.
|
||||
|
||||
Gate устроен так:
|
||||
@@ -133,9 +133,28 @@ Playwright/Chromium на полном стеке, одноразовая БД:
|
||||
- anonymous: `/admin/audit` → `/login`;
|
||||
- student: вход, `/admin/audit` → `/student`, `/learn/course/{no}`.
|
||||
|
||||
Результат: **3/3 passed**, evidence: `build/evidence/browser.json`.
|
||||
Результат: **4/4 passed**, evidence: `build/evidence/browser.json`.
|
||||
Дополнительно проверены сдача файла студентом и mobile-размер teacher-страницы.
|
||||
|
||||
### 2.7. Найденный дефект
|
||||
### 2.7. Конкурентные apply/rollback
|
||||
|
||||
Добавлен `PromotionConcurrencyIntegrationTest` (без `@Transactional`, два потока,
|
||||
advisory lock): два одновременных apply идемпотентны и пишут history один раз;
|
||||
два одновременных rollback дают ровно один успех и один `ConflictException`,
|
||||
состояние восстанавливается один раз.
|
||||
|
||||
### 2.8. Нагрузочный smoke
|
||||
|
||||
`ldd-runtime.sh` выполняет 100 чтений (10 workers) курса, лаб, профиля и аудита:
|
||||
**0 ошибок, avg 0.141 c, p95 0.945 c** (порог p95 < 2 c).
|
||||
|
||||
### 2.9. Release gate
|
||||
|
||||
`./scripts/ldd-release.sh` последовательно запускает тесты/линтеры, upgrade,
|
||||
mutation, runtime и browser E2E, затем финальный `evidenceCheck`.
|
||||
В `.gitlab-ci.yml` добавлен ручной job `release-evidence` с Chromium/Node.
|
||||
|
||||
### 2.10. Найденный дефект
|
||||
|
||||
Первый browser E2E упал на создании студента: API вернул `400`, потому что
|
||||
Jackson 3 не применял Kotlin-модуль, и DTO с default-значениями требовали все
|
||||
@@ -159,15 +178,15 @@ optional json fields`.
|
||||
|
||||
## 4. Чего это не доказывает
|
||||
|
||||
1. **Нет нагрузочных и конкурентных испытаний.** Advisory locks и гонки
|
||||
проверены кодом и unit/integration-тестами, но не под нагрузкой.
|
||||
2. **Mutation testing не 100%.** Остаются эквивалентные мутанты и
|
||||
1. **Mutation testing не 100%.** Остаются эквивалентные мутанты и
|
||||
Kotlin/Spring-специфичные мутации; PIT harness — JUnit 4, а не JUnit 5.
|
||||
3. **Property-based тесты покрывают не все ветки.** Есть генераторы для
|
||||
матрицы доступа и планировщика повышения, но не для транзакционного
|
||||
apply/rollback и конкурентных сценариев.
|
||||
4. **Браузерный E2E — один Chromium и один сценарий на роль.** Нет
|
||||
визуальной регрессии, мобильных размеров, Safari/Firefox.
|
||||
2. **Property-based тесты покрывают не все ветки.** Есть генераторы для
|
||||
матрицы доступа, планировщика и 10 транзакционных apply/rollback-кейсов,
|
||||
но не для всех сочетаний полей и распределённой нагрузки.
|
||||
3. **Браузерный E2E — один Chromium и 4 сценария.** Нет визуальной регрессии,
|
||||
Safari/Firefox и полного мобильного набора страниц.
|
||||
4. **Нагрузочный smoke — не benchmark.** Одна машина, синтетические данные,
|
||||
без SLA production.
|
||||
5. **Legacy-активы без `article_assets` остаются публичными.**
|
||||
6. **JWT живёт до 30 дней.** Web перепроверяет статус, прямой API — нет.
|
||||
7. **Ведущие нули номера группы нормализуются** (`01` → `1`).
|
||||
@@ -176,14 +195,15 @@ optional json fields`.
|
||||
|
||||
## 5. Вывод
|
||||
|
||||
Текущая функциональность прошла LDD-контур: **34/34 claims proven, P0 gaps = 0**,
|
||||
Текущая функциональность прошла LDD-контур: **37/37 claims proven, P0 gaps = 0**,
|
||||
273 теста, upgrade, mutation baseline и браузерный E2E зелёные. Это
|
||||
достаточное основание продолжать доработки, но не «формальное доказательство
|
||||
всей системы».
|
||||
|
||||
Следующий цикл LDD:
|
||||
|
||||
1. нагрузочный smoke на чтение ведомости/профиля и конкурентный apply/rollback;
|
||||
2. property-based/model-based тесты транзакционного повышения;
|
||||
3. расширение browser E2E (студенческая сдача, публикация оценки, мобильный вид);
|
||||
4. автоматический release-пайплайн с runtime/mutation/browser evidence.
|
||||
1. расширить browser E2E на публикацию оценки и остальные мобильные страницы;
|
||||
2. добавить нагрузочный профиль с реалистичным объёмом групп/студентов;
|
||||
3. закрыть известные продуктовые риски: legacy-активы, JWT 30 дней, ведущие
|
||||
нули, пагинация/N+1;
|
||||
4. сделать release-evidence job обязательным для тегов.
|
||||
|
||||
@@ -488,16 +488,56 @@
|
||||
},
|
||||
{
|
||||
"id": "LDD-BROWSER-001",
|
||||
"title": "Браузерный E2E админа, преподавателя и студента",
|
||||
"title": "Браузерный E2E админа, преподавателя и студента, включая сдачу и mobile",
|
||||
"criticality": "P1",
|
||||
"status": "active",
|
||||
"requirement": "docs/evidence/README.md",
|
||||
"claim": "Playwright на реальном стеке: admin видит курс и аудит, teacher открывает курс/ведомость/профиль и создаёт главу, аноним и студент не попадают в админку.",
|
||||
"claim": "Playwright на реальном стеке: admin видит курс и аудит; teacher открывает курс/ведомость/профиль, создаёт главу и видит mobile-вид; student сдаёт файл; аноним и студент не попадают в админку.",
|
||||
"oracle": "Playwright assertions на DOM/URL",
|
||||
"runtime": [
|
||||
"browser.e2e"
|
||||
],
|
||||
"limitations": "Один Chromium, один сценарий на роль; визуальная регрессия и мобильные размеры не проверяются."
|
||||
"limitations": "4 сценария, один Chromium; нет визуальной регрессии и Safari/Firefox."
|
||||
},
|
||||
{
|
||||
"id": "LDD-RUNTIME-002",
|
||||
"title": "Нагрузочный smoke чтения курса, лаб, профиля и аудита",
|
||||
"criticality": "P1",
|
||||
"status": "active",
|
||||
"requirement": "docs/evidence/README.md",
|
||||
"claim": "100 параллельных чтений (10 workers) через gateway дают 0 ошибок и p95 < 2 c.",
|
||||
"oracle": "HTTP status + latency percentiles",
|
||||
"runtime": [
|
||||
"runtime.load_gradebook_profile"
|
||||
],
|
||||
"limitations": "Smoke, не benchmark; одна машина и синтетические данные, без SLA production."
|
||||
},
|
||||
{
|
||||
"id": "LDD-PROM-006",
|
||||
"title": "Конкурентные apply/rollback одного запуска повышения",
|
||||
"criticality": "P0",
|
||||
"status": "active",
|
||||
"requirement": "docs/07-groups-courses.md, §7",
|
||||
"claim": "Два одновременных apply не дублируют историю; два одновременных rollback дают ровно один успех и один конфликт, состояние восстанавливается один раз.",
|
||||
"oracle": "Результаты двух потоков, количество APPLY/ROLLBACK и history",
|
||||
"evidence": [
|
||||
"ru.ysu.lms.identity.promotion.PromotionConcurrencyIntegrationTest#concurrent apply of one run is idempotent and writes history once()",
|
||||
"ru.ysu.lms.identity.promotion.PromotionConcurrencyIntegrationTest#concurrent rollback allows exactly one rollback and restores once()"
|
||||
],
|
||||
"limitations": "Два потока в одном JVM; распределённая нагрузка и несколько инстансов проверяются advisory lock-ом, но не chaos-тестом."
|
||||
},
|
||||
{
|
||||
"id": "LDD-PROM-007",
|
||||
"title": "Транзакционный apply/rollback на сгенерированных когортах",
|
||||
"criticality": "P1",
|
||||
"status": "active",
|
||||
"requirement": "docs/07-groups-courses.md, §7",
|
||||
"claim": "Для 10 сгенерированных когорт apply приводит группу к плану, а rollback возвращает точный before-state и активный статус студента.",
|
||||
"oracle": "Сравнение состояния группы/студента до, после apply и после rollback",
|
||||
"evidence": [
|
||||
"ru.ysu.lms.identity.promotion.PromotionApplyRollbackPropertyTest#generated cohorts apply to plan and rollback to before-state()"
|
||||
],
|
||||
"limitations": "10 детерминированных сценариев в одной транзакции; не заменяет property-генератор по всем полям."
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user