mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
773245b893
Add typing to the `ctx.obj` object used to store pypeline-specific data while parsing the command-line in click.
181 lines
4.3 KiB
Python
181 lines
4.3 KiB
Python
#
|
|
# This file is distributed under the MIT License. See LICENSE.md for details.
|
|
#
|
|
|
|
import functools
|
|
import shutil
|
|
import sys
|
|
import tarfile
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
import yaml
|
|
from click.testing import CliRunner
|
|
|
|
from revng.pypeline.cli.context import ContextObject
|
|
from revng.pypeline.main import pype
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
|
|
ENV_FILES = ["pipeline.yml", "pipebox.py", "model.yml"]
|
|
|
|
|
|
@pytest.fixture
|
|
def runner() -> CliRunner:
|
|
return CliRunner()
|
|
|
|
|
|
@pytest.fixture(params=["yaml", "tar"])
|
|
def container_format(request):
|
|
return request.param
|
|
|
|
|
|
def setup_env(test_func):
|
|
"""Decorator to setup an isolated filesystem for CLI tests.
|
|
This won't pass the arguments to the pipebox."""
|
|
|
|
@functools.wraps(test_func)
|
|
def wrapped(runner: CliRunner, *args, **kwargs):
|
|
# This is just a chdir to a tmp folder
|
|
with runner.isolated_filesystem():
|
|
# Create the necessary files inside the new filesystem
|
|
for file in ENV_FILES:
|
|
shutil.copyfile(ROOT / file, file)
|
|
# Run the test
|
|
test_func(runner, *args, **kwargs)
|
|
|
|
return wrapped
|
|
|
|
|
|
def run_partial(runner: CliRunner, **kwargs):
|
|
"""Convenience partial function to pre-fill common args"""
|
|
|
|
def run(*args: str):
|
|
result = runner.invoke(cli=pype, args=args, **kwargs)
|
|
if result.exit_code != 0:
|
|
print(result.output, file=sys.stderr)
|
|
assert result.exit_code == 0
|
|
return result
|
|
|
|
return run
|
|
|
|
|
|
def is_tar_file(path: Path) -> bool:
|
|
return tarfile.is_tarfile(path)
|
|
|
|
|
|
def is_yaml_file(path: Path) -> bool:
|
|
try:
|
|
with open(path, "r") as f:
|
|
yaml.safe_load(f)
|
|
return True
|
|
except (yaml.YAMLError, FileNotFoundError):
|
|
return False
|
|
|
|
|
|
def check_file_format(path: Path, expected_format: str):
|
|
if expected_format == "yaml":
|
|
assert is_yaml_file(path), f"File {path} is not a valid yaml file"
|
|
elif expected_format == "tar":
|
|
assert is_tar_file(path), f"File {path} is not a valid tar file"
|
|
else:
|
|
raise ValueError(f"Unknown format: {expected_format}")
|
|
|
|
|
|
@setup_env
|
|
def test_pipeline(runner: CliRunner, container_format: str):
|
|
run = run_partial(
|
|
runner,
|
|
obj=ContextObject.make(pipebox_args=["first pipebox arg", "second pipebox arg"]),
|
|
)
|
|
|
|
# First call some pipes to manually generate some containers
|
|
run(
|
|
"pipeline", "run-pipe", "GeneratorPipe", f"--format={container_format}", "model.yml", "out1"
|
|
)
|
|
check_file_format(Path("out1"), container_format)
|
|
|
|
run(
|
|
"pipeline",
|
|
"run-pipe",
|
|
"InPlacePipe",
|
|
f"--format={container_format}",
|
|
"model.yml",
|
|
"out1",
|
|
"out2",
|
|
)
|
|
check_file_format(Path("out2"), container_format)
|
|
|
|
run(
|
|
"pipeline",
|
|
"run-pipe",
|
|
"ToLowerKindPipe",
|
|
f"--format={container_format}",
|
|
"model.yml",
|
|
"out2",
|
|
"out3",
|
|
)
|
|
check_file_format(Path("out3"), container_format)
|
|
|
|
# Call a couple of analyses
|
|
run(
|
|
"pipeline",
|
|
"run-analysis",
|
|
"NullAnalysis",
|
|
"model.yml",
|
|
"out1",
|
|
)
|
|
|
|
run(
|
|
"pipeline",
|
|
"run-analysis",
|
|
"PurgeAllAnalysis",
|
|
"model.yml",
|
|
"out1",
|
|
)
|
|
|
|
run(
|
|
"pipeline",
|
|
"run-analysis",
|
|
"AddStuffAnalysis",
|
|
"model.yml",
|
|
"out1",
|
|
)
|
|
|
|
|
|
@setup_env
|
|
def test_project(runner: CliRunner, container_format: str):
|
|
run = run_partial(
|
|
runner,
|
|
obj=ContextObject.make(pipebox_args=["first pipebox arg", "second pipebox arg"]),
|
|
)
|
|
|
|
# Compute artifacts
|
|
run(
|
|
"project",
|
|
"artifact",
|
|
"ChildArtifact",
|
|
f"--format={container_format}",
|
|
"-o",
|
|
"child_artifact",
|
|
)
|
|
check_file_format(Path("child_artifact"), container_format)
|
|
|
|
run(
|
|
"project",
|
|
"artifact",
|
|
"RootArtifact",
|
|
f"--format={container_format}",
|
|
"-o",
|
|
"root_artifact",
|
|
)
|
|
check_file_format(Path("root_artifact"), container_format)
|
|
|
|
# Run analysis
|
|
run("project", "analyze", "NullAnalysis")
|
|
run("project", "analyze", "PurgeAllAnalysis")
|
|
run("project", "analyze", "AddStuffAnalysis")
|
|
|
|
# Run an analysis list
|
|
run("project", "analyze", "all_analyses")
|