From 6ce9079168bb104d6ea3bdfa17f56cd7a9412a95 Mon Sep 17 00:00:00 2001 From: CritasWang Date: Mon, 20 Jul 2026 12:23:34 +0800 Subject: [PATCH 1/2] ci: run e2e matrix against IoTDB 2.0.6 and 2.0.10 Parameterize the compose files with IOTDB_VERSION (defaults to 2.0.6 for local use) and add a version matrix to both e2e workflows. Artifact names carry the version suffix to avoid upload collisions. --- .github/workflows/e2e-1c1d.yml | 12 +++++++++--- .github/workflows/e2e-1c3d.yml | 12 +++++++++--- docker-compose-1c1d.yml | 4 ++-- docker-compose-1c3d.yml | 8 ++++---- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.github/workflows/e2e-1c1d.yml b/.github/workflows/e2e-1c1d.yml index 2cb20be..ee58962 100644 --- a/.github/workflows/e2e-1c1d.yml +++ b/.github/workflows/e2e-1c1d.yml @@ -8,9 +8,13 @@ on: jobs: e2e-1c1d: - name: E2E Test with 1 ConfigNode and 1 DataNode + name: E2E 1C1D (iotdb ${{ matrix.iotdb-version }}) runs-on: ubuntu-latest - + strategy: + fail-fast: false + matrix: + iotdb-version: ["2.0.6", "2.0.10"] + steps: - name: Checkout code uses: actions/checkout@v4 @@ -31,6 +35,8 @@ jobs: run: mkdir -p test-results - name: Start IoTDB with Docker Compose + env: + IOTDB_VERSION: ${{ matrix.iotdb-version }} run: | docker compose -f docker-compose-1c1d.yml up -d echo "Waiting for IoTDB to be ready..." @@ -80,5 +86,5 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: e2e-test-results-1c1d + name: e2e-test-results-1c1d-iotdb-${{ matrix.iotdb-version }} path: test-results/ diff --git a/.github/workflows/e2e-1c3d.yml b/.github/workflows/e2e-1c3d.yml index 8c336e7..2343137 100644 --- a/.github/workflows/e2e-1c3d.yml +++ b/.github/workflows/e2e-1c3d.yml @@ -8,9 +8,13 @@ on: jobs: e2e-1c3d: - name: E2E Test with 1 ConfigNode and 3 DataNodes + name: E2E 1C3D (iotdb ${{ matrix.iotdb-version }}) runs-on: ubuntu-latest - + strategy: + fail-fast: false + matrix: + iotdb-version: ["2.0.6", "2.0.10"] + steps: - name: Checkout code uses: actions/checkout@v4 @@ -31,6 +35,8 @@ jobs: run: mkdir -p test-results - name: Start IoTDB Cluster with Docker Compose + env: + IOTDB_VERSION: ${{ matrix.iotdb-version }} run: | docker compose -f docker-compose-1c3d.yml up -d echo "Waiting for IoTDB cluster to be ready..." @@ -93,5 +99,5 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: e2e-test-results-1c3d + name: e2e-test-results-1c3d-iotdb-${{ matrix.iotdb-version }} path: test-results/ diff --git a/docker-compose-1c1d.yml b/docker-compose-1c1d.yml index 4f6c49b..fa70c94 100644 --- a/docker-compose-1c1d.yml +++ b/docker-compose-1c1d.yml @@ -1,6 +1,6 @@ services: iotdb-datanode: - image: apache/iotdb:2.0.6-datanode + image: apache/iotdb:${IOTDB_VERSION:-2.0.6}-datanode container_name: iotdb-datanode restart: always depends_on: @@ -24,7 +24,7 @@ services: - CONFIGNODE_JMX_OPTS=-Xms384M -Xmx384M -XX:MaxDirectMemorySize=192M iotdb-confignode: - image: apache/iotdb:2.0.6-confignode + image: apache/iotdb:${IOTDB_VERSION:-2.0.6}-confignode container_name: iotdb-confignode restart: always healthcheck: diff --git a/docker-compose-1c3d.yml b/docker-compose-1c3d.yml index a71f76c..4669bd3 100644 --- a/docker-compose-1c3d.yml +++ b/docker-compose-1c3d.yml @@ -1,7 +1,7 @@ services: # ConfigNode (single instance for metadata management) iotdb-confignode: - image: apache/iotdb:2.0.6-confignode + image: apache/iotdb:${IOTDB_VERSION:-2.0.6}-confignode container_name: iotdb-confignode restart: always healthcheck: @@ -23,7 +23,7 @@ services: # DataNode 1 iotdb-datanode-1: - image: apache/iotdb:2.0.6-datanode + image: apache/iotdb:${IOTDB_VERSION:-2.0.6}-datanode container_name: iotdb-datanode-1 restart: always healthcheck: @@ -51,7 +51,7 @@ services: # DataNode 2 iotdb-datanode-2: - image: apache/iotdb:2.0.6-datanode + image: apache/iotdb:${IOTDB_VERSION:-2.0.6}-datanode container_name: iotdb-datanode-2 restart: always healthcheck: @@ -79,7 +79,7 @@ services: # DataNode 3 iotdb-datanode-3: - image: apache/iotdb:2.0.6-datanode + image: apache/iotdb:${IOTDB_VERSION:-2.0.6}-datanode container_name: iotdb-datanode-3 restart: always healthcheck: From 8b1e3b3b7539889ada9b974eb8ec2c2223c64569 Mon Sep 17 00:00:00 2001 From: CritasWang Date: Mon, 20 Jul 2026 12:30:54 +0800 Subject: [PATCH 2/2] test: retry row-count assertions in redirection e2e tests Rows written through redirects land on different DataNodes; with data_replication_factor=2 the last write may not be visible to an immediate query (observed once on the 2.0.10 1C3D matrix job). Poll up to 5x1s before asserting instead of querying once. --- tests/e2e/Redirection.test.ts | 53 +++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/tests/e2e/Redirection.test.ts b/tests/e2e/Redirection.test.ts index 5a4dccb..e5e8b87 100644 --- a/tests/e2e/Redirection.test.ts +++ b/tests/e2e/Redirection.test.ts @@ -35,6 +35,33 @@ describe("Redirection E2E Tests", () => { let tablePool: TableSessionPool; let isConnected = false; + // Rows written through redirects land on different DataNodes; with + // data_replication_factor=2 the last write may not be visible to an + // immediate query yet. Poll briefly instead of asserting right away. + async function countRowsWithRetry( + pool: SessionPool | TableSessionPool, + sql: string, + minRows: number, + attempts = 5, + delayMs = 1000, + ): Promise { + let rowCount = 0; + for (let attempt = 0; attempt < attempts; attempt++) { + const dataSet = await pool.executeQueryStatement(sql); + rowCount = 0; + while (await dataSet.hasNext()) { + dataSet.next(); + rowCount++; + } + await dataSet.close(); + if (rowCount >= minRows) { + return rowCount; + } + await new Promise((resolve) => setTimeout(resolve, delayMs)); + } + return rowCount; + } + beforeAll(async () => { // Skip redirection tests if not in multi-node environment if (!IS_MULTI_NODE) { @@ -175,17 +202,12 @@ describe("Redirection E2E Tests", () => { } // Verify data was written successfully by querying - const dataSet = await treePool.executeQueryStatement( - "SELECT * FROM root.test_redirect.**" + const rowCount = await countRowsWithRetry( + treePool, + "SELECT * FROM root.test_redirect.**", + 5, ); - let rowCount = 0; - while (await dataSet.hasNext()) { - dataSet.next(); - rowCount++; - } - await dataSet.close(); - // We should have at least 5 rows (one per device) expect(rowCount).toBeGreaterThanOrEqual(5); }); @@ -287,17 +309,12 @@ describe("Redirection E2E Tests", () => { } // Verify data was written successfully - const dataSet = await tablePool.executeQueryStatement( - "SELECT * FROM sensor_data" + const rowCount = await countRowsWithRetry( + tablePool, + "SELECT * FROM sensor_data", + 5, ); - let rowCount = 0; - while (await dataSet.hasNext()) { - dataSet.next(); - rowCount++; - } - await dataSet.close(); - expect(rowCount).toBeGreaterThanOrEqual(5); }); });