qa360 1.4.5 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/commands/ai.d.ts +41 -0
- package/dist/commands/ai.js +499 -0
- package/dist/commands/ask.js +12 -12
- package/dist/commands/coverage.d.ts +8 -0
- package/dist/commands/coverage.js +252 -0
- package/dist/commands/explain.d.ts +27 -0
- package/dist/commands/explain.js +630 -0
- package/dist/commands/flakiness.d.ts +73 -0
- package/dist/commands/flakiness.js +435 -0
- package/dist/commands/generate.d.ts +66 -0
- package/dist/commands/generate.js +438 -0
- package/dist/commands/init.d.ts +56 -9
- package/dist/commands/init.js +217 -10
- package/dist/commands/monitor.d.ts +27 -0
- package/dist/commands/monitor.js +225 -0
- package/dist/commands/ollama.d.ts +40 -0
- package/dist/commands/ollama.js +301 -0
- package/dist/commands/pack.d.ts +37 -9
- package/dist/commands/pack.js +240 -141
- package/dist/commands/regression.d.ts +8 -0
- package/dist/commands/regression.js +340 -0
- package/dist/commands/repair.d.ts +26 -0
- package/dist/commands/repair.js +307 -0
- package/dist/commands/retry.d.ts +43 -0
- package/dist/commands/retry.js +275 -0
- package/dist/commands/run.d.ts +8 -3
- package/dist/commands/run.js +45 -31
- package/dist/commands/slo.d.ts +8 -0
- package/dist/commands/slo.js +327 -0
- package/dist/core/adapters/playwright-native-api.d.ts +183 -0
- package/dist/core/adapters/playwright-native-api.js +461 -0
- package/dist/core/adapters/playwright-ui.d.ts +7 -0
- package/dist/core/adapters/playwright-ui.js +29 -1
- package/dist/core/ai/anthropic-provider.d.ts +50 -0
- package/dist/core/ai/anthropic-provider.js +211 -0
- package/dist/core/ai/deepseek-provider.d.ts +81 -0
- package/dist/core/ai/deepseek-provider.js +254 -0
- package/dist/core/ai/index.d.ts +60 -0
- package/dist/core/ai/index.js +18 -0
- package/dist/core/ai/llm-client.d.ts +45 -0
- package/dist/core/ai/llm-client.js +7 -0
- package/dist/core/ai/mock-provider.d.ts +49 -0
- package/dist/core/ai/mock-provider.js +121 -0
- package/dist/core/ai/ollama-provider.d.ts +78 -0
- package/dist/core/ai/ollama-provider.js +192 -0
- package/dist/core/ai/openai-provider.d.ts +48 -0
- package/dist/core/ai/openai-provider.js +188 -0
- package/dist/core/ai/provider-factory.d.ts +160 -0
- package/dist/core/ai/provider-factory.js +269 -0
- package/dist/core/auth/api-key-provider.d.ts +16 -0
- package/dist/core/auth/api-key-provider.js +63 -0
- package/dist/core/auth/aws-iam-provider.d.ts +35 -0
- package/dist/core/auth/aws-iam-provider.js +177 -0
- package/dist/core/auth/azure-ad-provider.d.ts +15 -0
- package/dist/core/auth/azure-ad-provider.js +99 -0
- package/dist/core/auth/basic-auth-provider.d.ts +26 -0
- package/dist/core/auth/basic-auth-provider.js +111 -0
- package/dist/core/auth/gcp-adc-provider.d.ts +27 -0
- package/dist/core/auth/gcp-adc-provider.js +126 -0
- package/dist/core/auth/index.d.ts +238 -0
- package/dist/core/auth/index.js +82 -0
- package/dist/core/auth/jwt-provider.d.ts +19 -0
- package/dist/core/auth/jwt-provider.js +160 -0
- package/dist/core/auth/manager.d.ts +84 -0
- package/dist/core/auth/manager.js +230 -0
- package/dist/core/auth/oauth2-provider.d.ts +17 -0
- package/dist/core/auth/oauth2-provider.js +114 -0
- package/dist/core/auth/totp-provider.d.ts +31 -0
- package/dist/core/auth/totp-provider.js +134 -0
- package/dist/core/auth/ui-login-provider.d.ts +26 -0
- package/dist/core/auth/ui-login-provider.js +198 -0
- package/dist/core/cache/index.d.ts +7 -0
- package/dist/core/cache/index.js +6 -0
- package/dist/core/cache/lru-cache.d.ts +203 -0
- package/dist/core/cache/lru-cache.js +397 -0
- package/dist/core/coverage/analyzer.d.ts +101 -0
- package/dist/core/coverage/analyzer.js +415 -0
- package/dist/core/coverage/collector.d.ts +74 -0
- package/dist/core/coverage/collector.js +459 -0
- package/dist/core/coverage/config.d.ts +37 -0
- package/dist/core/coverage/config.js +156 -0
- package/dist/core/coverage/index.d.ts +11 -0
- package/dist/core/coverage/index.js +15 -0
- package/dist/core/coverage/types.d.ts +267 -0
- package/dist/core/coverage/types.js +6 -0
- package/dist/core/coverage/vault.d.ts +95 -0
- package/dist/core/coverage/vault.js +405 -0
- package/dist/core/dashboard/assets.d.ts +6 -0
- package/dist/core/dashboard/assets.js +690 -0
- package/dist/core/dashboard/index.d.ts +6 -0
- package/dist/core/dashboard/index.js +5 -0
- package/dist/core/dashboard/server.d.ts +72 -0
- package/dist/core/dashboard/server.js +354 -0
- package/dist/core/dashboard/types.d.ts +70 -0
- package/dist/core/dashboard/types.js +5 -0
- package/dist/core/discoverer/index.d.ts +115 -0
- package/dist/core/discoverer/index.js +250 -0
- package/dist/core/flakiness/index.d.ts +228 -0
- package/dist/core/flakiness/index.js +384 -0
- package/dist/core/generation/code-formatter.d.ts +111 -0
- package/dist/core/generation/code-formatter.js +307 -0
- package/dist/core/generation/code-generator.d.ts +144 -0
- package/dist/core/generation/code-generator.js +293 -0
- package/dist/core/generation/generator.d.ts +40 -0
- package/dist/core/generation/generator.js +76 -0
- package/dist/core/generation/index.d.ts +30 -0
- package/dist/core/generation/index.js +28 -0
- package/dist/core/generation/pack-generator.d.ts +107 -0
- package/dist/core/generation/pack-generator.js +416 -0
- package/dist/core/generation/prompt-builder.d.ts +132 -0
- package/dist/core/generation/prompt-builder.js +672 -0
- package/dist/core/generation/source-analyzer.d.ts +213 -0
- package/dist/core/generation/source-analyzer.js +657 -0
- package/dist/core/generation/test-optimizer.d.ts +117 -0
- package/dist/core/generation/test-optimizer.js +328 -0
- package/dist/core/generation/types.d.ts +214 -0
- package/dist/core/generation/types.js +4 -0
- package/dist/core/index.d.ts +23 -1
- package/dist/core/index.js +39 -0
- package/dist/core/pack/validator.js +31 -1
- package/dist/core/pack-v2/index.d.ts +9 -0
- package/dist/core/pack-v2/index.js +8 -0
- package/dist/core/pack-v2/loader.d.ts +62 -0
- package/dist/core/pack-v2/loader.js +231 -0
- package/dist/core/pack-v2/migrator.d.ts +56 -0
- package/dist/core/pack-v2/migrator.js +455 -0
- package/dist/core/pack-v2/validator.d.ts +61 -0
- package/dist/core/pack-v2/validator.js +577 -0
- package/dist/core/regression/detector.d.ts +107 -0
- package/dist/core/regression/detector.js +497 -0
- package/dist/core/regression/index.d.ts +9 -0
- package/dist/core/regression/index.js +11 -0
- package/dist/core/regression/trend-analyzer.d.ts +102 -0
- package/dist/core/regression/trend-analyzer.js +345 -0
- package/dist/core/regression/types.d.ts +222 -0
- package/dist/core/regression/types.js +7 -0
- package/dist/core/regression/vault.d.ts +87 -0
- package/dist/core/regression/vault.js +289 -0
- package/dist/core/repair/engine/fixer.d.ts +24 -0
- package/dist/core/repair/engine/fixer.js +226 -0
- package/dist/core/repair/engine/suggestion-engine.d.ts +18 -0
- package/dist/core/repair/engine/suggestion-engine.js +187 -0
- package/dist/core/repair/index.d.ts +10 -0
- package/dist/core/repair/index.js +13 -0
- package/dist/core/repair/repairer.d.ts +90 -0
- package/dist/core/repair/repairer.js +284 -0
- package/dist/core/repair/types.d.ts +91 -0
- package/dist/core/repair/types.js +6 -0
- package/dist/core/repair/utils/error-analyzer.d.ts +28 -0
- package/dist/core/repair/utils/error-analyzer.js +264 -0
- package/dist/core/retry/flakiness-integration.d.ts +60 -0
- package/dist/core/retry/flakiness-integration.js +228 -0
- package/dist/core/retry/index.d.ts +14 -0
- package/dist/core/retry/index.js +16 -0
- package/dist/core/retry/retry-engine.d.ts +80 -0
- package/dist/core/retry/retry-engine.js +296 -0
- package/dist/core/retry/types.d.ts +178 -0
- package/dist/core/retry/types.js +52 -0
- package/dist/core/retry/vault.d.ts +77 -0
- package/dist/core/retry/vault.js +304 -0
- package/dist/core/runner/e2e-helpers.d.ts +102 -0
- package/dist/core/runner/e2e-helpers.js +153 -0
- package/dist/core/runner/phase3-runner.d.ts +101 -2
- package/dist/core/runner/phase3-runner.js +559 -24
- package/dist/core/self-healing/assertion-healer.d.ts +97 -0
- package/dist/core/self-healing/assertion-healer.js +371 -0
- package/dist/core/self-healing/engine.d.ts +122 -0
- package/dist/core/self-healing/engine.js +538 -0
- package/dist/core/self-healing/index.d.ts +10 -0
- package/dist/core/self-healing/index.js +11 -0
- package/dist/core/self-healing/selector-healer.d.ts +103 -0
- package/dist/core/self-healing/selector-healer.js +372 -0
- package/dist/core/self-healing/types.d.ts +152 -0
- package/dist/core/self-healing/types.js +6 -0
- package/dist/core/slo/config.d.ts +107 -0
- package/dist/core/slo/config.js +360 -0
- package/dist/core/slo/index.d.ts +11 -0
- package/dist/core/slo/index.js +15 -0
- package/dist/core/slo/sli-calculator.d.ts +92 -0
- package/dist/core/slo/sli-calculator.js +364 -0
- package/dist/core/slo/slo-tracker.d.ts +148 -0
- package/dist/core/slo/slo-tracker.js +379 -0
- package/dist/core/slo/types.d.ts +281 -0
- package/dist/core/slo/types.js +7 -0
- package/dist/core/slo/vault.d.ts +102 -0
- package/dist/core/slo/vault.js +427 -0
- package/dist/core/tui/index.d.ts +7 -0
- package/dist/core/tui/index.js +6 -0
- package/dist/core/tui/monitor.d.ts +92 -0
- package/dist/core/tui/monitor.js +271 -0
- package/dist/core/tui/renderer.d.ts +33 -0
- package/dist/core/tui/renderer.js +218 -0
- package/dist/core/tui/types.d.ts +63 -0
- package/dist/core/tui/types.js +5 -0
- package/dist/core/types/pack-v2.d.ts +425 -0
- package/dist/core/types/pack-v2.js +8 -0
- package/dist/core/vault/index.d.ts +116 -0
- package/dist/core/vault/index.js +400 -5
- package/dist/core/watch/index.d.ts +7 -0
- package/dist/core/watch/index.js +6 -0
- package/dist/core/watch/watch-mode.d.ts +213 -0
- package/dist/core/watch/watch-mode.js +389 -0
- package/dist/index.js +68 -68
- package/dist/utils/config.d.ts +5 -0
- package/dist/utils/config.js +136 -0
- package/package.json +5 -1
- package/dist/core/adapters/playwright-api.d.ts +0 -82
- package/dist/core/adapters/playwright-api.js +0 -264
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SLO/SLI Default Configuration
|
|
3
|
+
*
|
|
4
|
+
* Predefined SLOs and SLIs for common quality metrics.
|
|
5
|
+
* Factory functions for creating standard configurations.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from 'crypto';
|
|
8
|
+
/**
|
|
9
|
+
* Default time windows in milliseconds
|
|
10
|
+
*/
|
|
11
|
+
export const TimeWindows = {
|
|
12
|
+
HOUR: 60 * 60 * 1000,
|
|
13
|
+
DAY: 24 * 60 * 60 * 1000,
|
|
14
|
+
WEEK: 7 * 24 * 60 * 60 * 1000,
|
|
15
|
+
MONTH: 30 * 24 * 60 * 60 * 1000,
|
|
16
|
+
QUARTER: 90 * 24 * 60 * 60 * 1000
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Create default SLO configuration
|
|
20
|
+
*/
|
|
21
|
+
export function createDefaultSLOConfig() {
|
|
22
|
+
return {
|
|
23
|
+
enabled: true,
|
|
24
|
+
defaultWindowMs: TimeWindows.MONTH,
|
|
25
|
+
defaultOnExhaustion: 'alert_only',
|
|
26
|
+
alertThresholds: {
|
|
27
|
+
warning: 50, // Alert at 50% budget used
|
|
28
|
+
critical: 80 // Critical alert at 80% budget used
|
|
29
|
+
},
|
|
30
|
+
retention: {
|
|
31
|
+
measurements: 90, // Keep raw measurements for 90 days
|
|
32
|
+
aggregated: 365 // Keep aggregated data for 1 year
|
|
33
|
+
},
|
|
34
|
+
slos: [
|
|
35
|
+
createDefaultTestQualitySLO(),
|
|
36
|
+
createDefaultAPISuccessSLO(),
|
|
37
|
+
createDefaultPerformanceSLO()
|
|
38
|
+
],
|
|
39
|
+
slis: [
|
|
40
|
+
createTestPassRateSLI(),
|
|
41
|
+
createAPISuccessRateSLI(),
|
|
42
|
+
createLatencySLI()
|
|
43
|
+
]
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create strict SLO configuration (enterprise/production)
|
|
48
|
+
*/
|
|
49
|
+
export function createStrictSLOConfig() {
|
|
50
|
+
const config = createDefaultSLOConfig();
|
|
51
|
+
config.slos = [
|
|
52
|
+
createStrictTestQualitySLO(),
|
|
53
|
+
createStrictAPISuccessSLO(),
|
|
54
|
+
createStrictPerformanceSLO()
|
|
55
|
+
];
|
|
56
|
+
config.alertThresholds = {
|
|
57
|
+
warning: 20,
|
|
58
|
+
critical: 50
|
|
59
|
+
};
|
|
60
|
+
return config;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Create relaxed SLO configuration (development)
|
|
64
|
+
*/
|
|
65
|
+
export function createRelaxedSLOConfig() {
|
|
66
|
+
const config = createDefaultSLOConfig();
|
|
67
|
+
config.slos = [
|
|
68
|
+
createRelaxedTestQualitySLO(),
|
|
69
|
+
createRelaxedAPISuccessSLO(),
|
|
70
|
+
createRelaxedPerformanceSLO()
|
|
71
|
+
];
|
|
72
|
+
config.alertThresholds = {
|
|
73
|
+
warning: 70,
|
|
74
|
+
critical: 90
|
|
75
|
+
};
|
|
76
|
+
return config;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Default: Test Quality SLO (95% pass rate over 30 days)
|
|
80
|
+
*/
|
|
81
|
+
export function createDefaultTestQualitySLO() {
|
|
82
|
+
const sliId = `sli_test_pass_rate_${randomUUID().slice(0, 8)}`;
|
|
83
|
+
return {
|
|
84
|
+
id: `slo_test_quality_${randomUUID().slice(0, 8)}`,
|
|
85
|
+
name: 'Test Quality',
|
|
86
|
+
description: 'Percentage of tests passing across all gates',
|
|
87
|
+
sliIds: [sliId],
|
|
88
|
+
target: 95,
|
|
89
|
+
windowMs: TimeWindows.WEEK,
|
|
90
|
+
errorBudget: {
|
|
91
|
+
initialBudget: 5,
|
|
92
|
+
remainingBudget: 5,
|
|
93
|
+
alertThresholds: {
|
|
94
|
+
warning: 2,
|
|
95
|
+
critical: 5
|
|
96
|
+
},
|
|
97
|
+
onExhaustion: 'alert_only'
|
|
98
|
+
},
|
|
99
|
+
status: 'unknown',
|
|
100
|
+
tags: ['quality', 'testing'],
|
|
101
|
+
owner: 'qa',
|
|
102
|
+
createdAt: Date.now(),
|
|
103
|
+
updatedAt: Date.now()
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Default: API Success Rate SLO (99.9% over 30 days)
|
|
108
|
+
*/
|
|
109
|
+
export function createDefaultAPISuccessSLO() {
|
|
110
|
+
const sliId = `sli_api_success_${randomUUID().slice(0, 8)}`;
|
|
111
|
+
return {
|
|
112
|
+
id: `slo_api_success_${randomUUID().slice(0, 8)}`,
|
|
113
|
+
name: 'API Success Rate',
|
|
114
|
+
description: 'Percentage of successful API requests',
|
|
115
|
+
sliIds: [sliId],
|
|
116
|
+
target: 99.9,
|
|
117
|
+
windowMs: TimeWindows.MONTH,
|
|
118
|
+
errorBudget: {
|
|
119
|
+
initialBudget: 0.1,
|
|
120
|
+
remainingBudget: 0.1,
|
|
121
|
+
alertThresholds: {
|
|
122
|
+
warning: 2,
|
|
123
|
+
critical: 5
|
|
124
|
+
},
|
|
125
|
+
onExhaustion: 'alert_only'
|
|
126
|
+
},
|
|
127
|
+
status: 'unknown',
|
|
128
|
+
tags: ['api', 'reliability'],
|
|
129
|
+
owner: 'backend',
|
|
130
|
+
createdAt: Date.now(),
|
|
131
|
+
updatedAt: Date.now()
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Default: Performance SLO (p95 latency < 500ms)
|
|
136
|
+
*/
|
|
137
|
+
export function createDefaultPerformanceSLO() {
|
|
138
|
+
const sliId = `sli_latency_p95_${randomUUID().slice(0, 8)}`;
|
|
139
|
+
return {
|
|
140
|
+
id: `slo_performance_${randomUUID().slice(0, 8)}`,
|
|
141
|
+
name: 'API Latency (p95)',
|
|
142
|
+
description: '95th percentile response time for API requests',
|
|
143
|
+
sliIds: [sliId],
|
|
144
|
+
target: 95, // Interpreted as "95% of requests under threshold"
|
|
145
|
+
windowMs: TimeWindows.WEEK,
|
|
146
|
+
errorBudget: {
|
|
147
|
+
initialBudget: 5,
|
|
148
|
+
remainingBudget: 5,
|
|
149
|
+
alertThresholds: {
|
|
150
|
+
warning: 2,
|
|
151
|
+
critical: 5
|
|
152
|
+
},
|
|
153
|
+
onExhaustion: 'alert_only'
|
|
154
|
+
},
|
|
155
|
+
status: 'unknown',
|
|
156
|
+
tags: ['performance', 'latency'],
|
|
157
|
+
owner: 'backend',
|
|
158
|
+
createdAt: Date.now(),
|
|
159
|
+
updatedAt: Date.now()
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Strict: Test Quality SLO (98% pass rate)
|
|
164
|
+
*/
|
|
165
|
+
export function createStrictTestQualitySLO() {
|
|
166
|
+
const slo = createDefaultTestQualitySLO();
|
|
167
|
+
slo.id = `slo_test_quality_strict_${randomUUID().slice(0, 8)}`;
|
|
168
|
+
slo.target = 98;
|
|
169
|
+
slo.errorBudget.initialBudget = 2;
|
|
170
|
+
slo.errorBudget.remainingBudget = 2;
|
|
171
|
+
slo.tags = [...(slo.tags || []), 'strict'];
|
|
172
|
+
return slo;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Strict: API Success Rate SLO (99.95%)
|
|
176
|
+
*/
|
|
177
|
+
export function createStrictAPISuccessSLO() {
|
|
178
|
+
const slo = createDefaultAPISuccessSLO();
|
|
179
|
+
slo.id = `slo_api_success_strict_${randomUUID().slice(0, 8)}`;
|
|
180
|
+
slo.target = 99.95;
|
|
181
|
+
slo.errorBudget.initialBudget = 0.05;
|
|
182
|
+
slo.errorBudget.remainingBudget = 0.05;
|
|
183
|
+
slo.tags = [...(slo.tags || []), 'strict'];
|
|
184
|
+
return slo;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Strict: Performance SLO (p95 latency < 200ms)
|
|
188
|
+
*/
|
|
189
|
+
export function createStrictPerformanceSLO() {
|
|
190
|
+
const slo = createDefaultPerformanceSLO();
|
|
191
|
+
slo.id = `slo_performance_strict_${randomUUID().slice(0, 8)}`;
|
|
192
|
+
slo.target = 98;
|
|
193
|
+
slo.errorBudget.initialBudget = 2;
|
|
194
|
+
slo.errorBudget.remainingBudget = 2;
|
|
195
|
+
slo.tags = [...(slo.tags || []), 'strict'];
|
|
196
|
+
return slo;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Relaxed: Test Quality SLO (90% pass rate)
|
|
200
|
+
*/
|
|
201
|
+
export function createRelaxedTestQualitySLO() {
|
|
202
|
+
const slo = createDefaultTestQualitySLO();
|
|
203
|
+
slo.id = `slo_test_quality_relaxed_${randomUUID().slice(0, 8)}`;
|
|
204
|
+
slo.target = 90;
|
|
205
|
+
slo.errorBudget.initialBudget = 10;
|
|
206
|
+
slo.errorBudget.remainingBudget = 10;
|
|
207
|
+
slo.tags = [...(slo.tags || []), 'relaxed'];
|
|
208
|
+
return slo;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Relaxed: API Success Rate SLO (99%)
|
|
212
|
+
*/
|
|
213
|
+
export function createRelaxedAPISuccessSLO() {
|
|
214
|
+
const slo = createDefaultAPISuccessSLO();
|
|
215
|
+
slo.id = `slo_api_success_relaxed_${randomUUID().slice(0, 8)}`;
|
|
216
|
+
slo.target = 99;
|
|
217
|
+
slo.errorBudget.initialBudget = 1;
|
|
218
|
+
slo.errorBudget.remainingBudget = 1;
|
|
219
|
+
slo.tags = [...(slo.tags || []), 'relaxed'];
|
|
220
|
+
return slo;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Relaxed: Performance SLO (p95 latency < 1000ms)
|
|
224
|
+
*/
|
|
225
|
+
export function createRelaxedPerformanceSLO() {
|
|
226
|
+
const slo = createDefaultPerformanceSLO();
|
|
227
|
+
slo.id = `slo_performance_relaxed_${randomUUID().slice(0, 8)}`;
|
|
228
|
+
slo.target = 90;
|
|
229
|
+
slo.errorBudget.initialBudget = 10;
|
|
230
|
+
slo.errorBudget.remainingBudget = 10;
|
|
231
|
+
slo.tags = [...(slo.tags || []), 'relaxed'];
|
|
232
|
+
return slo;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* SLI: Test Pass Rate
|
|
236
|
+
*/
|
|
237
|
+
export function createTestPassRateSLI() {
|
|
238
|
+
return {
|
|
239
|
+
id: `sli_test_pass_rate_${randomUUID().slice(0, 8)}`,
|
|
240
|
+
name: 'Test Pass Rate',
|
|
241
|
+
description: 'Percentage of tests that pass',
|
|
242
|
+
type: 'quality',
|
|
243
|
+
source: 'qa360_tests',
|
|
244
|
+
query: {
|
|
245
|
+
queryString: 'test_results',
|
|
246
|
+
timeWindow: { value: 1, unit: 'd' }
|
|
247
|
+
},
|
|
248
|
+
aggregation: 'ratio',
|
|
249
|
+
unit: 'percentage',
|
|
250
|
+
threshold: {
|
|
251
|
+
operator: 'gte',
|
|
252
|
+
value: 95
|
|
253
|
+
},
|
|
254
|
+
category: 'quality',
|
|
255
|
+
tags: ['quality', 'testing'],
|
|
256
|
+
createdAt: Date.now(),
|
|
257
|
+
updatedAt: Date.now()
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* SLI: API Success Rate
|
|
262
|
+
*/
|
|
263
|
+
export function createAPISuccessRateSLI() {
|
|
264
|
+
return {
|
|
265
|
+
id: `sli_api_success_${randomUUID().slice(0, 8)}`,
|
|
266
|
+
name: 'API Success Rate',
|
|
267
|
+
description: 'Percentage of successful API requests',
|
|
268
|
+
type: 'availability',
|
|
269
|
+
source: 'qa360_tests',
|
|
270
|
+
query: {
|
|
271
|
+
queryString: 'api_smoke_results',
|
|
272
|
+
timeWindow: { value: 1, unit: 'd' }
|
|
273
|
+
},
|
|
274
|
+
aggregation: 'ratio',
|
|
275
|
+
unit: 'percentage',
|
|
276
|
+
threshold: {
|
|
277
|
+
operator: 'gte',
|
|
278
|
+
value: 99.9
|
|
279
|
+
},
|
|
280
|
+
category: 'reliability',
|
|
281
|
+
tags: ['api', 'reliability'],
|
|
282
|
+
createdAt: Date.now(),
|
|
283
|
+
updatedAt: Date.now()
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* SLI: Latency (p95)
|
|
288
|
+
*/
|
|
289
|
+
export function createLatencySLI() {
|
|
290
|
+
return {
|
|
291
|
+
id: `sli_latency_p95_${randomUUID().slice(0, 8)}`,
|
|
292
|
+
name: 'API Latency p95',
|
|
293
|
+
description: '95th percentile API response time',
|
|
294
|
+
type: 'latency',
|
|
295
|
+
source: 'qa360_tests',
|
|
296
|
+
query: {
|
|
297
|
+
queryString: 'api_latency',
|
|
298
|
+
timeWindow: { value: 1, unit: 'd' }
|
|
299
|
+
},
|
|
300
|
+
aggregation: 'p95',
|
|
301
|
+
unit: 'milliseconds',
|
|
302
|
+
threshold: {
|
|
303
|
+
operator: 'lte',
|
|
304
|
+
value: 500
|
|
305
|
+
},
|
|
306
|
+
category: 'performance',
|
|
307
|
+
tags: ['performance', 'latency'],
|
|
308
|
+
createdAt: Date.now(),
|
|
309
|
+
updatedAt: Date.now()
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Create custom SLO from parameters
|
|
314
|
+
*/
|
|
315
|
+
export function createCustomSLO(params) {
|
|
316
|
+
return {
|
|
317
|
+
id: `slo_custom_${randomUUID().slice(0, 8)}`,
|
|
318
|
+
name: params.name,
|
|
319
|
+
description: params.description,
|
|
320
|
+
sliIds: params.sliIds,
|
|
321
|
+
target: params.target,
|
|
322
|
+
windowMs: params.windowMs || TimeWindows.MONTH,
|
|
323
|
+
errorBudget: {
|
|
324
|
+
initialBudget: 100 - params.target,
|
|
325
|
+
remainingBudget: 100 - params.target,
|
|
326
|
+
alertThresholds: {
|
|
327
|
+
warning: 2,
|
|
328
|
+
critical: 5
|
|
329
|
+
},
|
|
330
|
+
onExhaustion: 'alert_only'
|
|
331
|
+
},
|
|
332
|
+
status: 'unknown',
|
|
333
|
+
tags: params.tags || ['custom'],
|
|
334
|
+
owner: params.owner,
|
|
335
|
+
createdAt: Date.now(),
|
|
336
|
+
updatedAt: Date.now()
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Create custom SLI from parameters
|
|
341
|
+
*/
|
|
342
|
+
export function createCustomSLI(params) {
|
|
343
|
+
return {
|
|
344
|
+
id: `sli_custom_${randomUUID().slice(0, 8)}`,
|
|
345
|
+
name: params.name,
|
|
346
|
+
description: params.description,
|
|
347
|
+
type: params.type,
|
|
348
|
+
source: params.source,
|
|
349
|
+
query: {
|
|
350
|
+
queryString: params.queryString
|
|
351
|
+
},
|
|
352
|
+
aggregation: params.aggregation,
|
|
353
|
+
unit: params.unit,
|
|
354
|
+
threshold: params.threshold,
|
|
355
|
+
category: params.category || 'custom',
|
|
356
|
+
tags: params.tags || ['custom'],
|
|
357
|
+
createdAt: Date.now(),
|
|
358
|
+
updatedAt: Date.now()
|
|
359
|
+
};
|
|
360
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 SLO/SLI Management Module
|
|
3
|
+
*
|
|
4
|
+
* Exports all SLO/SLI functionality.
|
|
5
|
+
*/
|
|
6
|
+
export type { SLO, SLI, SLIMeasurement, SLOReport, SLOStatus, SLOResult, ErrorBudget, BurnRate, SLOConfig, SLOViolation, SLIType, SLISource, SLIQuery, SLIAggregation, SLIUnit, SLIThreshold, SLICategory } from './types.js';
|
|
7
|
+
export { TimeWindows, createDefaultSLOConfig, createStrictSLOConfig, createRelaxedSLOConfig, createDefaultTestQualitySLO, createDefaultAPISuccessSLO, createDefaultPerformanceSLO, createStrictTestQualitySLO, createStrictAPISuccessSLO, createStrictPerformanceSLO, createRelaxedTestQualitySLO, createRelaxedAPISuccessSLO, createRelaxedPerformanceSLO, createTestPassRateSLI, createAPISuccessRateSLI, createLatencySLI, createCustomSLO, createCustomSLI } from './config.js';
|
|
8
|
+
export { SLICalculator, createSLICalculator } from './sli-calculator.js';
|
|
9
|
+
export { SLOTracker, createSLOTracker, type SLOTrackerOptions, type SLOAlert } from './slo-tracker.js';
|
|
10
|
+
export { SLOVault } from './vault.js';
|
|
11
|
+
export { createDefaultSLOConfig as createSLOConfig } from './config.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 SLO/SLI Management Module
|
|
3
|
+
*
|
|
4
|
+
* Exports all SLO/SLI functionality.
|
|
5
|
+
*/
|
|
6
|
+
// Config
|
|
7
|
+
export { TimeWindows, createDefaultSLOConfig, createStrictSLOConfig, createRelaxedSLOConfig, createDefaultTestQualitySLO, createDefaultAPISuccessSLO, createDefaultPerformanceSLO, createStrictTestQualitySLO, createStrictAPISuccessSLO, createStrictPerformanceSLO, createRelaxedTestQualitySLO, createRelaxedAPISuccessSLO, createRelaxedPerformanceSLO, createTestPassRateSLI, createAPISuccessRateSLI, createLatencySLI, createCustomSLO, createCustomSLI } from './config.js';
|
|
8
|
+
// Calculator
|
|
9
|
+
export { SLICalculator, createSLICalculator } from './sli-calculator.js';
|
|
10
|
+
// Tracker
|
|
11
|
+
export { SLOTracker, createSLOTracker } from './slo-tracker.js';
|
|
12
|
+
// Vault integration
|
|
13
|
+
export { SLOVault } from './vault.js';
|
|
14
|
+
// Re-exports for convenience
|
|
15
|
+
export { createDefaultSLOConfig as createSLOConfig } from './config.js';
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SLI Calculator
|
|
3
|
+
*
|
|
4
|
+
* Calculates Service Level Indicators from various data sources.
|
|
5
|
+
* Supports ratio-based, threshold-based, and percentile-based SLIs.
|
|
6
|
+
*/
|
|
7
|
+
import type { SLI, SLIMeasurement, SLIAggregation, SLOStatus, BurnRate } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Event data for ratio calculation
|
|
10
|
+
*/
|
|
11
|
+
export interface GoodBadEvents {
|
|
12
|
+
good: number;
|
|
13
|
+
bad: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Time series data point
|
|
17
|
+
*/
|
|
18
|
+
export interface TimeSeriesPoint {
|
|
19
|
+
timestamp: number;
|
|
20
|
+
value: number;
|
|
21
|
+
success?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* SLI Calculator class
|
|
25
|
+
*/
|
|
26
|
+
export declare class SLICalculator {
|
|
27
|
+
/**
|
|
28
|
+
* Calculate SLI from good/bad events (ratio-based)
|
|
29
|
+
*/
|
|
30
|
+
calculateFromEvents(sli: SLI, events: GoodBadEvents): SLIMeasurement;
|
|
31
|
+
/**
|
|
32
|
+
* Calculate SLI from time series data
|
|
33
|
+
*/
|
|
34
|
+
calculateFromTimeSeries(sli: SLI, data: TimeSeriesPoint[], windowMs: number): SLIMeasurement;
|
|
35
|
+
/**
|
|
36
|
+
* Calculate SLI from QA360 test results
|
|
37
|
+
*/
|
|
38
|
+
calculateFromTestResults(sli: SLI, results: {
|
|
39
|
+
total: number;
|
|
40
|
+
passed: number;
|
|
41
|
+
failed: number;
|
|
42
|
+
skipped: number;
|
|
43
|
+
}): SLIMeasurement;
|
|
44
|
+
/**
|
|
45
|
+
* Calculate SLI from latency measurements
|
|
46
|
+
*/
|
|
47
|
+
calculateLatency(sli: SLI, latencies: number[], percentile?: 'p50' | 'p95' | 'p99' | 'p99_9'): SLIMeasurement;
|
|
48
|
+
/**
|
|
49
|
+
* Calculate multiple SLIs from a single data source
|
|
50
|
+
*/
|
|
51
|
+
calculateBatch(slis: SLI[], data: TimeSeriesPoint[] | GoodBadEvents | {
|
|
52
|
+
total: number;
|
|
53
|
+
passed: number;
|
|
54
|
+
failed: number;
|
|
55
|
+
skipped: number;
|
|
56
|
+
}): SLIMeasurement[];
|
|
57
|
+
/**
|
|
58
|
+
* Calculate percentile value
|
|
59
|
+
*/
|
|
60
|
+
private percentile;
|
|
61
|
+
/**
|
|
62
|
+
* Parse percentile string to number
|
|
63
|
+
*/
|
|
64
|
+
private parsePercentile;
|
|
65
|
+
/**
|
|
66
|
+
* Create empty measurement
|
|
67
|
+
*/
|
|
68
|
+
private emptyMeasurement;
|
|
69
|
+
/**
|
|
70
|
+
* Aggregate measurements over time
|
|
71
|
+
*/
|
|
72
|
+
aggregateMeasurements(measurements: SLIMeasurement[], aggregation: SLIAggregation): SLIMeasurement;
|
|
73
|
+
/**
|
|
74
|
+
* Check if measurement meets threshold
|
|
75
|
+
*/
|
|
76
|
+
meetsThreshold(measurement: SLIMeasurement, threshold: {
|
|
77
|
+
operator: string;
|
|
78
|
+
value: number;
|
|
79
|
+
}): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Calculate burn rate for error budget
|
|
82
|
+
*/
|
|
83
|
+
calculateBurnRate(measurements: SLIMeasurement[], target: number, windowMs: number): BurnRate;
|
|
84
|
+
/**
|
|
85
|
+
* Determine SLO status from current value and target
|
|
86
|
+
*/
|
|
87
|
+
determineStatus(current: number, target: number, warningThreshold?: number): SLOStatus;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Create an SLI calculator
|
|
91
|
+
*/
|
|
92
|
+
export declare function createSLICalculator(): SLICalculator;
|