Skip to content

Commit 69f7c19

Browse files
authored
feat(core): extract url checker and support multiple api endpoints (#5)
1 parent 6e26983 commit 69f7c19

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

kc-compat.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,26 @@ def is_distro_supported(distro_name):
8989
return distro_name in SUPPORTED_DISTROS
9090

9191

92-
def is_compat():
93-
url = 'http://patches.kernelcare.com/' + get_kernel_hash() + '/version'
92+
def _check_url(url):
9493
try:
9594
urlopen(url)
9695
return True
9796
except HTTPError as e:
9897
if e.code == 404:
9998
return False
100-
else:
101-
raise
99+
raise
102100
except URLError:
103101
raise
104102

105103

104+
def is_compat():
105+
base = 'http://patches.kernelcare.com/' + get_kernel_hash()
106+
for endpoint in ('/version', '/latest.v2', '/latest.v3'):
107+
if _check_url(base + endpoint):
108+
return True
109+
return False
110+
111+
106112
def myprint(silent, message):
107113
if not silent:
108114
print(message)

test_kc_compat.py

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,69 @@ def test_is_distro_supported(self):
8585
assert kc_compat.is_distro_supported('debian') == False
8686

8787

88+
class TestCheckUrl:
89+
@patch.object(kc_compat, 'urlopen')
90+
def test_check_url_success(self, mock_urlopen):
91+
mock_urlopen.return_value = MagicMock()
92+
assert kc_compat._check_url('http://example.com') == True
93+
94+
@patch.object(kc_compat, 'urlopen')
95+
def test_check_url_404(self, mock_urlopen):
96+
mock_urlopen.side_effect = HTTPError(None, 404, 'Not Found', None, None)
97+
assert kc_compat._check_url('http://example.com') == False
98+
99+
@patch.object(kc_compat, 'urlopen')
100+
def test_check_url_500_raises(self, mock_urlopen):
101+
mock_urlopen.side_effect = HTTPError(None, 500, 'Server Error', None, None)
102+
with pytest.raises(HTTPError):
103+
kc_compat._check_url('http://example.com')
104+
105+
@patch.object(kc_compat, 'urlopen')
106+
def test_check_url_url_error_raises(self, mock_urlopen):
107+
mock_urlopen.side_effect = URLError('Connection refused')
108+
with pytest.raises(URLError):
109+
kc_compat._check_url('http://example.com')
110+
111+
88112
class TestIsCompat:
113+
BASE = 'http://patches.kernelcare.com/abcdef123456'
114+
89115
@patch.object(kc_compat, 'get_kernel_hash', return_value='abcdef123456')
90116
@patch.object(kc_compat, 'urlopen')
91-
def test_is_compat_success(self, mock_urlopen, mock_hash):
117+
def test_is_compat_version_hit(self, mock_urlopen, mock_hash):
92118
mock_urlopen.return_value = MagicMock()
93119
assert kc_compat.is_compat() == True
94-
mock_urlopen.assert_called_once_with('http://patches.kernelcare.com/abcdef123456/version')
120+
mock_urlopen.assert_called_once_with(self.BASE + '/version')
121+
122+
@patch.object(kc_compat, 'get_kernel_hash', return_value='abcdef123456')
123+
@patch.object(kc_compat, 'urlopen')
124+
def test_is_compat_fallback_to_v2(self, mock_urlopen, mock_hash):
125+
mock_urlopen.side_effect = [
126+
HTTPError(None, 404, 'Not Found', None, None),
127+
MagicMock(),
128+
]
129+
assert kc_compat.is_compat() == True
130+
assert mock_urlopen.call_count == 2
131+
mock_urlopen.assert_called_with(self.BASE + '/latest.v2')
132+
133+
@patch.object(kc_compat, 'get_kernel_hash', return_value='abcdef123456')
134+
@patch.object(kc_compat, 'urlopen')
135+
def test_is_compat_fallback_to_v3(self, mock_urlopen, mock_hash):
136+
mock_urlopen.side_effect = [
137+
HTTPError(None, 404, 'Not Found', None, None),
138+
HTTPError(None, 404, 'Not Found', None, None),
139+
MagicMock(),
140+
]
141+
assert kc_compat.is_compat() == True
142+
assert mock_urlopen.call_count == 3
143+
mock_urlopen.assert_called_with(self.BASE + '/latest.v3')
95144

96145
@patch.object(kc_compat, 'get_kernel_hash', return_value='abcdef123456')
97146
@patch.object(kc_compat, 'urlopen')
98-
def test_is_compat_404_error_returns_false(self, mock_urlopen, mock_hash):
147+
def test_is_compat_all_404_returns_false(self, mock_urlopen, mock_hash):
99148
mock_urlopen.side_effect = HTTPError(None, 404, 'Not Found', None, None)
100149
assert kc_compat.is_compat() == False
150+
assert mock_urlopen.call_count == 3
101151

102152
@patch.object(kc_compat, 'get_kernel_hash', return_value='abcdef123456')
103153
@patch.object(kc_compat, 'urlopen')

0 commit comments

Comments
 (0)