|
11 | 11 |
|
12 | 12 | from pypi_simple import ProjectPage |
13 | 13 | from packaging.version import parse |
14 | | -from urllib.parse import urljoin, urlsplit |
| 14 | +from urllib.parse import urljoin, urlsplit, urlunsplit |
15 | 15 | from random import sample |
| 16 | +from hashlib import sha256 |
16 | 17 |
|
17 | 18 |
|
18 | 19 | def test_pull_through_install( |
@@ -202,3 +203,85 @@ def test_pull_through_filtering_bad_names(python_remote_factory, python_distribu |
202 | 203 | # Should have no packages with None version (they get filtered out) |
203 | 204 | assert len(project_page.packages) > 0 |
204 | 205 | assert all(package.version is not None for package in project_page.packages) |
| 206 | + |
| 207 | + |
| 208 | +@pytest.mark.parallel |
| 209 | +def test_pull_through_metadata(python_remote_factory, python_distribution_factory): |
| 210 | + """ |
| 211 | + Tests that metadata is correctly served when using pull-through. |
| 212 | +
|
| 213 | + So when requesting the metadata url according to PEP 658 you should just need to add .metadata |
| 214 | + to the end of the url path. Since pull-through includes a redirect query parameter we need to |
| 215 | + test adding .metadata to the end of the url path vs adding it to the end of redirect query. |
| 216 | + """ |
| 217 | + remote = python_remote_factory(includes=["pytz"]) |
| 218 | + distro = python_distribution_factory(remote=remote.pulp_href) |
| 219 | + |
| 220 | + url = f"{distro.base_url}simple/pytz/" |
| 221 | + project_page = ProjectPage.from_response(requests.get(url), "pytz") |
| 222 | + filename1 = "pytz-2023.2-py2.py3-none-any.whl" |
| 223 | + filename2 = "pytz-2023.3-py2.py3-none-any.whl" |
| 224 | + package1 = next(p for p in project_page.packages if p.filename == filename1) |
| 225 | + package2 = next(p for p in project_page.packages if p.filename == filename2) |
| 226 | + assert package1.has_metadata |
| 227 | + assert package2.has_metadata |
| 228 | + |
| 229 | + # The correct way to get the metadata url: add to path (uv does this) |
| 230 | + parts1 = urlsplit(package1.url) |
| 231 | + url1 = urlunsplit((parts1[0], parts1[1], parts1[2] + ".metadata", parts1[3], parts1[4])) |
| 232 | + r = requests.get(url1) |
| 233 | + assert r.status_code == 200 |
| 234 | + assert sha256(r.content).hexdigest() == package1.metadata_digests["sha256"] |
| 235 | + |
| 236 | + # The incorrect way to get the metadata url: add to end of string (pip does this) |
| 237 | + url2 = package2.url + ".metadata" |
| 238 | + r = requests.get(url2) |
| 239 | + assert r.status_code == 200 |
| 240 | + assert sha256(r.content).hexdigest() == package2.metadata_digests["sha256"] |
| 241 | + |
| 242 | + |
| 243 | +@pytest.mark.parallel |
| 244 | +def test_pull_through_metadata_with_repo( |
| 245 | + python_repo_factory, |
| 246 | + python_remote_factory, |
| 247 | + python_distribution_factory, |
| 248 | + pulpcore_bindings, |
| 249 | +): |
| 250 | + """Tests that metadata is correctly saved when using pull-through with a repository.""" |
| 251 | + remote = python_remote_factory(url=PYPI_URL, includes=["pip"]) |
| 252 | + repo = python_repo_factory() |
| 253 | + distro = python_distribution_factory(repository=repo.pulp_href, remote=remote.pulp_href) |
| 254 | + |
| 255 | + pip_url = f"{distro.base_url}simple/pip/" |
| 256 | + project_page = ProjectPage.from_response(requests.get(pip_url), "pip") |
| 257 | + filename = "pip-26.0.1-py3-none-any.whl" |
| 258 | + package = next(p for p in project_page.packages if p.filename == filename) |
| 259 | + assert package.has_metadata |
| 260 | + assert "?redirect=" in package.url |
| 261 | + |
| 262 | + # Retrieve the metadata and assert the content was not saved to the repository |
| 263 | + parts = urlsplit(package.url) |
| 264 | + url = urlunsplit((parts[0], parts[1], parts[2] + ".metadata", parts[3], parts[4])) |
| 265 | + r = requests.get(url) |
| 266 | + assert r.status_code == 200 |
| 267 | + assert sha256(r.content).hexdigest() == package.metadata_digests["sha256"] |
| 268 | + project_page = ProjectPage.from_response(requests.get(pip_url), "pip") |
| 269 | + package = next(p for p in project_page.packages if p.filename == filename) |
| 270 | + assert package.has_metadata |
| 271 | + assert "?redirect=" in package.url |
| 272 | + |
| 273 | + # Now retrieve the package and assert the content was saved with metadata |
| 274 | + r = requests.get(package.url) |
| 275 | + assert r.status_code == 200 |
| 276 | + pa = pulpcore_bindings.ArtifactsApi.list(sha256=package.digests["sha256"]) |
| 277 | + assert pa.count == 1 |
| 278 | + ma = pulpcore_bindings.ArtifactsApi.list(sha256=package.metadata_digests["sha256"]) |
| 279 | + assert ma.count == 1 |
| 280 | + |
| 281 | + # Check the simple page is updated to point to the local repository |
| 282 | + project_page = ProjectPage.from_response(requests.get(pip_url), "pip") |
| 283 | + package = next(p for p in project_page.packages if p.filename == filename) |
| 284 | + assert "?redirect=" not in package.url |
| 285 | + r = requests.get(package.metadata_url) |
| 286 | + assert r.status_code == 200 |
| 287 | + assert sha256(r.content).hexdigest() == package.metadata_digests["sha256"] |
0 commit comments