Skip to content

Commit 205e172

Browse files
committed
fix(netapp): unify logging format strings
Replace positional %s format strings with dictionary-based %(key)s format in all NetApp module logging calls to fix literal format string display
1 parent 8714175 commit 205e172

File tree

12 files changed

+257
-112
lines changed

12 files changed

+257
-112
lines changed

python/understack-workflows/tests/test_netapp_config.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,11 +369,14 @@ def test_config_with_extra_options(self):
369369
assert config.password == "test-password"
370370

371371
os.unlink(f.name)
372-
def test_integration_netapp_config_with_from_nautobot_response(self, config_with_nic_prefix):
373-
"""Test integration between NetAppConfig and NetappIPInterfaceConfig.from_nautobot_response."""
372+
373+
def test_integration_netapp_config_with_from_nautobot_response(
374+
self, config_with_nic_prefix
375+
):
376+
"""Test integration between NetAppConfig and NetappIPInterfaceConfig."""
374377
from unittest.mock import MagicMock
378+
375379
from understack_workflows.netapp.value_objects import NetappIPInterfaceConfig
376-
import ipaddress
377380

378381
# Create config with custom NIC prefix
379382
config = NetAppConfig(config_with_nic_prefix)
@@ -401,9 +404,11 @@ def test_integration_netapp_config_with_from_nautobot_response(self, config_with
401404
assert configs[1].base_port_name == "e5b"
402405
assert configs[0].nic_slot_prefix == "e5"
403406
assert configs[1].nic_slot_prefix == "e5"
407+
404408
def test_from_nautobot_response_default_prefix(self, valid_config_file):
405-
"""Test that from_nautobot_response uses default prefix when no config provided."""
409+
"""Test that from_nautobot_response uses default when no config provided."""
406410
from unittest.mock import MagicMock
411+
407412
from understack_workflows.netapp.value_objects import NetappIPInterfaceConfig
408413

409414
# Create a mock nautobot response
@@ -423,7 +428,9 @@ def test_from_nautobot_response_default_prefix(self, valid_config_file):
423428

424429
# Test with config that has default prefix
425430
config = NetAppConfig(valid_config_file)
426-
configs_with_config = NetappIPInterfaceConfig.from_nautobot_response(mock_response, config)
431+
configs_with_config = NetappIPInterfaceConfig.from_nautobot_response(
432+
mock_response, config
433+
)
427434
assert len(configs_with_config) == 1
428435
assert configs_with_config[0].base_port_name == "e4a"
429-
assert configs_with_config[0].nic_slot_prefix == "e4"
436+
assert configs_with_config[0].nic_slot_prefix == "e4"

python/understack-workflows/tests/test_netapp_error_handler.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ def test_log_warning_with_context(self, error_handler, mock_logger):
215215
error_handler.log_warning(message, context)
216216

217217
mock_logger.warning.assert_called_once_with(
218-
"%s - Context: %s", message, context
218+
"%(message)s - Context: %(context)s",
219+
{"message": message, "context": context},
219220
)
220221

221222
def test_log_warning_without_context(self, error_handler, mock_logger):
@@ -233,7 +234,10 @@ def test_log_info_with_context(self, error_handler, mock_logger):
233234

234235
error_handler.log_info(message, context)
235236

236-
mock_logger.info.assert_called_once_with("%s - Context: %s", message, context)
237+
mock_logger.info.assert_called_once_with(
238+
"%(message)s - Context: %(context)s",
239+
{"message": message, "context": context},
240+
)
237241

238242
def test_log_info_without_context(self, error_handler, mock_logger):
239243
"""Test logging info without context."""
@@ -250,7 +254,10 @@ def test_log_debug_with_context(self, error_handler, mock_logger):
250254

251255
error_handler.log_debug(message, context)
252256

253-
mock_logger.debug.assert_called_once_with("%s - Context: %s", message, context)
257+
mock_logger.debug.assert_called_once_with(
258+
"%(message)s - Context: %(context)s",
259+
{"message": message, "context": context},
260+
)
254261

255262
def test_log_debug_without_context(self, error_handler, mock_logger):
256263
"""Test logging debug without context."""

python/understack-workflows/tests/test_netapp_manager.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ def test_create_volume_delegates_to_service(
7474
):
7575
"""Test create_volume delegates to VolumeService with correct parameters."""
7676
manager = NetAppManager(mock_config_file)
77-
manager._volume_service.create_volume = MagicMock(return_value="vol_test-project")
77+
manager._volume_service.create_volume = MagicMock(
78+
return_value="vol_test-project"
79+
)
7880

7981
result = manager.create_volume("test-project", "1TB", "test-aggregate")
8082

@@ -126,7 +128,9 @@ def test_delete_volume_standard_name_delegates_to_service(
126128
result = manager.delete_volume("vol_test-project", force=True)
127129

128130
# Verify delegation extracts project_id correctly
129-
manager._volume_service.delete_volume.assert_called_once_with("test-project", True)
131+
manager._volume_service.delete_volume.assert_called_once_with(
132+
"test-project", True
133+
)
130134
assert result is True
131135

132136
@patch("understack_workflows.netapp.manager.config")
@@ -158,7 +162,9 @@ def test_mapped_namespaces_standard_names_delegates_to_service(
158162
result = manager.mapped_namespaces("os-test-project", "vol_test-project")
159163

160164
# Verify delegation with extracted project_id
161-
manager._volume_service.get_mapped_namespaces.assert_called_once_with("test-project")
165+
manager._volume_service.get_mapped_namespaces.assert_called_once_with(
166+
"test-project"
167+
)
162168
assert result == expected_namespaces
163169

164170
@patch("understack_workflows.netapp.manager.config")
@@ -179,7 +185,9 @@ def test_create_lif_delegates_to_service(
179185

180186
manager.create_lif("test-project", config_obj)
181187

182-
manager._lif_service.create_lif.assert_called_once_with("test-project", config_obj)
188+
manager._lif_service.create_lif.assert_called_once_with(
189+
"test-project", config_obj
190+
)
183191

184192
@patch("understack_workflows.netapp.manager.config")
185193
@patch("understack_workflows.netapp.manager.HostConnection")
@@ -205,6 +213,7 @@ def test_error_propagation_from_services(
205213

206214
# Test SVM service error propagation
207215
from understack_workflows.netapp.exceptions import SvmOperationError
216+
208217
manager._svm_service.create_svm = MagicMock(
209218
side_effect=SvmOperationError("SVM creation failed")
210219
)
@@ -214,6 +223,7 @@ def test_error_propagation_from_services(
214223

215224
# Test Volume service error propagation
216225
from understack_workflows.netapp.exceptions import VolumeOperationError
226+
217227
manager._volume_service.create_volume = MagicMock(
218228
side_effect=VolumeOperationError("Volume creation failed")
219229
)
@@ -240,7 +250,9 @@ def test_cleanup_project_orchestration(
240250
# Verify orchestration sequence
241251
manager._volume_service.exists.assert_called_once_with("test-project")
242252
manager._svm_service.exists.assert_called_once_with("test-project")
243-
manager._volume_service.delete_volume.assert_called_once_with("test-project", force=True)
253+
manager._volume_service.delete_volume.assert_called_once_with(
254+
"test-project", force=True
255+
)
244256
manager._svm_service.delete_svm.assert_called_once_with("test-project")
245257

246258
assert result == {"volume": True, "svm": True}
@@ -262,7 +274,9 @@ def test_cleanup_project_volume_failure_stops_svm_deletion(
262274
result = manager.cleanup_project("test-project")
263275

264276
# Verify SVM deletion was not attempted
265-
manager._volume_service.delete_volume.assert_called_once_with("test-project", force=True)
277+
manager._volume_service.delete_volume.assert_called_once_with(
278+
"test-project", force=True
279+
)
266280
manager._svm_service.delete_svm.assert_not_called()
267281

268282
assert result == {"volume": False, "svm": False}

python/understack-workflows/tests/test_netapp_manager_integration.py

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ def test_cleanup_project_full_success_coordination(
112112
# Verify service coordination sequence
113113
manager._volume_service.exists.assert_called_once_with(project_id)
114114
manager._svm_service.exists.assert_called_once_with(project_id)
115-
manager._volume_service.delete_volume.assert_called_once_with(project_id, force=True)
115+
manager._volume_service.delete_volume.assert_called_once_with(
116+
project_id, force=True
117+
)
116118
manager._svm_service.delete_svm.assert_called_once_with(project_id)
117119

118120
assert result == {"volume": True, "svm": True}
@@ -135,7 +137,9 @@ def test_cleanup_project_volume_failure_coordination(
135137
result = manager.cleanup_project(project_id)
136138

137139
# Verify volume service was called but SVM service was not
138-
manager._volume_service.delete_volume.assert_called_once_with(project_id, force=True)
140+
manager._volume_service.delete_volume.assert_called_once_with(
141+
project_id, force=True
142+
)
139143
manager._svm_service.delete_svm.assert_not_called()
140144

141145
assert result == {"volume": False, "svm": False}
@@ -158,7 +162,9 @@ def test_cleanup_project_partial_failure_coordination(
158162
result = manager.cleanup_project(project_id)
159163

160164
# Verify both services were called
161-
manager._volume_service.delete_volume.assert_called_once_with(project_id, force=True)
165+
manager._volume_service.delete_volume.assert_called_once_with(
166+
project_id, force=True
167+
)
162168
manager._svm_service.delete_svm.assert_called_once_with(project_id)
163169

164170
assert result == {"volume": True, "svm": False}
@@ -202,7 +208,9 @@ def test_cleanup_project_mixed_existence_scenarios(
202208

203209
result = manager.cleanup_project("test-project-1")
204210

205-
manager._volume_service.delete_volume.assert_called_once_with("test-project-1", force=True)
211+
manager._volume_service.delete_volume.assert_called_once_with(
212+
"test-project-1", force=True
213+
)
206214
manager._svm_service.delete_svm.assert_not_called()
207215
assert result == {"volume": True, "svm": True}
208216

@@ -242,7 +250,8 @@ def test_cleanup_project_exception_handling_coordination(
242250
manager._svm_service.delete_svm.assert_not_called()
243251
assert result == {"volume": False, "svm": False}
244252

245-
# Test SVM service exception after successful volume deletion (new manager instance)
253+
# Test SVM service exception after successful volume deletion (new
254+
# manager instance)
246255
manager2 = NetAppManager(mock_config_file)
247256
manager2._volume_service.exists = MagicMock(return_value=True)
248257
manager2._volume_service.delete_volume = MagicMock(return_value=True)
@@ -254,7 +263,9 @@ def test_cleanup_project_exception_handling_coordination(
254263
result = manager2.cleanup_project(project_id)
255264

256265
# Verify both services were called despite SVM failure
257-
manager2._volume_service.delete_volume.assert_called_once_with(project_id, force=True)
266+
manager2._volume_service.delete_volume.assert_called_once_with(
267+
project_id, force=True
268+
)
258269
manager2._svm_service.delete_svm.assert_called_once_with(project_id)
259270
assert result == {"volume": True, "svm": False}
260271

@@ -268,15 +279,21 @@ def test_cleanup_project_existence_check_failures(
268279
project_id = "test-project-123"
269280

270281
# Mock existence check failures
271-
manager._volume_service.exists = MagicMock(side_effect=Exception("Connection error"))
272-
manager._svm_service.exists = MagicMock(side_effect=Exception("Connection error"))
282+
manager._volume_service.exists = MagicMock(
283+
side_effect=Exception("Connection error")
284+
)
285+
manager._svm_service.exists = MagicMock(
286+
side_effect=Exception("Connection error")
287+
)
273288
manager._volume_service.delete_volume = MagicMock(return_value=True)
274289
manager._svm_service.delete_svm = MagicMock(return_value=True)
275290

276291
result = manager.cleanup_project(project_id)
277292

278293
# Verify cleanup still proceeds (assumes both exist when check fails)
279-
manager._volume_service.delete_volume.assert_called_once_with(project_id, force=True)
294+
manager._volume_service.delete_volume.assert_called_once_with(
295+
project_id, force=True
296+
)
280297
manager._svm_service.delete_svm.assert_called_once_with(project_id)
281298
assert result == {"volume": True, "svm": True}
282299

@@ -295,7 +312,9 @@ def test_end_to_end_project_lifecycle(
295312

296313
# Mock successful creation workflow
297314
manager._svm_service.create_svm = MagicMock(return_value=f"os-{project_id}")
298-
manager._volume_service.create_volume = MagicMock(return_value=f"vol_{project_id}")
315+
manager._volume_service.create_volume = MagicMock(
316+
return_value=f"vol_{project_id}"
317+
)
299318
manager._svm_service.exists = MagicMock(return_value=True)
300319
manager._volume_service.exists = MagicMock(return_value=True)
301320

@@ -316,11 +335,15 @@ def test_end_to_end_project_lifecycle(
316335
assert cleanup_result == {"volume": True, "svm": True}
317336

318337
# Verify all service interactions
319-
manager._svm_service.create_svm.assert_called_once_with(project_id, "test-aggregate")
338+
manager._svm_service.create_svm.assert_called_once_with(
339+
project_id, "test-aggregate"
340+
)
320341
manager._volume_service.create_volume.assert_called_once_with(
321342
project_id, "1TB", "test-aggregate"
322343
)
323-
manager._volume_service.delete_volume.assert_called_once_with(project_id, force=True)
344+
manager._volume_service.delete_volume.assert_called_once_with(
345+
project_id, force=True
346+
)
324347
manager._svm_service.delete_svm.assert_called_once_with(project_id)
325348

326349
@patch("understack_workflows.netapp.manager.config")
@@ -361,12 +384,17 @@ def test_logging_coordination_across_services(
361384
result = manager.cleanup_project("test-project-123")
362385

363386
# Verify appropriate log messages were called at manager level
364-
mock_logger.info.assert_any_call("Starting cleanup for project: %s", "test-project-123")
365387
mock_logger.info.assert_any_call(
366-
"Successfully deleted volume for project: %s", "test-project-123"
388+
"Starting cleanup for project: %(project_id)s",
389+
{"project_id": "test-project-123"},
390+
)
391+
mock_logger.info.assert_any_call(
392+
"Successfully deleted volume for project: %(project_id)s",
393+
{"project_id": "test-project-123"},
367394
)
368395
mock_logger.warning.assert_any_call(
369-
"Failed to delete SVM for project: %s", "test-project-123"
396+
"Failed to delete SVM for project: %(project_id)s",
397+
{"project_id": "test-project-123"},
370398
)
371399

372400
assert result == {"volume": True, "svm": False}
@@ -409,7 +437,10 @@ def test_backward_compatibility_maintained(
409437

410438
# Network operations
411439
import ipaddress
412-
from understack_workflows.netapp.value_objects import NetappIPInterfaceConfig
440+
441+
from understack_workflows.netapp.value_objects import (
442+
NetappIPInterfaceConfig,
443+
)
413444

414445
config_obj = NetappIPInterfaceConfig(
415446
name="test",

python/understack-workflows/understack_workflows/main/netapp_configure_net.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,9 @@ def netapp_create_interfaces(
352352
Exception: If SVM for the project is not found
353353
NetAppRestError: If LIF creation fails on the NetApp system
354354
"""
355-
configs = NetappIPInterfaceConfig.from_nautobot_response(nautobot_response, mgr.config)
355+
configs = NetappIPInterfaceConfig.from_nautobot_response(
356+
nautobot_response, mgr.config
357+
)
356358
for interface_config in configs:
357359
logger.info("Creating LIF %s for project %s", interface_config.name, project_id)
358360
mgr.create_lif(project_id, interface_config)

0 commit comments

Comments
 (0)