deepdebug-local-agent 1.6.0 → 1.8.0
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/docs/la-protocol-v2.md +41 -11
- package/env.example +10 -1
- package/package.json +1 -1
- package/scripts/incident-parity/Gen.java +256 -0
- package/scripts/incident-parity/LogEntry.java +17 -0
- package/scripts/incident-parity/extract.py +51 -0
- package/scripts/incident-parity/gen.sh +32 -0
- package/src/incident-detector/README.md +51 -0
- package/src/incident-detector/aggregator.js +73 -0
- package/src/incident-detector/categorize.js +48 -0
- package/src/incident-detector/config.js +95 -0
- package/src/incident-detector/detector.js +92 -0
- package/src/incident-detector/emitter.js +154 -0
- package/src/incident-detector/index.js +44 -0
- package/src/incident-detector/java-compat.js +66 -0
- package/src/incident-detector/normalize.js +209 -0
- package/src/incident-detector/parse.js +114 -0
- package/src/incident-detector/sources/file-source.js +113 -0
- package/src/incident-detector/sources/loki-source.js +101 -0
- package/src/incident-detector/sources/stream-source.js +39 -0
- package/src/incident-detector/store.js +119 -0
- package/src/la-protocol-v2/content-handlers/config.js +3 -1
- package/src/la-protocol-v2/content-handlers/content-index.js +54 -19
- package/src/la-protocol-v2/content-handlers/egress.js +22 -0
- package/src/la-protocol-v2/content-handlers/file-list.js +174 -0
- package/src/la-protocol-v2/content-handlers/git-diff.js +43 -8
- package/src/la-protocol-v2/content-handlers/handler.js +28 -4
- package/src/la-protocol-v2/content-handlers/install.js +24 -19
- package/src/la-protocol-v2/content-handlers/path-guard.js +74 -5
- package/src/la-protocol-v2/content-handlers/ref-registry.js +18 -8
- package/src/la-protocol-v2/contract/CONTRACT_SOURCE.json +10 -8
- package/src/la-protocol-v2/contract/README.md +38 -0
- package/src/la-protocol-v2/contract/content.index.schema.json +1 -0
- package/src/la-protocol-v2/contract/content.request.schema.json +1 -0
- package/src/la-protocol-v2/contract/file.list.body.schema.json +69 -0
- package/src/la-protocol-v2/contract.js +9 -0
- package/src/la-protocol-v2/runtime.js +11 -2
- package/test/contract/la-protocol-v2/vectors/content.index.vectors.json +32 -0
- package/test/contract/la-protocol-v2/vectors/content.request.vectors.json +215 -0
- package/test/contract/la-protocol-v2/vectors/content.response.vectors.json +30 -0
- package/test/contract/la-protocol-v2/vectors/file.list.body.vectors.json +1645 -0
- package/test/incident-detector/parity.test.js +66 -0
- package/test/incident-detector/parity.vectors.json +2619 -0
- package/test/incident-detector/sources.test.js +179 -0
- package/test/incident-detector/units.test.js +430 -0
- package/test/incident-detector/wiring.test.js +165 -0
- package/test/la-protocol-v2/content-alignment.test.js +71 -10
- package/test/la-protocol-v2/content-deny-list.test.js +138 -0
- package/test/la-protocol-v2/content-diff-symlink.test.js +83 -0
- package/test/la-protocol-v2/content-file-list.test.js +385 -0
- package/test/la-protocol-v2/content-path-guard.test.js +1 -1
- package/test/la-protocol-v2/content-wiring.test.js +2 -2
- package/test/la-protocol-v2/contract.test.js +14 -4
- package/tools/interop/LaV2NodeFileListE2ETest.java +369 -0
- package/tools/interop/README.md +16 -0
- package/tools/interop/la-interop-list-client.mjs +93 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* F3-11b: the Node detector against vectors generated from the Java code (scripts/incident-parity/gen.sh).
|
|
3
|
+
* Every field of every case must match byte for byte: errorHash (group hash), group key, fingerprint, errorType, first user
|
|
4
|
+
* frame, normalised message/frame, significance, noise class; and the natural-key dedup (LogEntryDedup).
|
|
5
|
+
*/
|
|
6
|
+
import { test } from "node:test";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
import {
|
|
12
|
+
computeGroupHash, normalizeGroupKey, computeFingerprint, extractErrorType, extractFirstUserFrame, normaliseMessage, normaliseFrame,
|
|
13
|
+
isSignificant, classifyNoise, naturalKey,
|
|
14
|
+
} from "../../src/incident-detector/normalize.js";
|
|
15
|
+
|
|
16
|
+
const VECTORS = JSON.parse(fs.readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), "parity.vectors.json"), "utf8"));
|
|
17
|
+
const nl = (v) => (v === undefined ? null : v);
|
|
18
|
+
|
|
19
|
+
test("the vector file says where it came from and is big enough to mean something", () => {
|
|
20
|
+
assert.equal(VECTORS.schema, "incident-parity-vectors/1");
|
|
21
|
+
assert.match(VECTORS.source.commit, /^[0-9a-f]{40}$/);
|
|
22
|
+
assert.ok(Object.keys(VECTORS.source.files).length >= 5);
|
|
23
|
+
assert.ok(VECTORS.cases.length >= 100, `${VECTORS.cases.length} cases`);
|
|
24
|
+
assert.ok(VECTORS.dedup.length >= 5);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
for (const c of VECTORS.cases) {
|
|
28
|
+
test(`parity: ${c.name}`, () => {
|
|
29
|
+
const e = c.expect;
|
|
30
|
+
const message = nl(c.message);
|
|
31
|
+
const stack = nl(c.stack);
|
|
32
|
+
assert.equal(isSignificant({ severity: c.severity, message, stacktrace: stack }), e.significant, "significant");
|
|
33
|
+
assert.equal(normalizeGroupKey(message == null ? "" : message.split("\n")[0]), e.groupKey, "groupKey");
|
|
34
|
+
assert.equal(computeGroupHash(message), e.groupHash, "errorHash");
|
|
35
|
+
assert.equal(extractErrorType(message, stack), e.errorType, "errorType");
|
|
36
|
+
assert.equal(extractFirstUserFrame(stack), e.firstFrame, "firstFrame");
|
|
37
|
+
assert.equal(normaliseMessage(message), e.normalisedMessage, "normalisedMessage");
|
|
38
|
+
assert.equal(normaliseFrame(e.firstFrame), e.normalisedFrame, "normalisedFrame");
|
|
39
|
+
assert.equal(computeFingerprint(message, stack), e.fingerprint, "fingerprint");
|
|
40
|
+
assert.equal(classifyNoise(message), e.noiseClass, "noiseClass");
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const d of VECTORS.dedup) {
|
|
45
|
+
test(`parity dedup: ${d.name}`, () => {
|
|
46
|
+
const nanos = (iso) => {
|
|
47
|
+
if (iso == null) return null;
|
|
48
|
+
const m = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,9}))?Z$/.exec(iso);
|
|
49
|
+
assert.ok(m, iso);
|
|
50
|
+
return BigInt(Date.parse(`${m[1]}Z`)) * 1_000_000n + BigInt((m[2] || "").padEnd(9, "0"));
|
|
51
|
+
};
|
|
52
|
+
const keys = d.entries.map((x) => naturalKey(x.service, nanos(x.ts), x.message));
|
|
53
|
+
assert.deepEqual(keys, d.keys, "natural keys");
|
|
54
|
+
// filterNew: drop what is known or repeated inside the batch; an entry without a key is always kept
|
|
55
|
+
const known = new Set(d.known);
|
|
56
|
+
const seen = new Set();
|
|
57
|
+
const kept = [];
|
|
58
|
+
keys.forEach((k, i) => {
|
|
59
|
+
if (k == null) { kept.push(i); return; }
|
|
60
|
+
if (known.has(k) || seen.has(k)) return;
|
|
61
|
+
seen.add(k);
|
|
62
|
+
kept.push(i);
|
|
63
|
+
});
|
|
64
|
+
assert.deepEqual(kept, d.kept, "kept entries");
|
|
65
|
+
});
|
|
66
|
+
}
|