Skip to content

Commit 7b43c4e

Browse files
committed
Check db during integration test
db.json provides storage of the library index data in the Library Manager back end. The library_index.json content for previously indexed library releases is generated from this data with only the data for new releases being generated from the library repository content. For this reason, it's very important for the db.json content to be correct. Checking the db.json generated from a run of the system against a "golden master" provides improved confidence that the content remains correct during development on the project. The "golden master" db.json was checked against the one generated by the final "production" engine version (60ebae3ec0715c211682820354ebb0dfc3de2436) of the old library Manager system, confirming the only differences were: - The expected checksum changes. - The since added "Log" field.
1 parent 8d9ee29 commit 7b43c4e

File tree

2 files changed

+562
-1
lines changed

2 files changed

+562
-1
lines changed

test/test_all.py

+74-1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def test_all(run_command, working_dir):
7979
golden_logs_parent_path=test_data_path.joinpath("test_all", "golden", "logs", "generate"),
8080
logs_subpath=pathlib.Path("github.com", "arduino-libraries", "SpacebrewYun", "index.html"),
8181
)
82+
check_db(configuration=configuration)
8283
check_index(configuration=configuration)
8384

8485
# Run the engine again
@@ -97,6 +98,7 @@ def test_all(run_command, working_dir):
9798
golden_logs_parent_path=test_data_path.joinpath("test_all", "golden", "logs", "update"),
9899
logs_subpath=pathlib.Path("github.com", "arduino-libraries", "SpacebrewYun", "index.html"),
99100
)
101+
check_db(configuration=configuration)
100102
check_index(configuration=configuration)
101103

102104

@@ -106,9 +108,9 @@ def check_libraries(configuration):
106108
Keyword arguments:
107109
configuration -- dictionary defining the libraries-repository-engine configuration
108110
"""
111+
# Check against the index
109112
with pathlib.Path(configuration["LibrariesIndex"]).open(mode="r", encoding="utf-8") as libraries_index_file:
110113
libraries_index = json.load(fp=libraries_index_file)
111-
112114
for release in libraries_index["libraries"]:
113115
release_archive_path = pathlib.Path(
114116
configuration["LibrariesFolder"],
@@ -121,6 +123,21 @@ def check_libraries(configuration):
121123

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

126+
# Check against the db
127+
with pathlib.Path(configuration["LibrariesDB"]).open(mode="r", encoding="utf-8") as library_db_file:
128+
library_db = json.load(fp=library_db_file)
129+
for release in library_db["Releases"]:
130+
release_archive_path = pathlib.Path(
131+
configuration["LibrariesFolder"],
132+
release["URL"].removeprefix(configuration["BaseDownloadUrl"]),
133+
)
134+
135+
assert release_archive_path.exists()
136+
137+
assert release["Size"] == release_archive_path.stat().st_size
138+
139+
assert release["Checksum"] == "SHA-256:" + hashlib.sha256(release_archive_path.read_bytes()).hexdigest()
140+
124141

125142
def check_logs(configuration, golden_logs_parent_path, logs_subpath):
126143
"""Run tests to determine whether the engine's logs are as expected.
@@ -147,6 +164,62 @@ def check_logs(configuration, golden_logs_parent_path, logs_subpath):
147164
assert logs == golden_logs
148165

149166

167+
def check_db(configuration):
168+
"""Run tests to determine whether the generated library database is as expected.
169+
170+
Keyword arguments:
171+
configuration -- dictionary defining the libraries-repository-engine configuration
172+
"""
173+
checksum_placeholder = "CHECKSUM_PLACEHOLDER"
174+
175+
# Load generated db
176+
with pathlib.Path(configuration["LibrariesDB"]).open(mode="r", encoding="utf-8") as db_file:
177+
db = json.load(fp=db_file)
178+
for release in db["Releases"]:
179+
# The checksum values in the db will be different on every run, so it's necessary to replace them with a
180+
# placeholder before comparing to the golden master
181+
release["Checksum"] = checksum_placeholder
182+
183+
# Load golden index
184+
golden_db_template = test_data_path.joinpath("test_all", "golden", "db.json").read_text(encoding="utf-8")
185+
# Fill in mutable content
186+
golden_db_string = string.Template(template=golden_db_template).substitute(
187+
base_download_url=configuration["BaseDownloadUrl"],
188+
checksum_placeholder=checksum_placeholder,
189+
git_clones_folder=configuration["GitClonesFolder"],
190+
)
191+
golden_db = json.loads(golden_db_string)
192+
193+
# Compare db against golden master
194+
# Order of entries in the db is arbitrary so a simply equality assertion is not possible
195+
assert len(db["Libraries"]) == len(golden_db["Libraries"])
196+
for library in db["Libraries"]:
197+
assert library in golden_db["Libraries"]
198+
199+
assert len(db["Releases"]) == len(golden_db["Releases"])
200+
for release in db["Releases"]:
201+
# Find the golden master for the release
202+
golden_release = None
203+
for golden_release_candidate in golden_db["Releases"]:
204+
if (
205+
golden_release_candidate["LibraryName"] == release["LibraryName"]
206+
and golden_release_candidate["Version"] == release["Version"]
207+
):
208+
golden_release = golden_release_candidate
209+
break
210+
211+
assert golden_release is not None # Matching golden release was found
212+
213+
# Small variation in size could result from compression algorithm changes, so we allow a tolerance
214+
assert "Size" in release
215+
assert math.isclose(release["Size"], golden_release["Size"], rel_tol=size_comparison_tolerance)
216+
# Remove size data so a direct comparison of the remaining data can be made against the golden master
217+
del release["Size"]
218+
del golden_release["Size"]
219+
220+
assert release == golden_release
221+
222+
150223
def check_index(configuration):
151224
"""Run tests to determine whether the generated library index is as expected.
152225

0 commit comments

Comments
 (0)