Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

test(e2e): transfers through a gateway keep their promises

オープン
#559 コメント 0 件 リアクション 0 件 担当者 1 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@V3RON がすでに取り組んでいます。

2026年10月14日 から。

評価

この issue はまだ評価されていません。

説明

task:ready

Part of #552.

Scope

After this PR, #552's measured promises are proven against a real gateway
and worker over the real WebSocket: bytes on the uplink, the 1 s bound
for small calls with uploads and downloads running, a slow reader slowing
only itself, memory per transfer in both directions, 2 GiB both ways with
the download inside agent-device's 90 s, and, on the slow lane, the 1.5×
upload time.

A promise that fails is fixed in this PR, in the module that breaks it.
A fix that would change a value ADR 0028 or #552's Shared values table
sets (credit, unsent mark, message size, channel limit, waits) is not
made: the implementer stops and reports, since those values are the
maintainer's.

The values are in #552's Shared values table.

In short

flowchart LR
  T["test"] -->|relay| G["gateway"]
  G --- P["counting TCP proxy (test)"] --- W["worker"]
  W --> F["fake relay target / real agent-device"]

The tests put a TCP proxy between the worker and the gateway to count
the bytes on the uplink. The timing tests run in their own test project,
alone, so other test files do not compete for the CPU. If this goes
wrong, a promise #552 makes to users is false and nothing shows it.

Technical spec

Facts
# Fact Source
F1 startFleet starts a real gateway and worker over the real WebSocket on 127.0.0.1 with a fake relay target; it is local to the file's describe and points the worker's gateway.url straight at the gateway's port src/daemon/relay-gateway.e2e.test.ts:124-145, :178, :210
F2 patternStream and patternDigest make and check large bodies; the pattern is generated byte by byte src/daemon/test-relay-support.ts:88-93, :102-110
F3 The model for timing a small call while a relay runs, with a check that the relay had not finished first src/daemon/relay-gateway.e2e.test.ts:294-328
F4 The worker dials gateway.url; the uplink endpoint is derived from it src/ports/uplink.ts:52 (resolveUplinkUrl)
F5 The test projects: unit takes src/**/*.test.ts, e2e takes e2e/**/*.test.ts; CI runs pnpm run test:unit vitest.config.ts:14-27; package.json:47; .github/workflows/ci.yml:69
F6 The slow-lane gateway suite starts a gateway and one real-driver worker with one device; its lease tests each open their own lease through the gateway e2e/slow-agent-device-gateway.test.ts:124-153, :181-200
F7 A worker answers agent-device calls made with its own agent tokens on its own front docs/HTTP-API.md:1497-1499
F8 simlock's upload routes: preflight, direct upload, finalize, each naming the lease in x-agent-device-lease-id src/agent-device/shared/routes.ts:20-35; docs/HTTP-API.md:1507-1511
F10 CI's jobs: unit has a 10-minute limit; quality gates merges and needs static, unit and e2e; pnpm check runs pnpm test, and CI runs what it runs .github/workflows/ci.yml:49-54, :105-107; package.json:46, :62; docs/internal/agent-rules/toolchain.md:35
F11 The command guard lists the scripts agents never run, and toolchain.md's "Checks agents never run" table must match it .agents/scripts/tool-guard.mjs:17-28; docs/internal/agent-rules/toolchain.md:18-21
F12 The mutation config includes every src/**/*.test.ts, and Stryker reruns tests per mutant vitest.mutate.config.ts:8; stryker.config.mjs:4-6
F13 A test pins the lane filters in package.json src/test-lanes.test.ts
F9 agent-device's preflight body: sha256, uploadAttemptId, fileName, sizeBytes, artifactType, optional platform and contentType; finalize takes { uploadId } and checks size and hash agent-device src/daemon/upload-http.ts:246-256, :197-205; src/daemon/resumable-upload.ts:104-117, at the commit vendor/README.md names
Modules touched
  • src/daemon/test-relay-support.ts: startFleet moves here from
    src/daemon/relay-gateway.e2e.test.ts with a gatewayUrl option (F1);
    a counting TCP proxy helper that pipes each direction with backpressure
    and holds no buffer of its own; the pattern helpers derive each byte
    from its own offset (a hash in counter mode), so no stretch of the
    pattern equals any other, and build it fast enough for 2 GiB (F2).
  • src/daemon/relay-gateway.e2e.test.ts: uses the moved startFleet.
  • src/daemon/relay-promises.timing.test.ts (new): the tests below.
  • vitest.config.ts, vitest.mutate.config.ts, package.json,
    .github/workflows/ci.yml, docs/internal/agent-rules/toolchain.md,
    .agents/scripts/tool-guard.mjs, src/test-lanes.test.ts: a timing
    project that takes src/**/*.timing.test.ts, which the unit project
    and the mutation config leave out (F12), runs its files one at a time
    with nothing else in parallel, and gives each test 300 s; a test:timing script that
    pnpm test (and so pnpm check) runs (F10); a timing CI job with a
    30-minute limit that quality needs; the script in toolchain.md's
    "Checks agents never run" table and in the command guard's list (F11),
    and a "Tests agents run" row for one timing file:
    pnpm vitest run --project timing <file>.
  • e2e/slow-agent-device-gateway.test.ts: the slow-lane test.
  • A failing promise adds the module that fixes it (Scope).
