Skip to content

Commit e38dff7

Browse files
committed
Fix tests
1 parent b1b42a6 commit e38dff7

3 files changed

Lines changed: 77 additions & 44 deletions

File tree

test/src/mock/test_mas_mock.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030

3131
@pytest.fixture(autouse=True)
32-
@mock.patch("openshift.dynamic.DynamicClient")
32+
@mock.patch("kubernetes.dynamic.DynamicClient")
3333
def dynamic_client(client):
3434
return client
3535

test/src/test_olm_installplan_selection.py

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,21 @@ def test_automatic_approval_uses_label_selector_only(
111111
mock_subscription.status.state = "AtLatestKnown"
112112
mock_subscription.status.installedCSV = "test-operator.v1.0.0"
113113

114-
# First call returns empty list (no existing subscription), subsequent calls return the subscription
115-
sub_api.get.side_effect = [
116-
MockResourceList([]), # Initial check for existing subscription
117-
mock_subscription, # Subsequent calls when waiting for subscription to complete
118-
]
114+
# Mock to return empty list first, then the subscription for all subsequent calls
115+
def sub_get_side_effect(*args, **kwargs):
116+
if "label_selector" in kwargs:
117+
# First call with label_selector returns empty list
118+
if not hasattr(sub_get_side_effect, "called"):
119+
sub_get_side_effect.called = True
120+
return MockResourceList([])
121+
# Subsequent calls return the subscription
122+
return MockResourceList([mock_subscription])
123+
elif "name" in kwargs:
124+
# Direct get by name returns the subscription
125+
return mock_subscription
126+
return MockResourceList([])
127+
128+
sub_api.get.side_effect = sub_get_side_effect
119129
sub_api.apply.return_value = Mock()
120130

121131
# Mock InstallPlan API - label selector returns one InstallPlan
@@ -183,11 +193,18 @@ def test_manual_approval_without_starting_csv_uses_label_selector_only(
183193
mock_subscription.status.state = "UpgradePending"
184194
mock_subscription.status.installedCSV = "test-operator.v1.0.0"
185195

186-
# First call returns empty list (no existing subscription), subsequent calls return the subscription
187-
sub_api.get.side_effect = [
188-
MockResourceList([]), # Initial check for existing subscription
189-
mock_subscription, # Subsequent calls when waiting for subscription to complete
190-
]
196+
# Mock to return empty list first, then the subscription for all subsequent calls
197+
def sub_get_side_effect(*args, **kwargs):
198+
if "label_selector" in kwargs:
199+
if not hasattr(sub_get_side_effect, "called"):
200+
sub_get_side_effect.called = True
201+
return MockResourceList([])
202+
return MockResourceList([mock_subscription])
203+
elif "name" in kwargs:
204+
return mock_subscription
205+
return MockResourceList([])
206+
207+
sub_api.get.side_effect = sub_get_side_effect
191208
sub_api.apply.return_value = Mock()
192209

193210
# Mock InstallPlan API
@@ -270,11 +287,18 @@ def test_manual_approval_with_starting_csv_label_selector_finds_match(
270287
mock_subscription.status.state = "UpgradePending"
271288
mock_subscription.status.installedCSV = "test-operator.v1.0.0"
272289

273-
# First call returns empty list (no existing subscription), subsequent calls return the subscription
274-
sub_api.get.side_effect = [
275-
MockResourceList([]), # Initial check for existing subscription
276-
mock_subscription, # Subsequent calls when waiting for subscription to complete
277-
]
290+
# Mock to return empty list first, then the subscription for all subsequent calls
291+
def sub_get_side_effect(*args, **kwargs):
292+
if "label_selector" in kwargs:
293+
if not hasattr(sub_get_side_effect, "called"):
294+
sub_get_side_effect.called = True
295+
return MockResourceList([])
296+
return MockResourceList([mock_subscription])
297+
elif "name" in kwargs:
298+
return mock_subscription
299+
return MockResourceList([])
300+
301+
sub_api.get.side_effect = sub_get_side_effect
278302
sub_api.apply.return_value = Mock()
279303

280304
# Mock InstallPlan API - label selector returns matching InstallPlan
@@ -357,11 +381,18 @@ def test_manual_approval_with_starting_csv_fallback_to_ownership_search(
357381
mock_subscription.status.state = "UpgradePending"
358382
mock_subscription.status.installedCSV = "test-operator.v1.0.0"
359383

360-
# First call returns empty list (no existing subscription), subsequent calls return the subscription
361-
sub_api.get.side_effect = [
362-
MockResourceList([]), # Initial check for existing subscription
363-
mock_subscription, # Subsequent calls when waiting for subscription to complete
364-
]
384+
# Mock to return empty list first, then the subscription for all subsequent calls
385+
def sub_get_side_effect(*args, **kwargs):
386+
if "label_selector" in kwargs:
387+
if not hasattr(sub_get_side_effect, "called"):
388+
sub_get_side_effect.called = True
389+
return MockResourceList([])
390+
return MockResourceList([mock_subscription])
391+
elif "name" in kwargs:
392+
return mock_subscription
393+
return MockResourceList([])
394+
395+
sub_api.get.side_effect = sub_get_side_effect
365396
sub_api.apply.return_value = Mock()
366397

367398
# Mock InstallPlan API
@@ -464,11 +495,18 @@ def test_manual_approval_filters_by_subscription_ownership(
464495
mock_subscription.status.state = "UpgradePending"
465496
mock_subscription.status.installedCSV = "test-operator.v1.0.0"
466497

467-
# First call returns empty list (no existing subscription), subsequent calls return the subscription
468-
sub_api.get.side_effect = [
469-
MockResourceList([]), # Initial check for existing subscription
470-
mock_subscription, # Subsequent calls when waiting for subscription to complete
471-
]
498+
# Mock to return empty list first, then the subscription for all subsequent calls
499+
def sub_get_side_effect(*args, **kwargs):
500+
if "label_selector" in kwargs:
501+
if not hasattr(sub_get_side_effect, "called"):
502+
sub_get_side_effect.called = True
503+
return MockResourceList([])
504+
return MockResourceList([mock_subscription])
505+
elif "name" in kwargs:
506+
return mock_subscription
507+
return MockResourceList([])
508+
509+
sub_api.get.side_effect = sub_get_side_effect
472510
sub_api.apply.return_value = Mock()
473511

474512
# Mock InstallPlan API

test/src/test_tekton_update.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
class TestUpdateTektonDefinitions:
2020
"""Test suite for tekton.updateTektonDefinitions() function."""
2121

22+
@patch("mas.devops.tekton.applyResource")
2223
@patch("mas.devops.tekton.path.isfile")
2324
@patch("builtins.open", new_callable=mock_open)
2425
@patch("mas.devops.tekton.yaml.safe_load_all")
25-
def test_update_tekton_definitions_success(self, mock_yaml_load, mock_file, mock_isfile):
26+
def test_update_tekton_definitions_success(self, mock_yaml_load, mock_file, mock_isfile, mock_apply):
2627
"""Test successful application of Tekton resources."""
2728
# Setup
2829
mock_isfile.return_value = True
@@ -53,16 +54,7 @@ def test_update_tekton_definitions_success(self, mock_yaml_load, mock_file, mock
5354
)
5455

5556
# Verify
56-
assert mock_resource_api.apply.call_count == 2
57-
mock_resource_api.apply.assert_any_call(
58-
body={
59-
"apiVersion": "tekton.dev/v1beta1",
60-
"kind": "Task",
61-
"metadata": {"name": "test-task", "namespace": "test-namespace"},
62-
"spec": {},
63-
},
64-
namespace="test-namespace",
65-
)
57+
assert mock_apply.call_count == 2
6658

6759
@patch("mas.devops.tekton.path.isfile")
6860
def test_update_tekton_definitions_file_not_found(self, mock_isfile):
@@ -99,10 +91,11 @@ def test_update_tekton_definitions_invalid_yaml(self, mock_yaml_load, mock_file,
9991
yamlFile="/path/to/invalid.yaml",
10092
)
10193

94+
@patch("mas.devops.tekton.applyResource")
10295
@patch("mas.devops.tekton.path.isfile")
10396
@patch("builtins.open", new_callable=mock_open)
10497
@patch("mas.devops.tekton.yaml.safe_load_all")
105-
def test_update_tekton_definitions_multiple_resources(self, mock_yaml_load, mock_file, mock_isfile):
98+
def test_update_tekton_definitions_multiple_resources(self, mock_yaml_load, mock_file, mock_isfile, mock_apply):
10699
"""Test successful application of multiple resources in single file."""
107100
# Setup
108101
mock_isfile.return_value = True
@@ -139,13 +132,14 @@ def test_update_tekton_definitions_multiple_resources(self, mock_yaml_load, mock
139132
)
140133

141134
# Verify
142-
assert mock_resource_api.apply.call_count == 3
135+
assert mock_apply.call_count == 3
143136

137+
@patch("mas.devops.tekton.applyResource")
144138
@patch("mas.devops.tekton.path.isfile")
145139
@patch("builtins.open", new_callable=mock_open)
146140
@patch("mas.devops.tekton.yaml.safe_load_all")
147141
@patch("mas.devops.tekton.sleep")
148-
def test_update_tekton_definitions_retry_on_transient_error(self, mock_sleep, mock_yaml_load, mock_file, mock_isfile):
142+
def test_update_tekton_definitions_retry_on_transient_error(self, mock_sleep, mock_yaml_load, mock_file, mock_isfile, mock_apply):
149143
"""Test retry logic on transient API errors."""
150144
# Setup
151145
mock_isfile.return_value = True
@@ -163,7 +157,7 @@ def test_update_tekton_definitions_retry_on_transient_error(self, mock_sleep, mo
163157
mock_dyn_client.resources.get.return_value = mock_resource_api
164158

165159
# First call fails with 503, second succeeds
166-
mock_resource_api.apply.side_effect = [
160+
mock_apply.side_effect = [
167161
ApiException(status=503, reason="Service Unavailable"),
168162
None,
169163
]
@@ -176,13 +170,14 @@ def test_update_tekton_definitions_retry_on_transient_error(self, mock_sleep, mo
176170
)
177171

178172
# Verify retry occurred
179-
assert mock_resource_api.apply.call_count == 2
173+
assert mock_apply.call_count == 2
180174
mock_sleep.assert_called_once()
181175

176+
@patch("mas.devops.tekton.applyResource")
182177
@patch("mas.devops.tekton.path.isfile")
183178
@patch("builtins.open", new_callable=mock_open)
184179
@patch("mas.devops.tekton.yaml.safe_load_all")
185-
def test_update_tekton_definitions_api_exception(self, mock_yaml_load, mock_file, mock_isfile):
180+
def test_update_tekton_definitions_api_exception(self, mock_yaml_load, mock_file, mock_isfile, mock_apply):
186181
"""Test ApiException on non-retryable error."""
187182
# Setup
188183
mock_isfile.return_value = True
@@ -200,7 +195,7 @@ def test_update_tekton_definitions_api_exception(self, mock_yaml_load, mock_file
200195
mock_dyn_client.resources.get.return_value = mock_resource_api
201196

202197
# Non-retryable error (e.g., 400 Bad Request)
203-
mock_resource_api.apply.side_effect = ApiException(status=400, reason="Bad Request")
198+
mock_apply.side_effect = ApiException(status=400, reason="Bad Request")
204199

205200
# Execute and verify
206201
with pytest.raises(ApiException) as exc_info:

0 commit comments

Comments
 (0)