@ocpp-debugkit/toolkit 0.2.1 → 0.3.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 +234 -12
- package/dist/cli/commands/anonymize.d.ts +15 -0
- package/dist/cli/commands/anonymize.d.ts.map +1 -0
- package/dist/cli/commands/anonymize.js +104 -0
- package/dist/cli/commands/anonymize.js.map +1 -0
- package/dist/cli/commands/ci.d.ts +10 -0
- package/dist/cli/commands/ci.d.ts.map +1 -0
- package/dist/cli/commands/ci.js +96 -0
- package/dist/cli/commands/ci.js.map +1 -0
- package/dist/cli/commands/diff.d.ts +10 -0
- package/dist/cli/commands/diff.d.ts.map +1 -0
- package/dist/cli/commands/diff.js +71 -0
- package/dist/cli/commands/diff.js.map +1 -0
- package/dist/cli/index.js +27 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/assertions.d.ts +36 -0
- package/dist/core/assertions.d.ts.map +1 -0
- package/dist/core/assertions.js +335 -0
- package/dist/core/assertions.js.map +1 -0
- package/dist/core/detection.d.ts +9 -1
- package/dist/core/detection.d.ts.map +1 -1
- package/dist/core/detection.js +344 -1
- package/dist/core/detection.js.map +1 -1
- package/dist/core/diff.d.ts +68 -0
- package/dist/core/diff.d.ts.map +1 -0
- package/dist/core/diff.js +199 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/types.d.ts +77 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/scenarios/__scenarios__/heartbeat-irregular.d.ts +51 -0
- package/dist/scenarios/__scenarios__/heartbeat-irregular.d.ts.map +1 -0
- package/dist/scenarios/__scenarios__/heartbeat-irregular.js +81 -0
- package/dist/scenarios/__scenarios__/heartbeat-irregular.js.map +1 -0
- package/dist/scenarios/__scenarios__/meter-anomaly.d.ts +115 -0
- package/dist/scenarios/__scenarios__/meter-anomaly.d.ts.map +1 -0
- package/dist/scenarios/__scenarios__/meter-anomaly.js +152 -0
- package/dist/scenarios/__scenarios__/meter-anomaly.js.map +1 -0
- package/dist/scenarios/__scenarios__/short-session.d.ts +111 -0
- package/dist/scenarios/__scenarios__/short-session.d.ts.map +1 -0
- package/dist/scenarios/__scenarios__/short-session.js +129 -0
- package/dist/scenarios/__scenarios__/short-session.js.map +1 -0
- package/dist/scenarios/__scenarios__/slow-csms-response.d.ts +52 -0
- package/dist/scenarios/__scenarios__/slow-csms-response.d.ts.map +1 -0
- package/dist/scenarios/__scenarios__/slow-csms-response.js +61 -0
- package/dist/scenarios/__scenarios__/slow-csms-response.js.map +1 -0
- package/dist/scenarios/__scenarios__/unexpected-start.js +3 -3
- package/dist/scenarios/__scenarios__/unresponsive-csms.d.ts +53 -0
- package/dist/scenarios/__scenarios__/unresponsive-csms.d.ts.map +1 -0
- package/dist/scenarios/__scenarios__/unresponsive-csms.js +53 -0
- package/dist/scenarios/__scenarios__/unresponsive-csms.js.map +1 -0
- package/dist/scenarios/compare.d.ts +39 -0
- package/dist/scenarios/compare.d.ts.map +1 -0
- package/dist/scenarios/compare.js +77 -0
- package/dist/scenarios/compare.js.map +1 -0
- package/dist/scenarios/index.d.ts +10 -3
- package/dist/scenarios/index.d.ts.map +1 -1
- package/dist/scenarios/index.js +22 -1
- package/dist/scenarios/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scenario assertions — declarative assertions for scenario evaluation.
|
|
3
|
+
*
|
|
4
|
+
* Supports 8 assertion types:
|
|
5
|
+
* - event_order: verify events appear in a specific order
|
|
6
|
+
* - event_count: verify the count of events (optionally filtered by action)
|
|
7
|
+
* - payload_field: verify a payload field value on a specific action
|
|
8
|
+
* - timing: verify timing gaps between two actions
|
|
9
|
+
* - session_state: verify session status
|
|
10
|
+
* - failure_severity: verify a specific failure has the expected severity
|
|
11
|
+
* - no_failures: verify no failures are detected
|
|
12
|
+
* - failure_count: verify the count of detected failures
|
|
13
|
+
*
|
|
14
|
+
* @module @ocpp-debugkit/toolkit/core
|
|
15
|
+
*/
|
|
16
|
+
import type { AssertionResult, Event, Failure, Scenario, ScenarioAssertion, ScenarioEvalResult, Session } from './types.js';
|
|
17
|
+
/** Input for assertion evaluation. */
|
|
18
|
+
export interface AssertionContext {
|
|
19
|
+
events: Event[];
|
|
20
|
+
sessions: Session[];
|
|
21
|
+
failures: Failure[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Evaluate a single assertion against the analysis context.
|
|
25
|
+
*/
|
|
26
|
+
export declare function runAssertion(assertion: ScenarioAssertion, ctx: AssertionContext): AssertionResult;
|
|
27
|
+
/**
|
|
28
|
+
* Evaluate multiple assertions against the analysis context.
|
|
29
|
+
*/
|
|
30
|
+
export declare function runAssertions(ctx: AssertionContext, assertions: ScenarioAssertion[]): AssertionResult[];
|
|
31
|
+
/**
|
|
32
|
+
* Evaluate a scenario: parse the trace, run detection, evaluate assertions,
|
|
33
|
+
* and compare detected vs expected failures.
|
|
34
|
+
*/
|
|
35
|
+
export declare function evaluateScenario(scenario: Scenario): ScenarioEvalResult;
|
|
36
|
+
//# sourceMappingURL=assertions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../../src/core/assertions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,KAAK,EACL,OAAO,EAGP,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAClB,OAAO,EACR,MAAM,YAAY,CAAC;AA+CpB,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,iBAAiB,EAAE,GAAG,EAAE,gBAAgB,GAAG,eAAe,CAyBjG;AA+RD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,gBAAgB,EACrB,UAAU,EAAE,iBAAiB,EAAE,GAC9B,eAAe,EAAE,CAEnB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,kBAAkB,CA4BvE"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scenario assertions — declarative assertions for scenario evaluation.
|
|
3
|
+
*
|
|
4
|
+
* Supports 8 assertion types:
|
|
5
|
+
* - event_order: verify events appear in a specific order
|
|
6
|
+
* - event_count: verify the count of events (optionally filtered by action)
|
|
7
|
+
* - payload_field: verify a payload field value on a specific action
|
|
8
|
+
* - timing: verify timing gaps between two actions
|
|
9
|
+
* - session_state: verify session status
|
|
10
|
+
* - failure_severity: verify a specific failure has the expected severity
|
|
11
|
+
* - no_failures: verify no failures are detected
|
|
12
|
+
* - failure_count: verify the count of detected failures
|
|
13
|
+
*
|
|
14
|
+
* @module @ocpp-debugkit/toolkit/core
|
|
15
|
+
*/
|
|
16
|
+
import { parseTrace } from './parser.js';
|
|
17
|
+
import { buildSessionTimeline } from './timeline.js';
|
|
18
|
+
import { detectFailures } from './detection.js';
|
|
19
|
+
import { summarizeSessions } from './summarizer.js';
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Deep equality (same limited implementation as diff.ts)
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
function deepEqual(a, b) {
|
|
24
|
+
if (a === b)
|
|
25
|
+
return true;
|
|
26
|
+
if (a === null || b === null)
|
|
27
|
+
return false;
|
|
28
|
+
if (typeof a !== typeof b)
|
|
29
|
+
return false;
|
|
30
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
31
|
+
if (a.length !== b.length)
|
|
32
|
+
return false;
|
|
33
|
+
return a.every((item, i) => deepEqual(item, b[i]));
|
|
34
|
+
}
|
|
35
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
36
|
+
const objA = a;
|
|
37
|
+
const objB = b;
|
|
38
|
+
const keysA = Object.keys(objA);
|
|
39
|
+
const keysB = Object.keys(objB);
|
|
40
|
+
if (keysA.length !== keysB.length)
|
|
41
|
+
return false;
|
|
42
|
+
return keysA.every((key) => deepEqual(objA[key], objB[key]));
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
/** Safely access a nested field via dot notation (e.g., "idTagInfo.status"). */
|
|
47
|
+
function getNestedValue(obj, path) {
|
|
48
|
+
const parts = path.split('.');
|
|
49
|
+
let current = obj;
|
|
50
|
+
for (const part of parts) {
|
|
51
|
+
if (current === null || typeof current !== 'object')
|
|
52
|
+
return undefined;
|
|
53
|
+
current = current[part];
|
|
54
|
+
}
|
|
55
|
+
return current;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Evaluate a single assertion against the analysis context.
|
|
59
|
+
*/
|
|
60
|
+
export function runAssertion(assertion, ctx) {
|
|
61
|
+
switch (assertion.type) {
|
|
62
|
+
case 'event_order':
|
|
63
|
+
return evalEventOrder(assertion, ctx);
|
|
64
|
+
case 'event_count':
|
|
65
|
+
return evalEventCount(assertion, ctx);
|
|
66
|
+
case 'payload_field':
|
|
67
|
+
return evalPayloadField(assertion, ctx);
|
|
68
|
+
case 'timing':
|
|
69
|
+
return evalTiming(assertion, ctx);
|
|
70
|
+
case 'session_state':
|
|
71
|
+
return evalSessionState(assertion, ctx);
|
|
72
|
+
case 'failure_severity':
|
|
73
|
+
return evalFailureSeverity(assertion, ctx);
|
|
74
|
+
case 'no_failures':
|
|
75
|
+
return evalNoFailures(assertion, ctx);
|
|
76
|
+
case 'failure_count':
|
|
77
|
+
return evalFailureCount(assertion, ctx);
|
|
78
|
+
default:
|
|
79
|
+
return {
|
|
80
|
+
assertion,
|
|
81
|
+
passed: false,
|
|
82
|
+
message: `Unknown assertion type: ${assertion.type}`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function evalEventOrder(assertion, ctx) {
|
|
87
|
+
const { actions } = assertion.params;
|
|
88
|
+
const callActions = ctx.events
|
|
89
|
+
.filter((e) => e.messageType === 'Call' && e.action !== null)
|
|
90
|
+
.map((e) => e.action);
|
|
91
|
+
// Check if actions appear in order (not necessarily consecutive)
|
|
92
|
+
let searchFrom = 0;
|
|
93
|
+
for (const action of actions) {
|
|
94
|
+
const foundIndex = callActions.indexOf(action, searchFrom);
|
|
95
|
+
if (foundIndex === -1) {
|
|
96
|
+
return {
|
|
97
|
+
assertion,
|
|
98
|
+
passed: false,
|
|
99
|
+
message: `Expected action "${action}" in order after previous actions, but not found`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
searchFrom = foundIndex + 1;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
assertion,
|
|
106
|
+
passed: true,
|
|
107
|
+
message: `Actions [${actions.join(', ')}] appear in the correct order`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function evalEventCount(assertion, ctx) {
|
|
111
|
+
const { min, max, action } = assertion.params;
|
|
112
|
+
const count = action
|
|
113
|
+
? ctx.events.filter((e) => e.messageType === 'Call' && e.action === action).length
|
|
114
|
+
: ctx.events.length;
|
|
115
|
+
if (min !== undefined && count < min) {
|
|
116
|
+
return {
|
|
117
|
+
assertion,
|
|
118
|
+
passed: false,
|
|
119
|
+
message: `Expected at least ${min} ${action ? `"${action}" ` : ''}events, got ${count}`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (max !== undefined && count > max) {
|
|
123
|
+
return {
|
|
124
|
+
assertion,
|
|
125
|
+
passed: false,
|
|
126
|
+
message: `Expected at most ${max} ${action ? `"${action}" ` : ''}events, got ${count}`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
assertion,
|
|
131
|
+
passed: true,
|
|
132
|
+
message: `Event count ${count} is within range [${min ?? 0}, ${max ?? '∞'}]${action ? ` for "${action}"` : ''}`,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function evalPayloadField(assertion, ctx) {
|
|
136
|
+
const { action, field, equals, contains } = assertion.params;
|
|
137
|
+
const matchingEvents = ctx.events.filter((e) => e.messageType === 'Call' && e.action === action);
|
|
138
|
+
if (matchingEvents.length === 0) {
|
|
139
|
+
return {
|
|
140
|
+
assertion,
|
|
141
|
+
passed: false,
|
|
142
|
+
message: `No events with action "${action}" found`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
for (const event of matchingEvents) {
|
|
146
|
+
const value = getNestedValue(event.payload, field);
|
|
147
|
+
if (value === undefined) {
|
|
148
|
+
return {
|
|
149
|
+
assertion,
|
|
150
|
+
passed: false,
|
|
151
|
+
message: `Field "${field}" not found in payload of "${action}" event`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (equals !== undefined && !deepEqual(value, equals)) {
|
|
155
|
+
return {
|
|
156
|
+
assertion,
|
|
157
|
+
passed: false,
|
|
158
|
+
message: `Field "${field}" in "${action}" expected to equal ${JSON.stringify(equals)}, got ${JSON.stringify(value)}`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
if (contains !== undefined) {
|
|
162
|
+
if (Array.isArray(value) && !value.some((v) => deepEqual(v, contains))) {
|
|
163
|
+
return {
|
|
164
|
+
assertion,
|
|
165
|
+
passed: false,
|
|
166
|
+
message: `Field "${field}" in "${action}" expected to contain ${JSON.stringify(contains)}, got ${JSON.stringify(value)}`,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (typeof value === 'string' && !value.includes(String(contains))) {
|
|
170
|
+
return {
|
|
171
|
+
assertion,
|
|
172
|
+
passed: false,
|
|
173
|
+
message: `Field "${field}" in "${action}" expected to contain "${contains}", got "${value}"`,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
assertion,
|
|
180
|
+
passed: true,
|
|
181
|
+
message: `Payload field "${field}" in "${action}" matches expectations`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function evalTiming(assertion, ctx) {
|
|
185
|
+
const { actionA, actionB, maxGapMs, minGapMs } = assertion.params;
|
|
186
|
+
const eventA = ctx.events.find((e) => e.messageType === 'Call' && e.action === actionA && e.timestamp !== null);
|
|
187
|
+
const eventB = ctx.events.find((e) => e.messageType === 'Call' && e.action === actionB && e.timestamp !== null);
|
|
188
|
+
if (!eventA || eventA.timestamp === null) {
|
|
189
|
+
return {
|
|
190
|
+
assertion,
|
|
191
|
+
passed: false,
|
|
192
|
+
message: `Action "${actionA}" not found or has no timestamp`,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (!eventB || eventB.timestamp === null) {
|
|
196
|
+
return {
|
|
197
|
+
assertion,
|
|
198
|
+
passed: false,
|
|
199
|
+
message: `Action "${actionB}" not found or has no timestamp`,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const gap = eventB.timestamp - eventA.timestamp;
|
|
203
|
+
if (maxGapMs !== undefined && gap > maxGapMs) {
|
|
204
|
+
return {
|
|
205
|
+
assertion,
|
|
206
|
+
passed: false,
|
|
207
|
+
message: `Gap between "${actionA}" and "${actionB}" is ${gap}ms, exceeds max ${maxGapMs}ms`,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
if (minGapMs !== undefined && gap < minGapMs) {
|
|
211
|
+
return {
|
|
212
|
+
assertion,
|
|
213
|
+
passed: false,
|
|
214
|
+
message: `Gap between "${actionA}" and "${actionB}" is ${gap}ms, below min ${minGapMs}ms`,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
assertion,
|
|
219
|
+
passed: true,
|
|
220
|
+
message: `Gap between "${actionA}" and "${actionB}" is ${gap}ms (within range)`,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function evalSessionState(assertion, ctx) {
|
|
224
|
+
const { expected } = assertion.params;
|
|
225
|
+
if (ctx.sessions.length === 0) {
|
|
226
|
+
return { assertion, passed: false, message: 'No sessions found' };
|
|
227
|
+
}
|
|
228
|
+
for (const session of ctx.sessions) {
|
|
229
|
+
if (session.status !== expected) {
|
|
230
|
+
return {
|
|
231
|
+
assertion,
|
|
232
|
+
passed: false,
|
|
233
|
+
message: `Session ${session.sessionId} has status "${session.status}", expected "${expected}"`,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
assertion,
|
|
239
|
+
passed: true,
|
|
240
|
+
message: `All sessions have status "${expected}"`,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
function evalFailureSeverity(assertion, ctx) {
|
|
244
|
+
const { code, severity } = assertion.params;
|
|
245
|
+
const matching = ctx.failures.find((f) => f.code === code);
|
|
246
|
+
if (!matching) {
|
|
247
|
+
return {
|
|
248
|
+
assertion,
|
|
249
|
+
passed: false,
|
|
250
|
+
message: `Failure with code "${code}" not detected`,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
if (matching.severity !== severity) {
|
|
254
|
+
return {
|
|
255
|
+
assertion,
|
|
256
|
+
passed: false,
|
|
257
|
+
message: `Failure "${code}" has severity "${matching.severity}", expected "${severity}"`,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
assertion,
|
|
262
|
+
passed: true,
|
|
263
|
+
message: `Failure "${code}" has severity "${severity}" as expected`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function evalNoFailures(assertion, ctx) {
|
|
267
|
+
if (ctx.failures.length > 0) {
|
|
268
|
+
return {
|
|
269
|
+
assertion,
|
|
270
|
+
passed: false,
|
|
271
|
+
message: `Expected no failures, but ${ctx.failures.length} detected: ${ctx.failures.map((f) => f.code).join(', ')}`,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return { assertion, passed: true, message: 'No failures detected as expected' };
|
|
275
|
+
}
|
|
276
|
+
function evalFailureCount(assertion, ctx) {
|
|
277
|
+
const { min, max, code } = assertion.params;
|
|
278
|
+
const count = code ? ctx.failures.filter((f) => f.code === code).length : ctx.failures.length;
|
|
279
|
+
if (min !== undefined && count < min) {
|
|
280
|
+
return {
|
|
281
|
+
assertion,
|
|
282
|
+
passed: false,
|
|
283
|
+
message: `Expected at least ${min} ${code ? `"${code}" ` : ''}failures, got ${count}`,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
if (max !== undefined && count > max) {
|
|
287
|
+
return {
|
|
288
|
+
assertion,
|
|
289
|
+
passed: false,
|
|
290
|
+
message: `Expected at most ${max} ${code ? `"${code}" ` : ''}failures, got ${count}`,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
assertion,
|
|
295
|
+
passed: true,
|
|
296
|
+
message: `Failure count ${count} ${code ? `for "${code}" ` : ''}is within range [${min ?? 0}, ${max ?? '∞'}]`,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
// Batch evaluation
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
/**
|
|
303
|
+
* Evaluate multiple assertions against the analysis context.
|
|
304
|
+
*/
|
|
305
|
+
export function runAssertions(ctx, assertions) {
|
|
306
|
+
return assertions.map((assertion) => runAssertion(assertion, ctx));
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Evaluate a scenario: parse the trace, run detection, evaluate assertions,
|
|
310
|
+
* and compare detected vs expected failures.
|
|
311
|
+
*/
|
|
312
|
+
export function evaluateScenario(scenario) {
|
|
313
|
+
const { events } = parseTrace(JSON.stringify(scenario.trace));
|
|
314
|
+
const sessions = buildSessionTimeline(events);
|
|
315
|
+
const failures = detectFailures(events, sessions);
|
|
316
|
+
const detectedFailureCodes = [...new Set(failures.map((f) => f.code))];
|
|
317
|
+
// Compare detected vs expected failures (deduplicated)
|
|
318
|
+
const sortedDetected = [...detectedFailureCodes].sort();
|
|
319
|
+
const sortedExpected = [...scenario.expectedFailures].sort();
|
|
320
|
+
const expectedFailuresPassed = JSON.stringify(sortedDetected) === JSON.stringify(sortedExpected);
|
|
321
|
+
// Evaluate assertions
|
|
322
|
+
const ctx = { events, sessions, failures };
|
|
323
|
+
const assertions = scenario.assertions ? runAssertions(ctx, scenario.assertions) : [];
|
|
324
|
+
// Use summaries to ensure sessions are properly evaluated
|
|
325
|
+
summarizeSessions(sessions, failures);
|
|
326
|
+
const allPassed = expectedFailuresPassed && (assertions.length === 0 || assertions.every((a) => a.passed));
|
|
327
|
+
return {
|
|
328
|
+
assertions,
|
|
329
|
+
allPassed,
|
|
330
|
+
failures,
|
|
331
|
+
detectedFailureCodes,
|
|
332
|
+
expectedFailuresPassed,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=assertions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertions.js","sourceRoot":"","sources":["../../src/core/assertions.ts"],"names":[],"mappings":"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"}
|
package/dist/core/detection.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Failure detection — analyzes events and sessions for known failure patterns.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 16 detection rules (v0.1 + v0.2 + v0.3):
|
|
5
5
|
*
|
|
6
6
|
* v0.1:
|
|
7
7
|
* 1. FAILED_AUTHORIZATION — Authorize response with idTagInfo.status = "Invalid"
|
|
@@ -17,6 +17,14 @@
|
|
|
17
17
|
* 9. DIAGNOSTICS_FAILURE — DiagnosticsStatusNotification indicating failure
|
|
18
18
|
* 10. FIRMWARE_UPDATE_FAILURE — FirmwareStatusNotification indicating failure
|
|
19
19
|
*
|
|
20
|
+
* v0.3:
|
|
21
|
+
* 11. SUSPICIOUS_SESSION_DURATION — session < 60s or > 24h
|
|
22
|
+
* 12. SLOW_RESPONSE — gap between Call and matching CallResult/CallError > 10s
|
|
23
|
+
* 13. HEARTBEAT_INTERVAL_VIOLATION — heartbeat intervals deviate >50% from expected
|
|
24
|
+
* 14. METER_VALUE_ANOMALY — non-monotonic or negative meter readings
|
|
25
|
+
* 15. UNRESPONSIVE_CSMS — Call with no matching CallResult or CallError
|
|
26
|
+
* 16. REPEATED_BOOT_NOTIFICATION — 2+ BootNotification calls within 5 minutes
|
|
27
|
+
*
|
|
20
28
|
* @see ADR-0003
|
|
21
29
|
*/
|
|
22
30
|
import type { Event, Failure, Session } from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../src/core/detection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../src/core/detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAgC,OAAO,EAAE,MAAM,YAAY,CAAC;AAyUxF;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CA0B9E"}
|