Skip to content

test: classify networked suites and lock live-network runs - #372

Merged
andrevmatos merged 1 commit into
mainfrom
tests/contention
Aug 25, 2026
Merged

andrevmatos merged 1 commit into
mainfrom
tests/contention

Conversation

@andrevmatos

Copy link
Copy Markdown
Collaborator

What

A small test-infra refactor: every networked test suite is classified by filename suffix and serializes its live-network access through OS-level locks, so node --test's concurrent file runs stop rate-limiting shared public RPCs.

Changes

  • Naming β€” CLI e2e suites renamed show.test.ts β†’ show.e2e.test.ts, lane.test.ts β†’ lane.e2e.test.ts. Test files are classified purely by suffix (*.integration.test.ts, *.e2e.test.ts, *.fork.test.ts), so a bare integration.test.ts counts as integration exactly like logs.integration.test.ts.
  • npm run test:unit β€” new script (root + both workspaces) running only offline unit tests via scripts/run-tests.mjs (filename-only filtering; --exclude/--tags/--dry). npm test is unchanged and still runs everything.
  • Network locks β€” scripts/useResource.ts. Networked suites declare the networks they talk to:
    import { useResource } from '../../../scripts/useResource.ts'
    await useResource(['sepolia', 'fuji'])
    Each tag is a directory under <tmpdir>/ccip-tools-ts-network-locks, created atomically with fs.mkdir; exactly one process holds a tag at a time, and a waiting suite starts the moment the holder finishes β€” there is no batch/wave scheduling, the filesystem is the queue. Acquisition is all-or-nothing (deadlock-free), locks auto-release on process exit, and crashed holders self-heal via pid-liveness (a lock held by a live process is never stolen). All 13 networked suites are wired with tags verified against the endpoints they actually call.
  • CI β€” unchanged: npm test still runs everything in one job, and network contention is now resolved by the locks themselves (locks are per-machine, so the networked suites intentionally stay on the single CI runner rather than splitting across jobs).
  • Docs β€” CONTRIBUTING.md gained "Test Suite Layout" + "Networked tests and the useResource lock" sections; CHANGELOG.md Unreleased entry added.

Validation

  • npm run check clean (lint 0 warnings, typecheck, generate:lint up-to-date)
  • npm run test:unit β€” 1313 tests, 0 failures
  • Full npm test (CI parity) β€” 1327 sdk + 117 cli, 0 failures; lock contention observed and resolved during the run (e.g. waiting for "fuji" heartbeats), zero lock residue afterwards
  • Fork suites self-skip without anvil/surfpool (existing behavior; CI installs both)

@andrevmatos
andrevmatos requested review from a team, PabloMansanet and aelmanaa as code owners August 25, 2026 16:10
@vercel

vercel Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ccip-tools-ts Ready Ready Preview Aug 25, 2026 4:56pm

Request Review

@github-actions

Copy link
Copy Markdown

πŸ‘‹ andrevmatos, thanks for creating this pull request!

To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team.

Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks!

Comment thread scripts/useResource.ts Fixed
aelmanaa
aelmanaa previously approved these changes Aug 25, 2026
@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Coverage Report

β„Ή tests 1346
β„Ή suites 325
β„Ή pass 1340
β„Ή fail 0
β„Ή cancelled 0
β„Ή skipped 6
β„Ή todo 0
β„Ή duration_ms 308301.277073

> @chainlink/ccip-cli@1.12.0 test
> node --test

βœ” src/commands/e2e-helpers.test.ts (110.927095ms)
Verbose mode enabled
β–Ά getCtx
  β–Ά output β€” always stdout
    βœ” output.write goes to stdout (1.380641ms)
    βœ” output.table goes to stdout (0.829121ms)
  βœ” output β€” always stdout (3.376662ms)
  β–Ά logger β€” always stderr
    βœ” logger.info goes to stderr (0.482563ms)
    βœ” logger.warn goes to stderr (0.321991ms)
    βœ” logger.error goes to stderr (0.399026ms)
  βœ” logger β€” always stderr (1.472643ms)
  β–Ά verbose mode
    βœ” logger.debug is a no-op when verbose is false (0.41227ms)
    βœ” logger.debug goes to stderr when verbose is true (1.590777ms)
  βœ” verbose mode (2.212379ms)
  β–Ά destroy signal
    βœ” returns a working destroy function (10.094761ms)
    βœ” calling destroy twice does not throw (0.606263ms)
  βœ” destroy signal (10.944721ms)
