Skip to content

Commit 6eb253c

Browse files
committed
test: add unit tests for downloader
Signed-off-by: Felix Moessbauer <[email protected]>
1 parent 6b889bc commit 6eb253c

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

tests/test_download.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright (C) 2025 Siemens
4+
#
5+
# SPDX-License-Identifier: MIT
6+
7+
from pathlib import Path
8+
9+
import pytest
10+
from debsbom.download import PackageDownloader, PackageResolver
11+
from debsbom.download.download import PersistentResolverCache
12+
from debsbom.dpkg.package import BinaryPackage
13+
from debsbom.generate.spdx import spdx_bom
14+
from debsbom.generate.cdx import cyclonedx_bom
15+
from debsbom.snapshot.client import RemoteFile, SnapshotDataLake
16+
17+
import spdx_tools.spdx.writer.json.json_writer as spdx_json_writer
18+
import cyclonedx.output as cdx_output
19+
import cyclonedx.schema as cdx_schema
20+
21+
from unittest import mock
22+
23+
24+
@pytest.fixture()
25+
def spdx_bomfile(tmpdir):
26+
"""
27+
Return the path to a minimal spdx sbom file
28+
"""
29+
pkgs = BinaryPackage.parse_status_file("tests/data/dpkg-status-minimal")
30+
bom = spdx_bom(list(pkgs), "debian")
31+
outfile = Path(tmpdir) / "bom.spdx.json"
32+
spdx_json_writer.write_document_to_file(bom, outfile, False)
33+
return outfile
34+
35+
36+
@pytest.fixture()
37+
def cdx_bomfile(tmpdir):
38+
"""
39+
Return the path to a cdx minimal sbom file
40+
"""
41+
pkgs = BinaryPackage.parse_status_file("tests/data/dpkg-status-minimal")
42+
bom = cyclonedx_bom(list(pkgs), "debian")
43+
outfile = Path(tmpdir) / "bom.cdx.json"
44+
cdx_output.make_outputter(
45+
bom, cdx_schema.OutputFormat.JSON, cdx_schema.SchemaVersion.V1_6
46+
).output_to_file(outfile)
47+
return outfile
48+
49+
50+
def test_download(tmpdir):
51+
dl = PackageDownloader(Path(tmpdir))
52+
test_file = RemoteFile(
53+
hash="d206fa740383de1063a342222bc8c1d1d70b4c05",
54+
filename="dpkg-status-source",
55+
size=770,
56+
archive_name="local",
57+
path="/debian/pool",
58+
first_seen=42,
59+
downloadurl="file://" + str(Path("tests/data/dpkg-status-source").absolute()),
60+
architecture=None,
61+
)
62+
dl.register([test_file])
63+
assert dl.stat() == (1, 770)
64+
mock_cb = mock.Mock()
65+
downloaded = list(dl.download(mock_cb))
66+
mock_cb.assert_called_once_with(0, 1, test_file.filename)
67+
68+
assert len(downloaded) == 1
69+
assert downloaded[0].is_file()
70+
assert downloaded[0].is_relative_to(Path(tmpdir))
71+
stat_orig = downloaded[0].stat()
72+
73+
# now download again (which should not actually download)
74+
dl.register([test_file])
75+
downloaded = list(dl.download(None))
76+
assert downloaded[0].stat().st_mtime == stat_orig.st_mtime
77+
78+
# tamper the checksum of the downloaded file. Must result in re-download
79+
with open(downloaded[0], "w+") as f:
80+
f.write("append")
81+
dl.register([test_file])
82+
downloaded = list(dl.download(None))
83+
assert downloaded[0].stat().st_mtime != stat_orig.st_mtime
84+
85+
86+
def test_package_resolver_parse_spdx(spdx_bomfile):
87+
rs = PackageResolver.create(spdx_bomfile)
88+
assert any(filter(lambda p: p.name == "binutils", rs.sources()))
89+
assert any(filter(lambda p: p.architecture == "amd64", rs.binaries()))
90+
91+
92+
def test_package_resolver_parse_cdx(cdx_bomfile):
93+
rs = PackageResolver.create(cdx_bomfile)
94+
assert any(filter(lambda p: p.architecture == "amd64", rs.binaries()))
95+
96+
97+
@pytest.mark.online
98+
def test_package_resolver_resolve_spdx(spdx_bomfile, tmpdir):
99+
cachedir = Path(tmpdir) / ".cache"
100+
sdl = SnapshotDataLake()
101+
rs = PackageResolver.create(spdx_bomfile)
102+
rs_cache = PersistentResolverCache(cachedir)
103+
104+
files = list(rs.resolve(sdl, next(rs.sources()), rs_cache))
105+
assert "binutils" in files[0].filename
106+
107+
# resolve with cache
108+
files = list(rs.resolve(sdl, next(rs.sources()), rs_cache))
109+
assert "binutils" in files[0].filename

0 commit comments

Comments
 (0)