Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ocp_resources/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,9 @@ def __str__(self) -> str:
if self.path:
return f"Validation error at '{self.path}': {self.message}"
return f"Validation error: {self.message}"


class ConditionError(Exception):
"""Raised when a resource condition reaches an unexpected state."""

pass
16 changes: 15 additions & 1 deletion ocp_resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from ocp_resources.event import Event
from ocp_resources.exceptions import (
ClientWithBasicAuthError,
ConditionError,
MissingRequiredArgumentError,
MissingResourceResError,
ResourceTeardownError,
Expand Down Expand Up @@ -1239,6 +1240,8 @@ def wait_for_condition(
sleep_time: int = 1,
reason: str | None = None,
message: str = "",
stop_condition: str | None = None,
stop_status: str = "True",
) -> None:
"""
Wait for Resource condition to be in desire status.
Expand All @@ -1250,9 +1253,14 @@ def wait_for_condition(
message (str): Expected condition text inclusion.
timeout (int): Time to wait for the resource.
sleep_time(int): Interval between each retry when checking the resource's condition.
stop_condition (str | None): Condition which should stop the wait and fail.
Note: Matching for stop_condition only uses condition type and status.
The reason and message fields are ignored when checking for stop_condition.
stop_status (str): Status of the stop condition which should stop the wait and fail.

Raises:
TimeoutExpiredError: If Resource condition in not in desire status.
TimeoutExpiredError: If Resource condition is not in desired status within timeout.
ConditionError: If the desired condition is not met and stop_condition is detected before timeout.
"""
self.logger.info(f"Wait for {self.kind}/{self.name}'s '{condition}' condition to be '{status}'")

Expand All @@ -1266,6 +1274,12 @@ def wait_for_condition(
if sample:
for cond in sample.get("status", {}).get("conditions", []):
actual_condition = {"type": cond["type"], "status": cond["status"]}

if stop_condition and actual_condition == {"type": stop_condition, "status": stop_status}:
raise ConditionError(
f"{self.kind} {self.name} reached stop_condition '{stop_condition}' in status '{stop_status}':\n{cond}"
)

expected_condition = {"type": condition, "status": status}
if reason is not None:
actual_condition["reason"] = cond.get("reason", "")
Expand Down