You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2026/10/23 23:46:36 UTC
(iotdb) 01/01: Distinguish tree and table unordered result test helpers
This is an automated email from the ASF dual-hosted git repository.
JackieTien97 pushed a commit to branch ty/unordered-result-test-helpers
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 944db97956ff466546701d15440cba0791432113
Author: JackieTien97 <ja...@gmail.com>
AuthorDate: Sat Oct 24 07:46:21 2026 +0800
Distinguish tree and table unordered result test helpers
---
integration-test/AGENTS.md | 8 +++-
.../db/it/aggregation/IoTDBTimeDurationIT.java | 4 +-
.../org/apache/iotdb/db/it/utils/TestUtils.java | 45 ++++++++++++++++++++--
.../it/query/recent/IoTDBCollectFanInIT.java | 28 +++++++++-----
4 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/integration-test/AGENTS.md b/integration-test/AGENTS.md
index 9f3df1541e3..401dbf9b779 100644
--- a/integration-test/AGENTS.md
+++ b/integration-test/AGENTS.md
@@ -71,12 +71,16 @@ These instructions apply to `integration-test/` and supplement the repository-le
### Result ordering across DataNodes
- When row order is not part of the query's contract and may differ across DataNodes, use
- `TestUtils.resultSetEqualTestUnordered(sql, expectedHeader, expectedRetArray)` for tree-model
- SQL cases. When the test already owns a result set (including table-model queries), use
+ `TestUtils.treeResultSetEqualTestUnordered(sql, expectedHeader, expectedRetArray)` for tree-model
+ SQL cases, or
+ `TestUtils.tableResultSetEqualTestUnordered(sql, expectedHeader, expectedRetArray, database)`
+ for table-model SQL cases (`database` may be `null` when no `USE` is needed).
+ When the test already owns a result set, use
`TestUtils.assertResultSetEqualUnordered(resultSet, expectedHeader, expectedRows)` and close
the original result set after the assertion. Reuse these helpers instead of writing per-node
comparison loops in individual tests.
- These helpers check every node independently, including headers, values, and duplicate counts.
+ They use `ClusterTestResultSet.getNodeResultSets` to read each DataNode's underlying result set.
The default `ClusterTestResultSet` compares nodes at the same cursor position; collecting or
sorting rows after reading through that wrapper cannot avoid row-order mismatches. Do not
replace the helpers with set equality or single-node checks that weaken these assertions.
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/IoTDBTimeDurationIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/IoTDBTimeDurationIT.java
index ce2ea3eef36..4542c4f78a6 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/IoTDBTimeDurationIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/IoTDBTimeDurationIT.java
@@ -34,7 +34,7 @@ import org.junit.runner.RunWith;
import static org.apache.iotdb.db.it.utils.TestUtils.assertTestFail;
import static org.apache.iotdb.db.it.utils.TestUtils.prepareData;
import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTest;
-import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTestUnordered;
+import static org.apache.iotdb.db.it.utils.TestUtils.treeResultSetEqualTestUnordered;
@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
@@ -346,7 +346,7 @@ public class IoTDBTimeDurationIT {
// group by tags
expectedHeader = new String[] {"city", "time_duration(s1)"};
retArray = new String[] {"Beijing,1677570933,", "Nanjing,1677570938,"};
- resultSetEqualTestUnordered(
+ treeResultSetEqualTestUnordered(
"select time_duration(s1) from root.db1.**,root.db.** group by tags(city)",
expectedHeader,
retArray);
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java b/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
index a0d768ec771..5b9482c362b 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
@@ -27,6 +27,7 @@ import org.apache.iotdb.it.env.cluster.env.AbstractEnv;
import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
import org.apache.iotdb.itbase.env.BaseEnv;
import org.apache.iotdb.itbase.runtime.ClusterTestConnection;
+import org.apache.iotdb.itbase.runtime.ClusterTestResultSet;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.StatementExecutionException;
@@ -283,10 +284,17 @@ public class TestUtils {
/**
* Executes a tree-model query and checks unordered rows on every read node, including duplicate
- * multiplicity. Use only when the query's final result does not require a particular row order or
- * select a nondeterministic subset of rows.
+ * multiplicity.
+ *
+ * <p>Delegates to {@link #assertResultSetEqualUnordered(ResultSet, String, List)}, which uses
+ * {@link ClusterTestResultSet#getNodeResultSets(ResultSet)} to obtain each DataNode's underlying
+ * result set. Iterating those results bypasses the cluster wrapper's default cross-node,
+ * row-by-row comparison.
+ *
+ * <p>Use only when the query's final result does not require a particular row order or select a
+ * nondeterministic subset of rows.
*/
- public static void resultSetEqualTestUnordered(
+ public static void treeResultSetEqualTestUnordered(
String sql, String[] expectedHeader, String[] expectedRetArray) {
try (Connection connection = EnvFactory.getEnv().getConnection();
Statement statement = connection.createStatement()) {
@@ -301,6 +309,37 @@ public class TestUtils {
}
}
+ /**
+ * Executes a table-model query and checks unordered rows on every read node, including duplicate
+ * multiplicity. Selects {@code database} before the query when it is non-null.
+ *
+ * <p>Delegates to {@link #assertResultSetEqualUnordered(ResultSet, String, List)}, which uses
+ * {@link ClusterTestResultSet#getNodeResultSets(ResultSet)} to obtain each DataNode's underlying
+ * result set. Iterating those results bypasses the cluster wrapper's default cross-node,
+ * row-by-row comparison.
+ *
+ * <p>Use only when the query's final result does not require a particular row order or select a
+ * nondeterministic subset of rows.
+ */
+ public static void tableResultSetEqualTestUnordered(
+ String sql, String[] expectedHeader, String[] expectedRetArray, String database) {
+ try (Connection connection = EnvFactory.getEnv().getTableConnection()) {
+ connection.setClientInfo("time_zone", "+00:00");
+ try (Statement statement = connection.createStatement()) {
+ if (database != null) {
+ statement.execute("use " + database);
+ }
+ try (ResultSet resultSet = statement.executeQuery(sql)) {
+ assertResultSetEqualUnordered(
+ resultSet, String.join(",", expectedHeader) + ",", Arrays.asList(expectedRetArray));
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
public static void tableResultSetEqualTest(
String sql, String[] expectedHeader, String[] expectedRetArray, String database) {
tableResultSetEqualTest(
diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBCollectFanInIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBCollectFanInIT.java
index 745ec969d18..4d38448cf4b 100644
--- a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBCollectFanInIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBCollectFanInIT.java
@@ -41,6 +41,7 @@ import java.util.List;
import java.util.Set;
import static org.apache.iotdb.db.it.utils.TestUtils.assertResultSetEqualUnordered;
+import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTestUnordered;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -101,16 +102,23 @@ public class IoTDBCollectFanInIT {
expectedRows.add(row);
}
}
- try (Connection connection = EnvFactory.getEnv().getTableConnection();
- Statement statement = connection.createStatement()) {
- statement.execute("USE " + DATABASE);
- String sql =
- "SELECT device, zone, value FROM readings1 UNION ALL "
- + "SELECT device, zone, value FROM readings1";
- try (ResultSet result = statement.executeQuery(sql)) {
- assertResultSetEqualUnordered(result, "device,zone,value,", expectedRows);
- }
- }
+ String[] expectedHeader = {"device", "zone", "value"};
+ String[] expectedRetArray = expectedRows.toArray(new String[0]);
+ tableResultSetEqualTestUnordered(
+ "SELECT device, zone, value FROM readings1 UNION ALL "
+ + "SELECT device, zone, value FROM readings1",
+ expectedHeader,
+ expectedRetArray,
+ DATABASE);
+ tableResultSetEqualTestUnordered(
+ "SELECT device, zone, value FROM "
+ + DATABASE
+ + ".readings1 UNION ALL SELECT device, zone, value FROM "
+ + DATABASE
+ + ".readings1",
+ expectedHeader,
+ expectedRetArray,
+ null);
}
@Test