You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by ru...@apache.org on 2026/04/24 03:52:44 UTC
(spark) branch master updated: [SPARK-56595][SQL][TESTS] Move non-anyfun helpers from QueryTest to QueryTestBase
This is an automated email from the ASF dual-hosted git repository.
zhengruifeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new cefd6cab8ae5 [SPARK-56595][SQL][TESTS] Move non-anyfun helpers from QueryTest to QueryTestBase
cefd6cab8ae5 is described below
commit cefd6cab8ae57a580e68a87a6ff427a049b72d16
Author: Ruifeng Zheng <ru...@apache.org>
AuthorDate: Fri Apr 24 11:52:31 2026 +0800
[SPARK-56595][SQL][TESTS] Move non-anyfun helpers from QueryTest to QueryTestBase
### What changes were proposed in this pull request?
Move seven members from `trait QueryTest` down to `trait QueryTestBase`. None of them depend on `AnyFunSuite.test(...)`, so they fit in `QueryTestBase` (self-type `Suite`) without changing the self-type:
- `private var loadTestDataBeforeTests`
- `override def beforeAll()`
- `setupTestData()`
- `waitForTasksToFinish()`
- `withTempPaths(numPaths)(f)`
- `getCurrentClassCallSitePattern`
- `getNextLineCallSitePattern(lines)`
All dependencies (`spark` from `SQLTestData`, `eventually`/`timeout` from `Eventually`, `super.beforeAll()` via `BeforeAndAfterAll`, `loadTestData` from `SQLTestData`) are already parents of `QueryTestBase`, so this is a pure relocation — the `super.beforeAll()` chain resolves the same way at the concrete-class level.
### Why are the changes needed?
Making these helpers available to `QueryTestBase` allows tests that mix in `QueryTestBase` directly (without the `AnyFunSuite` overhead, e.g., non-FunSuite test styles) to reuse them. No functional change today; this lowers the bar for downstream test-style flexibility.
### Does this PR introduce _any_ user-facing change?
No, test-only.
### How was this patch tested?
Locally compiled `sql/Test/compile`. Ran `SortSuite` (255 tests) — all pass. No call-site churn; every existing caller still reaches these through `QueryTest` via inheritance.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 4.7
Closes #55509 from zhengruifeng/move-querytest-methods-to-querytestbase.
Authored-by: Ruifeng Zheng <ru...@apache.org>
Signed-off-by: Ruifeng Zheng <ru...@foxmail.com>
---
.../scala/org/apache/spark/sql/QueryTest.scala | 111 +++++++++++----------
1 file changed, 56 insertions(+), 55 deletions(-)
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/QueryTest.scala b/sql/core/src/test/scala/org/apache/spark/sql/QueryTest.scala
index 33160da53d3a..47ac9ea810a7 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/QueryTest.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/QueryTest.scala
@@ -624,6 +624,62 @@ trait QueryTestBase
}
}
+ // Whether to materialize all test data before the first test is run
+ private var loadTestDataBeforeTests = false
+
+ protected override def beforeAll(): Unit = {
+ super.beforeAll()
+ if (loadTestDataBeforeTests) {
+ loadTestData()
+ }
+ }
+
+ /**
+ * Materialize the test data immediately after the `SQLContext` is set up.
+ * This is necessary if the data is accessed by name but not through direct reference.
+ */
+ protected def setupTestData(): Unit = {
+ loadTestDataBeforeTests = true
+ }
+
+ /**
+ * Waits for all tasks on all executors to be finished.
+ */
+ protected def waitForTasksToFinish(): Unit = {
+ eventually(timeout(10.seconds)) {
+ assert(spark.sparkContext.statusTracker
+ .getExecutorInfos.map(_.numRunningTasks()).sum == 0)
+ }
+ }
+
+ /**
+ * Creates the specified number of temporary directories, which is then passed to `f` and will be
+ * deleted after `f` returns.
+ */
+ protected def withTempPaths(numPaths: Int)(f: Seq[File] => Unit): Unit = {
+ val files = Array.fill[File](numPaths)(Utils.createTempDir().getCanonicalFile)
+ try f(files.toImmutableArraySeq) finally {
+ // wait for all tasks to finish before deleting files
+ waitForTasksToFinish()
+ files.foreach(Utils.deleteRecursively)
+ }
+ }
+
+ protected def getCurrentClassCallSitePattern: String = {
+ val stack = Thread.currentThread().getStackTrace()
+ val idx = stack.lastIndexWhere(_.getMethodName == "getCurrentClassCallSitePattern")
+ val cs = stack(idx + 1)
+ s"${cs.getClassName}\\..*\\(${cs.getFileName}:\\d+\\)"
+ }
+
+ protected def getNextLineCallSitePattern(lines: Int = 1): String = {
+ val stack = Thread.currentThread().getStackTrace()
+ val idx = stack.lastIndexWhere(_.getMethodName == "getNextLineCallSitePattern")
+ val cs = stack(idx + 1)
+ Pattern.quote(
+ s"${cs.getClassName}.${cs.getMethodName}(${cs.getFileName}:${cs.getLineNumber + lines})")
+ }
+
}
/**
@@ -637,15 +693,6 @@ trait QueryTestBase
* prone to leaving multiple overlapping [[org.apache.spark.SparkContext]]s in the same JVM.
*/
trait QueryTest extends SparkFunSuite with QueryTestBase with PlanTest {
- // Whether to materialize all test data before the first test is run
- private var loadTestDataBeforeTests = false
-
- protected override def beforeAll(): Unit = {
- super.beforeAll()
- if (loadTestDataBeforeTests) {
- loadTestData()
- }
- }
/**
* Creates a temporary directory, which is then passed to `f` and will be deleted after `f`
@@ -672,14 +719,6 @@ trait QueryTest extends SparkFunSuite with QueryTestBase with PlanTest {
}
}
- /**
- * Materialize the test data immediately after the `SQLContext` is set up.
- * This is necessary if the data is accessed by name but not through direct reference.
- */
- protected def setupTestData(): Unit = {
- loadTestDataBeforeTests = true
- }
-
/**
* Disable stdout and stderr when running the test. To not output the logs to the console,
* ConsoleAppender's `follow` should be set to `true` so that it will honor reassignments of
@@ -760,44 +799,6 @@ trait QueryTest extends SparkFunSuite with QueryTestBase with PlanTest {
f(tmpFile)
}
}
-
- /**
- * Waits for all tasks on all executors to be finished.
- */
- protected def waitForTasksToFinish(): Unit = {
- eventually(timeout(10.seconds)) {
- assert(spark.sparkContext.statusTracker
- .getExecutorInfos.map(_.numRunningTasks()).sum == 0)
- }
- }
-
- /**
- * Creates the specified number of temporary directories, which is then passed to `f` and will be
- * deleted after `f` returns.
- */
- protected def withTempPaths(numPaths: Int)(f: Seq[File] => Unit): Unit = {
- val files = Array.fill[File](numPaths)(Utils.createTempDir().getCanonicalFile)
- try f(files.toImmutableArraySeq) finally {
- // wait for all tasks to finish before deleting files
- waitForTasksToFinish()
- files.foreach(Utils.deleteRecursively)
- }
- }
-
- protected def getCurrentClassCallSitePattern: String = {
- val stack = Thread.currentThread().getStackTrace()
- val idx = stack.lastIndexWhere(_.getMethodName == "getCurrentClassCallSitePattern")
- val cs = stack(idx + 1)
- s"${cs.getClassName}\\..*\\(${cs.getFileName}:\\d+\\)"
- }
-
- protected def getNextLineCallSitePattern(lines: Int = 1): String = {
- val stack = Thread.currentThread().getStackTrace()
- val idx = stack.lastIndexWhere(_.getMethodName == "getNextLineCallSitePattern")
- val cs = stack(idx + 1)
- Pattern.quote(
- s"${cs.getClassName}.${cs.getMethodName}(${cs.getFileName}:${cs.getLineNumber + lines})")
- }
}
object QueryTest extends Assertions {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org