@norskvideo/ctl-test-harness 0.1.23 → 0.1.24
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/compose-advancing.d.ts +8 -0
- package/compose-advancing.js +18 -4
- package/demo/gates.js +11 -2
- package/package.json +1 -1
package/compose-advancing.d.ts
CHANGED
|
@@ -4,6 +4,11 @@ export declare const DEFAULT_COMPOSE_NODE = "video_compose";
|
|
|
4
4
|
export declare function maxNodeMediaIn(summary: unknown, node: string): number;
|
|
5
5
|
export interface ComposeSample {
|
|
6
6
|
frames: number;
|
|
7
|
+
/** Root workflows the visualiser listed — 0 while nothing is deployed. */
|
|
8
|
+
roots: number;
|
|
9
|
+
/** Whether any root workflow's summary carried a node of that name — a
|
|
10
|
+
* flat 0 with the node absent is a different failure from a stalled one. */
|
|
11
|
+
nodeSeen: boolean;
|
|
7
12
|
/** Why the sample is 0 when it is: the visualiser was unreachable, and how. */
|
|
8
13
|
error?: string;
|
|
9
14
|
}
|
|
@@ -25,6 +30,9 @@ export interface ComposeAdvancingResult {
|
|
|
25
30
|
before: number;
|
|
26
31
|
after: number;
|
|
27
32
|
node: string;
|
|
33
|
+
/** From the second sample: root workflows listed, and whether the node was in any. */
|
|
34
|
+
roots: number;
|
|
35
|
+
nodeSeen: boolean;
|
|
28
36
|
/** Set when a sample could not read the visualiser at all. */
|
|
29
37
|
error?: string;
|
|
30
38
|
}
|
package/compose-advancing.js
CHANGED
|
@@ -24,6 +24,10 @@ export function maxNodeMediaIn(summary, node) {
|
|
|
24
24
|
}
|
|
25
25
|
return max;
|
|
26
26
|
}
|
|
27
|
+
function hasNode(summary, node) {
|
|
28
|
+
const nodes = summary?.nodes;
|
|
29
|
+
return Array.isArray(nodes) && nodes.some((n) => n?.name === node);
|
|
30
|
+
}
|
|
27
31
|
async function getJson(fetch, url) {
|
|
28
32
|
const r = await fetch(url, { signal: AbortSignal.timeout(5000) });
|
|
29
33
|
if (!r.ok)
|
|
@@ -44,16 +48,24 @@ export async function composeSample(opts) {
|
|
|
44
48
|
try {
|
|
45
49
|
const wf = (await getJson(opts.fetch, `${opts.base}/workflow`));
|
|
46
50
|
let max = 0;
|
|
51
|
+
let roots = 0;
|
|
52
|
+
let nodeSeen = false;
|
|
47
53
|
for (const root of wf?.rootWorkflows ?? []) {
|
|
48
|
-
|
|
54
|
+
// The engine numbers its workflows (`wfid: 3339`); a string-only check
|
|
55
|
+
// here skipped every root and the gate read a silent 0 -> 0 everywhere.
|
|
56
|
+
const wfid = root?.wfid;
|
|
57
|
+
if (typeof wfid !== "string" && typeof wfid !== "number")
|
|
49
58
|
continue;
|
|
50
|
-
|
|
59
|
+
roots += 1;
|
|
60
|
+
const summary = await getJson(opts.fetch, `${opts.base}/workflow/${encodeURIComponent(String(wfid))}/summary`);
|
|
61
|
+
if (hasNode(summary, node))
|
|
62
|
+
nodeSeen = true;
|
|
51
63
|
max = Math.max(max, maxNodeMediaIn(summary, node));
|
|
52
64
|
}
|
|
53
|
-
return { frames: max };
|
|
65
|
+
return { frames: max, roots, nodeSeen };
|
|
54
66
|
}
|
|
55
67
|
catch (e) {
|
|
56
|
-
return { frames: 0, error: e instanceof Error ? e.message : String(e) };
|
|
68
|
+
return { frames: 0, roots: 0, nodeSeen: false, error: e instanceof Error ? e.message : String(e) };
|
|
57
69
|
}
|
|
58
70
|
}
|
|
59
71
|
export async function composeFrames(opts) {
|
|
@@ -72,6 +84,8 @@ export async function composeAdvancing(opts) {
|
|
|
72
84
|
before: before.frames,
|
|
73
85
|
after: after.frames,
|
|
74
86
|
node,
|
|
87
|
+
roots: after.roots,
|
|
88
|
+
nodeSeen: after.nodeSeen,
|
|
75
89
|
...(error !== undefined ? { error } : {}),
|
|
76
90
|
};
|
|
77
91
|
}
|
package/demo/gates.js
CHANGED
|
@@ -50,8 +50,17 @@ export function composeAdvancingGate(opts = {}) {
|
|
|
50
50
|
});
|
|
51
51
|
if (r.error)
|
|
52
52
|
ctx.log(`visualiser unreachable at ${base}: ${r.error}`);
|
|
53
|
-
else if (!r.advancing)
|
|
54
|
-
|
|
53
|
+
else if (!r.advancing) {
|
|
54
|
+
// A flat 0 has three causes worth telling apart before anyone reads
|
|
55
|
+
// engine logs: nothing deployed yet, a graph without that node, or a
|
|
56
|
+
// stalled feed into a node that is there.
|
|
57
|
+
const why = r.roots === 0
|
|
58
|
+
? "; no root workflows deployed yet"
|
|
59
|
+
: r.nodeSeen
|
|
60
|
+
? ""
|
|
61
|
+
: `; no node named ${node} in ${r.roots} root workflow(s)`;
|
|
62
|
+
ctx.log(`${node} not advancing yet (${r.before} -> ${r.after}${why})`);
|
|
63
|
+
}
|
|
55
64
|
return r.advancing;
|
|
56
65
|
},
|
|
57
66
|
};
|