Skip to content

Commit 77efb56

Browse files
authored
[ibm] Make IBM _wait_for_instance_start timeout configurable (#487)
<!-- Thank you for submitting a PR to Pycloudlib! ____ ________________________/ O \___/ <_O_O_O_O_O_O_O_O_O_O_O_O_____/ \ --> ## PR Checklist To ease the process of reviewing your PR, do make sure to complete the following checklist **before** submitting a pull request. - [X] I have added unit tests to cover the new behavior under ``tests/unit_tests/``` - [X] I have run `tox -e format` locally to automatically format my code before submitting - [X] I have run `tox` locally ensuring that it passes before submitting - [X] (if applicable) I have added a reference to issues that this PR relates to in the PR message (Refs GH-1234, Fixes GH-1234) - [X] My commits are atomic and follow the convetional commit message format (https://www.conventionalcommits.org/en/v1.0.0/) Otherwise, please leave the PR as a draft to indicate that it is still a work in progress. ## Description <!-- Describe the changes in this PR, and reference issues that this PR relates to. If referencing an issue, say "Fixes #1234" to automatically close the issue when the PR is merged. --> IBM `_wait_for_instance_start` has a hardcoded timeout value of 900s. This change keeps that as the default value but allows it to be configurable. The motivation for it came from bare metal servers which sometimes can take longer than 900s to get to "running" state. ## Additional Context and Relevant Issues <!-- Add any other context about the PR here. --> <!-- If not relevant, leave "N/A" --> N/A ## Test Steps <!-- Please provide steps to test the changes in this PR, if applicable --> <!-- If not relevant, leave "N/A" --> * Added unit tests. * The change can be manually tested by creating an instance and calling `wait` on it: ```instance.wait(start_timeout=123)```
1 parent 6131272 commit 77efb56

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1!10.13.2
1+
1!10.13.3

pycloudlib/ibm/instance.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,12 +919,12 @@ def _check_instance_failed_status(self) -> None:
919919
f"{self._instance['status_reasons'][0]['message']}"
920920
)
921921

922-
def _wait_for_instance_start(self, **kwargs):
922+
def _wait_for_instance_start(self, start_timeout=900, **kwargs):
923923
"""Wait for the cloud instance to be up."""
924924
self._log.info("Waiting for instance to finish provisioning.")
925925
self._wait_for_status(
926926
_Status.RUNNING,
927-
sleep_seconds=900,
927+
sleep_seconds=start_timeout,
928928
side_effect_fn=self._check_instance_failed_status,
929929
)
930930

tests/unit_tests/ibm/test_instance.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44
from unittest import mock
55

6-
from pycloudlib.ibm.instance import IBMInstance, _IBMInstanceType
6+
from pycloudlib.ibm.instance import IBMInstance, _IBMInstanceType, _Status
77

88
SAMPLE_RAW_INSTANCE = {
99
"id": "ibm1",
@@ -39,6 +39,7 @@ def test_type_from_raw_instance(self, client, raw_instance, inst_id, zone_id, in
3939
assert zone_id == inst.zone
4040
assert inst_type == inst._ibm_instance_type
4141

42+
4243
@mock.patch("time.sleep") # bypass the time.sleep call in _attach_floating_ip()
4344
@mock.patch(M_PATH + "VpcV1", autospec=True)
4445
def test_attach_floating_ip(self, m_sleep, client, caplog):
@@ -94,3 +95,55 @@ def test_attach_floating_ip(self, m_sleep, client, caplog):
9495

9596
assert inst._floating_ip["id"] == fi_id
9697
assert inst._floating_ip["name"] == fi_name
98+
99+
100+
@pytest.mark.parametrize(
101+
"kwargs, expected_timeout",
102+
[
103+
pytest.param({}, 900, id="default_timeout"),
104+
pytest.param({"start_timeout": 123}, 123, id="custom_timeout"),
105+
],
106+
)
107+
@mock.patch(M_PATH + "VpcV1", autospec=True)
108+
def test_wait_for_instance_start(self, m_client, kwargs, expected_timeout, caplog):
109+
"""Test _wait_for_instance_start calls _wait_for_status correctly."""
110+
inst = IBMInstance.from_raw_instance(
111+
key_pair=None,
112+
client=m_client,
113+
instance=SAMPLE_RAW_INSTANCE,
114+
)
115+
116+
with mock.patch.object(inst, "_wait_for_status") as m_wait_for_status:
117+
inst._wait_for_instance_start(**kwargs)
118+
assert "Waiting for instance to finish provisioning." in caplog.text
119+
120+
m_wait_for_status.assert_called_once_with(
121+
_Status.RUNNING,
122+
sleep_seconds=expected_timeout,
123+
side_effect_fn=inst._check_instance_failed_status,
124+
)
125+
126+
127+
@mock.patch(M_PATH + "VpcV1", autospec=True)
128+
def test_wait_passes_kwargs(self, m_client):
129+
"""Test that wait() correctly passes kwargs to internal methods."""
130+
inst = IBMInstance.from_raw_instance(
131+
key_pair=None,
132+
client=m_client,
133+
instance=SAMPLE_RAW_INSTANCE,
134+
)
135+
custom_timeout = 123
136+
137+
with mock.patch.multiple(
138+
inst,
139+
_wait_for_instance_start=mock.DEFAULT,
140+
_wait_for_execute=mock.DEFAULT,
141+
_wait_for_cloudinit=mock.DEFAULT,
142+
) as mocks:
143+
inst.wait(start_timeout=custom_timeout)
144+
145+
mocks["_wait_for_instance_start"].assert_called_once_with(
146+
start_timeout=custom_timeout
147+
)
148+
mocks["_wait_for_execute"].assert_called_once()
149+
mocks["_wait_for_cloudinit"].assert_called_once()

0 commit comments

Comments
 (0)