This is an automated email from the ASF dual-hosted git repository.

gaogaotiantian 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 08462255a8a4 [SPARK-59912][PYTHON][TEST] Fix flaky WorkerReuseTest and 
WorkerPoolCrashTest by pinning spark.python.use.daemon
08462255a8a4 is described below

commit 08462255a8a440667e19282327e77637020405e9
Author: Tian Gao <[email protected]>
AuthorDate: Thu Oct 1 12:02:17 2026 -0700

    [SPARK-59912][PYTHON][TEST] Fix flaky WorkerReuseTest and 
WorkerPoolCrashTest by pinning spark.python.use.daemon
    
    ### What changes were proposed in this pull request?
    
    Pin `spark.python.use.daemon=true` in `WorkerReuseTest` and 
`WorkerPoolCrashTest` (`python/pyspark/tests/test_worker.py`) by switching them 
to `ReusedPySparkTestCase` and overriding `conf()`, so they no longer rely on 
the gateway JVM's ambient default for `spark.python.use.daemon`.
    
    ### Why are the changes needed?
    
    `WorkerReuseTest.test_reuse_worker_of_parallelize_range` and 
`WorkerPoolCrashTest.test_worker_crash` assert that Python worker PIDs are 
reused across consecutive jobs. Worker reuse (and thus stable PIDs) only 
happens on the daemon path: the forked daemon child loops and serves task after 
task in the same process. The simple-worker path 
(`spark.python.use.daemon=false`) runs `python -m pyspark.worker` once per 
task, so every task gets a fresh process and a fresh PID, and the reuse asse 
[...]
    
    PySpark tests share one gateway JVM per process. The first `SparkContext` 
to launch the gateway propagates its conf into the JVM's system properties (via 
`JavaMainApplication`), and every later `SparkConf(loadDefaults=True)` inherits 
them (same mechanism as SPARK-59885). Sibling suites in this file set 
`spark.python.use.daemon=false` (`SimpleWorkerTests`, 
`WorkerSegfaultNonDaemonTest`). When one of those launches the gateway first, 
the leaked `use.daemon=false` makes the two reuse sui [...]
    
    Pinning `spark.python.use.daemon=true` on each suite's own `SparkContext` 
overrides the leaked default (the flag is read from the context's own conf via 
`SparkEnv.get.conf`), so the assertions are independent of test ordering.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Existing `WorkerReuseTest` / `WorkerPoolCrashTest`. Test-only change (a 
config pin); no new tests needed.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8)
    
    Closes #59172 from gaogaotiantian/SPARK-59912-worker-reuse-daemon.
    
    Authored-by: Tian Gao <[email protected]>
    Signed-off-by: Tian Gao <[email protected]>
---
 python/pyspark/tests/test_worker.py | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/python/pyspark/tests/test_worker.py 
b/python/pyspark/tests/test_worker.py
index 402821a75288..a7468ff0ff9e 100644
--- a/python/pyspark/tests/test_worker.py
+++ b/python/pyspark/tests/test_worker.py
@@ -31,7 +31,7 @@ except ImportError:
 from py4j.protocol import Py4JJavaError
 
 from pyspark import SparkConf, SparkContext
-from pyspark.testing.utils import PySparkTestCase, QuietTest, 
ReusedPySparkTestCase, eventually
+from pyspark.testing.utils import QuietTest, ReusedPySparkTestCase, eventually
 
 
 class WorkerTests(ReusedPySparkTestCase):
@@ -205,7 +205,19 @@ class WorkerTests(ReusedPySparkTestCase):
             self.assertRegex(str(e), "exception with δΈ­")
 
 
-class WorkerReuseTest(PySparkTestCase):
+class WorkerReuseTest(ReusedPySparkTestCase):
+    @classmethod
+    def conf(cls):
+        # Pin spark.python.use.daemon=true. Worker reuse (hence stable worker 
PIDs) only
+        # happens on the daemon path; the simple-worker path spawns a fresh 
process per
+        # task. Sibling suites here run with use.daemon=false and, because all 
suites in
+        # this file share one gateway JVM, whichever launches it first leaks 
its conf into
+        # the JVM system properties (SPARK-59885). Pinning it keeps this reuse 
assertion
+        # independent of test ordering.
+        conf = super().conf()
+        conf.set("spark.python.use.daemon", "true")
+        return conf
+
     @eventually(catch_assertions=True)
     def test_reuse_worker_of_parallelize_range(self):
         rdd = self.sc.parallelize(range(20), 8)
@@ -307,7 +319,15 @@ class WorkerSegfaultNonDaemonTest(WorkerSegfaultTest):
         return _conf
 
 
-class WorkerPoolCrashTest(PySparkTestCase):
+class WorkerPoolCrashTest(ReusedPySparkTestCase):
+    @classmethod
+    def conf(cls):
+        # Pin daemon so worker reuse (stable PIDs) is independent of test 
ordering; see
+        # WorkerReuseTest.conf for the shared-gateway leak rationale 
(SPARK-59885).
+        conf = super().conf()
+        conf.set("spark.python.use.daemon", "true")
+        return conf
+
     def test_worker_crash(self):
         # SPARK-47565: Kill a worker that is currently idling
         rdd = self.sc.parallelize(range(20), 4)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to