|
|
838e4d |
import pytest
|
|
|
838e4d |
import yaml
|
|
|
838e4d |
|
|
|
838e4d |
from pathlib import Path
|
|
|
838e4d |
from pprint import pprint
|
|
|
838e4d |
|
|
|
838e4d |
from pyproject_preprocess_record import parse_record, read_record, save_parsed_record
|
|
|
838e4d |
|
|
|
838e4d |
from pyproject_save_files import argparser, generate_file_list, BuildrootPath
|
|
|
838e4d |
from pyproject_save_files import main as save_files_main
|
|
|
838e4d |
|
|
|
838e4d |
DIR = Path(__file__).parent
|
|
|
838e4d |
BINDIR = BuildrootPath("/usr/bin")
|
|
|
838e4d |
DATADIR = BuildrootPath("/usr/share")
|
|
|
838e4d |
SITELIB = BuildrootPath("/usr/lib/python3.7/site-packages")
|
|
|
838e4d |
SITEARCH = BuildrootPath("/usr/lib64/python3.7/site-packages")
|
|
|
838e4d |
|
|
|
838e4d |
yaml_file = DIR / "pyproject_save_files_test_data.yaml"
|
|
|
838e4d |
yaml_data = yaml.safe_load(yaml_file.read_text())
|
|
|
838e4d |
EXPECTED_DICT = yaml_data["classified"]
|
|
|
838e4d |
EXPECTED_FILES = yaml_data["dumped"]
|
|
|
838e4d |
TEST_RECORDS = yaml_data["records"]
|
|
|
838e4d |
TEST_METADATAS = yaml_data["metadata"]
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
@pytest.fixture
|
|
|
838e4d |
def tldr_root(tmp_path):
|
|
|
838e4d |
prepare_pyproject_record(tmp_path, package="tldr")
|
|
|
838e4d |
return tmp_path
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
@pytest.fixture
|
|
|
838e4d |
def pyproject_record(tmp_path):
|
|
|
838e4d |
return tmp_path / "pyproject-record"
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def prepare_pyproject_record(tmp_path, package=None, content=None):
|
|
|
838e4d |
"""
|
|
|
838e4d |
Creates RECORD from test data and then uses
|
|
|
838e4d |
functions from pyproject_process_record to convert
|
|
|
838e4d |
it to pyproject-record file which is then
|
|
|
838e4d |
further processed by functions from pyproject_save_files.
|
|
|
838e4d |
"""
|
|
|
838e4d |
record_file = tmp_path / "RECORD"
|
|
|
838e4d |
pyproject_record = tmp_path / "pyproject-record"
|
|
|
838e4d |
|
|
|
838e4d |
if package is not None:
|
|
|
838e4d |
# Get test data and write dist-info/RECORD file
|
|
|
838e4d |
record_path = BuildrootPath(TEST_RECORDS[package]["path"])
|
|
|
838e4d |
record_file.write_text(TEST_RECORDS[package]["content"])
|
|
|
838e4d |
if package in TEST_METADATAS:
|
|
|
838e4d |
metadata_path = BuildrootPath(TEST_METADATAS[package]["path"]).to_real(tmp_path)
|
|
|
838e4d |
metadata_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
838e4d |
metadata_path.write_text(TEST_METADATAS[package]["content"])
|
|
|
838e4d |
# Parse RECORD file
|
|
|
838e4d |
parsed_record = parse_record(record_path, read_record(record_file))
|
|
|
838e4d |
# Save JSON content to pyproject-record
|
|
|
838e4d |
save_parsed_record(record_path, parsed_record, pyproject_record)
|
|
|
838e4d |
elif content is not None:
|
|
|
838e4d |
save_parsed_record(*content, output_file=pyproject_record)
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
@pytest.fixture
|
|
|
838e4d |
def output(tmp_path):
|
|
|
838e4d |
return tmp_path / "pyproject_files"
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def test_parse_record_tldr():
|
|
|
838e4d |
record_path = BuildrootPath(TEST_RECORDS["tldr"]["path"])
|
|
|
838e4d |
record_content = read_record(DIR / "test_RECORD")
|
|
|
838e4d |
output = list(parse_record(record_path, record_content))
|
|
|
838e4d |
pprint(output)
|
|
|
838e4d |
expected = [
|
|
|
838e4d |
str(BINDIR / "__pycache__/tldr.cpython-37.pyc"),
|
|
|
838e4d |
str(BINDIR / "tldr"),
|
|
|
838e4d |
str(BINDIR / "tldr.py"),
|
|
|
838e4d |
str(SITELIB / "__pycache__/tldr.cpython-37.pyc"),
|
|
|
838e4d |
str(SITELIB / "tldr-0.5.dist-info/INSTALLER"),
|
|
|
838e4d |
str(SITELIB / "tldr-0.5.dist-info/LICENSE"),
|
|
|
838e4d |
str(SITELIB / "tldr-0.5.dist-info/METADATA"),
|
|
|
838e4d |
str(SITELIB / "tldr-0.5.dist-info/RECORD"),
|
|
|
838e4d |
str(SITELIB / "tldr-0.5.dist-info/WHEEL"),
|
|
|
838e4d |
str(SITELIB / "tldr-0.5.dist-info/top_level.txt"),
|
|
|
838e4d |
str(SITELIB / "tldr.py"),
|
|
|
838e4d |
]
|
|
|
838e4d |
assert output == expected
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def test_parse_record_tensorflow():
|
|
|
838e4d |
long = "tensorflow_core/include/tensorflow/core/common_runtime/base_collective_executor.h"
|
|
|
838e4d |
record_path = SITEARCH / "tensorflow-2.1.0.dist-info/RECORD"
|
|
|
838e4d |
record_content = [
|
|
|
838e4d |
["../../../bin/toco_from_protos", "sha256=hello", "289"],
|
|
|
838e4d |
[f"../../../lib/python3.7/site-packages/{long}", "sha256=darkness", "1024"],
|
|
|
838e4d |
["tensorflow-2.1.0.dist-info/METADATA", "sha256=friend", "2859"],
|
|
|
838e4d |
]
|
|
|
838e4d |
output = list(parse_record(record_path, record_content))
|
|
|
838e4d |
pprint(output)
|
|
|
838e4d |
expected = [
|
|
|
838e4d |
str(BINDIR / "toco_from_protos"),
|
|
|
838e4d |
str(SITELIB / long),
|
|
|
838e4d |
str(SITEARCH / "tensorflow-2.1.0.dist-info/METADATA"),
|
|
|
838e4d |
]
|
|
|
838e4d |
assert output == expected
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def remove_others(expected):
|
|
|
838e4d |
return [p for p in expected if not (p.startswith(str(BINDIR)) or p.endswith(".pth") or p.rpartition(' ')[-1].startswith(str(DATADIR)))]
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
@pytest.mark.parametrize("include_auto", (True, False))
|
|
|
838e4d |
@pytest.mark.parametrize("package, glob, expected", EXPECTED_FILES)
|
|
|
838e4d |
def test_generate_file_list(package, glob, expected, include_auto):
|
|
|
838e4d |
paths_dict = EXPECTED_DICT[package]
|
|
|
838e4d |
modules_glob = {glob}
|
|
|
838e4d |
if not include_auto:
|
|
|
838e4d |
expected = remove_others(expected)
|
|
|
838e4d |
tested = generate_file_list(paths_dict, modules_glob, include_auto)
|
|
|
838e4d |
|
|
|
838e4d |
assert tested == expected
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def test_generate_file_list_unused_glob():
|
|
|
838e4d |
paths_dict = EXPECTED_DICT["kerberos"]
|
|
|
838e4d |
modules_glob = {"kerberos", "unused_glob1", "unused_glob2", "kerb*"}
|
|
|
838e4d |
with pytest.raises(ValueError) as excinfo:
|
|
|
838e4d |
generate_file_list(paths_dict, modules_glob, True)
|
|
|
838e4d |
|
|
|
838e4d |
assert "unused_glob1, unused_glob2" in str(excinfo.value)
|
|
|
838e4d |
assert "kerb" not in str(excinfo.value)
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def default_options(output, mock_root, pyproject_record):
|
|
|
838e4d |
return [
|
|
|
838e4d |
"--output",
|
|
|
838e4d |
str(output),
|
|
|
838e4d |
"--buildroot",
|
|
|
838e4d |
str(mock_root),
|
|
|
838e4d |
"--sitelib",
|
|
|
838e4d |
str(SITELIB),
|
|
|
838e4d |
"--sitearch",
|
|
|
838e4d |
str(SITEARCH),
|
|
|
838e4d |
"--python-version",
|
|
|
838e4d |
"3.7", # test data are for 3.7,
|
|
|
838e4d |
"--pyproject-record",
|
|
|
838e4d |
str(pyproject_record)
|
|
|
838e4d |
]
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
@pytest.mark.parametrize("include_auto", (True, False))
|
|
|
838e4d |
@pytest.mark.parametrize("package, glob, expected", EXPECTED_FILES)
|
|
|
838e4d |
def test_cli(tmp_path, package, glob, expected, include_auto, pyproject_record):
|
|
|
838e4d |
prepare_pyproject_record(tmp_path, package)
|
|
|
838e4d |
output = tmp_path / "files"
|
|
|
838e4d |
globs = [glob, "+auto"] if include_auto else [glob]
|
|
|
838e4d |
cli_args = argparser().parse_args([*default_options(output, tmp_path, pyproject_record), *globs])
|
|
|
838e4d |
save_files_main(cli_args)
|
|
|
838e4d |
|
|
|
838e4d |
if not include_auto:
|
|
|
838e4d |
expected = remove_others(expected)
|
|
|
838e4d |
tested = output.read_text()
|
|
|
838e4d |
assert tested == "\n".join(expected) + "\n"
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def test_cli_no_pyproject_record(tmp_path, pyproject_record):
|
|
|
838e4d |
output = tmp_path / "files"
|
|
|
838e4d |
cli_args = argparser().parse_args([*default_options(output, tmp_path, pyproject_record), "tldr*"])
|
|
|
838e4d |
|
|
|
838e4d |
with pytest.raises(FileNotFoundError):
|
|
|
838e4d |
save_files_main(cli_args)
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def test_cli_too_many_RECORDS(tldr_root, output, pyproject_record):
|
|
|
838e4d |
# Two calls to simulate how %pyproject_install process more than one RECORD file
|
|
|
838e4d |
prepare_pyproject_record(tldr_root,
|
|
|
838e4d |
content=("foo/bar/dist-info/RECORD", []))
|
|
|
838e4d |
prepare_pyproject_record(tldr_root,
|
|
|
838e4d |
content=("foo/baz/dist-info/RECORD", []))
|
|
|
838e4d |
cli_args = argparser().parse_args([*default_options(output, tldr_root, pyproject_record), "tldr*"])
|
|
|
838e4d |
|
|
|
838e4d |
with pytest.raises(FileExistsError):
|
|
|
838e4d |
save_files_main(cli_args)
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def test_cli_bad_argument(tldr_root, output, pyproject_record):
|
|
|
838e4d |
cli_args = argparser().parse_args(
|
|
|
838e4d |
[*default_options(output, tldr_root, pyproject_record), "tldr*", "+foodir"]
|
|
|
838e4d |
)
|
|
|
838e4d |
|
|
|
838e4d |
with pytest.raises(ValueError):
|
|
|
838e4d |
save_files_main(cli_args)
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def test_cli_bad_option(tldr_root, output, pyproject_record):
|
|
|
838e4d |
prepare_pyproject_record(tldr_root.parent, content=("RECORD1", []))
|
|
|
838e4d |
cli_args = argparser().parse_args(
|
|
|
838e4d |
[*default_options(output, tldr_root, pyproject_record), "tldr*", "you_cannot_have_this"]
|
|
|
838e4d |
)
|
|
|
838e4d |
|
|
|
838e4d |
with pytest.raises(ValueError):
|
|
|
838e4d |
save_files_main(cli_args)
|
|
|
838e4d |
|
|
|
838e4d |
|
|
|
838e4d |
def test_cli_bad_namespace(tldr_root, output, pyproject_record):
|
|
|
838e4d |
cli_args = argparser().parse_args(
|
|
|
838e4d |
[*default_options(output, tldr_root, pyproject_record), "tldr.didntread"]
|
|
|
838e4d |
)
|
|
|
838e4d |
|
|
|
838e4d |
with pytest.raises(ValueError):
|
|
|
838e4d |
save_files_main(cli_args)
|