Contract and event changes

None.

Other code on the same state

None: tests and test tooling. A fix this PR makes names the code it
changes in the PR body.

Rules in play
  • testing.md: rule 2, every test can fail for the right reason: a
    timing test checks its load was still running when it measured.
  • toolchain.md: the new script goes in "Checks agents never run" and
    the command guard's list; the slow lane runs through
    scripts/slow-e2e.sh.
Tests

Seam: startFleet (F1) with gatewayUrl pointed at the counting TCP
proxy in front of the gateway's port (F4). The proxy counts the bytes it
carries in both directions from a transfer's start to its end. The two
ratio tests (the 1 s bound and the 1.5× slow reader) take the median of 5
runs against a baseline measured the same way in the same test; every
other test is one run. Tests moving 1 GiB or more set a 180 s timeout
and compare by digest while streaming. Model: F3.

  • a 100 MiB upload through the gateway puts at most 105 MiB on the uplink
  • a 1 GiB upload through the gateway puts at most 1.05 GiB on the uplink, and so does a 1 GiB download, each measured on its own
  • while 10 relays each upload 64 MiB and 10 each download 64 MiB to one worker, a forwarded lease.renew and a relayed request whose target answers at once each answer at most 1 s later than with nothing running, and each of the 20 relays carried at least 1 MiB in the second before and the second after each answer came back
  • while one relay's caller reads none of its 1 GiB response, another relay's 256 MiB upload to the same worker takes at most 1.5 times as long as with nothing else running
  • while the gateway's caller reads none of a 2 GiB response, the target has handed over at most 8 MiB after 5 s; reading it then gets every byte, in order
  • while the target reads none of a 2 GiB upload, the gateway has read at most 8 MiB of the caller's body after 5 s; once the target reads, every byte arrives, in order
  • a 2 GiB upload through the gateway arrives byte for byte
  • a 2 GiB download through the gateway arrives byte for byte and finishes within 90 s
  • swapping two chunks of different random sizes (1 byte to 64 KiB) at random offsets of a 2 GiB pattern changes its digest, in each of 100 trials
  • the unit project and the mutation config leave out *.timing.test.ts, the timing project takes them and runs files one at a time, pnpm test runs test:timing, and CI's quality job needs the timing job (in src/test-lanes.test.ts)

Slow lane (F6–F9): in the iOS suite, a test opens a device through the
worker's own front with an agent token minted on the worker, and times a
1 GiB upload with that lease from the preflight to the finalize answer
(F9), three times, then closes it. It then opens a device through the
gateway and times the same upload the same way. The ratio compares the
medians. Both legs run on the same machine, one after the other.

Done when

  • Every Tests line passes, and CI runs the timing project.
  • On a Mac with an iOS runtime and the agent-device checks of toolchain.md: "a 1 GiB upload takes at most 1.5 times as long through the gateway as straight to the worker" passes in e2e/slow-agent-device-gateway.test.ts.

Out of scope

  • Any behaviour #558 or #557 owns, except a fix a failing promise needs.

Depends on

  • #558

Written by an agent.

主要言語
TypeScript
スター
19
フォーク
1
平均マージ
6時間 31分
マージ済み PR(30日)
194

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

callstackincubator/simlock のほかの issue

callstackincubator/simlock の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。