βœ” getCtx (18.831667ms)
β–Ά lane-latency command
  βœ” should output JSON format correctly (17.121968ms)
  βœ” should resolve chain IDs to chain selectors (1.893049ms)
  βœ” should use custom API URL when provided (4.617883ms)
  βœ” should output log format correctly (1.76518ms)
  βœ” should handle chain IDs as input (4.427386ms)
  βœ” should handle chain selectors as input (1.571988ms)
  βœ” should throw CCIPApiClientNotAvailableError when --no-api flag is set (1.246681ms)
  βœ” should work normally when --no-api flag is false (1.650285ms)
  βœ” should forward blockConfirmations to API URL (1.46595ms)
  βœ” should not include numOfBlocks when blockConfirmations is not provided (1.452485ms)
  β–Ά CCIP_API environment variable integration
    βœ” should respect CCIP_API=false environment variable (0.532997ms)
  βœ” CCIP_API environment variable integration (0.753589ms)
βœ” lane-latency command (40.692081ms)
[network-locks] acquired "aptos-testnet"
[network-locks] acquired "fuji"
[network-locks] acquired "sepolia"
[network-locks] acquired "solana-devnet"
[network-locks] acquired "ton-testnet"
β–Ά e2e command lane EVM v1.5
  βœ” should show lane config Sepolia -> Fuji (v1.5) in JSON (5372.913367ms)
  βœ” should show lane config Sepolia -> Fuji (v1.5) in pretty format (4683.589404ms)
βœ” e2e command lane EVM v1.5 (10058.701063ms)
β–Ά e2e command lane EVM v2.0
  βœ” should show lane config Sepolia -> Fuji (v2.0) in JSON (2753.85504ms)
βœ” e2e command lane EVM v2.0 (2754.191349ms)
β–Ά e2e command lane EVM <-> Aptos (v1.6)
  βœ” should show lane config Sepolia -> Aptos (v1.6) (4254.367301ms)
  βœ” should show lane config Aptos -> Sepolia (v1.6) (3741.601119ms)
βœ” e2e command lane EVM <-> Aptos (v1.6) (7996.422358ms)
β–Ά e2e command lane EVM <-> Solana (v1.6)
  βœ” should show lane config Sepolia -> Solana (v1.6) (5009.545306ms)
  βœ” should show lane config Solana -> Sepolia (v1.6) (4832.546081ms)
βœ” e2e command lane EVM <-> Solana (v1.6) (9842.507425ms)
β–Ά e2e command lane EVM <-> TON (v1.6)
  βœ” should show lane config TON -> Sepolia (v1.6) (27619.6152ms)
  βœ” should show lane config Sepolia -> TON (v1.6) (16642.279702ms)
βœ” e2e command lane EVM <-> TON (v1.6) (44262.371713ms)
β–Ά selectRequest non-interactive behavior
  βœ” returns the single request without prompting (1.14991ms)
  βœ” returns the request matching logIndex (0.188483ms)
  βœ” throws CCIPInteractiveRequiredError for multiple requests without logIndex (1.703414ms)
βœ” selectRequest non-interactive behavior (4.783933ms)
β–Ά CCIPInteractiveRequiredError
  βœ” has correct code and is not transient (0.333243ms)
  βœ” uses default recovery when none provided (0.293669ms)
  βœ” preserves context fields (0.177973ms)
βœ” CCIPInteractiveRequiredError (1.004668ms)
β–Ά preprocessArgv TTY auto-detection
  βœ” --interactive flag is defined in globalOpts (0.263102ms)
βœ” preprocessArgv TTY auto-detection (0.427489ms)
β–Ά search messages command
  βœ” should throw CCIPApiClientNotAvailableError when --no-api flag is set (2.792641ms)
  βœ” should output JSON format correctly (12.298481ms)
  βœ” should pass sender filter to API (3.865977ms)
  βœ” should pass receiver filter to API (3.330646ms)
  βœ” should resolve source chain to selector (2.536041ms)
  βœ” should resolve dest chain to selector (2.055092ms)
  βœ” should pass manual-exec-only filter to API (5.79297ms)
  βœ” should treat limit 0 as unlimited (5.730542ms)
  βœ” should respect limit parameter (6.120842ms)
  βœ” should warn when no results found (0.987997ms)
  βœ” should use custom API URL when provided (1.833638ms)
  βœ” should warn on negative limit and fall back to default (1.993136ms)
  βœ” should output log format (1.536732ms)
βœ” search messages command (52.894893ms)
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] waiting for "aptos-testnet" β€” held by pid 5217 since 2026-08-25T17:10:01.153Z
[network-locks] acquired "api"
[network-locks] acquired "api"
[network-locks] acquired "aptos-testnet"
[network-locks] acquired "fuji"
[network-locks] acquired "sepolia"
[network-locks] acquired "solana-devnet"
[network-locks] acquired "ton-testnet"
β–Ά e2e command show EVM
  β–Ά pretty format (default)
    βœ” should show complete CCIP transaction details EVM to EVM (9033.260221ms)
  βœ” pretty format (default) (9034.463641ms)
  β–Ά json format
    βœ” should output a single valid JSON envelope with all expected fields (6665.16523ms)
  βœ” json format (6665.504665ms)
  β–Ά log format
    βœ” should output in log format with object assignments (6664.347446ms)
  βœ” log format (6664.817684ms)
  β–Ά verbose flag
    βœ” should work with verbose flag enabled (7454.416741ms)
  βœ” verbose flag (7454.692028ms)
  β–Ά error handling
    βœ” should handle invalid transaction hash gracefully (6524.666678ms)
    βœ” should require transaction hash argument (1795.681197ms)
  βœ” error handling (8320.78928ms)
  βœ” should show complete CCIP transaction details EVM to Aptos (7698.826888ms)
  βœ” should show complete CCIP transaction details EVM to Solana (6137.90738ms)
  βœ” should show EVM to Solana v2 OffRamp execution without verifications (3778.045616ms)
