def run_step(step, catalog):
    """Run an end-to-end test step with a command and expected output."""
    result = subprocess.run(  # noqa: S603
        step["command"],
        shell=False,
        capture_output=True,
        check=True,
        encoding="utf-8",
        env={
            **os.environ,
            "DATACHAIN__METASTORE": catalog.metastore.serialize(),
            "DATACHAIN__WAREHOUSE": catalog.warehouse.serialize(),
        },
    )
    if step.get("sort_expected_lines"):
        assert sorted(result.stdout.split("\n")) == sorted(
            step["expected"].lstrip("\n").split("\n")
        )
    else:
        assert result.stdout.strip("\n") == step["expected"].strip("\n")
    if step.get("listing"):
        assert "Listing" in result.stderr
    else:
        assert "Listing" not in result.stderr
    if step.get("downloading"):
        assert "Downloading" in result.stderr
    else:
        assert "Downloading" not in result.stderr
    if step.get("instantiating"):
        assert "Instantiating" in result.stderr
    else:
        assert "Instantiating" not in result.stderr
    files = step.get("files")
    if files:
        verify_files(files)
Run an end-to-end test step with a command and expected output.
tests/test_cli_e2e.py