|
1 | | -import pytest |
| 1 | +import inspect |
2 | 2 | from unittest.mock import patch |
3 | | -from inspect import getmodule |
4 | | -from inspect import getmro |
| 3 | + |
| 4 | +import pytest |
5 | 5 |
|
6 | 6 | from vulnerabilities import importers |
7 | | -from vulnerabilities.importer_yielder import IMPORTER_REGISTRY |
8 | 7 | from vulnerabilities.data_source import Advisory |
| 8 | +from vulnerabilities.importer_yielder import IMPORTER_REGISTRY |
| 9 | + |
| 10 | +MAX_ADVISORIES = 1 |
9 | 11 |
|
10 | | -MAX_ADVISORIES = 2000 |
11 | 12 |
|
12 | | -class MaxAdvisoriesCreatedInterrupt(Exception): |
| 13 | +class MaxAdvisoriesCreatedInterrupt(BaseException): |
| 14 | + # Inheriting BaseException is intentional because the function being tested might catch Exception |
13 | 15 | pass |
14 | 16 |
|
15 | 17 |
|
16 | 18 | @pytest.mark.webtest |
17 | 19 | @pytest.mark.parametrize( |
18 | 20 | ("data_source", "config"), |
19 | | - ((data["data_source"], data["data_source_cfg"]) for data in IMPORTER_REGISTRY[0:1]), |
| 21 | + ((data["data_source"], data["data_source_cfg"]) for data in IMPORTER_REGISTRY), |
20 | 22 | ) |
21 | 23 | def test_updated_advisories(data_source, config): |
22 | 24 | if not data_source == "GitHubAPIDataSource": |
23 | 25 | data_src = getattr(importers, data_source) |
24 | 26 | data_src = data_src(batch_size=MAX_ADVISORIES, config=config) |
25 | | - module = getmodule(data_src).__name__ |
26 | 27 | advisory_counter = 0 |
27 | 28 |
|
28 | | - def patched_advisory(**kwargs): |
| 29 | + def patched_advisory(*args, **kwargs): |
29 | 30 | nonlocal advisory_counter |
30 | | - ueatnhasnuth |
31 | | - advisory_counter += 1 |
32 | 31 |
|
33 | 32 | if advisory_counter >= MAX_ADVISORIES: |
34 | 33 | raise MaxAdvisoriesCreatedInterrupt |
35 | 34 |
|
36 | | - x = Advisory(**kwargs) |
37 | | - with open("/tmp/x") as f: |
38 | | - f.write(x) |
39 | | - return x |
40 | | - |
41 | | - with patch(f"{module}.Advisory", side_effect=patched_advisory, create=True): |
| 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): |
42 | 50 | try: |
43 | 51 | with data_src: |
44 | | - print(list(data_src.updated_advisories())) |
45 | | - for i in data_src.updated_advisories(): |
46 | | - print("EE:") |
47 | | - print(i) |
| 52 | + assert len(list(data_src.updated_advisories())) > 0 |
48 | 53 | except MaxAdvisoriesCreatedInterrupt: |
49 | 54 | pass |
50 | | - |
51 | | - |
|
0 commit comments