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:
m-cahill 2026-03-08 18:39:40 -07:00 committed by GitHub
parent ffad3a73ee
commit 975dda4b56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 663 additions and 31 deletions

View file

@ -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

View file

@ -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
View 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
View 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

View file

@ -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

View file

@ -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`.

View 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.

View 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

View 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

View 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

View 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 |

View file

@ -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
View 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

View 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

View file

@ -0,0 +1 @@
# Test package for Serena

View file

@ -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
View file

0
test/quality/.gitkeep Normal file
View file