Repository navigation
Conversation
wait_for_job_status did not check the requested statuses against SparkJobStatus. A misspelled value such as "Complete" (the Trainer and Optimizer spelling) or an empty set can never match a job's status, so the backend polled until timeout instead of reporting invalid input. Validate the requested statuses against set(SparkJobStatus) before polling and raise ValueError for invalid values or an empty set. This mirrors the existing checks in the Trainer and Optimizer Kubernetes backends. Correctly spelled plain strings keep working because SparkJobStatus is a str enum. Fixes kubeflow#873 Signed-off-by: Karman Singh Talwar <183269712+Karman580@users.noreply.github.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/ok-to-test |
A bare string is iterable, so set("Completed") yields individual
characters rather than one job status and fails with a misleading
message. Reject bare string inputs explicitly with a ValueError that
shows the expected set form, before the general subset validation.
Add a regression test for a bare string status and assert on the error
message for failing wait_for_job_status cases.
Signed-off-by: Karman Singh Talwar <183269712+Karman580@users.noreply.github.com>
|
Hi @tariq-hasan, @szaher ,@Shekharrajak could you please take a look at my PR #874 and review it when you get a chance |
| # An invalid or empty status can never match, so fail fast instead of polling until timeout. | ||
| valid_statuses = set(SparkJobStatus) | ||
| # A bare str is iterable, so set("Completed") would yield characters rather than a status. | ||
| if isinstance(status, str): | ||
| raise ValueError( | ||
| f"status must be a set of SparkJobStatus values, e.g. " | ||
| f"{{SparkJobStatus.COMPLETED}}; got {status!r}" | ||
| ) |
There was a problem hiding this comment.
No need for the comments. The code is self-explanatory.
| # An invalid or empty status can never match, so fail fast instead of polling until timeout. | |
| valid_statuses = set(SparkJobStatus) | |
| # A bare str is iterable, so set("Completed") would yield characters rather than a status. | |
| if isinstance(status, str): | |
| raise ValueError( | |
| f"status must be a set of SparkJobStatus values, e.g. " | |
| f"{{SparkJobStatus.COMPLETED}}; got {status!r}" | |
| ) | |
| valid_statuses = set(SparkJobStatus) | |
| if isinstance(status, str): | |
| raise ValueError( | |
| f"status must be a set of SparkJobStatus values, e.g. " | |
| f"{{SparkJobStatus.COMPLETED}}; got {status!r}" | |
| ) |
There was a problem hiding this comment.
Thanks for taking another look, @tariq-hasan! You're right, the code reads fine without them. I've removed both comments and applied your suggestion as-is in 91c5857, and the tests still pass locally.
Whenever you have a moment, I'd really appreciate another review. Thanks again for your patience and the helpful feedback!
…alidation Signed-off-by: Karman Singh Talwar <183269712+Karman580@users.noreply.github.com>
|
Hi @tariq-hasan, a quick heads-up on the failing It seems to be the controller/Helm chart mismatch described in #933 (the same failure shows up on #910), which #930 should take care of. Once that lands, I'll rebase this branch on Thanks a lot for your time! |
What this PR does / why we need it:
Problem:
SparkClient.wait_for_job_status()does not check the requestedstatusagainstSparkJobStatus. If a value can never match the job's status, the Kubernetes backend keeps polling untiltimeoutinstead of reporting invalid input. Two cases:{"Complete"}, which is the Trainer/Optimizer spelling. Spark uses"Completed".Solution:
KubernetesBackend.wait_for_job_status()now validates the requested statuses againstset(SparkJobStatus)before polling. It raisesValueErrorif the collection is empty or contains a value that is not a validSparkJobStatus.status.issubset(...)checks in the Trainer and Optimizer Kubernetes backends.set(SparkJobStatus)rather than a hard-coded list, so it stays correct if enum members are added, as fix(spark): treat Spark Operator retry states as non-terminal #690 proposes.Raises:docs in the backend, theRuntimeBackendbase interface, andSparkClientare updated to match.Compatibility:
SparkJobStatusis astrenum, so enum members and correctly spelled plain strings such as{"Completed"}behave as before.status: set[SparkJobStatus]signature and its{SparkJobStatus.COMPLETED}default are unchanged."Complete". A barestris outside theset[...]type hint.Tests (run locally on macOS):
Added cases to the parametrized
test_wait_for_job_statusinkubeflow/spark/backends/kubernetes/backend_test.py:{"Complete"}raisesValueErrorset()raisesValueError{"Completed"}(plain string) returns the jobThe existing enum case
{SparkJobStatus.COMPLETED}is unchanged and still passes.uv run pytest -q kubeflow/spark/backends/kubernetes/backend_test.py -k wait_for_job_status: 10 passed.With the backend change reverted, the two new
ValueErrorcases fail. That confirms they cover the defect.I ran the commands behind
make verifydirectly:uv lock --check,ruff check,ruff format --check kubeflow,ty check kubeflow/hub. All passed. The Makefile's GNU sed check stopsmakeitself on macOS.I ran the test command behind
make test-pythondirectly:uv run coverage run --source=kubeflow -m pytest ./kubeflow/. 700 passed.The pre-commit hooks passed on the changed files.
Note: #690 also modifies
wait_for_job_status, in the docstring and theRuntimeErrormessage. The overlap is small, and I am happy to rebase on whichever lands first.Which issue(s) this PR fixes:
Fixes #873
Checklist: