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

fix: add creation of artifacts to spl_build #135

Merged
merged 1 commit into from
Apr 18, 2024
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
17 changes: 17 additions & 0 deletions src/spl_core/test_utils/base_variant_test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ def expected_component_report_artifacts(self) -> List[Path]:
Path("coverage/index.html"),
]

@property
def create_artifacts_archive(self) -> bool:
return True

@property
def create_artifacts_json(self) -> bool:
return True

@property
def expected_archive_artifacts(self) -> List[Path]:
return self.expected_build_artifacts

def assert_artifact_exists(self, dir: Path, artifact: Path) -> None:
if artifact.is_absolute():
assert artifact.exists(), f"Artifact {artifact} does not exist" # noqa: S101
Expand All @@ -50,6 +62,11 @@ def test_build(self) -> None:
assert 0 == spl_build.execute(target="all") # noqa: S101
for artifact in self.expected_build_artifacts:
self.assert_artifact_exists(dir=spl_build.build_dir, artifact=artifact)
if self.create_artifacts_archive:
# create artifacts archive
spl_build.create_artifacts_archive(self.expected_archive_artifacts)
if self.create_artifacts_json:
spl_build.create_artifacts_json(self.expected_archive_artifacts)

def test_unittest(self) -> None:
spl_build: SplBuild = SplBuild(variant=self.variant, build_kit="test")
Expand Down
85 changes: 85 additions & 0 deletions src/spl_core/test_utils/spl_build.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import json
import time
import zipfile
from dataclasses import dataclass
from pathlib import Path
from typing import List, Optional

Expand All @@ -7,6 +10,34 @@
from spl_core.common.command_line_executor import CommandLineExecutor


@dataclass
class ArchiveArtifact:
archive_path: Path
absolute_path: Path


class ArtifactsCollection:
def __init__(self, artifacts: List[Path], build_dir: Path):
self.archive_artifacts: List[ArchiveArtifact] = []
for artifact in artifacts:
if artifact.is_absolute():
artifact_path = artifact
else:
artifact_path = Path.joinpath(build_dir.absolute(), artifact)
if artifact_path.is_dir():
for artifact in artifact_path.glob("**/*"):
if artifact.is_file():
if artifact_path.is_relative_to(build_dir.absolute()):
self.archive_artifacts.append(ArchiveArtifact(archive_path=artifact.relative_to(build_dir.absolute()), absolute_path=artifact.absolute()))
else:
self.archive_artifacts.append(ArchiveArtifact(archive_path=Path(artifact.name), absolute_path=artifact.absolute()))
else:
if artifact_path.is_relative_to(build_dir.absolute()):
self.archive_artifacts.append(ArchiveArtifact(archive_path=artifact_path.relative_to(build_dir.absolute()), absolute_path=artifact_path.absolute()))
else:
self.archive_artifacts.append(ArchiveArtifact(archive_path=Path(artifact_path.name), absolute_path=artifact_path.absolute()))


class SplBuild:
"""Class for building an SPL repository."""

Expand Down Expand Up @@ -75,3 +106,57 @@ def execute(self, target: str, additional_args: Optional[List[str]] = None) -> i
else:
break
return return_code

def create_artifacts_archive(self, expected_artifacts: List[Path]) -> Path:
"""
Create a zip file containing the collected artifacts.

Args:
expected_artifacts: List of Path of artifacts which should be archived

Returns:
Path: The path to the created zip file.

Raises:
Exception: If there is an error creating the zip file.

"""
zip_path = self.build_dir / "artifacts.zip"

# Delete the file if it already exists
if zip_path.exists():
zip_path.unlink()

try:
with zipfile.ZipFile(zip_path, "w") as zip_file:
artifacts_collection = ArtifactsCollection(artifacts=expected_artifacts, build_dir=self.build_dir)
for artifact in artifacts_collection.archive_artifacts:
zip_file.write(artifact.absolute_path, arcname=artifact.archive_path)
print(f"Zip file created at: {zip_path}")
return zip_path
except Exception as e:
print(f"Error creating artifacts zip file: {e}")
raise e

def create_artifacts_json(self, expected_artifacts: List[Path]) -> Path:
"""
Create a JSON file listing the collected artifacts.

Returns:
Path: The path to the created JSON file.

Raises:
Exception: If there is an error creating the JSON file.

"""
artifacts_collection = ArtifactsCollection(artifacts=expected_artifacts, build_dir=self.build_dir)
json_content = {
"variant": self.variant,
"build_kit": self.build_kit,
"artifacts": [str(artifact.archive_path.as_posix()) for artifact in artifacts_collection.archive_artifacts],
}
json_path = self.build_dir / "artifacts.json"

json_path.write_text(json.dumps(json_content, indent=4))

return json_path
8 changes: 8 additions & 0 deletions tests/test_base_variant_test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ class Test_SomeVariant(BaseVariantTestRunner):
def test_variant(self):
assert self.variant == "SomeVariant"

@property
def create_artifacts_archive(self):
return False

@property
def create_artifacts_json(self):
return False

@property
def component_paths(self):
return [Path("component1"), Path("component2")]
Expand Down
66 changes: 64 additions & 2 deletions tests/test_spl_build.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import json
import os
import zipfile
from pathlib import Path
from unittest.mock import MagicMock, patch

Expand All @@ -7,10 +10,10 @@


@pytest.fixture
def spl_build():
def spl_build(tmp_path_factory):
os.chdir(tmp_path_factory.mktemp("spl_build"))
return SplBuild(variant="my_var", build_kit="defaultKit")


def test_build_dir(spl_build: SplBuild) -> None:
"""
Test that the build directory is constructed correctly.
Expand Down Expand Up @@ -67,3 +70,62 @@ def test_execute_with_additional_args(mock_execute: MagicMock, spl_build: SplBui

# Assertions
mock_execute.assert_called_once_with(["build.bat", "-buildKit", "defaultKit", "-variants", "my_var", "-target", "all", "-reconfigure", "-j", "4"])


def test_create_artifacts_archive_inside_spl_build(spl_build: SplBuild) -> None:
"""
Test the creation of artifacts archive and json for artifacts inside of the spl_build folder
"""
# Generate some files and folder inside the spl build dir
file_1 = spl_build.build_dir.joinpath("out", "some_file.exe")
file_2 = spl_build.build_dir.joinpath("other_file.exe")
folder_1 = spl_build.build_dir.joinpath("some_folder")
file_3 = folder_1.joinpath("other_file.exe")
artifacts = [file_1, file_2, file_3]
for file in artifacts:
file.parent.mkdir(parents=True, exist_ok=True)
file.write_text("some_text")

# create artifacts archive and artifacts json
archive_dir = spl_build.create_artifacts_archive([Path("some_folder"), Path("out/some_file.exe"), Path("other_file.exe")])
archive_json = spl_build.create_artifacts_json([Path("some_folder"), Path("out/some_file.exe"), Path("other_file.exe")])
assert archive_dir.exists()
assert archive_json.exists()

# check content of archive and json file
expected_artifacts = ["some_folder/other_file.exe", "out/some_file.exe", "other_file.exe"]
with zipfile.ZipFile(archive_dir) as zip_ref:
file_list = zip_ref.namelist()
assert file_list == expected_artifacts

assert dict(json.loads(archive_json.read_text())) == {'variant': 'my_var',
'build_kit': 'defaultKit',
'artifacts': expected_artifacts
}

def test_create_artifacts_archive_outside_spl_build(spl_build: SplBuild, tmp_path: Path) -> None:
"""
Test the creation of artifacts archive and json for artifacts outsice of the spl_build folder
"""
# Generate a file and folder outside the spl build dir
spl_build.build_dir.mkdir(parents=True, exist_ok=True)
test_dir = tmp_path
outside_file = test_dir.joinpath("some_file.txt")
outside_file.write_text("something")

# create artifacts archive and artifacts json
archive_dir = spl_build.create_artifacts_archive([test_dir.absolute()])
archive_json = spl_build.create_artifacts_json([test_dir.absolute()])
assert archive_dir.exists()
assert archive_json.exists()

# check content of archive and json file
expected_artifacts = [outside_file.name]
with zipfile.ZipFile(archive_dir) as zip_ref:
file_list = zip_ref.namelist()
assert file_list == expected_artifacts

assert dict(json.loads(archive_json.read_text())) == {'variant': 'my_var',
'build_kit': 'defaultKit',
'artifacts': expected_artifacts
}
JuReMq marked this conversation as resolved.
Show resolved Hide resolved