Skip to content

Commit b7e256b

Browse files
fix(workflows): Update workflows to handle dynamic and multiple netapp driver configs
1 parent ed4a8e6 commit b7e256b

13 files changed

Lines changed: 612 additions & 289 deletions

‎python/understack-workflows/tests/test_cinder_volume_type.py‎

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,25 @@ def test_wrong_event_type(self, mock_conn, mock_nautobot):
7272
result = handle_volume_type_access_added(mock_conn, mock_nautobot, event_data)
7373
assert result == 1
7474

75+
@patch(
76+
"understack_workflows.oslo_event.cinder_volume_type.NetAppConfig.get_all_backends"
77+
)
7578
@patch("understack_workflows.oslo_event.cinder_volume_type.NetAppManager")
7679
@patch("builtins.open")
7780
def test_svm_does_not_exist_returns_1(
78-
self, mock_open, mock_netapp_class, mock_conn, mock_nautobot, valid_event_data
81+
self,
82+
mock_open,
83+
mock_netapp_class,
84+
mock_get_all_backends,
85+
mock_conn,
86+
mock_nautobot,
87+
valid_event_data,
7988
):
8089
"""If SVM doesn't exist, skip volume creation and return 1."""
8190
mock_conn.block_storage.get_type.return_value = MagicMock(extra_specs={})
91+
mock_backend = MagicMock()
92+
mock_backend.section = "backend1"
93+
mock_get_all_backends.return_value = [mock_backend]
8294
mock_netapp_manager = MagicMock()
8395
mock_netapp_manager.check_if_svm_exists.return_value = False
8496
mock_netapp_class.return_value = mock_netapp_manager
@@ -93,13 +105,25 @@ def test_svm_does_not_exist_returns_1(
93105
)
94106
mock_netapp_manager.create_volume.assert_not_called()
95107

108+
@patch(
109+
"understack_workflows.oslo_event.cinder_volume_type.NetAppConfig.get_all_backends"
110+
)
96111
@patch("understack_workflows.oslo_event.cinder_volume_type.NetAppManager")
97112
@patch("builtins.open")
98113
def test_successful_volume_creation(
99-
self, mock_open, mock_netapp_class, mock_conn, mock_nautobot, valid_event_data
114+
self,
115+
mock_open,
116+
mock_netapp_class,
117+
mock_get_all_backends,
118+
mock_conn,
119+
mock_nautobot,
120+
valid_event_data,
100121
):
101122
"""Volume created with the dynamically selected aggregate and default size."""
102123
mock_conn.block_storage.get_type.return_value = MagicMock(extra_specs={})
124+
mock_backend = MagicMock()
125+
mock_backend.section = "backend1"
126+
mock_get_all_backends.return_value = [mock_backend]
103127
mock_netapp_manager = MagicMock()
104128
mock_netapp_manager.check_if_svm_exists.return_value = True
105129
mock_netapp_manager.select_aggregate_name.return_value = "aggr-selected"
@@ -118,10 +142,19 @@ def test_successful_volume_creation(
118142
aggregate_name="aggr-selected",
119143
)
120144

145+
@patch(
146+
"understack_workflows.oslo_event.cinder_volume_type.NetAppConfig.get_all_backends"
147+
)
121148
@patch("understack_workflows.oslo_event.cinder_volume_type.NetAppManager")
122149
@patch("builtins.open")
123150
def test_extra_specs_used_for_aggregate_and_size(
124-
self, mock_open, mock_netapp_class, mock_conn, mock_nautobot, valid_event_data
151+
self,
152+
mock_open,
153+
mock_netapp_class,
154+
mock_get_all_backends,
155+
mock_conn,
156+
mock_nautobot,
157+
valid_event_data,
125158
):
126159
"""aggregate_name and volume_size from extra_specs override defaults."""
127160
mock_conn.block_storage.get_type.return_value = MagicMock(
@@ -130,6 +163,9 @@ def test_extra_specs_used_for_aggregate_and_size(
130163
"netapp:flexvol_size": "1TB",
131164
}
132165
)
166+
mock_backend = MagicMock()
167+
mock_backend.section = "backend1"
168+
mock_get_all_backends.return_value = [mock_backend]
133169
mock_netapp_manager = MagicMock()
134170
mock_netapp_manager.check_if_svm_exists.return_value = True
135171
mock_netapp_class.return_value = mock_netapp_manager
@@ -147,13 +183,25 @@ def test_extra_specs_used_for_aggregate_and_size(
147183
aggregate_name="aggr_custom",
148184
)
149185

