Skip to content

Commit 3bbede6

Browse files
authored
Fix test 20251223 (#5637)
2 parents b67a1a7 + f46b037 commit 3bbede6

7 files changed

Lines changed: 92 additions & 69 deletions

File tree

.github/workflows/develop-status.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
- name: Build
3030
run: mvn -B -U clean install -Pquick,\!formatting
3131
- name: Verify
32-
run: mvn -B install -P-skipSlowTests -Dmaven.javadoc.skip=true
32+
run: ./scripts/ci/run-with-thread-dump.sh mvn -B install -P-skipSlowTests -Dmaven.javadoc.skip=true
3333
- name: Publish Test Report
3434
if: failure()
3535
uses: scacap/action-surefire-report@v1

.github/workflows/main-status.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
- name: Build
3030
run: mvn -B -U -T 2C clean install -DskipTests
3131
- name: Run all tests
32-
run: mvn -B install -P-skipSlowTests -Dmaven.javadoc.skip=true
32+
run: ./scripts/ci/run-with-thread-dump.sh mvn -B install -P-skipSlowTests -Dmaven.javadoc.skip=true
3333
- name: Publish Test Report
3434
if: failure()
3535
uses: scacap/action-surefire-report@v1

.github/workflows/pr-verify.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ jobs:
6262
- name: Build
6363
run: mvn --quiet clean && mvn -B --quiet -T 2C install -Pquick
6464
- name: Test
65-
run: mvn -B test -DskipITs -P-formatting -Dmaven.javadoc.skip -Djapicmp.skip -Denforcer.skip -Danimal.sniffer.skip
65+
run: ./scripts/ci/run-with-thread-dump.sh mvn -B test -DskipITs -P-formatting -Dmaven.javadoc.skip -Djapicmp.skip -Denforcer.skip -Danimal.sniffer.skip
6666
- name: Publish Test Report
6767
if: failure()
6868
uses: scacap/action-surefire-report@v1.9.0
@@ -84,7 +84,7 @@ jobs:
8484
- name: Build
8585
run: mvn --quiet clean && mvn -B --quiet -T 2C install -Pquick
8686
- name: Verify
87-
run: mvn -B verify -PskipUnitTests,-formatting -Dmaven.javadoc.skip -Denforcer.skip -Danimal.sniffer.skip
87+
run: ./scripts/ci/run-with-thread-dump.sh mvn -B verify -PskipUnitTests,-formatting -Dmaven.javadoc.skip -Denforcer.skip -Danimal.sniffer.skip
8888
- name: Publish Test Report
8989
if: failure()
9090
uses: scacap/action-surefire-report@v1.9.0
@@ -105,7 +105,7 @@ jobs:
105105
- name: Build
106106
run: mvn --quiet clean && mvn -B --quiet -T 2C install -Pquick
107107
- name: Verify
108-
run: mvn -B verify -PslowTestsOnly,-skipSlowTests,-formatting -Dmaven.javadoc.skip -Djapicmp.skip -Denforcer.skip -Danimal.sniffer.skip
108+
run: ./scripts/ci/run-with-thread-dump.sh mvn -B verify -PslowTestsOnly,-skipSlowTests,-formatting -Dmaven.javadoc.skip -Djapicmp.skip -Denforcer.skip -Danimal.sniffer.skip
109109
- name: Publish Test Report
110110
if: failure()
111111
uses: scacap/action-surefire-report@v1.9.0
@@ -148,12 +148,11 @@ jobs:
148148
node-version: 18
149149
- name: Run end-to-end tests of RDF4J Server and Workbench
150150
working-directory: ./e2e
151-
run: ./run.sh
151+
run: ../scripts/ci/run-with-thread-dump.sh ./run.sh
152152

153153
copyright-check:
154154
runs-on: ubuntu-latest
155155
steps:
156156
- uses: actions/checkout@v4
157157
- name: check copyright header present
158158
run: scripts/checkCopyrightPresent.sh
159-

AGENTS.md

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -126,48 +126,6 @@ When writing complex features or significant refactors, use an ExecPlan (as desc
126126

127127
When writing complex features or significant refactors, use an ExecPlan (as described in PLANS.md) from design to implementation.
128128

129-
## PIOSEE Decision Model (Adopted)
130-
131-
Use this as a compact, repeatable loop for anything from a one‑line bug fix to a multi‑quarter program.
132-
133-
### P — **Problem**
134-
135-
**Goal:** State the core problem and what “good” looks like.
136-
**Ask:** Who’s affected? What outcome is required? What happens if we do nothing?
137-
**Tip:** Include measurable target(s): error rate ↓, latency p95 ↓, revenue ↑, risk ↓.
138-
139-
### I — **Information**
140-
141-
**Goal:** Gather only the facts needed to move.
142-
**Ask:** What do logs/metrics/user feedback say? What constraints (security, compliance, budget, SLA/SLO)? What assumptions must we test?
143-
144-
### O — **Options**
145-
146-
**Goal:** Generate viable ways forward, including “do nothing.”
147-
**Ask:** What are 2–4 distinct approaches (patch, redesign, buy vs. build, defer)? What risks, costs, and second‑order effects?
148-
**Tip:** Check guardrails: reliability, security/privacy, accessibility, performance, operability, unit economics.
149-
150-
### S — **Select**
151-
152-
**Goal:** Decide deliberately and document why.
153-
**Ask:** Which option best meets the success criteria under constraints? Who is the decision owner? What’s the fallback/abort condition?
154-
**Tip:** Use lightweight scoring (e.g., Impact×Confidence÷Effort) to avoid bike‑shedding.
155-
156-
### E — **Execute**
157-
158-
**Goal:** Ship safely and visibly.
159-
**Ask:** What is the smallest safe slice? How do we de‑risk (feature flag, canary, dark launch, rollback)? Who owns what?
160-
**Checklist:** Traces/logs/alerts; security & privacy checks; docs & changelog; incident plan if relevant.
161-
162-
### E — **Evaluate**
163-
164-
**Goal:** Verify outcomes and learn.
165-
**Ask:** Did metrics hit targets? Any regressions or side effects? What will we keep/change next loop?
166-
**Output:** Post‑release review (or retro), decision log entry, follow‑ups (tickets), debt captured.
167-
**Tip:** If outcomes miss, either **iterate** (new Options) or **reframe** (back to Problem).
168-
169-
---
170-
171129
### Benchmarking workflow (repository-wide)
172130

173131
The `scripts/run-single-benchmark.sh` helper is the supported path for spot-checking performance optimisations. It builds the chosen module with the `benchmarks` profile, constrains the benchmark selection to a single `@Benchmark` method, and when `--enable-jfr` is supplied it enforces repeatable profiling defaults (no warmup, ten 10-second measurements, one fork) while clearly reporting the destination of the generated JFR recording. Lean on this script whenever you need a reproducible measurement harness.
@@ -466,7 +424,6 @@ When writing complex features or significant refactors, use an ExecPlan (as desc
466424
467425
## Working Loop
468426
469-
* **PIOSEE first:** restate Problem, gather Information, list Options; then Select, Execute, Evaluate.
470427
* **Plan:** small, verifiable steps; keep one `in_progress`, or follow PLANS.md (ExecPlans)
471428
* **Change:** minimal, surgical edits; keep style/structure consistent.
472429
* **Format:** `mvn -o -Dmaven.repo.local=.m2_repo -q -T 2C formatter:format impsort:sort xml-format:xml-format`
@@ -657,7 +614,6 @@ Immediately after creating any new Java source file, add the signature comment (
657614
* **Files touched:** list file paths.
658615
* **Commands run:** key build/test commands.
659616
* **Verification:** which tests passed, where you checked reports.
660-
* **PIOSEE trace (concise):** P/I/O summary, selected option/routine, key evaluate outcomes.
661617
* **Evidence:**
662618
*Routine A:* failing output (pre‑fix) and passing output (post‑fix).
663619
*Routine B:* pre‑ and post‑green snippets from the **same selection** + **Hit Proof**.

core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/FilterByPredicateObject.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ public FilterByPredicateObject(SailConnection connection, Resource[] dataGraph,
7373
if (connection instanceof MemoryStoreConnection) {
7474
cache = null;
7575
} else {
76-
cache = CacheBuilder.newBuilder().maximumSize(10000).build();
76+
cache = CacheBuilder.newBuilder()
77+
.concurrencyLevel(Runtime.getRuntime().availableProcessors() * 2)
78+
.maximumSize(10000)
79+
.build();
7780
}
7881

7982
this.connectionsGroup = connectionsGroup;

core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShutdownDuringValidationIT.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ void tearDown() {
115115
@ParameterizedTest
116116
@MethodSource("sleepTimes")
117117
public void shutdownDuringValidation(int sleepMillis) {
118+
System.err.println(Thread.currentThread() + " shutdownDuringValidation with sleepMillis=" + sleepMillis);
118119
try {
119120
// clear interrupted flag
120121
Thread.interrupted();
@@ -156,15 +157,15 @@ public void shutdownDuringValidation(int sleepMillis) {
156157
}
157158
} catch (Exception e) {
158159
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
159-
System.out.println(e);
160+
System.err.println(e);
160161
return;
161162
}
162163
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedSailException) {
163-
System.out.println(e);
164+
System.err.println(e);
164165
return;
165166
}
166167
if (e.toString().contains("closed")) {
167-
System.out.println(e);
168+
System.err.println(e);
168169
return;
169170
}
170171
throw e;
@@ -174,6 +175,8 @@ public void shutdownDuringValidation(int sleepMillis) {
174175
@ParameterizedTest
175176
@MethodSource("sleepTimes")
176177
public void shutdownDuringValidationTransactional(int sleepMillis) {
178+
System.err.println(
179+
Thread.currentThread() + " shutdownDuringValidationTransactional with sleepMillis=" + sleepMillis);
177180
try {
178181
// clear interrupted flag
179182
Thread.interrupted();
@@ -221,15 +224,15 @@ public void shutdownDuringValidationTransactional(int sleepMillis) {
221224
}
222225
} catch (Exception e) {
223226
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
224-
System.out.println(e);
227+
System.err.println(e);
225228
return;
226229
}
227230
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedSailException) {
228-
System.out.println(e);
231+
System.err.println(e);
229232
return;
230233
}
231234
if (e.toString().contains("closed")) {
232-
System.out.println(e);
235+
System.err.println(e);
233236
return;
234237
}
235238
throw e;
@@ -239,6 +242,7 @@ public void shutdownDuringValidationTransactional(int sleepMillis) {
239242
@ParameterizedTest
240243
@MethodSource("sleepTimes")
241244
public void shutdownDuringValidationFailure(int sleepMillis) {
245+
System.err.println(Thread.currentThread() + " shutdownDuringValidationFailure with sleepMillis=" + sleepMillis);
242246
try {
243247

244248
// clear interrupted flag
@@ -280,15 +284,15 @@ public void shutdownDuringValidationFailure(int sleepMillis) {
280284
}
281285
} catch (Exception e) {
282286
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
283-
System.out.println(e);
287+
System.err.println(e);
284288
return;
285289
}
286290
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedSailException) {
287-
System.out.println(e);
291+
System.err.println(e);
288292
return;
289293
}
290294
if (e.toString().contains("closed")) {
291-
System.out.println(e);
295+
System.err.println(e);
292296
return;
293297
}
294298
throw e;
@@ -298,6 +302,8 @@ public void shutdownDuringValidationFailure(int sleepMillis) {
298302
@ParameterizedTest
299303
@MethodSource("sleepTimes")
300304
public void shutdownDuringValidationFailureNonParallel(int sleepMillis) {
305+
System.err.println(
306+
Thread.currentThread() + " shutdownDuringValidationFailureNonParallel with sleepMillis=" + sleepMillis);
301307
try {
302308
// clear interrupted flag
303309
Thread.interrupted();
@@ -339,15 +345,15 @@ public void shutdownDuringValidationFailureNonParallel(int sleepMillis) {
339345
}
340346
} catch (Exception e) {
341347
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
342-
System.out.println(e);
348+
System.err.println(e);
343349
return;
344350
}
345351
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedSailException) {
346-
System.out.println(e);
352+
System.err.println(e);
347353
return;
348354
}
349355
if (e.toString().contains("closed")) {
350-
System.out.println(e);
356+
System.err.println(e);
351357
return;
352358
}
353359

@@ -358,6 +364,8 @@ public void shutdownDuringValidationFailureNonParallel(int sleepMillis) {
358364
@ParameterizedTest
359365
@MethodSource("sleepTimes")
360366
public void shutdownDuringValidationTransactionalNonParallel(int sleepMillis) {
367+
System.err.println(Thread.currentThread()
368+
+ " shutdownDuringValidationTransactionalNonParallel with sleepMillis=" + sleepMillis);
361369
try {
362370
// clear interrupted flag
363371
boolean interrupted = Thread.interrupted();
@@ -378,7 +386,7 @@ public void shutdownDuringValidationTransactionalNonParallel(int sleepMillis) {
378386

379387
commitAndExpect(connection, EXPECTED_REPOSITORY_SIZE + 1, 1);
380388
} catch (RepositoryException | SailException e) {
381-
System.out.println(e);
389+
System.err.println(e);
382390
if (e instanceof InterruptedSailException) {
383391
// ignore this exception
384392
return;
@@ -413,15 +421,15 @@ public void shutdownDuringValidationTransactionalNonParallel(int sleepMillis) {
413421
}
414422
} catch (Exception e) {
415423
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
416-
System.out.println(e);
424+
System.err.println(e);
417425
return;
418426
}
419427
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedSailException) {
420-
System.out.println(e);
428+
System.err.println(e);
421429
return;
422430
}
423431
if (e.toString().contains("closed")) {
424-
System.out.println(e);
432+
System.err.println(e);
425433
return;
426434
}
427435
throw e;
@@ -430,6 +438,7 @@ public void shutdownDuringValidationTransactionalNonParallel(int sleepMillis) {
430438

431439
@Test
432440
void nestedInterruptedExceptionShouldBeDetected() {
441+
System.err.println(Thread.currentThread() + " nestedInterruptedExceptionShouldBeDetected");
433442
InterruptedException interruptedException = new InterruptedException("nested");
434443
SailException sailException = new SailException("wrapper", new SailException("inner", interruptedException));
435444
RepositoryException repositoryException = new RepositoryException("top", sailException);
@@ -473,7 +482,7 @@ private static void commitAndExpect(SailRepositoryConnection connection, long ex
473482
throw e;
474483
}
475484
} catch (RepositoryException ignored) {
476-
System.out.println(ignored.getMessage());
485+
System.err.println(ignored.getMessage());
477486
try {
478487
connection.rollback();
479488
} catch (Exception e) {

scripts/ci/run-with-thread-dump.sh

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
dump_threads() {
5+
echo "== Cancellation received: capturing JVM thread dumps =="
6+
local pids
7+
pids=$(pgrep -f '[j]ava' || true)
8+
if [[ -z "${pids}" ]]; then
9+
echo "No Java processes found."
10+
return 0
11+
fi
12+
13+
if command -v jcmd >/dev/null 2>&1; then
14+
for pid in ${pids}; do
15+
echo "-- jcmd Thread.print for PID ${pid} --"
16+
jcmd "${pid}" Thread.print || true
17+
done
18+
return 0
19+
fi
20+
21+
if command -v jstack >/dev/null 2>&1; then
22+
for pid in ${pids}; do
23+
echo "-- jstack for PID ${pid} --"
24+
jstack "${pid}" || true
25+
done
26+
return 0
27+
fi
28+
29+
for pid in ${pids}; do
30+
echo "-- kill -QUIT ${pid} (no jcmd/jstack available) --"
31+
kill -QUIT "${pid}" || true
32+
done
33+
}
34+
35+
on_term() {
36+
dump_threads
37+
if [[ -n "${child_pid:-}" ]]; then
38+
kill -TERM "${child_pid}" 2>/dev/null || true
39+
fi
40+
}
41+
42+
if [[ $# -eq 0 ]]; then
43+
echo "Usage: $0 <command> [args...]" >&2
44+
exit 2
45+
fi
46+
47+
trap on_term INT TERM
48+
49+
"$@" &
50+
child_pid=$!
51+
52+
wait "${child_pid}"
53+
status=$?
54+
55+
trap - INT TERM
56+
exit "${status}"

0 commit comments

Comments
 (0)