from subprocess import CalledProcessError from unittest import TestCase from unittest.mock import MagicMock, patch from requests.exceptions import Timeout from requests.models import HTTPError from transip_client.adapters import IpifyAdapter, OpenDNSAdapter class IpifyAdapterTestCase(TestCase): adapter_class = IpifyAdapter def setUp(self) -> None: patcher = patch("transip_client.adapters.requests.get") self.mocked_requests_get = patcher.start() self.addCleanup(patcher.stop) def test_simple(self): self.mocked_requests_get.return_value = MagicMock(text="8.8.8.8") adapter = self.adapter_class() self.assertEqual(adapter.get_ip(), "8.8.8.8") def test_service_unavailable(self): self.mocked_requests_get.side_effect = Timeout adapter = self.adapter_class() with self.assertRaises(OSError) as exception_manager: adapter.get_ip() exception = exception_manager.exception self.assertEqual( str(exception), f"Unable to retrieve current IP from {adapter.service}" ) def test_error_response(self): request_mock = MagicMock() request_mock.raise_for_status.side_effect = HTTPError self.mocked_requests_get.return_value = request_mock adapter = self.adapter_class() with self.assertRaises(OSError) as exception_manager: adapter.get_ip() exception = exception_manager.exception self.assertEqual( str(exception), f"Unable to retrieve current IP from {adapter.service}" ) def test_no_text_content(self): self.mocked_requests_get.return_value = MagicMock(text="") adapter = self.adapter_class() with self.assertRaises(OSError) as exception_manager: adapter.get_ip() exception = exception_manager.exception self.assertEqual( str(exception), f"Unable to determine IP from response from {adapter.service}", ) class OpenDNSAdapterTestCase(TestCase): def setUp(self) -> None: patcher = patch("transip_client.adapters.subprocess.check_output") self.mocked_check_output = patcher.start() self.addCleanup(patcher.stop) def test_simple(self): self.mocked_check_output.return_value = "8.8.8.8\n" adapter = OpenDNSAdapter() self.assertEqual(adapter.get_ip(), "8.8.8.8") def test_retry_next_resolvers(self): self.mocked_check_output.side_effect = ( CalledProcessError(9, "dig +short myip.opendns.com @resolver1.opendns.com"), CalledProcessError(9, "dig +short myip.opendns.com @resolver2.opendns.com"), CalledProcessError(9, "dig +short myip.opendns.com @resolver3.opendns.com"), "9.9.9.9\n", ) adapter = OpenDNSAdapter() self.assertEqual(adapter.get_ip(), "9.9.9.9") def test_resolvers_exhausted(self): self.mocked_check_output.side_effect = ( CalledProcessError(9, "dig +short myip.opendns.com @resolver1.opendns.com"), CalledProcessError(9, "dig +short myip.opendns.com @resolver2.opendns.com"), CalledProcessError(9, "dig +short myip.opendns.com @resolver3.opendns.com"), CalledProcessError(9, "dig +short myip.opendns.com @resolver4.opendns.com"), ) adapter = OpenDNSAdapter() with self.assertRaises(OSError) as exception_manager: adapter.get_ip() self.assertEqual( str(exception_manager.exception), "Exhausted all known IP resolvers, unable to retrieve IP", ) def test_command_error(self): self.mocked_check_output.side_effect = ( CalledProcessError(1, "dig +short myip.opendns.com @resolver1.opendns.com"), ) adapter = OpenDNSAdapter() with self.assertRaises(OSError) as exception_manager: adapter.get_ip() self.assertEqual( str(exception_manager.exception), "Unable to retrieve current IP" )