βœ” e2e command show EVM (55756.538453ms)
β–Ά e2e command show Solana
  βœ” should show complete CCIP transaction details Solana to EVM (9765.170525ms)
βœ” e2e command show Solana (9765.432273ms)
β–Ά e2e command show Aptos
  βœ” should show complete CCIP transaction details Aptos to EVM (8301.895649ms)
βœ” e2e command show Aptos (8302.163531ms)
οΉ£ e2e command show TON (0.071223ms) # SKIP
β–Ά formatCCIPError
  βœ” should return null for non-CCIPError instances (1.697022ms)
  βœ” should format CCIPError with code and message (0.616002ms)
  βœ” should include help section with recovery hint (0.259565ms)
  βœ” should include note section for transient errors (0.318816ms)
  βœ” should include retry timing for transient errors with retryAfterMs (0.42786ms)
  βœ” should not include note section for permanent errors (0.174166ms)
  βœ” should format error with structured output (0.264394ms)
  βœ” should include stack trace when verbose is true (0.527446ms)
  βœ” should not include stack trace when verbose is false (0.238636ms)
βœ” formatCCIPError (6.853062ms)
β–Ά pretty display formatters
  βœ” formats TON addresses to friendly form, bare tx hashes, recursively (1.538365ms)
  βœ” formats remote-family values with the familyFor override (0.30512ms)
  βœ” leaves values without known address/hash keys untouched (0.203ms)
  βœ” formatDisplayTxHash is identity for non-TON hashes (0.277229ms)
βœ” pretty display formatters (2.715908ms)
β–Ά yieldResolved
  βœ” throws if a promise rejects while the generator is paused after a yield (16.22449ms)
βœ” yieldResolved (16.570988ms)
β–Ά canton/signer
  β–Ά Ed25519TransactionSigner constructor
    βœ” constructs with a valid 64-char hex seed (3.689838ms)
    βœ” constructs with a 0x-prefixed seed (0.423832ms)
    βœ” throws when seed is too short (0.544899ms)
    βœ” throws when seed is too long (0.316902ms)
    βœ” throws when seed contains non-hex characters (0.147625ms)
    βœ” computes the correct Canton fingerprint (0.828338ms)
    βœ” produces different fingerprints for different seeds (0.703887ms)
  βœ” Ed25519TransactionSigner constructor (8.051642ms)
  β–Ά Ed25519TransactionSigner.sign()
    βœ” returns a PartySignatures structure (1.030706ms)
    βœ” includes the correct party ID (0.513029ms)
    βœ” produces a signature with correct properties (0.798804ms)
    βœ” produces a valid Ed25519 signature (64 bytes) (0.517507ms)
    βœ” produces a cryptographically valid signature (1.271106ms)
    βœ” produces different signatures for different hashes (0.48118ms)
    βœ” produces different signatures for different signers (same hash) (0.71155ms)
    βœ” handles empty hash (edge case) (0.408524ms)
  βœ” Ed25519TransactionSigner.sign() (6.242339ms)
  β–Ά Ed25519TransactionSigner.getFingerprint()
    βœ” returns the fingerprint computed during construction (0.364832ms)
    βœ” returns a 68-character hex string (0.336108ms)
  βœ” Ed25519TransactionSigner.getFingerprint() (0.82349ms)
  β–Ά Integration: multiple signers with same party
    βœ” allows multiple signers for the same party with different keys (0.73848ms)
  βœ” Integration: multiple signers with same party (0.82938ms)
βœ” canton/signer (16.676135ms)
β–Ά fetchChainsFromRpcs
  βœ” lets duplicate tx-hash race endpoints query before aborting losers (14.799647ms)
  βœ” chainGetter: returns chain from first winning endpoint and destroys late arrivals (51.658722ms)
  βœ” chainGetter: resolves a pending request once the endpoint connects (Branch 2) (20.826142ms)
  βœ” chainGetter: rejects with CCIPRpcNotFoundError when all endpoints fail to connect (2.01174ms)
  βœ” chainGetter: rejects immediately with CCIPRpcNotFoundError once family is already exhausted (0.980743ms)
  βœ” txHash: rejects with CCIPTransactionNotFoundError when tx not on any chain (2.784916ms)
  βœ” txHash: Branch-4 (txOnlyRacer) is destroyed via catch when it loses the tx race (11.6764ms)
  βœ” txHash: chain connecting after txFoundIn is set is immediately destroyed without calling getTransaction (24.081769ms)
  βœ” txHash: Branch-2 chain given to a pending chainGetter is NOT destroyed when it cannot find the tx (14.085051ms)
  βœ” txFoundIn shared across families: SVM txOnlyRacer is destroyed after EVM wins (33.560648ms)
