@matter/testing 0.13.0-alpha.0-20250327-8b06e5a79 → 0.13.0-alpha.0-20250328-6dde053de
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/chip/chip.d.ts +4 -0
- package/dist/cjs/chip/chip.d.ts.map +1 -1
- package/dist/cjs/chip/chip.js +2 -1
- package/dist/cjs/chip/chip.js.map +1 -1
- package/dist/cjs/chip/python-test.js +11 -11
- package/dist/cjs/chip/python-test.js.map +1 -1
- package/dist/cjs/chip/state.d.ts +4 -0
- package/dist/cjs/chip/state.d.ts.map +1 -1
- package/dist/cjs/chip/state.js +61 -32
- package/dist/cjs/chip/state.js.map +1 -1
- package/dist/cjs/docker/container.d.ts +1 -0
- package/dist/cjs/docker/container.d.ts.map +1 -1
- package/dist/cjs/docker/container.js +3 -0
- package/dist/cjs/docker/container.js.map +1 -1
- package/dist/cjs/mocha.d.ts.map +1 -1
- package/dist/cjs/mocha.js +5 -2
- package/dist/cjs/mocha.js.map +1 -1
- package/dist/cjs/print-report.d.ts +1 -0
- package/dist/cjs/print-report.d.ts.map +1 -1
- package/dist/cjs/test-descriptor.d.ts +1 -0
- package/dist/cjs/test-descriptor.d.ts.map +1 -1
- package/dist/cjs/test-descriptor.js.map +1 -1
- package/dist/esm/chip/chip.d.ts +4 -0
- package/dist/esm/chip/chip.d.ts.map +1 -1
- package/dist/esm/chip/chip.js +2 -1
- package/dist/esm/chip/chip.js.map +1 -1
- package/dist/esm/chip/python-test.js +11 -11
- package/dist/esm/chip/python-test.js.map +1 -1
- package/dist/esm/chip/state.d.ts +4 -0
- package/dist/esm/chip/state.d.ts.map +1 -1
- package/dist/esm/chip/state.js +62 -33
- package/dist/esm/chip/state.js.map +1 -1
- package/dist/esm/docker/container.d.ts +1 -0
- package/dist/esm/docker/container.d.ts.map +1 -1
- package/dist/esm/docker/container.js +3 -0
- package/dist/esm/docker/container.js.map +1 -1
- package/dist/esm/mocha.d.ts.map +1 -1
- package/dist/esm/mocha.js +5 -2
- package/dist/esm/mocha.js.map +1 -1
- package/dist/esm/print-report.d.ts +1 -0
- package/dist/esm/print-report.d.ts.map +1 -1
- package/dist/esm/test-descriptor.d.ts +1 -0
- package/dist/esm/test-descriptor.d.ts.map +1 -1
- package/dist/esm/test-descriptor.js.map +1 -1
- package/package.json +2 -2
- package/src/chip/chip.ts +6 -0
- package/src/chip/matter-js-pics.properties +7 -1
- package/src/chip/python-test.ts +17 -19
- package/src/chip/state.ts +72 -33
- package/src/docker/container.ts +7 -0
- package/src/mocha.ts +6 -2
- package/src/test-descriptor.ts +1 -0
package/src/chip/python-test.ts
CHANGED
|
@@ -168,27 +168,13 @@ function spiffy(line: string) {
|
|
|
168
168
|
* or the test will not run. So we must extract these arguments to pass into the script.
|
|
169
169
|
*
|
|
170
170
|
* A program defining mandatory arguments to itself seems silly but we work with what we've got amiright?
|
|
171
|
-
*
|
|
172
|
-
* We read the entire configuration but all we currently extract are arguments to the first run that aren't
|
|
173
|
-
* "boilerplate" arguments that we don't need.
|
|
174
|
-
*
|
|
175
|
-
* We also use this opportunity to extract PICS which are returned programmatically. So we use a regexp which has high
|
|
176
|
-
* "eww" factory, but the alternative would be invoking Python and instantiating, which would not be fast.
|
|
177
171
|
*/
|
|
178
172
|
async function createCommand(descriptor: TestFileDescriptor, subject: Subject, extraArgs: string[]) {
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
let args = config["script-args"] as string;
|
|
185
|
-
if (typeof args === "string") {
|
|
186
|
-
args = args.replace(
|
|
187
|
-
/--(?:storage-path|commissioning-method|discriminator|passcode|trace-to|PICS)\s+\S+\s+/g,
|
|
188
|
-
"",
|
|
189
|
-
);
|
|
190
|
-
command.push(...args.trim().split(/\s+/));
|
|
191
|
-
}
|
|
173
|
+
const command = ["python3", descriptor.path, ...Constants.PythonRunnerArgs];
|
|
174
|
+
|
|
175
|
+
const args = scriptArgsOf(descriptor);
|
|
176
|
+
if (args !== undefined) {
|
|
177
|
+
command.push(...args);
|
|
192
178
|
}
|
|
193
179
|
|
|
194
180
|
command.push(...extraArgs);
|
|
@@ -200,3 +186,15 @@ async function createCommand(descriptor: TestFileDescriptor, subject: Subject, e
|
|
|
200
186
|
|
|
201
187
|
return command;
|
|
202
188
|
}
|
|
189
|
+
|
|
190
|
+
function scriptArgsOf(descriptor: TestFileDescriptor) {
|
|
191
|
+
const scriptArgs = descriptor.config?.["script-args"];
|
|
192
|
+
if (typeof scriptArgs !== "string") {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return scriptArgs
|
|
197
|
+
.replace(/--(?:storage-path|commissioning-method|discriminator|passcode|trace-to|PICS)\s+\S+\s+/g, "")
|
|
198
|
+
.trim()
|
|
199
|
+
.split(/\s+/);
|
|
200
|
+
}
|
package/src/chip/state.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { Package } from "#tools";
|
|
7
|
+
import { ansi, Package } from "#tools";
|
|
8
8
|
import { BackchannelCommand } from "../device/backchannel.js";
|
|
9
9
|
import { Subject } from "../device/subject.js";
|
|
10
10
|
import { Test } from "../device/test.js";
|
|
@@ -28,13 +28,14 @@ import { YamlTest } from "./yaml-test.js";
|
|
|
28
28
|
*/
|
|
29
29
|
const Values = {
|
|
30
30
|
isInitialized: false,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
runner: undefined as TestRunner | undefined,
|
|
32
|
+
mocha: undefined as Mocha | undefined,
|
|
33
|
+
subject: undefined as Subject.Factory | undefined,
|
|
34
|
+
test: undefined as Test | undefined,
|
|
35
|
+
mainContainer: undefined as Container | undefined,
|
|
36
|
+
mdnsContainer: undefined as Container | undefined,
|
|
37
|
+
pics: undefined as PicsFile | undefined,
|
|
38
|
+
tests: undefined as TestDescriptor.Filesystem | undefined,
|
|
38
39
|
initializedSubjects: new WeakSet<Subject>(),
|
|
39
40
|
activeSubject: undefined as Subject | undefined,
|
|
40
41
|
singleUseSubject: false,
|
|
@@ -43,7 +44,7 @@ const Values = {
|
|
|
43
44
|
subjects: new Map<Subject.Factory, Record<string, Subject>>(),
|
|
44
45
|
snapshots: new Map<Subject, {}>(),
|
|
45
46
|
containerLifecycleInstalled: false,
|
|
46
|
-
|
|
47
|
+
testMap: new Map<TestDescriptor, Test>(),
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
/**
|
|
@@ -51,7 +52,7 @@ const Values = {
|
|
|
51
52
|
*/
|
|
52
53
|
export const State = {
|
|
53
54
|
get container() {
|
|
54
|
-
const container = Values.
|
|
55
|
+
const container = Values.mainContainer;
|
|
55
56
|
|
|
56
57
|
if (container === undefined) {
|
|
57
58
|
throw new Error("Docker container is not initialized");
|
|
@@ -61,11 +62,11 @@ export const State = {
|
|
|
61
62
|
},
|
|
62
63
|
|
|
63
64
|
set runner(runner: TestRunner) {
|
|
64
|
-
Values.
|
|
65
|
+
Values.runner = runner;
|
|
65
66
|
},
|
|
66
67
|
|
|
67
68
|
get runner() {
|
|
68
|
-
const runner = Values.
|
|
69
|
+
const runner = Values.runner;
|
|
69
70
|
|
|
70
71
|
if (runner === undefined) {
|
|
71
72
|
throw new Error("No test runner configured");
|
|
@@ -75,11 +76,11 @@ export const State = {
|
|
|
75
76
|
},
|
|
76
77
|
|
|
77
78
|
set mocha(mocha: Mocha) {
|
|
78
|
-
Values.
|
|
79
|
+
Values.mocha = mocha;
|
|
79
80
|
},
|
|
80
81
|
|
|
81
82
|
get mocha() {
|
|
82
|
-
const mocha = Values.
|
|
83
|
+
const mocha = Values.mocha;
|
|
83
84
|
|
|
84
85
|
if (mocha === undefined) {
|
|
85
86
|
throw new Error("No mocha instance configured");
|
|
@@ -89,11 +90,11 @@ export const State = {
|
|
|
89
90
|
},
|
|
90
91
|
|
|
91
92
|
set subject(subject: Subject.Factory) {
|
|
92
|
-
Values.
|
|
93
|
+
Values.subject = subject;
|
|
93
94
|
},
|
|
94
95
|
|
|
95
96
|
get subject() {
|
|
96
|
-
const subject = Values.
|
|
97
|
+
const subject = Values.subject;
|
|
97
98
|
|
|
98
99
|
if (subject === undefined) {
|
|
99
100
|
throw new Error("no default subject configured");
|
|
@@ -103,26 +104,26 @@ export const State = {
|
|
|
103
104
|
},
|
|
104
105
|
|
|
105
106
|
get pics() {
|
|
106
|
-
if (Values.
|
|
107
|
+
if (Values.pics === undefined) {
|
|
107
108
|
throw new Error("PICS not initialized");
|
|
108
109
|
}
|
|
109
110
|
|
|
110
|
-
return Values.
|
|
111
|
+
return Values.pics;
|
|
111
112
|
},
|
|
112
113
|
|
|
113
114
|
get tests() {
|
|
114
|
-
if (Values.
|
|
115
|
+
if (Values.tests === undefined) {
|
|
115
116
|
throw new Error("CHIP test descriptor not loaded");
|
|
116
117
|
}
|
|
117
|
-
return Values.
|
|
118
|
+
return Values.tests;
|
|
118
119
|
},
|
|
119
120
|
|
|
120
121
|
get test() {
|
|
121
|
-
if (Values.
|
|
122
|
+
if (Values.test === undefined) {
|
|
122
123
|
throw new Error("No active test");
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
return Values.
|
|
126
|
+
return Values.test;
|
|
126
127
|
},
|
|
127
128
|
|
|
128
129
|
get isInitialized() {
|
|
@@ -138,7 +139,23 @@ export const State = {
|
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
const { progress } = State.runner;
|
|
141
|
-
|
|
142
|
+
|
|
143
|
+
progress.update("Initializing containers");
|
|
144
|
+
try {
|
|
145
|
+
const result = await initialize();
|
|
146
|
+
|
|
147
|
+
const imageVersion = formatSha(await State.container.imageId);
|
|
148
|
+
const chipVersion = formatSha(await State.container.read("/etc/chip-version"));
|
|
149
|
+
|
|
150
|
+
progress.success(
|
|
151
|
+
`Initialized containers from image ${ansi.bold(imageVersion)} for CHIP ${ansi.bold(chipVersion)}`,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
return result;
|
|
155
|
+
} catch (e) {
|
|
156
|
+
progress.failure("Initializing containers");
|
|
157
|
+
throw e;
|
|
158
|
+
}
|
|
142
159
|
},
|
|
143
160
|
|
|
144
161
|
/**
|
|
@@ -187,11 +204,11 @@ export const State = {
|
|
|
187
204
|
const subject = Values.activeSubject!;
|
|
188
205
|
|
|
189
206
|
try {
|
|
190
|
-
Values.
|
|
207
|
+
Values.test = test;
|
|
191
208
|
await beforeTest(subject, test);
|
|
192
209
|
await test.invoke(subject, reporter.beginStep.bind(reporter), args);
|
|
193
210
|
} finally {
|
|
194
|
-
Values.
|
|
211
|
+
Values.test = undefined;
|
|
195
212
|
}
|
|
196
213
|
},
|
|
197
214
|
|
|
@@ -238,10 +255,10 @@ export const State = {
|
|
|
238
255
|
identifier = maybeDescriptor;
|
|
239
256
|
}
|
|
240
257
|
|
|
241
|
-
let test = Values.
|
|
258
|
+
let test = Values.testMap.get(identifier);
|
|
242
259
|
if (!test) {
|
|
243
260
|
test = createTest(identifier);
|
|
244
|
-
Values.
|
|
261
|
+
Values.testMap.set(identifier, test);
|
|
245
262
|
}
|
|
246
263
|
|
|
247
264
|
return test;
|
|
@@ -347,6 +364,21 @@ export const State = {
|
|
|
347
364
|
Values.activeSubject = undefined;
|
|
348
365
|
}
|
|
349
366
|
},
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Clear the MDNS cache.
|
|
370
|
+
*/
|
|
371
|
+
async clearMdns() {
|
|
372
|
+
if (!Values.mdnsContainer) {
|
|
373
|
+
throw new Error("Cannot reset MDNS because MDNS container is not initialized");
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Active subjects will not be discoverable after we clear DNS
|
|
377
|
+
await this.deactivateSubject();
|
|
378
|
+
|
|
379
|
+
// Clear DNS
|
|
380
|
+
await Values.mdnsContainer.exec("/bin/mdns-clear");
|
|
381
|
+
},
|
|
350
382
|
};
|
|
351
383
|
|
|
352
384
|
/**
|
|
@@ -387,12 +419,12 @@ async function configureContainer() {
|
|
|
387
419
|
command: ["/usr/bin/dbus-daemon", "--nopidfile", "--system", "--nofork"],
|
|
388
420
|
});
|
|
389
421
|
|
|
390
|
-
await composition.add({
|
|
422
|
+
Values.mdnsContainer = await composition.add({
|
|
391
423
|
name: "mdns",
|
|
392
|
-
command: ["/
|
|
424
|
+
command: ["/bin/mdns-run"],
|
|
393
425
|
});
|
|
394
426
|
|
|
395
|
-
Values.
|
|
427
|
+
Values.mainContainer = await composition.add({
|
|
396
428
|
name: "chip",
|
|
397
429
|
recreate: true,
|
|
398
430
|
});
|
|
@@ -404,7 +436,7 @@ async function configureContainer() {
|
|
|
404
436
|
console.error("Error terminating containers:", e);
|
|
405
437
|
}
|
|
406
438
|
|
|
407
|
-
Values.
|
|
439
|
+
Values.mainContainer = undefined;
|
|
408
440
|
});
|
|
409
441
|
}
|
|
410
442
|
|
|
@@ -419,7 +451,7 @@ async function configurePics() {
|
|
|
419
451
|
const overrides = new PicsFile(testing.resolve(Constants.localPicsOverrideFile));
|
|
420
452
|
pics.patch(overrides);
|
|
421
453
|
|
|
422
|
-
Values.
|
|
454
|
+
Values.pics = pics;
|
|
423
455
|
|
|
424
456
|
await State.container.write(ContainerPaths.matterJsPics, pics.toString());
|
|
425
457
|
}
|
|
@@ -435,7 +467,7 @@ async function configureTests() {
|
|
|
435
467
|
if (!Array.isArray(descriptor.members)) {
|
|
436
468
|
throw new Error(`CHIP test descriptor has no members`);
|
|
437
469
|
}
|
|
438
|
-
Values.
|
|
470
|
+
Values.tests = TestDescriptor.Filesystem(descriptor);
|
|
439
471
|
}
|
|
440
472
|
|
|
441
473
|
/**
|
|
@@ -528,3 +560,10 @@ function createTest(descriptor: TestDescriptor) {
|
|
|
528
560
|
throw new Error(`Cannot implement CHIP test ${descriptor.name} of kind ${descriptor.kind}`);
|
|
529
561
|
}
|
|
530
562
|
}
|
|
563
|
+
|
|
564
|
+
function formatSha(sha: string) {
|
|
565
|
+
if (sha.startsWith("sha256:")) {
|
|
566
|
+
sha = sha.substring(7);
|
|
567
|
+
}
|
|
568
|
+
return ansi.bold(sha.substring(0, 12));
|
|
569
|
+
}
|
package/src/docker/container.ts
CHANGED
|
@@ -19,6 +19,9 @@ import { Terminal } from "./terminal.js";
|
|
|
19
19
|
*/
|
|
20
20
|
export interface Container {
|
|
21
21
|
docker: Docker;
|
|
22
|
+
|
|
23
|
+
imageId: Promise<string>;
|
|
24
|
+
|
|
22
25
|
start(): Promise<void>;
|
|
23
26
|
kill(): Promise<void>;
|
|
24
27
|
remove(force?: boolean): Promise<void>;
|
|
@@ -226,6 +229,10 @@ function adaptContainer(docker: Docker, ct: Dockerode.Container): Container {
|
|
|
226
229
|
return {
|
|
227
230
|
docker,
|
|
228
231
|
|
|
232
|
+
get imageId() {
|
|
233
|
+
return ct.inspect().then(info => info.Image);
|
|
234
|
+
},
|
|
235
|
+
|
|
229
236
|
async start() {
|
|
230
237
|
await DockerError.adapt(ct.start());
|
|
231
238
|
},
|
package/src/mocha.ts
CHANGED
|
@@ -221,7 +221,7 @@ export function adaptReporter(
|
|
|
221
221
|
});
|
|
222
222
|
|
|
223
223
|
runner.on(RUNNER.EVENT_TEST_BEGIN, test => {
|
|
224
|
-
if (updateStats) {
|
|
224
|
+
if (updateStats && test.descriptor) {
|
|
225
225
|
test.descriptor.runAt = new Date();
|
|
226
226
|
}
|
|
227
227
|
logs = (test as any).logs = [];
|
|
@@ -230,13 +230,17 @@ export function adaptReporter(
|
|
|
230
230
|
|
|
231
231
|
if (updateStats) {
|
|
232
232
|
runner.on(RUNNER.EVENT_TEST_PASS, test => {
|
|
233
|
+
if (!test.descriptor) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
233
237
|
test.descriptor.durationMs = test.duration;
|
|
234
238
|
test.descriptor.passed = true;
|
|
235
239
|
});
|
|
236
240
|
}
|
|
237
241
|
|
|
238
242
|
runner.on(RUNNER.EVENT_TEST_FAIL, (test, error) => {
|
|
239
|
-
if (updateStats) {
|
|
243
|
+
if (updateStats && test.descriptor) {
|
|
240
244
|
test.descriptor.durationMs = test.duration;
|
|
241
245
|
test.descriptor.passed = false;
|
|
242
246
|
}
|