|
1 | 1 | import hashlib |
2 | 2 | import io |
| 3 | +import json |
3 | 4 | import os |
4 | 5 | import re |
5 | 6 | import ssl |
|
9 | 10 | import textwrap |
10 | 11 | from os.path import curdir, join, pardir |
11 | 12 | from pathlib import Path |
12 | | -from typing import Dict, Iterable, List, Optional, Tuple |
| 13 | +from typing import Any, Dict, Iterable, List, Optional, Tuple |
13 | 14 |
|
14 | 15 | import pytest |
15 | 16 |
|
@@ -2743,3 +2744,154 @@ def add_link(tar: tarfile.TarFile, name: str, linktype: str, target: str) -> Non |
2743 | 2744 | # Run the internal test |
2744 | 2745 | result = script.run("python", "-m", "linktest") |
2745 | 2746 | assert result.stdout.strip() == "8 files checked" |
| 2747 | + |
| 2748 | + |
| 2749 | +def _check_provenance_url(provenance_url: Dict[str, Any]) -> None: |
| 2750 | + assert "archive_info" in provenance_url |
| 2751 | + assert "url" in provenance_url |
| 2752 | + assert ( |
| 2753 | + len(provenance_url) == 2 |
| 2754 | + ), "provenance_url.json should hold only archive_info and url keys" |
| 2755 | + |
| 2756 | + assert "hashes" in provenance_url["archive_info"] |
| 2757 | + assert len(provenance_url["archive_info"]["hashes"]) > 0 |
| 2758 | + |
| 2759 | + |
| 2760 | +@pytest.mark.parametrize( |
| 2761 | + "pkg_name, pkg_version, distribution", |
| 2762 | + [ |
| 2763 | + pytest.param( |
| 2764 | + "simplewheel", |
| 2765 | + "1.0", |
| 2766 | + "simplewheel-1.0-py2.py3-none-any.whl", |
| 2767 | + id="wheel", |
| 2768 | + ), |
| 2769 | + pytest.param( |
| 2770 | + "simple", |
| 2771 | + "1.0", |
| 2772 | + "simple-1.0.tar.gz", |
| 2773 | + id="sdist", |
| 2774 | + ), |
| 2775 | + ], |
| 2776 | +) |
| 2777 | +def test_install_provenance_url( |
| 2778 | + script: PipTestEnvironment, |
| 2779 | + data: TestData, |
| 2780 | + pkg_name: str, |
| 2781 | + pkg_version: str, |
| 2782 | + distribution: str, |
| 2783 | +) -> None: |
| 2784 | + """Test installing a distribution from a simple API produces provenance_url.json.""" |
| 2785 | + server = make_mock_server() |
| 2786 | + |
| 2787 | + distribution_path = f"/files/{distribution}" |
| 2788 | + server.mock.side_effect = [ |
| 2789 | + package_page( |
| 2790 | + { |
| 2791 | + distribution: distribution_path, |
| 2792 | + } |
| 2793 | + ), |
| 2794 | + file_response(data.packages.joinpath(distribution)), |
| 2795 | + ] |
| 2796 | + |
| 2797 | + index_url = f"http://{server.host}:{server.port}" |
| 2798 | + |
| 2799 | + pip_args = [ |
| 2800 | + "install", |
| 2801 | + "-i", |
| 2802 | + index_url, |
| 2803 | + f"{pkg_name}=={pkg_version}", |
| 2804 | + ] |
| 2805 | + with server_running(server): |
| 2806 | + result = script.pip(*pip_args) |
| 2807 | + |
| 2808 | + result.assert_installed( |
| 2809 | + pkg_name=pkg_name, without_egg_link=True, editable=False |
| 2810 | + ) |
| 2811 | + |
| 2812 | + provenance_url_path = ( |
| 2813 | + script.site_packages |
| 2814 | + / f"{pkg_name}-{pkg_version}.dist-info" |
| 2815 | + / "provenance_url.json" |
| 2816 | + ) |
| 2817 | + |
| 2818 | + assert result.files_created[ |
| 2819 | + provenance_url_path |
| 2820 | + ], "provenance_url.json was not created" |
| 2821 | + |
| 2822 | + provenance_url_full_path = result.files_created[provenance_url_path].full |
| 2823 | + |
| 2824 | + with open(provenance_url_full_path) as f: |
| 2825 | + provenance_url_content = json.load(f) |
| 2826 | + |
| 2827 | + _check_provenance_url(provenance_url_content) |
| 2828 | + assert provenance_url_content["url"] == f"{index_url}{distribution_path}" |
| 2829 | + |
| 2830 | + |
| 2831 | +def test_install_provenance_url_cached( |
| 2832 | + script: PipTestEnvironment, data: TestData |
| 2833 | +) -> None: |
| 2834 | + """Test installing a cached distribution produced provenance_url.json.""" |
| 2835 | + pkg_name = "simple" |
| 2836 | + pkg_version = "1.0" |
| 2837 | + distribution = "simple-1.0.tar.gz" |
| 2838 | + |
| 2839 | + server = make_mock_server() |
| 2840 | + |
| 2841 | + distribution_path = f"/files/{distribution}" |
| 2842 | + server.mock.side_effect = [ |
| 2843 | + package_page( |
| 2844 | + { |
| 2845 | + distribution: distribution_path, |
| 2846 | + } |
| 2847 | + ), |
| 2848 | + file_response(data.packages.joinpath(distribution)), |
| 2849 | + ] * 2 |
| 2850 | + |
| 2851 | + index_url = f"http://{server.host}:{server.port}" |
| 2852 | + |
| 2853 | + pip_args = [ |
| 2854 | + "install", |
| 2855 | + "-i", |
| 2856 | + index_url, |
| 2857 | + f"{pkg_name}=={pkg_version}", |
| 2858 | + ] |
| 2859 | + |
| 2860 | + with server_running(server): |
| 2861 | + result = script.pip(*pip_args) |
| 2862 | + |
| 2863 | + result.assert_installed( |
| 2864 | + pkg_name=pkg_name, without_egg_link=True, editable=False |
| 2865 | + ) |
| 2866 | + |
| 2867 | + provenance_url_path = ( |
| 2868 | + script.site_packages |
| 2869 | + / f"{pkg_name}-{pkg_version}.dist-info" |
| 2870 | + / "provenance_url.json" |
| 2871 | + ) |
| 2872 | + |
| 2873 | + assert result.files_created[ |
| 2874 | + provenance_url_path |
| 2875 | + ], "provenance_url.json was not created" |
| 2876 | + |
| 2877 | + provenance_url_full_path = result.files_created[provenance_url_path].full |
| 2878 | + |
| 2879 | + with open(provenance_url_full_path) as f: |
| 2880 | + provenance_url_content = json.load(f) |
| 2881 | + |
| 2882 | + _check_provenance_url(provenance_url_content) |
| 2883 | + assert provenance_url_content["url"] == f"{index_url}{distribution_path}" |
| 2884 | + |
| 2885 | + os.unlink(provenance_url_full_path) |
| 2886 | + |
| 2887 | + pip_args.append("--ignore-installed") |
| 2888 | + result = script.pip(*pip_args) |
| 2889 | + |
| 2890 | + assert f"Using cached {pkg_name}" in result.stdout |
| 2891 | + |
| 2892 | + assert os.path.exists(provenance_url_full_path) |
| 2893 | + with open(provenance_url_full_path) as f: |
| 2894 | + new_provenance_url_content = json.load(f) |
| 2895 | + |
| 2896 | + _check_provenance_url(new_provenance_url_content) |
| 2897 | + assert new_provenance_url_content == provenance_url_content |
0 commit comments