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

HyukjinKwon pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.x by this push:
     new ee18a8d41784 [SPARK-57615][CONNECT][TEST] Wait for the Connect server 
before creating a ResourceProfile in test_profile_before_sc_for_connect
ee18a8d41784 is described below

commit ee18a8d417846cd2cbd1e95ff7cc7d4255da2275
Author: Hyukjin Kwon <[email protected]>
AuthorDate: Tue Jun 23 10:33:06 2026 +0900

    [SPARK-57615][CONNECT][TEST] Wait for the Connect server before creating a 
ResourceProfile in test_profile_before_sc_for_connect
    
    ### What changes were proposed in this pull request?
    
    `test_profile_before_sc_for_connect` creates a `ResourceProfile` over Spark 
Connect immediately
    after `SparkSession.builder.remote(...).getOrCreate()`. This PR makes the 
test wait for the Connect
    server to be ready before doing so, using the existing 
`pyspark.testing.eventually` helper to retry a
    trivial job until it succeeds:
    
    ```python
    from pyspark.testing.utils import eventually
    
    def _server_ready() -> bool:
        spark.range(1).count()
        return True
    
    eventually(timeout=120, expected_exceptions=(Exception,))(_server_ready)()
    rp.id
    ```
    
    ### Why are the changes needed?
    
    The scheduled "Build / Python-only, Connect-only (Python 3.11)" build runs 
this test in its
    `Run tests (local-cluster)` step, where the server is started with
    `start-connect-server.sh --master "local-cluster[2, 4, 1024]"`. That script 
returns before the
    local-cluster `SparkContext` is fully initialized, so the first command(s) 
issued against it can
    fail server-side. `test_connect_resources` is the first test in that step, 
so it races server
    startup and fails intermittently (~60% of runs), observed as a bare 
`java.lang.AssertionError` on
    `rp.id`, or `SparkConnectGrpcException: Application error processing RPC` 
on the first job. When the
    cluster happens to be ready, the test passes (~22-77s). Waiting for 
readiness first makes it
    deterministic.
    
    This is a test-only stabilization. The underlying server behavior (an 
internal error leaking on a
    very-early command before the context is ready) is a separate, deeper 
robustness concern and is not
    addressed here.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No. Test-only change.
    
    ### How was this patch tested?
    
    Ran the scheduled workflow (`build_python_connect.yml`) on a fork. The 
Connect-only build is green
    end-to-end, including the previously-flaky `local-cluster` step, on two 
consecutive runs:
    
    - https://github.com/HyukjinKwon/spark/actions/runs/27969109059 (attempt 1 
and attempt 2: both
      `Run tests (local)` and `Run tests (local-cluster)` green)
    
    The default `build_and_test` on this branch is also green:
    https://github.com/HyukjinKwon/spark/actions/runs/27973120689
    
    Note: the Connect-only build's `Run tests (local)` step also requires the 
import fix in #56644
    (SPARK-57598); the validation runs above were performed on a branch 
carrying both changes so the
    `local-cluster` step is reached. This PR contains only the 
`test_connect_resources.py` change.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8)
    
    Closes #56676 from HyukjinKwon/ci-fix/connect-rp.
    
    Authored-by: Hyukjin Kwon <[email protected]>
    Signed-off-by: Hyukjin Kwon <[email protected]>
    (cherry picked from commit 3a5d6160f72dfddce3ab30eecf715749ea06e27f)
    Signed-off-by: Hyukjin Kwon <[email protected]>
---
 python/pyspark/resource/tests/test_connect_resources.py | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/python/pyspark/resource/tests/test_connect_resources.py 
b/python/pyspark/resource/tests/test_connect_resources.py
index 67ec3617fbcd..a80e00814504 100644
--- a/python/pyspark/resource/tests/test_connect_resources.py
+++ b/python/pyspark/resource/tests/test_connect_resources.py
@@ -17,12 +17,14 @@
 import unittest
 import os
 
+from pyspark.errors import PySparkException
 from pyspark.resource import ResourceProfileBuilder, TaskResourceRequests, 
ExecutorResourceRequests
 from pyspark.sql import SparkSession
 from pyspark.testing.connectutils import (
     should_test_connect,
     connect_requirement_message,
 )
+from pyspark.testing.utils import eventually
 
 
 @unittest.skipIf(not should_test_connect, connect_requirement_message)
@@ -46,6 +48,18 @@ class ResourceProfileTests(unittest.TestCase):
         ).getOrCreate()
         # Still can access taskResources, similar to executorResources.
         self.assertEqual(rp.taskResources["cpus"].amount, 2.0)
+
+        # SPARK-57615: the local-cluster Spark Connect server can return 
errors on the first
+        # commands right after start-connect-server.sh returns, before its 
SparkContext is fully
+        # initialized. Wait until a trivial job succeeds before creating a 
ResourceProfile, which
+        # would otherwise race that initialization and fail server-side.
+        def _server_ready() -> bool:
+            spark.range(1).count()
+            return True
+
+        # The race surfaces as a server-side PySpark error (e.g. a 
SparkConnect* exception,
+        # which subclasses PySparkException) rather than an arbitrary Python 
exception.
+        eventually(timeout=120, 
expected_exceptions=(PySparkException,))(_server_ready)()
         rp.id
         df = spark.range(10)
         df.mapInPandas(lambda x: x, df.schema, False, rp).show(n=10)


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

Reply via email to