Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1667,11 +1667,24 @@ It runs twice: in the `package` job over `llama/target` (every classifier jar pl
jar, as early as they exist), and again in `smoke-fatjar-linux` over the downloaded `fatjars/` —
`package-fatjars` rewrites those zips, and they are the artifacts users actually download.

**Surefire excludes `org.slf4j:slf4j-simple` from the test classpath** (`classpathDependencyExcludes`).
Runtime scope is on the test classpath too, and LogCaptor (test scope) requires logback specifically —
with both providers present it fails with *"SLF4J Logger implementation should be of the type
[ch.qos.logback.classic.Logger]"*. The exclusion leaves logback the sole provider in tests and does
not touch the artifact.
**Surefire AND PIT both exclude `org.slf4j:slf4j-simple` from the test classpath**
(`classpathDependencyExcludes` in each). Runtime scope is on the test classpath too, and LogCaptor
(test scope) requires logback specifically — with both providers present SLF4J's `ServiceLoader`
picks one arbitrarily and the LogCaptor assertions fail. The exclusions leave logback the sole
provider in tests and do not touch the artifact: the jar and the fat jar still ship slf4j-simple.

**The PIT half is not redundant, and forgetting it is a trap worth naming.** `spotbugs:check` and
`spotless:check` bind to `verify`, so `mvn test` misses them — a different trap. This one is
sharper: **PIT builds its own classpath and never reads Surefire's configuration**, so a
Surefire-only exclusion leaves the mutation run with two providers. It then aborts the whole gate
with *"N tests did not pass without mutation … requires a green suite"* — a red gate on a suite
Surefire had just reported green, which reads like a PIT bug rather than a classpath one. This
shipped once (#411 added the binding with only the Surefire exclusion; the five affected
LogCaptor tests reddened `Java Tests Ubuntu` and the failure went unseen because every publish run
in between was cancelled). The sibling repo srcmorph hit the identical thing and solved it a
different way — there both providers arrive transitively, so it excludes at the dependency instead.
Same rule either way: **one SLF4J provider on the test classpath, enforced everywhere a test
classpath is built.**

## SpotBugs Suppressions

Expand Down
19 changes: 19 additions & 0 deletions llama/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,25 @@ SPDX-License-Identifier: MIT
</targetTests>
<mutationThreshold>100</mutationThreshold>
<timeoutConstant>30000</timeoutConstant>
<!--
The same exclusion Surefire carries above, and it has to be repeated here
because PIT builds its OWN classpath and does not read Surefire's
configuration. Two SLF4J providers are on the test classpath: slf4j-simple
arrives at runtime scope (it is the binding shipped in the fat jar) and
logback-classic at test scope (LogCaptor requires logback specifically).
SLF4J's ServiceLoader then picks one arbitrarily; when it picks
slf4j-simple, every LogCaptor assertion fails and PIT aborts the whole run
with "N tests did not pass without mutation ... requires a green suite" —
a red gate on a suite Surefire had just run green, which is a genuinely
confusing failure to land on.

The parameter is pitest-maven's own, modelled on Surefire's and taking the
same "groupId:artifactId" form. It changes nothing about the artifact: the
jar and the fat jar still ship slf4j-simple.
-->
<classpathDependencyExcludes>
<classpathDependencyExclude>org.slf4j:slf4j-simple</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
</plugins>
Expand Down
26 changes: 26 additions & 0 deletions llama/src/test/java/net/ladenthin/llama/args/FlashAttnTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2026 Bernard Ladenthin <bernard.ladenthin@gmail.com>
//
// SPDX-License-Identifier: MIT

package net.ladenthin.llama.args;

import java.util.Arrays;
import java.util.Collection;

/**
* The three {@code --flash-attn} values, pinned to the exact tokens llama.cpp's parser accepts.
*
* <p>These strings are a wire contract, not labels: since llama.cpp b10273 the option takes a
* mandatory value, so a wrong or empty token is not a cosmetic defect — the parser consumes the
* following argv entry and the model load fails naming a flag the caller never set.</p>
*/
public class FlashAttnTest extends AbstractCliArgEnumTest<FlashAttn> {

public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{FlashAttn.ON, "on", 3},
{FlashAttn.OFF, "off", 3},
{FlashAttn.AUTO, "auto", 3},
});
}
}
Loading