Files
loader/_docs/02_document/tests/blackbox-tests.md
T
Oleksandr Bezdieniezhnykh 8f7deb3fca Add E2E tests, fix bugs
Made-with: Cursor
2026-04-13 05:17:48 +03:00

281 lines
8.2 KiB
Markdown

# Blackbox Tests
## Positive Scenarios
### FT-P-01: Health endpoint returns healthy
**Summary**: Verify the liveness probe returns a healthy status without authentication.
**Traces to**: AC-1
**Category**: Health Check
**Preconditions**: Loader service is running.
**Input data**: None
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | GET /health | HTTP 200, body: `{"status": "healthy"}` |
**Expected outcome**: HTTP 200 with exact body `{"status": "healthy"}`
**Max execution time**: 2s
---
### FT-P-02: Status reports unauthenticated state
**Summary**: Verify status endpoint reports no authentication before login.
**Traces to**: AC-1
**Category**: Health Check
**Preconditions**: Loader service is running, no prior login.
**Input data**: None
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | GET /status | HTTP 200, body contains `"authenticated": false` and `"modelCacheDir": "models"` |
**Expected outcome**: HTTP 200 with `authenticated=false`
**Max execution time**: 2s
---
### FT-P-03: Login with valid credentials
**Summary**: Verify login succeeds with valid email/password and sets credentials on the API client.
**Traces to**: AC-2, AC-14
**Category**: Authentication
**Preconditions**: Loader service is running, mock API configured to accept credentials.
**Input data**: `{"email": "test@azaion.com", "password": "validpass"}`
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /login with valid credentials | HTTP 200, body: `{"status": "ok"}` |
| 2 | GET /status | HTTP 200, body contains `"authenticated": true` |
**Expected outcome**: Login returns 200; subsequent status shows authenticated=true
**Max execution time**: 5s
---
### FT-P-04: Download resource via binary-split
**Summary**: Verify a resource can be downloaded and decrypted through the big/small split scheme.
**Traces to**: AC-4, AC-11, AC-13
**Category**: Resource Download
**Preconditions**: Logged in; mock API serves encrypted small part; mock CDN hosts big part.
**Input data**: `{"filename": "testmodel", "folder": "models"}`
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /login with valid credentials | HTTP 200 |
| 2 | POST /load/testmodel with body `{"filename": "testmodel", "folder": "models"}` | HTTP 200, Content-Type: application/octet-stream, non-empty body |
**Expected outcome**: HTTP 200 with binary content matching the original test resource
**Max execution time**: 10s
---
### FT-P-05: Upload resource via binary-split
**Summary**: Verify a resource can be uploaded, split, encrypted, and stored.
**Traces to**: AC-5
**Category**: Resource Upload
**Preconditions**: Logged in; mock API accepts uploads; mock CDN accepts writes.
**Input data**: Binary test file + folder="models"
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /login with valid credentials | HTTP 200 |
| 2 | POST /upload/testmodel multipart (file=test_bytes, folder="models") | HTTP 200, body: `{"status": "ok"}` |
**Expected outcome**: Upload returns 200; big part present on CDN, small part on mock API
**Max execution time**: 10s
---
### FT-P-06: Unlock starts background workflow
**Summary**: Verify unlock endpoint starts the background decryption and Docker loading workflow.
**Traces to**: AC-6, AC-9
**Category**: Docker Unlock
**Preconditions**: Encrypted test archive at IMAGES_PATH; Docker daemon accessible; mock API configured.
**Input data**: `{"email": "test@azaion.com", "password": "validpass"}`
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /unlock with valid credentials | HTTP 200, body contains `"state"` field |
| 2 | Poll GET /unlock/status until state changes | States progress through: authenticating → downloading_key → decrypting → loading_images → ready |
**Expected outcome**: Final state is "ready"
**Max execution time**: 60s
---
### FT-P-07: Unlock detects already-loaded images
**Summary**: Verify unlock returns immediately when Docker images are already present.
**Traces to**: AC-7
**Category**: Docker Unlock
**Preconditions**: All 7 API_SERVICES Docker images already loaded with correct version tag.
**Input data**: `{"email": "test@azaion.com", "password": "validpass"}`
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /unlock with valid credentials | HTTP 200, body: `{"state": "ready"}` |
**Expected outcome**: Immediate ready state, no background processing
**Max execution time**: 5s
---
### FT-P-08: Unlock status poll
**Summary**: Verify unlock status endpoint returns current state and error.
**Traces to**: AC-8
**Category**: Docker Unlock
**Preconditions**: No unlock started (idle state).
**Input data**: None
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | GET /unlock/status | HTTP 200, body: `{"state": "idle", "error": null}` |
**Expected outcome**: State is idle, error is null
**Max execution time**: 2s
---
## Negative Scenarios
### FT-N-01: Login with invalid credentials
**Summary**: Verify login rejects invalid credentials with HTTP 401.
**Traces to**: AC-3
**Category**: Authentication
**Preconditions**: Loader service is running; mock API rejects these credentials.
**Input data**: `{"email": "bad@test.com", "password": "wrongpass"}`
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /login with invalid credentials | HTTP 401, body has `"detail"` field |
**Expected outcome**: HTTP 401 with error detail
**Max execution time**: 5s
---
### FT-N-02: Login with missing fields
**Summary**: Verify login rejects requests with missing email/password fields.
**Traces to**: AC-3
**Category**: Authentication
**Preconditions**: Loader service is running.
**Input data**: `{}`
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /login with empty JSON body | HTTP 422 (validation error) |
**Expected outcome**: HTTP 422 from Pydantic validation
**Max execution time**: 2s
---
### FT-N-03: Upload without file attachment
**Summary**: Verify upload rejects requests without a file.
**Traces to**: AC-5 (negative)
**Category**: Resource Upload
**Preconditions**: Logged in.
**Input data**: POST without multipart file
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /upload/testfile without file attachment | HTTP 422 |
**Expected outcome**: HTTP 422 validation error
**Max execution time**: 2s
---
### FT-N-04: Download non-existent resource
**Summary**: Verify download returns 500 when the requested resource does not exist.
**Traces to**: AC-4 (negative)
**Category**: Resource Download
**Preconditions**: Logged in; resource "nonexistent" does not exist on API or CDN.
**Input data**: `{"filename": "nonexistent", "folder": "models"}`
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /load/nonexistent with body | HTTP 500, body has `"detail"` field |
**Expected outcome**: HTTP 500 with error detail
**Max execution time**: 10s
---
### FT-N-05: Unlock without encrypted archive
**Summary**: Verify unlock returns 404 when no encrypted archive is present and images are not loaded.
**Traces to**: AC-10
**Category**: Docker Unlock
**Preconditions**: No file at IMAGES_PATH; Docker images not loaded.
**Input data**: `{"email": "test@azaion.com", "password": "validpass"}`
**Steps**:
| Step | Consumer Action | Expected System Response |
|------|----------------|------------------------|
| 1 | POST /unlock with valid credentials | HTTP 404, body has `"detail"` containing "Encrypted archive not found" |
**Expected outcome**: HTTP 404 with archive-not-found message
**Max execution time**: 5s