Skip to content

Commit 6b29388

Browse files
committed
Speed up test_upstream
Earlier, one batch of advisories was requested from updated_advisories method of the respective importers. This was inefficient as not all importers respect batching internally. Eventually, we wish to eliminate batches as well ( # 338 ). Now, the updated_advisories method of each importer is expected to create at least one Advisory object. If it does so, the importer is marked working. This brings major performance improvement. It is a necessity to improve this test as GitHub only allows 6 hrs of workflow time. Before: ~6hrs, now ~9 minutes Signed-off-by: Hritik Vijay <hritikxx8@gmail.com>
1 parent a530627 commit 6b29388

1 file changed

Lines changed: 40 additions & 4 deletions

File tree

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,54 @@
1+
import inspect
2+
from unittest.mock import patch
3+
14
import pytest
5+
26
from vulnerabilities import importers
7+
from vulnerabilities.data_source import Advisory
38
from vulnerabilities.importer_yielder import IMPORTER_REGISTRY
49

10+
MAX_ADVISORIES = 1
11+
12+
13+
class MaxAdvisoriesCreatedInterrupt(BaseException):
14+
# Inheriting BaseException is intentional because the function being tested might catch Exception
15+
pass
16+
517

618
@pytest.mark.webtest
719
@pytest.mark.parametrize(
820
("data_source", "config"),
921
((data["data_source"], data["data_source_cfg"]) for data in IMPORTER_REGISTRY),
1022
)
1123
def test_updated_advisories(data_source, config):
12-
1324
if not data_source == "GitHubAPIDataSource":
1425
data_src = getattr(importers, data_source)
15-
data_src = data_src(batch_size=1, config=config)
16-
with data_src:
17-
for i in data_src.updated_advisories():
26+
data_src = data_src(batch_size=MAX_ADVISORIES, config=config)
27+
advisory_counter = 0
28+
29+
def patched_advisory(*args, **kwargs):
30+
nonlocal advisory_counter
31+
32+
if advisory_counter >= MAX_ADVISORIES:
33+
raise MaxAdvisoriesCreatedInterrupt
34+
35+
advisory_counter += 1
36+
return Advisory(*args, **kwargs)
37+
38+
module = inspect.getmodule(data_src)
39+
module_members = [m[0] for m in inspect.getmembers(module)]
40+
advisory_class = f"{module.__name__}.Advisory"
41+
if "Advisory" not in module_members:
42+
advisory_class = "vulnerabilities.data_source.Advisory"
43+
44+
# Either
45+
# 1) Advisory class is successfully patched and MaxAdvisoriesCreatedInterrupt is thrown when
46+
# an importer tries to create an Advisory or
47+
# 2) Importer somehow bypasses the patch / handles BaseException internally, then
48+
# updated_advisories is required to return non zero advisories
49+
with patch(advisory_class, side_effect=patched_advisory):
50+
try:
51+
with data_src:
52+
assert len(list(data_src.updated_advisories())) > 0
53+
except MaxAdvisoriesCreatedInterrupt:
1854
pass

0 commit comments

Comments
 (0)