mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 07:51:52 +00:00
Cleanup repo structure and consolidate tests
- Consolidated `tests/` into `test/` - Moved `test-audit/` scripts to `scripts/test-audit/` - Updated audit scripts to support configurable output directory - Removed root clutter (`test_output.txt`) - Updated documentation and agent prompts Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
bec0b2ba0d
commit
12625bc41b
12 files changed
+342
-4231
No files matched your search
@@ -125,6 +125,7 @@ Agents must keep the repository root clean. Do not create log files, temporary o
|
|||||||
* **Test Logs**: `test_logs/` (e.g., `test_logs/test_output_full.txt`).
|
* **Test Logs**: `test_logs/` (e.g., `test_logs/test_output_full.txt`).
|
||||||
* **Task Logs**: `task-logs/` (e.g., `task-logs/daily/`).
|
* **Task Logs**: `task-logs/` (e.g., `task-logs/daily/`).
|
||||||
* **Artifacts**: `artifacts/` (for raw data, repros, or other artifacts).
|
* **Artifacts**: `artifacts/` (for raw data, repros, or other artifacts).
|
||||||
|
* **Scripts**: `scripts/` (e.g., `scripts/test-audit/`).
|
||||||
* **General Logs**: `logs/` (if needed, otherwise `task-logs/`).
|
* **General Logs**: `logs/` (if needed, otherwise `task-logs/`).
|
||||||
|
|
||||||
**Prohibitions:**
|
**Prohibitions:**
|
||||||
|
|||||||
+2
-1
@@ -21,6 +21,7 @@
|
|||||||
"src/docs/",
|
"src/docs/",
|
||||||
"scripts/check-file-size.mjs",
|
"scripts/check-file-size.mjs",
|
||||||
"scripts/check-innerhtml.mjs",
|
"scripts/check-innerhtml.mjs",
|
||||||
|
"scripts/test-audit/",
|
||||||
"scripts/memory/",
|
"scripts/memory/",
|
||||||
"skills/",
|
"skills/",
|
||||||
"dashboard/",
|
"dashboard/",
|
||||||
@@ -30,7 +31,7 @@
|
|||||||
"TORCH.md"
|
"TORCH.md"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run validate:scheduler && npm run test:integration:e2e && node --test test/*.test.mjs tests/*.test.js",
|
"test": "npm run validate:scheduler && npm run test:integration:e2e && node --test test/*.test.mjs test/*.test.js",
|
||||||
"test:unit:lock-backend": "node --test test/lock-ops.test.mjs test/lock-ops-publish-retry.test.mjs",
|
"test:unit:lock-backend": "node --test test/lock-ops.test.mjs test/lock-ops-publish-retry.test.mjs",
|
||||||
"lock:check:daily": "node bin/torch-lock.mjs check --cadence daily",
|
"lock:check:daily": "node bin/torch-lock.mjs check --cadence daily",
|
||||||
"lock:check:weekly": "node bin/torch-lock.mjs check --cadence weekly",
|
"lock:check:weekly": "node bin/torch-lock.mjs check --cadence weekly",
|
||||||
|
|||||||
@@ -1,4 +1,16 @@
|
|||||||
{
|
{
|
||||||
|
"scripts/agent/load-test.mjs": {
|
||||||
|
"pass": 0,
|
||||||
|
"fail": 5
|
||||||
|
},
|
||||||
|
"scripts/agent/smoke-test.mjs": {
|
||||||
|
"pass": 0,
|
||||||
|
"fail": 5
|
||||||
|
},
|
||||||
|
"Build artifacts verification": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"parseArgs should parse basic command": {
|
"parseArgs should parse basic command": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -35,6 +47,38 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"cmdList": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"Dashboard Authentication": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"Dashboard Configuration Exposure Security": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"Dashboard Configuration Security": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"Dashboard Path Traversal Security Fix": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"Dashboard File Access Security": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"test/fixtures/memory-fixtures.js": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"cmdInit should validate install directory name": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"src/lib.mjs": {
|
"src/lib.mjs": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -51,6 +95,10 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"lock-utils": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"listMemories, inspectMemory, pinMemory, and unpinMemory support admin hooks": {
|
"listMemories, inspectMemory, pinMemory, and unpinMemory support admin hooks": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -67,6 +115,10 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"markMemoryMerged delegates to repository and clears cache": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"stores runtime events in signer/session namespace and clears scope": {
|
"stores runtime events in signer/session namespace and clears scope": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -99,6 +151,106 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"estimateTokenCount returns heuristic count": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"formatMemoryBlock converts memory record to display block": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"formatMemoryBlock handles missing optional fields and default clamping": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"formatMemoryBlock respects custom clamping options": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"formatMemoryBlock handles edge cases for clamping": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"formatMemoriesForPrompt enforces token budget and k limit": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"formatMemoriesForPrompt handles aggressive budget fitting": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext injects context when enabled": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext returns base prompt when disabled": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext handles missing query or service": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext handles circular agentContext gracefully": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext handles agentContext as array of strings": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext handles agentContext as plain object": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext handles agentContext as primitives": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext calls updateMemoryUsage for retrieved memories": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext handles empty memories gracefully": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext handles null/undefined memories gracefully": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext respects TORCH_MEMORY_ENABLED=false": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext respects retrieval allowlist": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"renderPromptWithMemoryContext passes k and tokenBudget": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"getRelevantMemories uses cached results when available": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"getRelevantMemories calls ranker and updates cache on miss": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"getRelevantMemories passes correct parameters to ranker": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"getRelevantMemories triggers updateMemoryUsage on repository": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"ingestEvents": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"ingestMemoryWindow gathers sources, redacts pii, chunks, embeds, links, and emits telemetry": {
|
"ingestMemoryWindow gathers sources, redacts pii, chunks, embeds, links, and emits telemetry": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -107,6 +259,22 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"pinMemory pins the memory and clears the cache": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"pinMemory returns null for non-existent ID but still clears cache": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"unpinMemory unpins the memory and clears the cache": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"unpinMemory returns null for non-existent ID but still clears cache": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"createLifecyclePlan respects delete safety constraints and logs reasons": {
|
"createLifecyclePlan respects delete safety constraints and logs reasons": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -135,6 +303,22 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"runPruneCycle respects off mode": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"runPruneCycle respects dry-run mode": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"runPruneCycle removes stale unpinned memories in active mode": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"runPruneCycle starts scheduler if requested": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"createDbAdvisoryLockProvider acquires and releases postgres advisory locks": {
|
"createDbAdvisoryLockProvider acquires and releases postgres advisory locks": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -159,6 +343,26 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"memoryStats with empty repository returns zero counts and rates": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"memoryStats with populated repository returns correct counts and totals": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"memoryStats calculates ingest throughput based on window": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"memoryStats reflects deleted count from prune cycle": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"memoryStats handles windowMs parameter correctly": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"loadMemoryPromptTemplates loads all memory prompt templates from disk": {
|
"loadMemoryPromptTemplates loads all memory prompt templates from disk": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -171,6 +375,38 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"telemetry should not log to stdout or stderr by default": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"telemetry should log to stderr when NODE_DEBUG=torch-memory is set": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"schema validation covers required fields, coercion, and rejection paths": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizer parser accepts valid json and recovers after malformed json response": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"ingest integration persists memory records and links embeddings from event batches": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"retrieval ranking blends semantic, importance, and recency signals": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"pruner policy protects pins, merges duplicates, and picks archive/delete outcomes": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"scheduler smoke test handles mocked clock and lock contention": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"CLI Smoke Test": {
|
"CLI Smoke Test": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -207,11 +443,51 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
"raises all-relays-down duration alert after threshold": {
|
"RelayHealthManager": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
"raises success-rate alert when rolling health falls below threshold": {
|
"evaluateAlertThresholds": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - basic statistics calculation": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - handles empty history": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - respects time window for stats": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - allDownDurationMinutes considers outside window entries": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - allDownDurationMinutes is null if never healthy": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - allDownDurationMinutes is 0 if currently healthy": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - handles malformed entries gracefully": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - handles valid timestamp but missing summary": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"summarizeHistory - healthy entry with invalid timestamp results in NaN duration": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
|
"Roster (Unit Tests with Dependency Injection)": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
@@ -311,6 +587,10 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"secureRandom": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"summarizes recent lock reliability by platform/cadence/backend/relay": {
|
"summarizes recent lock reliability by platform/cadence/backend/relay": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -327,6 +607,10 @@
|
|||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
},
|
||||||
|
"File Utilities": {
|
||||||
|
"pass": 5,
|
||||||
|
"fail": 0
|
||||||
|
},
|
||||||
"passes when artifacts include metadata and failure IDs map to unresolved known issue entries": {
|
"passes when artifacts include metadata and failure IDs map to unresolved known issue entries": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
@@ -338,29 +622,5 @@
|
|||||||
"fails when failure identifiers are not cross-linked to known issues or incidents": {
|
"fails when failure identifiers are not cross-linked to known issues or incidents": {
|
||||||
"pass": 5,
|
"pass": 5,
|
||||||
"fail": 0
|
"fail": 0
|
||||||
},
|
|
||||||
"schema validation covers required fields, coercion, and rejection paths": {
|
|
||||||
"pass": 5,
|
|
||||||
"fail": 0
|
|
||||||
},
|
|
||||||
"summarizer parser accepts valid json and recovers after malformed json response": {
|
|
||||||
"pass": 5,
|
|
||||||
"fail": 0
|
|
||||||
},
|
|
||||||
"ingest integration persists memory records and links embeddings from event batches": {
|
|
||||||
"pass": 5,
|
|
||||||
"fail": 0
|
|
||||||
},
|
|
||||||
"retrieval ranking blends semantic, importance, and recency signals": {
|
|
||||||
"pass": 5,
|
|
||||||
"fail": 0
|
|
||||||
},
|
|
||||||
"pruner policy protects pins, merges duplicates, and picks archive/delete outcomes": {
|
|
||||||
"pass": 5,
|
|
||||||
"fail": 0
|
|
||||||
},
|
|
||||||
"scheduler smoke test handles mocked clock and lock contention": {
|
|
||||||
"pass": 5,
|
|
||||||
"fail": 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"file": "test/fixtures/memory-fixtures.js",
|
||||||
|
"issues": [
|
||||||
|
"No obvious assertions"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"file": "test/memory-cache.test.mjs",
|
"file": "test/memory-cache.test.mjs",
|
||||||
"issues": [
|
"issues": [
|
||||||
@@ -6,7 +12,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file": "test/memory-scheduler.test.mjs",
|
"file": "test/memory.test.js",
|
||||||
"issues": [
|
"issues": [
|
||||||
"Found setTimeout()"
|
"Found setTimeout()"
|
||||||
]
|
]
|
||||||
@@ -16,17 +22,5 @@
|
|||||||
"issues": [
|
"issues": [
|
||||||
"Found setTimeout()"
|
"Found setTimeout()"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"file": "tests/fixtures/memory-fixtures.js",
|
|
||||||
"issues": [
|
|
||||||
"No obvious assertions"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"file": "tests/memory.test.js",
|
|
||||||
"issues": [
|
|
||||||
"Found setTimeout()"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1,13 +1,29 @@
|
|||||||
import { spawn } from 'node:child_process';
|
import { spawn } from 'node:child_process';
|
||||||
import { writeFileSync } from 'node:fs';
|
import { writeFileSync, mkdirSync } from 'node:fs';
|
||||||
|
import { join } from 'node:path';
|
||||||
|
|
||||||
const RUNS = 5;
|
const RUNS = 5;
|
||||||
const results = {};
|
const results = {};
|
||||||
|
|
||||||
|
// Parse arguments to separate our flags from test runner args
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
let outputDir = 'reports/test-audit';
|
||||||
|
const testArgs = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
if (args[i] === '--output-dir') {
|
||||||
|
outputDir = args[i + 1];
|
||||||
|
i++; // Skip next arg
|
||||||
|
} else {
|
||||||
|
testArgs.push(args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function runTests(i) {
|
async function runTests(i) {
|
||||||
console.log(`Run ${i + 1}/${RUNS}...`);
|
console.log(`Run ${i + 1}/${RUNS}...`);
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const child = spawn('node', ['--test', ...process.argv.slice(2)], {
|
// Pass strictly the test args to the child process
|
||||||
|
const child = spawn('node', ['--test', ...testArgs], {
|
||||||
stdio: ['ignore', 'pipe', 'pipe']
|
stdio: ['ignore', 'pipe', 'pipe']
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -38,8 +54,12 @@ async function main() {
|
|||||||
await runTests(i);
|
await runTests(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync('test-audit/flakiness-matrix.json', JSON.stringify(results, null, 2));
|
// Ensure output directory exists
|
||||||
console.log('Flakiness matrix written.');
|
mkdirSync(outputDir, { recursive: true });
|
||||||
|
|
||||||
|
const outputPath = join(outputDir, 'flakiness-matrix.json');
|
||||||
|
writeFileSync(outputPath, JSON.stringify(results, null, 2));
|
||||||
|
console.log(`Flakiness matrix written to ${outputPath}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs';
|
import { readFileSync, writeFileSync, readdirSync, statSync, mkdirSync } from 'node:fs';
|
||||||
import { join } from 'node:path';
|
import { join } from 'node:path';
|
||||||
|
|
||||||
function getFiles(dir, files = []) {
|
function getFiles(dir, files = []) {
|
||||||
@@ -18,7 +18,19 @@ function getFiles(dir, files = []) {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
const testFiles = [...getFiles('test'), ...getFiles('tests')];
|
// Parse arguments
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
let outputDir = 'reports/test-audit';
|
||||||
|
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
if (args[i] === '--output-dir') {
|
||||||
|
outputDir = args[i + 1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only scan test/ directory now, as tests/ was consolidated
|
||||||
|
const testFiles = [...getFiles('test')];
|
||||||
const suspicious = [];
|
const suspicious = [];
|
||||||
|
|
||||||
for (const file of testFiles) {
|
for (const file of testFiles) {
|
||||||
@@ -45,5 +57,10 @@ for (const file of testFiles) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync('test-audit/suspicious-tests.json', JSON.stringify(suspicious, null, 2));
|
// Ensure output directory exists
|
||||||
|
mkdirSync(outputDir, { recursive: true });
|
||||||
|
|
||||||
|
const outputPath = join(outputDir, 'suspicious-tests.json');
|
||||||
|
writeFileSync(outputPath, JSON.stringify(suspicious, null, 2));
|
||||||
console.log(`Found ${suspicious.length} suspicious files.`);
|
console.log(`Found ${suspicious.length} suspicious files.`);
|
||||||
|
console.log(`Report written to ${outputPath}.`);
|
||||||
@@ -22,6 +22,8 @@ CONSTITUTION (non-negotiable):
|
|||||||
MISSION:
|
MISSION:
|
||||||
1) Inspect repo to discover test runners, CI entry points, and existing test layers.
|
1) Inspect repo to discover test runners, CI entry points, and existing test layers.
|
||||||
2) Audit tests for: behavior fidelity, determinism, and cheat vectors.
|
2) Audit tests for: behavior fidelity, determinism, and cheat vectors.
|
||||||
|
- Use provided audit tools in `scripts/test-audit/` (e.g., `run-flaky-check.mjs`, `run-static-analysis.mjs`) to identify flaky or suspicious tests.
|
||||||
|
- Ensure all tool outputs and reports are saved to `reports/test-audit/`.
|
||||||
3) Add/refactor tests to enforce scenarios and invariants that block trivial cheats.
|
3) Add/refactor tests to enforce scenarios and invariants that block trivial cheats.
|
||||||
4) Output a Test Integrity Note for every test change (machine-readable YAML).
|
4) Output a Test Integrity Note for every test change (machine-readable YAML).
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -1,151 +0,0 @@
|
|||||||
TAP version 13
|
|
||||||
# Subtest: parseArgs should parse basic command
|
|
||||||
ok 1 - parseArgs should parse basic command
|
|
||||||
---
|
|
||||||
duration_ms: 2.074523
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
# Subtest: parseArgs should parse agent and cadence
|
|
||||||
ok 2 - parseArgs should parse agent and cadence
|
|
||||||
---
|
|
||||||
duration_ms: 0.373647
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
# Subtest: parseArgs should parse equals sign syntax
|
|
||||||
ok 3 - parseArgs should parse equals sign syntax
|
|
||||||
---
|
|
||||||
duration_ms: 0.204255
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
# Subtest: parseArgs should parse dry-run flag
|
|
||||||
ok 4 - parseArgs should parse dry-run flag
|
|
||||||
---
|
|
||||||
duration_ms: 0.16969
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
# Subtest: parseArgs should parse port with default
|
|
||||||
ok 5 - parseArgs should parse port with default
|
|
||||||
---
|
|
||||||
duration_ms: 0.170406
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
# Subtest: parseArgs should parse custom port
|
|
||||||
ok 6 - parseArgs should parse custom port
|
|
||||||
---
|
|
||||||
duration_ms: 0.211104
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
# Subtest: parseArgs should parse ignore-logs flag
|
|
||||||
ok 7 - parseArgs should parse ignore-logs flag
|
|
||||||
---
|
|
||||||
duration_ms: 0.273681
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
# Subtest: parseArgs should parse memory flags
|
|
||||||
ok 8 - parseArgs should parse memory flags
|
|
||||||
---
|
|
||||||
duration_ms: 5.033281
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
# Subtest: parseArgs should parse memory flags with equals
|
|
||||||
ok 9 - parseArgs should parse memory flags with equals
|
|
||||||
---
|
|
||||||
duration_ms: 0.269666
|
|
||||||
type: 'test'
|
|
||||||
...
|
|
||||||
1..9
|
|
||||||
# tests 9
|
|
||||||
# suites 0
|
|
||||||
# pass 9
|
|
||||||
# fail 0
|
|
||||||
# cancelled 0
|
|
||||||
# skipped 0
|
|
||||||
# todo 0
|
|
||||||
# duration_ms 32.484347
|
|
||||||
# start of coverage report
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
# file | line % | branch % | funcs % | uncovered lines
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
# src | | | |
|
|
||||||
# cli-parser.mjs | 76.99 | 85.71 | 100.00 | 52 56 86-109
|
|
||||||
# constants.mjs | 100.00 | 100.00 | 100.00 |
|
|
||||||
# test | | | |
|
|
||||||
# cli-parser.test.mjs | 100.00 | 100.00 | 100.00 |
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
# all files | 87.50 | 88.33 | 100.00 |
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
# end of coverage report
|
|
||||||
TAP version 13
|
|
||||||
# node:internal/modules/cjs/loader:1386
|
|
||||||
# throw err;
|
|
||||||
# ^
|
|
||||||
# Error: Cannot find module '/app/test'
|
|
||||||
# at Function._resolveFilename (node:internal/modules/cjs/loader:1383:15)
|
|
||||||
# at defaultResolveImpl (node:internal/modules/cjs/loader:1025:19)
|
|
||||||
# at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1030:22)
|
|
||||||
# at Function._load (node:internal/modules/cjs/loader:1192:37)
|
|
||||||
# at TracingChannel.traceSync (node:diagnostics_channel:328:14)
|
|
||||||
# at wrapModuleLoad (node:internal/modules/cjs/loader:237:24)
|
|
||||||
# at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:171:5)
|
|
||||||
# at node:internal/main/run_main_module:36:49 {
|
|
||||||
# code: 'MODULE_NOT_FOUND',
|
|
||||||
# requireStack: []
|
|
||||||
# }
|
|
||||||
# Node.js v22.22.0
|
|
||||||
# Subtest: test
|
|
||||||
not ok 1 - test
|
|
||||||
---
|
|
||||||
duration_ms: 51.535733
|
|
||||||
type: 'test'
|
|
||||||
location: '/app/test:1:1'
|
|
||||||
failureType: 'testCodeFailure'
|
|
||||||
exitCode: 1
|
|
||||||
signal: ~
|
|
||||||
error: 'test failed'
|
|
||||||
code: 'ERR_TEST_FAILURE'
|
|
||||||
...
|
|
||||||
# node:internal/modules/cjs/loader:1386
|
|
||||||
# throw err;
|
|
||||||
# ^
|
|
||||||
# Error: Cannot find module '/app/tests'
|
|
||||||
# at Function._resolveFilename (node:internal/modules/cjs/loader:1383:15)
|
|
||||||
# at defaultResolveImpl (node:internal/modules/cjs/loader:1025:19)
|
|
||||||
# at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1030:22)
|
|
||||||
# at Function._load (node:internal/modules/cjs/loader:1192:37)
|
|
||||||
# at TracingChannel.traceSync (node:diagnostics_channel:328:14)
|
|
||||||
# at wrapModuleLoad (node:internal/modules/cjs/loader:237:24)
|
|
||||||
# at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:171:5)
|
|
||||||
# at node:internal/main/run_main_module:36:49 {
|
|
||||||
# code: 'MODULE_NOT_FOUND',
|
|
||||||
# requireStack: []
|
|
||||||
# }
|
|
||||||
# Node.js v22.22.0
|
|
||||||
# Subtest: tests
|
|
||||||
not ok 2 - tests
|
|
||||||
---
|
|
||||||
duration_ms: 50.740646
|
|
||||||
type: 'test'
|
|
||||||
location: '/app/tests:1:1'
|
|
||||||
failureType: 'testCodeFailure'
|
|
||||||
exitCode: 1
|
|
||||||
signal: ~
|
|
||||||
error: 'test failed'
|
|
||||||
code: 'ERR_TEST_FAILURE'
|
|
||||||
...
|
|
||||||
1..2
|
|
||||||
# tests 2
|
|
||||||
# suites 0
|
|
||||||
# pass 0
|
|
||||||
# fail 2
|
|
||||||
# cancelled 0
|
|
||||||
# skipped 0
|
|
||||||
# todo 0
|
|
||||||
# duration_ms 66.495879
|
|
||||||
# start of coverage report
|
|
||||||
# ----------------------------------------------------------
|
|
||||||
# file | line % | branch % | funcs % | uncovered lines
|
|
||||||
# ----------------------------------------------------------
|
|
||||||
# ----------------------------------------------------------
|
|
||||||
# all files | 100.00 | 100.00 | 100.00 |
|
|
||||||
# ----------------------------------------------------------
|
|
||||||
# end of coverage report
|
|
||||||
File renamed without changes.
File renamed without changes.
-2641
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user