Skip to content

[issue-403] change spdx version handling during validation #404

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions src/validation/creation_info_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ def validate_creation_info(creation_info: CreationInfo) -> List[ValidationMessag

context = ValidationContext(spdx_id=creation_info.spdx_id, element_type=SpdxElementType.DOCUMENT)

if not re.match(r"^SPDX-\d+.\d+$", creation_info.spdx_version):
validation_messages.append(
ValidationMessage(
f'spdx_version must be of the form "SPDX-[major].[minor]" but is: {creation_info.spdx_version}',
context
)
)

if creation_info.spdx_id != "SPDXRef-DOCUMENT":
validation_messages.append(
ValidationMessage(
Expand Down
29 changes: 27 additions & 2 deletions src/validation/document_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import re
from typing import List

from src.model.document import Document
Expand All @@ -24,9 +24,34 @@
from src.validation.validation_message import ValidationMessage, ValidationContext, SpdxElementType


def validate_full_spdx_document(document: Document, spdx_version: str) -> List[ValidationMessage]:
def validate_full_spdx_document(document: Document, spdx_version: str = None) -> List[ValidationMessage]:
validation_messages: List[ValidationMessage] = []

# SPDX version validation has to happen here because subsequent validators rely on it
document_version: str = document.creation_info.spdx_version
context = ValidationContext(spdx_id=document.creation_info.spdx_id, element_type=SpdxElementType.DOCUMENT)
if not spdx_version:
spdx_version = document_version

if not re.match(r"^SPDX-\d+.\d+$", document_version):
validation_messages.append(
ValidationMessage(
f'the document\'s spdx_version must be of the form "SPDX-[major].[minor]" but is: {document_version}',
context
)
)
elif spdx_version != document_version:
validation_messages.append(
ValidationMessage(f"provided SPDX version {spdx_version} does not match "
f"the document's SPDX version {document_version}", context)
)

if validation_messages:
validation_messages.append(ValidationMessage("There are issues concerning the SPDX version of the document. "
"As subsequent validation relies on the correct version, "
"the validation process has been cancelled.", context))
return validation_messages

validation_messages.extend(validate_creation_info(document.creation_info))
validation_messages.extend(validate_packages(document.packages, document))
validation_messages.extend(validate_files(document.files, document))
Expand Down
4 changes: 2 additions & 2 deletions src/validation/relationship_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def validate_relationship(relationship: Relationship, document: Document, spdx_v
for message in messages:
validation_messages.append(ValidationMessage(message, context))

if spdx_version != "2.3":
if spdx_version != "SPDX-2.3":
if relationship_type == RelationshipType.SPECIFICATION_FOR or relationship_type == RelationshipType.REQUIREMENT_DESCRIPTION_FOR:
validation_messages.append(
ValidationMessage(f"{relationship_type} is not supported for SPDX versions below 2.3", context))
ValidationMessage(f"{relationship_type} is not supported for SPDX versions below SPDX-2.3", context))

return validation_messages
3 changes: 1 addition & 2 deletions src/writer/json/json_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ def write_document(document: Document, file_name: str, validate: bool = True, co
a new one is created.
"""
if validate:
validation_messages: List[ValidationMessage] = validate_full_spdx_document(document,
document.creation_info.spdx_version)
validation_messages: List[ValidationMessage] = validate_full_spdx_document(document)
if validation_messages:
raise ValueError(f"Document is not valid. The following errors were detected: {validation_messages}")
if converter is None:
Expand Down
4 changes: 1 addition & 3 deletions tests/validation/test_creation_info_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ def test_valid_creation_info():

@pytest.mark.parametrize \
("creation_info_input, spdx_id, expected_message",
[(creation_info_fixture(spdx_version="version-2.3"), "SPDXRef-DOCUMENT",
'spdx_version must be of the form "SPDX-[major].[minor]" but is: version-2.3'),
(creation_info_fixture(spdx_id="SPDXRef-doc"), "SPDXRef-doc",
[(creation_info_fixture(spdx_id="SPDXRef-doc"), "SPDXRef-doc",
'spdx_id must be "SPDXRef-DOCUMENT", but is: SPDXRef-doc'),
(creation_info_fixture(data_license="MIT"), "SPDXRef-DOCUMENT",
'data_license must be "CC0-1.0", but is: MIT'),
Expand Down
43 changes: 38 additions & 5 deletions tests/validation/test_document_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,50 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List
from typing import List, Optional

import pytest

from src.model.document import Document, CreationInfo
from src.validation.document_validator import validate_full_spdx_document
from src.validation.validation_message import ValidationMessage
from tests.fixtures import document_fixture
from src.validation.validation_message import ValidationMessage, ValidationContext, SpdxElementType
from tests.fixtures import document_fixture, creation_info_fixture


def test_valid_document():
document = document_fixture()
validation_messages: List[ValidationMessage] = validate_full_spdx_document(document, "2.3")
validation_messages: List[ValidationMessage] = validate_full_spdx_document(document)

assert validation_messages == []

# TODO: https://github.com/spdx/tools-python/issues/375

@pytest.mark.parametrize("creation_info, version_input, expected_message",
[(creation_info_fixture(spdx_version="SPDX-2.3"), "SPDX-2.3", None),
(creation_info_fixture(spdx_version="SPDX-2.3"), None, None),
(creation_info_fixture(spdx_version="SPDX-2.3"), "SPDX-2.2",
"provided SPDX version SPDX-2.2 does not match the document's SPDX version SPDX-2.3"),
(creation_info_fixture(spdx_version="SPDX-2.3"), "SPDX2.3",
"provided SPDX version SPDX2.3 does not match the document's SPDX version SPDX-2.3"),
(creation_info_fixture(spdx_version="SPDX2.3"), "SPDX-2.3",
'the document\'s spdx_version must be of the form "SPDX-[major].[minor]" but is: SPDX2.3'),
(creation_info_fixture(spdx_version="SPDX2.3"), None,
'the document\'s spdx_version must be of the form "SPDX-[major].[minor]" but is: SPDX2.3'),
(creation_info_fixture(spdx_version="SPDX2.3"), "SPDX2.3",
'the document\'s spdx_version must be of the form "SPDX-[major].[minor]" but is: SPDX2.3'),
])
def test_spdx_version_handling(creation_info: CreationInfo, version_input: str, expected_message: Optional[str]):
document: Document = document_fixture(creation_info=creation_info)
validation_messages: List[ValidationMessage] = validate_full_spdx_document(document, version_input)

context = ValidationContext(spdx_id=creation_info.spdx_id, element_type=SpdxElementType.DOCUMENT)
expected: List[ValidationMessage] = []

if expected_message:
expected.append(ValidationMessage(expected_message, context))
expected.append(ValidationMessage("There are issues concerning the SPDX version of the document. "
"As subsequent validation relies on the correct version, "
"the validation process has been cancelled.", context))

assert validation_messages == expected

# TODO: https://github.com/spdx/tools-python/issues/375
8 changes: 4 additions & 4 deletions tests/validation/test_relationship_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_valid_relationship(related_spdx_element):
def test_unknown_spdx_id(spdx_element_id, related_spdx_element_id, expected_message):
relationship: Relationship = relationship_fixture(spdx_element_id=spdx_element_id,
related_spdx_element_id=related_spdx_element_id)
validation_messages: List[ValidationMessage] = validate_relationship(relationship, document_fixture(), "2.3")
validation_messages: List[ValidationMessage] = validate_relationship(relationship, document_fixture(), "SPDX-2.3")

expected = ValidationMessage(expected_message,
ValidationContext(element_type=SpdxElementType.RELATIONSHIP,
Expand All @@ -51,14 +51,14 @@ def test_unknown_spdx_id(spdx_element_id, related_spdx_element_id, expected_mess

@pytest.mark.parametrize("relationship, expected_message",
[(Relationship("SPDXRef-DOCUMENT", RelationshipType.SPECIFICATION_FOR, "SPDXRef-Package"),
"RelationshipType.SPECIFICATION_FOR is not supported for SPDX versions below 2.3"),
"RelationshipType.SPECIFICATION_FOR is not supported for SPDX versions below SPDX-2.3"),
(Relationship("SPDXRef-DOCUMENT", RelationshipType.REQUIREMENT_DESCRIPTION_FOR,
"SPDXRef-Package"),
"RelationshipType.REQUIREMENT_DESCRIPTION_FOR is not supported for SPDX versions below 2.3")])
"RelationshipType.REQUIREMENT_DESCRIPTION_FOR is not supported for SPDX versions below SPDX-2.3")])
def test_v2_3_only_types(relationship, expected_message):
document: Document = document_fixture()

validation_message: List[ValidationMessage] = validate_relationship(relationship, document, "2.2")
validation_message: List[ValidationMessage] = validate_relationship(relationship, document, "SPDX-2.2")

expected = [ValidationMessage(expected_message,
ValidationContext(element_type=SpdxElementType.RELATIONSHIP,
Expand Down