βœ” fetchChainsFromRpcs (179.111958ms)
β–Ά isCantonLedgerUrl
  βœ” matches Canton JSON Ledger API paths (0.131165ms)
  βœ” does not match EVM JSON-RPC URLs (0.090039ms)
βœ” isCantonLedgerUrl (0.41205ms)
β–Ά filterEndpointsForFamily
  βœ” gives Canton only ledger URLs (0.136224ms)
  βœ” gives EVM only non-ledger URLs (0.101179ms)
βœ” filterEndpointsForFamily (0.33165ms)
β–Ά resolveRouter
  βœ” returns explicit CLI -r for any source family (0.174707ms)
  βœ” returns undefined for EVM source without -r (0.082404ms)
βœ” resolveRouter (0.346999ms)
β–Ά resolveCliIndexer
  βœ” prefers explicit CLI --indexer values (0.169998ms)
  βœ” falls back to canton-config indexerUrl when the lane involves Canton (0.102912ms)
  βœ” does not fall back to canton-config indexerUrl for EVM-only lanes (0.082955ms)
  βœ” returns undefined when neither CLI nor config provides an indexer (0.10714ms)
βœ” resolveCliIndexer (0.629537ms)
β–Ά resolveCliRouter
  βœ” prefers explicit CLI -r on Canton source (0.160941ms)
  βœ” prefers explicit CLI -r on EVM source even when canton-config has senderInstanceId (0.089568ms)
  βœ” falls back to canton-config senderInstanceId for Canton source (0.12252ms)
  βœ” does not fall back to senderInstanceId for EVM source (0.097672ms)
