Skip to content

build: consolidate arcadedb-test-utils into server test-jar + fix HA bootstrap-fingerprint replay race#4259

Merged
robfrank merged 15 commits into
mainfrom
fix/failing-it-tests-2
May 19, 2026
Merged

build: consolidate arcadedb-test-utils into server test-jar + fix HA bootstrap-fingerprint replay race#4259
robfrank merged 15 commits into
mainfrom
fix/failing-it-tests-2

Conversation

@robfrank
Copy link
Copy Markdown
Collaborator

@robfrank robfrank commented May 18, 2026

Summary

Consolidates the duplicate test scaffolding (TestServerHelper, StaticBaseServerTest, BaseGraphServerTest, WebSocketClientHelper) into a single canonical home at server/src/test/java/com/arcadedb/server/, then deletes the arcadedb-test-utils module entirely.

Background: two near-identical copies of these helpers existed (one in arcadedb-test-utils, one in server/src/test/java). The duplication was structural (a Maven reactor cycle blocked the server module from depending on arcadedb-test-utils) and caused real test failures — the target/config/ cleanup was added to one copy but not the other, leading to HTTP 403 failures in RaftHTTP2ServersCreateReplicatedDatabaseIT and FollowerSessionTokenQueryIT when stale server-users.jsonl carried a different password hash.

Approach

