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

1from importlib import resources 

2import os 

3from pathlib import Path 

4import re 

5import time 

6from typing import Optional, cast 

7 

8from cargo2rpm.metadata import Metadata, FeatureFlags 

9import pytest 

10 

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 

22 

23 

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 

31 

32FIXED_DATE = time.gmtime(12345) 

33 

34 

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] 

50 

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()) 

54 

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() 

60 

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 ) 

80 

81 rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered) 

82 

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) 

86 

87 fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.{target}.spec") 

88 fixture_path = cast(Path, fixture_path) 

89 

90 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover 

91 # helper mode to create test data 

92 fixture_path.write_text(rendered) 

93 

94 else: 

95 expected = fixture_path.read_text() 

96 assert rendered == expected 

97 

98 

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] 

108 

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()) 

112 

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() 

118 

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 ) 

133 

134 rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered) 

135 

136 fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.spec") 

137 fixture_path = cast(Path, fixture_path) 

138 

139 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover 

140 # helper mode to create test data 

141 fixture_path.write_text(rendered) 

142 

143 else: 

144 expected = fixture_path.read_text() 

145 assert rendered == expected 

146 

147 

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] 

161 

162 real_path = resources.files("rust2rpm.tests.samples").joinpath(filename) 

163 metadata = Metadata.from_json(real_path.read_text()) 

164 

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 ) 

182 

183 rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered) 

184 

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) 

188 

189 fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.{target}.spec") 

190 fixture_path = cast(Path, fixture_path) 

191 

192 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover 

193 # helper mode to create test data 

194 fixture_path.write_text(rendered) 

195 

196 else: 

197 expected = fixture_path.read_text() 

198 assert rendered == expected 

199 

200 

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] 

213 

214 real_path = resources.files("rust2rpm.tests.samples").joinpath(filename) 

215 metadata = Metadata.from_json(real_path.read_text()) 

216 

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 ) 

233 

234 rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered) 

235 

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) 

239 

240 fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.{target}.spec") 

241 fixture_path = cast(Path, fixture_path) 

242 

243 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover 

244 # helper mode to create test data 

245 fixture_path.write_text(rendered) 

246 

247 else: 

248 expected = fixture_path.read_text() 

249 assert rendered == expected 

250 

251 

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) 

330 

331 toml_before = before_path.read_text() 

332 patched = preprocess_cargo_toml(toml_before, features) or toml_before 

333 

334 if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover 

335 # helper mode to create / update test fixtures 

336 after_path.write_text(patched) 

337 

338 toml_after = after_path.read_text() 

339 

340 assert patched == toml_after 

341 

342 

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