βœ” resolveCliRouter (0.683578ms)
β„Ή tests 117
β„Ή suites 39
β„Ή pass 117
β„Ή fail 0
β„Ή cancelled 0
β„Ή skipped 0
β„Ή todo 0
β„Ή duration_ms 149128.778669
---------------------------------------|---------|----------|---------|---------|-------------------
File                                   | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------------------------------|---------|----------|---------|---------|-------------------
All files                              |   77.69 |    78.71 |   67.31 |   77.69 |                   
 ccip-cli/src                          |   90.42 |    59.25 |      75 |   90.42 |                   
  index.ts                             |   90.42 |    59.25 |      75 |   90.42 | ...73-174,180-185 
 ccip-cli/src/commands                 |   52.24 |    74.58 |   61.29 |   52.24 |                   
  index.ts                             |     100 |      100 |     100 |     100 |                   
  lane-latency.ts                      |   70.76 |    83.33 |   33.33 |   70.76 | ...,76-83,119-128 
  lane.ts                              |   86.98 |    68.42 |     100 |   86.98 | ...41-144,148-150 
  manual-exec.ts                       |   20.34 |      100 |       0 |   20.34 | ...39-149,151-347 
  parse.ts                             |    55.2 |      100 |       0 |    55.2 | 47-51,58-65,67-96 
  search.ts                            |   81.25 |      100 |       0 |   81.25 | 24-29             
  send.ts                              |   14.13 |      100 |       0 |   14.13 | ...09-237,239-552 
  show.ts                              |   75.62 |    63.75 |     100 |   75.62 | ...15-318,398-400 
  supported-tokens.ts                  |   17.93 |      100 |       0 |   17.93 | ...80-353,355-368 
  token.ts                             |   22.72 |      100 |       0 |   22.72 | ...3,60-67,69-132 
  types.ts                             |     100 |      100 |     100 |     100 |                   
  utils.ts                             |   86.44 |    78.26 |   93.33 |   86.44 | ...11-721,729-737 
 ccip-cli/src/commands/search          |   53.89 |    76.19 |    12.5 |   53.89 |                   
  messages.ts                          |   53.89 |    76.19 |    12.5 |   53.89 | ...36-258,260-295 
 ccip-cli/src/providers                |   58.73 |     86.2 |   32.72 |   58.73 |                   
  aptos.ts                             |   51.47 |      100 |       0 |   51.47 | ...,95-96,105-136 
  canton.ts                            |   84.98 |    96.29 |      90 |   84.98 | 183-201,252-273   
  evm.ts                               |    36.3 |      100 |       0 |    36.3 | ...69-104,116-168 
  index.ts                             |   84.27 |    82.14 |      90 |   84.27 | ...30-131,289-337 
  solana.ts                            |   47.44 |      100 |       0 |   47.44 | ...02-103,112-137 
  sui.ts                               |    49.5 |      100 |       0 |    49.5 | ...57-258,267-301 
  ton.ts                               |   15.03 |      100 |       0 |   15.03 | 24-153            
 ccip-sdk/src                          |   95.17 |    87.37 |    92.7 |   95.17 |                   
  chain.ts                             |   96.29 |    80.88 |   84.37 |   96.29 | ...2413,2446-2447 
  commits.ts                           |    90.9 |    77.41 |     100 |    90.9 | ...06,115-118,120 
  execution.ts                         |   89.69 |    85.29 |     100 |   89.69 | ...65-172,192-199 
  explorer.ts                          |     100 |      100 |     100 |     100 |                   
  extra-args.ts                        |     100 |    89.47 |     100 |     100 | 225,260,297,312   
  fetch.ts                             |   97.87 |    93.81 |   97.56 |   97.87 | ...-784,1027-1029 
  gas.ts                               |   85.17 |    86.04 |      75 |   85.17 | ...83-294,403-452 
  http-status.ts                       |     100 |      100 |     100 |     100 |                   
  index.ts                             |     100 |      100 |     100 |     100 |                   
  messages.ts                          |    79.2 |    46.15 |      40 |    79.2 | ...99-310,314-327 
  networks.ts                          |     100 |      100 |     100 |     100 |                   
  offchain.ts                          |   84.64 |    76.92 |     100 |   84.64 | ...18-227,236-237 
  requests.ts                          |   95.32 |    90.47 |     100 |   95.32 | ...45-646,671-676 
  supported-chains.ts                  |     100 |      100 |     100 |     100 |                   
  types.ts                             |     100 |      100 |     100 |     100 |                   
  utils.ts                             |    99.2 |    95.97 |     100 |    99.2 | ...12,217-218,220 
 ccip-sdk/src/api                      |   93.22 |    83.44 |   94.73 |   93.22 |                   
  index.ts                             |   93.22 |    83.44 |   94.73 |   93.22 | ...92-895,898-901 
 ccip-sdk/src/aptos                    |   69.29 |    80.82 |   64.06 |   69.29 |                   
  exec.ts                              |   29.31 |      100 |       0 |   29.31 | 18-58             
  hasher.ts                            |   75.89 |       80 |   66.66 |   75.89 | 17-36,50-56       
  index.ts                             |   67.11 |    73.78 |   66.66 |   67.11 | ...1021,1025-1036 
  logs.ts                              |   95.77 |    84.74 |   83.33 |   95.77 | ...56,424,533-544 
  send.ts                              |    25.6 |      100 |       0 |    25.6 | ...2,63-80,93-125 
  token.ts                             |   23.75 |       75 |     100 |   23.75 | 35-156            
  types.ts                             |   65.97 |      100 |       0 |   65.97 | 26-33,65-89       
 ccip-sdk/src/canton                   |    44.7 |    76.56 |   31.66 |    44.7 |                   
  amount.ts                            |   92.59 |       70 |     100 |   92.59 | 22-23             
  ccv-addresses.ts                     |     100 |    91.07 |     100 |     100 | 13,30,64,67       
  defaults.ts                          |   99.28 |    90.24 |     100 |   99.28 | 93                
  events.ts                            |   45.74 |     52.5 |   23.52 |   45.74 | ...13-525,531-540 
  index.ts                             |   33.54 |     60.6 |   12.82 |   33.54 | ...2535,2538-2540 
  types.ts                             |   95.34 |      100 |      50 |   95.34 | 55-62             
  update-id.ts                         |   98.11 |    88.88 |     100 |   98.11 | 52                
 ccip-sdk/src/canton/client            |   56.53 |     61.9 |   20.58 |   56.53 |                   
  client.ts                            |   54.67 |       60 |   20.58 |   54.67 | ...16-735,750-770 
  index.ts                             |     100 |      100 |     100 |     100 |                   
 ...dk/src/canton/explicit-disclosures |   74.81 |    69.35 |    55.1 |   74.81 |                   
  acs.ts                               |   87.36 |     69.1 |      90 |   87.36 | ...20,568,606-607 
  eds.ts                               |   54.34 |      100 |       0 |   54.34 | ...86-393,397-402 
 ccip-sdk/src/canton/token-metadata    |   62.64 |      100 |       0 |   62.64 |                   
  client.ts                            |   62.64 |      100 |       0 |   62.64 | 104-163,170-174   
 ...dk/src/canton/transfer-instruction |    53.4 |      100 |       0 |    53.4 |                   
  client.ts                            |    53.4 |      100 |       0 |    53.4 | 97-180,187-191    
 ccip-sdk/src/errors                   |   89.19 |    76.66 |   54.81 |   89.19 |                   
  CCIPError.ts                         |     100 |      100 |     100 |     100 |                   
  codes.ts                             |     100 |      100 |     100 |     100 |                   
  index.ts                             |     100 |      100 |     100 |     100 |                   
  pure.ts                              |     100 |       75 |     100 |     100 | 32                
  recovery.ts                          |     100 |      100 |     100 |     100 |                   
  specialized.ts                       |   86.79 |    73.11 |   52.34 |   86.79 | ...3606,3629-3638 
  utils.ts                             |   94.44 |    81.48 |     100 |   94.44 | 15,17,22,24       
 ccip-sdk/src/evm                      |   91.36 |    82.19 |   93.04 |   91.36 |                   
  const.ts                             |   98.66 |    92.85 |     100 |   98.66 | 122-123           
  errors.ts                            |   91.98 |    81.57 |     100 |   91.98 | ...85,239-242,247 
  extra-args.ts                        |    94.5 |    61.01 |     100 |    94.5 | ...11-212,328-340 
  fork.test.data.ts                    |     100 |      100 |     100 |     100 |                   
  gas.ts                               |   98.19 |    63.15 |     100 |   98.19 | 90-91,93          
  hasher.ts                            |     100 |     92.3 |     100 |     100 | 135               
  index.ts                             |   85.42 |     80.1 |   90.66 |   85.42 | ...2686,2841-2872 
  logs.ts                              |   99.16 |    92.02 |      90 |   99.16 | 69-70,75-76       
  messageCodec.ts                      |     100 |      100 |     100 |     100 |                   
  messages.ts                          |     100 |      100 |     100 |     100 |                   
  offchain.ts                          |    87.5 |    71.42 |     100 |    87.5 | 13-14             
  simulate.ts                          |     100 |    94.82 |     100 |     100 | 109-111,425       
  types.ts                             |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/evm/viem                 |   79.76 |    90.62 |   69.23 |   79.76 |                   
  client-adapter.ts                    |     100 |       90 |     100 |     100 | 48,74             
  index.ts                             |     100 |      100 |     100 |     100 |                   
  wallet-adapter.ts                    |   63.09 |     90.9 |   55.55 |   63.09 | ...91-124,131-157 
 ccip-sdk/src/hasher                   |   94.29 |    78.94 |     100 |   94.29 |                   
  common.ts                            |     100 |      100 |     100 |     100 |                   
  hasher.ts                            |     100 |    66.66 |     100 |     100 | 19                
  index.ts                             |     100 |      100 |     100 |     100 |                   
  merklemulti.ts                       |   93.43 |       78 |     100 |   93.43 | ...06-307,315-316 
 ccip-sdk/src/shared                   |   85.35 |    84.33 |   82.35 |   85.35 |                   
  bcs-codecs.ts                        |   79.07 |    60.86 |   66.66 |   79.07 | ...42-252,260-269 
  codec.ts                             |   94.32 |    93.22 |     100 |   94.32 | 140-141,179-187   
  constants.ts                         |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/solana                   |   77.11 |    72.43 |    82.4 |   77.11 |                   
  cleanup.ts                           |   26.95 |    66.66 |   33.33 |   26.95 | ...59-101,114-227 
  exec.ts                              |   69.11 |    62.96 |   66.66 |   69.11 | ...69-473,513-514 
  extra-args.ts                        |   58.07 |       75 |      60 |   58.07 | 84-120,130-188    
  fork.test.data.ts                    |     100 |      100 |     100 |     100 |                   
  gas.ts                               |   92.02 |    68.57 |     100 |   92.02 | ...,80-89,169-170 
  hasher.ts                            |   96.49 |    81.81 |     100 |   96.49 | 64-67             
  index.ts                             |   80.51 |       78 |    84.9 |   80.51 | ...2095,2099-2132 
  logs.ts                              |   87.79 |    74.07 |     100 |   87.79 | ...50-151,163-164 
  offchain.ts                          |     100 |      100 |     100 |     100 |                   
  patchBorsh.ts                        |   78.31 |       50 |     100 |   78.31 | ...47,65-66,72-78 
  send.ts                              |    77.6 |    33.33 |      80 |    77.6 | ...52-360,403-442 
  signatures-cache.ts                  |   79.78 |    69.23 |    87.5 |   79.78 | ...51-260,274-275 
  types.ts                             |     100 |      100 |     100 |     100 |                   
  utils.ts                             |   77.44 |    64.17 |   81.25 |   77.44 | ...54-556,588-603 
 ccip-sdk/src/sui                      |   67.03 |    61.87 |   76.69 |   67.03 |                   
  discovery.ts                         |   47.49 |    48.27 |      60 |   47.49 | ...32-780,783-817 
  events.ts                            |   71.09 |     67.1 |    90.9 |   71.09 | ...30-443,470-481 
  exec.ts                              |   30.71 |      100 |       0 |   30.71 | 37-89,101-153     
  hasher.ts                            |   98.19 |    66.66 |     100 |   98.19 | 35,51             
  index.ts                             |   73.69 |    57.58 |   77.96 |   73.69 | ...2117,2133-2134 
  objects.ts                           |   55.24 |    85.45 |   83.33 |   55.24 | ...57-313,324-467 
  types.ts                             |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/sui/manuallyExec         |   53.36 |       75 |      50 |   53.36 |                   
  encoder.ts                           |    83.9 |    66.66 |     100 |    83.9 | 51-58,73-77,82    
  index.ts                             |   33.82 |      100 |       0 |   33.82 | 47-136            
 ccip-sdk/src/ton                      |   85.66 |    79.51 |    87.5 |   85.66 |                   
  exec.ts                              |     100 |      100 |     100 |     100 |                   
  extra-args.ts                        |   98.66 |    72.72 |     100 |   98.66 | 156-157,222       
  hasher.ts                            |   78.07 |    77.77 |      75 |   78.07 | 100-108,156-187   
  index.ts                             |   84.71 |    78.37 |   79.03 |   84.71 | ...2097,2104-2105 
  logs.ts                              |   94.01 |    83.22 |     100 |   94.01 | ...95-602,658-661 
  send.ts                              |   95.52 |    66.66 |     100 |   95.52 | 37-44,188         
  ton-cache.ts                         |     100 |    94.11 |     100 |     100 | 102               
  types.ts                             |   91.24 |    81.25 |     100 |   91.24 | ...61-63,71-74,92 
  utils.ts                             |    63.1 |    77.77 |    90.9 |    63.1 | ...37-395,397-400 
 scripts                               |   77.24 |     64.7 |    90.9 |   77.24 |                   
  useResource.ts                       |   77.24 |     64.7 |    90.9 |   77.24 | ...67-272,287-288 
