Coverage for rust2rpm/tests/test_generator.py: 98%
100 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-27 15:21 +0100
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-27 15:21 +0100
1from importlib import resources
2import os
3from pathlib import Path
4import re
5import time
6from typing import Optional, cast
8from cargo2rpm.metadata import Metadata, FeatureFlags
9import pytest
11from rust2rpm.conf import TomlConf
12from rust2rpm.generator import (
13 spec_render_crate,
14 spec_render_epel8,
15 spec_render_project,
16 spec_render_workspace,
17 cargo_args_from_flags,
18)
19from rust2rpm.metadata import guess_main_package
20from rust2rpm.patching import preprocess_cargo_toml
21from rust2rpm.utils import package_name_suffixed
24# How to add new tests samples:
25# - find an interesting crate
26# - copy unpatched Cargo.toml to rust2rpm/test/samples/<name>-<version>.toml
27# (i.e. not Cargo.orig.toml and not the patched version after %prep)
28# The license of the crate must allow this, e.g. MIT is fine.
29# - execute PYTHONPATH=. SAVE_SPECS=1 pytest -v rust2rpm/tests/test_generator.py
30# - review output and commit
32FIXED_DATE = time.gmtime(12345)
35@pytest.mark.parametrize(
36 "filename,conf",
37 [
38 ("cxx-build-1.0.71.json", None),
39 ("dotenvy-0.15.6.json", "dotenvy-0.15.7.rust2rpm.toml"),
40 ("glib-sys-0.17.2.json", "glib-sys-0.17.2.rust2rpm.toml"),
41 ("nix-0.24.1.json", "nix-0.24.1.rust2rpm.toml"),
42 ("tokio-1.19.2.json", "tokio-1.19.2.rust2rpm.toml"),
43 ],
44)
45@pytest.mark.parametrize("target", ["plain", "fedora", "mageia", "opensuse"])
46def test_spec_file_render_crate(filename: str, conf: Optional[str], target: str):
47 crate_name_version = filename.removesuffix(".json")
48 crate = crate_name_version.rsplit("-", 1)[0]
49 version = crate_name_version.rsplit("-", 1)[1]
51 rpm_name = package_name_suffixed(crate, None)
52 real_path = resources.files("rust2rpm.tests.samples").joinpath(filename)
53 metadata = Metadata.from_json(real_path.read_text())
55 if conf:
56 toml_path = resources.files("rust2rpm.tests.samples").joinpath(conf)
57 tomlconf = TomlConf.load(str(toml_path), metadata.packages[0].get_feature_names())
58 else:
59 tomlconf = TomlConf()
61 rendered = spec_render_crate(
62 target=target,
63 legacy=False,
64 upstream_version=version,
65 metadata=metadata,
66 rpm_name=rpm_name,
67 compat=False,
68 patch_file_automatic=f"{crate}-patch1.diff",
69 patch_file_manual=f"{crate}-patch2.diff",
70 license_files=["LIC1", "LIC2"],
71 doc_files=["DOC1", "DOC2"],
72 vendor_tarball=None,
73 tomlconf=tomlconf,
74 relative_license_paths=False,
75 rpmautospec=target == "fedora",
76 auto_changelog_entry=True,
77 date=FIXED_DATE,
78 packager="Jane Jane <jane@jane.org>",
79 )
81 rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered)
83 if target == "opensuse":
84 spec_copyright_year = time.strftime("%Y")
85 rendered = re.sub(rf"(Copyright \(c\)) {spec_copyright_year}", r"\1 XXXX", rendered)
87 fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.{target}.spec")
88 fixture_path = cast(Path, fixture_path)
90 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover
91 # helper mode to create test data
92 fixture_path.write_text(rendered)
94 else:
95 expected = fixture_path.read_text()
96 assert rendered == expected
99@pytest.mark.parametrize(
100 "filename,conf",
101 [
102 ("bindgen-cli-0.69.4.json", "bindgen-cli-0.69.4.rust2rpm.toml"),
103 ],
104)
105def test_spec_file_render_epel8(filename: str, conf: Optional[str]):
106 crate_name_version = filename.removesuffix(".json")
107 crate = crate_name_version.rsplit("-", 1)[0]
109 rpm_name = package_name_suffixed(crate, None)
110 real_path = resources.files("rust2rpm.tests.samples").joinpath(filename)
111 metadata = Metadata.from_json(real_path.read_text())
113 if conf: 113 ↛ 117line 113 didn't jump to line 117 because the condition on line 113 was always true
114 toml_path = resources.files("rust2rpm.tests.samples").joinpath(conf)
115 tomlconf = TomlConf.load(str(toml_path), metadata.packages[0].get_feature_names())
116 else:
117 tomlconf = TomlConf()
119 rendered = spec_render_epel8(
120 metadata=metadata,
121 rpm_name=rpm_name,
122 patch_file_automatic=f"{crate}-patch1.diff",
123 patch_file_manual=f"{crate}-patch2.diff",
124 license_files=["LIC1", "LIC2"],
125 doc_files=["DOC1", "DOC2"],
126 vendor_tarball="%{crate}-%{version}-vendor.tar.xz",
127 tomlconf=tomlconf,
128 rpmautospec=True,
129 auto_changelog_entry=True,
130 date=FIXED_DATE,
131 packager="Jane Jane <jane@jane.org>",
132 )
134 rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered)
136 fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.spec")
137 fixture_path = cast(Path, fixture_path)
139 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover
140 # helper mode to create test data
141 fixture_path.write_text(rendered)
143 else:
144 expected = fixture_path.read_text()
145 assert rendered == expected
148@pytest.mark.parametrize(
149 "filename,vendor_tarball",
150 [
151 ("rust2rpm-helper-0.1.3.json", None),
152 ("stgit-2.3.3.json", "stgit-vendor-2.3.3.tar.xz"),
153 ],
154 ids=repr,
155)
156@pytest.mark.parametrize("target", ["plain", "fedora", "mageia", "opensuse"])
157def test_spec_file_render_project(filename: str, vendor_tarball: Optional[str], target: str):
158 crate_name_version = filename.removesuffix(".json")
159 crate = crate_name_version.rsplit("-", 1)[0]
160 version = crate_name_version.rsplit("-", 1)[1]
162 real_path = resources.files("rust2rpm.tests.samples").joinpath(filename)
163 metadata = Metadata.from_json(real_path.read_text())
165 rendered = spec_render_project(
166 target=target,
167 legacy=False,
168 upstream_version=version,
169 metadata=metadata,
170 rpm_name=crate,
171 patch_file_automatic=f"{crate}-patch1.diff",
172 patch_file_manual=f"{crate}-patch2.diff",
173 license_files=["LIC1", "LIC2"],
174 doc_files=["DOC1", "DOC2"],
175 vendor_tarball=vendor_tarball,
176 tomlconf=TomlConf(),
177 rpmautospec=target == "fedora",
178 auto_changelog_entry=True,
179 date=FIXED_DATE,
180 packager="Jane Jane <jane@jane.org>",
181 )
183 rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered)
185 if target == "opensuse":
186 spec_copyright_year = time.strftime("%Y")
187 rendered = re.sub(rf"(Copyright \(c\)) {spec_copyright_year}", r"\1 XXXX", rendered)
189 fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.{target}.spec")
190 fixture_path = cast(Path, fixture_path)
192 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover
193 # helper mode to create test data
194 fixture_path.write_text(rendered)
196 else:
197 expected = fixture_path.read_text()
198 assert rendered == expected
201@pytest.mark.parametrize(
202 "filename,vendor_tarball",
203 [
204 ("system76-keyboard-configurator-1.3.9.json", None),
205 ("zola-0.16.1.json", "zola-0.16.1-vendor.tar.xz"),
206 ],
207)
208@pytest.mark.parametrize("target", ["plain", "fedora", "mageia", "opensuse"])
209def test_spec_file_render_workspace(filename: str, vendor_tarball: Optional[str], target: str):
210 crate_name_version = filename.removesuffix(".json")
211 crate = crate_name_version.rsplit("-", 1)[0]
212 version = crate_name_version.rsplit("-", 1)[1]
214 real_path = resources.files("rust2rpm.tests.samples").joinpath(filename)
215 metadata = Metadata.from_json(real_path.read_text())
217 rendered = spec_render_workspace(
218 metadata=metadata,
219 main_package=guess_main_package(metadata),
220 upstream_version=version,
221 target=target,
222 legacy=False,
223 rpm_name=crate,
224 license_files=["LIC1", "LIC2"],
225 doc_files=["DOC1", "DOC2"],
226 vendor_tarball=vendor_tarball,
227 tomlconf=TomlConf(),
228 rpmautospec=target == "fedora",
229 auto_changelog_entry=True,
230 date=FIXED_DATE,
231 packager="Jane Jane <jane@jane.org>",
232 )
234 rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered)
236 if target == "opensuse":
237 spec_copyright_year = time.strftime("%Y")
238 rendered = re.sub(rf"(Copyright \(c\)) {spec_copyright_year}", r"\1 XXXX", rendered)
240 fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.{target}.spec")
241 fixture_path = cast(Path, fixture_path)
243 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover
244 # helper mode to create test data
245 fixture_path.write_text(rendered)
247 else:
248 expected = fixture_path.read_text()
249 assert rendered == expected
252@pytest.mark.parametrize(
253 "filename,features,expected",
254 [
255 (
256 "cxx-build-1.0.71.toml",
257 {
258 "experimental-async-fn",
259 "parallel",
260 },
261 "cxx-build-1.0.71.toml.patched",
262 ),
263 (
264 "nix-0.24.1.toml",
265 {
266 "acct",
267 "aio",
268 "default",
269 "dir",
270 "env",
271 "event",
272 "feature",
273 "fs",
274 "hostname",
275 "inotify",
276 "ioctl",
277 "kmod",
278 "mman",
279 "mount",
280 "mqueue",
281 "net",
282 "personality",
283 "poll",
284 "process",
285 "pthread",
286 "ptrace",
287 "quota",
288 "reboot",
289 "resource",
290 "sched",
291 "signal",
292 "socket",
293 "term",
294 "time",
295 "ucontext",
296 "uio",
297 "user",
298 "zerocopy",
299 },
300 "nix-0.24.1.toml.patched",
301 ),
302 (
303 "tokio-1.19.2.toml",
304 {
305 "default",
306 "fs",
307 "full",
308 "io-std",
309 "io-util",
310 "macros",
311 "net",
312 "process",
313 "rt",
314 "rt-multi-thread",
315 "signal",
316 "stats",
317 "sync",
318 "test-util",
319 "time",
320 },
321 "tokio-1.19.2.toml.patched",
322 ),
323 ],
324)
325def test_drop_foreign_dependencies(filename: str, features: set[str], expected: str):
326 before_path = resources.files("rust2rpm.tests.samples").joinpath(filename)
327 before_path = cast(Path, before_path)
328 after_path = resources.files("rust2rpm.tests.samples").joinpath(expected)
329 after_path = cast(Path, after_path)
331 toml_before = before_path.read_text()
332 patched = preprocess_cargo_toml(toml_before, features) or toml_before
334 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover
335 # helper mode to create / update test fixtures
336 after_path.write_text(patched)
338 toml_after = after_path.read_text()
340 assert patched == toml_after
343@pytest.mark.parametrize(
344 "flags,required,enabled,expected",
345 [
346 (FeatureFlags(), set(), set(), ""),
347 (FeatureFlags(), {"test"}, set(), " -f test"),
348 (FeatureFlags(features=["test"]), {"test"}, set(), " -f test"),
349 (FeatureFlags(features=["test"]), set(), {"test"}, " -f test"),
350 (FeatureFlags(), {"test"}, {"test"}, ""),
351 (FeatureFlags(), {"test1"}, {"test2"}, " -f test1"),
352 (FeatureFlags(no_default_features=True), {"test"}, set(), " -n -f test"),
353 (FeatureFlags(no_default_features=True, features=["test"]), {"test"}, set(), " -n -f test"),
354 (FeatureFlags(no_default_features=True, features=["test"]), set(), {"test"}, " -n -f test"),
355 (FeatureFlags(no_default_features=True), {"test"}, {"test"}, " -n"),
356 (FeatureFlags(all_features=True), set(), set(), " -a"),
357 (FeatureFlags(no_default_features=True), set(), set(), " -n"),
358 (FeatureFlags(no_default_features=True, features=["test1", "test2"]), set(), set(), " -n -f test1,test2"),
359 ],
360 ids=repr,
361)
362def test_cargo_args_from_flags(flags: FeatureFlags, required: set[str], enabled: set[str], expected: str):
363 assert cargo_args_from_flags(flags, required, enabled) == expected