Skip to content

Commit

Permalink
Merge pull request #48 from per1234/test-db
Browse files Browse the repository at this point in the history
Check db during integration test
  • Loading branch information
per1234 authored Jun 8, 2021
2 parents 5068e17 + 7b43c4e commit 464e243
Show file tree
Hide file tree
Showing 3 changed files with 634 additions and 28 deletions.
108 changes: 102 additions & 6 deletions test/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
import pathlib
import platform
import typing
import math

import invoke.context
import pytest

test_data_path = pathlib.Path(__file__).resolve().parent.joinpath("testdata")
size_comparison_tolerance = 0.03 # Maximum allowed archive size difference ratio


def test_all(run_command, working_dir):
Expand Down Expand Up @@ -77,6 +79,7 @@ def test_all(run_command, working_dir):
golden_logs_parent_path=test_data_path.joinpath("test_all", "golden", "logs", "generate"),
logs_subpath=pathlib.Path("github.com", "arduino-libraries", "SpacebrewYun", "index.html"),
)
check_db(configuration=configuration)
check_index(configuration=configuration)

# Run the engine again
Expand All @@ -95,6 +98,7 @@ def test_all(run_command, working_dir):
golden_logs_parent_path=test_data_path.joinpath("test_all", "golden", "logs", "update"),
logs_subpath=pathlib.Path("github.com", "arduino-libraries", "SpacebrewYun", "index.html"),
)
check_db(configuration=configuration)
check_index(configuration=configuration)


Expand All @@ -104,9 +108,9 @@ def check_libraries(configuration):
Keyword arguments:
configuration -- dictionary defining the libraries-repository-engine configuration
"""
# Check against the index
with pathlib.Path(configuration["LibrariesIndex"]).open(mode="r", encoding="utf-8") as libraries_index_file:
libraries_index = json.load(fp=libraries_index_file)

for release in libraries_index["libraries"]:
release_archive_path = pathlib.Path(
configuration["LibrariesFolder"],
Expand All @@ -119,6 +123,21 @@ def check_libraries(configuration):

assert release["checksum"] == "SHA-256:" + hashlib.sha256(release_archive_path.read_bytes()).hexdigest()

# Check against the db
with pathlib.Path(configuration["LibrariesDB"]).open(mode="r", encoding="utf-8") as library_db_file:
library_db = json.load(fp=library_db_file)
for release in library_db["Releases"]:
release_archive_path = pathlib.Path(
configuration["LibrariesFolder"],
release["URL"].removeprefix(configuration["BaseDownloadUrl"]),
)

assert release_archive_path.exists()

assert release["Size"] == release_archive_path.stat().st_size

assert release["Checksum"] == "SHA-256:" + hashlib.sha256(release_archive_path.read_bytes()).hexdigest()


def check_logs(configuration, golden_logs_parent_path, logs_subpath):
"""Run tests to determine whether the engine's logs are as expected.
Expand All @@ -145,34 +164,111 @@ def check_logs(configuration, golden_logs_parent_path, logs_subpath):
assert logs == golden_logs


def check_db(configuration):
"""Run tests to determine whether the generated library database is as expected.
Keyword arguments:
configuration -- dictionary defining the libraries-repository-engine configuration
"""
checksum_placeholder = "CHECKSUM_PLACEHOLDER"

# Load generated db
with pathlib.Path(configuration["LibrariesDB"]).open(mode="r", encoding="utf-8") as db_file:
db = json.load(fp=db_file)
for release in db["Releases"]:
# The checksum values in the db will be different on every run, so it's necessary to replace them with a
# placeholder before comparing to the golden master
release["Checksum"] = checksum_placeholder

# Load golden index
golden_db_template = test_data_path.joinpath("test_all", "golden", "db.json").read_text(encoding="utf-8")
# Fill in mutable content
golden_db_string = string.Template(template=golden_db_template).substitute(
base_download_url=configuration["BaseDownloadUrl"],
checksum_placeholder=checksum_placeholder,
git_clones_folder=configuration["GitClonesFolder"],
)
golden_db = json.loads(golden_db_string)

# Compare db against golden master
# Order of entries in the db is arbitrary so a simply equality assertion is not possible
assert len(db["Libraries"]) == len(golden_db["Libraries"])
for library in db["Libraries"]:
assert library in golden_db["Libraries"]

assert len(db["Releases"]) == len(golden_db["Releases"])
for release in db["Releases"]:
# Find the golden master for the release
golden_release = None
for golden_release_candidate in golden_db["Releases"]:
if (
golden_release_candidate["LibraryName"] == release["LibraryName"]
and golden_release_candidate["Version"] == release["Version"]
):
golden_release = golden_release_candidate
break

assert golden_release is not None # Matching golden release was found

# Small variation in size could result from compression algorithm changes, so we allow a tolerance
assert "Size" in release
assert math.isclose(release["Size"], golden_release["Size"], rel_tol=size_comparison_tolerance)
# Remove size data so a direct comparison of the remaining data can be made against the golden master
del release["Size"]
del golden_release["Size"]

assert release == golden_release


def check_index(configuration):
"""Run tests to determine whether the generated library index is as expected.
Keyword arguments:
configuration -- dictionary defining the libraries-repository-engine configuration
"""
checksum_placeholder = "CHECKSUM_PLACEHOLDER"

# Load generated index
with pathlib.Path(configuration["LibrariesIndex"]).open(mode="r", encoding="utf-8") as library_index_file:
library_index = json.load(fp=library_index_file)
for release in library_index["libraries"]:
# The checksum values in the index will be different on every run, so it's necessary to remove them before
# comparing to the golden index
del release["checksum"]
# The checksum values in the index will be different on every run, so it's necessary to replace them with a
# placeholder before comparing to the golden index
release["checksum"] = checksum_placeholder

# Load golden index
golden_library_index_template = test_data_path.joinpath("test_all", "golden", "library_index.json").read_text(
encoding="utf-8"
)
# Fill in mutable content
golden_library_index_string = string.Template(template=golden_library_index_template).substitute(
base_download_url=configuration["BaseDownloadUrl"]
base_download_url=configuration["BaseDownloadUrl"], checksum_placeholder=checksum_placeholder
)
golden_library_index = json.loads(golden_library_index_string)

# Order of releases in the index is arbitrary so a simply equality assertion is not possible
assert len(library_index["libraries"]) == len(golden_library_index["libraries"])
for release in library_index["libraries"]:
assert release in golden_library_index["libraries"]
# Find the golden master for the release
golden_release = None
for golden_release_candidate in golden_library_index["libraries"]:
if (
golden_release_candidate["name"] == release["name"]
and golden_release_candidate["version"] == release["version"]
):
golden_release = golden_release_candidate
break

assert golden_release is not None # Matching golden release was found

# Small variation in size could result from compression algorithm changes, so we allow a tolerance
assert "size" in release
assert math.isclose(release["size"], golden_release["size"], rel_tol=size_comparison_tolerance)
# Remove size data so a direct comparison of the remaining data can be made against the golden master
del release["size"]
del golden_release["size"]

assert release == golden_release


# The engine's Git code struggles to get a clean checkout of releases under some circumstances.
Expand Down
Loading

0 comments on commit 464e243

Please sign in to comment.