---------------------------------------|---------|----------|---------|---------|-------------------

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds suffix-based test classification and cross-process network locks to reduce RPC contention during concurrent test execution.

Changes:

  • Adds unit-test filtering and workspace scripts.
  • Serializes networked suites by resource tags.
  • Updates documentation and CI tooling.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/useResource.ts Adds filesystem-based resource locks.
scripts/run-tests.mjs Adds suffix-based test filtering.
package.json Updates root unit-test command.
CONTRIBUTING.md Documents test categories and locks.
CHANGELOG.md Records test infrastructure changes.
ccip-sdk/src/ton/logs.integration.test.ts Locks TON testnet access.
ccip-sdk/src/ton/index.integration.test.ts Locks TON testnet access.
ccip-sdk/src/sui/integration.test.ts Locks Sui and Fuji access.
ccip-sdk/src/solana/fork.test.ts Locks Solana and API access.
ccip-sdk/src/solana/__tests__/integration.test.ts Locks utilized RPC networks.
ccip-sdk/src/evm/integration.test.ts Locks EVM networks and API access.
ccip-sdk/src/evm/fork.test.ts Locks fork upstreams and API access.
ccip-sdk/src/evm/dest-liquidity.integration.test.ts Locks Sepolia and Fuji access.
ccip-sdk/src/evm/dest-liquidity.fork.test.ts Locks fork upstream access.
ccip-sdk/src/api/api.integration.test.ts Locks CCIP API access.
ccip-sdk/package.json Adds SDK unit-test filtering.
ccip-cli/src/commands/show.e2e.test.ts Classifies and locks show E2E tests.
ccip-cli/src/commands/lane.e2e.test.ts Classifies and locks lane E2E tests.
ccip-cli/src/commands/e2e-helpers.test.ts Documents and types CLI output capture.
ccip-cli/package.json Adds CLI unit-test filtering.
.github/workflows/publish.yml Updates workflow actions.
.github/workflows/docs.yml Updates documentation workflow actions.
.github/workflows/ci.yml Updates actions and Foundry installation.
Suppressed comments (3)

