From 878b88c51c99d697d12a5ae4521c7fa9bc30efd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20M=2E=20Ottestad?= Date: Wed, 15 Apr 2026 14:22:53 +0200 Subject: [PATCH 1/2] Downgrade spotless to a version that doesn't need to download the eclipse formatter from p2 directly (#5750) downgrade spotless to a version that doesn't need to download the eclipse formatter from p2 directly --- .../impl/DefaultEvaluationStrategy.java | 4 +- ...OrderQueryEvaluationStepTelemetryTest.java | 2 +- ...rviceQueryEvaluationStepTelemetryTest.java | 10 ++-- .../QueryModelTreeToGenericPlanNodeTest.java | 2 +- .../text/csv/SPARQLResultsCSVParser.java | 6 +- .../rio/helpers/RDFParserHelperTest.java | 14 ++--- .../AbstractDatatypeHandlerTest.java | 6 +- .../nquads/AbstractNQuadsParserUnitTest.java | 8 +-- .../ElasticsearchDataStructure.java | 16 ++--- .../sail/lmdb/TripleStoreAutoGrowTest.java | 2 +- .../OverflowBenchmarkConcurrent.java | 4 +- .../lmdb/benchmark/OverflowBenchmarkReal.java | 2 +- .../benchmark/OverflowBenchmarkSynthetic.java | 2 +- .../OverflowBenchmarkConcurrent.java | 4 +- .../benchmark/OverflowBenchmarkReal.java | 2 +- .../benchmark/OverflowBenchmarkSynthetic.java | 2 +- .../wal/ValueStoreWalIntegrationTest.java | 2 +- .../wal/ValueStoreWalReaderJacksonTest.java | 4 +- .../ClosedConstraintComponent.java | 2 +- .../HasValueConstraintComponent.java | 2 +- .../shacl/ast/targets/EffectiveTarget.java | 2 +- .../examples/updatespec/Section3Test.java | 4 +- pom.xml | 2 +- .../cache/SourceSelectionMemoryCache.java | 2 +- .../repository/FedXRepositoryConfigTest.java | 60 +++++++++---------- .../Rdf4jServerWorkbenchApplicationTest.java | 4 +- .../TransformationServletCoverageTest.java | 10 ++-- .../commands/CreateTemplateConfigTest.java | 16 ++--- .../QueryServletFlowCoverageTest.java | 4 +- .../commands/SavedQueriesServletTest.java | 12 ++-- .../proxy/ProxyRepositoryServletTest.java | 4 +- .../workbench/proxy/WorkbenchGatewayTest.java | 10 ++-- .../workbench/proxy/WorkbenchServletTest.java | 22 +++---- .../util/QueryEvaluatorCoverageTest.java | 4 +- .../workbench/util/QueryStorageTest.java | 18 +++--- 35 files changed, 135 insertions(+), 135 deletions(-) diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java index ccb27e27e53..900a872f677 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java @@ -1032,7 +1032,7 @@ public Value evaluate(ValueExpr expr, BindingSet bindings) return precompile(expr, new QueryEvaluationContext.Minimal(DefaultEvaluationStrategy.this.sharedValueOfNow, dataset, tripleSource.getComparator())) - .evaluate(bindings); + .evaluate(bindings); } protected QueryValueEvaluationStep prepare(Var var, QueryEvaluationContext context) @@ -1167,7 +1167,7 @@ public Value evaluate(Regex node, BindingSet bindings) throws QueryEvaluationException { return prepare(node, new QueryEvaluationContext.Minimal(sharedValueOfNow, dataset, tripleSource.getComparator())) - .evaluate(bindings); + .evaluate(bindings); } /** diff --git a/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/OrderQueryEvaluationStepTelemetryTest.java b/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/OrderQueryEvaluationStepTelemetryTest.java index 38be8eaa25d..e867e91f9ad 100644 --- a/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/OrderQueryEvaluationStepTelemetryTest.java +++ b/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/OrderQueryEvaluationStepTelemetryTest.java @@ -36,7 +36,7 @@ class OrderQueryEvaluationStepTelemetryTest { void retainsLegacyConstructorForBinaryCompatibility() throws Exception { assertThat(OrderQueryEvaluationStep.class .getConstructor(Comparator.class, long.class, boolean.class, QueryEvaluationStep.class, long.class)) - .isNotNull(); + .isNotNull(); } @Test diff --git a/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/ServiceQueryEvaluationStepTelemetryTest.java b/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/ServiceQueryEvaluationStepTelemetryTest.java index 62ab7ca7021..340a3f2e3c6 100644 --- a/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/ServiceQueryEvaluationStepTelemetryTest.java +++ b/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/ServiceQueryEvaluationStepTelemetryTest.java @@ -97,10 +97,10 @@ void recordsLatencyQuantilesForSelectRequests() { FederatedService federatedService = mock(FederatedService.class); when(federatedService.select(eq(service), anySet(), any(BindingSet.class), eq(service.getBaseURI()))) - .thenAnswer(invocation -> { - LockSupport.parkNanos(1_000_000L); - return new CloseableIteratorIteration<>(List.of(singleBindingSet("s", "row")).iterator()); - }); + .thenAnswer(invocation -> { + LockSupport.parkNanos(1_000_000L); + return new CloseableIteratorIteration<>(List.of(singleBindingSet("s", "row")).iterator()); + }); FederatedServiceResolver resolver = mock(FederatedServiceResolver.class); when(resolver.getService("http://example.com/service")).thenReturn(federatedService); @@ -139,7 +139,7 @@ void skipsRequestAndResponseByteAccountingWhenRuntimeTelemetryDisabled() { when(responseRow.toString()).thenThrow(new AssertionError("response byte accounting should be disabled")); when(federatedService.select(eq(service), anySet(), any(BindingSet.class), eq(service.getBaseURI()))) - .thenReturn(new CloseableIteratorIteration<>(List.of(responseRow).iterator())); + .thenReturn(new CloseableIteratorIteration<>(List.of(responseRow).iterator())); FederatedServiceResolver resolver = mock(FederatedServiceResolver.class); when(resolver.getService("http://example.com/service")).thenReturn(federatedService); diff --git a/core/queryalgebra/model/src/test/java/org/eclipse/rdf4j/query/algebra/helpers/QueryModelTreeToGenericPlanNodeTest.java b/core/queryalgebra/model/src/test/java/org/eclipse/rdf4j/query/algebra/helpers/QueryModelTreeToGenericPlanNodeTest.java index 4287d22a786..40ab99c53aa 100644 --- a/core/queryalgebra/model/src/test/java/org/eclipse/rdf4j/query/algebra/helpers/QueryModelTreeToGenericPlanNodeTest.java +++ b/core/queryalgebra/model/src/test/java/org/eclipse/rdf4j/query/algebra/helpers/QueryModelTreeToGenericPlanNodeTest.java @@ -235,7 +235,7 @@ public void doesNotAnnotateConnectedJoinWhenSharedVarIsAlreadyGuaranteedBound() assertThat(outerPlan.getStringMetricActual(TelemetryMetricNames.JOIN_TYPE)).isNull(); assertThat(findFirstPlan(outerPlan.getPlans().get(1), node -> node.getStringMetricActual(TelemetryMetricNames.JOIN_TYPE) != null)) - .isNull(); + .isNull(); } @Test diff --git a/core/queryresultio/text/src/main/java/org/eclipse/rdf4j/query/resultio/text/csv/SPARQLResultsCSVParser.java b/core/queryresultio/text/src/main/java/org/eclipse/rdf4j/query/resultio/text/csv/SPARQLResultsCSVParser.java index 88662f9ae66..d79a7d71bc6 100644 --- a/core/queryresultio/text/src/main/java/org/eclipse/rdf4j/query/resultio/text/csv/SPARQLResultsCSVParser.java +++ b/core/queryresultio/text/src/main/java/org/eclipse/rdf4j/query/resultio/text/csv/SPARQLResultsCSVParser.java @@ -43,9 +43,9 @@ public void parse(InputStream in) throws QueryResultParseException, TupleQueryRe List bindingSets = new CsvToBeanBuilder( new InputStreamReader(in, StandardCharsets.UTF_8)).withType(BindingSet.class) - .withMappingStrategy(strategy) - .build() - .parse(); + .withMappingStrategy(strategy) + .build() + .parse(); List bindingNames = strategy.getBindingNames(); handler.startQueryResult(bindingNames); for (BindingSet bs : bindingSets) { diff --git a/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/helpers/RDFParserHelperTest.java b/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/helpers/RDFParserHelperTest.java index 2213d046d69..8208c156d0a 100644 --- a/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/helpers/RDFParserHelperTest.java +++ b/core/rio/api/src/test/java/org/eclipse/rdf4j/rio/helpers/RDFParserHelperTest.java @@ -82,8 +82,8 @@ public void tearDown() { public final void testCreateLiteralLabelNull() { assertThatThrownBy( () -> RDFParserHelper.createLiteral(null, null, null, parserConfig, errListener, valueFactory)) - .isInstanceOf(NullPointerException.class) - .hasMessage("Cannot create a literal using a null label"); + .isInstanceOf(NullPointerException.class) + .hasMessage("Cannot create a literal using a null label"); } /** @@ -168,7 +168,7 @@ public final void testCreateLiteralLabelNoLanguageWithRDFLangStringWithVerify() assertTrue(parserConfig.get(BasicParserSettings.VERIFY_DATATYPE_VALUES)); assertThatThrownBy(() -> RDFParserHelper.createLiteral(LABEL_TESTA, null, RDF.LANGSTRING, parserConfig, errListener, valueFactory)) - .isInstanceOf(RDFParseException.class); + .isInstanceOf(RDFParseException.class); } @Test @@ -187,8 +187,8 @@ public final void testReportErrorStringFatalActive() { assertThatThrownBy( () -> RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, BasicParserSettings.VERIFY_DATATYPE_VALUES, parserConfig, errListener)) - .isInstanceOf(RDFParseException.class) - .hasMessage(TEST_MESSAGE_FOR_FAILURE); + .isInstanceOf(RDFParseException.class) + .hasMessage(TEST_MESSAGE_FOR_FAILURE); assertErrorListener(0, 1, 0); } @@ -227,8 +227,8 @@ public final void testReportErrorStringIntIntFatalActive() { () -> RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, 1, 1, BasicParserSettings.VERIFY_DATATYPE_VALUES, parserConfig, errListener)) - .isInstanceOf(RDFParseException.class) - .hasMessageContaining(TEST_MESSAGE_FOR_FAILURE); + .isInstanceOf(RDFParseException.class) + .hasMessageContaining(TEST_MESSAGE_FOR_FAILURE); assertErrorListener(0, 1, 0); } diff --git a/core/rio/datatypes/src/test/java/org/eclipse/rdf4j/rio/datatypes/AbstractDatatypeHandlerTest.java b/core/rio/datatypes/src/test/java/org/eclipse/rdf4j/rio/datatypes/AbstractDatatypeHandlerTest.java index 60829dfcc5f..786866c9e28 100644 --- a/core/rio/datatypes/src/test/java/org/eclipse/rdf4j/rio/datatypes/AbstractDatatypeHandlerTest.java +++ b/core/rio/datatypes/src/test/java/org/eclipse/rdf4j/rio/datatypes/AbstractDatatypeHandlerTest.java @@ -162,7 +162,7 @@ public void testVerifyDatatypeNullValueUnrecognised() { public void testVerifyDatatypeUnrecognisedDatatypeUri() { assertThatThrownBy( () -> testHandler.verifyDatatype(getValueMatchingRecognisedDatatypeUri(), getUnrecognisedDatatypeUri())) - .isInstanceOf(LiteralUtilException.class); + .isInstanceOf(LiteralUtilException.class); } /** @@ -214,7 +214,7 @@ public void testNormalizeDatatypeNullValue() { public void testNormalizeDatatypeUnrecognisedDatatypeUri() { assertThatThrownBy(() -> testHandler.normalizeDatatype(getValueMatchingRecognisedDatatypeUri(), getUnrecognisedDatatypeUri(), vf)) - .isInstanceOf(LiteralUtilException.class); + .isInstanceOf(LiteralUtilException.class); } /** @@ -226,7 +226,7 @@ public void testNormalizeDatatypeUnrecognisedDatatypeUri() { public void testNormalizeDatatypeInvalidValue() { assertThatThrownBy(() -> testHandler.normalizeDatatype(getValueNotMatchingRecognisedDatatypeUri(), getRecognisedDatatypeUri(), vf)) - .isInstanceOf(LiteralUtilException.class); + .isInstanceOf(LiteralUtilException.class); } /** diff --git a/core/rio/nquads/src/test/java/org/eclipse/rdf4j/rio/nquads/AbstractNQuadsParserUnitTest.java b/core/rio/nquads/src/test/java/org/eclipse/rdf4j/rio/nquads/AbstractNQuadsParserUnitTest.java index 87b9d1c91ae..d2e2401a0dd 100644 --- a/core/rio/nquads/src/test/java/org/eclipse/rdf4j/rio/nquads/AbstractNQuadsParserUnitTest.java +++ b/core/rio/nquads/src/test/java/org/eclipse/rdf4j/rio/nquads/AbstractNQuadsParserUnitTest.java @@ -282,7 +282,7 @@ public void testParseBasicLiteralDatatype() throws RDFHandlerException, IOExcept final ByteArrayInputStream bais = new ByteArrayInputStream( (" " + " " + "\"2010\"^^ " + ".") - .getBytes()); + .getBytes()); final TestRDFHandler rdfHandler = new TestRDFHandler(); parser.setRDFHandler(rdfHandler); parser.parse(bais, "http://test.base.uri"); @@ -491,7 +491,7 @@ public void testStatementWithInvalidLiteralContentAndIgnoreValidation() + " " + "\"1380.0\"^^ " + " .") - .getBytes()); + .getBytes()); parser.getParserConfig().set(BasicParserSettings.VERIFY_DATATYPE_VALUES, false); parser.getParserConfig().set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, false); parser.parse(bais, "http://base-uri"); @@ -506,7 +506,7 @@ public void testStatementWithInvalidLiteralContentAndStrictValidation() + " " + "\"1380.0\"^^ " + " .") - .getBytes()); + .getBytes()); parser.getParserConfig().set(BasicParserSettings.VERIFY_DATATYPE_VALUES, true); parser.getParserConfig().set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true); try { @@ -601,7 +601,7 @@ private void verifyStatementWithInvalidDatatype(boolean useDatatypeVerification) + " " + "\"1380.0\"^^ " + " .") - .getBytes()); + .getBytes()); parser.parse(bais, "http://base-uri"); rdfHandler.assertHandler(1); } diff --git a/core/sail/elasticsearch-store/src/main/java/org/eclipse/rdf4j/sail/elasticsearchstore/ElasticsearchDataStructure.java b/core/sail/elasticsearch-store/src/main/java/org/eclipse/rdf4j/sail/elasticsearchstore/ElasticsearchDataStructure.java index f4dff97822e..ce35a440fff 100644 --- a/core/sail/elasticsearch-store/src/main/java/org/eclipse/rdf4j/sail/elasticsearchstore/ElasticsearchDataStructure.java +++ b/core/sail/elasticsearch-store/src/main/java/org/eclipse/rdf4j/sail/elasticsearchstore/ElasticsearchDataStructure.java @@ -148,10 +148,10 @@ synchronized public void clear(boolean inferred, Resource[] contexts) { BulkByScrollResponse response = new DeleteByQueryRequestBuilder(clientProvider.getClient(), DeleteByQueryAction.INSTANCE) - .filter(getQueryBuilder(null, null, null, inferred, contexts)) - .abortOnVersionConflict(false) - .source(index) - .get(); + .filter(getQueryBuilder(null, null, null, inferred, contexts)) + .abortOnVersionConflict(false) + .source(index) + .get(); long deleted = response.getDeleted(); } @@ -596,10 +596,10 @@ public synchronized boolean removeStatementsByQuery(Resource subj, IRI pred, Val BulkByScrollResponse response = new DeleteByQueryRequestBuilder(clientProvider.getClient(), DeleteByQueryAction.INSTANCE) - .filter(getQueryBuilder(subj, pred, obj, inferred, contexts)) - .source(index) - .abortOnVersionConflict(false) - .get(); + .filter(getQueryBuilder(subj, pred, obj, inferred, contexts)) + .source(index) + .abortOnVersionConflict(false) + .get(); long deleted = response.getDeleted(); return deleted > 0; diff --git a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/TripleStoreAutoGrowTest.java b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/TripleStoreAutoGrowTest.java index afcfc5e64b0..02c5848a2d7 100644 --- a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/TripleStoreAutoGrowTest.java +++ b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/TripleStoreAutoGrowTest.java @@ -37,7 +37,7 @@ public void before(@TempDir File dataDir) throws Exception { tripleStore = new TripleStore(dataDir, config, null); ((Logger) LoggerFactory .getLogger(TripleStore.class.getName())) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); } @Test diff --git a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkConcurrent.java b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkConcurrent.java index fa836af114f..270d25d1703 100644 --- a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkConcurrent.java +++ b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkConcurrent.java @@ -80,11 +80,11 @@ public class OverflowBenchmarkConcurrent { public void setup() { ((Logger) (LoggerFactory .getLogger("org.eclipse.rdf4j.sail.lmdb.MemoryOverflowModel"))) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); ((Logger) (LoggerFactory .getLogger("org.eclipse.rdf4j.model.impl.AbstractMemoryOverflowModel"))) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); } @TearDown(Level.Trial) diff --git a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkReal.java b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkReal.java index dc10145af92..3eb373a2a66 100644 --- a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkReal.java +++ b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkReal.java @@ -59,7 +59,7 @@ public class OverflowBenchmarkReal { public void setup() { ((Logger) (LoggerFactory .getLogger("org.eclipse.rdf4j.sail.lmdb.MemoryOverflowModel"))) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); } public static void main(String[] args) throws RunnerException { diff --git a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkSynthetic.java b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkSynthetic.java index 85ef81f4ebb..f06d2e52b27 100644 --- a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkSynthetic.java +++ b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/OverflowBenchmarkSynthetic.java @@ -64,7 +64,7 @@ public class OverflowBenchmarkSynthetic { public void setup() { ((Logger) (LoggerFactory .getLogger("org.eclipse.rdf4j.sail.lmdbrdf.MemoryOverflowModel"))) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); } public static void main(String[] args) throws RunnerException { diff --git a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkConcurrent.java b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkConcurrent.java index 00c1158cb1b..2211916a37d 100644 --- a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkConcurrent.java +++ b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkConcurrent.java @@ -82,11 +82,11 @@ public class OverflowBenchmarkConcurrent { public void setup() { ((Logger) (LoggerFactory .getLogger("org.eclipse.rdf4j.sail.nativerdf.MemoryOverflowModel"))) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); ((Logger) (LoggerFactory .getLogger("org.eclipse.rdf4j.model.impl.AbstractMemoryOverflowModel"))) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); } public static void main(String[] args) throws RunnerException { diff --git a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkReal.java b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkReal.java index 4edc6b715b1..411fa1a2b49 100644 --- a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkReal.java +++ b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkReal.java @@ -59,7 +59,7 @@ public class OverflowBenchmarkReal { public void setup() { ((Logger) (LoggerFactory .getLogger("org.eclipse.rdf4j.sail.nativerdf.MemoryOverflowModel"))) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); } public static void main(String[] args) throws RunnerException { diff --git a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkSynthetic.java b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkSynthetic.java index c367ce4bca4..10c642d9110 100644 --- a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkSynthetic.java +++ b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/benchmark/OverflowBenchmarkSynthetic.java @@ -64,7 +64,7 @@ public class OverflowBenchmarkSynthetic { public void setup() { ((Logger) (LoggerFactory .getLogger("org.eclipse.rdf4j.sail.nativerdf.MemoryOverflowModel"))) - .setLevel(ch.qos.logback.classic.Level.DEBUG); + .setLevel(ch.qos.logback.classic.Level.DEBUG); } public static void main(String[] args) throws RunnerException { diff --git a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/wal/ValueStoreWalIntegrationTest.java b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/wal/ValueStoreWalIntegrationTest.java index 2527067865e..21f18183faf 100644 --- a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/wal/ValueStoreWalIntegrationTest.java +++ b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/wal/ValueStoreWalIntegrationTest.java @@ -242,7 +242,7 @@ void enablingWalOnPopulatedStoreRebuildsExistingEntries() throws Exception { .filter(Files::isRegularFile) .map(path -> path.getFileName().toString()) .filter(name -> name.startsWith("wal-"))) - .allMatch(name -> name.matches("wal-[1-9]\\d*\\.v1(?:\\.gz)?")); + .allMatch(name -> name.matches("wal-[1-9]\\d*\\.v1(?:\\.gz)?")); } } } diff --git a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/wal/ValueStoreWalReaderJacksonTest.java b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/wal/ValueStoreWalReaderJacksonTest.java index 2dd2d55cb4a..f29eb83c999 100644 --- a/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/wal/ValueStoreWalReaderJacksonTest.java +++ b/core/sail/nativerdf/src/test/java/org/eclipse/rdf4j/sail/nativerdf/wal/ValueStoreWalReaderJacksonTest.java @@ -71,11 +71,11 @@ void scanReturnsMintedRecordsWithEscapes() throws Exception { assertThat(records.stream() .anyMatch(r -> r.valueKind() == ValueStoreWalValueKind.IRI && r.lexical().equals("http://example.com/resource"))) - .isTrue(); + .isTrue(); assertThat(records.stream() .anyMatch(r -> r.valueKind() == ValueStoreWalValueKind.LITERAL && r.lexical().equals(specialText))) - .isTrue(); + .isTrue(); assertThat(scan.lastValidLsn()).isGreaterThan(ValueStoreWAL.NO_LSN); } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClosedConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClosedConstraintComponent.java index 5b993f92bd5..4bec21db0dc 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClosedConstraintComponent.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ClosedConstraintComponent.java @@ -234,7 +234,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections return validationTuple; }, connectionsGroup) - .getTrueNode(UnBufferedPlanNode.class); + .getTrueNode(UnBufferedPlanNode.class); return falseNode1; diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java index 11cfed73fcf..f38b1dbc996 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java @@ -137,7 +137,7 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections PlanNode falseNode = new ValueInFilter(addedTargets, new HashSet<>(Collections.singletonList(hasValue)), connectionsGroup) - .getFalseNode(UnBufferedPlanNode.class); + .getFalseNode(UnBufferedPlanNode.class); return falseNode; diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java index 470b32fc685..a4700ab13a3 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java @@ -377,7 +377,7 @@ public PlanNode getTargetFilter(ConnectionsGroup connectionsGroup, Resource[] da return new ExternalFilterByQuery(connectionsGroup.getBaseConnection(), dataGraph, parent, sparqlFragment, last.var, ValidationTuple::getActiveTarget, null, connectionsGroup) - .getTrueNode(UnBufferedPlanNode.class); + .getTrueNode(UnBufferedPlanNode.class); } public String getQuery(boolean includeOptional) { diff --git a/core/sparqlbuilder/src/test/java/org/eclipse/rdf4j/sparqlbuilder/examples/updatespec/Section3Test.java b/core/sparqlbuilder/src/test/java/org/eclipse/rdf4j/sparqlbuilder/examples/updatespec/Section3Test.java index 36ae74b3851..78f4a6a70fa 100644 --- a/core/sparqlbuilder/src/test/java/org/eclipse/rdf4j/sparqlbuilder/examples/updatespec/Section3Test.java +++ b/core/sparqlbuilder/src/test/java/org/eclipse/rdf4j/sparqlbuilder/examples/updatespec/Section3Test.java @@ -369,8 +369,8 @@ public void example_10() { .delete(book.has(p, v)) .where(and(book.has(dc.iri("date"), date).andHas(dc.iri("type"), dcmitype.iri("PhysicalObject")), book.has(p, v)) - .filter(Expressions.lt(date, - Rdf.literalOfType("2000-01-01T00:00:00-02:00", xsd.iri("dateTime"))))); + .filter(Expressions.lt(date, + Rdf.literalOfType("2000-01-01T00:00:00-02:00", xsd.iri("dateTime"))))); assertThat(deleteFromBookStoreQuery.getQueryString()).is(stringEqualsIgnoreCaseAndWhitespace( "WITH \n" diff --git a/pom.xml b/pom.xml index 68b46991162..88a425e87ac 100644 --- a/pom.xml +++ b/pom.xml @@ -331,7 +331,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.46.1 + 2.34.0 diff --git a/tools/federation/src/main/java/org/eclipse/rdf4j/federated/cache/SourceSelectionMemoryCache.java b/tools/federation/src/main/java/org/eclipse/rdf4j/federated/cache/SourceSelectionMemoryCache.java index 9ef97959c39..0110cc1fa64 100644 --- a/tools/federation/src/main/java/org/eclipse/rdf4j/federated/cache/SourceSelectionMemoryCache.java +++ b/tools/federation/src/main/java/org/eclipse/rdf4j/federated/cache/SourceSelectionMemoryCache.java @@ -76,7 +76,7 @@ public StatementSourceAssurance getAssurance(SubQuery subQuery, Endpoint endpoin if (subQuery.object() != null) { if (getAssurance(new SubQuery(subQuery.subject(), subQuery.predicate(), null, subQuery.contexts()), endpoint) - .equals(StatementSourceAssurance.NONE)) { + .equals(StatementSourceAssurance.NONE)) { return StatementSourceAssurance.NONE; } } diff --git a/tools/federation/src/test/java/org/eclipse/rdf4j/federated/repository/FedXRepositoryConfigTest.java b/tools/federation/src/test/java/org/eclipse/rdf4j/federated/repository/FedXRepositoryConfigTest.java index 7281e19fb0a..da34d493515 100644 --- a/tools/federation/src/test/java/org/eclipse/rdf4j/federated/repository/FedXRepositoryConfigTest.java +++ b/tools/federation/src/test/java/org/eclipse/rdf4j/federated/repository/FedXRepositoryConfigTest.java @@ -164,73 +164,73 @@ public void testExport() throws Exception { assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_JOIN_WORKER_THREADS, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(101)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(101)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_UNION_WORKER_THREADS, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(102)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(102)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LEFT_JOIN_WORKER_THREADS, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(103)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(103)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_BOUND_JOIN_BLOCK_SIZE, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(104)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(104)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENFORCE_MAX_QUERY_TIME, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(105)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(105)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_SERVICE_AS_BOUND_JOIN, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_OPTIONAL_AS_BIND_JOIN, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_MONITORING, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LOG_QUERY_PLAN, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LOG_QUERIES, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_DEBUG_QUERY_PLAN, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_INCLUDE_INFERRED_DEFAULT, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_SOURCE_SELECTION_CACHE_SPEC, null))) - .hasValueSatisfying( - v -> assertThat(v.stringValue()).isEqualTo("spec-goes-here")); + .hasValueSatisfying( + v -> assertThat(v.stringValue()).isEqualTo("spec-goes-here")); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_PREFIX_DECLARATIONS, null))) - .hasValueSatisfying( - v -> assertThat(v.stringValue()).isEqualTo("prefixes-go-here")); + .hasValueSatisfying( + v -> assertThat(v.stringValue()).isEqualTo("prefixes-go-here")); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_CONSUMING_ITERATION_MAX, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(106)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(106)); } @Test @@ -254,60 +254,60 @@ public void testExportWithEmptyConfig() throws Exception { assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_JOIN_WORKER_THREADS, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(20)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(20)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_UNION_WORKER_THREADS, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(20)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(20)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LEFT_JOIN_WORKER_THREADS, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(10)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(10)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_BOUND_JOIN_BLOCK_SIZE, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(25)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(25)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENFORCE_MAX_QUERY_TIME, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(30)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(30)); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_SERVICE_AS_BOUND_JOIN, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_OPTIONAL_AS_BIND_JOIN, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_ENABLE_MONITORING, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LOG_QUERY_PLAN, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_LOG_QUERIES, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_DEBUG_QUERY_PLAN, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isFalse()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_INCLUDE_INFERRED_DEFAULT, null))) - .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); + .hasValueSatisfying(v -> assertThat(v.booleanValue()).isTrue()); assertThat( Models.objectLiteral( export.getStatements(configNode, FedXRepositoryConfig.CONFIG_CONSUMING_ITERATION_MAX, null))) - .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(1000)); + .hasValueSatisfying(v -> assertThat(v.intValue()).isEqualTo(1000)); } } } diff --git a/tools/server-boot/src/test/java/org/eclipse/rdf4j/tools/serverboot/Rdf4jServerWorkbenchApplicationTest.java b/tools/server-boot/src/test/java/org/eclipse/rdf4j/tools/serverboot/Rdf4jServerWorkbenchApplicationTest.java index 22cd69a15fe..f99608f8a69 100644 --- a/tools/server-boot/src/test/java/org/eclipse/rdf4j/tools/serverboot/Rdf4jServerWorkbenchApplicationTest.java +++ b/tools/server-boot/src/test/java/org/eclipse/rdf4j/tools/serverboot/Rdf4jServerWorkbenchApplicationTest.java @@ -335,8 +335,8 @@ void shaclRepositoryRejectsInvalidData() throws Exception { .isInstanceOf(RepositoryException.class) .satisfies(ex -> assertThat(hasRootCause(ex, ShaclSailValidationException.class) || hasRootCause(ex, RemoteShaclValidationException.class)) - .as("SHACL validation exception propagated to caller") - .isTrue()); + .as("SHACL validation exception propagated to caller") + .isTrue()); String validInstance = String.join("\n", "@prefix ex: .", diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/base/TransformationServletCoverageTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/base/TransformationServletCoverageTest.java index 1e780b306aa..3928141fed5 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/base/TransformationServletCoverageTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/base/TransformationServletCoverageTest.java @@ -98,7 +98,7 @@ void initRequiresTransformationsAndDefaultBuilderServiceIsCallable() throws Exce assertThatThrownBy(() -> missing.init(new TestServletConfig("transform", new MockServletContext(), java.util.Map.of()))) - .isInstanceOf(MissingInitParameterException.class); + .isInstanceOf(MissingInitParameterException.class); NoOpTransformationServlet servlet = new NoOpTransformationServlet(); servlet.setRepositoryManager(mock(RepositoryManager.class)); @@ -107,7 +107,7 @@ void initRequiresTransformationsAndDefaultBuilderServiceIsCallable() throws Exce assertThatCode( () -> servlet.service(mock(WorkbenchRequest.class), mock(HttpServletResponse.class), "/transform")) - .doesNotThrowAnyException(); + .doesNotThrowAnyException(); assertThat(servlet.builderRequested).isTrue(); } @@ -120,9 +120,9 @@ void publicServiceWrapsCheckedExceptions() throws Exception { assertThatThrownBy(() -> servlet.service(new MockHttpServletRequest("GET", "/transform"), mock(HttpServletResponse.class))) - .isInstanceOf(ServletException.class) - .hasCauseInstanceOf(Exception.class) - .hasMessageContaining("boom"); + .isInstanceOf(ServletException.class) + .hasCauseInstanceOf(Exception.class) + .hasMessageContaining("boom"); } private static final class RecordingTransformationServlet extends TransformationServlet { diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/CreateTemplateConfigTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/CreateTemplateConfigTest.java index d2b0dab60c2..8d0a9c6c650 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/CreateTemplateConfigTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/CreateTemplateConfigTest.java @@ -64,8 +64,8 @@ void parseRejectsLegacyInlineFieldHints() { assertThatThrownBy(() -> parse("synthetic", String.join("\n", "# @workbench.template label=\"Synthetic\" order=5", "[] config:rep.id \"{%Repository ID[len=16]|synthetic%}\" ."))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("# @workbench.field"); + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("# @workbench.field"); } @Test @@ -184,17 +184,17 @@ void parseCoversExplicitVisibleMetadataAndFileTemplateDiscoveryBranches() throws new Class[] { String.class, String.class }, "ftp://example.org/RepositoryConfig.class", "org/eclipse/rdf4j/repository/config")) - .isInstanceOf(RuntimeException.class) - .hasCauseInstanceOf(IOException.class) - .hasMessageContaining("Unsupported RepositoryConfig resource URI"); + .isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(IOException.class) + .hasMessageContaining("Unsupported RepositoryConfig resource URI"); assertThatThrownBy(() -> invoke("discoverBuiltinTemplateTypes", new Class[] { String.class, String.class }, "https://example.org/with space", "org/eclipse/rdf4j/repository/config")) - .isInstanceOf(RuntimeException.class) - .hasCauseInstanceOf(IOException.class) - .hasMessageContaining("Could not resolve RepositoryConfig resources"); + .isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(IOException.class) + .hasMessageContaining("Could not resolve RepositoryConfig resources"); } @Test diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/QueryServletFlowCoverageTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/QueryServletFlowCoverageTest.java index 042c73b520e..6bde94e6e2d 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/QueryServletFlowCoverageTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/QueryServletFlowCoverageTest.java @@ -80,8 +80,8 @@ void initWrapsQueryStorageInitializationFailures(@TempDir Path tempDir) throws E assertThatThrownBy(() -> servlet.init( TestServletConfig.withParams("query", "transformations", "/transform", "cookie-max-age", "60"))) - .isInstanceOf(ServletException.class) - .hasCauseInstanceOf(RepositoryException.class); + .isInstanceOf(ServletException.class) + .hasCauseInstanceOf(RepositoryException.class); } finally { if (previous == null) { System.clearProperty(key); diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/SavedQueriesServletTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/SavedQueriesServletTest.java index d3bcbfa30e4..d7230716555 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/SavedQueriesServletTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/commands/SavedQueriesServletTest.java @@ -140,8 +140,8 @@ void serviceFallsBackToRepositoryClassNameAndUnknownRepository() throws Exceptio assertThatThrownBy(() -> repoServlet.service(new MockHttpServletRequest("GET", "/saved"), new CapturingHttpServletResponse())) - .isInstanceOf(BadRequestException.class) - .hasMessageContaining(expectedReference(repository.getClass().getName())); + .isInstanceOf(BadRequestException.class) + .hasMessageContaining(expectedReference(repository.getClass().getName())); QueryStorage unknownStorage = mock(QueryStorage.class); when(unknownStorage.checkAccess(null)).thenReturn(false); @@ -151,8 +151,8 @@ void serviceFallsBackToRepositoryClassNameAndUnknownRepository() throws Exceptio assertThatThrownBy(() -> unknownServlet.service(new MockHttpServletRequest("GET", "/saved"), new CapturingHttpServletResponse())) - .isInstanceOf(BadRequestException.class) - .hasMessageContaining(expectedReference("unknown-repository")); + .isInstanceOf(BadRequestException.class) + .hasMessageContaining(expectedReference("unknown-repository")); } @Test @@ -166,8 +166,8 @@ void postRejectsMissingDeleteAndUnauthorizedDelete() throws Exception { assertThatThrownBy(() -> servlet.service(new MockHttpServletRequest("POST", "/saved"), new CapturingHttpServletResponse())) - .isInstanceOf(BadRequestException.class) - .hasMessageContaining("Expected POST to contain a 'delete=' parameter."); + .isInstanceOf(BadRequestException.class) + .hasMessageContaining("Expected POST to contain a 'delete=' parameter."); MockHttpServletRequest request = new MockHttpServletRequest("POST", "/saved"); request.addParameter("delete", "urn:test:query"); diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/ProxyRepositoryServletTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/ProxyRepositoryServletTest.java index 5a8569e1be0..754b2077fff 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/ProxyRepositoryServletTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/ProxyRepositoryServletTest.java @@ -53,8 +53,8 @@ void initRequiresDefaultCommandAndWrapsChildConstructionFailures() { assertThatThrownBy(() -> servlet.init(TestServletConfig.withParams("proxy", "default-command", "/summary", "/summary", AbstractBrokenServlet.class.getName()))) - .isInstanceOf(ServletException.class) - .hasCauseInstanceOf(InstantiationException.class); + .isInstanceOf(ServletException.class) + .hasCauseInstanceOf(InstantiationException.class); } @Test diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/WorkbenchGatewayTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/WorkbenchGatewayTest.java index 83a28f13f3f..3cc4ad66331 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/WorkbenchGatewayTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/WorkbenchGatewayTest.java @@ -50,13 +50,13 @@ void initValidatesRequiredParametersAndServerMode() throws Exception { assertThatThrownBy( () -> missingDefault .init(TestServletConfig.withParams("gateway", WorkbenchGateway.TRANSFORMATIONS, "/xsl"))) - .isInstanceOf(MissingInitParameterException.class); + .isInstanceOf(MissingInitParameterException.class); TestWorkbenchGateway missingTransformations = new TestWorkbenchGateway(new TestCookieHandler("9"), mock(ServerValidator.class)); assertThatThrownBy(() -> missingTransformations .init(TestServletConfig.withParams("gateway", "default-server", "https://example.org/rdf4j-server"))) - .isInstanceOf(MissingInitParameterException.class); + .isInstanceOf(MissingInitParameterException.class); TestWorkbenchGateway mutable = new TestWorkbenchGateway(new TestCookieHandler("9"), mock(ServerValidator.class)); @@ -64,7 +64,7 @@ void initValidatesRequiredParametersAndServerMode() throws Exception { "default-server", "https://example.org/rdf4j-server", "change-server-path", "/change", WorkbenchGateway.TRANSFORMATIONS, "/transform"))) - .isSameAs(mutable); + .isSameAs(mutable); assertThat(mutable.getChangeServerPath()).isEqualTo("/change"); assertThat(mutable.getDefaultServerPath()).isEqualTo("https://example.org/rdf4j-server"); assertThat(mutable.isServerFixed()).isFalse(); @@ -222,8 +222,8 @@ void gatewayWrapsChangeServerFailuresAndRedirectsNullPathRequests() throws Excep assertThatThrownBy(() -> failingGateway.service(request("GET", "/workbench/change", "/change"), failingResponse)) - .isInstanceOf(java.io.IOException.class) - .hasCauseInstanceOf(QueryResultHandlerException.class); + .isInstanceOf(java.io.IOException.class) + .hasCauseInstanceOf(QueryResultHandlerException.class); TestCookieHandler cookies = new TestCookieHandler("10"); cookies.cookies.put("workbench-server", "urn:bad"); diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/WorkbenchServletTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/WorkbenchServletTest.java index 8e47e124734..9eec10a8014 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/WorkbenchServletTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/proxy/WorkbenchServletTest.java @@ -61,20 +61,20 @@ void initValidatesParametersAndManagerCreation(@TempDir File tempDir) throws Exc assertThatThrownBy( () -> missingDefault.init(TestServletConfig.withParams("workbench", WorkbenchServlet.SERVER_PARAM, "https://example.org/rdf4j-server"))) - .isInstanceOf(MissingInitParameterException.class); + .isInstanceOf(MissingInitParameterException.class); TestWorkbenchServlet missingServer = new TestWorkbenchServlet(); assertThatThrownBy( () -> missingServer.init(TestServletConfig.withParams("workbench", "default-path", "/repositories"))) - .isInstanceOf(MissingInitParameterException.class); + .isInstanceOf(MissingInitParameterException.class); TestWorkbenchServlet failing = new TestWorkbenchServlet(); failing.managerFailure = new RepositoryException("boom"); assertThatThrownBy(() -> failing.init(TestServletConfig.withParams("workbench", "default-path", "/repositories", WorkbenchServlet.SERVER_PARAM, "https://example.org/rdf4j-server"))) - .isInstanceOf(ServletException.class) - .hasCauseInstanceOf(RepositoryException.class); + .isInstanceOf(ServletException.class) + .hasCauseInstanceOf(RepositoryException.class); WorkbenchServlet real = new WorkbenchServlet(); assertThat(real.createRepositoryManager(tempDir.toURI().toString())).isInstanceOf(LocalRepositoryManager.class); @@ -88,7 +88,7 @@ void initRejectsBlankServerAndHelperFactoriesAreCovered() throws Exception { assertThatThrownBy(() -> blankServer.init(TestServletConfig.withParams("workbench", "default-path", "/repositories", WorkbenchServlet.SERVER_PARAM, " "))) - .isInstanceOf(MissingInitParameterException.class); + .isInstanceOf(MissingInitParameterException.class); RepositoryManager manager = mock(RepositoryManager.class); FactoryWorkbenchServlet servlet = new FactoryWorkbenchServlet(manager); @@ -201,8 +201,8 @@ void serviceHandlesRepositoryErrorsValidationAndUnauthorizedResponses() throws E when(manager.getRepository("broken")).thenThrow(new RepositoryException("broken")); assertThatThrownBy( () -> failingServlet.service(request("/workbench/broken", "/broken"), new CapturedResponse())) - .isInstanceOf(ServletException.class) - .hasCauseInstanceOf(RepositoryException.class); + .isInstanceOf(ServletException.class) + .hasCauseInstanceOf(RepositoryException.class); } @Test @@ -250,8 +250,8 @@ void serviceWrapsUnauthorizedRenderingFailuresAndNonMatchingNoRepositoryIds() th when(manager.getRepository("missing")).thenReturn(null); assertThatThrownBy( () -> missingServlet.service(request("/workbench/missing", "/missing"), new CapturedResponse())) - .isInstanceOf(BadRequestException.class) - .hasMessageContaining("No such repository: missing"); + .isInstanceOf(BadRequestException.class) + .hasMessageContaining("No such repository: missing"); ThrowingUnauthorizedWorkbenchServlet unauthorizedServlet = new ThrowingUnauthorizedWorkbenchServlet(); unauthorizedServlet.managerToReturn = manager; @@ -267,8 +267,8 @@ void serviceWrapsUnauthorizedRenderingFailuresAndNonMatchingNoRepositoryIds() th assertThatThrownBy( () -> unauthorizedServlet.service(request("/workbench/repo", "/repo"), new CapturedResponse())) - .isInstanceOf(IOException.class) - .hasCauseInstanceOf(org.eclipse.rdf4j.query.QueryResultHandlerException.class); + .isInstanceOf(IOException.class) + .hasCauseInstanceOf(org.eclipse.rdf4j.query.QueryResultHandlerException.class); } private static TestWorkbenchServlet initServlet(RepositoryManager manager) throws Exception { diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/util/QueryEvaluatorCoverageTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/util/QueryEvaluatorCoverageTest.java index ce259e69005..9fb01116eaf 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/util/QueryEvaluatorCoverageTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/util/QueryEvaluatorCoverageTest.java @@ -299,8 +299,8 @@ void unknownQueryTypesFailFast() throws Exception { assertThatThrownBy(() -> QueryEvaluator.INSTANCE.extractQueryAndEvaluate(builder, response, new ByteArrayOutputStream(), "transformations", connection, "describe ?s where { ?s ?p ?o }", request, cookies, null)) - .isInstanceOf(BadRequestException.class) - .hasMessageContaining("Unknown query type:"); + .isInstanceOf(BadRequestException.class) + .hasMessageContaining("Unknown query type:"); } @Test diff --git a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/util/QueryStorageTest.java b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/util/QueryStorageTest.java index 83548d83337..621365a5da9 100644 --- a/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/util/QueryStorageTest.java +++ b/tools/workbench/src/test/java/org/eclipse/rdf4j/workbench/util/QueryStorageTest.java @@ -94,20 +94,20 @@ void saveQueryRejectsIllegalInputs() throws Exception { assertThatThrownBy(() -> storage.saveQuery("urn:test:repository", "bad", "alice", false, new QueryLanguage("SERQL"), "select * where { ?s ?p ?o }", true, 10, 0)) - .isInstanceOf(RepositoryException.class) - .hasMessageContaining("May only save SPARQL queries"); + .isInstanceOf(RepositoryException.class) + .hasMessageContaining("May only save SPARQL queries"); assertThatThrownBy(() -> storage.saveQuery("urn:test:repository", "bad", "alice", false, QueryLanguage.SPARQL, "select * where { ?s ?p ?o }", true, 13, 0)) - .isInstanceOf(RepositoryException.class) - .hasMessageContaining("Illegal value for rows per page"); + .isInstanceOf(RepositoryException.class) + .hasMessageContaining("Illegal value for rows per page"); assertThatThrownBy(() -> storage.saveQuery("urn:test:repository", "bad", "alice", false, QueryLanguage.SPARQL, "select * where { ?s ?p ?o }", true, 10, -1)) - .isInstanceOf(RepositoryException.class) - .hasMessageContaining("Illegal value for query timeout"); + .isInstanceOf(RepositoryException.class) + .hasMessageContaining("Illegal value for query timeout"); assertThatThrownBy(() -> storage.saveQuery("urn:test:repository", "bad", "alice", false, QueryLanguage.SPARQL, "select '''bad''' where { ?s ?p ?o }", true, 10, 0)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("queryText may not contain '''-quoted strings."); + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("queryText may not contain '''-quoted strings."); storage.shutdown(); } @@ -160,7 +160,7 @@ void checkAccessReturnsFalseWhenConnectionOperationFails() throws Exception { when(connection.hasStatement((IRI) org.mockito.ArgumentMatchers.any(), (IRI) org.mockito.ArgumentMatchers.any(), (IRI) org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.eq(false), (IRI) org.mockito.ArgumentMatchers.any())) - .thenThrow(new RepositoryException("forbidden")); + .thenThrow(new RepositoryException("forbidden")); QueryStorage storage = new QueryStorage(repository); From 32db428ffa0d0a66536320554b9288f57b3752d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20M=2E=20Ottestad?= Date: Wed, 15 Apr 2026 18:10:40 +0200 Subject: [PATCH 2/2] GH-5711 improve data import speed (also GH-5748) (#5721) Fixes GH-5711 and fixes GH-5748 --- .codex/skills/onboard/SKILL.md | 243 - .codex/skills/optimize/SKILL.md | 269 - .codex/skills/review/SKILL.md | 78 - .codex/skills/review/checklist.md | 125 - compliance/pom.xml | 2 +- .../lmdb/LmdbPARQL11UpdateComplianceTest.java | 5 + .../lmdb/LmdbSPARQL11QueryComplianceTest.java | 5 + .../sail/lmdb/LmdbSPARQLComplianceTest.java | 5 + .../common/transaction/DataImportMetrics.java | 19 + .../transaction/DataImportMetricsFactory.java | 34 + ...mmon.transaction.TransactionSettingFactory | 1 + .../transaction/DataImportMetricsTest.java | 32 + .../impl/AbstractMemoryOverflowModel.java | 119 +- .../rdf4j/model/impl/AbstractModel.java | 3 +- .../rdf4j/model/impl/DynamicModel.java | 676 +- .../rdf4j/model/impl/LinkedHashModel.java | 6 +- .../impl/AbstractMemoryOverflowModelTest.java | 183 + .../rdf4j/model/impl/DynamicModelTest.java | 723 ++ .../eclipse/rdf4j/repository/config/lmdb.ttl | 6 +- .../sail/helpers/AbstractSailConnection.java | 66 +- ...ctSailConnectionDataImportMetricsTest.java | 333 + .../rdf4j/sail/base/SailSourceConnection.java | 4 + .../sail/base/SnapshotSailStoreTest.java | 105 +- core/sail/lmdb/pom.xml | 18 + .../rdf4j/sail/lmdb/LeadingFieldSorters.java | 140 + .../rdf4j/sail/lmdb/LmdbSailStore.java | 233 +- .../eclipse/rdf4j/sail/lmdb/LmdbStore.java | 2 +- .../rdf4j/sail/lmdb/MemoryOverflowModel.java | 76 +- .../eclipse/rdf4j/sail/lmdb/TripleStore.java | 702 +- .../rdf4j/sail/lmdb/TxnRecordCache.java | 59 +- .../eclipse/rdf4j/sail/lmdb/ValueStore.java | 102 +- .../sail/lmdb/config/LmdbStoreConfig.java | 30 + .../sail/lmdb/config/LmdbStoreSchema.java | 6 + .../rdf4j/sail/lmdb/CardinalityTest.java | 10 +- .../rdf4j/sail/lmdb/DefaultIndexTest.java | 5 +- .../sail/lmdb/LeadingFieldSortBenchmark.java | 202 + .../lmdb/LmdbCascadeValueExceptionTest.java | 5 + .../sail/lmdb/LmdbEvaluationStrategyTest.java | 5 + .../sail/lmdb/LmdbGraphQueryResultTest.java | 5 + .../lmdb/LmdbOptimisticIsolationTest.java | 2 +- .../rdf4j/sail/lmdb/LmdbSailStoreTest.java | 178 +- .../sail/lmdb/LmdbSparqlOrderByTest.java | 5 + .../rdf4j/sail/lmdb/LmdbSparqlRegexTest.java | 5 + .../sail/lmdb/LmdbStoreConcurrencyTest.java | 5 + .../sail/lmdb/LmdbStoreConnectionTest.java | 5 + .../sail/lmdb/LmdbStoreConsistencyIT.java | 224 +- .../rdf4j/sail/lmdb/LmdbStoreContextTest.java | 5 + .../rdf4j/sail/lmdb/LmdbStoreDirLockTest.java | 1 + .../sail/lmdb/LmdbStoreErrorHandlingTest.java | 6 +- .../sail/lmdb/LmdbStoreInterruptTest.java | 5 + .../lmdb/LmdbStoreIsolationLevelTest.java | 5 + .../sail/lmdb/LmdbStoreModelLifecycleIT.java | 230 + .../sail/lmdb/LmdbStoreRepositoryTest.java | 5 + .../rdf4j/sail/lmdb/LmdbStoreTest.java | 5 + .../sail/lmdb/LmdbStoreTmpDatadirTest.java | 2 + .../eclipse/rdf4j/sail/lmdb/LmdbTestUtil.java | 39 + .../sail/lmdb/LmdbTupleQueryResultTest.java | 5 + .../lmdb/LongMultithreadedTransactions.java | 158 +- .../rdf4j/sail/lmdb/QueryBenchmarkTest.java | 12 +- .../sail/lmdb/RecordIteratorBenchmark.java | 3 +- .../rdf4j/sail/lmdb/SailSourceModelTest.java | 13 +- .../lmdb/TestLmdbStoreMemoryOverflow.java | 19 +- .../rdf4j/sail/lmdb/TestLmdbStoreUpgrade.java | 8 +- .../sail/lmdb/TripleIndexToKeyCacheTest.java | 3 + .../lmdb/TripleStoreAlignedSortResetTest.java | 129 + .../sail/lmdb/TripleStoreAutoGrowTest.java | 325 +- ...TripleStoreIndexOrderOptimizationTest.java | 209 + ...ripleStoreLeadingFieldSortVariantTest.java | 80 + .../sail/lmdb/TripleStoreManyIndexesTest.java | 17 +- .../rdf4j/sail/lmdb/TripleStoreTest.java | 473 +- .../rdf4j/sail/lmdb/ValueStoreCacheTest.java | 1 + .../lmdb/ValueStoreNamespaceCacheTest.java | 1 + .../rdf4j/sail/lmdb/ValueStoreTest.java | 72 +- .../lmdb/benchmark/BenchmarkBaseFoaf.java | 9 +- .../benchmark/BenchmarkMetadataSmokeTest.java | 38 + .../rdf4j/sail/lmdb/benchmark/ConfigUtil.java | 13 +- .../DatagovLoadIsolationBenchmark.java | 67 +- .../OverflowBenchmarkConcurrent.java | 4 +- .../lmdb/benchmark/OverflowBenchmarkReal.java | 4 +- .../benchmark/OverflowBenchmarkSynthetic.java | 6 +- .../sail/lmdb/benchmark/QueryBenchmark.java | 9 +- .../lmdb/benchmark/QueryWriteBenchmark.java | 9 +- .../lmdb/benchmark/ThemeQueryBenchmark.java | 1 + .../TransactionsPerSecondBenchmark.java | 9 +- .../sail/lmdb/config/LmdbStoreConfigTest.java | 51 + .../rdf4j/sail/lucene/impl/LuceneIndex.java | 18 +- .../impl/AbstractGenericLuceneTest.java | 4 + .../impl/LuceneNonTransactionalTest.java | 11 +- .../sail/nativerdf/MemoryOverflowModel.java | 37 +- .../rdf4j/sail/nativerdf/NativeStore.java | 13 +- .../ParallelBenchmarkDeadlockIT.java | 109 + logs/mvnf/20260413-123107-clean.log | 27 + logs/mvnf/20260413-123107-install.log | 7285 +++++++++++++++++ logs/mvnf/20260413-123107-verify.log | 76 + logs/mvnf/20260413-123147-clean.log | 27 + logs/mvnf/20260413-123147-install.log | 7285 +++++++++++++++++ logs/mvnf/20260413-123147-verify.log | 4377 ++++++++++ logs/mvnf/20260413-123228-clean.log | 27 + logs/mvnf/20260413-123228-install.log | 7285 +++++++++++++++++ logs/mvnf/20260413-123228-verify.log | 0 logs/mvnf/20260413-123530-clean.log | 27 + logs/mvnf/20260413-123530-install.log | 7285 +++++++++++++++++ logs/mvnf/20260413-123530-verify.log | 168 + pom.xml | 4 +- scripts/run-single-benchmark.sh | 12 +- .../plan/QueryPlanSnapshotCliTest.java | 95 +- .../rdf4j/testsuite/model/ModelTest.java | 42 + .../repository/CascadeValueExceptionTest.java | 24 +- .../repository/GraphQueryResultTest.java | 18 +- .../repository/OptimisticIsolationTest.java | 23 +- .../repository/RepositoryConnectionTest.java | 39 +- .../repository/RepositoryDirCleanup.java | 39 + .../testsuite/repository/RepositoryTest.java | 21 +- .../repository/SparqlOrderByTest.java | 24 +- .../testsuite/repository/SparqlRegexTest.java | 24 +- .../repository/TupleQueryResultTest.java | 18 +- .../sail/EvaluationStrategyTest.java | 28 + .../rdf4j/testsuite/sail/RDFStoreTest.java | 18 +- .../testsuite/sail/SailConcurrencyTest.java | 16 +- .../rdf4j/testsuite/sail/SailDirCleanup.java | 39 + .../testsuite/sail/SailInterruptTest.java | 16 +- .../sail/SailIsolationLevelTest.java | 16 +- .../SPARQL11UpdateComplianceTest.java | 2 +- .../sparql/manifest/SPARQLComplianceTest.java | 37 + .../manifest/SPARQLQueryComplianceTest.java | 4 +- .../RepositorySPARQLComplianceTestSuite.java | 36 +- .../tools/serverboot/ServerBootSignalIT.java | 3 +- .../server/LmdbInvalidIndexDeletionIT.java | 8 + .../workbench/commands/CreateServletTest.java | 9 + 129 files changed, 40446 insertions(+), 1347 deletions(-) delete mode 100644 .codex/skills/onboard/SKILL.md delete mode 100644 .codex/skills/optimize/SKILL.md delete mode 100644 .codex/skills/review/SKILL.md delete mode 100644 .codex/skills/review/checklist.md create mode 100644 core/common/transaction/src/main/java/org/eclipse/rdf4j/common/transaction/DataImportMetrics.java create mode 100644 core/common/transaction/src/main/java/org/eclipse/rdf4j/common/transaction/DataImportMetricsFactory.java create mode 100644 core/common/transaction/src/test/java/org/eclipse/rdf4j/common/transaction/DataImportMetricsTest.java create mode 100644 core/model/src/test/java/org/eclipse/rdf4j/model/impl/AbstractMemoryOverflowModelTest.java create mode 100644 core/sail/api/src/test/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnectionDataImportMetricsTest.java create mode 100644 core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LeadingFieldSorters.java create mode 100644 core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/LeadingFieldSortBenchmark.java create mode 100644 core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/LmdbStoreModelLifecycleIT.java create mode 100644 core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/LmdbTestUtil.java create mode 100644 core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/TripleStoreAlignedSortResetTest.java create mode 100644 core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/TripleStoreIndexOrderOptimizationTest.java create mode 100644 core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/TripleStoreLeadingFieldSortVariantTest.java create mode 100644 core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/BenchmarkMetadataSmokeTest.java create mode 100644 core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ParallelBenchmarkDeadlockIT.java create mode 100644 logs/mvnf/20260413-123107-clean.log create mode 100644 logs/mvnf/20260413-123107-install.log create mode 100644 logs/mvnf/20260413-123107-verify.log create mode 100644 logs/mvnf/20260413-123147-clean.log create mode 100644 logs/mvnf/20260413-123147-install.log create mode 100644 logs/mvnf/20260413-123147-verify.log create mode 100644 logs/mvnf/20260413-123228-clean.log create mode 100644 logs/mvnf/20260413-123228-install.log create mode 100644 logs/mvnf/20260413-123228-verify.log create mode 100644 logs/mvnf/20260413-123530-clean.log create mode 100644 logs/mvnf/20260413-123530-install.log create mode 100644 logs/mvnf/20260413-123530-verify.log create mode 100644 testsuites/repository/src/main/java/org/eclipse/rdf4j/testsuite/repository/RepositoryDirCleanup.java create mode 100644 testsuites/sail/src/main/java/org/eclipse/rdf4j/testsuite/sail/SailDirCleanup.java diff --git a/.codex/skills/onboard/SKILL.md b/.codex/skills/onboard/SKILL.md deleted file mode 100644 index fdf55acb49c..00000000000 --- a/.codex/skills/onboard/SKILL.md +++ /dev/null @@ -1,243 +0,0 @@ ---- -name: onboard -description: Design or improve onboarding flows, empty states, and first-time user experiences. Helps users get started successfully and understand value quickly. -args: - - name: target - description: The feature or area needing onboarding (optional) - required: false -user-invokable: true ---- - -Create or improve onboarding experiences that help users understand, adopt, and succeed with the product quickly. - -## Assess Onboarding Needs - -Understand what users need to learn and why: - -1. **Identify the challenge**: - - What are users trying to accomplish? - - What's confusing or unclear about current experience? - - Where do users get stuck or drop off? - - What's the "aha moment" we want users to reach? - -2. **Understand the users**: - - What's their experience level? (Beginners, power users, mixed?) - - What's their motivation? (Excited and exploring? Required by work?) - - What's their time commitment? (5 minutes? 30 minutes?) - - What alternatives do they know? (Coming from competitor? New to category?) - -3. **Define success**: - - What's the minimum users need to learn to be successful? - - What's the key action we want them to take? (First project? First invite?) - - How do we know onboarding worked? (Completion rate? Time to value?) - -**CRITICAL**: Onboarding should get users to value as quickly as possible, not teach everything possible. - -## Onboarding Principles - -Follow these core principles: - -### Show, Don't Tell -- Demonstrate with working examples, not just descriptions -- Provide real functionality in onboarding, not separate tutorial mode -- Use progressive disclosure - teach one thing at a time - -### Make It Optional (When Possible) -- Let experienced users skip onboarding -- Don't block access to product -- Provide "Skip" or "I'll explore on my own" options - -### Time to Value -- Get users to their "aha moment" ASAP -- Front-load most important concepts -- Teach 20% that delivers 80% of value -- Save advanced features for contextual discovery - -### Context Over Ceremony -- Teach features when users need them, not upfront -- Empty states are onboarding opportunities -- Tooltips and hints at point of use - -### Respect User Intelligence -- Don't patronize or over-explain -- Be concise and clear -- Assume users can figure out standard patterns - -## Design Onboarding Experiences - -Create appropriate onboarding for the context: - -### Initial Product Onboarding - -**Welcome Screen**: -- Clear value proposition (what is this product?) -- What users will learn/accomplish -- Time estimate (honest about commitment) -- Option to skip (for experienced users) - -**Account Setup**: -- Minimal required information (collect more later) -- Explain why you're asking for each piece of information -- Smart defaults where possible -- Social login when appropriate - -**Core Concept Introduction**: -- Introduce 1-3 core concepts (not everything) -- Use simple language and examples -- Interactive when possible (do, don't just read) -- Progress indication (step 1 of 3) - -**First Success**: -- Guide users to accomplish something real -- Pre-populated examples or templates -- Celebrate completion (but don't overdo it) -- Clear next steps - -### Feature Discovery & Adoption - -**Empty States**: -Instead of blank space, show: -- What will appear here (description + screenshot/illustration) -- Why it's valuable -- Clear CTA to create first item -- Example or template option - -Example: -``` -No projects yet -Projects help you organize your work and collaborate with your team. -[Create your first project] or [Start from template] -``` - -**Contextual Tooltips**: -- Appear at relevant moment (first time user sees feature) -- Point directly at relevant UI element -- Brief explanation + benefit -- Dismissable (with "Don't show again" option) -- Optional "Learn more" link - -**Feature Announcements**: -- Highlight new features when they're released -- Show what's new and why it matters -- Let users try immediately -- Dismissable - -**Progressive Onboarding**: -- Teach features when users encounter them -- Badges or indicators on new/unused features -- Unlock complexity gradually (don't show all options immediately) - -### Guided Tours & Walkthroughs - -**When to use**: -- Complex interfaces with many features -- Significant changes to existing product -- Industry-specific tools needing domain knowledge - -**How to design**: -- Spotlight specific UI elements (dim rest of page) -- Keep steps short (3-7 steps max per tour) -- Allow users to click through tour freely -- Include "Skip tour" option -- Make replayable (help menu) - -**Best practices**: -- Interactive > passive (let users click real buttons) -- Focus on workflow, not features ("Create a project" not "This is the project button") -- Provide sample data so actions work - -### Interactive Tutorials - -**When to use**: -- Users need hands-on practice -- Concepts are complex or unfamiliar -- High stakes (better to practice in safe environment) - -**How to design**: -- Sandbox environment with sample data -- Clear objectives ("Create a chart showing sales by region") -- Step-by-step guidance -- Validation (confirm they did it right) -- Graduation moment (you're ready!) - -### Documentation & Help - -**In-product help**: -- Contextual help links throughout interface -- Keyboard shortcut reference -- Search-able help center -- Video tutorials for complex workflows - -**Help patterns**: -- `?` icon near complex features -- "Learn more" links in tooltips -- Keyboard shortcut hints (`⌘K` shown on search box) - -## Empty State Design - -Every empty state needs: - -### What Will Be Here -"Your recent projects will appear here" - -### Why It Matters -"Projects help you organize your work and collaborate with your team" - -### How to Get Started -[Create project] or [Import from template] - -### Visual Interest -Illustration or icon (not just text on blank page) - -### Contextual Help -"Need help getting started? [Watch 2-min tutorial]" - -**Empty state types**: -- **First use**: Never used this feature (emphasize value, provide template) -- **User cleared**: Intentionally deleted everything (light touch, easy to recreate) -- **No results**: Search or filter returned nothing (suggest different query, clear filters) -- **No permissions**: Can't access (explain why, how to get access) -- **Error state**: Failed to load (explain what happened, retry option) - -## Implementation Patterns - -### Technical approaches: - -**Tooltip libraries**: Tippy.js, Popper.js -**Tour libraries**: Intro.js, Shepherd.js, React Joyride -**Modal patterns**: Focus trap, backdrop, ESC to close -**Progress tracking**: LocalStorage for "seen" states -**Analytics**: Track completion, drop-off points - -**Storage patterns**: -```javascript -// Track which onboarding steps user has seen -localStorage.setItem('onboarding-completed', 'true'); -localStorage.setItem('feature-tooltip-seen-reports', 'true'); -``` - -**IMPORTANT**: Don't show same onboarding twice (annoying). Track completion and respect dismissals. - -**NEVER**: -- Force users through long onboarding before they can use product -- Patronize users with obvious explanations -- Show same tooltip repeatedly (respect dismissals) -- Block all UI during tour (let users explore) -- Create separate tutorial mode disconnected from real product -- Overwhelm with information upfront (progressive disclosure!) -- Hide "Skip" or make it hard to find -- Forget about returning users (don't show initial onboarding again) - -## Verify Onboarding Quality - -Test with real users: - -- **Time to completion**: Can users complete onboarding quickly? -- **Comprehension**: Do users understand after completing? -- **Action**: Do users take desired next step? -- **Skip rate**: Are too many users skipping? (Maybe it's too long/not valuable) -- **Completion rate**: Are users completing? (If low, simplify) -- **Time to value**: How long until users get first value? - -Remember: You're a product educator with excellent teaching instincts. Get users to their "aha moment" as quickly as possible. Teach the essential, make it contextual, respect user time and intelligence. - diff --git a/.codex/skills/optimize/SKILL.md b/.codex/skills/optimize/SKILL.md deleted file mode 100644 index 720ccc792d7..00000000000 --- a/.codex/skills/optimize/SKILL.md +++ /dev/null @@ -1,269 +0,0 @@ ---- -name: optimize -description: Improve interface performance across loading speed, rendering, animations, images, and bundle size. Makes experiences faster and smoother. -args: - - name: target - description: The feature or area to optimize (optional) - required: false -user-invokable: true ---- - -Identify and fix performance issues to create faster, smoother user experiences. - -## Assess Performance Issues - -Understand current performance and identify problems: - -1. **Measure current state**: - - **Core Web Vitals**: LCP, FID/INP, CLS scores - - **Load time**: Time to interactive, first contentful paint - - **Bundle size**: JavaScript, CSS, image sizes - - **Runtime performance**: Frame rate, memory usage, CPU usage - - **Network**: Request count, payload sizes, waterfall - -2. **Identify bottlenecks**: - - What's slow? (Initial load? Interactions? Animations?) - - What's causing it? (Large images? Expensive JavaScript? Layout thrashing?) - - How bad is it? (Perceivable? Annoying? Blocking?) - - Who's affected? (All users? Mobile only? Slow connections?) - -**CRITICAL**: Measure before and after. Premature optimization wastes time. Optimize what actually matters. - -## Optimization Strategy - -Create systematic improvement plan: - -### Loading Performance - -**Optimize Images**: -- Use modern formats (WebP, AVIF) -- Proper sizing (don't load 3000px image for 300px display) -- Lazy loading for below-fold images -- Responsive images (`srcset`, `picture` element) -- Compress images (80-85% quality is usually imperceptible) -- Use CDN for faster delivery - -```html -Hero image -``` - -**Reduce JavaScript Bundle**: -- Code splitting (route-based, component-based) -- Tree shaking (remove unused code) -- Remove unused dependencies -- Lazy load non-critical code -- Use dynamic imports for large components - -```javascript -// Lazy load heavy component -const HeavyChart = lazy(() => import('./HeavyChart')); -``` - -**Optimize CSS**: -- Remove unused CSS -- Critical CSS inline, rest async -- Minimize CSS files -- Use CSS containment for independent regions - -**Optimize Fonts**: -- Use `font-display: swap` or `optional` -- Subset fonts (only characters you need) -- Preload critical fonts -- Use system fonts when appropriate -- Limit font weights loaded - -```css -@font-face { - font-family: 'CustomFont'; - src: url('/fonts/custom.woff2') format('woff2'); - font-display: swap; /* Show fallback immediately */ - unicode-range: U+0020-007F; /* Basic Latin only */ -} -``` - -**Optimize Loading Strategy**: -- Critical resources first (async/defer non-critical) -- Preload critical assets -- Prefetch likely next pages -- Service worker for offline/caching -- HTTP/2 or HTTP/3 for multiplexing - -### Rendering Performance - -**Avoid Layout Thrashing**: -```javascript -// ❌ Bad: Alternating reads and writes (causes reflows) -elements.forEach(el => { - const height = el.offsetHeight; // Read (forces layout) - el.style.height = height * 2; // Write -}); - -// ✅ Good: Batch reads, then batch writes -const heights = elements.map(el => el.offsetHeight); // All reads -elements.forEach((el, i) => { - el.style.height = heights[i] * 2; // All writes -}); -``` - -**Optimize Rendering**: -- Use CSS `contain` property for independent regions -- Minimize DOM depth (flatter is faster) -- Reduce DOM size (fewer elements) -- Use `content-visibility: auto` for long lists -- Virtual scrolling for very long lists (react-window, react-virtualized) - -**Reduce Paint & Composite**: -- Use `transform` and `opacity` for animations (GPU-accelerated) -- Avoid animating layout properties (width, height, top, left) -- Use `will-change` sparingly for known expensive operations -- Minimize paint areas (smaller is faster) - -### Animation Performance - -**GPU Acceleration**: -```css -/* ✅ GPU-accelerated (fast) */ -.animated { - transform: translateX(100px); - opacity: 0.5; -} - -/* ❌ CPU-bound (slow) */ -.animated { - left: 100px; - width: 300px; -} -``` - -**Smooth 60fps**: -- Target 16ms per frame (60fps) -- Use `requestAnimationFrame` for JS animations -- Debounce/throttle scroll handlers -- Use CSS animations when possible -- Avoid long-running JavaScript during animations - -**Intersection Observer**: -```javascript -// Efficiently detect when elements enter viewport -const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - // Element is visible, lazy load or animate - } - }); -}); -``` - -### React/Framework Optimization - -**React-specific**: -- Use `memo()` for expensive components -- `useMemo()` and `useCallback()` for expensive computations -- Virtualize long lists -- Code split routes -- Avoid inline function creation in render -- Use React DevTools Profiler - -**Framework-agnostic**: -- Minimize re-renders -- Debounce expensive operations -- Memoize computed values -- Lazy load routes and components - -### Network Optimization - -**Reduce Requests**: -- Combine small files -- Use SVG sprites for icons -- Inline small critical assets -- Remove unused third-party scripts - -**Optimize APIs**: -- Use pagination (don't load everything) -- GraphQL to request only needed fields -- Response compression (gzip, brotli) -- HTTP caching headers -- CDN for static assets - -**Optimize for Slow Connections**: -- Adaptive loading based on connection (navigator.connection) -- Optimistic UI updates -- Request prioritization -- Progressive enhancement - -## Core Web Vitals Optimization - -### Largest Contentful Paint (LCP < 2.5s) -- Optimize hero images -- Inline critical CSS -- Preload key resources -- Use CDN -- Server-side rendering - -### First Input Delay (FID < 100ms) / INP (< 200ms) -- Break up long tasks -- Defer non-critical JavaScript -- Use web workers for heavy computation -- Reduce JavaScript execution time - -### Cumulative Layout Shift (CLS < 0.1) -- Set dimensions on images and videos -- Don't inject content above existing content -- Use `aspect-ratio` CSS property -- Reserve space for ads/embeds -- Avoid animations that cause layout shifts - -```css -/* Reserve space for image */ -.image-container { - aspect-ratio: 16 / 9; -} -``` - -## Performance Monitoring - -**Tools to use**: -- Chrome DevTools (Lighthouse, Performance panel) -- WebPageTest -- Core Web Vitals (Chrome UX Report) -- Bundle analyzers (webpack-bundle-analyzer) -- Performance monitoring (Sentry, DataDog, New Relic) - -**Key metrics**: -- LCP, FID/INP, CLS (Core Web Vitals) -- Time to Interactive (TTI) -- First Contentful Paint (FCP) -- Total Blocking Time (TBT) -- Bundle size -- Request count - -**IMPORTANT**: Measure on real devices with real network conditions. Desktop Chrome with fast connection isn't representative. - -**NEVER**: -- Optimize without measuring (premature optimization) -- Sacrifice accessibility for performance -- Break functionality while optimizing -- Use `will-change` everywhere (creates new layers, uses memory) -- Lazy load above-fold content -- Optimize micro-optimizations while ignoring major issues (optimize the biggest bottleneck first) -- Forget about mobile performance (often slower devices, slower connections) - -## Verify Improvements - -Test that optimizations worked: - -- **Before/after metrics**: Compare Lighthouse scores -- **Real user monitoring**: Track improvements for real users -- **Different devices**: Test on low-end Android, not just flagship iPhone -- **Slow connections**: Throttle to 3G, test experience -- **No regressions**: Ensure functionality still works -- **User perception**: Does it *feel* faster? - -Remember: Performance is a feature. Fast experiences feel more responsive, more polished, more professional. Optimize systematically, measure ruthlessly, and prioritize user-perceived performance. - diff --git a/.codex/skills/review/SKILL.md b/.codex/skills/review/SKILL.md deleted file mode 100644 index 88f24150ccd..00000000000 --- a/.codex/skills/review/SKILL.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -name: review -version: 1.0.0 -description: | - Pre-landing PR review. Analyzes diff against main for SQL safety, LLM trust - boundary violations, conditional side effects, and other structural issues. -allowed-tools: - - Bash - - Read - - Edit - - Write - - Grep - - Glob - - AskUserQuestion ---- - -# Pre-Landing PR Review - -You are running the `/review` workflow. Analyze the current branch's diff against main for structural issues that tests don't catch. - ---- - -## Step 1: Check branch - -1. Run `git branch --show-current` to get the current branch. -2. If on `main`, output: **"Nothing to review — you're on main or have no changes against main."** and stop. -3. Run `git fetch origin main --quiet && git diff origin/main --stat` to check if there's a diff. If no diff, output the same message and stop. - ---- - -## Step 2: Read the checklist - -Read `checklist.md`. - -**If the file cannot be read, STOP and report the error.** Do not proceed without the checklist. - ---- - -## Step 3: Get the diff - -Fetch the latest main to avoid false positives from a stale local main: - -```bash -git fetch origin main --quiet -``` - -Run `git diff origin/main` to get the full diff. This includes both committed and uncommitted changes against the latest main. - ---- - -## Step 4: Two-pass review - -Apply the checklist against the diff in two passes: - -1. **Pass 1 (CRITICAL):** SQL & Data Safety, LLM Output Trust Boundary -2. **Pass 2 (INFORMATIONAL):** Conditional Side Effects, Magic Numbers & String Coupling, Dead Code & Consistency, LLM Prompt Issues, Test Gaps, View/Frontend - -Follow the output format specified in the checklist. Respect the suppressions — do NOT flag items listed in the "DO NOT flag" section. - ---- - -## Step 5: Output findings - -**Always output ALL findings** — both critical and informational. The user must see every issue. - -- If CRITICAL issues found: output all findings, then for EACH critical issue use a separate AskUserQuestion with the problem, your recommended fix, and options (A: Fix it now, B: Acknowledge, C: False positive — skip). - After all critical questions are answered, output a summary of what the user chose for each issue. If the user chose A (fix) on any issue, apply the recommended fixes. If only B/C were chosen, no action needed. -- If only non-critical issues found: output findings. No further action needed. -- If no issues found: output `Pre-Landing Review: No issues found.` - ---- - -## Important Rules - -- **Read the FULL diff before commenting.** Do not flag issues already addressed in the diff. -- **Read-only by default.** Only modify files if the user explicitly chooses "Fix it now" on a critical issue. Never commit, push, or create PRs. -- **Be terse.** One line problem, one line fix. No preamble. -- **Only flag real problems.** Skip anything that's fine. diff --git a/.codex/skills/review/checklist.md b/.codex/skills/review/checklist.md deleted file mode 100644 index e3218900b14..00000000000 --- a/.codex/skills/review/checklist.md +++ /dev/null @@ -1,125 +0,0 @@ -# Pre-Landing Review Checklist - -## Instructions - -Review the `git diff origin/main` output for the issues listed below. Be specific — cite `file:line` and suggest fixes. Skip anything that's fine. Only flag real problems. - -**Two-pass review:** -- **Pass 1 (CRITICAL):** Run SQL & Data Safety and LLM Output Trust Boundary first. These can block `/ship`. -- **Pass 2 (INFORMATIONAL):** Run all remaining categories. These are included in the PR body but do not block. - -**Output format:** - -``` -Pre-Landing Review: N issues (X critical, Y informational) - -**CRITICAL** (blocking /ship): -- [file:line] Problem description - Fix: suggested fix - -**Issues** (non-blocking): -- [file:line] Problem description - Fix: suggested fix -``` - -If no issues found: `Pre-Landing Review: No issues found.` - -Be terse. For each issue: one line describing the problem, one line with the fix. No preamble, no summaries, no "looks good overall." - ---- - -## Review Categories - -### Pass 1 — CRITICAL - -#### SQL & Data Safety -- String interpolation in SQL (even if values are `.to_i`/`.to_f` — use `sanitize_sql_array` or Arel) -- TOCTOU races: check-then-set patterns that should be atomic `WHERE` + `update_all` -- `update_column`/`update_columns` bypassing validations on fields that have or should have constraints -- N+1 queries: `.includes()` missing for associations used in loops/views (especially avatar, attachments) - -#### Race Conditions & Concurrency -- Read-check-write without uniqueness constraint or `rescue RecordNotUnique; retry` (e.g., `where(hash:).first` then `save!` without handling concurrent insert) -- `find_or_create_by` on columns without unique DB index — concurrent calls can create duplicates -- Status transitions that don't use atomic `WHERE old_status = ? UPDATE SET new_status` — concurrent updates can skip or double-apply transitions -- `html_safe` on user-controlled data (XSS) — check any `.html_safe`, `raw()`, or string interpolation into `html_safe` output - -#### LLM Output Trust Boundary -- LLM-generated values (emails, URLs, names) written to DB or passed to mailers without format validation. Add lightweight guards (`EMAIL_REGEXP`, `URI.parse`, `.strip`) before persisting. -- Structured tool output (arrays, hashes) accepted without type/shape checks before database writes. - -### Pass 2 — INFORMATIONAL - -#### Conditional Side Effects -- Code paths that branch on a condition but forget to apply a side effect on one branch. Example: item promoted to verified but URL only attached when a secondary condition is true — the other branch promotes without the URL, creating an inconsistent record. -- Log messages that claim an action happened but the action was conditionally skipped. The log should reflect what actually occurred. - -#### Magic Numbers & String Coupling -- Bare numeric literals used in multiple files — should be named constants documented together -- Error message strings used as query filters elsewhere (grep for the string — is anything matching on it?) - -#### Dead Code & Consistency -- Variables assigned but never read -- Version mismatch between PR title and VERSION/CHANGELOG files -- CHANGELOG entries that describe changes inaccurately (e.g., "changed from X to Y" when X never existed) -- Comments/docstrings that describe old behavior after the code changed - -#### LLM Prompt Issues -- 0-indexed lists in prompts (LLMs reliably return 1-indexed) -- Prompt text listing available tools/capabilities that don't match what's actually wired up in the `tool_classes`/`tools` array -- Word/token limits stated in multiple places that could drift - -#### Test Gaps -- Negative-path tests that assert type/status but not the side effects (URL attached? field populated? callback fired?) -- Assertions on string content without checking format (e.g., asserting title present but not URL format) -- `.expects(:something).never` missing when a code path should explicitly NOT call an external service -- Security enforcement features (blocking, rate limiting, auth) without integration tests verifying the enforcement path works end-to-end - -#### Crypto & Entropy -- Truncation of data instead of hashing (last N chars instead of SHA-256) — less entropy, easier collisions -- `rand()` / `Random.rand` for security-sensitive values — use `SecureRandom` instead -- Non-constant-time comparisons (`==`) on secrets or tokens — vulnerable to timing attacks - -#### Time Window Safety -- Date-key lookups that assume "today" covers 24h — report at 8am PT only sees midnight→8am under today's key -- Mismatched time windows between related features — one uses hourly buckets, another uses daily keys for the same data - -#### Type Coercion at Boundaries -- Values crossing Ruby→JSON→JS boundaries where type could change (numeric vs string) — hash/digest inputs must normalize types -- Hash/digest inputs that don't call `.to_s` or equivalent before serialization — `{ cores: 8 }` vs `{ cores: "8" }` produce different hashes - -#### View/Frontend -- Inline `