After reconciling the four helper pairs (taking the better-quality version from each, keeping the server-copy's error-body capture in BaseGraphServerTest), all 10 downstream modules switch from arcadedb-test-utils to arcadedb-server:test-jar:test. The test-utils module is deleted. ~50 test imports rewritten.

Spec: docs/superpowers/specs/2026-05-18-test-utils-consolidation-design.md
Plan: docs/superpowers/plans/2026-05-18-test-utils-consolidation.md

Verification

  • Full reactor build: mvn clean install -DskipTests BUILD SUCCESS
  • Original-bug sentinels: RaftHTTP2ServersCreateReplicatedDatabaseIT, FollowerSessionTokenQueryIT PASS
  • Downstream sentinels (one IT per migrated module): BoltProtocolIT, ConsoleTest, GremlinServerTest, PostgresProtocolIT, MongoDBServerTest, RedisWTest, GrpcServerIT, RemoteGrpcServerIT, PrometheusMetricsPluginAuthenticatedTest, BoltTlsIT — all PASS (17 tests total, 0 failures)
  • Server test-jar still emitted after removing the misleading phase=none override in server/pom.xml (verified by inspecting ~/.m2/repository/com/arcadedb/arcadedb-server/26.6.1-SNAPSHOT/arcadedb-server-26.6.1-SNAPSHOT-tests.jar timestamp post-build)

Net diff

  • Deleted arcadedb-test-utils module (1158 lines)
  • 10 module poms updated (graphql had a dead dep, so its arcadedb-test-utils entry is removed without replacement)
  • 51 test files migrated to new imports
  • 1 small dep adjustment in grpc-client/pom.xml (test-scope arcadedb-server added because the test classpath needs ArcadeDBServer at class load via BaseGraphServerTest)

Rollback

Single git revert of the consolidation range restores everything (helpers, module, poms, imports). No data, schema, or config impact.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request consolidates test scaffolding by moving common test utilities from the arcadedb-test-utils module into the arcadedb-server test-jar and deleting the test-utils module. Key changes include updating Maven dependencies across multiple modules to use the test-jar type, migrating Java imports, and enhancing test helpers with improved resource management and logging. Feedback identifies that the arcadedb-server dependency in the grpc-client module was added with provided scope instead of test scope, which could lead to dependency leakage.

Comment thread grpc-client/pom.xml
Comment on lines 142 to +147
<dependency>
<groupId>com.arcadedb</groupId>
<artifactId>arcadedb-test-utils</artifactId>
<artifactId>arcadedb-server</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The dependency on arcadedb-server is added with provided scope, which deviates from the implementation plan (Task 4, Step 1) and potentially exposes server-side classes to the client module's main source code at compile time. Since this dependency is required for integration tests (supporting BaseGraphServerTest), it should be restricted to test scope to maintain proper modularity and avoid dependency leakage.

Suggested change
<dependency>
<groupId>com.arcadedb</groupId>
<artifactId>arcadedb-test-utils</artifactId>
<artifactId>arcadedb-server</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.arcadedb</groupId>
<artifactId>arcadedb-server</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 0107cb3. Changed <scope>provided</scope> to <scope>test</scope>. Verified RemoteGrpcServerIT still passes — grpc-client main code only imports the protobuf-generated com.arcadedb.server.grpc.* classes (which ship in the arcadedb-grpc module, not arcadedb-server), so test scope is the right fit.

@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented May 18, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity

Metric Results
Complexity 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@claude
Copy link
Copy Markdown

claude Bot commented May 18, 2026

Code Review

Overview

This PR consolidates the duplicate test scaffolding (TestServerHelper, StaticBaseServerTest, BaseGraphServerTest, WebSocketClientHelper) from the separate arcadedb-test-utils module into the canonical location in server/src/test/java/com/arcadedb/server/. All 10 downstream modules switch from arcadedb-test-utils to arcadedb-server:test-jar:test, and the test-utils module is deleted. The core motivation is good: the duplication caused real test failures (HTTP 403 due to stale target/config/ state).


Positives

  • Bug fix included: Adding FileUtils.deleteRecursively(new File("./target/config/")) to TestServerHelper.deleteDatabaseFolders directly addresses the 403 regression.
  • Correct utility-class pattern: TestServerHelper is now final with a private constructor instead of abstract — this is the right idiom.
  • Resource leak fixed: PrintWriter is now wrapped in try-with-resources in BaseGraphServerTest.checkArcadeIsTotallyDown().
  • Interrupt flag restored: WebSocketClientHelper.popMessage now calls Thread.currentThread().interrupt() in the InterruptedException catch — important correctness fix.
  • Structured logging: Replacing e.printStackTrace() with LogManager.instance().log() in the async callback aligns with the project's logging conventions.
  • Explicit import: Replacing java.util.logging.* with java.util.logging.Level in StaticBaseServerTest is cleaner.

Issues and Concerns

1. grpc-client/pom.xml introduces an unexpected provided-scope dependency

<!-- NEW - was not in the original pom -->
<dependency>
    <groupId>com.arcadedb</groupId>
    <artifactId>arcadedb-server</artifactId>
    <version>${project.parent.version}</version>
    <scope>provided</scope>
</dependency>
<!-- Plus the test-jar block -->
<dependency>
    <groupId>com.arcadedb</groupId>
    <artifactId>arcadedb-server</artifactId>
    <version>${project.parent.version}</version>
    <scope>test</scope>
    <type>test-jar</type>
</dependency>

The other 9 modules only add the test-jar block. The extra provided-scope entry in grpc-client affects main-source compilation, not just tests. If grpc-client is meant to be a standalone client library, this is a new compile-time coupling that should be documented or removed if it is not actually needed for main sources. Per CLAUDE.md conventions, wire-protocol modules should have arcadedb-server in provided scope only when they need it for main-source compilation — this addition should be justified explicitly.

2. graphql/pom.xml — spec says drop, implementation swaps

The spec document says:

"graphql declares the dep but no Java code references the classes — drop the dep, no import migration needed"

But the implementation swaps arcadedb-test-utils for arcadedb-server:test-jar:test instead of dropping it entirely. A zero-reference test dependency should just be removed. Either the spec is wrong (graphql does use something transitively) or the implementation missed the intent — either way, this should be resolved.

3. Planning/AI-workflow documents committed to the repo

docs/superpowers/plans/2026-05-18-test-utils-consolidation.md and docs/superpowers/specs/2026-05-18-test-utils-consolidation-design.md are implementation plans generated by an AI assistant (they reference "agentic workers", "superpowers:subagent-driven-development", and contain checkbox task lists). These are workflow artifacts, not project documentation. Consider removing them before merging or moving them to a non-committed location (wiki, issue comment, etc.).

4. PR description and checklist are unfilled

The PR body still contains placeholder text ("A brief description of the change being made...", "What inspired you...", etc.) and both checklist items are unchecked. This makes it harder to verify that the build and sentinel tests were actually run.

5. server/pom.xml — removing phase=none override

The plan document asserts that the maven-jar-plugin phase=none override is "functionally inert" because the test-jar is already emitted via parent pluginManagement. If that assumption is wrong, removing this block silently stops test-jar production and breaks all the new consumers at build time. The claim appears reasonable (ha-raft already consumed the test-jar successfully before this PR) but it is worth explicitly verifying via CI.


Minor Nits

  • The fail() message improvement is good: "Expected exception of type " + expectedException.getName() + " but none was thrown" is much more useful than "".
  • Import rewriting across ~50 files is mechanical and looks correct throughout.
  • The Javadoc update on BaseGraphServerTest (removing the "copied under Console project" comment) is overdue and correct.

Summary

The structural change is sound and the bug fix is valuable. Main actionable items before merging:

  1. Fix or justify the extra provided-scope arcadedb-server dependency in grpc-client/pom.xml.
  2. Drop the graphql test-jar dep if graphql truly has zero references to the helpers (or explain why it is kept).
  3. Remove the AI planning documents from docs/superpowers/ — these do not belong in a committed project tree.
  4. Fill in the PR description and confirm the build and sentinel tests pass.

@github-actions
Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 395 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL 2.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.5.32 - http://logback.qos.ch/logback-classic)
     (EPL 2.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.5.32 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.3 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.3 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@robfrank
Copy link
Copy Markdown
Collaborator Author

robfrank commented May 18, 2026

Walking the 5 items from the review.

1. grpc-client/pom.xml provided-scope dep. Fixed in 0107cb392: changed providedtest. Verified grpc-client main code only imports the protobuf-generated com.arcadedb.server.grpc.* package (which ships in the arcadedb-grpc module, not arcadedb-server), so test scope is correct. RemoteGrpcServerIT still passes.

2. graphql/pom.xml swap vs drop. Fixed in 0107cb392: dropped the arcadedb-server:test-jar:test entry entirely (it was added in error during Task 4 — the spec said to drop it). Verified: grep -rn 'com\.arcadedb\.server\.' graphql/src/test --include='*.java' returns nothing.

3. AI planning documents. Pushing back. The repo already collects design specs and implementation plans under docs/superpowers/specs/ and docs/superpowers/plans/ (14 prior specs, 17 prior plans before this PR), all committed by robfrank over the last ~2 months. This PR follows that established convention. The two new files document the why and the migration steps, which is useful for anyone reverting or doing similar consolidations later. If the project decides to move workflow artifacts elsewhere, that should be a single cross-cutting cleanup rather than carving out an exception for this PR.

4. PR description. Filled in — summary, approach, verification (17 sentinel tests pass), net diff, rollback. Both checklist items remain unchecked because the project's PR template predates this kind of refactor; they don't apply cleanly.

5. server/pom.xml phase=none removal — verified empirically. The test-jar emission was confirmed both before and after removing the override:

  • Before: arcadedb-server-26.6.1-SNAPSHOT-tests.jar was already in ~/.m2/repository/... (consumed by ha-raft and grpcw pre-PR)
  • After (post-Task 6 cleanup): re-built test-jar present with a fresh timestamp
  • All 17 sentinel tests across ha-raft, bolt, console, gremlin, grpc-client, grpcw, metrics, mongodbw, postgresw, redisw pass. If test-jar production were silently broken, none of those would resolve BaseGraphServerTest and would fail at class load.

Items 1, 2, 4 are concrete fixes; 3 and 5 addressed with reasoning above.

@github-actions
Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 395 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL 2.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.5.32 - http://logback.qos.ch/logback-classic)
     (EPL 2.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.5.32 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.3 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.3 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

❌ Patch coverage is 59.45946% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.65%. Comparing base (3591e93) to head (713e0d7).

Files with missing lines Patch % Lines
...com/arcadedb/server/ha/raft/SnapshotInstaller.java 54.54% 4 Missing and 1 partial ⚠️
...va/com/arcadedb/server/grpc/GrpcTypeConverter.java 0.00% 3 Missing and 1 partial ⚠️
...om/arcadedb/server/ha/raft/ArcadeStateMachine.java 80.00% 0 Missing and 2 partials ⚠️
...ain/java/com/arcadedb/server/ai/AiChatHandler.java 33.33% 2 Missing ⚠️
...java/com/arcadedb/server/ai/AiActivateHandler.java 50.00% 1 Missing ⚠️
...m/arcadedb/server/ai/AiAnalyzeProfilerHandler.java 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4259      +/-   ##
==========================================
+ Coverage   64.63%   64.65%   +0.02%     
==========================================
  Files        1644     1644              
  Lines      127254   127277      +23     
  Branches    27264    27267       +3     
==========================================
+ Hits        82255    82297      +42     
+ Misses      33509    33479      -30     
- Partials    11490    11501      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@claude
Copy link
Copy Markdown

claude Bot commented May 18, 2026

Code Review

Overview

This PR consolidates duplicate test scaffolding (TestServerHelper, StaticBaseServerTest, BaseGraphServerTest, WebSocketClientHelper) from the now-deleted arcadedb-test-utils module into server/src/test/java/com/arcadedb/server/. It also contains a production fix in ArcadeStateMachine.java. The motivation is clear, the execution is clean, and the core bug fix (403 failures from stale server-users.jsonl) is solid.


Positives

  • Root cause fix is correct. Adding FileUtils.deleteRecursively(new File("./target/config/")) to TestServerHelper.deleteDatabaseFolders() is exactly the right one-liner. The divergence between the two copies was the actual bug.
  • TestServerHelper utility-class idiom. Changing from abstract class to final class + private constructor is the right pattern for a class that only has static methods.
  • InterruptedException fix in WebSocketClientHelper. Restoring the interrupt flag is a correctness improvement - swallowing it silently can cause downstream blocking calls to hang.
  • try-with-resources for PrintWriter. Small but correct resource-safety improvement.
  • Structured logging over e.printStackTrace() is consistent with the rest of the codebase.
  • graphql/pom.xml correctly drops arcadedb-test-utils without a replacement since no Java code used it. Good catch.

Issues to Address

1. Docs files should not be checked in

docs/superpowers/plans/2026-05-18-test-utils-consolidation.md and docs/superpowers/specs/2026-05-18-test-utils-consolidation-design.md are AI agent execution artifacts - they document the plan for an agent to follow, not the design intent for future maintainers. This information belongs in the PR description and/or a commit message, not in the repository tree.

Recommendation: delete both files before merging.

2. grpc-client/pom.xml has a duplicate arcadedb-server dependency

The diff adds two separate arcadedb-server entries to grpc-client/pom.xml:

<!-- plain server jar - no <type> -->
<dependency>
    <artifactId>arcadedb-server</artifactId>
    <scope>test</scope>
</dependency>
<!-- test-jar -->
<dependency>
    <artifactId>arcadedb-server</artifactId>
    <scope>test</scope>
    <type>test-jar</type>
</dependency>

The PR description explains this is intentional ("the test classpath needs ArcadeDBServer at class load"), but it's worth confirming: does grpc-client not already have arcadedb-server on its compile classpath (directly or transitively)? If ArcadeDBServer is already resolvable at test compile time, the plain test-scope entry is redundant. Please verify or add a comment in the pom explaining why both are needed.

3. ArcadeStateMachine.java change is production code - needs explicit callout

This PR bundles a meaningful HA/Raft behavior change alongside the test scaffolding consolidation. The guard added to applyBootstrapFingerprintEntry skips verification when persistedAppliedIndex >= entryIndex, preventing a race during log replay on restart. This is a real production fix, not test cleanup.

Two questions:

  • Is readPersistedAppliedIndex() guaranteed to read from durable (on-disk) storage, not just in-memory state? A stale in-memory value on a fresh JVM startup would defeat the guard.
  • Has a targeted regression test been added for this scenario (node restart mid-bootstrap-fingerprint-replay)? The existing sentinel tests (RaftHTTP2ServersCreateReplicatedDatabaseIT, FollowerSessionTokenQueryIT) validate the 403 fix but not this code path directly.

Minor / Nits

  • The Javadoc on TestServerHelper still says "Static utility methods for test server lifecycle and database management" which is accurate - no change needed, just noting the new doc is good.
  • The StaticBaseServerTest wildcard-import cleanup (java.util.logging.*java.util.logging.Level) is correct per CLAUDE.md style guidance.
  • The comment on the ArcadeStateMachine change (lines beginning with // Re-application during log replay...) is unusually verbose for in-code comments but the scenario is genuinely subtle - acceptable here.

Summary

The consolidation itself is well-executed and the 403 bug fix is correct. Two action items before merge:

  1. Delete the docs/superpowers/ files.
  2. Clarify the grpc-client dual-dependency and confirm whether the plain test-scope arcadedb-server entry is actually needed.

The ArcadeStateMachine change should also be highlighted in the PR title/description since it's a production fix, not test cleanup.

@github-actions
Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 395 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL 2.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.5.32 - http://logback.qos.ch/logback-classic)
     (EPL 2.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.5.32 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.3 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.3 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@robfrank
Copy link
Copy Markdown
Collaborator Author

Pushing back on all three items - mostly verification, not implementation.

1. docs/superpowers/ files

This is established repo convention, not a one-off. main already carries 15 plan files and 12 spec files under docs/superpowers/, oldest dating to 2026-04-04 (ha-raft-test-porting.md). Removing these would break a documented practice maintained across the HA/Raft port effort.

Keeping them.

2. grpc-client/pom.xml dual arcadedb-server entries

The plain test-scope entry is required, not redundant. Reasoning:

  • grpc-client/pom.xml declares no arcadedb-server dependency in compile or provided scope (it's a client library, not part of the server assembly).
  • arcadedb-grpcw is brought in at test scope (line 131-136). Its arcadedb-server dep has provided scope. Per Maven dependency mediation, provided scope is never transitive, so grpc-client receives nothing through that path.
  • Test-jar artifact dependencies (<type>test-jar</type>) do not implicitly pull in the corresponding main jar.

Concretely, grpc-client tests import com.arcadedb.server.BaseGraphServerTest from server's test-jar; that class extends/uses ArcadeDBServer, ServerDatabase, etc. from the main server jar - those references need to be resolvable at grpc-client's test compile AND runtime. Only the plain entry provides them.

This mirrors console/pom.xml, which is the precedent for client modules (vs. wire-protocol modules that use provided + test-jar). Both entries stay.

3. ArcadeStateMachine change

Is readPersistedAppliedIndex() guaranteed to read from durable (on-disk) storage?

Yes. ArcadeStateMachine.readPersistedAppliedIndex() reads .raft/applied-index via Files.readString() on every call - no in-memory cache. The companion writePersistedAppliedIndex() writes via temp file + Files.move(..., ATOMIC_MOVE), so the on-disk value is always the most recent durable apply.

Has a targeted regression test been added?

Yes - RaftBootstrapDoesNotEngageOnRestartIT.restartDoesNotReengageBootstrap (ha-raft test). It:

  • Runs a 3-node cluster with persistentRaftStorage() == true (Raft log survives restart).
  • Waits for BOOTSTRAP_FINGERPRINT_ENTRY to commit and apply on every peer.
  • Restarts a non-leader peer, which triggers Ratis log replay and re-application of the bootstrap entry.
  • Asserts the baseline (lastTxId, fingerprint) is unchanged after replay.

This is exactly the path the new guard short-circuits. Without the guard, the re-applied entry hits the install path on the StateMachineUpdater thread, which blocks Ratis leader-info notifications and burns the snapshot-retry budget on null leader URLs (and ultimately halts via the critical-error path). The IT was failing for that reason before the guard.

Agreed the PR title undersells the production fix - I'll update it to reflect the HA change alongside the test-utils consolidation.

@robfrank robfrank changed the title docs: spec for consolidating arcadedb-test-utils into server test-jar build: consolidate arcadedb-test-utils into server test-jar + fix HA bootstrap-fingerprint replay race May 18, 2026
@github-actions
Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 395 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL 2.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.5.32 - http://logback.qos.ch/logback-classic)
     (EPL 2.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.5.32 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.3 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.3 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@claude
Copy link
Copy Markdown

claude Bot commented May 18, 2026

Code Review

Overall this is a solid refactor that pays down real technical debt. The core consolidation is well-executed and the HA race fix addresses a genuine production issue. Some notes below.


What works well

  • Root cause / bug fix: The target/config/ cleanup missing from one copy of TestServerHelper is exactly the kind of subtle divergence that silent duplication causes. Good catch, and the fix is correctly applied to the canonical copy.
  • WebSocketClientHelper interrupt flag: Restoring Thread.currentThread().interrupt() after catching InterruptedException is correct Java threading practice. The previous version swallowed the interrupt signal.
  • SnapshotInstaller lazy leader resolution: The Supplier<String> overload is an elegant solution to the bootstrap race. Resolving the leader address on every retry gives Raft election time to complete without hard sleeps. The existing String overload is preserved for backward compatibility.
  • Utility class pattern: Making TestServerHelper final with a private constructor is the right fix.
  • PrintWriter try-with-resources and replacing e.printStackTrace() with LogManager logging are both good cleanup.
  • PromQL URL encoding fix: match[]= -> match%5B%5D= is correct HTTP encoding.

Concerns

1. grpc-client/pom.xml double arcadedb-server dependency

<dependency>
    <artifactId>arcadedb-server</artifactId>
    <scope>test</scope>
    <!-- no type - pulls in production jar -->
</dependency>
<dependency>
    <artifactId>arcadedb-server</artifactId>
    <scope>test</scope>
    <type>test-jar</type>
</dependency>

The first entry (no <type>) pulls in the full production server jar on the test classpath. The project conventions in CLAUDE.md show the standard pattern as provided scope for main jar + test scope for test-jar. Having the production jar in test scope here is unconventional - it means Maven resolves two separate artifacts from the same module at test time. If ArcadeDBServer is needed directly, can the tests use the version already available via grpcw test-jar, or is there a reason the production jar itself is needed rather than the test-jar that already includes server infrastructure?

2. BackupDatabaseStatement.isIdempotent() returning true

A backup statement writes data to disk (the backup archive) and may overwrite or create new files depending on the URL. In the general case, running it twice produces a different side-effect each time (two backups, or an overwrite). Without context on where isIdempotent() is used in the planner or executor, it is hard to verify this is correct.

If isIdempotent() in ArcadeDB means "does not modify the logical database state" (i.e., read-only from the database's perspective), then true is defensible. But the semantics should be confirmed - if it controls whether the statement is replayed on follower nodes during HA replication, then true here could suppress a backup that should run everywhere, or trigger it unexpectedly.

The test added covers parsing and the return value, but does not document the intended semantics of the flag.

3. docs/superpowers/ planning artifacts committed to the repo

Two files are added:

  • docs/superpowers/plans/2026-05-18-test-utils-consolidation.md (540 lines)
  • docs/superpowers/specs/2026-05-18-test-utils-consolidation-design.md (185 lines)

These look like AI agent working documents used during development - they contain task checklists, step-by-step implementation notes, and internal planning context. They add no value to contributors reading the repository and will confuse future readers. Recommend removing them before merge.

4. PR scope mixes several independent concerns

The title covers two topics (test-utils consolidation + HA race fix), but the diff also includes:

  • BackupDatabaseStatement.isIdempotent() (engine change, unrelated)
  • LocalDate gRPC serialization fix in grpcw (unrelated)
  • RemoteDateIT hardcoded-port fix (unrelated)
  • TestLinkedPropertiesSchemaReloadIT SQL text block refactor (cosmetic)

Each of these is fine on its own, but bundling them makes the PR harder to review and bisect if a regression appears. Not a blocker, but worth noting for future PRs.


Minor notes

  • StaticBaseServerTest: switching from wildcard import java.util.logging.* to import java.util.logging.Level is correct but very minor.
  • The ArcadeStateMachine applyBootstrapFingerprintEntry change (skip re-application when readPersistedAppliedIndex() shows the entry was already applied) is a correct guard - Raft log replay on restart should be idempotent for already-applied entries.
  • RemoteTypesIT assertion that millisecond precision is preserved is a good regression guard for the LocalDateTime fix.

@github-actions
Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 395 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL 2.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.5.32 - http://logback.qos.ch/logback-classic)
     (EPL 2.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.5.32 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.3 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.3 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented May 18, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity

Metric Results
Complexity 0

View in Codacy

🟢 Coverage 70.27% diff coverage · -7.45% coverage variation

Metric Results
Coverage variation -7.45% coverage variation
Diff coverage 70.27% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (3591e93) 127254 93773 73.69%
Head commit (713e0d7) 158955 (+31701) 105289 (+11516) 66.24% (-7.45%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#4259) 37 26 70.27%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@claude
Copy link
Copy Markdown

claude Bot commented May 19, 2026

Code Review

Overview

This PR consolidates the duplicated test scaffolding (TestServerHelper, StaticBaseServerTest, BaseGraphServerTest, WebSocketClientHelper) from the arcadedb-test-utils module into server's test-jar, then deletes the now-redundant module. It also bundles several unrelated but valuable fixes: an HA bootstrap-fingerprint replay race, gRPC LocalDate serialization, static HttpClient thread-leak prevention in AI handlers, and a BackupDatabaseStatement.isIdempotent() change.


What works well

  • Root cause of the 403 failures is correctly identified. The target/config/ cleanup existed only in the test-utils copy of TestServerHelper, not the server copy - the divergence is well documented and the fix (single canonical home) is the right architecture.
  • HA bootstrap-fingerprint race fix is well reasoned. Passing a Supplier for the leader address instead of eagerly resolving it lets each retry observe the elected leader. The early-return guard (persistedApplied >= index) correctly short-circuits replays from prior sessions. Both changes have clear explanatory comments.
  • gRPC LocalDate serialization - the fix in both ArcadeDbGrpcService and GrpcTypeConverter is consistent, and RemoteTypesIT confirms millisecond precision is now preserved end-to-end.
  • Static HttpClient in AI handlers - HttpClient is thread-safe and designed to be shared per Java docs; this correctly eliminates the NIO-thread-per-instance leak seen under integration tests.
  • InterruptedException flag restoration in WebSocketClientHelper is an important correctness fix.
  • PrintWriter in try-with-resources and structured logging instead of e.printStackTrace() are both improvements.
  • All 10 downstream pom changes follow the project's wire-protocol dep convention (test-scope test-jar).

Issues and suggestions

1. grpc-client/pom.xml ends up with two arcadedb-server test entries

<!-- entry 1: main jar in test scope -->
<dependency>
    <groupId>com.arcadedb</groupId>
    <artifactId>arcadedb-server</artifactId>
    <version>${project.parent.version}</version>
    <scope>test</scope>
</dependency>
<!-- entry 2: test-jar in test scope -->
<dependency>
    <groupId>com.arcadedb</groupId>
    <artifactId>arcadedb-server</artifactId>
    <version>${project.parent.version}</version>
    <scope>test</scope>
    <type>test-jar</type>
</dependency>

The PR description explains the reason (test classpath needs ArcadeDBServer at class-load time), but a short XML comment would help future readers. Also worth confirming: other modules like bolt have arcadedb-server in provided scope (which is visible on the test classpath), so they get the main jar without an extra test-scope entry. If grpc-client genuinely has no transitive path to the main server jar at test time, both entries are necessary - confirming that closes this question.

2. BackupDatabaseStatement.isIdempotent() returning true - semantics look wrong

@Override
public boolean isIdempotent() {
  return true;
}

In ArcadeDB's SQL layer, isIdempotent() returning true typically means the statement is safe for GET/HEAD HTTP dispatch and may be treated as read-only for replication decisions. A backup writes data to storage or the network - it is not read-only. Returning true could allow the statement through GET endpoints meant only for reads, or affect HA routing.

The added test verifies the return value but does not explain why it should be true. Please clarify: if backup is intentionally considered idempotent here (e.g. re-running it safely overwrites the same target and callers should be free to retry), the reasoning belongs in a comment. If it is a mistake, false is the correct value, or the override can be dropped to inherit the base-class default.

3. Three separate static HttpClient instances in AI handlers

AiActivateHandler, AiAnalyzeProfilerHandler, and AiChatHandler each declare their own static HttpClient with identical configuration. A single shared constant in a utility class or AiConfiguration would be cleaner and marginally cheaper to initialize. Not a blocker, worth a follow-up.

4. Hardcoded local path in plan doc

docs/superpowers/plans/2026-05-18-test-utils-consolidation.md contains a reference to /Users/frank/projects/arcade/arcadedb/pom.xml - a local filesystem path from the authoring machine. A repo-relative path or just "the root pom.xml" is enough.


Test coverage

  • The sentinel IT list (17 tests across 10 modules) is comprehensive for a refactor of this scope.
  • The two original-bug sentinels (RaftHTTP2ServersCreateReplicatedDatabaseIT, FollowerSessionTokenQueryIT) are the right regression anchors.
  • The BackupDatabaseStatement test asserts the return value but not any observable downstream behavior change - see issue 2 above.

Summary

The test-utils consolidation is clean, well-motivated, and follows project conventions. The HA race fix is solid. The main items worth addressing before merge are: clarifying the isIdempotent() semantics on BackupDatabaseStatement (issue 2) and adding a comment to the dual grpc-client dep (issue 1).

robfrank added 14 commits May 19, 2026 10:20
Captures the design for collapsing the duplicate test scaffolding
(TestServerHelper, StaticBaseServerTest, BaseGraphServerTest,
WebSocketClientHelper) into a single canonical location at
server/src/test/java/com/arcadedb/server/. Downstream modules switch
to depend on arcadedb-server:test-jar:test and arcadedb-test-utils is
deleted.
Seven tasks producing six commits: three reconciliation commits (one
per helper pair that drifted), two migration commits (downstream pom
swap, then import rename), and one cleanup commit (delete test-utils
module + remove misleading server/pom test-jar override).
…Folders

RaftHTTP2ServersCreateReplicatedDatabaseIT and other Raft ITs were
failing with HTTP 403 on basic-auth login because stale
target/config/server-users.jsonl from a previous test run held a
password hash created with a different SERVER_ROOT_PASSWORD.

The matching cleanup was already in
test-utils/src/main/java/com/arcadedb/test/TestServerHelper - this
brings the server-module copy in line. The duplicate helpers will be
consolidated in a follow-up branch.
Adopt try-with-resources for PrintWriter, structured async-callback
logging, and refreshed Javadoc from the test-utils copy. Server-copy
error-body capture in initialConnection retained.
The InterruptedException catch was swallowing the interrupt status,
which can cause downstream blocking calls to hang. Mirror the
test-utils copy by re-asserting the interrupt flag.
- TestServerHelper: informative fail() message and utility-class form
  (final + private ctor)
- StaticBaseServerTest: explicit Level import instead of wildcard
Step 1 of 2 for the test-utils consolidation. Tests in these modules
will still fail to compile until imports are migrated in the next
commit.
Step 2 of 2 for the test-utils consolidation. All test classes now
import the canonical helpers from server's test-jar.
The four helpers (TestServerHelper, StaticBaseServerTest,
BaseGraphServerTest, WebSocketClientHelper) now live solely in
server's test-jar. Removes the structural duplication that caused
the recent 403 test failures (test-utils' deleteDatabaseFolders had
target/config cleanup; server's did not).

Also drops the misleading maven-jar-plugin phase=none override in
server/pom.xml -- it did not actually disable test-jar emission
and would break the test-jar consumers if it ever started working.
- grpc-client/pom.xml: arcadedb-server scope provided -> test. The
  grpc-client main code only references com.arcadedb.server.grpc.*
  classes that ship in the arcadedb-grpc protobuf module, not the
  arcadedb-server module. Test-scope is sufficient for the tests
  (RemoteGrpcServerIT etc.) that need ArcadeDBServer at class load.

- graphql/pom.xml: drop arcadedb-server:test-jar:test. The graphql
  test sources do not reference any com.arcadedb.server.* helper, so
  the dependency was dead weight. Aligns the pom with the spec's
  original intent to drop (not swap) graphql's test-utils dep.
RaftHAComprehensiveIT.test14_writesDuringSlowFollower failed because the
restarted follower's StateMachine replayed the BOOTSTRAP_FINGERPRINT_ENTRY
at index 1 and detected a mismatch (the local database had been
forward-replicated past the original baseline). The mismatch path triggered
installFromLeaderForBootstrap inside applyTransaction. Because that runs
on the StateMachineUpdater thread - the same thread that would service
Ratis leader-info notifications - the snapshot install's 4 retries all
saw a null leader HTTP address, exhausted the budget, and tripped the
critical-error halt. After the halt, every subsequent entry was refused
("State machine halted after critical error at earlier index") and the
follower could never catch up.

Fix: short-circuit applyBootstrapFingerprintEntry when the persisted
applied index is at or beyond this entry's index. In that case the
verification ran in a prior session and the local database has been
replicated forward by Ratis AppendEntries; re-running install is both
unnecessary and dangerous. Recording the baseline in bootstrapBaselines
is preserved so status export and tests still see the correct value.

The genuine initial-bootstrap path is untouched: a brand-new follower
has no persisted applied index file, readPersistedAppliedIndex() returns
-1, and the check fails so the full verification + install runs.

Verified:
- RaftHAComprehensiveIT#test14_writesDuringSlowFollower: was failing,
  now passes
- RaftHAComprehensiveIT full suite: 13/13 pass
- SnapshotInstallerRetryTest + SnapshotInstallerIntegrationIT: 6/6 pass
  (confirms genuine bootstrap-install path still works)
- PromQLHttpHandlerIT.series: percent-encode the match[] query parameter
  so Undertow accepts the request (literal [] is rejected per RFC 3986
  and the handler was never reached).
- RemoteDateIT.dateTimeMicros1: connect to the actual bound HTTP port
  via arcadeDBServer.getHttpServer().getPort() instead of hard-coding
  2480, so the test still authenticates against its own server when
  another process holds 2480.
AiActivateHandler, AiChatHandler, and AiAnalyzeProfilerHandler each held
the HttpClient as a per-instance final field built in the constructor.
The JDK HttpClient spawns a SelectorManager NIO daemon thread that lives
until the client is garbage-collected, so every ArcadeDBServer start
leaked one SelectorManager per handler (3 per server). Under the ha-raft
IT suite (reuseForks=true, 2-5 servers per test, dozens of ITs), a thread
dump showed hundreds of leaked SelectorManager threads partway through
the run, which slowed leader election enough on later tests to exceed
their 30s budget.

Make the HttpClient private static final, matching the existing pattern
in PostServerCommandHandler and PostBatchHandler. All three handlers used
identical configuration (10s connect timeout), so a single shared client
is correct.
@robfrank robfrank force-pushed the fix/failing-it-tests-2 branch from cbefa76 to 6a357fd Compare May 19, 2026 08:20
@claude
Copy link
Copy Markdown

claude Bot commented May 19, 2026

Code Review

Overview

This PR consolidates duplicate test scaffolding (TestServerHelper, StaticBaseServerTest, BaseGraphServerTest, WebSocketClientHelper) from arcadedb-test-utils into server's test-jar, deletes the old module, and fixes a Raft bootstrap-fingerprint replay race. It also bundles several other improvements: LocalDate gRPC support, static HttpClient to prevent thread leaks in AI handlers, a dynamic port fix in RemoteDateIT, and a PromQL URL encoding correction.


Positive aspects

  • Root cause fixed properly: Adding FileUtils.deleteRecursively(new File("./target/config/")) to TestServerHelper.deleteDatabaseFolders is the correct fix for the 403 failures - not a workaround, but removal of stale server-users.jsonl state between runs.
  • Interrupt flag restoration in WebSocketClientHelper.popMessage (Thread.currentThread().interrupt()) is a correctness fix.
  • PrintWriter try-with-resources in BaseGraphServerTest.checkArcadeIsTotallyDown - good catch.
  • Structured logging replacing e.printStackTrace() in the async callback matches the project's logging discipline.
  • TestServerHelper utility-class idiom (final class + private constructor) is the right pattern for a static-only helper.
  • HA supplier pattern for lazy leader address resolution is a clean design - lets each retry attempt observe the freshest Raft leadership without coupling SnapshotInstaller to the election timeline.
  • Static HttpClient in AI handlers fixes a real thread leak (one SelectorManager NIO thread per instance was surviving GC).
  • Dynamic port in RemoteDateIT (arcadeDBServer.getHttpServer().getPort()) - hardcoded 2480 was always fragile in parallel test runs.
  • Text block conversion in TestLinkedPropertiesSchemaReloadIT is a significant readability improvement.

Issues and suggestions

1. Planning/spec documents checked into source (medium)

docs/superpowers/plans/2026-05-18-test-utils-consolidation.md (540 lines) and docs/superpowers/specs/2026-05-18-test-utils-consolidation-design.md (185 lines) are AI-generated intermediate planning artifacts. These are useful context for reviewers but don't belong in the source tree long-term - they're not documentation for users or future contributors, they're ephemeral scaffolding for this change. Consider removing them before merge or keeping them only in the PR description/comments.

2. grpc-client/pom.xml - duplicate arcadedb-server declarations (low)

After the change, grpc-client/pom.xml declares arcadedb-server twice - once as a plain test dep and once as test-jar. The PR description explains why (test classpath needs ArcadeDBServer at class load via BaseGraphServerTest), but the pom itself has no comment explaining the duplication. A future maintainer removing one of the two entries would break the build. A short XML comment (<!-- needed for ArcadeDBServer at runtime, separate from the test-jar that provides BaseGraphServerTest -->) would prevent this confusion.

3. BackupDatabaseStatement.isIdempotent() returning true (medium)

This change is not mentioned in the PR title or description, and a backup is not idempotent in the strict sense - running it twice creates two backup archives. The test just asserts the value is true without explaining the intent. What query planner optimization does this enable? If isIdempotent is used to classify statements as safe for read-only transactions or for cache key purposes, a clarifying comment on the override would prevent it from being reverted as a mistake.

4. SnapshotInstaller - leaderHttpAddr == null check behavior (low)

if (leaderHttpAddr == null) {
  lastException = new IOException("Leader HTTP address not yet known (Raft election in progress)");
  ...
  continue;
}

The retry loop handles null by continuing to the next attempt, but the exponential backoff sleep that follows this null-check block is skipped because the continue jumps past it. On slow elections, all retries may exhaust immediately without real back-off. Is the sleep before the address resolution or after the download attempt? Verify the loop structure ensures back-off applies on null returns too.

5. Static HttpClient - SSL configuration concern (low)

Three AI handlers each have their own private static final HttpClient (not a single shared one). More importantly, the client is built at class-load time with connectTimeout(Duration.ofSeconds(10)) but no SSL configuration. If the server is configured with TLS (GlobalConfiguration.NETWORK_USE_SSL), these clients will connect on plain HTTP. The existing SnapshotInstaller.downloadWithRetry reads NETWORK_USE_SSL per attempt - the AI handlers should do the same, or at least the behavior should be documented.

6. PromQLHttpHandlerIT URL encoding change (low)

- "match[]=" + encode("prom_cpu") + ...
+ "match%5B%5D=" + encode("prom_cpu") + ...

No comment explains why the literal [] in the key needed percent-encoding. If Undertow or the test HTTP client was un-encoding %5B%5D to [] and the handler was expecting the encoded form, that's worth a one-line comment so the next person doesn't "fix" it back.

7. No regression test for the HA replay guard (low)

The persistedApplied >= index early-return path in applyBootstrapFingerprintEntry is the core of the race-condition fix. The PR verifies it passes RaftHTTP2ServersCreateReplicatedDatabaseIT and FollowerSessionTokenQueryIT, which is good, but a targeted unit or IT test that specifically exercises the replay-on-restart path would prevent regression without requiring a multi-node timing window to reproduce. This is a nice-to-have, not a blocker.


Minor style notes

  • StaticBaseServerTest explicit import java.util.logging.Level - correct per project style (import java.util.logging.* was the only wildcard in that file).
  • The BackupDatabaseStatementTestParserTest.isIdempotent() test uses the preferred assertThat(...).isTrue() style - good.

Summary

The consolidation is well-executed: correct fix, clean migration, good quality improvements across the helpers. The main ask before merge is to either remove the planning docs from the source tree or justify keeping them, and to clarify the BackupDatabaseStatement.isIdempotent() intent. The SnapshotInstaller back-off concern on null leader address is worth checking before merge; the other items are low-priority.

@github-actions
Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 395 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL 2.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.5.32 - http://logback.qos.ch/logback-classic)
     (EPL 2.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.5.32 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.3 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.3 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@claude
Copy link
Copy Markdown

claude Bot commented May 19, 2026

Code Review

Overview

This PR does two things: (1) consolidates duplicate test scaffolding into a single canonical home by deleting arcadedb-test-utils and routing all consumers to arcadedb-server:test-jar:test; and (2) fixes a real HA bootstrap-fingerprint replay race that caused 403 failures in RaftHTTP2ServersCreateReplicatedDatabaseIT. It also bundles several unrelated fixes (HttpClient thread leak, LocalDate gRPC encoding, dynamic port in RemoteDateIT, URL encoding in PromQLHttpHandlerIT).

The motivation is solid. The duplication was structural (Maven reactor cycle), and the 403 failures were a direct consequence of the helpers diverging between copies. Good approach.


Issues

1. grpc-client/pom.xml - duplicate arcadedb-server test dep (needs comment)

After the migration, grpc-client/pom.xml ends up with two arcadedb-server test-scope entries - one without <type>test-jar</type> (the replaced arcadedb-test-utils block) and one with it (newly added). The PR summary explains this is intentional: "test-scope arcadedb-server added because the test classpath needs ArcadeDBServer at class load via BaseGraphServerTest." Without a comment in the POM this will look like a copy-paste mistake to the next person who reads it. Please add an XML comment on the first entry explaining why both entries are needed.

2. BackupDatabaseStatement.isIdempotent() returning true - needs justification

BACKUP DATABASE writes data to disk (creates a backup file). In the REST/HTTP sense, idempotent means repeating the call has no additional observable effect - that is clearly not true here (each invocation creates or overwrites a backup artifact). If isIdempotent() in this SQL execution context means something narrower ("does not mutate primary database records"), that semantic must be documented explicitly, because the method name strongly implies the HTTP/REST meaning. Without a comment this will confuse future readers and could cause incorrect routing or retry logic. The test asserts isIdempotent() is true but provides no rationale.

3. docs/superpowers/ plan/spec files committed to main repo

The PR adds two large markdown files:

  • docs/superpowers/plans/2026-05-18-test-utils-consolidation.md (540 lines)
  • docs/superpowers/specs/2026-05-18-test-utils-consolidation-design.md (185 lines)

These are AI agent workflow documents with step-by-step task checklists, commit-message templates, and implementation instructions. They are not user-facing documentation and do not belong in the project's git history. They should be excluded from this PR. If there is a desire to keep design rationale, a brief comment in the deleted module's commit message or a short ADR is enough.

4. AI handlers - three separate static HttpClient instances (minor)

Each of AiActivateHandler, AiAnalyzeProfilerHandler, and AiChatHandler declares its own private static final HttpClient HTTP_CLIENT. Each static field creates an independent client with its own NIO thread pool - the very problem this PR is fixing in tests. Three clients instead of three-times-requests-per-run is much better, but a single shared client in an AiHttpClient utility class would be cleaner and fully prevents the same leak for any future handler classes.


Positives

  • Root cause of the 403 failures correctly identified and fixed: adding FileUtils.deleteRecursively(new File("./target/config/")) to TestServerHelper.deleteDatabaseFolders() prevents stale server-users.jsonl from carrying old password hashes across test runs.

  • HA bootstrap-fingerprint replay race fix is sound: passing the Raft log index into applyBootstrapFingerprintEntry and short-circuiting when persistedAppliedIndex >= entryIndex correctly avoids re-running the snapshot install path during log replay. The Supplier<String> overload in SnapshotInstaller is a clean solution to the leader-not-yet-elected problem on startup.

  • WebSocketClientHelper interrupt flag restored: the InterruptedException catch now calls Thread.currentThread().interrupt() - this was a genuine bug that could cause downstream blocking calls to hang.

  • TestServerHelper utility class idiom: changing from abstract class to final class with a private constructor is correct for a static utility class.

  • LocalDate gRPC encoding: properly emits timestamp_value with logical_type="date" instead of falling through to string conversion. Consistent with the existing LocalDateTime and ZonedDateTime branches in the same switch.

  • Dynamic port in RemoteDateIT: replacing hardcoded 2480 with arcadeDBServer.getHttpServer().getPort() is the right fix for port-conflict-sensitive CI environments.

  • URL encoding in PromQLHttpHandlerIT: match%5B%5D= instead of match[]= is correct - brackets must be percent-encoded in query strings per RFC 3986.

  • Text block in TestLinkedPropertiesSchemaReloadIT: converting the long string-concatenation schema script to a Java text block is a readability improvement with no behavioral change.


Summary

The consolidation approach is correct and the immediate bug fixes are well-executed. Three actionable items before merging: add a POM comment in grpc-client explaining the dual dependency, add a comment on BackupDatabaseStatement.isIdempotent() justifying the true return, and drop the docs/superpowers/ workflow files from this PR.

@robfrank robfrank merged commit 6eb94b1 into main May 19, 2026
26 of 30 checks passed
@robfrank robfrank deleted the fix/failing-it-tests-2 branch May 19, 2026 09:45
@robfrank robfrank added this to the 26.6.1 milestone May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant