213 Commits
Author SHA1 Message Date
EugeneandEugene f4618946c5 [2.x] fix: Read all forked test output before reporting the fork's exit (#9860)
**Problem**
When a forked test JVM exits, WorkerProxy.watch calls notifyExit right
away, and on exit code 0 that completes the run. If the response reader
has not consumed the rest of the stream yet, the remaining events, logs and
the final response are dropped, and the build passes with failing tests
unreported. Slow listeners, or several forks at once, make this likely.

**Solution**
Track when the response stream reaches end of input (the socket reader for
Tcp/Ipc, stdout for Stdio), and have the watch thread wait for it, with a
bound, before calling notifyExit. This is what sbt 1.x did by joining the
acceptor thread. The new scripted test uses a listener that sleeps per
event, and fails without this change.

Fixes #9859

Generated-by: Claude Opus 5.5

Co-authored-by: Eugene <[email protected]>
2026-10-03 23:12:50 -04:00
eugene yokota c8a0007d6e [2.x] feat: Persistent worker for test (#9678) 2026-09-25 03:30:09 -04:00
Eugene Yokota f9688c1464 Apply Scalafmt format (Scala 3 syntax) 2026-09-10 14:16:27 -04:00
eugene yokota 01198f5407 [2.x] feat: workerMaxInstances + testTopology (#9665)
* [2.x] feat: testForkedWorker setting

**Problem**
A major bottleneck of the default setting is that concurrentRestriction
allows exactly one forked test in flight at a time,
and partly due to the restriction all test suites from a subproject runs
within the forked process.

**Solution**
This adds a new setting called testForkedWorker, which lets the build users
tune the number of concurrent worker process in flight.
I've set the default to CPU count / 3.
Within a single worker, the default parallelism is reduced to 2.

The default test grouping now splits the test suites into
testForkedWorker count.

* Use Global scope for overall worker count

Subproject scoping can be used for single vs split

* Adds math.max(..., 1)

* Avoid running setup/cleanup on an empty selection

* Fix the tag application order

* Rename key to workerMaxInstances

* Implement TestTopology

* fix: Fixes exclusive test

Note due to the limitation of the tag system, setup-clean/cleanup
may overlap.

* Check that workerMaxInstances >= 1
2026-09-09 14:13:13 +09:00
eugene yokota a62c3d62f4 [2.x] Scala 3.9.0 (#9439)
Use Scala 3.9.0 for metabuild.
2026-08-27 01:44:57 -04:00
Anatolii Kmetiukandeugene yokota 0da3f6b478 [2.x] Add test result cache opt-out (#9675)
* [2.x] Add test result cache opt-out

* Update main/src/main/scala/sbt/internal/SysProp.scala

Co-authored-by: eugene yokota <[email protected]>

* Use Boolean values for test cache opt-out

---------

Co-authored-by: eugene yokota <[email protected]>
2026-08-26 11:27:05 +09:00
Mai Huy HoàngandClaude Opus 5 e98ead410c [2.x] perf: write packageBin jars and action cache zips in parallel (#9661)
sbt writes two archives per module per build: the packageBin /
packageInternal jar, and the zip the disk action cache stores an output
directory as. Both deflate one entry at a time on the calling thread.

io 1.13.0 adds IO.jarParallel / IO.zipParallel, which deflate entries
concurrently and produce byte-identical archives. Switch both call sites
over, taking the executor from IO.Implicits.zipContext -- io keeps it
behind that object so the choice is explicit rather than an ambient
ExecutionContext.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-08-25 10:56:08 -04:00
eugene yokota d4ada26c86 [2.x] fix: Fixes JDK 17 domain socket deadlocks (#9671)
**Problem**
Channels.newInputStream/newOutputStream share a channel-wide lock,
which would deadlock for a duplex communication.

**Solution**
This implements an alternative DuplexChannels functions that's capable
of duplex communication expected of a "socket".

This also duplicates the Java implementation to the worker app,
so we can use JDK domain socket for forked test communication.
2026-08-25 02:02:37 -04:00
Dmitrii NaumenkoandCodex b1ea80d066 [2.x] fix: Restore public test result report types (#9655)
**Problem**
Commit c8737b8e4f, "refactor: Change the test type" (PR #8181, Eugene Yokota), made Tests.Output and SuiteResult private[sbt] while changing test tasks to return TestResult. The stated rationale was to type test tasks; it did not describe restricting TestResultLogger customization.

TestResultLogger remains a public, documented extension point, but its run method accepts Tests.Output. External plugins consequently cannot implement it in source. This was noticed while working on TW-102637.

**Solution**
Restore public visibility for Tests.Output, SuiteResult, and its companion. Add a scripted external-build regression test that implements TestResultLogger, uses Output.events as Iterable[SuiteResult], runs test, and observes the logger.

---------

Co-authored-by: Codex <[email protected]>
2026-08-24 12:26:08 -04:00
eugene yokota 27c3f035e5 [2.x] feat: Test summary (#9602)
**Problem/Solution**
This extends the idea started with TestRecap, and applies it to
both test success and failures.

1. Existing TestResultLogger trait is extended to handle the summary
   rendering.
2. TestSummary enum is added to control the verbosity via
   commandline option, system property, or a setting.
3. Script test captures the log.
2026-08-17 23:54:32 -04:00
Kevin Lee 97a1dc360b [2.x] fix: Fixes three test-classloader / jar-handle leaks in the sbt server JVM (#9485)
Three independent, pre-existing retention bugs kept the classloader of a
finished in-process test run -- and the open jar handles it holds -- alive
for the rest of the server session.

- JUnitXmlTestsListener: testSuite is an InheritableThreadLocal, so
  threads spawned during a run (e.g. async-framework pool workers) inherit
  a copy of the suite reference that remove() cannot reach.

- TestRecap.collect: the recap is stashed on State.attributes and outlives
  the command, so it must not retain live throwables.

- ClassLoaderCache: loaders evicted from delegate by clearExpiredLoaders
  are unreachable from the map and never enqueued on the ReferenceQueue, so
  neither clear()/close() nor the cleanup thread could ever close them.

SuiteResult now documents the retention hazard on throwables. Adds
deterministic, cross-platform tests for all three severed chains.
2026-07-23 18:05:37 -04:00
kenji yoshida 5310381bb4 [2.x] Avoid dollars in name (#9313) 2026-06-08 23:39:10 -04:00
eugene yokota 315202181c [2.x] ci: Scalafmt 3.11.1 (#9279)
Apply Scalafmt
2026-05-31 16:01:15 -04:00
BrianHotoppandClaude Opus 4.7 68dde13fdc [2.x] feat: Print cross-project test failure recap at end of aggregated run (#9214)
Fixes #2998

When test is run at the prompt in a multi-project build,
sbt aggregates <proj>/test across subprojects. Each subproject's
TestResultLogger emits its own pass/fail summary inline, but the
aggregation layer never restated which projects failed. The final
"sbt.TestsFailedException" line surfaced no project names or failing
test classes, so on CI users had to scrollback-grep through thousands
of log lines to find what broke.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-15 15:41:39 -04:00
Anatolii Kmetiuk 1f151ad6e3 [2.x] Fix #9190: Ensure resources are copied atomically (#9193)
Bumps io to released 1.12.0 which contains the atomic-write changes
to IO.copyFile, IO.transfer(InputStream, File), and IO.jar/zip.
ActionCacheStore.putBlob now uses IO.transfer instead of duplicating
staging logic.
2026-05-07 01:22:22 -04:00
kenji yoshidaandEugene Yokota 21403eeefc [2.x] Add ForkOptions.connectionTimeout (#9172)
---------

Co-authored-by: Eugene Yokota <[email protected]>
2026-05-03 13:51:09 -04:00
eugene yokota 5586488f6c [2.x] fix: Adjust the forked test classpath (#9170)
**Problem**
We can't test WorkerMain using forked test.

**Solution**
Allow WorkerMain to be shadowed.
2026-05-03 02:36:00 -04:00
eugene yokota 4a02167fa4 [2.x] feat: ClassLoaderStrategy.Raw (#9161)
**Problem**
In sbt 2.x, forking still creates layered classloader in the worker process,
which doesn't work for some tests.

**Solution**
This provides an escape hatch to emulate the sbt 1.x semantics of
using the system classpath for testing.
2026-04-30 12:35:30 -04:00
Clayton ef90ca0540 [2.x] feat: Forward test events to listeners as they are emitted (#9087)
Test report listeners now receive testEvent callbacks as the underlying test framework emits events, instead of only after a whole group finishes. startGroup / endGroup timing is aligned with that streaming model for both in-process and forked test runs.

No public API changes - only listener callback timing and the internal worker <-> sbt JSON-RPC protocol.
2026-04-16 00:58:06 -04:00
kenji yoshida 767ebec906 [2.x] override sbt.Tests.Group hashCode (#9065) 2026-04-11 13:40:28 -04:00
kenji yoshida 6d44aca9b1 Add parentheses (#9000) 2026-03-31 13:48:59 -04:00
PandaMan c7da2b72c3 [2.x] fix: Fixes explicitlySpecified and selectors for testOnly (#8727)
**Problem**
When the user runs testOnly with an explicit suite name (e.g. testOnly com.example.MySuite),
ScalaTest suites annotated with @DoNotDiscover were not run because sbt always passed
explicitlySpecified=false to the test framework.

**Solution**
In Tests.processOptions, when the user has specified test filters (orderedFilters.nonEmpty),
mark the filtered tests as explicitlySpecified=true with SuiteSelector so frameworks
can run @DoNotDiscover suites when explicitly requested.
2026-02-13 09:19:05 -08:00
eugene yokota edd7061f15 [2.x] Minimalist console (#8722)
**Problem**
Forked console currently pulls in full Zinc, which includes JLine.

**Solution**
This implements a lighter-weight, full Java ForkConsoleMain,
which no longer depends on JLine.
2026-02-09 10:55:44 -05:00
Eugene Yokota 138621eacb [2.x] client-side console and fixes
**Problem**
1. forked console is missing user code from the classpath.
2. forked console still blocks the server.

**Solution**
1. This includes proper products and classpaths to the console.
2. This also implements client-side run for console.
2026-02-07 00:42:54 -05:00
DEBORAH FUNMILOLA OLABOYE a66a3064f9 [2.x] fix: Display HTTP response body when bundle upload fails (#8630)
When a bundle upload to Central Portal fails, the error now displays the HTTP response body instead of just the status code. This provides more useful debugging information, as the response body typically contains detailed error messages from the server.
2026-01-28 10:36:45 -05:00
eugene yokota cc0915fed9 [2.x] refactor: Scala Instance (#8648)
**Problem**
Strings are used to pass paths around.

**Solution**
This cleans up the Scala instance construction code.
2026-01-28 02:27:57 -05:00
calm 9951a302c9 [2.x] feat: Support fork in console task (#8604)
When enabled, the Scala REPL runs in a separate JVM.
2026-01-25 02:16:49 -05:00
Eugene Yokota 9813e60fe3 refactor: Clean up infix etc 2026-01-24 04:52:28 -05:00
calm c099be5f18 [2.x] fix: Race condition in WorkerExchangeTest.propBye (#8606) 2026-01-22 00:49:41 -05:00
eugene yokota 215e9d6325 [2.x] fix: Prevent fork test cross talk (#8575)
**Problem**
currently all notifications go to all listeners.

**Solution**
This adds "re" field so we can check if it matches with the id.
2026-01-19 00:55:16 -05:00
E.GandGlobalStar117 574654900f [2.x] test: migrate SonaClientTest from ScalaTest to verify.BasicTestSuite (#8562)
- Convert class to object with BasicTestSuite
- Use test() syntax instead of 'should ... in'
- Move RecordingLogger and extension to top-level
- Use Scala 3 colon indentation syntax

Co-authored-by: GlobalStar117 <[email protected]>
2026-01-18 14:31:06 -05:00
MkDev11 fb53925fb6 [2.x] fix: Prevent sbt test from hanging when forked process crashes (#8536)
When a forked test process crashes (e.g., due to UnsupportedClassVersionError),
sbt would hang forever waiting for test results. This happened because
notifyExit only completed the promise with success, regardless of the
exit code.

This fix checks the exit code and fails the promise if the process
exited with a non-zero code, allowing sbt to properly report the failure
and exit.

Fixes #7429
2026-01-14 21:54:17 -05:00
MkDev11 061145e67b [2.x] Add testForkedParallelism setting for forked test thread count (#8453)
**Problems**

When running forked tests, sbt uses `Runtime.getRuntime().availableProcessors()` to determine the thread pool size, ignoring `concurrentRestrictions`. This is inconsistent with non-forked parallel tests.

**Expectations**

Users should be able to control the number of parallel test threads in forked mode, similar to how `concurrentRestrictions` works for non-forked tests.

**Notes**

Added a new setting `testForkedParallelism` that allows explicit control:

```scala
testForkedParallelism := Some(2)  // Use 2 threads
testForkedParallelism := None     // Use availableProcessors() (default)
```
2026-01-09 12:43:50 -05:00
Eugene Yokota c20d83a8e2 Use TCP for the fork test
**Problem**
Forked test currently uses stdio, but that println to be lost.

**Solution**
Use TCP for communication similar to sbt 1.x.
2026-01-04 01:48:45 -05:00
Eugene Yokota 9888aae7fa [2.x] Switch to using shaded-gson
Fixes https://github.com/sbt/sbt/issues/8334
2025-12-15 03:17:33 -05:00
xuwei-k 038fa6c476 remove unnecessary nowarn annotations 2025-10-04 19:25:11 +09:00
Eugene Yokota 645908f597 Apply Contraband 2025-09-28 21:28:21 -04:00
Eugene Yokota 2fa3159f18 Update to Contraband 0.8.0 2025-09-19 00:46:34 -04:00
Eugene Yokota f7a3c593e9 fix: Catch gson parsing error
If non-JSON leaks into stdout, send it to the logger.
2025-09-13 22:52:24 -04:00
Eugene Yokota ed0b16375d Update test 2025-08-09 13:58:35 -04:00
Eugene Yokota 7d00a2c51d Merge branch '1.11.x' into wip/merge-1.11.x 2025-08-09 13:47:36 -04:00
Dmitrii Naumenko b83eee4528 [sonatype publishing] print deployment validation errors if present
Before this change you had to log into the sonatype account and search for the errors there.
(https://central.sonatype.com/publishing/deployments)
This was inconvenient, especially if you don't have the admin access to the account.
2025-08-04 15:03:53 +02:00
Eugene Yokota b1a3ef3743 Merge branch '1.11.x' into wip/merge-1.11.x 2025-08-02 23:13:41 -04:00
Eugene Yokota c8737b8e4f refactor: Change the test type
**Problem**
test task is typed to unit.
To distinguish test from any other tasks, we want to actually type this to something.

**Solution**
Forward TestResult to the test task.
2025-08-02 18:12:20 -04:00
Eugene Yokota 9b1e644be1 fix: Use promise to wait for forked test
**Problem**
I'm seeing NPE in some test-related tests like tests/junit:
[info] [error] java.lang.NullPointerException: Null output stream
[info] [error] 	at java.io.PrintStream.requireNonNull(PrintStream.java:79)
[info] [error] 	at java.io.PrintStream.<init>(PrintStream.java:151)
[info] [error] 	at java.io.PrintStream.<init>(PrintStream.java:135)
[info] [error] 	at sbt.internal.WorkerProxy.inputStream$lzyINIT1(WorkerExchange.scala:69)
[info] [error] 	at sbt.internal.WorkerProxy.inputStream(WorkerExchange.scala:69)
[info] [error] 	at sbt.internal.WorkerProxy.println(WorkerExchange.scala:77)
[info] [error] 	at sbt.ForkTests$.mainTestTask$$anonfun$1(ForkTests.scala:160)

This is likely coming from ProcessBuilder#run not immediately processing the passed in processIO.

**Solution**
This uses Promise to wait for the processIO to be processed.
2025-08-02 15:14:22 -04:00
Jules Ivanic 8c0010a086 Review: the new configurable request timeout value should be 10.minutes and should only be used for upload 2025-07-04 16:40:52 +04:00
Eugene Yokota b247e2620f Reimplement test agent as a worker command
This sends JSON-RPC over stdin as opposed to using ObjectStream over socket.
2025-07-04 01:28:56 -04:00
Jules Ivanic 084ca08f34 Allow users to configure the timeout when publishing to the Maven Central repo 2025-07-02 13:53:50 +04:00
Leonidas Spyropoulos 1cd9c1ec64 fix: semanticdb expects Wildcard imports to be in the last position
Signed-off-by: Leonidas Spyropoulos <[email protected]>
2025-06-11 08:57:07 +01:00
Eugene Yokota e023c2dc64 Merge branch '1.11.x' into wip/merge-1.11.x 2025-05-25 17:20:48 -04:00