diff --git a/CLAUDE.md b/CLAUDE.md index 33015b568d96..5ef345696db0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -51,56 +51,16 @@ mvn clean package -pl distribution -am -DskipTests -P with-zh-locale # Format code (requires JDK 17+; auto-skipped on JDK <17) mvn spotless:apply -# Format code in integration-test module -mvn spotless:apply -P with-integration-tests - # Check formatting without applying mvn spotless:check ``` ## Integration Tests -Integration tests live in `integration-test/` (not included in default build). They require the `with-integration-tests` profile: - -```bash -# Build template-node first (needed once, or after code changes) -mvn clean package -DskipTests -pl integration-test -am -P with-integration-tests - -# Run tree-model ITs (simple: 1 ConfigNode + 1 DataNode) -mvn clean verify -DskipUTs -pl integration-test -am -P with-integration-tests - -# Run tree-model ITs (cluster: 1 ConfigNode + 3 DataNodes) -mvn clean verify -DskipUTs -pl integration-test -am -PClusterIT -P with-integration-tests - -# Run table-model ITs (simple) -mvn clean verify -DskipUTs -pl integration-test -am -PTableSimpleIT -P with-integration-tests - -# Run table-model ITs (cluster) -mvn clean verify -DskipUTs -pl integration-test -am -PTableClusterIT -P with-integration-tests - -# Run a single IT class (tree-model simple, 1C1D) -mvn clean verify -DskipUTs -Dit.test=ClassName -DfailIfNoTests=false -Dfailsafe.failIfNoSpecifiedTests=false -pl integration-test -am -P with-integration-tests - -# Run a single IT class (tree-model cluster, 1C3D) -mvn clean verify -DskipUTs -Dit.test=ClassName -DfailIfNoTests=false -Dfailsafe.failIfNoSpecifiedTests=false -pl integration-test -am -PClusterIT -P with-integration-tests - -# Run a single IT class (table-model simple, 1C1D) -mvn clean verify -DskipUTs -Dit.test=ClassName -DfailIfNoTests=false -Dfailsafe.failIfNoSpecifiedTests=false -pl integration-test -am -PTableSimpleIT -P with-integration-tests - -# Run a single IT class (table-model cluster, 1C3D) -mvn clean verify -DskipUTs -Dit.test=ClassName -DfailIfNoTests=false -Dfailsafe.failIfNoSpecifiedTests=false -pl integration-test -am -PTableClusterIT -P with-integration-tests - -# Run a single test method within an IT class (use ClassName#methodName) -mvn clean verify -DskipUTs -Dit.test=ClassName#methodName -DfailIfNoTests=false -Dfailsafe.failIfNoSpecifiedTests=false -pl integration-test -am -PTableSimpleIT -P with-integration-tests - -# Build the Edge distribution and run its dedicated Tree/Table read-write IT -mvn clean package -DskipTests -pl distribution -am -mvn verify -DskipUTs -Dit.test=IoTDBEdgeBasicIT -DfailIfNoTests=false -Dfailsafe.failIfNoSpecifiedTests=false -pl integration-test -am -P EdgeIT -P with-integration-tests -``` - -When verifying a new feature, only run the specific IT classes/methods that were added or modified in the current branch — do not run all ITs. - -To run integration tests from IntelliJ: enable the `with-integration-tests` profile in Maven sidebar, then run test cases directly. +Before editing or running integration tests, read and follow +[integration-test/AGENTS.md](integration-test/AGENTS.md). It contains the IT authoring rules, +formatting and build commands, test profiles, targeted verification, and Edge/IDE instructions. +Keep IT-specific rules and commands in that module-level file. ## Code Style @@ -202,7 +162,7 @@ The project uses compile-time i18n via the `build-helper-maven-plugin`. The prop ### Code Style -- **Always run `mvn spotless:apply` after editing Java files**: Spotless runs `spotless:check` automatically during the `compile` phase. Format violations cause an immediate BUILD FAILURE. Make it a habit to run `mvn spotless:apply -pl ` right after editing, not at the end. For files under `integration-test/`, add `-P with-integration-tests`. +- **Always run `mvn spotless:apply` after editing Java files**: Spotless runs `spotless:check` automatically during the `compile` phase. Format violations cause an immediate BUILD FAILURE. Make it a habit to run `mvn spotless:apply -pl ` right after editing, not at the end. - **Always run `black` and `isort` after editing Python files under `iotdb-core/ainode/`**: The AINode Code Style Check CI runs `black --check .` and `isort --check-only --profile black .` on that directory. Run `cd iotdb-core/ainode && black . && isort --profile black .` before committing. Requires `pip install black==25.1.0 isort==6.0.1`. - **Gson version compatibility**: `JsonObject.isEmpty()` / `JsonArray.isEmpty()` may not be available in the Gson version used by this project. Use `size() > 0` instead and add a comment explaining why. diff --git a/integration-test/AGENTS.md b/integration-test/AGENTS.md new file mode 100644 index 000000000000..15690a76477b --- /dev/null +++ b/integration-test/AGENTS.md @@ -0,0 +1,127 @@ + + +# Integration Test Guidelines + +These instructions apply to `integration-test/` and supplement the repository-level instructions. + +## Credentials and deployment defaults + +- Use `EnvFactory.getEnv()` connection helpers or client builders with their default credentials + when a test does not need a specific user. +- When constructing clients or helpers that require explicit default credentials, use + `SessionConfig.DEFAULT_USER` and `SessionConfig.DEFAULT_PASSWORD`. This includes + `NodesSupplier`, pools, and direct RPC helpers; do not hardcode `"root"` as the default password. + Default credentials can differ between IoTDB and downstream editions. +- Keep a client's business connections and discovery/recovery helpers on the same credentials. + Check helper methods as well as the main test body: a builder may use the correct defaults + while a manually constructed discovery client silently uses different ones. +- Explicit credentials are appropriate for users created by the test and for authentication or + invalid-password scenarios. Make that intent clear, and clean up users created by the test. +- Obtain node addresses and allocated ports from the test environment or node wrappers. Configure + required consensus protocols, replication factors, and other non-default settings before + initializing the cluster. + +## Asynchronous behavior and failure recovery + +- Use bounded condition waits, such as Awaitility or environment status helpers, for startup, + discovery, leader election, and recovery. Prefer observable conditions over fixed sleeps. +- Wait for each relevant layer separately. A node status reported by ConfigNode does not prove + that an existing client has refreshed its endpoint snapshot or recovered its connection. +- For locally stopped nodes, use `EnvUtils.getNodeStatusAfterLocalStop()` where applicable; + graceful process termination behaves differently on Unix and Windows. Use the appropriate + status expectation for forced termination. +- Keep connection/socket timeouts distinct from query timeouts and the overall assertion deadline. + Allow for startup and election costs on CI; use deliberately short timeouts only when needed by + the scenario. Do not retry non-idempotent setup statements just to hide a short timeout. +- For tests that require a stale discovery snapshot or a particular failover order, control + background refresh and assert the preconditions before triggering recovery. +- Investigate authentication, configuration, and transport failures before increasing a wait + timeout. A retained client snapshot can mean that discovery never succeeded. Include useful + endpoint/status context and preserve underlying failures when adding diagnostics. +- Do not label a failure as environmental or intermittent based only on one failed run. + +## Isolation and assertions + +- Follow the neighboring tests' runner, category, and environment lifecycle conventions. Select + the category matching the data model and topology required by the scenario. +- Close sessions, pools, and result sets; shut down test-owned executors and clean the cluster + even when assertions fail. Use try-with-resources and `finally` as appropriate. +- Assert the behavior under test and its recovery result. Only tolerate expected cleanup errors + in narrowly scoped cleanup code; do not swallow failures from the operation being verified. + +## Verification + +This module is excluded from the default build. Run the commands below from the repository root, +always enabling `-P with-integration-tests` when building or testing this module. + +Format Java changes with `mvn spotless:apply -pl integration-test -P with-integration-tests`. + +### Targeted test runs + +Run only the affected IT classes or methods for a focused change. Select the matching test profile: + +| Data model | Default topology | Test profile | +| --- | --- | --- | +| Tree | 1 ConfigNode + 1 DataNode | `SimpleIT` (default) | +| Tree | 1 ConfigNode + 3 DataNodes | `ClusterIT` | +| Table | 1 ConfigNode + 1 DataNode | `TableSimpleIT` | +| Table | 1 ConfigNode + 3 DataNodes | `TableClusterIT` | + +For example, run one tree-model cluster test method: + +```bash +mvn clean verify -DskipUTs \ + '-Dit.test=ClassName#methodName' \ + -DfailIfNoTests=false -Dfailsafe.failIfNoSpecifiedTests=false \ + -pl integration-test -am -PClusterIT -P with-integration-tests +``` + +Use `-Dit.test=ClassName` to run a whole class. Replace `-PClusterIT` with the profile needed by the +test; it may be omitted for the default `SimpleIT` profile. + +- Check the Failsafe report to confirm that the selected test actually ran; the no-tests flags + allow upstream reactor modules to have no matching tests. +- Report the tested revision, edition, profile, and result accurately. Passing an upstream build + does not establish that the corresponding downstream edition was tested. + +### Node templates and IDE runs + +Build the node templates before an IDE run or a direct Failsafe invocation, and rebuild them after +code changes: + +```bash +mvn clean package -DskipTests -pl integration-test -am -P with-integration-tests +``` + +The `clean verify` command above already includes this packaging step. In IntelliJ, enable the +`with-integration-tests` profile in the Maven sidebar before running test cases directly. + +### Edge tests + +Build the Edge distribution before running its dedicated Tree/Table read-write IT: + +```bash +mvn clean package -DskipTests -pl distribution -am +mvn verify -DskipUTs -Dit.test=IoTDBEdgeBasicIT \ + -DfailIfNoTests=false -Dfailsafe.failIfNoSpecifiedTests=false \ + -pl integration-test -am -P EdgeIT -P with-integration-tests +``` diff --git a/integration-test/src/test/java/org/apache/iotdb/session/it/SessionSeedNodeFallbackIT.java b/integration-test/src/test/java/org/apache/iotdb/session/it/SessionSeedNodeFallbackIT.java index a13fc8183b91..ceed96c3eb89 100644 --- a/integration-test/src/test/java/org/apache/iotdb/session/it/SessionSeedNodeFallbackIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/session/it/SessionSeedNodeFallbackIT.java @@ -196,8 +196,8 @@ private NodesSupplier createSupplier(ScheduledThreadPoolExecutor executor) { return NodesSupplier.createNodeSupplier( seeds, executor, - "root", - "root", + SessionConfig.DEFAULT_USER, + SessionConfig.DEFAULT_PASSWORD, ZoneId.of("UTC"), SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY, SessionConfig.DEFAULT_MAX_FRAME_SIZE,