Repository navigation
v7.190.1
Derived Maven/Gradle test targets for file selections (issue #3072)
What changed
test_runner with framework maven or gradle, scope: "convention"
(resolution), a non-empty files selection, and no explicit targets used to
fail with Framework "maven" does not support targeted test-file execution
even though the resolved test files map 1:1 to class names for these
frameworks. runTests in src/tools/test-runner.ts now derives the
framework-native selector from the resolved test-file basenames before the
command build:
- Maven:
-Dtest=<ClassA,ClassB>as a single comma-joined argument. - Gradle: one
--tests <Class>pair per target.
Both the dispatch path (buildTestCommandViaDispatch) and the legacy inline
switch receive the same derived targets, so argv is identical under
SWARM_LANG_BACKEND=legacy.
Also in this change:
- R2 sibling mapping: when the resolved test file lives below a nested
module directory, source files are mapped to their sibling test files
relative to that module directory (not the repo root). - G-nested Gradle detection:
detectTestFrameworknow recognizes nested
build.gradle/build.gradle.ktsmodule directories, mirroring the
existing nestedpom.xmlfallback, so execution cwd resolves to the module
that actually owns the tests.
Why
Class-based JVM frameworks cannot take file paths, but a resolved JVM test
selection is exactly a set of test classes. Refusing the selection gave
agents no way to run a targeted Maven/Gradle test sweep through test_runner
(issue #3072), forcing the framework-native selector to be hand-written or the
whole suite swept.
Derivation is deliberately fail-closed: it applies only when every selected
file has a JVM test extension (.java, .kt, .groovy) yielding a non-empty
basename. Any other file in the selection derives nothing and the original
structured error is preserved, and explicit targets always keep precedence.
Frameworks that take file paths are unaffected — the derivation guard only
matches maven/gradle, so no other framework's command changes.
Migration
No configuration change required. Callers that previously passed explicit
targets see identical behavior. Callers that previously received the
unsupported-framework error for a pure JVM test selection now get a targeted
run.
Caveats
- Derivation uses file basenames, so a selection containing a JVM file that
is not a test class (for example a helper undersrc/test/) derives a
class name the build tool cannot match. By default maven (Surefire
failIfNoSpecifiedTests) and gradle fail the run with
No tests matching pattern ... were executedrather than passing with
zero tests; this change deliberately does not set the framework's
ignore-no-match flag, so the failure stays visible and the caller can
rescope the selection. - Scope
allandtargetare excluded from derivation; native-target
pairing validation is unchanged.
/swarm full-auto resume now runs the same authorization preflight as on
Summary
/swarm full-auto resumere-armed a paused Full-Auto run without consulting
the authorization checks that/swarm full-auto onruns: the
configHadErrorsfail-closed guard and thefull_auto.locked
administrative hard-off. On a project whose config was locked or unreadable,
onwas correctly refused whileresumestill re-armed the run — defeating
the lock exactly where it was supposed to refuse activation.- The enable path's preflight is now a single shared predicate in
src/commands/full-auto.tsthat both activation paths consult:resumeis
activation for lock purposes and is refused identically toonwhen the
config is locked or cannot be parsed. A refused resume leaves the durable
run paused and the session flag untouched. - Refusal precedence and ordering are pinned by tests: an unreadable config
wins over a user-level lock (the lock cannot be verified in an unreadable
config), and the authorization preflight runs before any resume-eligibility
check, so the fail-closed message cannot be masked by a stale or invalid
recovery probe. retry-oversight(a transport-only health probe that never activates), the
full-auto escalation paths, andoff/status/abortbehavior are
unchanged: a locked project keeps its documented recovery controls.