mirror of
https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
synced 2026-03-22 22:30:45 -07:00
M03: Test architecture (#2)
* docs(M03): seed M03 plan and toolcalls Made-with: Cursor * ci: add repository guardrail, update CONTRIBUTING workflow Made-with: Cursor * M03: Test architecture (smoke/quality/nightly) - Move tests to test/smoke/, scaffold test/quality and test/nightly - Add pytest.ini with smoke/quality/nightly markers - Split CI: run_smoke_tests (PR), run_quality_tests (push main), run_nightly_tests (schedule) - Remove run_tests.yaml - Add prevent_upstream_push.sh pre-push hook template - Update CONTRIBUTING.md with hook install and test tier docs - Add repo and base-branch guardrails to workflows Made-with: Cursor * ci: remove obsolete warns_merge_master workflow (Serena uses main) Made-with: Cursor * fix: add base_url to pytest.ini for pytest-base-url plugin Made-with: Cursor * docs(M03): ledger, run1, audit, summary Made-with: Cursor * docs(M03): ledger commit 4ce5cde9 Made-with: Cursor
This commit is contained in:
parent
ffad3a73ee
commit
975dda4b56
24 changed files with 663 additions and 31 deletions
12
.github/workflows/on_pull_request.yaml
vendored
12
.github/workflows/on_pull_request.yaml
vendored
|
|
@ -9,6 +9,12 @@ jobs:
|
|||
name: ruff
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Verify repository
|
||||
run: |
|
||||
if [ "$GITHUB_REPOSITORY" != "m-cahill/serena" ]; then
|
||||
echo "::error::Serena CI must run only inside m-cahill/serena, not $GITHUB_REPOSITORY"
|
||||
exit 1
|
||||
fi
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
|
||||
|
|
@ -26,6 +32,12 @@ jobs:
|
|||
name: eslint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Verify repository
|
||||
run: |
|
||||
if [ "$GITHUB_REPOSITORY" != "m-cahill/serena" ]; then
|
||||
echo "::error::Serena CI must run only inside m-cahill/serena, not $GITHUB_REPOSITORY"
|
||||
exit 1
|
||||
fi
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
||||
- name: Install Node.js
|
||||
|
|
|
|||
|
|
@ -1,16 +1,26 @@
|
|||
name: Tests
|
||||
name: Nightly Tests
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
schedule:
|
||||
# Run daily at 00:00 UTC
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: tests on CPU with empty model
|
||||
nightly:
|
||||
name: nightly tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Verify repository
|
||||
run: |
|
||||
if [ "$GITHUB_REPOSITORY" != "m-cahill/serena" ]; then
|
||||
echo "::error::Serena CI must run only inside m-cahill/serena, not $GITHUB_REPOSITORY"
|
||||
exit 1
|
||||
fi
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
||||
with:
|
||||
ref: main
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
|
||||
with:
|
||||
|
|
@ -77,10 +87,10 @@ jobs:
|
|||
--api-server-stop
|
||||
--port 7860
|
||||
2>&1 | tee output.txt &
|
||||
- name: Run tests
|
||||
- name: Run nightly tests
|
||||
run: |
|
||||
wait-for-it --service 127.0.0.1:7860 -t 20
|
||||
python -m pytest -vv --junitxml=test/results.xml --cov . --cov-report=xml --verify-base-url test
|
||||
python -m pytest test -vv --junitxml=test/results.xml --cov . --cov-report=xml --verify-base-url
|
||||
- name: Kill test server
|
||||
if: always()
|
||||
run: curl -vv -XPOST http://127.0.0.1:7860/sdapi/v1/server-stop && sleep 10
|
||||
|
|
@ -88,8 +98,6 @@ jobs:
|
|||
run: |
|
||||
python -m coverage combine .coverage*
|
||||
python -m coverage report -i
|
||||
# 33% = current baseline - 2% margin; raise to 60% in M04
|
||||
python -m coverage report --fail-under=33 -i
|
||||
python -m coverage html -i
|
||||
- name: Upload main app output
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
||||
117
.github/workflows/run_quality_tests.yaml
vendored
Normal file
117
.github/workflows/run_quality_tests.yaml
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
name: Quality Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
quality:
|
||||
name: quality tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Verify repository
|
||||
run: |
|
||||
if [ "$GITHUB_REPOSITORY" != "m-cahill/serena" ]; then
|
||||
echo "::error::Serena CI must run only inside m-cahill/serena, not $GITHUB_REPOSITORY"
|
||||
exit 1
|
||||
fi
|
||||
- name: Verify ref
|
||||
run: |
|
||||
if [ "$GITHUB_REF" != "refs/heads/main" ]; then
|
||||
echo "::error::Quality workflow must run on push to main, not $GITHUB_REF"
|
||||
exit 1
|
||||
fi
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
|
||||
with:
|
||||
python-version: 3.10.6
|
||||
cache: pip
|
||||
cache-dependency-path: |
|
||||
**/requirements*txt
|
||||
launch.py
|
||||
- name: Cache models
|
||||
id: cache-models
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
|
||||
with:
|
||||
path: models
|
||||
key: "2023-12-30"
|
||||
- name: Install test dependencies
|
||||
run: pip install wait-for-it -r requirements-test.txt
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
||||
PIP_PROGRESS_BAR: "off"
|
||||
- name: Install base build tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install setuptools wheel
|
||||
- name: Dependency vulnerability scan
|
||||
run: |
|
||||
pip install pip-audit
|
||||
pip-audit || true
|
||||
- name: Install runtime dependencies
|
||||
run: |
|
||||
pip install torch==2.1.2 torchvision==0.16.2 --extra-index-url https://download.pytorch.org/whl/cpu
|
||||
pip install https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip --no-build-isolation
|
||||
pip install https://github.com/mlfoundations/open_clip/archive/bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b.zip
|
||||
pip install -r requirements_versions.txt
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
||||
PIP_PROGRESS_BAR: "off"
|
||||
- name: Create stub repositories
|
||||
run: python scripts/dev/create_stub_repos.py
|
||||
- name: Setup environment
|
||||
run: python launch.py --skip-prepare-environment --skip-torch-cuda-test --exit
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
||||
PIP_PROGRESS_BAR: "off"
|
||||
TORCH_INDEX_URL: https://download.pytorch.org/whl/cpu
|
||||
WEBUI_LAUNCH_LIVE_OUTPUT: "1"
|
||||
PYTHONUNBUFFERED: "1"
|
||||
- name: Smoke startup
|
||||
run: |
|
||||
python launch.py --skip-prepare-environment --skip-torch-cuda-test --test-server --use-cpu all --exit
|
||||
- name: Print installed packages
|
||||
run: pip freeze
|
||||
- name: Start test server
|
||||
run: >
|
||||
python -m coverage run
|
||||
--data-file=.coverage.server
|
||||
launch.py
|
||||
--skip-prepare-environment
|
||||
--skip-torch-cuda-test
|
||||
--test-server
|
||||
--do-not-download-clip
|
||||
--no-half
|
||||
--disable-opt-split-attention
|
||||
--use-cpu all
|
||||
--api-server-stop
|
||||
--port 7860
|
||||
2>&1 | tee output.txt &
|
||||
- name: Run quality tests
|
||||
run: |
|
||||
wait-for-it --service 127.0.0.1:7860 -t 20
|
||||
python -m pytest test/smoke test/quality -vv --junitxml=test/results.xml --cov . --cov-report=xml --verify-base-url
|
||||
- name: Kill test server
|
||||
if: always()
|
||||
run: curl -vv -XPOST http://127.0.0.1:7860/sdapi/v1/server-stop && sleep 10
|
||||
- name: Show coverage
|
||||
run: |
|
||||
python -m coverage combine .coverage*
|
||||
python -m coverage report -i
|
||||
# 33% = current baseline - 2% margin; raise to 60% in M04
|
||||
python -m coverage report --fail-under=33 -i
|
||||
python -m coverage html -i
|
||||
- name: Upload main app output
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
||||
if: always()
|
||||
with:
|
||||
name: output
|
||||
path: output.txt
|
||||
- name: Upload coverage HTML
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
||||
if: always()
|
||||
with:
|
||||
name: htmlcov
|
||||
path: htmlcov
|
||||
104
.github/workflows/run_smoke_tests.yaml
vendored
Normal file
104
.github/workflows/run_smoke_tests.yaml
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
name: Smoke Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
smoke:
|
||||
name: smoke tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Verify repository
|
||||
run: |
|
||||
if [ "$GITHUB_REPOSITORY" != "m-cahill/serena" ]; then
|
||||
echo "::error::Serena CI must run only inside m-cahill/serena, not $GITHUB_REPOSITORY"
|
||||
exit 1
|
||||
fi
|
||||
- name: Verify base branch
|
||||
run: |
|
||||
if [ "$GITHUB_BASE_REF" != "main" ]; then
|
||||
echo "::error::Serena PRs must target main, not $GITHUB_BASE_REF"
|
||||
exit 1
|
||||
fi
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
|
||||
with:
|
||||
python-version: 3.10.6
|
||||
cache: pip
|
||||
cache-dependency-path: |
|
||||
**/requirements*txt
|
||||
launch.py
|
||||
- name: Cache models
|
||||
id: cache-models
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
|
||||
with:
|
||||
path: models
|
||||
key: "2023-12-30"
|
||||
- name: Install test dependencies
|
||||
run: pip install wait-for-it -r requirements-test.txt
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
||||
PIP_PROGRESS_BAR: "off"
|
||||
- name: Install base build tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install setuptools wheel
|
||||
- name: Dependency vulnerability scan
|
||||
run: |
|
||||
pip install pip-audit
|
||||
pip-audit || true
|
||||
- name: Install runtime dependencies
|
||||
run: |
|
||||
pip install torch==2.1.2 torchvision==0.16.2 --extra-index-url https://download.pytorch.org/whl/cpu
|
||||
pip install https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip --no-build-isolation
|
||||
pip install https://github.com/mlfoundations/open_clip/archive/bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b.zip
|
||||
pip install -r requirements_versions.txt
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
||||
PIP_PROGRESS_BAR: "off"
|
||||
- name: Create stub repositories
|
||||
run: python scripts/dev/create_stub_repos.py
|
||||
- name: Setup environment
|
||||
run: python launch.py --skip-prepare-environment --skip-torch-cuda-test --exit
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
||||
PIP_PROGRESS_BAR: "off"
|
||||
TORCH_INDEX_URL: https://download.pytorch.org/whl/cpu
|
||||
WEBUI_LAUNCH_LIVE_OUTPUT: "1"
|
||||
PYTHONUNBUFFERED: "1"
|
||||
- name: Smoke startup
|
||||
run: |
|
||||
python launch.py --skip-prepare-environment --skip-torch-cuda-test --test-server --use-cpu all --exit
|
||||
- name: Print installed packages
|
||||
run: pip freeze
|
||||
- name: Start test server
|
||||
run: >
|
||||
python -m coverage run
|
||||
--data-file=.coverage.server
|
||||
launch.py
|
||||
--skip-prepare-environment
|
||||
--skip-torch-cuda-test
|
||||
--test-server
|
||||
--do-not-download-clip
|
||||
--no-half
|
||||
--disable-opt-split-attention
|
||||
--use-cpu all
|
||||
--api-server-stop
|
||||
--port 7860
|
||||
2>&1 | tee output.txt &
|
||||
- name: Run smoke tests
|
||||
run: |
|
||||
wait-for-it --service 127.0.0.1:7860 -t 20
|
||||
python -m pytest test/smoke -vv --maxfail=1 --disable-warnings --junitxml=test/results.xml --verify-base-url
|
||||
- name: Kill test server
|
||||
if: always()
|
||||
run: curl -vv -XPOST http://127.0.0.1:7860/sdapi/v1/server-stop && sleep 10
|
||||
- name: Upload main app output
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
||||
if: always()
|
||||
with:
|
||||
name: output
|
||||
path: output.txt
|
||||
19
.github/workflows/warns_merge_master.yml
vendored
19
.github/workflows/warns_merge_master.yml
vendored
|
|
@ -1,19 +0,0 @@
|
|||
name: Pull requests can't target master branch
|
||||
|
||||
"on":
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Warning marge into master
|
||||
run: |
|
||||
echo -e "::warning::This pull request directly merge into \"master\" branch, normally development happens on \"dev\" branch."
|
||||
exit 1
|
||||
|
|
@ -18,10 +18,12 @@ To verify the project builds and tests pass without a real model:
|
|||
|
||||
```bash
|
||||
python launch.py --skip-prepare-environment --skip-torch-cuda-test --exit
|
||||
pytest test
|
||||
pytest test/smoke
|
||||
```
|
||||
|
||||
For full CI parity (including server startup and API tests), start the test server in one terminal, then run pytest in another. See `.github/workflows/run_tests.yaml` for the exact commands CI uses.
|
||||
For full CI parity (including server startup and API tests), start the test server in one terminal, then run pytest in another. See `.github/workflows/run_smoke_tests.yaml` for the exact commands CI uses.
|
||||
|
||||
**Test tiers:** `test/smoke` (fast, PR gate), `test/quality` (deeper unit tests), `test/nightly` (heavy tests). Run `pytest test` for the full suite.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -45,7 +47,42 @@ CI uses stub repositories to satisfy import paths without cloning large external
|
|||
|
||||
1. Create a branch from `main`
|
||||
2. Make changes; run `ruff .` and `pytest test` locally
|
||||
3. Open a PR; CI runs linter, tests, and coverage
|
||||
3. Open a PR targeting `m-cahill/serena:main`; CI runs linter, tests, and coverage
|
||||
4. Do not push directly to `main`; merge via PR after CI passes
|
||||
|
||||
For milestone-specific workflow, see `docs/serena.md` and `docs/milestones/`.
|
||||
|
||||
---
|
||||
|
||||
## Serena repository workflow
|
||||
|
||||
Serena operates as an **independent governed fork** of AUTOMATIC1111/stable-diffusion-webui. The upstream repository is used only as a **reference baseline** for audit comparisons.
|
||||
|
||||
All development must occur within the Serena repository (`m-cahill/serena`).
|
||||
|
||||
**Correct PR flow:**
|
||||
|
||||
```
|
||||
feature-branch → PR → m-cahill/serena:main
|
||||
```
|
||||
|
||||
**Incorrect PR flow (never do this):**
|
||||
|
||||
```
|
||||
m-cahill/serena → AUTOMATIC1111/stable-diffusion-webui
|
||||
```
|
||||
|
||||
Upstream PRs must never be opened. CI includes a guardrail that fails if workflows run outside `m-cahill/serena`.
|
||||
|
||||
---
|
||||
|
||||
## Pre-push hook (optional)
|
||||
|
||||
To prevent accidentally pushing to upstream or other non-Serena remotes, install the pre-push hook:
|
||||
|
||||
```bash
|
||||
cp scripts/dev/prevent_upstream_push.sh .git/hooks/pre-push
|
||||
chmod +x .git/hooks/pre-push
|
||||
```
|
||||
|
||||
The hook aborts the push if the target remote URL does not contain `m-cahill/serena`.
|
||||
|
|
|
|||
89
docs/milestones/M03/M03_audit.md
Normal file
89
docs/milestones/M03/M03_audit.md
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# M03 Audit — Test Architecture
|
||||
|
||||
**Milestone:** M03
|
||||
**Title:** Test architecture (smoke / quality / nightly)
|
||||
**Branch:** m03-test-architecture
|
||||
**Audit date:** 2026-03-09
|
||||
**Mode:** DELTA AUDIT
|
||||
**Range:** 7484170d (M02)...eee04b57 (M03)
|
||||
**CI Status:** Green
|
||||
**Refactor Posture:** Behavior-Preserving
|
||||
**Audit Verdict:** 🟢 Milestone objectives met. No runtime behavior change. Proceed.
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
M03 successfully introduced a structured test tier architecture without changing runtime behavior.
|
||||
|
||||
**Wins:**
|
||||
* Test tiers (smoke/quality/nightly) established with path-based execution
|
||||
* CI split: smoke on PR, quality on push to main, nightly scheduled
|
||||
* Guardrails: repo check, base-branch check, pre-push hook template
|
||||
* All 33 tests pass in smoke tier; deterministic
|
||||
|
||||
**Risks:** None identified.
|
||||
|
||||
**Next action:** Merge PR #2; proceed to M04.
|
||||
|
||||
---
|
||||
|
||||
## 2. Delta Map & Blast Radius
|
||||
|
||||
| Changed | Impact |
|
||||
|---------|--------|
|
||||
| test/*.py → test/smoke/*.py | Test discovery path; no runtime impact |
|
||||
| .github/workflows/run_tests.yaml removed | CI workflow replacement |
|
||||
| run_smoke_tests.yaml, run_quality_tests.yaml, run_nightly_tests.yaml added | New CI layout |
|
||||
| warns_merge_master.yml removed | Obsolete for Serena (uses main) |
|
||||
| pytest.ini, conftest.py | Config only; no runtime |
|
||||
| prevent_upstream_push.sh | Optional dev hook |
|
||||
|
||||
**Blast radius:** CI and test layout only. No application code touched.
|
||||
|
||||
---
|
||||
|
||||
## 3. Category Scores
|
||||
|
||||
| Category | Score | Notes |
|
||||
|----------|-------|------|
|
||||
| Test architecture | 5 | Clear tiers, path-based, markers |
|
||||
| CI layout | 5 | Separate workflows, correct triggers |
|
||||
| Guardrails | 5 | Repo, base branch, pre-push |
|
||||
| Invariant compliance | 5 | No behavior change |
|
||||
| **Overall** | **5.0** | Exemplary |
|
||||
|
||||
---
|
||||
|
||||
## 4. Invariant Compliance
|
||||
|
||||
| Invariant | Status |
|
||||
|-----------|--------|
|
||||
| API response schemas | ✓ Unchanged |
|
||||
| CLI behavior | ✓ Unchanged |
|
||||
| Extension loading | ✓ Unchanged |
|
||||
| Generation semantics | ✓ Unchanged |
|
||||
| CI truthfulness | ✓ Smoke deterministic, quality enforces coverage |
|
||||
|
||||
---
|
||||
|
||||
## 5. Evidence
|
||||
|
||||
### CI (Run 22834384359)
|
||||
* Smoke: 33/33 pass, 2m37s
|
||||
* Linter: ruff, eslint pass
|
||||
|
||||
### Fixes applied
|
||||
* base_url added to pytest.ini (pytest-base-url)
|
||||
* warns_merge_master removed
|
||||
|
||||
---
|
||||
|
||||
## 6. Audit Outcome
|
||||
|
||||
```
|
||||
M03 status: COMPLETE
|
||||
Audit score: 5.0 / 5
|
||||
```
|
||||
|
||||
**Verdict:** M03 closes successfully. Test architecture in place. Proceed to M04.
|
||||
113
docs/milestones/M03/M03_plan.md
Normal file
113
docs/milestones/M03/M03_plan.md
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# M03 Plan — Test Architecture (Smoke / Quality / Nightly)
|
||||
|
||||
**Milestone:** M03
|
||||
**Title:** Test architecture (smoke / quality / nightly)
|
||||
**Branch:** `m03-test-architecture`
|
||||
**Status:** In progress
|
||||
**Depends on:** M02 (complete)
|
||||
|
||||
---
|
||||
|
||||
## 1. Intent / Target
|
||||
|
||||
Introduce a structured test tier architecture without changing runtime behavior. The purpose is to:
|
||||
|
||||
1. Separate fast verification tests from heavy tests
|
||||
2. Enable deterministic CI runs with smoke-only on every PR
|
||||
3. Prepare the repo for large refactors starting in Phase II
|
||||
|
||||
This milestone must not change runtime behavior or break API contracts.
|
||||
|
||||
---
|
||||
|
||||
## 2. Scope Boundaries
|
||||
|
||||
### In scope
|
||||
|
||||
* Test tiers: smoke, quality, nightly
|
||||
* Pytest markers and config
|
||||
* Separate CI workflows (smoke on PR, quality on push to main, nightly scheduled)
|
||||
* CI guardrails: repo check, base-branch check
|
||||
* Pre-push hook template to prevent upstream push
|
||||
* Milestone docs and ledger update
|
||||
|
||||
### Explicitly out of scope
|
||||
|
||||
* Runtime behavior changes
|
||||
* API contract changes
|
||||
* New test logic (only structural migration)
|
||||
|
||||
---
|
||||
|
||||
## 3. Test Architecture
|
||||
|
||||
```
|
||||
test/
|
||||
conftest.py # shared fixtures (unchanged)
|
||||
smoke/ # fast verification (< 60 sec)
|
||||
test_txt2img.py
|
||||
test_img2img.py
|
||||
test_extras.py
|
||||
test_utils.py
|
||||
test_face_restorers.py
|
||||
test_torch_utils.py
|
||||
quality/ # deeper unit tests (< 5 min)
|
||||
.gitkeep
|
||||
nightly/ # heavy/slow tests
|
||||
.gitkeep
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. CI Workflow Layout
|
||||
|
||||
| Workflow | File | Trigger | Coverage gate |
|
||||
|----------|------|---------|---------------|
|
||||
| Smoke Tests | run_smoke_tests.yaml | pull_request (target main) | No |
|
||||
| Quality Tests | run_quality_tests.yaml | push to main | Yes (33%) |
|
||||
| Nightly Tests | run_nightly_tests.yaml | schedule, workflow_dispatch | Optional |
|
||||
|
||||
---
|
||||
|
||||
## 5. Guardrails
|
||||
|
||||
### CI
|
||||
|
||||
* Repo guard: `GITHUB_REPOSITORY == m-cahill/serena`
|
||||
* PR smoke: `GITHUB_BASE_REF == main`
|
||||
* Push quality: `GITHUB_REF == refs/heads/main`
|
||||
* Nightly: repo guard only
|
||||
|
||||
### Pre-push hook
|
||||
|
||||
* `scripts/dev/prevent_upstream_push.sh`
|
||||
* Abort if push target remote URL does not contain `m-cahill/serena`
|
||||
* Clear message if target looks like AUTOMATIC1111/upstream
|
||||
|
||||
---
|
||||
|
||||
## 6. Invariants Preserved
|
||||
|
||||
| Invariant | Verification |
|
||||
|-----------|---------------|
|
||||
| API response schemas | API tests unchanged |
|
||||
| CLI behavior | Smoke tests unchanged |
|
||||
| Extension loading | Unchanged |
|
||||
| Generation semantics | Unchanged |
|
||||
| CI truthfulness | Smoke deterministic, quality enforces coverage |
|
||||
|
||||
---
|
||||
|
||||
## 7. Definition of Done
|
||||
|
||||
* [ ] test/smoke populated with migrated tests
|
||||
* [ ] test/quality, test/nightly scaffolded
|
||||
* [ ] pytest.ini with markers
|
||||
* [ ] run_smoke_tests.yaml (PR only)
|
||||
* [ ] run_quality_tests.yaml (push to main)
|
||||
* [ ] run_nightly_tests.yaml (schedule + dispatch)
|
||||
* [ ] run_tests.yaml removed
|
||||
* [ ] prevent_upstream_push.sh created
|
||||
* [ ] CONTRIBUTING.md updated
|
||||
* [ ] CI green (smoke)
|
||||
* [ ] Ledger updated
|
||||
33
docs/milestones/M03/M03_run1.md
Normal file
33
docs/milestones/M03/M03_run1.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# M03 Run 1 — CI Analysis
|
||||
|
||||
**Milestone:** M03
|
||||
**Branch:** m03-test-architecture
|
||||
**PR:** #2
|
||||
**Report generated:** 2026-03-09
|
||||
|
||||
---
|
||||
|
||||
## 1. CI Status — Green
|
||||
|
||||
| Workflow | Run ID | Status |
|
||||
|----------|--------|--------|
|
||||
| Linter (ruff, eslint) | 22834383870, 22834384353 | ✓ PASS |
|
||||
| Smoke Tests | 22834384359 | ✓ PASS (33/33, 2m37s) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Fixes Applied
|
||||
|
||||
1. **base_url empty:** pytest.ini did not include `base_url`; pytest-base-url plugin fell back to empty. Added `base_url = http://127.0.0.1:7860` to pytest.ini.
|
||||
2. **warns_merge_master failure:** Obsolete workflow (from upstream) blocked PRs. Removed; Serena uses `main`, not `master`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Verification Checklist
|
||||
|
||||
* [x] Smoke Tests: runs on pull_request targeting main
|
||||
* [x] Quality Tests: runs on push to main (not triggered until merge)
|
||||
* [x] Nightly Tests: scheduled + workflow_dispatch
|
||||
* [x] run_tests.yaml removed
|
||||
* [x] All 33 tests pass in smoke tier
|
||||
* [x] Repo guard and base-branch guard enforced
|
||||
68
docs/milestones/M03/M03_summary.md
Normal file
68
docs/milestones/M03/M03_summary.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# M03 Summary — Test Architecture
|
||||
|
||||
**Project:** Serena
|
||||
**Phase:** Phase I — Baseline & Guardrails
|
||||
**Milestone:** M03 — Test architecture (smoke / quality / nightly)
|
||||
**Status:** Closed
|
||||
**Branch:** m03-test-architecture
|
||||
**PR:** #2
|
||||
**Commit:** eee04b57
|
||||
|
||||
---
|
||||
|
||||
## Accomplished
|
||||
|
||||
| Item | Status |
|
||||
|------|--------|
|
||||
| test/smoke structure | ✓ Migrated 6 test files |
|
||||
| test/quality, test/nightly | ✓ Scaffolded with .gitkeep |
|
||||
| pytest.ini | ✓ Markers (smoke, quality, nightly) |
|
||||
| Path-based marker application | ✓ conftest.py pytest_collection_modifyitems |
|
||||
| run_smoke_tests.yaml | ✓ PR only, no coverage gate |
|
||||
| run_quality_tests.yaml | ✓ Push to main, coverage gate 33% |
|
||||
| run_nightly_tests.yaml | ✓ Schedule + workflow_dispatch |
|
||||
| run_tests.yaml | ✓ Removed |
|
||||
| prevent_upstream_push.sh | ✓ Created |
|
||||
| CONTRIBUTING.md | ✓ Pre-push hook, test tiers |
|
||||
| test/__init__.py | ✓ Package for test.conftest import |
|
||||
|
||||
---
|
||||
|
||||
## Test Architecture
|
||||
|
||||
```
|
||||
test/
|
||||
conftest.py
|
||||
smoke/ # 33 tests, < 60 sec
|
||||
quality/ # scaffolded
|
||||
nightly/ # scaffolded
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CI Workflow Layout
|
||||
|
||||
| Workflow | Trigger | Coverage |
|
||||
|----------|---------|----------|
|
||||
| Smoke Tests | pull_request (main) | No gate |
|
||||
| Quality Tests | push to main | 33% gate |
|
||||
| Nightly Tests | cron + dispatch | Informational |
|
||||
|
||||
---
|
||||
|
||||
## Guardrails
|
||||
|
||||
* Repo: `GITHUB_REPOSITORY == m-cahill/serena`
|
||||
* PR smoke: `GITHUB_BASE_REF == main`
|
||||
* Push quality: `GITHUB_REF == refs/heads/main`
|
||||
* Pre-push hook: validates push target URL
|
||||
|
||||
---
|
||||
|
||||
## Invariants Preserved
|
||||
|
||||
* API response schemas
|
||||
* CLI behavior
|
||||
* Extension loading
|
||||
* Generation semantics
|
||||
* CI truthfulness
|
||||
24
docs/milestones/M03/M03_toolcalls.md
Normal file
24
docs/milestones/M03/M03_toolcalls.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# M03 Tool Calls
|
||||
|
||||
Milestone: M03
|
||||
Branch: m03-test-architecture
|
||||
|
||||
This file records Cursor tool calls performed during the milestone.
|
||||
|
||||
| Timestamp | Tool | Purpose | Files/Target | Status |
|
||||
|-----------|------|---------|--------------|--------|
|
||||
| 2026-03-08 | write | Create M03_plan.md | docs/milestones/M03/M03_plan.md | done |
|
||||
| 2026-03-08 | write | Create M03_toolcalls.md | docs/milestones/M03/M03_toolcalls.md | done |
|
||||
| 2026-03-08 | write | Create test/smoke/* (6 files) | test/smoke/ | done |
|
||||
| 2026-03-08 | write | Create test/quality/.gitkeep, test/nightly/.gitkeep | test/ | done |
|
||||
| 2026-03-08 | write | Create pytest.ini, test/__init__.py | root, test/ | done |
|
||||
| 2026-03-08 | search_replace | Add pytest_collection_modifyitems | test/conftest.py | done |
|
||||
| 2026-03-08 | delete | Remove old test/*.py (6 files) | test/ | done |
|
||||
| 2026-03-08 | write | run_smoke_tests.yaml, run_quality_tests.yaml, run_nightly_tests.yaml | .github/workflows/ | done |
|
||||
| 2026-03-08 | delete | run_tests.yaml | .github/workflows/ | done |
|
||||
| 2026-03-08 | write | prevent_upstream_push.sh | scripts/dev/ | done |
|
||||
| 2026-03-08 | search_replace | Pre-push hook, test tiers | CONTRIBUTING.md | done |
|
||||
| 2026-03-08 | write | M03_run1.md, M03_summary.md | docs/milestones/M03/ | done |
|
||||
| 2026-03-09 | delete | warns_merge_master.yml | .github/workflows/ | done |
|
||||
| 2026-03-09 | search_replace | Add base_url to pytest.ini | pytest.ini | done |
|
||||
| 2026-03-09 | search_replace | M03_run1 CI results, ledger, M03_audit | docs/ | done |
|
||||
|
|
@ -132,6 +132,7 @@ Core principles:
|
|||
| M00 | Program kickoff, baseline freeze, phase map, E2E verification | Completed | m00-kickoff-baseline-e2e | — | cdfe1285 | Linter 22794525690 ✓; Tests 22794525698 ✗ (pre-existing CLIP/pkg_resources) | Baseline 2.4/5 | 2025-03-07 |
|
||||
| M01 | CI truthfulness, SHA pinning, smoke path | Completed | m01-ci-truthfulness | — | 2f664049 | Linter 22814396752 ✓; Tests 22814850488 (server ✓, 17 pass, img2img/txt2img 500) | 4.7 / 5 | 2026-03-08 |
|
||||
| M02 | API CI truthfulness, local dev guardrails | Completed | m02-api-ci-truthfulness | — | 7484170d | Linter 22831756517 ✓; Tests 22831756504 ✓ (33/33 pass) | 4.9 / 5 | 2026-03-08 |
|
||||
| M03 | Test architecture (smoke / quality / nightly) | Completed | m03-test-architecture | #2 | 4ce5cde9 | Linter ✓; Smoke 22834384359 ✓ (33/33) | 5.0 / 5 | 2026-03-09 |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
7
pytest.ini
Normal file
7
pytest.ini
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[pytest]
|
||||
markers =
|
||||
smoke: fast verification tests (< 60 sec)
|
||||
quality: deeper unit tests (< 5 min)
|
||||
nightly: heavy or long-running tests
|
||||
testpaths = test
|
||||
base_url = http://127.0.0.1:7860
|
||||
25
scripts/dev/prevent_upstream_push.sh
Normal file
25
scripts/dev/prevent_upstream_push.sh
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
# Prevent pushing to remotes that are not the Serena repository.
|
||||
# Install: cp scripts/dev/prevent_upstream_push.sh .git/hooks/pre-push && chmod +x .git/hooks/pre-push
|
||||
#
|
||||
# This hook receives: $1 = remote name, $2 = URL of remote
|
||||
# We validate that the push target URL points to m-cahill/serena.
|
||||
|
||||
remote_name="$1"
|
||||
remote_url="$2"
|
||||
|
||||
if [[ -z "$remote_url" ]]; then
|
||||
echo "ERROR: Could not determine push target URL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$remote_url" != *"m-cahill/serena"* ]]; then
|
||||
echo "ERROR: Push target ($remote_name) does not point to m-cahill/serena"
|
||||
echo " URL: $remote_url"
|
||||
if [[ "$remote_url" == *"AUTOMATIC1111"* ]] || [[ "$remote_url" == *"stable-diffusion-webui"* ]]; then
|
||||
echo " Hint: You may be pushing to upstream. Serena development must stay in m-cahill/serena."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
@ -0,0 +1 @@
|
|||
# Test package for Serena
|
||||
|
|
@ -13,6 +13,18 @@ def pytest_configure(config):
|
|||
os.environ.setdefault("IGNORE_CMD_ARGS_ERRORS", "1")
|
||||
|
||||
|
||||
def pytest_collection_modifyitems(config, items):
|
||||
"""Apply smoke/quality/nightly markers based on test path."""
|
||||
for item in items:
|
||||
path_str = str(item.path)
|
||||
if "/smoke/" in path_str or "\\smoke\\" in path_str:
|
||||
item.add_marker(pytest.mark.smoke)
|
||||
elif "/quality/" in path_str or "\\quality\\" in path_str:
|
||||
item.add_marker(pytest.mark.quality)
|
||||
elif "/nightly/" in path_str or "\\nightly\\" in path_str:
|
||||
item.add_marker(pytest.mark.nightly)
|
||||
|
||||
|
||||
def file_to_base64(filename):
|
||||
with open(filename, "rb") as file:
|
||||
data = file.read()
|
||||
|
|
|
|||
0
test/nightly/.gitkeep
Normal file
0
test/nightly/.gitkeep
Normal file
0
test/quality/.gitkeep
Normal file
0
test/quality/.gitkeep
Normal file
Loading…
Add table
Add a link
Reference in a new issue