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
1 change: 1 addition & 0 deletions .github/models.csv
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ SmolVLM-500M-Instruct-Q8_0.gguf,https://huggingface.co/ggml-org/SmolVLM-500M-Ins
mmproj-SmolVLM-500M-Instruct-Q8_0.gguf,https://huggingface.co/ggml-org/SmolVLM-500M-Instruct-GGUF/resolve/main/mmproj-SmolVLM-500M-Instruct-Q8_0.gguf
Qwen3-TTS-12Hz-1.7B-Base-Q4_K_M.gguf,https://huggingface.co/ggml-org/Qwen3-TTS-12Hz-1.7B-Base-GGUF/resolve/main/Qwen3-TTS-12Hz-1.7B-Base-Q4_K_M.gguf
mmproj-Qwen3-TTS-12Hz-1.7B-Base-Q8_0.gguf,https://huggingface.co/ggml-org/Qwen3-TTS-12Hz-1.7B-Base-GGUF/resolve/main/mmproj-Qwen3-TTS-12Hz-1.7B-Base-Q8_0.gguf
stories260K.gguf,https://huggingface.co/ggml-org/tiny-llamas/resolve/main/stories260K.gguf
78 changes: 78 additions & 0 deletions .github/verify-patches-applied.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash

# SPDX-FileCopyrightText: 2026 Bernard Ladenthin <[email protected]>
#
# SPDX-License-Identifier: MIT OR Apache-2.0

# Asserts that every llama/patches/*.patch really reached the fetched llama.cpp tree.
#
# WHY THIS EXISTS. The patch applier (llama/cmake/apply-llama-patches.cmake) is fail-loud on
# "does not apply", so a *stale* patch cannot ship silently. What it cannot detect is a patch
# that stops having an effect while still applying, and most patches do not need this check
# because they have a runnable guard that reds CI on every platform if they go missing:
#
# 0003, 0006, 0007, 0008 -> jllama.cpp / native_server.cpp call the symbols they add,
# so dropping one is a compile or link error.
# 0011 -> the ContentOnlyParseUtf8 tests in src/test/cpp/test_utils.cpp.
# 0012 -> src/test/cpp/test_model_split.cpp.
# 0001, 0002 -> model-gated Java jobs (Windows argv, LoadProgressCallbackTest).
#
# `0010` is the exception and the reason for this script. It casts one enum to int inside
# upstream's `get_res_model_info()`, which is `static` in server-context.cpp and therefore
# unreachable from jllama_test; reverting it leaves `ctest` completely green. Its only guard is
# NativeServerAttachIntegrationTest.models_reportNumericVocabType, which is model-gated — so the
# day a platform stops downloading models, the regression ships. This check runs in the
# always-on `C++ Tests` job, needs no model, and costs milliseconds.
#
# Usage: .github/verify-patches-applied.sh [<llama.cpp-src-dir>]
# Exit codes: 0 all good, 1 a check failed.

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SRC="${1:-$ROOT/llama/build/_deps/llama.cpp-src}"
PATCH_DIR="$ROOT/llama/patches"
STAMP="$SRC/.jllama-patches-applied"

fail() {
echo "ERROR: $*" >&2
exit 1
}

[ -d "$SRC" ] || fail "llama.cpp source dir not found: $SRC (configure the build first)"
[ -f "$STAMP" ] || fail "patch stamp not found: $STAMP — the applier never ran, so the tree is unpatched"

