Skip to content

Commit 19534e7

Browse files
authored
test(available-fix): mock cve data (fixes #1503) (#1513)
* fixes #1503
1 parent 9ada43f commit 19534e7

File tree

4 files changed

+246
-78
lines changed

4 files changed

+246
-78
lines changed

cve_bin_tool/available_fix/debian_cve_tracker.py

+25-22
Original file line numberDiff line numberDiff line change
@@ -44,33 +44,36 @@ def cve_info(
4444
"""Produces the Backported fixes' info"""
4545

4646
cve_data = format_output(all_cve_data)
47-
check_json()
48-
with open(DEB_CVE_JSON_PATH) as jsonfile:
49-
json_data = load(jsonfile)
50-
for cve in cve_data:
51-
try:
52-
cve_fix = json_data[cve["product"]][cve["cve_number"]]["releases"][
53-
self.compute_distro()
54-
]
55-
if cve_fix["status"] == "resolved":
56-
if self.is_backport:
57-
if cve_fix["fixed_version"].startswith(cve["version"]):
58-
LOGGER.info(
59-
f'{cve["product"]}: {cve["cve_number"]} has backported fix in v{cve_fix["fixed_version"]} release.'
60-
)
61-
else:
62-
LOGGER.info(
63-
f'{cve["product"]}: No known backported fix for {cve["cve_number"]}.'
64-
)
47+
json_data = self.get_data()
48+
for cve in cve_data:
49+
try:
50+
cve_fix = json_data[cve["product"]][cve["cve_number"]]["releases"][
51+
self.compute_distro()
52+
]
53+
if cve_fix["status"] == "resolved":
54+
if self.is_backport:
55+
if cve_fix["fixed_version"].startswith(cve["version"]):
56+
LOGGER.info(
57+
f'{cve["product"]}: {cve["cve_number"]} has backported fix in v{cve_fix["fixed_version"]} release.'
58+
)
6559
else:
6660
LOGGER.info(
67-
f'{cve["product"]}: {cve["cve_number"]} has available fix in v{cve_fix["fixed_version"]} release.'
61+
f'{cve["product"]}: No known backported fix for {cve["cve_number"]}.'
6862
)
69-
except KeyError:
70-
if cve["cve_number"] != "UNKNOWN":
63+
else:
7164
LOGGER.info(
72-
f'{cve["product"]}: No known fix for {cve["cve_number"]}.'
65+
f'{cve["product"]}: {cve["cve_number"]} has available fix in v{cve_fix["fixed_version"]} release.'
7366
)
67+
except KeyError:
68+
if cve["cve_number"] != "UNKNOWN":
69+
LOGGER.info(
70+
f'{cve["product"]}: No known fix for {cve["cve_number"]}.'
71+
)
72+
73+
def get_data(self):
74+
check_json()
75+
with open(DEB_CVE_JSON_PATH) as jsonfile:
76+
return load(jsonfile)
7477

7578
def compute_distro(self):
7679
if self.distro_name == "ubuntu":

requirements.csv

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pytest_not_in_db,pytest
88
pytest_not_in_db,pytest-xdist
99
pytest_not_in_db,pytest-cov
1010
pytest_not_in_db,pytest-asyncio
11+
pytest_not_in_db,pytest-mock
1112
willmcgugan_not_in_db,rich
1213
crummy_not_in_db,beautifulsoup4
1314
uiri_not_in_db,toml

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pytest
1111
pytest-xdist
1212
pytest-cov
1313
pytest-asyncio
14+
pytest-mock
1415
rpmfile>=1.0.6
1516
zstandard; python_version >= "3.4"
1617
reportlab

test/test_available_fix.py

+219-56
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from test.utils import LONG_TESTS
55

66
import pytest
7+
from pytest_mock import MockerFixture
78

89
from cve_bin_tool.available_fix import AvailableFixReport
910
from cve_bin_tool.available_fix.debian_cve_tracker import check_json
@@ -15,6 +16,140 @@ class TestAvailableFixReport:
1516
def arrange_data(self):
1617
check_json()
1718

19+
@pytest.mark.skipif(
20+
LONG_TESTS() != 1, reason="Skipping tests to reduce network calls"
21+
)
22+
def test_long_debian_backport_fix_output(
23+
self, caplog: pytest.LogCaptureFixture
24+
) -> None:
25+
"""Test Backported fix for Debian distros output on console with external API"""
26+
27+
fixes = AvailableFixReport(self.MOCK_PSPP_CVE_DATA, "debian-bullseye", True)
28+
fixes.check_available_fix()
29+
expected_output = [
30+
"pspp: CVE-2018-20230 has backported fix in v1.2.0-3 release.",
31+
"pspp: CVE-2019-9211 has backported fix in v1.2.0-4 release.",
32+
]
33+
34+
assert expected_output == [rec.message for rec in caplog.records]
35+
36+
def test_debian_backport_fix_output(
37+
self, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
38+
) -> None:
39+
"""Test Backported fix for Debian distros output on console"""
40+
41+
fixes = AvailableFixReport(self.MOCK_PSPP_CVE_DATA, "debian-bullseye", True)
42+
mocker.patch(
43+
"cve_bin_tool.available_fix.debian_cve_tracker.DebianCVETracker.get_data",
44+
return_value=self.MOCK_DEBIAN_API,
45+
)
46+
fixes.check_available_fix()
47+
expected_output = [
48+
"pspp: CVE-2018-20230 has backported fix in v1.2.0-3 release.",
49+
"pspp: CVE-2019-9211 has backported fix in v1.2.0-4 release.",
50+
]
51+
52+
assert expected_output == [rec.message for rec in caplog.records]
53+
54+
@pytest.mark.skipif(
55+
LONG_TESTS() != 1, reason="Skipping tests to reduce network calls"
56+
)
57+
def test_long_debian_available_fix_output(
58+
self, caplog: pytest.LogCaptureFixture
59+
) -> None:
60+
"""Test Available fix for Debian distros output on console with external API"""
61+
62+
fixes = AvailableFixReport(self.MOCK_AVAHI_CVE_DATA, "debian-bullseye", False)
63+
fixes.check_available_fix()
64+
expected_output = [
65+
"avahi: CVE-2010-2244 has available fix in v0.6.26-1 release.",
66+
"avahi: CVE-2011-1002 has available fix in v0.6.28-4 release.",
67+
"avahi: CVE-2017-6519 has available fix in v0.7-5 release.",
68+
"avahi: CVE-2021-26720 has available fix in v0.8-4 release.",
69+
]
70+
71+
assert expected_output == [rec.message for rec in caplog.records]
72+
73+
def test_debian_available_fix_output(
74+
self, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
75+
) -> None:
76+
"""Test Available fix for Debian distros output on console"""
77+
78+
fixes = AvailableFixReport(self.MOCK_AVAHI_CVE_DATA, "debian-bullseye", False)
79+
mocker.patch(
80+
"cve_bin_tool.available_fix.debian_cve_tracker.DebianCVETracker.get_data",
81+
return_value=self.MOCK_DEBIAN_API,
82+
)
83+
fixes.check_available_fix()
84+
expected_output = [
85+
"avahi: CVE-2010-2244 has available fix in v0.6.26-1 release.",
86+
"avahi: CVE-2011-1002 has available fix in v0.6.28-4 release.",
87+
"avahi: CVE-2017-6519 has available fix in v0.7-5 release.",
88+
"avahi: CVE-2021-26720 has available fix in v0.8-4 release.",
89+
]
90+
91+
assert expected_output == [rec.message for rec in caplog.records]
92+
93+
@pytest.mark.skipif(
94+
LONG_TESTS() != 1, reason="Skipping tests to reduce network calls"
95+
)
96+
def test_long_redhat_available_fix_output(
97+
self, caplog: pytest.LogCaptureFixture
98+
) -> None:
99+
"""Test Available fix for Redhat distros output on console with external API"""
100+
101+
fixes = AvailableFixReport(self.MOCK_NODEJS_CVE_DATA, "rhel-8", False)
102+
fixes.check_available_fix()
103+
expected_output = [
104+
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: nodejs v12",
105+
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: nodejs v14",
106+
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: libuv v1.41",
107+
"node.js: CVE-2021-22918 - Status: Not affected - Related package: nodejs v16",
108+
"node.js: CVE-2021-22931 - Status: Fixed - Fixed package: nodejs v12",
109+
"node.js: CVE-2021-22931 - Status: Fixed - Fixed package: nodejs v14",
110+
"node.js: CVE-2021-22931 - Status: Not affected - Related package: nodejs v16",
111+
"node.js: CVE-2021-22939 - Status: Fixed - Fixed package: nodejs v12",
112+
"node.js: CVE-2021-22939 - Status: Fixed - Fixed package: nodejs v14",
113+
"node.js: CVE-2021-22939 - Status: Not affected - Related package: nodejs v16",
114+
"node.js: CVE-2021-22940 - Status: Fixed - Fixed package: nodejs v12",
115+
"node.js: CVE-2021-22940 - Status: Fixed - Fixed package: nodejs v14",
116+
"node.js: CVE-2021-22940 - Status: Not affected - Related package: nodejs v16",
117+
]
118+
119+
assert expected_output == [rec.message for rec in caplog.records]
120+
121+
def test_redhat_available_fix_output(
122+
self, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
123+
) -> None:
124+
"""Test Available fix for Redhat distros output on console"""
125+
126+
fixes = AvailableFixReport(self.MOCK_NODEJS_CVE_DATA, "rhel-8", False)
127+
mocker.patch(
128+
"cve_bin_tool.available_fix.redhat_cve_tracker.RedhatCVETracker.get_data",
129+
return_value=self.MOCK_RH_API,
130+
)
131+
fixes.check_available_fix()
132+
expected_output = [
133+
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: nodejs v12",
134+
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: nodejs v14",
135+
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: libuv v1.41",
136+
"node.js: CVE-2021-22918 - Status: Not affected - Related package: nodejs v16",
137+
"node.js: CVE-2021-22931 - Status: Fixed - Fixed package: nodejs v12",
138+
"node.js: CVE-2021-22931 - Status: Fixed - Fixed package: nodejs v14",
139+
"node.js: CVE-2021-22931 - Status: Fixed - Fixed package: libuv v1.41",
140+
"node.js: CVE-2021-22931 - Status: Not affected - Related package: nodejs v16",
141+
"node.js: CVE-2021-22939 - Status: Fixed - Fixed package: nodejs v12",
142+
"node.js: CVE-2021-22939 - Status: Fixed - Fixed package: nodejs v14",
143+
"node.js: CVE-2021-22939 - Status: Fixed - Fixed package: libuv v1.41",
144+
"node.js: CVE-2021-22939 - Status: Not affected - Related package: nodejs v16",
145+
"node.js: CVE-2021-22940 - Status: Fixed - Fixed package: nodejs v12",
146+
"node.js: CVE-2021-22940 - Status: Fixed - Fixed package: nodejs v14",
147+
"node.js: CVE-2021-22940 - Status: Fixed - Fixed package: libuv v1.41",
148+
"node.js: CVE-2021-22940 - Status: Not affected - Related package: nodejs v16",
149+
]
150+
151+
assert expected_output == [rec.message for rec in caplog.records]
152+
18153
MOCK_PSPP_CVE_DATA = {
19154
ProductInfo(vendor="gnu", product="pspp", version="1.2.0"): CVEData(
20155
None,
@@ -89,60 +224,88 @@ def arrange_data(self):
89224
)
90225
}
91226

92-
@pytest.mark.skipif(
93-
LONG_TESTS() != 1, reason="Skipping tests to reduce network calls"
94-
)
95-
def test_debian_backport_fix_output(self, caplog: pytest.LogCaptureFixture):
96-
"""Test Backported fix for Debian distros output on console"""
97-
98-
fixes = AvailableFixReport(self.MOCK_PSPP_CVE_DATA, "debian-bullseye", True)
99-
fixes.check_available_fix()
100-
expected_output = [
101-
"pspp: CVE-2018-20230 has backported fix in v1.2.0-3 release.",
102-
"pspp: CVE-2019-9211 has backported fix in v1.2.0-4 release.",
103-
]
104-
105-
assert expected_output == [rec.message for rec in caplog.records]
106-
107-
@pytest.mark.skipif(
108-
LONG_TESTS() != 1, reason="Skipping tests to reduce network calls"
109-
)
110-
def test_debian_available_fix_output(self, caplog: pytest.LogCaptureFixture):
111-
"""Test Available fix for Debian distros output on console"""
112-
113-
fixes = AvailableFixReport(self.MOCK_AVAHI_CVE_DATA, "debian-bullseye", False)
114-
fixes.check_available_fix()
115-
expected_output = [
116-
"avahi: CVE-2010-2244 has available fix in v0.6.26-1 release.",
117-
"avahi: CVE-2011-1002 has available fix in v0.6.28-4 release.",
118-
"avahi: CVE-2017-6519 has available fix in v0.7-5 release.",
119-
"avahi: CVE-2021-26720 has available fix in v0.8-4 release.",
120-
]
121-
122-
assert expected_output == [rec.message for rec in caplog.records]
123-
124-
@pytest.mark.skipif(
125-
LONG_TESTS() != 1, reason="Skipping tests to reduce network calls"
126-
)
127-
def test_redhat_available_fix_output(self, caplog: pytest.LogCaptureFixture):
128-
"""Test Available fix for Redhat distros output on console"""
129-
130-
fixes = AvailableFixReport(self.MOCK_NODEJS_CVE_DATA, "rhel-8", False)
131-
fixes.check_available_fix()
132-
expected_output = [
133-
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: nodejs v12",
134-
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: nodejs v14",
135-
"node.js: CVE-2021-22918 - Status: Fixed - Fixed package: libuv v1.41",
136-
"node.js: CVE-2021-22918 - Status: Not affected - Related package: nodejs v16",
137-
"node.js: CVE-2021-22931 - Status: Fixed - Fixed package: nodejs v12",
138-
"node.js: CVE-2021-22931 - Status: Fixed - Fixed package: nodejs v14",
139-
"node.js: CVE-2021-22931 - Status: Not affected - Related package: nodejs v16",
140-
"node.js: CVE-2021-22939 - Status: Fixed - Fixed package: nodejs v12",
141-
"node.js: CVE-2021-22939 - Status: Fixed - Fixed package: nodejs v14",
142-
"node.js: CVE-2021-22939 - Status: Not affected - Related package: nodejs v16",
143-
"node.js: CVE-2021-22940 - Status: Fixed - Fixed package: nodejs v12",
144-
"node.js: CVE-2021-22940 - Status: Fixed - Fixed package: nodejs v14",
145-
"node.js: CVE-2021-22940 - Status: Not affected - Related package: nodejs v16",
146-
]
227+
MOCK_RH_API = {
228+
"affected_release": [
229+
{
230+
"product_name": "Red Hat Enterprise Linux 8",
231+
"package": "nodejs:12-8040020210708131418.522a0ee4",
232+
},
233+
{
234+
"product_name": "Red Hat Enterprise Linux 8",
235+
"package": "nodejs:14-8040020210708154809.522a0ee4",
236+
},
237+
{
238+
"product_name": "Red Hat Enterprise Linux 8",
239+
"package": "libuv-1:1.41.1-1.el8_4",
240+
},
241+
],
242+
"package_state": [
243+
{
244+
"product_name": "Red Hat Enterprise Linux 8",
245+
"fix_state": "Not affected",
246+
"package_name": "nodejs:16/nodejs",
247+
}
248+
],
249+
}
147250

148-
assert expected_output == [rec.message for rec in caplog.records]
251+
MOCK_DEBIAN_API = {
252+
"pspp": {
253+
"CVE-2018-20230": {
254+
"releases": {
255+
"bullseye": {
256+
"status": "resolved",
257+
"fixed_version": "1.2.0-3",
258+
},
259+
},
260+
},
261+
"CVE-2019-9211": {
262+
"releases": {
263+
"bullseye": {
264+
"status": "resolved",
265+
"fixed_version": "1.2.0-4",
266+
},
267+
},
268+
},
269+
},
270+
"avahi": {
271+
"CVE-2010-2244": {
272+
"releases": {
273+
"bullseye": {
274+
"status": "resolved",
275+
"fixed_version": "0.6.26-1",
276+
},
277+
},
278+
},
279+
"CVE-2011-1002": {
280+
"releases": {
281+
"bullseye": {
282+
"status": "resolved",
283+
"fixed_version": "0.6.28-4",
284+
},
285+
},
286+
},
287+
"CVE-2017-6519": {
288+
"releases": {
289+
"bullseye": {
290+
"status": "resolved",
291+
"fixed_version": "0.7-5",
292+
},
293+
},
294+
},
295+
"CVE-2021-26720": {
296+
"releases": {
297+
"bullseye": {
298+
"status": "resolved",
299+
"fixed_version": "0.8-4",
300+
},
301+
},
302+
},
303+
"CVE-2021-3468": {
304+
"releases": {
305+
"bullseye": {
306+
"status": "open",
307+
},
308+
}
309+
},
310+
},
311+
}

0 commit comments

Comments
 (0)