scripts/useResource.ts:215

  • release() is documented as idempotent, but a second call decrements an absent count and removes the directory again. If another process acquired the resource after the first release, that second call deletes its live lock. Track whether this handle has already released before touching shared state.
        release: async () => {
          for (const resource of [...wanted].reverse()) {
            const remaining = (held.get(resource) ?? 0) - 1
            if (remaining <= 0) {
              held.delete(resource)
              rmSync(lockDir(resource), { recursive: true, force: true })

scripts/useResource.ts:201

  • Skipping a process-local resource does not increment its refcount for the new handle. Consequently, two useResource(['x']) calls return two handles backed by count 1, and releasing either handle removes the lock while the other is still active. Record pre-held resources once the full requested set has been acquired.
    for (const resource of wanted) {
      if (isHeldHere(resource)) continue
      if (tryAcquire(resource)) {
        held.set(resource, (held.get(resource) ?? 0) + 1)

ccip-cli/src/commands/show.e2e.test.ts:8

  • The show command calls the default CCIP API for every 32-byte transaction hash (show.ts:171-176), but this suite does not acquire the shared api resource. It can therefore contend with the API and EVM/Solana integration suites despite the new locking scheme.

πŸ’‘ Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/useResource.ts Outdated
Comment on lines +153 to +155
if (!isStale(resource)) return false
const holder = describeHolder(resource)
rmSync(dir, { recursive: true, force: true })
Comment thread scripts/run-tests.mjs
Comment on lines +39 to +41
return Object.entries(TAG_SUFFIXES)
.filter(([, suffix]) => lower.endsWith(suffix))
.map(([tag]) => tag)
Comment thread .github/workflows/ci.yml Outdated
Comment on lines +29 to +35
- name: Install Foundry (anvil for fork tests)
uses: foundry-rs/foundry-toolchain@8789b3e21e6c11b2697f5eb56eddae542f746c10 # v1.7.0
run: |
# The canonical one-liner installs the compiled foundryup binary to
# $HOME/.config/.foundry/bin (the legacy ~/.foundry path is gone); running it
# then installs forge/cast/anvil (stable, ethereum β€” the repo defaults).
curl -sSL https://foundry.paradigm.xyz | bash
"$HOME/.config/.foundry/bin/foundryup"
- CLI e2e suites renamed to *.e2e.test.ts; test files classified by
  filename suffix (integration/e2e/fork), excluded from the new
  npm run test:unit via scripts/run-tests.mjs
- add scripts/useResource.ts: OS-level per-network locks (atomic mkdir,
  pid-liveness staleness) so concurrently running node --test suites
  never share a live RPC endpoint; suites hold their networks via
  await useResource([...]) and release on process exit
- harden lock paths for the predictable os.tmpdir() names: owner-only
  mode, symlink/ownership validation (CodeQL js/insecure-temporary-file)
- CI: replace the broken foundry-toolchain action (foundryup is now a
  compiled binary the action still bash-executes) with the official
  installer; bump checkout/setup-node/artifacts/github-script to current
  majors (clears the Node 20 action-runtime deprecation warnings)
- CHANGELOG entry under Unreleased

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.

Comment thread scripts/run-tests.mjs
}

function tagsOf(filePath) {
const name = filePath.split('/').at(-1) ?? ''
Comment thread scripts/useResource.ts
Comment on lines +108 to +113
if (ownerPid !== undefined) {
try {
process.kill(ownerPid, 0) // same-machine pid: locks are per-machine
return false // alive β†’ never steal, regardless of age
} catch (err) {
return (err as NodeJS.ErrnoException).code === 'ESRCH' // dead β†’ stale
Comment thread scripts/useResource.ts
Comment on lines +44 to +47
import { join } from 'node:path'

const LOCK_ROOT =
process.env['CCIP_TOOLS_TEST_LOCK_DIR'] || join(tmpdir(), 'ccip-tools-ts-network-locks')
Comment thread scripts/run-tests.mjs
Comment on lines +30 to +33
const TAG_SUFFIXES = {
integration: 'integration.test.ts',
e2e: 'e2e.test.ts',
fork: 'fork.test.ts',
@andrevmatos

Copy link
Copy Markdown
Collaborator Author

Addressed all review points in ee7c30bb:

Copilot (suppressed)

  • release() idempotency β€” fixed: each handle now tracks its own released state; a second release is a no-op and can no longer delete a lock another process re-acquired.
  • Pre-held resource refcounting β€” fixed: every requested resource (pre-held or freshly acquired) is counted against each handle, so a handle's release withdraws exactly its own share.
  • show.e2e missing api β€” fixed: the suite now also holds the api lock (the show command resolves 32-byte hashes through the default CCIP API).

Copilot (inline)

  • TOCTOU in stale-steal (useResource.ts:155) β€” fixed with an atomic rename-to-tombstone: only one waiter can claim a dead lock (a concurrent stealer's rename fails ENOENT), so nobody can delete another's freshly re-created live lock. Abandoned tombstones are swept in ensureLockRoot.
  • run-tests.mjs suffix boundary β€” fixed: a name classifies as integration only when it is integration.test.ts or ends with a dot-delimited .integration.test.ts (notintegration.test.ts no longer matches).
  • curl | bash supply chain β€” agreed and fixed: reverted to the SHA-pinned foundry-rs/foundry-toolchain@908c540… (# v1.9.1). Verified v1.9.1 executes the now-compiled foundryup directly (run(foundryup, args), no bash) and pins its foundryup installer internally β€” the "cannot execute binary file" breakage was specific to older pins.

CodeQL (github-advanced-security[bot])

  • js/insecure-temporary-file β€” fixed: the owner marker is written with mode: 0o600 (owner-only, per the rule's own isSecureMode predicate), on top of the existing owned-dir/symlink validation. CodeQL now passes.

First CI attempt hit transient upstream flakiness (staging API HTTP 503 on the latency endpoint; toncenter 429s on the TON v2 walk); the rerun on the same commit is fully green.

@andrevmatos
andrevmatos enabled auto-merge (squash) August 25, 2026 17:17

@michelemin michelemin left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving publish.yml

@andrevmatos
andrevmatos merged commit 15cab0a into main Aug 25, 2026
15 of 16 checks passed
@andrevmatos
andrevmatos deleted the tests/contention branch August 25, 2026 17:51

This branch was successfully deployed

1 active deployment
Preview β€” aa1fc4a8 Deployed Aug 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants