Skip to content

Commit

Permalink
Additional images tests (#320)
Browse files Browse the repository at this point in the history
* Additional images tests

* Additional images tests

* Additional images tests

* Fix nav image test

* mo

* Update image

* Fix docker quote

* image determination

* import warnings

* Remove container at start

* Release notes poster

* whoops
  • Loading branch information
cidrblock authored Jul 25, 2024
1 parent c258b3b commit 2ce7a0b
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 51 deletions.
10 changes: 5 additions & 5 deletions .config/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ ansible-navigator==24.7.0
ansible-runner==2.4.0
ansible-sign==0.1.1
asgiref==3.8.1
astroid==3.2.3
astroid==3.2.4
attrs==23.2.0
babel==2.15.0
backports-strenum==1.3.1
beautifulsoup4==4.12.3
bindep==2.11.0
black==24.4.2
Expand Down Expand Up @@ -67,6 +68,7 @@ jsonschema==4.23.0
jsonschema-path==0.3.3
jsonschema-specifications==2023.12.1
lazy-object-proxy==1.10.0
libtmux==0.37.0
linkchecker==10.4.0
lockfile==0.12.2
markdown==3.6
Expand Down Expand Up @@ -117,7 +119,7 @@ ptyprocess==0.7.0
pycparser==2.22
pydoclint==0.5.6
pygments==2.18.0
pylint==3.2.5
pylint==3.2.6
pymdown-extensions==10.8.1
pyproject-api==1.7.1
pyproject-hooks==1.1.0
Expand All @@ -133,14 +135,13 @@ pyyaml-env-tag==0.1
referencing==0.31.1
regex==2024.5.15
requests==2.32.3
requirements-parser==0.9.0
resolvelib==1.0.1
rfc3339-validator==0.1.4
rich==13.7.1
rpds-py==0.19.0
ruamel-yaml==0.18.6
ruamel-yaml-clib==0.2.8
ruff==0.5.2
ruff==0.5.4
six==1.16.0
soupsieve==2.5
sqlparse==0.5.1
Expand All @@ -155,7 +156,6 @@ tox==4.16.0
tox-ansible==24.7.0
types-pyyaml==6.0.12.20240311
types-requests==2.32.0.20240712
types-setuptools==70.3.0.20240710
typing-extensions==4.12.2
tzdata==2024.1
urllib3==2.2.2
Expand Down
1 change: 1 addition & 0 deletions .config/requirements-test.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ansible-dev-tools[server]
black
coverage[toml]
libtmux
mypy
pip-tools
pre-commit
Expand Down
14 changes: 8 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ repos:
)$
- repo: https://github.com/pycontribs/mirrors-prettier
rev: v3.3.2
rev: v3.3.3
hooks:
- id: prettier
always_run: true
Expand All @@ -59,28 +59,28 @@ repos:
- id: tox-ini-fmt

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.0
rev: v0.5.4
hooks:
- id: ruff
args:
- --exit-non-zero-on-fix

- repo: https://github.com/streetsidesoftware/cspell-cli
rev: v8.9.0
rev: v8.11.0
hooks:
- id: cspell
name: Spell check with cspell

- repo: https://github.com/jsh9/pydoclint
rev: "0.5.3"
rev: "0.5.6"
hooks:
- id: pydoclint
# This allows automatic reduction of the baseline file when needed.
entry: sh -ec "pydoclint . && pydoclint --generate-baseline=1 ."
pass_filenames: false

- repo: https://github.com/pycqa/pylint.git
rev: v3.2.4
rev: v3.2.6
hooks:
- id: pylint
args:
Expand All @@ -90,19 +90,21 @@ repos:
- ansible-navigator
- django
- gunicorn
- libtmux
- openapi_core
- pytest
- pyyaml

- repo: https://github.com/pre-commit/mirrors-mypy.git
rev: v1.10.1
rev: v1.11.0
hooks:
- id: mypy
additional_dependencies:
- ansible-creator
- ansible-navigator
- django-stubs[compatible-mypy]
- jinja2
- libtmux
- openapi-core>=0.19.1
- pytest
- types-pyyaml
Expand Down
3 changes: 2 additions & 1 deletion final/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ python3-pyyaml \
python3-ruamel-yaml \
python3-wheel \
--exclude container-selinux \
&& microdnf clean all
&& microdnf clean all \
&& ln -s /usr/bin/vim /usr/bin/vi

RUN useradd podman; \
echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid; \
Expand Down
115 changes: 79 additions & 36 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import subprocess
import sys
import time
import warnings

from collections.abc import Callable
from dataclasses import dataclass
Expand All @@ -33,8 +34,6 @@
import pytest
import requests

from ansible_navigator.utils.packaged_data import ImageEntry

import ansible_dev_tools # noqa: F401


Expand All @@ -55,6 +54,7 @@ class Infrastructure:
only_container: Only container tests
proc: The server process
server: Server required
navigator_ee: The image to use with ansible navigator
"""

session: pytest.Session
Expand All @@ -66,6 +66,7 @@ class Infrastructure:
only_container: bool = False
proc: None | subprocess.Popen[bytes] = None
server: bool = False
navigator_ee: str = ""

def __post_init__(self) -> None:
"""Initialize the infrastructure.
Expand Down Expand Up @@ -236,7 +237,7 @@ def pytest_sessionfinish(session: pytest.Session) -> None:
_stop_server()


