|
5 | 5 | from unittest.mock import patch |
6 | 6 |
|
7 | 7 | import pytest |
| 8 | +import requests |
8 | 9 |
|
9 | 10 | from understack_workflows.oslo_event.nautobot_device_sync import EXIT_STATUS_FAILURE |
10 | 11 | from understack_workflows.oslo_event.nautobot_device_sync import EXIT_STATUS_SUCCESS |
|
15 | 16 | ) |
16 | 17 | from understack_workflows.oslo_event.nautobot_device_sync import _generate_device_name |
17 | 18 | from understack_workflows.oslo_event.nautobot_device_sync import _get_record_value |
| 19 | +from understack_workflows.oslo_event.nautobot_device_sync import _is_retryable_error |
18 | 20 | from understack_workflows.oslo_event.nautobot_device_sync import _normalise_manufacturer |
19 | 21 | from understack_workflows.oslo_event.nautobot_device_sync import ( |
20 | 22 | _populate_from_inventory, |
@@ -807,3 +809,85 @@ def test_handle_delete_event_success(self, mock_delete, mock_conn, mock_nautobot |
807 | 809 |
|
808 | 810 | assert result == EXIT_STATUS_SUCCESS |
809 | 811 | mock_delete.assert_called_once_with(node_uuid, mock_nautobot) |
| 812 | + |
| 813 | + |
| 814 | +class TestIsRetryableError: |
| 815 | + """Test cases for _is_retryable_error function.""" |
| 816 | + |
| 817 | + def test_connection_error_is_retryable(self): |
| 818 | + exc = requests.exceptions.ConnectionError("Connection refused") |
| 819 | + assert _is_retryable_error(exc) is True |
| 820 | + |
| 821 | + def test_503_service_unavailable_is_retryable(self): |
| 822 | + from pynautobot import RequestError |
| 823 | + |
| 824 | + mock_response = MagicMock() |
| 825 | + mock_response.status_code = 503 |
| 826 | + mock_response.reason = "Service Unavailable" |
| 827 | + mock_response.json.return_value = {"detail": "Service temporarily unavailable"} |
| 828 | + mock_response.request.body = None |
| 829 | + mock_response.url = "http://nautobot/api/dcim/devices/" |
| 830 | + mock_response.text = "Service Unavailable" |
| 831 | + |
| 832 | + exc = RequestError(mock_response) |
| 833 | + assert _is_retryable_error(exc) is True |
| 834 | + |
| 835 | + def test_502_bad_gateway_is_retryable(self): |
| 836 | + from pynautobot import RequestError |
| 837 | + |
| 838 | + mock_response = MagicMock() |
| 839 | + mock_response.status_code = 502 |
| 840 | + mock_response.reason = "Bad Gateway" |
| 841 | + mock_response.json.return_value = {} |
| 842 | + mock_response.request.body = None |
| 843 | + mock_response.url = "http://nautobot/api/dcim/devices/" |
| 844 | + mock_response.text = "Bad Gateway" |
| 845 | + |
| 846 | + exc = RequestError(mock_response) |
| 847 | + assert _is_retryable_error(exc) is True |
| 848 | + |
| 849 | + def test_504_gateway_timeout_is_retryable(self): |
| 850 | + from pynautobot import RequestError |
| 851 | + |
| 852 | + mock_response = MagicMock() |
| 853 | + mock_response.status_code = 504 |
| 854 | + mock_response.reason = "Gateway Timeout" |
| 855 | + mock_response.json.return_value = {} |
| 856 | + mock_response.request.body = None |
| 857 | + mock_response.url = "http://nautobot/api/dcim/devices/" |
| 858 | + mock_response.text = "Gateway Timeout" |
| 859 | + |
| 860 | + exc = RequestError(mock_response) |
| 861 | + assert _is_retryable_error(exc) is True |
| 862 | + |
| 863 | + def test_400_bad_request_is_not_retryable(self): |
| 864 | + from pynautobot import RequestError |
| 865 | + |
| 866 | + mock_response = MagicMock() |
| 867 | + mock_response.status_code = 400 |
| 868 | + mock_response.reason = "Bad Request" |
| 869 | + mock_response.json.return_value = {"device_type": ["Not found"]} |
| 870 | + mock_response.request.body = None |
| 871 | + mock_response.url = "http://nautobot/api/dcim/devices/" |
| 872 | + mock_response.text = "Bad Request" |
| 873 | + |
| 874 | + exc = RequestError(mock_response) |
| 875 | + assert _is_retryable_error(exc) is False |
| 876 | + |
| 877 | + def test_404_not_found_is_not_retryable(self): |
| 878 | + from pynautobot import RequestError |
| 879 | + |
| 880 | + mock_response = MagicMock() |
| 881 | + mock_response.status_code = 404 |
| 882 | + mock_response.reason = "Not Found" |
| 883 | + mock_response.json.return_value = {} |
| 884 | + mock_response.request.body = None |
| 885 | + mock_response.url = "http://nautobot/api/dcim/devices/123/" |
| 886 | + mock_response.text = "Not Found" |
| 887 | + |
| 888 | + exc = RequestError(mock_response) |
| 889 | + assert _is_retryable_error(exc) is False |
| 890 | + |
| 891 | + def test_value_error_is_not_retryable(self): |
| 892 | + exc = ValueError("Invalid value") |
| 893 | + assert _is_retryable_error(exc) is False |
0 commit comments