Skip to content

Commit 683c92c

Browse files
committed
GH-4673 Add failing test for Cleaner-based auto shutdown in SPARQLRepository
1 parent a014e92 commit 683c92c

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Eclipse RDF4J contributors.
3+
*
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Distribution License v1.0
6+
* which accompanies this distribution, and is available at
7+
* http://www.eclipse.org/org/documents/edl-v10.php.
8+
*
9+
* SPDX-License-Identifier: BSD-3-Clause
10+
*******************************************************************************/
11+
package org.eclipse.rdf4j.repository.sparql;
12+
13+
import static org.assertj.core.api.Assertions.fail;
14+
15+
import java.util.concurrent.CountDownLatch;
16+
import java.util.concurrent.TimeUnit;
17+
18+
import org.eclipse.rdf4j.repository.RepositoryConnection;
19+
import org.eclipse.rdf4j.repository.RepositoryException;
20+
import org.junit.jupiter.api.Test;
21+
22+
/**
23+
* Verifies that a SPARQLRepository performs internal shutdown when it becomes unreachable.
24+
*
25+
* <p>
26+
* This test intentionally does not call {@code repository.shutDown()}. It expects the repository to arrange for its
27+
* internal {@code shutDownInternal()} to run when the object is no longer reachable (e.g., by using Java 9 Cleaner).
28+
* </p>
29+
*/
30+
public class SPARQLRepositoryCleanerTest {
31+
32+
@Test
33+
void autoShutdownOnUnreachable() throws Exception {
34+
CountDownLatch shutdownInvoked = new CountDownLatch(1);
35+
36+
runRepo(shutdownInvoked);
37+
38+
// Encourage GC and wait briefly for cleaner to run
39+
boolean observed = false;
40+
for (int i = 0; i < 20 && !observed; i++) {
41+
System.gc();
42+
System.runFinalization();
43+
observed = shutdownInvoked.await(250, TimeUnit.MILLISECONDS);
44+
}
45+
46+
if (!observed) {
47+
fail("Expected shutDownInternal() to be invoked when SPARQLRepository became unreachable");
48+
}
49+
}
50+
51+
private static void runRepo(CountDownLatch shutdownInvoked) {
52+
// Create a repository instance that signals when shutDownInternal() is invoked
53+
SPARQLRepository repo = new SPARQLRepository("http://example.org/sparql") {
54+
@Override
55+
protected void shutDownInternal() throws RepositoryException {
56+
try {
57+
super.shutDownInternal();
58+
} finally {
59+
shutdownInvoked.countDown();
60+
}
61+
}
62+
};
63+
64+
// Exercise minimal usage without hitting the network
65+
try (RepositoryConnection conn = repo.getConnection()) {
66+
// no-op
67+
}
68+
69+
// Drop strong reference and ask GC to collect
70+
repo = null;
71+
}
72+
}

0 commit comments

Comments
 (0)