PODMAN_CMD = """{container_engine} run -d --rm
BASE_CMD = """{container_engine} run -d --rm
--cap-add=SYS_ADMIN
--cap-add=SYS_RESOURCE
--device "/dev/fuse"
Expand All @@ -247,55 +248,59 @@ def pytest_sessionfinish(session: pytest.Session) -> None:
--security-opt "apparmor=unconfined"
--security-opt "label=disable"
--security-opt "seccomp=unconfined"
--user=root
--userns=host
-v $PWD:/workdir
-v ansible-dev-tools-container-test-storage-podman:/var/lib/containers \
{image_name}
adt server --port 8001 &"""
-v ansible-dev-tools-container-test-storage-podman:/var/lib/containers
"""

DOCKER_CMD = """{container_engine} run -d --rm
--cap-add=SYS_ADMIN
--cap-add=SYS_RESOURCE
--device "/dev/fuse"
-e NO_COLOR=1
--hostname=ansible-dev-container
--name={container_name}
-p 8001:8001
--security-opt "apparmor=unconfined"
--security-opt "label=disable"
--security-opt "seccomp=unconfined"
--user=podman
-v $PWD:/workdir
-v ansible-dev-tools-container-test-storage-docker:/var/lib/containers \
{image_name}
adt server --port 8001"""
PODMAN_CMD = """ --user=root
--userns=host
"""

DOCKER_CMD = """ --user=podman
"""

END = """ {image_name}
adt server --port 8001
"""


def _start_container() -> None:
"""Start the container.
The default image for navigator is pulled ahead of time.
It is determined by the container image name. If the image name
starts with localhost, the default ee for navigator is pulled.
If the image name contains a /, that is used, otherwise the default
ee for navigator is pulled.
Raises:
ValueError: If the container engine is not podman or docker.
"""
cmd = (
f"{INFRASTRUCTURE.container_engine} kill {INFRASTRUCTURE.container_name};"
f"{INFRASTRUCTURE.container_engine} rm {INFRASTRUCTURE.container_name}"
)
subprocess.run(cmd, check=False, capture_output=True, shell=True, text=True)

auth_file = "$XDG_RUNTIME_DIR/containers/auth.json"
auth_mount = ""
if "XDG_RUNTIME_DIR" in os.environ and Path(os.path.expandvars(auth_file)).exists():
auth_mount = f" -v {auth_file}:/run/containers/0/auth.json"

if "podman" in INFRASTRUCTURE.container_engine:
cmd = PODMAN_CMD.format(
container_engine=INFRASTRUCTURE.container_engine,
container_name=INFRASTRUCTURE.container_name,
image_name=INFRASTRUCTURE.image_name,
)
cmd = BASE_CMD + PODMAN_CMD + auth_mount + END
warnings.warn("Podman auth mount added: " + auth_mount, stacklevel=0)
elif "docker" in INFRASTRUCTURE.container_engine:
cmd = DOCKER_CMD.format(
container_engine=INFRASTRUCTURE.container_engine,
container_name=INFRASTRUCTURE.container_name,
image_name=INFRASTRUCTURE.image_name,
)
cmd = BASE_CMD + DOCKER_CMD + END
else:
err = f"Container engine {INFRASTRUCTURE.container_engine} not found."
raise ValueError(err)
cmd = cmd.replace("\n", " ")

cmd = cmd.replace("\n", " ").format(
container_engine=INFRASTRUCTURE.container_engine,
container_name=INFRASTRUCTURE.container_name,
image_name=INFRASTRUCTURE.image_name,
)
try:
subprocess.run(cmd, check=True, capture_output=True, shell=True, text=True)
except subprocess.CalledProcessError as exc:
Expand All @@ -307,10 +312,48 @@ def _start_container() -> None:
)
pytest.fail(err)

nav_ee = ImageEntry.DEFAULT_EE.get(app_name="ansible_navigator")
# image is local, can't be pulled, use default
if INFRASTRUCTURE.image_name.startswith("localhost"):
nav_ee = get_nav_default_ee_in_container()
warning = f"localhost in image name, pulling default {nav_ee} for navigator"
# dots and slashes in image name, use it
elif "/" in INFRASTRUCTURE.image_name and "." in INFRASTRUCTURE.image_name:
nav_ee = INFRASTRUCTURE.image_name
warning = f"/ and . in image name, pulling {nav_ee} for navigator"
# otherwise, use default
else:
nav_ee = get_nav_default_ee_in_container()
warning = f"localhost / . not in image name, pulling default {nav_ee} for navigator"
warnings.warn(warning, stacklevel=0)
INFRASTRUCTURE.navigator_ee = nav_ee
_proc = _exec_container(command=f"podman pull {nav_ee}")


def get_nav_default_ee_in_container() -> str:
"""Get the default ee for navigator in the container.
Returns:
str: The default ee for navigator in the container.
"""
cmd = (
'python -c "from ansible_navigator.utils.packaged_data import ImageEntry;'
'print(ImageEntry.DEFAULT_EE.get(app_name=\\"ansible_navigator\\"))"'
)

proc = _exec_container(cmd)
return proc.stdout.strip()


@pytest.fixture(name="nav_default_ee")
def nav_default_ee() -> str:
"""Get the default ee for navigator in the container.
Returns:
str: The default ee for navigator in the container.
"""
return get_nav_default_ee_in_container()


def _stop_container() -> None:
"""Stop the container."""
cmd = [
Expand Down
Loading

0 comments on commit 2ce7a0b

Please sign in to comment.