Skip to content

Commit

Permalink
Add tests for list and uninstall (#239)
Browse files Browse the repository at this point in the history
* Start cache

* Tests for uninstall and list
  • Loading branch information
cidrblock authored Aug 5, 2024
1 parent 4c7d994 commit 8e39f14
Show file tree
Hide file tree
Showing 6 changed files with 498 additions and 29 deletions.
3 changes: 3 additions & 0 deletions .config/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ capsys
cauthor
cdescription
cnamespace
collectonly
cpath
crepository
csource
Expand All @@ -21,7 +22,9 @@ platlib
platstdlib
purelib
reqs
sessionstart
setenv
treemaker
usefixtures
XDIST
xmltodict
12 changes: 4 additions & 8 deletions src/ansible_dev_environment/subcommands/lister.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ def __init__(self: Lister, config: Config, output: Output) -> None:
self._output = output

def run(self: Lister) -> None:
"""Run the Lister.
Raises:
TypeError: If the link is not a string.
"""
"""Run the Lister."""
collections = collect_manifests(
target=self._config.site_pkg_collections_path,
venv_cache_dir=self._config.venv_cache_dir,
Expand Down Expand Up @@ -80,10 +76,10 @@ def run(self: Lister) -> None:
homepage = ci.get("homepage")
repository = ci.get("repository")
issues = ci.get("issues")
link = repository or homepage or docs or issues or "http://ansible.com"
link = repository or homepage or docs or issues or "https://ansible.com"
if not isinstance(link, str):
msg = "Link is not a string."
raise TypeError(msg)
self._output.error(err)
link = "https://ansible.com"
fqcn_linked = term_link(
uri=link,
label=fqcn,
Expand Down
35 changes: 17 additions & 18 deletions src/ansible_dev_environment/subcommands/uninstaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,21 @@ def _remove_collection(self: UnInstaller) -> None:
self._output.debug(msg)

collection_namespace_root = self._collection.site_pkg_path.parent
try:
collection_namespace_root.rmdir()
msg = f"Removed collection namespace root: {collection_namespace_root}"
self._output.debug(msg)
except FileNotFoundError:
pass
except OSError as exc:
msg = f"Failed to remove collection namespace root: {exc}"
self._output.debug(msg)

try:
self._config.site_pkg_collections_path.rmdir()
msg = f"Removed collection root: {self._config.site_pkg_collections_path}"
self._output.debug(msg)
except FileNotFoundError:
pass
except OSError as exc:
msg = f"Failed to remove collection root: {exc}"
self._output.debug(msg)
if collection_namespace_root.exists():
try:
collection_namespace_root.rmdir()
msg = f"Removed collection namespace root: {collection_namespace_root}"
self._output.debug(msg)
except OSError as exc:
msg = f"Failed to remove collection namespace root: {exc}"
self._output.debug(msg)

if self._config.site_pkg_collections_path.exists():
try:
self._config.site_pkg_collections_path.rmdir()
msg = f"Removed collection root: {self._config.site_pkg_collections_path}"
self._output.debug(msg)
except OSError as exc:
msg = f"Failed to remove collection root: {exc}"
self._output.debug(msg)
133 changes: 130 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,103 @@
Tracing '/**/src/<package>/__init__.py'
"""

import json
import os
import shutil
import tempfile
import warnings

from collections.abc import Generator
from pathlib import Path
from urllib.request import HTTPError, urlopen

import pytest
import yaml

import ansible_dev_environment # noqa: F401

from ansible_dev_environment.cli import Cli
from ansible_dev_environment.config import Config


GALAXY_CACHE = Path(__file__).parent.parent / ".cache" / ".galaxy_cache"
REQS_FILE_NAME = "requirements.yml"


@pytest.fixture()
def galaxy_cache() -> Path:
"""Return the galaxy cache directory.
Returns:
The galaxy cache directory.
"""
return GALAXY_CACHE


def check_download_collection(name: str, dest: Path) -> None:
"""Download a collection if necessary.
Args:
name: The collection name.
dest: The destination directory.
"""
namespace, name = name.split(".")
base_url = "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections"

url = f"{base_url}/index/{namespace}/{name}/versions/?is_highest=true"
try:
with urlopen(url) as response: # noqa: S310
body = response.read()
except HTTPError:
err = f"Failed to check collection version: {name}"
pytest.fail(err)
with urlopen(url) as response: # noqa: S310
body = response.read()
json_response = json.loads(body)
version = json_response["data"][0]["version"]
file_name = f"{namespace}-{name}-{version}.tar.gz"
file_path = dest / file_name
if file_path.exists():
return
for found_file in dest.glob(f"{namespace}-{name}-*"):
found_file.unlink()
url = f"{base_url}/artifacts/{file_name}"
warnings.warn(f"Downloading collection: {file_name}", stacklevel=0)
try:
with urlopen(url) as response, file_path.open(mode="wb") as file: # noqa: S310
file.write(response.read())
except HTTPError:
err = f"Failed to download collection: {name}"
pytest.fail(err)


def pytest_sessionstart(session: pytest.Session) -> None:
"""Start the server.
Args:
session: The pytest session.
"""
if session.config.option.collectonly:
return

if os.environ.get("PYTEST_XDIST_WORKER"):
return

if not GALAXY_CACHE.exists():
GALAXY_CACHE.mkdir(parents=True, exist_ok=True)

for collection in ("ansible.utils", "ansible.scm", "ansible.posix"):
check_download_collection(collection, GALAXY_CACHE)

reqs: dict[str, list[dict[str, str]]] = {"collections": []}

for found_file in GALAXY_CACHE.glob("*.tar.gz"):
reqs["collections"].append({"name": str(found_file)})

requirements = GALAXY_CACHE / REQS_FILE_NAME
requirements.write_text(yaml.dump(reqs))


@pytest.fixture(name="monkey_session", scope="session")
def fixture_monkey_session() -> Generator[pytest.MonkeyPatch, None, None]:
"""Session scoped monkeypatch fixture.
Expand Down Expand Up @@ -76,9 +159,8 @@ def session_venv(session_dir: Path, monkey_session: pytest.MonkeyPatch) -> Confi
[
"ade",
"install",
"ansible.utils",
"ansible.scm",
"ansible.posix",
"-r",
str(GALAXY_CACHE / REQS_FILE_NAME),
"--venv",
str(venv_path),
"--ll",
Expand All @@ -98,3 +180,48 @@ def session_venv(session_dir: Path, monkey_session: pytest.MonkeyPatch) -> Confi
with pytest.raises(SystemExit):
cli.run()
return cli.config


@pytest.fixture()
def function_venv(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Config:
"""Create a temporary venv for the session.
Add some common collections to the venv.
Since this is a session level fixture, care should be taken to not manipulate it
or the resulting config in a way that would affect other tests.
Args:
tmp_path: Temporary directory.
monkeypatch: Pytest monkeypatch fixture.
Returns:
The configuration object for the venv.
"""
venv_path = tmp_path / "venv"
monkeypatch.setattr(
"sys.argv",
[
"ade",
"install",
"-r",
str(GALAXY_CACHE / REQS_FILE_NAME),
"--venv",
str(venv_path),
"--ll",
"debug",
"--la",
"true",
"--lf",
str(tmp_path / "ade.log"),
"-vvv",
],
)
cli = Cli()
cli.parse_args()
cli.init_output()
cli.args_sanity()
cli.ensure_isolated()
with pytest.raises(SystemExit):
cli.run()
return cli.config
Loading

0 comments on commit 8e39f14

Please sign in to comment.