Publish ITWorx Pulse source
Public source validation / validate (push) Failing after 3m8s

This commit is contained in:
ITWorx Pulse release export
2026-09-03 02:09:19 +02:00
commit bd774932d5
614 changed files with 77116 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
# Deterministic fixtures and scenarios
`fixtures/scenarios/` defines failure and recovery behavior without touching the real server.
Codex must build a telemetry simulator/fake sources capable of:
- serving Prometheus-compatible query/metadata responses or a suitable deterministic adapter;
- exposing Unraid/inventory snapshots;
- emitting normalized events;
- changing source freshness;
- simulating service probe results;
- controlling time for alert tests;
- supporting browser end-to-end scenarios.
Every scenario must validate against `specs/simulator-scenario.schema.json`.
Production fault tests must use these fixtures or captured redacted read-only data. Never remove disks, degrade arrays, crash real containers or disrupt the network solely for testing.
+36
View File
@@ -0,0 +1,36 @@
{
"schemaVersion": 1,
"id": "array-degraded",
"name": "Array degraded fixture",
"description": "Read-only captured/simulated array membership fault.",
"initialState": {
"array": {
"status": "operational",
"missingDisks": 0
}
},
"timeline": [
{
"atSeconds": 30,
"action": "set-entity-status",
"payload": {
"entity": "fixture-array",
"status": "critical",
"facts": {
"missingDisks": 1,
"emulatedDisk": "disk3"
}
}
}
],
"expectedOutcomes": [
{
"bySeconds": 60,
"assertion": "Array and global status become critical with the missing/emulated disk reason."
},
{
"bySeconds": 60,
"assertion": "No repair/start/stop/correct action is offered."
}
]
}
+22
View File
@@ -0,0 +1,22 @@
{
"schemaVersion": 1,
"id": "capacity-forecast",
"name": "Capacity forecast confidence states",
"description": "A bounded usage history yields a qualified projection while bulk imports, irregular intervals and disabled policy remain explicit without false precision.",
"initialState": {
"forecasts": {
"windowSeconds": 2592000,
"maxPoints": 128,
"method": "linear_median_rate"
}
},
"timeline": [
{"atSeconds": 604800, "action": "set-metric", "payload": {"metric": "storage.share.used_bytes", "entity": "fixture-media", "value": 400000000000}},
{"atSeconds": 1209600, "action": "set-metric", "payload": {"metric": "storage.share.used_bytes", "entity": "fixture-media", "value": 500000000000}}
],
"expectedOutcomes": [
{"bySeconds": 1209600, "assertion": "Forecast response always exposes method, historical window, point count and confidence."},
{"bySeconds": 1209600, "assertion": "Bulk-import, irregular-history and insufficient-data states do not expose a projected capacity date."},
{"bySeconds": 1209600, "assertion": "Disabled forecasting is rendered as an explicit read-only state rather than as a healthy forecast."}
]
}
@@ -0,0 +1,65 @@
{
"schemaVersion": 1,
"id": "container-restart-loop",
"name": "Container restart loop",
"description": "A container repeatedly restarts while returning to running state.",
"initialState": {
"container": {
"id": "fixture-plex",
"name": "Plex",
"status": "running",
"restartCount": 0
}
},
"timeline": [
{
"atSeconds": 10,
"action": "emit-event",
"payload": {
"eventType": "container.restart",
"entity": "fixture-plex",
"exitCode": 137
}
},
{
"atSeconds": 120,
"action": "emit-event",
"payload": {
"eventType": "container.restart",
"entity": "fixture-plex",
"exitCode": 137
}
},
{
"atSeconds": 240,
"action": "emit-event",
"payload": {
"eventType": "container.restart",
"entity": "fixture-plex",
"exitCode": 137
}
},
{
"atSeconds": 360,
"action": "set-entity-status",
"payload": {
"entity": "fixture-plex",
"status": "operational"
}
}
],
"expectedOutcomes": [
{
"bySeconds": 300,
"assertion": "Container is degraded due to instability even when current runtime state is running."
},
{
"bySeconds": 330,
"assertion": "Restart-loop alert is firing and grouped under the application."
},
{
"bySeconds": 1500,
"assertion": "Alert resolves only after the configured stable recovery window."
}
]
}
+37
View File
@@ -0,0 +1,37 @@
{
"schemaVersion": 1,
"id": "database-restart",
"name": "Database restart recovery",
"description": "Database temporarily restarts while API/worker are active.",
"initialState": {
"database": {
"status": "healthy"
},
"alerts": {
"active": 2
}
},
"timeline": [
{
"atSeconds": 30,
"action": "restart-database",
"payload": {
"downtimeSeconds": 20
}
}
],
"expectedOutcomes": [
{
"bySeconds": 40,
"assertion": "API readiness fails while liveness remains appropriate."
},
{
"bySeconds": 90,
"assertion": "Connections recover without duplicate alert transitions or notifications."
},
{
"bySeconds": 120,
"assertion": "Persisted dashboards and alert state are intact."
}
]
}
+60
View File
@@ -0,0 +1,60 @@
{
"schemaVersion": 1,
"id": "disk-temperature",
"name": "Sustained disk temperature",
"description": "Tests pending, firing, hysteresis and recovery.",
"initialState": {
"disk": {
"id": "fixture-disk4",
"temperatureC": 38,
"smart": "healthy"
}
},
"timeline": [
{
"atSeconds": 30,
"action": "set-metric",
"payload": {
"metric": "storage.disk.temperature",
"entity": "fixture-disk4",
"value": 52
}
},
{
"atSeconds": 420,
"action": "set-metric",
"payload": {
"metric": "storage.disk.temperature",
"entity": "fixture-disk4",
"value": 48
}
},
{
"atSeconds": 600,
"action": "set-metric",
"payload": {
"metric": "storage.disk.temperature",
"entity": "fixture-disk4",
"value": 44
}
}
],
"expectedOutcomes": [
{
"bySeconds": 120,
"assertion": "Temperature rule is pending, not firing."
},
{
"bySeconds": 360,
"assertion": "Temperature alert is firing."
},
{
"bySeconds": 500,
"assertion": "Alert remains firing at 48 C because recovery threshold has not been crossed."
},
{
"bySeconds": 930,
"assertion": "Alert resolves only after temperature stays below recovery threshold for the configured duration."
}
]
}
@@ -0,0 +1,44 @@
{
"schemaVersion": 1,
"id": "dns-outage-suppression",
"name": "DNS outage with downstream suppression",
"description": "Many services fail name resolution due to one DNS dependency.",
"initialState": {
"dns": {
"status": "up"
},
"services": {
"up": 20
}
},
"timeline": [
{
"atSeconds": 30,
"action": "set-probe-result",
"payload": {
"probe": "dns-primary",
"success": false,
"error": "timeout"
}
},
{
"atSeconds": 40,
"action": "set-probe-result",
"payload": {
"probeGroup": "dependent-http",
"success": false,
"error": "dns"
}
}
],
"expectedOutcomes": [
{
"bySeconds": 180,
"assertion": "One primary DNS/network incident is created."
},
{
"bySeconds": 180,
"assertion": "Downstream service alerts are visible but suppressed/grouped rather than individually notified."
}
]
}
+60
View File
@@ -0,0 +1,60 @@
{
"schemaVersion": 1,
"id": "healthy-baseline",
"name": "Healthy baseline",
"description": "Stable host, containers, storage and services used as the default deterministic fixture.",
"initialState": {
"host": {
"status": "operational",
"cpuPercent": 18,
"memoryPercent": 42
},
"containers": {
"running": 70,
"stoppedIntentional": 1,
"unhealthy": 0
},
"storage": {
"arrayStatus": "operational",
"poolUtilizationPercent": 55,
"maxDiskTemperatureC": 38
},
"services": {
"up": 25,
"down": 0
},
"sources": {
"prometheus": "healthy",
"unraid": "healthy",
"agent": "healthy"
}
},
"timeline": [
{
"atSeconds": 0,
"action": "set-metric",
"payload": {
"metric": "host.cpu.utilization",
"value": 18
}
},
{
"atSeconds": 0,
"action": "set-metric",
"payload": {
"metric": "host.memory.utilization",
"value": 42
}
}
],
"expectedOutcomes": [
{
"bySeconds": 10,
"assertion": "Global status is operational and contains no active problem reason."
},
{
"bySeconds": 10,
"assertion": "All required datasource freshness indicators are fresh."
}
]
}
@@ -0,0 +1,42 @@
{
"schemaVersion": 1,
"id": "pool-capacity-pressure",
"name": "Pool capacity pressure",
"description": "Cache/pool utilization crosses warning and critical thresholds.",
"initialState": {
"pool": {
"id": "fixture-cache",
"utilizationPercent": 70
}
},
"timeline": [
{
"atSeconds": 30,
"action": "set-metric",
"payload": {
"metric": "storage.pool.utilization",
"entity": "fixture-cache",
"value": 91
}
},
{
"atSeconds": 720,
"action": "set-metric",
"payload": {
"metric": "storage.pool.utilization",
"entity": "fixture-cache",
"value": 98
}
}
],
"expectedOutcomes": [
{
"bySeconds": 700,
"assertion": "Pool is degraded with a capacity reason after sustained 91 percent."
},
{
"bySeconds": 1100,
"assertion": "Pool reaches critical according to policy at sustained 98 percent."
}
]
}
@@ -0,0 +1,21 @@
{
"schemaVersion": 1,
"id": "pool-degraded-scrub",
"name": "Btrfs pool degraded scrub",
"description": "A Btrfs pool keeps its identity and redundancy metadata while one member is missing and scrub reports errors.",
"initialState": {
"pool": {
"id": "fixture-cache",
"filesystem": "btrfs",
"state": "degraded",
"profile": "raid1",
"memberStates": ["online", "missing"],
"scrub": {"state": "failed", "errors": 3}
}
},
"timeline": [{"atSeconds": 30, "action": "set-metric", "payload": {"metric": "storage.pool.utilization", "entity": "fixture-cache", "value": 91}}],
"expectedOutcomes": [
{"bySeconds": 0, "assertion": "Pool remains degraded and the missing member is visible."},
{"bySeconds": 0, "assertion": "Scrub errors are visible as a warning/critical reason without exposing a scrub control."}
]
}
@@ -0,0 +1,33 @@
{
"schemaVersion": 1,
"id": "probe-executor-cases",
"name": "Bounded service probe executor cases",
"description": "Synthetic cases for successful, failed, timed out, redirected, TLS and unsupported probe execution without real credentials or remote resources.",
"initialState": {
"networkPolicy": {
"allowedNetworks": ["10.0.0.0/8", "127.0.0.0/8"],
"maxResponseBytes": 1048576,
"maxRedirects": 5
},
"cases": [
{"id": "http-success-json-keyword", "type": "http", "expectedState": "up"},
{"id": "http-status-failure", "type": "http", "expectedState": "down"},
{"id": "http-timeout", "type": "http", "expectedState": "unknown", "errorClass": "transport_error"},
{"id": "http-redirect-policy", "type": "http", "expectedState": "up"},
{"id": "http-response-body-limit", "type": "http", "expectedState": "unknown", "errorClass": "response_too_large"},
{"id": "tls-certificate-facts", "type": "tls", "expectedState": "up"},
{"id": "dns-resolution", "type": "dns", "expectedState": "up"},
{"id": "tcp-connect", "type": "tcp", "expectedState": "up"},
{"id": "icmp-capability-fallback", "type": "icmp", "expectedState": "unknown", "errorClass": "unsupported"}
],
"credentialExpectation": "secret references are configuration identifiers only; no plaintext credential is sent, stored or included in result errors"
},
"timeline": [
{"atSeconds": 1, "action": "set-probe-result", "payload": {"resolver": "deterministic", "http": "httptest", "tcp": "net-pipe", "tls": "self-signed-net-pipe"}}
],
"expectedOutcomes": [
{"bySeconds": 2, "assertion": "HTTP success, status failure, bounded response and per-probe timeout produce the documented states without leaking secret references."},
{"bySeconds": 2, "assertion": "Redirects are bounded and revalidated; TLS captures certificate expiry, issuer, subject and hostname validity."},
{"bySeconds": 2, "assertion": "TCP and DNS succeed with allowlisted synthetic addresses; ICMP returns Unknown/unsupported when capability is unavailable."}
]
}
+15
View File
@@ -0,0 +1,15 @@
{
"schemaVersion": 1,
"id": "probe-scale-300",
"name": "Three hundred bounded probes",
"description": "A synthetic 300-probe set is scheduled with bounded concurrency, duplicate suppression, cancellation and deterministic result ordering.",
"initialState": {"probes": {"count": 300, "maxConcurrent": 16, "maxAttempts": 2}},
"timeline": [
{"atSeconds": 1, "action": "set-probe-result", "payload": {"probeId": "probe-000", "state": "up", "responseTimeMs": 8}},
{"atSeconds": 2, "action": "set-probe-result", "payload": {"probeId": "probe-299", "state": "unknown", "errorClass": "timeout"}}
],
"expectedOutcomes": [
{"bySeconds": 2, "assertion": "All 300 probes are bounded by the worker pool and results are returned in deterministic probe ID order."},
{"bySeconds": 2, "assertion": "A duplicate in-flight probe is skipped rather than overlapping, and timeout/retry attempts remain bounded."}
]
}
+50
View File
@@ -0,0 +1,50 @@
{
"schemaVersion": 1,
"id": "prometheus-stale",
"name": "Prometheus becomes stale",
"description": "Tests that missing current metrics become Unknown rather than remaining healthy.",
"initialState": {
"sources": {
"prometheus": "healthy"
},
"host": {
"status": "operational",
"cpuPercent": 20
}
},
"timeline": [
{
"atSeconds": 0,
"action": "set-metric",
"payload": {
"metric": "host.cpu.utilization",
"value": 20
}
},
{
"atSeconds": 30,
"action": "disconnect",
"payload": {
"source": "prometheus"
}
}
],
"expectedOutcomes": [
{
"bySeconds": 90,
"assertion": "Prometheus datasource is delayed or stale according to policy."
},
{
"bySeconds": 180,
"assertion": "Required metric-derived host state is unknown, not operational."
},
{
"bySeconds": 180,
"assertion": "A datasource alert exists without resolving unrelated existing firing alerts."
},
{
"bySeconds": 190,
"assertion": "Previous values, if shown, include their age."
}
]
}
@@ -0,0 +1,53 @@
{
"schemaVersion": 1,
"id": "service-down-container-running",
"name": "Service down while container runs",
"description": "Proves application health is independent from Docker running state.",
"initialState": {
"container": {
"id": "fixture-app",
"status": "running"
},
"service": {
"id": "fixture-http",
"status": "up",
"latencyMs": 80
}
},
"timeline": [
{
"atSeconds": 30,
"action": "set-probe-result",
"payload": {
"probe": "fixture-http",
"success": false,
"statusCode": 503,
"latencyMs": 150
}
},
{
"atSeconds": 240,
"action": "set-probe-result",
"payload": {
"probe": "fixture-http",
"success": true,
"statusCode": 200,
"latencyMs": 90
}
}
],
"expectedOutcomes": [
{
"bySeconds": 150,
"assertion": "Service and parent application are degraded while the container remains running."
},
{
"bySeconds": 150,
"assertion": "Service alert fires after pending duration."
},
{
"bySeconds": 330,
"assertion": "Alert and incident resolve after successful recovery duration."
}
]
}
+21
View File
@@ -0,0 +1,21 @@
{
"schemaVersion": 1,
"id": "share-growth",
"name": "Share growth and cache relation",
"description": "A bounded share-size history grows across array and cache placement without enumerating file content.",
"initialState": {
"share": {
"id": "fixture-media",
"usedBytes": 500000000000,
"cachePool": "cache",
"primaryPool": "array"
}
},
"timeline": [
{"atSeconds": 86400, "action": "set-metric", "payload": {"metric": "storage.share.used_bytes", "entity": "fixture-media", "value": 700000000000}}
],
"expectedOutcomes": [
{"bySeconds": 86400, "assertion": "Growth history reports a positive 200000000000 byte change per day."},
{"bySeconds": 86400, "assertion": "Cache/pool relation remains visible and no file names or content are returned."}
]
}
+37
View File
@@ -0,0 +1,37 @@
{
"schemaVersion": 1,
"id": "smart-warning",
"name": "SMART warning",
"description": "A disk reports pending sectors while overall generic status may still be ambiguous.",
"initialState": {
"disk": {
"id": "fixture-disk5",
"smartOverall": "passed",
"pendingSectors": 0
}
},
"timeline": [
{
"atSeconds": 30,
"action": "set-entity-status",
"payload": {
"entity": "fixture-disk5",
"status": "attention",
"facts": {
"pendingSectors": 2,
"smartOverall": "passed"
}
}
}
],
"expectedOutcomes": [
{
"bySeconds": 90,
"assertion": "Disk status is attention or degraded with an explicit pending-sector reason."
},
{
"bySeconds": 90,
"assertion": "UI does not reduce the state to generic SMART passed."
}
]
}
@@ -0,0 +1,12 @@
{
"schemaVersion": 1,
"id": "storage-map-heatmap",
"name": "Storage map and temperature heatmap",
"description": "A 40-disk storage view remains readable with explicit text states and a table alternative.",
"initialState": {"disks": {"count": 40, "temperaturePoints": 40}},
"timeline": [{"atSeconds": 60, "action": "set-metric", "payload": {"metric": "storage.disk.temperature", "entity": "disk-7", "value": 52}}],
"expectedOutcomes": [
{"bySeconds": 60, "assertion": "All 40 disk temperature points remain bounded and the elevated disk has a textual attention state."},
{"bySeconds": 60, "assertion": "Storage map and heatmap retain table/text alternatives and drill-down links."}
]
}
+52
View File
@@ -0,0 +1,52 @@
{
"schemaVersion": 1,
"id": "ups-on-battery",
"name": "UPS on battery",
"description": "Optional UPS source changes power state.",
"initialState": {
"ups": {
"available": true,
"status": "online",
"chargePercent": 100,
"runtimeSeconds": 3600
}
},
"timeline": [
{
"atSeconds": 30,
"action": "set-entity-status",
"payload": {
"entity": "fixture-ups",
"status": "attention",
"facts": {
"powerState": "on-battery",
"chargePercent": 96,
"runtimeSeconds": 3300
}
}
},
{
"atSeconds": 300,
"action": "set-entity-status",
"payload": {
"entity": "fixture-ups",
"status": "operational",
"facts": {
"powerState": "online",
"chargePercent": 95,
"runtimeSeconds": 3500
}
}
}
],
"expectedOutcomes": [
{
"bySeconds": 60,
"assertion": "UPS is attention with on-battery reason and runtime shown."
},
{
"bySeconds": 360,
"assertion": "Recovery is recorded as an event."
}
]
}
@@ -0,0 +1,43 @@
{
"schemaVersion": 1,
"id": "websocket-slow-client",
"name": "Slow live client",
"description": "A client cannot consume every live sample.",
"initialState": {
"live": {
"subscriptions": 50,
"intervalSeconds": 1
}
},
"timeline": [
{
"atSeconds": 30,
"action": "slow-client",
"payload": {
"client": "fixture-wallboard",
"consumeDelayMs": 5000
}
},
{
"atSeconds": 120,
"action": "reconnect",
"payload": {
"client": "fixture-wallboard"
}
}
],
"expectedOutcomes": [
{
"bySeconds": 60,
"assertion": "Server coalesces/drops intermediate non-critical samples without unbounded queue growth."
},
{
"bySeconds": 140,
"assertion": "Client resynchronizes using sequence/status protocol."
},
{
"bySeconds": 180,
"assertion": "Subscription count returns to expected value with no duplicate streams."
}
]
}