@torrent-tv/proxy 2.80.10 → 2.80.12

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.
@@ -19,6 +19,7 @@ import { Timeline } from "../services/output/Timeline.js";
19
19
  import test from "node:test";
20
20
 
21
21
  import { HlsSessionManager } from "../services/hls-session-manager.js";
22
+ import { trueStartOf } from "../services/encode/run-command.js";
22
23
  import { fmp4Format } from "../services/segment-formats/fmp4.js";
23
24
  import { ENCODE_RUN_STATE, INITIAL_RUN_STATE } from "../services/encode/encode-run-state.js";
24
25
 
@@ -108,20 +109,38 @@ test("a soundtrack follows the picture to the instant the picture really began",
108
109
  10.5,
109
110
  "and every member's table with it — one film, one table, nothing to keep in step"
110
111
  );
111
- // A NEW run, not a seek. A seek decides by index, finds the soundtrack
112
- // already begins at #2 and answers "already within the running encode"
113
- // true about the index, false about the instant. The first version of this
114
- // fix did exactly that and moved nothing.
115
- //
116
- // The attempt is the evidence because it is what a run start claims before
117
- // it awaits anything: the assertion then holds without the test needing a
118
- // filesystem, a process, or a guess about how many ticks to wait for one.
119
- assert.ok(
120
- sound.pendingRun,
121
- "the soundtrack's run must be started again, at the corrected time"
112
+ // THE RUN AT THE WRONG INSTANT IS STOPPED, and nothing here places its
113
+ // replacement. What has been learned is that this run is producing in the
114
+ // wrong place, which nothing but the piece it produced could say — the plan
115
+ // reasons about numbers and cannot know it. So the fact is acted on as far as
116
+ // it is known and no further: the run goes, the stretch it held returns to the
117
+ // map, and where the next one stands follows from where the viewers are.
118
+ assert.equal(runBefore.state, ENCODE_RUN_STATE.STOPPED, "the run in the wrong place goes");
119
+ assert.equal(sound.pendingRun, null, "and this path places nothing");
120
+ // The corrected instant reaches whatever the plan places there through the
121
+ // table, which every session of the file shares. It used to be passed as an
122
+ // argument from this one call site, so only a run started by that line ever
123
+ // had it — a run the plan placed at the same number landed apart again.
124
+ assert.equal(
125
+ trueStartOf(sound.timeline, 2),
126
+ 10.5,
127
+ "the live table holds the measurement and the published one the prediction"
128
+ );
129
+ });
130
+
131
+ test("where a number really begins is answered only where it has been measured", () => {
132
+ const { sound } = familyAtBoundaryTwo();
133
+
134
+ assert.equal(
135
+ trueStartOf(sound.timeline, 2),
136
+ undefined,
137
+ "the two tables agree, so there is nothing measured to prefer"
122
138
  );
123
- assert.equal(sound.pendingRun.startIndex, 2);
124
- assert.equal([...sound.runs][0], runBefore, "and the run in force is only replaced once one is built");
139
+ sound.timeline.boundaries[2] = 10.5;
140
+ assert.equal(trueStartOf(sound.timeline, 2), 10.5);
141
+ assert.equal(trueStartOf(sound.timeline, 3), undefined, "and only about the number measured");
142
+ assert.equal(trueStartOf(sound.timeline, 99), undefined, "a number the file does not have");
143
+ assert.equal(trueStartOf(null, 0), undefined, "and no table at all");
125
144
  });
126
145
 
127
146
  test("a correction the table already holds moves nobody", () => {
@@ -19,6 +19,29 @@ import { WebSocketServer } from "ws";
19
19
 
20
20
  import { createTunnelClient } from "../services/tunnel-client.js";
21
21
 
22
+ /**
23
+ * Wait for the thing being asserted, not for a length of time.
24
+ *
25
+ * A chosen interval followed by an assertion does not test — it samples, and
26
+ * what it samples is how busy the machine is. The deadline here is a backstop
27
+ * that turns a hang into a failure; it is never the measurement.
28
+ *
29
+ * @param {() => boolean} until
30
+ * @param {string} what - Named in the failure, since a timeout otherwise says
31
+ * only that something did not happen.
32
+ * @param {number} [limit]
33
+ * @returns {Promise<void>}
34
+ */
35
+ async function waitFor(until, what, limit = 10_000) {
36
+ const deadline = Date.now() + limit;
37
+ while (!until()) {
38
+ if (Date.now() > deadline) {
39
+ throw new Error(`${what} never happened`);
40
+ }
41
+ await new Promise((resolve) => { setTimeout(resolve, 5); });
42
+ }
43
+ }
44
+
22
45
  /**
23
46
  * A stand-in for the registry's tunnel endpoint, with the one behaviour that
24
47
  * matters here: a new connection for a proxy REPLACES the previous one, which
@@ -92,8 +115,10 @@ test("the connection is replaced before its lifetime runs out, without a gap", a
92
115
  });
93
116
 
94
117
  client.connect();
95
- // Long enough for several renewals at 150 ms each.
96
- await new Promise((resolve) => { setTimeout(resolve, 700); });
118
+ // Until the renewals have happened, however long this machine takes over
119
+ // them. Waited out as 700 ms instead — about four lifetimes — this asserted
120
+ // how many the scheduler had got round to.
121
+ await waitFor(() => registry.opened() >= 3, "three connections");
97
122
 
98
123
  assert.ok(registry.opened() >= 3, `expected several renewals, saw ${registry.opened()}`);
99
124
  // The property this exists for: the registry was never left with nothing.
@@ -128,11 +153,15 @@ test("a connection killed from outside is still reconnected", async (t) => {
128
153
  });
129
154
 
130
155
  client.connect();
131
- await new Promise((resolve) => { setTimeout(resolve, 200); });
156
+ await waitFor(() => registry.opened() === 1, "the first connection");
157
+ // And exactly one: the lifetime above is far longer than this test runs, so
158
+ // nothing renews and a second would mean something else had opened it.
132
159
  assert.equal(registry.opened(), 1);
133
160
 
134
161
  registry.killCurrent();
135
- await new Promise((resolve) => { setTimeout(resolve, 300); });
136
162
  // The renewal must not have taken the ordinary reconnect away with it.
137
- assert.ok(lines.some((line) => line.includes("Reconnecting in")), lines.join("\n"));
163
+ await waitFor(
164
+ () => lines.some((line) => line.includes("Reconnecting in")),
165
+ "the reconnect after a connection was killed from outside"
166
+ );
138
167
  });