@matter/testing 0.17.9 → 0.18.0-alpha.0-20260812-4d7f2790e
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/dist/cjs/chai.js +4 -4
- package/dist/cjs/chai.js.map +2 -2
- package/dist/cjs/chip/cert/cert-context.d.ts +115 -0
- package/dist/cjs/chip/cert/cert-context.d.ts.map +1 -0
- package/dist/cjs/chip/cert/cert-context.js +22 -0
- package/dist/cjs/chip/cert/cert-context.js.map +6 -0
- package/dist/cjs/chip/cert/cert-dsl.d.ts +48 -0
- package/dist/cjs/chip/cert/cert-dsl.d.ts.map +1 -0
- package/dist/cjs/chip/cert/cert-dsl.js +308 -0
- package/dist/cjs/chip/cert/cert-dsl.js.map +6 -0
- package/dist/cjs/chip/cert/cert-test.d.ts +46 -0
- package/dist/cjs/chip/cert/cert-test.d.ts.map +1 -0
- package/dist/cjs/chip/cert/cert-test.js +250 -0
- package/dist/cjs/chip/cert/cert-test.js.map +6 -0
- package/dist/cjs/chip/cert/chip-app-subject.d.ts +80 -0
- package/dist/cjs/chip/cert/chip-app-subject.d.ts.map +1 -0
- package/dist/cjs/chip/cert/chip-app-subject.js +337 -0
- package/dist/cjs/chip/cert/chip-app-subject.js.map +6 -0
- package/dist/cjs/chip/cert/controller-adapter.d.ts +119 -0
- package/dist/cjs/chip/cert/controller-adapter.d.ts.map +1 -0
- package/dist/cjs/chip/cert/controller-adapter.js +45 -0
- package/dist/cjs/chip/cert/controller-adapter.js.map +6 -0
- package/dist/cjs/chip/cert/device-config.d.ts +15 -0
- package/dist/cjs/chip/cert/device-config.d.ts.map +1 -0
- package/dist/cjs/chip/cert/device-config.js +43 -0
- package/dist/cjs/chip/cert/device-config.js.map +6 -0
- package/dist/cjs/chip/cert/evidence.d.ts +70 -0
- package/dist/cjs/chip/cert/evidence.d.ts.map +1 -0
- package/dist/cjs/chip/cert/evidence.js +128 -0
- package/dist/cjs/chip/cert/evidence.js.map +6 -0
- package/dist/cjs/chip/cert/log-follower.d.ts +96 -0
- package/dist/cjs/chip/cert/log-follower.d.ts.map +1 -0
- package/dist/cjs/chip/cert/log-follower.js +209 -0
- package/dist/cjs/chip/cert/log-follower.js.map +6 -0
- package/dist/cjs/chip/cert/matterjs-subject-registry.d.ts +22 -0
- package/dist/cjs/chip/cert/matterjs-subject-registry.d.ts.map +1 -0
- package/dist/cjs/chip/cert/matterjs-subject-registry.js +40 -0
- package/dist/cjs/chip/cert/matterjs-subject-registry.js.map +6 -0
- package/dist/cjs/chip/cert/prompt-driven-python-test.d.ts +40 -0
- package/dist/cjs/chip/cert/prompt-driven-python-test.d.ts.map +1 -0
- package/dist/cjs/chip/cert/prompt-driven-python-test.js +77 -0
- package/dist/cjs/chip/cert/prompt-driven-python-test.js.map +6 -0
- package/dist/cjs/chip/chip-bins.d.ts +132 -0
- package/dist/cjs/chip/chip-bins.d.ts.map +1 -0
- package/dist/cjs/chip/chip-bins.js +232 -0
- package/dist/cjs/chip/chip-bins.js.map +6 -0
- package/dist/cjs/chip/chip-test-common.d.ts.map +1 -1
- package/dist/cjs/chip/chip-test-common.js +1 -1
- package/dist/cjs/chip/chip-test-common.js.map +1 -1
- package/dist/cjs/chip/chip.d.ts.map +1 -1
- package/dist/cjs/chip/chip.js +1 -1
- package/dist/cjs/chip/chip.js.map +1 -1
- package/dist/cjs/chip/config.d.ts +26 -0
- package/dist/cjs/chip/config.d.ts.map +1 -1
- package/dist/cjs/chip/config.js +11 -3
- package/dist/cjs/chip/config.js.map +1 -1
- package/dist/cjs/chip/index.d.ts +26 -0
- package/dist/cjs/chip/index.d.ts.map +1 -1
- package/dist/cjs/chip/index.js +49 -0
- package/dist/cjs/chip/index.js.map +2 -2
- package/dist/cjs/chip/pics/file.d.ts +8 -0
- package/dist/cjs/chip/pics/file.d.ts.map +1 -1
- package/dist/cjs/chip/pics/file.js +4 -1
- package/dist/cjs/chip/pics/file.js.map +1 -1
- package/dist/cjs/chip/pics/source.d.ts +8 -5
- package/dist/cjs/chip/pics/source.d.ts.map +1 -1
- package/dist/cjs/chip/pics/source.js +25 -17
- package/dist/cjs/chip/pics/source.js.map +1 -1
- package/dist/cjs/chip/python-test.d.ts +12 -0
- package/dist/cjs/chip/python-test.d.ts.map +1 -1
- package/dist/cjs/chip/python-test.js +6 -4
- package/dist/cjs/chip/python-test.js.map +1 -1
- package/dist/cjs/chip/state.d.ts.map +1 -1
- package/dist/cjs/chip/state.js +24 -7
- package/dist/cjs/chip/state.js.map +1 -1
- package/dist/cjs/chip/yaml-test.js +1 -1
- package/dist/cjs/chip/yaml-test.js.map +1 -1
- package/dist/cjs/cli.d.ts.map +1 -1
- package/dist/cjs/cli.js +33 -2
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/device/backchannel.d.ts.map +1 -1
- package/dist/cjs/device/subject.d.ts.map +1 -1
- package/dist/cjs/device/test.d.ts.map +1 -1
- package/dist/cjs/docker/container.d.ts.map +1 -1
- package/dist/cjs/docker/docker.d.ts.map +1 -1
- package/dist/cjs/docker/edit.d.ts.map +1 -1
- package/dist/cjs/docker/errors.d.ts.map +1 -1
- package/dist/cjs/docker/network.d.ts.map +1 -1
- package/dist/cjs/docker/terminal.d.ts.map +1 -1
- package/dist/cjs/failure-reporter.d.ts.map +1 -1
- package/dist/cjs/global-declarations.d.js +0 -1
- package/dist/cjs/global-declarations.d.js.map +1 -1
- package/dist/cjs/global-declarations.d.ts +2 -2
- package/dist/cjs/global-definitions.js +17 -4
- package/dist/cjs/global-definitions.js.map +2 -2
- package/dist/cjs/index.d.js +2 -0
- package/dist/cjs/index.d.js.map +1 -1
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/mocha.d.ts.map +1 -1
- package/dist/cjs/mocha.js +5 -0
- package/dist/cjs/mocha.js.map +1 -1
- package/dist/cjs/mocharc.cjs +4 -3
- package/dist/cjs/options.d.ts.map +1 -1
- package/dist/cjs/print-report.js +1 -1
- package/dist/cjs/print-report.js.map +1 -1
- package/dist/cjs/test-descriptor.d.ts +1 -1
- package/dist/cjs/test-descriptor.d.ts.map +1 -1
- package/dist/cjs/text-diff.d.ts.map +1 -1
- package/dist/cjs/util/async.d.ts +30 -0
- package/dist/cjs/util/async.d.ts.map +1 -0
- package/dist/cjs/util/async.js +85 -0
- package/dist/cjs/util/async.js.map +6 -0
- package/dist/cjs/util/trace-unhandled.d.ts.map +1 -1
- package/dist/cjs/util/wtf.d.ts.map +1 -1
- package/dist/cjs/util/wtf.js +1 -1
- package/dist/cjs/util/wtf.js.map +1 -1
- package/dist/cjs/web.d.ts.map +1 -1
- package/dist/cjs/web.js +5 -1
- package/dist/cjs/web.js.map +1 -1
- package/dist/esm/chai.js +1 -1
- package/dist/esm/chai.js.map +1 -1
- package/dist/esm/chip/cert/cert-context.d.ts +115 -0
- package/dist/esm/chip/cert/cert-context.d.ts.map +1 -0
- package/dist/esm/chip/cert/cert-context.js +6 -0
- package/dist/esm/chip/cert/cert-context.js.map +6 -0
- package/dist/esm/chip/cert/cert-dsl.d.ts +48 -0
- package/dist/esm/chip/cert/cert-dsl.d.ts.map +1 -0
- package/dist/esm/chip/cert/cert-dsl.js +288 -0
- package/dist/esm/chip/cert/cert-dsl.js.map +6 -0
- package/dist/esm/chip/cert/cert-test.d.ts +46 -0
- package/dist/esm/chip/cert/cert-test.d.ts.map +1 -0
- package/dist/esm/chip/cert/cert-test.js +230 -0
- package/dist/esm/chip/cert/cert-test.js.map +6 -0
- package/dist/esm/chip/cert/chip-app-subject.d.ts +80 -0
- package/dist/esm/chip/cert/chip-app-subject.d.ts.map +1 -0
- package/dist/esm/chip/cert/chip-app-subject.js +317 -0
- package/dist/esm/chip/cert/chip-app-subject.js.map +6 -0
- package/dist/esm/chip/cert/controller-adapter.d.ts +119 -0
- package/dist/esm/chip/cert/controller-adapter.d.ts.map +1 -0
- package/dist/esm/chip/cert/controller-adapter.js +25 -0
- package/dist/esm/chip/cert/controller-adapter.js.map +6 -0
- package/dist/esm/chip/cert/device-config.d.ts +15 -0
- package/dist/esm/chip/cert/device-config.d.ts.map +1 -0
- package/dist/esm/chip/cert/device-config.js +23 -0
- package/dist/esm/chip/cert/device-config.js.map +6 -0
- package/dist/esm/chip/cert/evidence.d.ts +70 -0
- package/dist/esm/chip/cert/evidence.d.ts.map +1 -0
- package/dist/esm/chip/cert/evidence.js +108 -0
- package/dist/esm/chip/cert/evidence.js.map +6 -0
- package/dist/esm/chip/cert/log-follower.d.ts +96 -0
- package/dist/esm/chip/cert/log-follower.d.ts.map +1 -0
- package/dist/esm/chip/cert/log-follower.js +189 -0
- package/dist/esm/chip/cert/log-follower.js.map +6 -0
- package/dist/esm/chip/cert/matterjs-subject-registry.d.ts +22 -0
- package/dist/esm/chip/cert/matterjs-subject-registry.d.ts.map +1 -0
- package/dist/esm/chip/cert/matterjs-subject-registry.js +20 -0
- package/dist/esm/chip/cert/matterjs-subject-registry.js.map +6 -0
- package/dist/esm/chip/cert/prompt-driven-python-test.d.ts +40 -0
- package/dist/esm/chip/cert/prompt-driven-python-test.d.ts.map +1 -0
- package/dist/esm/chip/cert/prompt-driven-python-test.js +57 -0
- package/dist/esm/chip/cert/prompt-driven-python-test.js.map +6 -0
- package/dist/esm/chip/chip-bins.d.ts +132 -0
- package/dist/esm/chip/chip-bins.d.ts.map +1 -0
- package/dist/esm/chip/chip-bins.js +212 -0
- package/dist/esm/chip/chip-bins.js.map +6 -0
- package/dist/esm/chip/chip-test-common.d.ts.map +1 -1
- package/dist/esm/chip/chip-test-common.js +1 -1
- package/dist/esm/chip/chip-test-common.js.map +1 -1
- package/dist/esm/chip/chip.d.ts.map +1 -1
- package/dist/esm/chip/chip.js +1 -1
- package/dist/esm/chip/chip.js.map +1 -1
- package/dist/esm/chip/config.d.ts +26 -0
- package/dist/esm/chip/config.d.ts.map +1 -1
- package/dist/esm/chip/config.js +11 -3
- package/dist/esm/chip/config.js.map +1 -1
- package/dist/esm/chip/index.d.ts +26 -0
- package/dist/esm/chip/index.d.ts.map +1 -1
- package/dist/esm/chip/index.js +60 -0
- package/dist/esm/chip/index.js.map +1 -1
- package/dist/esm/chip/pics/file.d.ts +8 -0
- package/dist/esm/chip/pics/file.d.ts.map +1 -1
- package/dist/esm/chip/pics/file.js +4 -1
- package/dist/esm/chip/pics/file.js.map +1 -1
- package/dist/esm/chip/pics/source.d.ts +8 -5
- package/dist/esm/chip/pics/source.d.ts.map +1 -1
- package/dist/esm/chip/pics/source.js +24 -16
- package/dist/esm/chip/pics/source.js.map +1 -1
- package/dist/esm/chip/python-test.d.ts +12 -0
- package/dist/esm/chip/python-test.d.ts.map +1 -1
- package/dist/esm/chip/python-test.js +6 -4
- package/dist/esm/chip/python-test.js.map +1 -1
- package/dist/esm/chip/state.d.ts.map +1 -1
- package/dist/esm/chip/state.js +25 -8
- package/dist/esm/chip/state.js.map +1 -1
- package/dist/esm/chip/yaml-test.js +1 -1
- package/dist/esm/chip/yaml-test.js.map +1 -1
- package/dist/esm/cli.d.ts.map +1 -1
- package/dist/esm/cli.js +33 -2
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/device/backchannel.d.ts.map +1 -1
- package/dist/esm/device/subject.d.ts.map +1 -1
- package/dist/esm/device/test.d.ts.map +1 -1
- package/dist/esm/docker/container.d.ts.map +1 -1
- package/dist/esm/docker/docker.d.ts.map +1 -1
- package/dist/esm/docker/edit.d.ts.map +1 -1
- package/dist/esm/docker/errors.d.ts.map +1 -1
- package/dist/esm/docker/network.d.ts.map +1 -1
- package/dist/esm/docker/terminal.d.ts.map +1 -1
- package/dist/esm/failure-reporter.d.ts.map +1 -1
- package/dist/esm/global-declarations.d.js +0 -1
- package/dist/esm/global-declarations.d.js.map +1 -1
- package/dist/esm/global-declarations.d.ts +2 -2
- package/dist/esm/global-definitions.js +16 -3
- package/dist/esm/global-definitions.js.map +1 -1
- package/dist/esm/index.d.js +2 -0
- package/dist/esm/index.d.js.map +1 -1
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mocha.d.ts.map +1 -1
- package/dist/esm/mocha.js +5 -0
- package/dist/esm/mocha.js.map +1 -1
- package/dist/esm/mocharc.cjs +4 -3
- package/dist/esm/options.d.ts.map +1 -1
- package/dist/esm/print-report.js +1 -1
- package/dist/esm/print-report.js.map +1 -1
- package/dist/esm/test-descriptor.d.ts +1 -1
- package/dist/esm/test-descriptor.d.ts.map +1 -1
- package/dist/esm/text-diff.d.ts.map +1 -1
- package/dist/esm/util/async.d.ts +30 -0
- package/dist/esm/util/async.d.ts.map +1 -0
- package/dist/esm/util/async.js +65 -0
- package/dist/esm/util/async.js.map +6 -0
- package/dist/esm/util/trace-unhandled.d.ts.map +1 -1
- package/dist/esm/util/wtf.d.ts.map +1 -1
- package/dist/esm/util/wtf.js +1 -1
- package/dist/esm/util/wtf.js.map +1 -1
- package/dist/esm/web.d.ts.map +1 -1
- package/dist/esm/web.js +5 -1
- package/dist/esm/web.js.map +1 -1
- package/package.json +9 -9
- package/src/chai.ts +3 -3
- package/src/chip/cert/cert-context.ts +126 -0
- package/src/chip/cert/cert-dsl.ts +451 -0
- package/src/chip/cert/cert-test.ts +360 -0
- package/src/chip/cert/chip-app-subject.ts +457 -0
- package/src/chip/cert/controller-adapter.ts +142 -0
- package/src/chip/cert/device-config.ts +33 -0
- package/src/chip/cert/evidence.ts +170 -0
- package/src/chip/cert/log-follower.ts +266 -0
- package/src/chip/cert/matterjs-subject-registry.ts +33 -0
- package/src/chip/cert/prompt-driven-python-test.ts +104 -0
- package/src/chip/chip-bins.ts +401 -0
- package/src/chip/chip-test-common.ts +3 -1
- package/src/chip/chip.ts +1 -1
- package/src/chip/config.ts +28 -1
- package/src/chip/index.ts +67 -0
- package/src/chip/pics/file.ts +8 -0
- package/src/chip/pics/source.ts +39 -19
- package/src/chip/python-test.ts +5 -4
- package/src/chip/state.ts +39 -8
- package/src/chip/yaml-test.ts +1 -1
- package/src/cli.ts +40 -2
- package/src/global-declarations.d.ts +2 -2
- package/src/global-definitions.ts +27 -3
- package/src/index.d.ts +3 -0
- package/src/index.js +1 -0
- package/src/mocha.ts +13 -0
- package/src/mocharc.cjs +4 -3
- package/src/print-report.ts +1 -1
- package/src/test-descriptor.ts +1 -1
- package/src/util/async.ts +83 -0
- package/src/util/wtf.ts +3 -1
- package/src/web.ts +5 -1
- package/test/util/AsyncTest.ts +68 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var cert_test_exports = {};
|
|
20
|
+
__export(cert_test_exports, {
|
|
21
|
+
CertTest: () => CertTest,
|
|
22
|
+
createRegisteredCertTest: () => createRegisteredCertTest,
|
|
23
|
+
registerCertTestFactory: () => registerCertTestFactory
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(cert_test_exports);
|
|
26
|
+
var import_test = require("../../device/test.js");
|
|
27
|
+
var import_expression = require("../pics/expression.js");
|
|
28
|
+
var import_file = require("../pics/file.js");
|
|
29
|
+
/**
|
|
30
|
+
* @license
|
|
31
|
+
* Copyright 2022-2026 Matter.js Authors
|
|
32
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
33
|
+
*/
|
|
34
|
+
const inertRecorder = {
|
|
35
|
+
beginStep() {
|
|
36
|
+
},
|
|
37
|
+
check() {
|
|
38
|
+
},
|
|
39
|
+
endStep() {
|
|
40
|
+
return [];
|
|
41
|
+
},
|
|
42
|
+
async flush() {
|
|
43
|
+
return "";
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
class CertTest extends import_test.BaseTest {
|
|
47
|
+
#definition;
|
|
48
|
+
constructor(definition, descriptor, container) {
|
|
49
|
+
super(descriptor, container);
|
|
50
|
+
this.#definition = definition;
|
|
51
|
+
}
|
|
52
|
+
get definition() {
|
|
53
|
+
return this.#definition;
|
|
54
|
+
}
|
|
55
|
+
async initializeSubject(_subject) {
|
|
56
|
+
}
|
|
57
|
+
async invoke(subject, step, _args, _uncommissioned) {
|
|
58
|
+
const cx = this.contextFor(subject);
|
|
59
|
+
const { recorder, devices } = cx;
|
|
60
|
+
const picsFile = resolvePicsFile(subject);
|
|
61
|
+
const deviceExitWatch = watchDeviceExits(devices, recorder);
|
|
62
|
+
const flavor = currentFlavor(devices);
|
|
63
|
+
const tc = this.#definition.tc;
|
|
64
|
+
let aborted = false;
|
|
65
|
+
let failure;
|
|
66
|
+
let failed = false;
|
|
67
|
+
try {
|
|
68
|
+
for (const stepDef of this.#definition.steps) {
|
|
69
|
+
if (aborted) {
|
|
70
|
+
announceStepEnd(cx, tc, stepDef, "aborted", recorder.endStep(stepDef, "aborted"));
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
if (stepDef.flavors && flavor !== void 0 && !stepDef.flavors.includes(flavor)) {
|
|
75
|
+
announceStepEnd(
|
|
76
|
+
cx,
|
|
77
|
+
tc,
|
|
78
|
+
stepDef,
|
|
79
|
+
"skipped",
|
|
80
|
+
recorder.endStep(stepDef, "skipped", `unsupported on device flavor "${flavor}"`)
|
|
81
|
+
);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (!stepPicsMet(stepDef, picsFile)) {
|
|
85
|
+
announceStepEnd(
|
|
86
|
+
cx,
|
|
87
|
+
tc,
|
|
88
|
+
stepDef,
|
|
89
|
+
"skipped",
|
|
90
|
+
recorder.endStep(stepDef, "skipped", `PICS "${stepDef.pics}" not met`)
|
|
91
|
+
);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
step(`Test Step ${stepDef.number}: ${stepDef.text}`);
|
|
95
|
+
announceStepStart(cx, tc, stepDef);
|
|
96
|
+
recorder.beginStep(stepDef);
|
|
97
|
+
await raceAgainstDeviceExit(stepDef.run(cx), deviceExitWatch.exit, tc, stepDef.number);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
announceStepEnd(cx, tc, stepDef, "fail", recorder.endStep(stepDef, "fail"));
|
|
100
|
+
aborted = true;
|
|
101
|
+
failed = true;
|
|
102
|
+
failure = e;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
announceStepEnd(cx, tc, stepDef, "pass", recorder.endStep(stepDef, "pass"));
|
|
106
|
+
}
|
|
107
|
+
} finally {
|
|
108
|
+
try {
|
|
109
|
+
await this.beforeFlush(cx);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
console.warn("Cert test beforeFlush hook failed:", e);
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
await recorder.flush();
|
|
115
|
+
} catch (e) {
|
|
116
|
+
if (failed) {
|
|
117
|
+
console.warn("Cert test evidence flush failed after a step failure:", e);
|
|
118
|
+
} else {
|
|
119
|
+
failed = true;
|
|
120
|
+
failure = e;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
deviceExitWatch.disarm();
|
|
124
|
+
}
|
|
125
|
+
if (failed) {
|
|
126
|
+
throw failure;
|
|
127
|
+
}
|
|
128
|
+
const exited = deviceExitWatch.observed;
|
|
129
|
+
if (exited !== void 0) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
`A cert-test device exited unexpectedly (code ${exited.code}, signal ${exited.signal}) during the run`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Build the step context for a run. Overridable so controller/device wiring can be layered on in
|
|
137
|
+
* later tasks without changing {@link invoke}'s public contract.
|
|
138
|
+
*/
|
|
139
|
+
contextFor(_subject) {
|
|
140
|
+
return {
|
|
141
|
+
controllers: {},
|
|
142
|
+
devices: {},
|
|
143
|
+
recorder: inertRecorder
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Runs immediately before {@link StepRecorder.flush}, after every step has settled. Overridable
|
|
148
|
+
* so wiring that built its own concrete recorder (see `WiredCertTest` in `cert-dsl.ts`) can attach
|
|
149
|
+
* final device/controller logs — `contextFor`'s generic `StepRecorder` type doesn't expose that,
|
|
150
|
+
* only the concrete recorder implementation does.
|
|
151
|
+
*/
|
|
152
|
+
async beforeFlush(_cx) {
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function resolvePicsFile(subject) {
|
|
156
|
+
try {
|
|
157
|
+
return subject.pics ?? void 0;
|
|
158
|
+
} catch (e) {
|
|
159
|
+
if (e instanceof import_file.PicsUnavailableError) {
|
|
160
|
+
return void 0;
|
|
161
|
+
}
|
|
162
|
+
throw e;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function currentFlavor(devices) {
|
|
166
|
+
return Object.values(devices)[0]?.flavor;
|
|
167
|
+
}
|
|
168
|
+
function stepPicsMet(stepDef, picsFile) {
|
|
169
|
+
if (stepDef.pics === void 0 || !picsFile) {
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
return new import_expression.PicsExpression(stepDef.pics).evaluate(picsFile);
|
|
173
|
+
}
|
|
174
|
+
const STEP_BANNER_RULE = "-".repeat(70);
|
|
175
|
+
function announceStep(cx, lines) {
|
|
176
|
+
for (const line of lines) {
|
|
177
|
+
for (const device of Object.values(cx.devices)) {
|
|
178
|
+
device.log.annotate(line);
|
|
179
|
+
}
|
|
180
|
+
for (const controller of Object.values(cx.controllers)) {
|
|
181
|
+
controller.log.annotate(line);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function announceStepStart(cx, tc, stepDef) {
|
|
186
|
+
announceStep(cx, [STEP_BANNER_RULE, `${tc} \u2014 Test Step ${stepDef.number}: ${stepDef.text}`, STEP_BANNER_RULE]);
|
|
187
|
+
}
|
|
188
|
+
function formatCheckLine(check) {
|
|
189
|
+
if (check.type === "device-log") {
|
|
190
|
+
return `pattern=${check.pattern ?? "(none)"} matched=${check.matched ?? "(none)"}`;
|
|
191
|
+
}
|
|
192
|
+
return check.detail ?? "(no detail)";
|
|
193
|
+
}
|
|
194
|
+
function announceStepEnd(cx, tc, stepDef, verdict, checks) {
|
|
195
|
+
const checkLines = checks.map(
|
|
196
|
+
(check, index) => checks.length > 1 ? `${index}: ${formatCheckLine(check)}` : formatCheckLine(check)
|
|
197
|
+
);
|
|
198
|
+
announceStep(cx, [
|
|
199
|
+
STEP_BANNER_RULE,
|
|
200
|
+
`${tc} \u2014 Test Step ${stepDef.number}: ${verdict.toUpperCase()}`,
|
|
201
|
+
...checkLines,
|
|
202
|
+
STEP_BANNER_RULE
|
|
203
|
+
]);
|
|
204
|
+
}
|
|
205
|
+
function watchDeviceExits(devices, recorder) {
|
|
206
|
+
let observed;
|
|
207
|
+
let onExit = (info) => recorder.deviceExited?.(info);
|
|
208
|
+
const exit = Promise.race(Object.values(devices).map((device) => device.exit));
|
|
209
|
+
void exit.then((info) => {
|
|
210
|
+
if (onExit === void 0) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
observed = info;
|
|
214
|
+
try {
|
|
215
|
+
onExit(info);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
console.warn("Cert test deviceExited hook failed:", e);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
exit,
|
|
222
|
+
get observed() {
|
|
223
|
+
return observed;
|
|
224
|
+
},
|
|
225
|
+
disarm() {
|
|
226
|
+
onExit = void 0;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
async function raceAgainstDeviceExit(stepRun, deviceExit, tc, step) {
|
|
231
|
+
const outcome = await Promise.race([stepRun.then(() => "ran"), deviceExit.then(() => "exited")]);
|
|
232
|
+
if (outcome === "exited") {
|
|
233
|
+
void stepRun.catch((e) => {
|
|
234
|
+
console.warn(`Cert test ${tc} step ${step}: orphaned step run settled after the device exit:`, e);
|
|
235
|
+
});
|
|
236
|
+
throw new Error("A cert-test device exited unexpectedly while a step was running");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const certTestFactories = /* @__PURE__ */ new WeakMap();
|
|
240
|
+
function registerCertTestFactory(descriptor, factory) {
|
|
241
|
+
certTestFactories.set(descriptor, factory);
|
|
242
|
+
}
|
|
243
|
+
function createRegisteredCertTest(descriptor) {
|
|
244
|
+
const factory = certTestFactories.get(descriptor);
|
|
245
|
+
if (!factory) {
|
|
246
|
+
throw new Error(`No cert test registered for descriptor "${descriptor.name}"`);
|
|
247
|
+
}
|
|
248
|
+
return factory();
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=cert-test.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/chip/cert/cert-test.ts"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2026 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { Subject } from "../../device/subject.js";
|
|
7
|
+
import type { Container } from "../../docker/container.js";
|
|
8
|
+
import { HARNESS_DBUS_CONTAINER } from "../config.js";
|
|
9
|
+
import { type PicsFile } from "../pics/file.js";
|
|
10
|
+
import type { CertDevice, CertDeviceFactory, DeviceExitInfo, DeviceFlavor } from "./cert-context.js";
|
|
11
|
+
import { LogFollower } from "./log-follower.js";
|
|
12
|
+
export { HARNESS_DBUS_CONTAINER };
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the directory `chip-local` subjects spawn `chip-<app>-app` binaries from. When
|
|
15
|
+
* `MATTER_CHIP_BINS_SOURCE=cert-bins`, this extracts (if not already cached — see
|
|
16
|
+
* {@link prepareChipBins}) the official `connectedhomeip/chip-cert-bins` image and returns its own
|
|
17
|
+
* directory, ignoring `MATTER_CERT_APP_DIR` entirely; otherwise it requires `MATTER_CERT_APP_DIR` as
|
|
18
|
+
* before (a directory the user built/populated themselves). `cert-dsl.ts`'s
|
|
19
|
+
* `chipLocalMarkerRevision()` calls this too, so a cert-bins-sourced run's evidence `chipRef` comes
|
|
20
|
+
* from the same directory without separate wiring.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveChipLocalAppDir(): Promise<string>;
|
|
23
|
+
export declare function chipImageBase(): string;
|
|
24
|
+
/**
|
|
25
|
+
* The subset of `Docker.compose()`'s return value that {@link ChipDockerDevice} needs, extracted so
|
|
26
|
+
* tests can substitute a fake without a running Docker daemon.
|
|
27
|
+
*/
|
|
28
|
+
export interface CompositionHandle {
|
|
29
|
+
add(config: Partial<Container.Configuration> & {
|
|
30
|
+
name: string;
|
|
31
|
+
recreate?: boolean;
|
|
32
|
+
}): Promise<Container>;
|
|
33
|
+
close(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The subset of {@link Docker} (plus volume setup) that {@link ChipDockerDevice} needs, extracted so
|
|
37
|
+
* tests can substitute a fake without a running Docker daemon.
|
|
38
|
+
*/
|
|
39
|
+
export interface DockerHandle {
|
|
40
|
+
ensureVolume(name: string): Promise<void>;
|
|
41
|
+
compose(name: string, config?: Partial<Container.Configuration>): CompositionHandle;
|
|
42
|
+
containerStatus(name: string): Promise<{
|
|
43
|
+
isRunning: boolean;
|
|
44
|
+
} | undefined>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A chip-app device run in Docker. Runs the app-specific `ghcr.io/matter-js/chip-<app>` image (its
|
|
48
|
+
* own `ENTRYPOINT` already runs the right binary) as a single container, reusing the CHIP harness's
|
|
49
|
+
* dbus/mdns sidecars (`chip/state.ts`'s `configureContainer`) instead of starting a duplicate pair —
|
|
50
|
+
* see {@link HARNESS_DBUS_CONTAINER}.
|
|
51
|
+
*/
|
|
52
|
+
export declare class ChipDockerDevice implements CertDevice {
|
|
53
|
+
#private;
|
|
54
|
+
readonly flavor: DeviceFlavor;
|
|
55
|
+
readonly id: string;
|
|
56
|
+
readonly app: string;
|
|
57
|
+
readonly commissioning: Subject.CommissioningParameters;
|
|
58
|
+
readonly log: LogFollower;
|
|
59
|
+
constructor(app: string, domain: string, options?: Subject.Options, docker?: DockerHandle);
|
|
60
|
+
get pics(): PicsFile;
|
|
61
|
+
get exit(): Promise<DeviceExitInfo>;
|
|
62
|
+
initialize(): Promise<void>;
|
|
63
|
+
start(): Promise<void>;
|
|
64
|
+
stop(): Promise<void>;
|
|
65
|
+
close(): Promise<void>;
|
|
66
|
+
snapshot(): Promise<{}>;
|
|
67
|
+
restore(): Promise<void>;
|
|
68
|
+
backchannel(): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Spawns `${MATTER_CERT_APP_DIR}/chip-<app>-app` as a local child process for cert tests.
|
|
72
|
+
*/
|
|
73
|
+
export declare function ChipLocalSubject(app: string): CertDeviceFactory;
|
|
74
|
+
/**
|
|
75
|
+
* Runs a chip-<app> device in a Docker container. Requires the CHIP harness's dbus/mdns sidecars
|
|
76
|
+
* (started by `certTest()` via `State.initialize()`) to already be running — see
|
|
77
|
+
* {@link HARNESS_DBUS_CONTAINER}.
|
|
78
|
+
*/
|
|
79
|
+
export declare function ChipDockerSubject(app: string): CertDeviceFactory;
|
|
80
|
+
//# sourceMappingURL=chip-app-subject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chip-app-subject.d.ts","sourceRoot":"","sources":["../../../../src/chip/cert/chip-app-subject.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAQ3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAwB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACrG,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKhD,OAAO,EAAE,sBAAsB,EAAE,CAAC;AA0ClC;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAsB9D;AAwID,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAMD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAC9B,GAAG,CACC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG;QACvC,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,OAAO,CAAC;KACtB,GACF,OAAO,CAAC,SAAS,CAAC,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAAC;IACpF,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;CAC9E;AAiBD;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,UAAU;;IAC/C,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAiB;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,uBAAuB,CAAC;IACxD,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAU1B,YAAY,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,GAAE,YAAiC,EAO5G;IAED,IAAI,IAAI,IAAI,QAAQ,CAEnB;IAED,IAAI,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,CAElC;IAEK,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAG;IAE9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA6D3B;IAgBK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAgB1B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ3B;IAEK,QAAQ,IAAI,OAAO,CAAC,EAAE,CAAC,CAE5B;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7B;IAEK,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjC;CACJ;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAEhE"}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var chip_app_subject_exports = {};
|
|
20
|
+
__export(chip_app_subject_exports, {
|
|
21
|
+
ChipDockerDevice: () => ChipDockerDevice,
|
|
22
|
+
ChipDockerSubject: () => ChipDockerSubject,
|
|
23
|
+
ChipLocalSubject: () => ChipLocalSubject,
|
|
24
|
+
HARNESS_DBUS_CONTAINER: () => import_config.HARNESS_DBUS_CONTAINER,
|
|
25
|
+
chipImageBase: () => chipImageBase,
|
|
26
|
+
resolveChipLocalAppDir: () => resolveChipLocalAppDir
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(chip_app_subject_exports);
|
|
29
|
+
var import_node_child_process = require("node:child_process");
|
|
30
|
+
var import_promises = require("node:fs/promises");
|
|
31
|
+
var import_node_os = require("node:os");
|
|
32
|
+
var import_node_path = require("node:path");
|
|
33
|
+
var import_node_process = require("node:process");
|
|
34
|
+
var import_docker = require("../../docker/docker.js");
|
|
35
|
+
var import_errors = require("../../docker/errors.js");
|
|
36
|
+
var import_terminal = require("../../docker/terminal.js");
|
|
37
|
+
var import_volume = require("../../docker/volume.js");
|
|
38
|
+
var import_async = require("../../util/async.js");
|
|
39
|
+
var import_text = require("../../util/text.js");
|
|
40
|
+
var import_chip_bins = require("../chip-bins.js");
|
|
41
|
+
var import_config = require("../config.js");
|
|
42
|
+
var import_file = require("../pics/file.js");
|
|
43
|
+
var import_log_follower = require("./log-follower.js");
|
|
44
|
+
/**
|
|
45
|
+
* @license
|
|
46
|
+
* Copyright 2022-2026 Matter.js Authors
|
|
47
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
48
|
+
*/
|
|
49
|
+
const DEFAULT_DISCRIMINATOR = 3840;
|
|
50
|
+
const DEFAULT_PASSCODE = 20202021;
|
|
51
|
+
const STOP_TIMEOUT_MS = 5e3;
|
|
52
|
+
const TRACE_ARGS = ["--trace_log", "1", "--trace_decode", "1"];
|
|
53
|
+
function defaultCommissioning() {
|
|
54
|
+
return {
|
|
55
|
+
kind: "on-network",
|
|
56
|
+
passcode: DEFAULT_PASSCODE,
|
|
57
|
+
discriminator: DEFAULT_DISCRIMINATOR,
|
|
58
|
+
// A real onboarding QR code needs the spec's base38 payload encoder, which lives in
|
|
59
|
+
// matter.js and is out of reach here per the packages/testing dependency invariant.
|
|
60
|
+
// ControllerAdapter.CommissioningTarget treats qrPairingCode as optional and commissions
|
|
61
|
+
// via discriminator/passcode instead.
|
|
62
|
+
qrPairingCode: ""
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function throwUnsupported(flavor, capability) {
|
|
66
|
+
throw new Error(`${flavor} subjects do not support ${capability}; commission fresh per test instead`);
|
|
67
|
+
}
|
|
68
|
+
function createExitDeferred() {
|
|
69
|
+
let resolve;
|
|
70
|
+
const promise = new Promise((r) => {
|
|
71
|
+
resolve = r;
|
|
72
|
+
});
|
|
73
|
+
return { promise, resolve };
|
|
74
|
+
}
|
|
75
|
+
async function resolveChipLocalAppDir() {
|
|
76
|
+
if ((0, import_chip_bins.resolveChipBinsSource)() === "cert-bins") {
|
|
77
|
+
if (import_node_process.platform !== "linux") {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`MATTER_CHIP_BINS_SOURCE=cert-bins selects Linux/${import_chip_bins.CERT_BINS_PLATFORM} binaries that chip-local spawns directly on the host; this host is "${import_node_process.platform}", which cannot run them. Use a Linux host or CI runner for chip-local with cert-bins, or unset MATTER_CHIP_BINS_SOURCE and point MATTER_CERT_APP_DIR at binaries built for this platform.`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
return (await (0, import_chip_bins.prepareChipBins)()).dir;
|
|
83
|
+
}
|
|
84
|
+
const dir = import_node_process.env.MATTER_CERT_APP_DIR;
|
|
85
|
+
if (!dir) {
|
|
86
|
+
throw new Error("MATTER_CERT_APP_DIR is not set; ChipLocalSubject needs it to find chip-<app>-app binaries");
|
|
87
|
+
}
|
|
88
|
+
return dir;
|
|
89
|
+
}
|
|
90
|
+
class ChipLocalDevice {
|
|
91
|
+
flavor = "chip-local";
|
|
92
|
+
id;
|
|
93
|
+
app;
|
|
94
|
+
commissioning;
|
|
95
|
+
log;
|
|
96
|
+
#appArgs;
|
|
97
|
+
#hub = new import_async.LineQueue();
|
|
98
|
+
#storageDir;
|
|
99
|
+
#child;
|
|
100
|
+
#exit = createExitDeferred();
|
|
101
|
+
#pumps = new Array();
|
|
102
|
+
constructor(app, domain, options) {
|
|
103
|
+
this.app = app;
|
|
104
|
+
this.id = domain;
|
|
105
|
+
this.commissioning = defaultCommissioning();
|
|
106
|
+
this.log = new import_log_follower.LogFollower(this.#hub.follow(), domain);
|
|
107
|
+
this.#appArgs = options?.appArgs ?? [];
|
|
108
|
+
}
|
|
109
|
+
get pics() {
|
|
110
|
+
throw new import_file.PicsUnavailableError("No active PICS file for this device");
|
|
111
|
+
}
|
|
112
|
+
get exit() {
|
|
113
|
+
return this.#exit.promise;
|
|
114
|
+
}
|
|
115
|
+
async initialize() {
|
|
116
|
+
await resolveChipLocalAppDir();
|
|
117
|
+
this.#storageDir ??= await (0, import_promises.mkdtemp)((0, import_node_path.join)((0, import_node_os.tmpdir)(), "matter-cert-local-"));
|
|
118
|
+
}
|
|
119
|
+
async start() {
|
|
120
|
+
if (this.#child) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const dir = await resolveChipLocalAppDir();
|
|
124
|
+
this.#storageDir ??= await (0, import_promises.mkdtemp)((0, import_node_path.join)((0, import_node_os.tmpdir)(), "matter-cert-local-"));
|
|
125
|
+
const binPath = (0, import_node_path.join)(dir, `chip-${this.app}-app`);
|
|
126
|
+
const kvsPath = (0, import_node_path.join)(this.#storageDir, "chip_kvs");
|
|
127
|
+
const args = [
|
|
128
|
+
"--discriminator",
|
|
129
|
+
String(this.commissioning.discriminator),
|
|
130
|
+
"--passcode",
|
|
131
|
+
String(this.commissioning.passcode),
|
|
132
|
+
"--KVS",
|
|
133
|
+
kvsPath,
|
|
134
|
+
...TRACE_ARGS,
|
|
135
|
+
...this.#appArgs
|
|
136
|
+
];
|
|
137
|
+
const child = (0, import_node_child_process.spawn)(binPath, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
138
|
+
const { stdout, stderr } = child;
|
|
139
|
+
if (!stdout || !stderr) {
|
|
140
|
+
throw new Error("Spawned process has no stdout/stderr streams");
|
|
141
|
+
}
|
|
142
|
+
this.#child = child;
|
|
143
|
+
this.#exit = createExitDeferred();
|
|
144
|
+
this.#pumps = [this.#hub.pump((0, import_text.asyncLinesOf)(stdout)), this.#hub.pump((0, import_text.asyncLinesOf)(stderr))];
|
|
145
|
+
child.once("exit", (code, signal) => {
|
|
146
|
+
this.#exit.resolve({ code, signal });
|
|
147
|
+
});
|
|
148
|
+
child.once("error", (error) => {
|
|
149
|
+
this.#exit.resolve({ code: null, signal: null });
|
|
150
|
+
console.warn(`Error running ${binPath}:`, error);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async stop() {
|
|
154
|
+
const child = this.#child;
|
|
155
|
+
if (!child) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
child.kill("SIGTERM");
|
|
159
|
+
const timer = (0, import_async.delay)(STOP_TIMEOUT_MS);
|
|
160
|
+
try {
|
|
161
|
+
const outcome = await Promise.race([this.#exit.promise.then(() => "exited"), timer.promise]);
|
|
162
|
+
if (outcome === "timeout") {
|
|
163
|
+
child.kill("SIGKILL");
|
|
164
|
+
await this.#exit.promise;
|
|
165
|
+
}
|
|
166
|
+
} finally {
|
|
167
|
+
timer.cancel();
|
|
168
|
+
this.#child = void 0;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async close() {
|
|
172
|
+
await this.stop();
|
|
173
|
+
const results = await Promise.allSettled(this.#pumps);
|
|
174
|
+
for (const result of results) {
|
|
175
|
+
if (result.status === "rejected") {
|
|
176
|
+
console.warn("Error reading device output:", result.reason);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
this.#hub.close();
|
|
180
|
+
if (this.#storageDir) {
|
|
181
|
+
await (0, import_promises.rm)(this.#storageDir, { recursive: true, force: true });
|
|
182
|
+
this.#storageDir = void 0;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async snapshot() {
|
|
186
|
+
throwUnsupported(this.flavor, "snapshot/restore");
|
|
187
|
+
}
|
|
188
|
+
async restore() {
|
|
189
|
+
throwUnsupported(this.flavor, "snapshot/restore");
|
|
190
|
+
}
|
|
191
|
+
async backchannel() {
|
|
192
|
+
throwUnsupported(this.flavor, "backchannel simulation");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function chipImageBase() {
|
|
196
|
+
return import_node_process.env.MATTER_CERT_CHIP_IMAGE_BASE || "ghcr.io/matter-js/chip";
|
|
197
|
+
}
|
|
198
|
+
function mdnsVolumeName() {
|
|
199
|
+
return import_node_process.env.MATTER_MDNS_VOLUME || "matter.js-mdns";
|
|
200
|
+
}
|
|
201
|
+
function realDockerHandle() {
|
|
202
|
+
const docker = new import_docker.Docker();
|
|
203
|
+
return {
|
|
204
|
+
async ensureVolume(name) {
|
|
205
|
+
await (0, import_volume.Volume)(docker, name).open();
|
|
206
|
+
},
|
|
207
|
+
compose(name, config) {
|
|
208
|
+
return docker.compose(name, config);
|
|
209
|
+
},
|
|
210
|
+
containerStatus(name) {
|
|
211
|
+
return docker.containerStatus(name);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
class ChipDockerDevice {
|
|
216
|
+
flavor = "chip-docker";
|
|
217
|
+
id;
|
|
218
|
+
app;
|
|
219
|
+
commissioning;
|
|
220
|
+
log;
|
|
221
|
+
#appArgs;
|
|
222
|
+
#hub = new import_async.LineQueue();
|
|
223
|
+
#docker;
|
|
224
|
+
#composition;
|
|
225
|
+
#container;
|
|
226
|
+
#exit = createExitDeferred();
|
|
227
|
+
#pump;
|
|
228
|
+
constructor(app, domain, options, docker = realDockerHandle()) {
|
|
229
|
+
this.app = app;
|
|
230
|
+
this.id = domain;
|
|
231
|
+
this.commissioning = defaultCommissioning();
|
|
232
|
+
this.log = new import_log_follower.LogFollower(this.#hub.follow(), domain);
|
|
233
|
+
this.#appArgs = options?.appArgs ?? [];
|
|
234
|
+
this.#docker = docker;
|
|
235
|
+
}
|
|
236
|
+
get pics() {
|
|
237
|
+
throw new import_file.PicsUnavailableError("No active PICS file for this device");
|
|
238
|
+
}
|
|
239
|
+
get exit() {
|
|
240
|
+
return this.#exit.promise;
|
|
241
|
+
}
|
|
242
|
+
async initialize() {
|
|
243
|
+
}
|
|
244
|
+
async start() {
|
|
245
|
+
if (this.#container) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const dbusStatus = await this.#docker.containerStatus(import_config.HARNESS_DBUS_CONTAINER);
|
|
249
|
+
if (!dbusStatus?.isRunning) {
|
|
250
|
+
throw new Error(
|
|
251
|
+
`Cannot start chip-docker cert subject "${this.id}": harness dbus container "${import_config.HARNESS_DBUS_CONTAINER}" is not running. chip-docker subjects reuse the CHIP harness's dbus/mdns sidecars (chip/state.ts's configureContainer) instead of starting their own; start the harness (e.g. via certTest(), which installs State.initialize() as a beforeRun hook) before starting this subject.`
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
const platform = import_node_process.env.MATTER_CHIP_PLATFORM || "linux/amd64";
|
|
255
|
+
const appImage = `${chipImageBase()}-${this.app}:latest`;
|
|
256
|
+
const volumeName = mdnsVolumeName();
|
|
257
|
+
await this.#docker.ensureVolume(volumeName);
|
|
258
|
+
const composition = this.#docker.compose(`cert-${this.app}-${this.id}`, {
|
|
259
|
+
platform,
|
|
260
|
+
binds: { [volumeName]: "/run/dbus" },
|
|
261
|
+
network: "host",
|
|
262
|
+
autoRemove: true
|
|
263
|
+
});
|
|
264
|
+
const args = [
|
|
265
|
+
"--discriminator",
|
|
266
|
+
String(this.commissioning.discriminator),
|
|
267
|
+
"--passcode",
|
|
268
|
+
String(this.commissioning.passcode),
|
|
269
|
+
...TRACE_ARGS,
|
|
270
|
+
...this.#appArgs
|
|
271
|
+
];
|
|
272
|
+
const container = await composition.add({
|
|
273
|
+
name: "app",
|
|
274
|
+
image: appImage,
|
|
275
|
+
recreate: true,
|
|
276
|
+
binds: { [volumeName]: "/run/dbus" },
|
|
277
|
+
command: args
|
|
278
|
+
});
|
|
279
|
+
this.#composition = composition;
|
|
280
|
+
this.#container = container;
|
|
281
|
+
this.#exit = createExitDeferred();
|
|
282
|
+
void this.#trackExit(container);
|
|
283
|
+
const terminal = await container.attach(import_terminal.Terminal.Line);
|
|
284
|
+
this.#pump = this.#hub.pump(terminal);
|
|
285
|
+
}
|
|
286
|
+
async #trackExit(container) {
|
|
287
|
+
try {
|
|
288
|
+
await container.wait();
|
|
289
|
+
this.#exit.resolve({ code: 0, signal: null });
|
|
290
|
+
} catch (e) {
|
|
291
|
+
if (e instanceof import_errors.NonZeroExitError) {
|
|
292
|
+
this.#exit.resolve({ code: e.code, signal: null });
|
|
293
|
+
} else {
|
|
294
|
+
console.warn(`Error waiting for cert device container ${this.id}:`, e);
|
|
295
|
+
this.#exit.resolve({ code: null, signal: null });
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async stop() {
|
|
300
|
+
const container = this.#container;
|
|
301
|
+
if (!container) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
await container.kill();
|
|
306
|
+
} catch {
|
|
307
|
+
}
|
|
308
|
+
await this.#exit.promise;
|
|
309
|
+
await this.#composition?.close();
|
|
310
|
+
this.#composition = void 0;
|
|
311
|
+
this.#container = void 0;
|
|
312
|
+
}
|
|
313
|
+
async close() {
|
|
314
|
+
await this.stop();
|
|
315
|
+
if (this.#pump) {
|
|
316
|
+
await this.#pump.catch((e) => console.warn("Error reading device output:", e));
|
|
317
|
+
this.#pump = void 0;
|
|
318
|
+
}
|
|
319
|
+
this.#hub.close();
|
|
320
|
+
}
|
|
321
|
+
async snapshot() {
|
|
322
|
+
throwUnsupported(this.flavor, "snapshot/restore");
|
|
323
|
+
}
|
|
324
|
+
async restore() {
|
|
325
|
+
throwUnsupported(this.flavor, "snapshot/restore");
|
|
326
|
+
}
|
|
327
|
+
async backchannel() {
|
|
328
|
+
throwUnsupported(this.flavor, "backchannel simulation");
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function ChipLocalSubject(app) {
|
|
332
|
+
return (domain, options) => new ChipLocalDevice(app, domain, options);
|
|
333
|
+
}
|
|
334
|
+
function ChipDockerSubject(app) {
|
|
335
|
+
return (domain, options) => new ChipDockerDevice(app, domain, options);
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=chip-app-subject.js.map
|