Skip to content

test(amber): cover the runtime's serde bootstrap and worker startup - #7663

Merged
aglinxinyuan merged 1 commit into
apache:mainfrom
aglinxinyuan:cov/amber-runtime
Aug 15, 2026
Merged

test(amber): cover the runtime's serde bootstrap and worker startup#7663
aglinxinyuan merged 1 commit into
apache:mainfrom
aglinxinyuan:cov/amber-runtime

Conversation

@aglinxinyuan

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

AmberRuntime had no spec. It owns the actor system the rest of amber leans on, the serialization extension every message goes through, and the scheduling helpers services use for recurring work.

Adds 15 tests, taking the file from 12.20% to 65.85% of lines (5/41 → 27/41, branches 1/8 → 5/8).

Nothing needs a cluster: startActorWorker(None) builds its whole system with artery on port 0 in under 100 ms, makes no network call, and tears down again — so the worker startup path is drivable end to end.

Covered: the serde bootstrap and its memoization, extending an installed system rather than replacing it, both scheduling helpers including cancellation and the recurring delay, the seed-node URI and master address, the artery host binding, the config fallback chain, and the two child actors with their dead-letter subscription.

Cross-suite safety

This matters more than the coverage number. amber sets neither Test / fork nor Test / parallelExecution := false, so every suite shares one JVM — and this file is the global state others depend on. The spec saves and restores _actorSystem, _serde and AmberConfig.masterNodeAddr by reflection, the way eight sibling specs already do, and terminates every system it starts.

Verified rather than asserted: run alongside ClusterListenerSpec and SessionStateSpec, all 21 tests pass. Review also drove twelve runtime-touching suites in one shared JVM with a sentinel system and address installed beforehand, and confirmed both were handed back untouched.

Verification

21 mutations applied one at a time and reverted, production diff empty each time.

Review then found three survivors, and two of the three are the same failure mode:

Survivor Why it passed Fix
the fallback chain dropping pekkoConfig the assertion read artery.transport == "tcp", which is pekko's own reference.conf default — it holds with pekkoConfig absent entirely assert the kryo serializer binding, which only cluster.conf supplies
the serde bound to a different, same-named system the test compared system.name == "Amber", not identity capture and compare with eq
ClusterListener swapped for DeadLetterMonitorActor at the same path an ActorRef exposes no class, and nothing exchanges a message only one answers not fixed — recorded in the spec instead; pinning it would mean adding a seam production does not need

The first of those also exposed a measurement error worth stating: the build reported that mutation as killed, but the kill came from an earlier assertion in the same test failing first (actor.provider == "cluster", which is genuine), so the transport line was never evaluated. A red test is not evidence that the assertion you care about pins anything.

One further mutation survived during the build and was resolved by deleting the assertion rather than keeping it: cluster.conf already sets canonical.port = 0, so the production override of it is unobservable.

Deliberately not included

getNodeIpAddress and startActorMaster bind real network interfaces. One partial branch remains at the mainNodeAddress.isDefined guard, whose true arm needs that same address lookup.

No production file is touched.

Any related issues, documentation, discussions?

Closes #7662

How was this PR tested?

STORAGE_ICEBERG_CATALOG_TYPE=postgres sbt "WorkflowExecutionService/testOnly org.apache.texera.amber.engine.common.AmberRuntimeSpec"
[info] Total number of tests run: 15
[info] Tests: succeeded 15, failed 0, canceled 0, ignored 0, pending 0

Test/scalafmtCheck and Test/scalafix --check both pass.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 5)

AmberRuntime had no spec. It owns the actor system the rest of amber
leans on, the serialization extension every message goes through, and the
scheduling helpers services use for recurring work - and none of it was
verified.

Adds 15 tests, taking the file from 12.20% to 65.85% of lines. Nothing
needs a cluster: startActorWorker(None) builds its whole system with
artery on port 0 in under 100ms, makes no network call, and tears down
again, so the worker startup path is drivable end to end.

Covered: the serde bootstrap and its memoization, extending an installed
system rather than replacing it, both scheduling helpers including
cancellation and the recurring delay, the seed-node URI and master
address, the artery host binding, the config fallback chain, and the two
child actors with their dead-letter subscription.

The spec saves and restores AmberRuntime's globals by reflection, the
same way eight sibling specs do, and terminates every system it starts;
run alongside ClusterListenerSpec and SessionStateSpec, all 21 pass.

Left uncovered: getNodeIpAddress and startActorMaster, which bind real
network interfaces.

No production file is touched.
Copilot AI lite review requested due to automatic review settings August 14, 2026 09:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • No candidates found from git blame history.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 2 better · 🔴 6 worse · ⚪ 7 noise (<±5%) · 0 without baseline

Compared against main 8e80187 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 349 0.213 27,776/33,948/33,948 us 🟢 -12.0% / 🔴 +118.1%
🔴 bs=100 sw=10 sl=64 749 0.457 131,353/162,507/162,507 us 🔴 +8.6% / 🔴 +51.0%
bs=1000 sw=10 sl=64 867 0.529 1,147,592/1,270,796/1,270,796 us ⚪ within ±5% / 🔴 +22.6%
Baseline details

Latest main 8e80187 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 349 tuples/sec 375 tuples/sec 774.89 tuples/sec -6.9% -55.0%
bs=10 sw=10 sl=64 MB/s 0.213 MB/s 0.229 MB/s 0.473 MB/s -7.0% -55.0%
bs=10 sw=10 sl=64 p50 27,776 us 26,148 us 12,738 us +6.2% +118.1%
bs=10 sw=10 sl=64 p95 33,948 us 38,574 us 16,348 us -12.0% +107.7%
bs=10 sw=10 sl=64 p99 33,948 us 38,574 us 18,848 us -12.0% +80.1%
bs=100 sw=10 sl=64 throughput 749 tuples/sec 791 tuples/sec 1,005 tuples/sec -5.3% -25.4%
bs=100 sw=10 sl=64 MB/s 0.457 MB/s 0.483 MB/s 0.613 MB/s -5.4% -25.5%
bs=100 sw=10 sl=64 p50 131,353 us 120,958 us 100,970 us +8.6% +30.1%
bs=100 sw=10 sl=64 p95 162,507 us 166,345 us 107,605 us -2.3% +51.0%
bs=100 sw=10 sl=64 p99 162,507 us 166,345 us 116,429 us -2.3% +39.6%
bs=1000 sw=10 sl=64 throughput 867 tuples/sec 883 tuples/sec 1,030 tuples/sec -1.8% -15.9%
bs=1000 sw=10 sl=64 MB/s 0.529 MB/s 0.539 MB/s 0.629 MB/s -1.9% -15.9%
bs=1000 sw=10 sl=64 p50 1,147,592 us 1,122,125 us 991,433 us +2.3% +15.8%
bs=1000 sw=10 sl=64 p95 1,270,796 us 1,264,503 us 1,036,668 us +0.5% +22.6%
bs=1000 sw=10 sl=64 p99 1,270,796 us 1,264,503 us 1,070,470 us +0.5% +18.7%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,573.34,200,128000,349,0.213,27776.44,33948.01,33948.01
1,100,10,64,20,2669.00,2000,1280000,749,0.457,131352.95,162507.42,162507.42
2,1000,10,64,20,23080.18,20000,12800000,867,0.529,1147592.08,1270795.80,1270795.80

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.15%. Comparing base (8e80187) to head (f473f28).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #7663      +/-   ##
============================================
+ Coverage     90.13%   90.15%   +0.02%     
+ Complexity     4414     4410       -4     
============================================
  Files          1174     1174              
  Lines         46964    46964              
  Branches       5262     5262              
============================================
+ Hits          42329    42342      +13     
+ Misses         2877     2860      -17     
- Partials       1758     1762       +4     
Flag Coverage Δ *Carryforward flag
access-control-service 70.00% <ø> (ø) Carriedforward from 8e80187
agent-service 98.62% <ø> (ø) Carriedforward from 8e80187
amber 86.79% <ø> (+0.07%) ⬆️
computing-unit-managing-service 72.46% <ø> (ø) Carriedforward from 8e80187
config-service 77.31% <ø> (ø) Carriedforward from 8e80187
file-service 68.90% <ø> (ø) Carriedforward from 8e80187
frontend 91.44% <ø> (ø) Carriedforward from 8e80187
notebook-migration-service 78.89% <ø> (ø) Carriedforward from 8e80187
pyamber 97.57% <ø> (ø) Carriedforward from 8e80187
workflow-compiling-service 57.89% <ø> (ø) Carriedforward from 8e80187

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (2)

amber/src/test/scala/org/apache/texera/amber/engine/common/AmberRuntimeSpec.scala:323

  • workerStartup restores _actorSystem/_serde but leaves other globals (e.g., AmberConfig.masterNodeAddr, ClusterListener.numWorkerNodesInCluster) potentially mutated until afterAll. Restoring these inside the fixture’s finally keeps the cross-suite visibility window as short as possible (see ClusterListenerSpec’s pattern).
    } finally {
      setAmberRuntimeField("_actorSystem", testSystem)
      setAmberRuntimeField("_serde", testSerde)
      if (created != null) TestKit.shutdownActorSystem(created)
    }

amber/src/test/scala/org/apache/texera/amber/engine/common/AmberRuntimeSpec.scala:292

  • workerStartup mutates JVM-global AmberConfig.masterNodeAddr but doesn’t restore it in the fixture’s finally. Since amber suites can run concurrently in one JVM, other suites can observe the mutated address for the remainder of this suite (until afterAll), which is longer than one test.

This issue also appears on line 319 of the same file.

  private lazy val workerStartup: WorkerStartup = {
    // A sentinel is mandatory: AmberConfig.masterNodeAddr's DEFAULT is already
    // Address("pekko", "Amber", "localhost", 2552), so without this the
    // masterNodeAddr case would assert a value that held before the call.
    AmberConfig.masterNodeAddr = Address("pekko", "Sentinel", "nowhere", 1)

@mengw15 mengw15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@aglinxinyuan
aglinxinyuan added this pull request to the merge queue Aug 15, 2026
Merged via the queue into apache:main with commit cb811a8 Aug 15, 2026
24 checks passed
@aglinxinyuan
aglinxinyuan deleted the cov/amber-runtime branch August 15, 2026 01:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cover the runtime's serde bootstrap and worker startup

4 participants