# --- 1. every patch on disk is named in the stamp -----------------------------------------------
# Self-maintaining on purpose: adding a patch file needs no edit here. The stamp's first line is
# the checked-out llama.cpp commit; every other line is "<patch filename> <sha256>".
on_disk=0
for p in "$PATCH_DIR"/*.patch; do
[ -e "$p" ] || fail "no *.patch files in $PATCH_DIR"
on_disk=$((on_disk + 1))
name="$(basename "$p")"
grep -qF "$name" "$STAMP" || fail "patch '$name' is on disk but absent from the stamp $STAMP"
done

in_stamp="$(($(wc -l < "$STAMP") - 1))"
[ "$in_stamp" -eq "$on_disk" ] \
|| fail "stamp lists $in_stamp patch(es) but $on_disk are on disk — the build dir is stale; configure into a fresh one"

# --- 2. the tree is actually modified ------------------------------------------------------------
# A valid stamp over a clean tree means the patches were reverted after the fact.
if git -C "$SRC" rev-parse --git-dir >/dev/null 2>&1; then
if git -C "$SRC" diff --quiet; then
fail "stamp says $on_disk patch(es) applied but '$SRC' is clean — the patched files were reverted"
fi
fi

# --- 3. the one patch with no runnable guard ------------------------------------------------------
VOCAB_CAST='(int) meta.model_vocab_type'
SERVER_CONTEXT="$SRC/tools/server/server-context.cpp"
[ -f "$SERVER_CONTEXT" ] || fail "not found: $SERVER_CONTEXT"
grep -qF "$VOCAB_CAST" "$SERVER_CONTEXT" \
|| fail "patches/0010 is not present in $SERVER_CONTEXT: expected '$VOCAB_CAST'.
Without the cast, common_json binds the unscoped enum to its bool constructor and
GET /models + GET /v1/models report vocab_type as true/false instead of a number.
If upstream added the cast themselves, DROP patch 0010 and update this check."

echo "patches verified: $on_disk applied, tree dirty, patches/0010 cast present"
89 changes: 89 additions & 0 deletions .github/verify-test-counts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env bash

# SPDX-FileCopyrightText: 2026 Bernard Ladenthin <[email protected]>
#
# SPDX-License-Identifier: MIT OR Apache-2.0

# Fails a Java test job when the suite silently stopped running tests.
#
# WHY THIS EXISTS. Surefire's working directory is the module basedir while the shared GGUF cache
# restores to the reactor root, so every model path resolved one directory too deep and EVERY
# model-gated class aborted in its @BeforeAll assumption — on every test-java-* job, for months,
# while the pipeline stayed green. Several stale assertions rode along unnoticed.
#
# The shape is what defeats the obvious guard: a CLASS-LEVEL assumption failure makes Surefire
# record tests="0" errors="0" failures="0" skipped="0" for that class. It contributes NO test
# entries at all, so "did this run skip anything?" is structurally blind to it — a skipped test is
# still a reported test. Two checks catch it:
#
# 1. Any testsuite reporting tests="0". This is the exact signature above, it is precise, and it
# is platform-independent: a class that runs nowhere is a bug on every OS.
# 2. A floor on the total number of tests executed. The backstop for a whole class file going
# missing from the run rather than reporting zero.
#
# Check 1 is the sensitive one; check 2 is deliberately slack so it never fails spuriously on a
# platform that legitimately runs fewer tests. Tighten --min-total once real per-platform numbers
# are known from a green run.
#
# Usage: .github/verify-test-counts.sh <surefire-reports-dir> [--min-total N]
# Exit codes: 0 all good, 1 a check failed, 2 nothing to scan.

set -euo pipefail

REPORT_DIR="${1:-}"
MIN_TOTAL=0
shift || true
while [ $# -gt 0 ]; do
case "$1" in
--min-total) MIN_TOTAL="$2"; shift 2 ;;
*) echo "unknown argument: $1" >&2; exit 1 ;;
esac
done

[ -n "$REPORT_DIR" ] || { echo "usage: $0 <surefire-reports-dir> [--min-total N]" >&2; exit 1; }
[ -d "$REPORT_DIR" ] || { echo "ERROR: no such directory: $REPORT_DIR" >&2; exit 2; }

shopt -s nullglob
reports=("$REPORT_DIR"/TEST-*.xml)
shopt -u nullglob

# An empty input is a failure, never a pass — the same rule verify-bytecode-version.sh follows,
# for the same reason: a job that produced no reports at all has not proved anything.
if [ "${#reports[@]}" -eq 0 ]; then
echo "ERROR: no TEST-*.xml under $REPORT_DIR — the suite did not run" >&2
exit 2
fi

total=0
empty_suites=()
for f in "${reports[@]}"; do
# The count lives on the <testsuite> element; take the first match so a nested element
# carrying the same attribute name cannot shift the number.
n="$(grep -o 'tests="[0-9]*"' "$f" | head -1 | grep -o '[0-9]*' || true)"
[ -n "$n" ] || n=0
total=$((total + n))
if [ "$n" -eq 0 ]; then
empty_suites+=("$(basename "$f")")
fi
done

status=0

if [ "${#empty_suites[@]}" -gt 0 ]; then
echo "ERROR: ${#empty_suites[@]} test class(es) contributed ZERO test entries:" >&2
printf ' %s\n' "${empty_suites[@]}" >&2
echo " A class-level @BeforeAll assumption that fails looks exactly like this. It is NOT a" >&2
echo " skip — the class reports no tests at all, so it is invisible to a skip check. If a" >&2
echo " model is missing, validate-models should have failed the job before this point." >&2
status=1
fi

if [ "$total" -lt "$MIN_TOTAL" ]; then
echo "ERROR: only $total test(s) executed, below the floor of $MIN_TOTAL" >&2
status=1
fi

if [ "$status" -eq 0 ]; then
echo "test counts verified: $total test(s) across ${#reports[@]} class(es), none empty (floor $MIN_TOTAL)"
fi
exit "$status"
Loading
Loading