186+
@patch(
187+
"understack_workflows.oslo_event.cinder_volume_type.NetAppConfig.get_all_backends"
188+
)
150189
@patch("understack_workflows.oslo_event.cinder_volume_type.NetAppManager")
151190
@patch("builtins.open")
152191
def test_aggregate_selection_failure_propagates(
153-
self, mock_open, mock_netapp_class, mock_conn, mock_nautobot, valid_event_data
192+
self,
193+
mock_open,
194+
mock_netapp_class,
195+
mock_get_all_backends,
196+
mock_conn,
197+
mock_nautobot,
198+
valid_event_data,
154199
):
155200
"""If no aggregate can be selected, volume creation is not attempted."""
156201
mock_conn.block_storage.get_type.return_value = MagicMock(extra_specs={})
202+
mock_backend = MagicMock()
203+
mock_backend.section = "backend1"
204+
mock_get_all_backends.return_value = [mock_backend]
157205
mock_netapp_manager = MagicMock()
158206
mock_netapp_manager.check_if_svm_exists.return_value = True
159207
mock_netapp_manager.select_aggregate_name.side_effect = Exception(
@@ -198,14 +246,27 @@ def test_wrong_event_type(self, mock_conn, mock_nautobot):
198246
result = handle_volume_type_access_removed(mock_conn, mock_nautobot, event_data)
199247
assert result == 1
200248

249+
@patch(
250+
"understack_workflows.oslo_event.cinder_volume_type.NetAppConfig.get_all_backends"
251+
)
201252
@patch("understack_workflows.oslo_event.cinder_volume_type.NetAppManager")
202253
@patch("builtins.open")
203254
def test_successful_volume_deletion(
204-
self, mock_open, mock_netapp_class, mock_conn, mock_nautobot, valid_event_data
255+
self,
256+
mock_open,
257+
mock_netapp_class,
258+
mock_get_all_backends,
259+
mock_conn,
260+
mock_nautobot,
261+
valid_event_data,
205262
):
206263
"""Volume deleted and returns 0 on success."""
207264
expected_volume_name = f"vol_{VOLUME_TYPE_ID.replace('-', '')}"
265+
mock_backend = MagicMock()
266+
mock_backend.section = "backend1"
267+
mock_get_all_backends.return_value = [mock_backend]
208268
mock_netapp_manager = MagicMock()
269+
mock_netapp_manager.check_if_svm_exists.return_value = True
209270
mock_netapp_manager.get_volume_name.return_value = expected_volume_name
210271
mock_netapp_manager.delete_volume.return_value = True
211272
mock_netapp_class.return_value = mock_netapp_manager
@@ -220,13 +281,26 @@ def test_successful_volume_deletion(
220281
expected_volume_name, force=False
221282
)
222283

284+
@patch(
285+
"understack_workflows.oslo_event.cinder_volume_type.NetAppConfig.get_all_backends"
286+
)
223287
@patch("understack_workflows.oslo_event.cinder_volume_type.NetAppManager")
224288
@patch("builtins.open")
225289
def test_deletion_returns_false_returns_1(
226-
self, mock_open, mock_netapp_class, mock_conn, mock_nautobot, valid_event_data
290+
self,
291+
mock_open,
292+
mock_netapp_class,
293+
mock_get_all_backends,
294+
mock_conn,
295+
mock_nautobot,
296+
valid_event_data,
227297
):
228298
"""Returns 1 when delete_volume returns False."""
299+
mock_backend = MagicMock()
300+
mock_backend.section = "backend1"
301+
mock_get_all_backends.return_value = [mock_backend]
229302
mock_netapp_manager = MagicMock()
303+
mock_netapp_manager.check_if_svm_exists.return_value = True
230304
mock_netapp_manager.delete_volume.return_value = False
231305
mock_netapp_class.return_value = mock_netapp_manager
232306

@@ -236,13 +310,26 @@ def test_deletion_returns_false_returns_1(
236310

237311
assert result == 1
238312

313+
@patch(
314+
"understack_workflows.oslo_event.cinder_volume_type.NetAppConfig.get_all_backends"
315+
)
239316
@patch("understack_workflows.oslo_event.cinder_volume_type.NetAppManager")
240317
@patch("builtins.open")
241318
def test_deletion_failure_returns_1(
242-
self, mock_open, mock_netapp_class, mock_conn, mock_nautobot, valid_event_data
319+
self,
320+
mock_open,
321+
mock_netapp_class,
322+
mock_get_all_backends,
323+
mock_conn,
324+
mock_nautobot,
325+
valid_event_data,
243326
):
244327
"""Returns 1 when delete_volume raises an exception."""
328+
mock_backend = MagicMock()
329+
mock_backend.section = "backend1"
330+
mock_get_all_backends.return_value = [mock_backend]
245331
mock_netapp_manager = MagicMock()
332+
mock_netapp_manager.check_if_svm_exists.return_value = True
246333
mock_netapp_manager.delete_volume.side_effect = Exception("Delete failed")
247334
mock_netapp_class.return_value = mock_netapp_manager
248335

‎python/understack-workflows/tests/test_keystone_project.py‎

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,17 @@ def test_project_tags_empty_tags(self):
9696
class TestHandleProjectCreated:
9797
"""Test cases for handle_project_created function."""
9898

99+
@pytest.fixture(autouse=True)
100+
def _mock_get_all_backends(self):
101+
"""Auto-mock get_all_backends for all create tests."""
102+
mock_backend = MagicMock()
103+
mock_backend.section = "backend1"
104+
with patch(
105+
"understack_workflows.oslo_event.keystone_project.NetAppConfig.get_all_backends",
106+
return_value=[mock_backend],
107+
):
108+
yield
109+
99110
@pytest.fixture
100111
def mock_conn(self):
101112
"""Create a mock OpenStack connection."""
@@ -352,6 +363,17 @@ def test_handle_project_created_json_tags_output(
352363
class TestHandleProjectUpdated:
353364
"""Test cases for handle_project_updated function."""
354365

366+
@pytest.fixture(autouse=True)
367+
def _mock_get_all_backends(self):
368+
"""Auto-mock get_all_backends for all update tests."""
369+
mock_backend = MagicMock()
370+
mock_backend.section = "backend1"
371+
with patch(
372+
"understack_workflows.oslo_event.keystone_project.NetAppConfig.get_all_backends",
373+
return_value=[mock_backend],
374+
):
375+
yield
376+
355377
@pytest.fixture
356378
def mock_conn(self):
357379
"""Create a mock OpenStack connection."""
@@ -737,8 +759,12 @@ def test_handle_project_deleted_wrong_event_type(self, mock_conn, mock_nautobot)
737759

738760
@patch("builtins.open", new_callable=mock.mock_open)
739761
@patch("understack_workflows.oslo_event.keystone_project.NetAppManager")
762+
@patch(
763+
"understack_workflows.oslo_event.keystone_project.NetAppConfig.get_all_backends"
764+
)
740765
def test_handle_project_deleted_svm_exists(
741766
self,
767+
mock_get_all_backends,
742768
mock_netapp_class,
743769
mock_open,
744770
mock_conn,
@@ -747,6 +773,9 @@ def test_handle_project_deleted_svm_exists(
747773
):
748774
"""Test project deletion when SVM exists."""
749775
mock_file = mock_open.return_value
776+
mock_backend = MagicMock()
777+
mock_backend.section = "backend1"
778+
mock_get_all_backends.return_value = [mock_backend]
750779
mock_netapp_manager = MagicMock()
751780
mock_netapp_manager.check_if_svm_exists.return_value = True
752781
mock_netapp_class.return_value = mock_netapp_manager
@@ -756,6 +785,7 @@ def test_handle_project_deleted_svm_exists(
756785
)
757786

758787
assert result == 0
788+
mock_netapp_class.assert_called_once_with(netapp_config=mock_backend)
759789
mock_netapp_manager.check_if_svm_exists.assert_called_once_with(
760790
project_id="test-project-123"
761791
)
@@ -765,8 +795,12 @@ def test_handle_project_deleted_svm_exists(
765795

766796
@patch("builtins.open", new_callable=mock.mock_open)
767797
@patch("understack_workflows.oslo_event.keystone_project.NetAppManager")
798+
@patch(
799+
"understack_workflows.oslo_event.keystone_project.NetAppConfig.get_all_backends"
800+
)
768801
def test_handle_project_deleted_svm_does_not_exist(
769802
self,
803+
mock_get_all_backends,
770804
mock_netapp_class,
771805
mock_open,
772806
mock_conn,
@@ -775,6 +809,9 @@ def test_handle_project_deleted_svm_does_not_exist(
775809
):
776810
"""Test project deletion when SVM does not exist."""
777811
mock_file = mock_open.return_value
812+
mock_backend = MagicMock()
813+
mock_backend.section = "backend1"
814+
mock_get_all_backends.return_value = [mock_backend]
778815
mock_netapp_manager = MagicMock()
779816
mock_netapp_manager.check_if_svm_exists.return_value = False
780817
mock_netapp_class.return_value = mock_netapp_manager
@@ -793,8 +830,12 @@ def test_handle_project_deleted_svm_does_not_exist(
793830

794831
@patch("builtins.open", new_callable=mock.mock_open)
795832
@patch("understack_workflows.oslo_event.keystone_project.NetAppManager")
833+
@patch(
834+
"understack_workflows.oslo_event.keystone_project.NetAppConfig.get_all_backends"
835+
)
796836
def test_handle_project_deleted_netapp_manager_failure(
797837
self,
838+
mock_get_all_backends,
798839
mock_netapp_class,
799840
mock_open,
800841
mock_conn,
@@ -803,21 +844,28 @@ def test_handle_project_deleted_netapp_manager_failure(
803844
):
804845
"""Test handling when NetAppManager creation fails during deletion."""
805846
mock_file = mock_open.return_value
847+
mock_backend = MagicMock()
848+
mock_backend.section = "backend1"
849+
mock_get_all_backends.return_value = [mock_backend]
806850
mock_netapp_class.side_effect = Exception("NetApp connection failed")
807851

808852
result = handle_project_deleted(
809853
mock_conn, mock_nautobot, valid_delete_event_data
810854
)
811855

812856
assert result == 1 # Should return 1 on exception
813-
mock_netapp_class.assert_called_once()
857+
mock_netapp_class.assert_called_once_with(netapp_config=mock_backend)
814858
mock_open.assert_any_call("/var/run/argo/output.svm_state", "w")
815859
mock_file.write.assert_any_call("unknown")
816860

817861
@patch("builtins.open", new_callable=mock.mock_open)
818862
@patch("understack_workflows.oslo_event.keystone_project.NetAppManager")
863+
@patch(
864+
"understack_workflows.oslo_event.keystone_project.NetAppConfig.get_all_backends"
865+
)
819866
def test_handle_project_deleted_cleanup_failure(
820867
self,
868+
mock_get_all_backends,
821869
mock_netapp_class,
822870
mock_open,
823871
mock_conn,
@@ -826,6 +874,9 @@ def test_handle_project_deleted_cleanup_failure(
826874
):
827875
"""Test handling when cleanup_project fails during deletion."""
828876
mock_file = mock_open.return_value
877+
mock_backend = MagicMock()
878+
mock_backend.section = "backend1"
879+
mock_get_all_backends.return_value = [mock_backend]
829880
mock_netapp_manager = MagicMock()
830881
mock_netapp_manager.check_if_svm_exists.return_value = True
831882
mock_netapp_manager.cleanup_project.side_effect = Exception("Cleanup failed")

0 commit comments

Comments
 (0)