Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor codebase and tests to treat Advisory class mutable #363

Merged
merged 3 commits into from
Mar 4, 2021

Conversation

sbs2001
Copy link
Collaborator

@sbs2001 sbs2001 commented Feb 25, 2021

Signed-off-by: Shivam Sandbhor shivam.sandbhor@gmail.com
Fixes #334

Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
Copy link
Collaborator

@pombredanne pombredanne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, see a few nits for your consideration. And merge!

@@ -187,7 +187,7 @@ def _load_advisories(
impacted_package_urls=[],
resolved_package_urls=resolved_purls,
vuln_references=references,
vulnerability_id=vuln_ids[0] if vuln_ids[0] != "CVE-????-?????" else None,
vulnerability_id=vuln_ids[0] if vuln_ids[0] != "CVE-????-?????" else "",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add TODO or ticket to revisit this cryptic code

@@ -209,7 +200,7 @@ def batch_advisories(self, advisories: List[Advisory]) -> Set[Advisory]:

while advisories:
b, advisories = advisories[: self.batch_size], advisories[self.batch_size:]
yield set(b)
yield b
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add TODO or ticket to revisit this cryptic code

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also do not use incorrect type hints as in Set[Advisory]... nothing is better than wrong.

@@ -78,19 +78,10 @@ class Advisory:
"""

summary: str
impacted_package_urls: Iterable[PackageURL]
vulnerability_id: Optional[str] = None
impacted_package_urls: Iterable[PackageURL] = dataclasses.field(default_factory=list)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO you should have a way to compare and sort Advisory.
This would make the tests super simpler. See https://docs.python.org/3/library/functools.html?highlight=functools#functools.total_ordering

return advisory.vulnerability_id


def advisories_are_equal(expected_advisories, found_advisories):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above. You should implmenent https://docs.python.org/3/library/functools.html?highlight=functools#functools.total_ordering for an Advisory for simpler and clearer code.

With that, the advisories_are_equal would become:
sorted(expected_advisories) == sorted(found_advisories)
and could be removed

from vulnerabilities.data_source import Reference


def normalized_reference(reference):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO make this a method of Reference

return Reference(reference_id=reference.reference_id, url=reference.url, severities=severities)


def normalized_advisory(advisory):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO move as a method of Advisory


# This is not entirely correct, but enough for testing purpose.
def advisory_sort_key(advisory):
return advisory.vulnerability_id
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below using attrgetter

def advisories_are_equal(expected_advisories, found_advisories):

expected_advisories = list(filter(lambda x: isinstance(x, Advisory), expected_advisories))
expected_advisories.sort(key=advisory_sort_key)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using from operator import attrgetter you could use:

Suggested change
expected_advisories.sort(key=advisory_sort_key)
expected_advisories.sort(key=attrgetter('vulnerability_id`))

Or...

Suggested change
expected_advisories.sort(key=advisory_sort_key)
expected_advisories.sort(key=lambda advisory: advisory.vulnerability_id)

But IMHO it is better to have that in the Advisory class as suggested here.

@sbs2001 sbs2001 merged commit a187f90 into aboutcode-org:main Mar 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use immutable dataclasses
2 participants