Skip to content

Commit dc41456

Browse files
committed
GH-5380 Add Jetty IT reproducing invalid LMDB index deletion after invalid index config
1 parent 8ae9307 commit dc41456

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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.http.server;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
15+
import org.eclipse.rdf4j.http.protocol.Protocol;
16+
import org.eclipse.rdf4j.model.IRI;
17+
import org.eclipse.rdf4j.model.ValueFactory;
18+
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
19+
import org.eclipse.rdf4j.repository.Repository;
20+
import org.eclipse.rdf4j.repository.RepositoryConnection;
21+
import org.eclipse.rdf4j.repository.RepositoryException;
22+
import org.eclipse.rdf4j.repository.config.RepositoryConfig;
23+
import org.eclipse.rdf4j.repository.manager.RemoteRepositoryManager;
24+
import org.eclipse.rdf4j.repository.sail.config.SailRepositoryConfig;
25+
import org.eclipse.rdf4j.sail.config.AbstractSailImplConfig;
26+
import org.junit.jupiter.api.AfterAll;
27+
import org.junit.jupiter.api.BeforeAll;
28+
import org.junit.jupiter.api.Test;
29+
30+
/**
31+
* Jetty-based integration test that reproduces a user report: Creating an LMDB repository with an invalid triple index
32+
* (e.g., "cposc") then attempting to delete it via HTTP fails.
33+
*
34+
* Expected behavior: either reject creation upfront or allow deletion. This test asserts deletion succeeds; it
35+
* currently fails, exposing the bug.
36+
*/
37+
public class LmdbInvalidIndexDeletionIT {
38+
39+
private static TestServer server;
40+
41+
@BeforeAll
42+
public static void startServer() throws Exception {
43+
server = new TestServer();
44+
try {
45+
server.start();
46+
} catch (Exception e) {
47+
server.stop();
48+
throw e;
49+
}
50+
}
51+
52+
@AfterAll
53+
public static void stopServer() throws Exception {
54+
server.stop();
55+
}
56+
57+
@Test
58+
void deletionSucceedsAfterInvalidLmdbInit() throws Exception {
59+
String id = "badlmdb-server";
60+
61+
// Build a minimal LMDB Sail config without depending on LMDB classes
62+
// by exporting with the LMDB sail type and the tripleIndexes property.
63+
class GenericLmdbConfig extends AbstractSailImplConfig {
64+
private final String tripleIndexes;
65+
66+
GenericLmdbConfig(String type, String tripleIndexes) {
67+
super(type);
68+
this.tripleIndexes = tripleIndexes;
69+
}
70+
71+
@Override
72+
public org.eclipse.rdf4j.model.Resource export(org.eclipse.rdf4j.model.Model m) {
73+
org.eclipse.rdf4j.model.Resource node = super.export(m);
74+
ValueFactory vf = SimpleValueFactory.getInstance();
75+
IRI tripleIdx = vf.createIRI("http://rdf4j.org/config/sail/lmdb#tripleIndexes");
76+
m.add(node, tripleIdx, vf.createLiteral(tripleIndexes));
77+
return node;
78+
}
79+
}
80+
81+
GenericLmdbConfig lmdbConfig = new GenericLmdbConfig("rdf4j:LmdbStore", "cposc");
82+
RepositoryConfig repoConfig = new RepositoryConfig(id, new SailRepositoryConfig(lmdbConfig));
83+
84+
RemoteRepositoryManager manager = RemoteRepositoryManager.getInstance(TestServer.SERVER_URL);
85+
try {
86+
// Create config on server (does not initialize the underlying store yet)
87+
manager.addRepositoryConfig(repoConfig);
88+
89+
// Trigger initialization by opening a connection; expected to fail due to invalid index
90+
Repository httpRepo = new org.eclipse.rdf4j.repository.http.HTTPRepository(
91+
Protocol.getRepositoryLocation(TestServer.SERVER_URL, id));
92+
try (RepositoryConnection conn = httpRepo.getConnection()) {
93+
// attempt a trivial call to ensure init
94+
conn.size();
95+
} catch (RepositoryException expected) {
96+
// initialization fails as LMDB rejects invalid index spec
97+
}
98+
99+
// Now attempt to delete the repository; expected to succeed
100+
boolean removed = manager.removeRepository(id);
101+
assertThat(removed).isTrue();
102+
} finally {
103+
// best-effort cleanup if assertion failed
104+
try {
105+
manager.removeRepository(id);
106+
} catch (Exception ignore) {
107+
}
108+
manager.shutDown();
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)