Skip to content

Commit

Permalink
Use testcontainers to test ocp_resources, add more test (#2232)
Browse files Browse the repository at this point in the history
* Use testcontainers to test ocp_resources, add more test

* Use testcontainers to test ocp_resources, add more test

* add pytest-cov

* uv update pkgs
  • Loading branch information
myakove authored Dec 15, 2024
1 parent eadfaef commit 821383c
Show file tree
Hide file tree
Showing 5 changed files with 362 additions and 94 deletions.
12 changes: 9 additions & 3 deletions ocp_resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,6 @@ def events(
example: reading all CSV Warning events in namespace "my-namespace", with reason of "AnEventReason"
pod = Pod(client=client, name="pod", namespace="my-namespace")
for event in pod.events(
default_client,
namespace="my-namespace",
field_selector="involvedObject.kind==ClusterServiceVersion,type==Warning,reason=AnEventReason",
timeout=10,
Expand All @@ -1198,12 +1197,18 @@ def events(

@staticmethod
def get_all_cluster_resources(
config_file: str = "", context: str = "", config_dict: Dict[str, Any] | None = None, *args: Any, **kwargs: Any
client: DynamicClient | None = None,
config_file: str = "",
context: str = "",
config_dict: Dict[str, Any] | None = None,
*args: Any,
**kwargs: Any,
) -> Generator[ResourceField, None, None]:
"""
Get all cluster resources
Args:
client (DynamicClient): k8s client
config_file (str): path to a kubeconfig file.
config_dict (dict): dict with kubeconfig configuration.
context (str): name of the context to use.
Expand All @@ -1217,8 +1222,9 @@ def get_all_cluster_resources(
for resource in get_all_cluster_resources(label_selector="my-label=value"):
print(f"Resource: {resource}")
"""
if not client:
client = get_client(config_file=config_file, config_dict=config_dict, context=context)

client = get_client(config_file=config_file, config_dict=config_dict, context=context)
for _resource in client.resources.search():
try:
_resources = client.get(_resource, *args, **kwargs)
Expand Down
75 changes: 46 additions & 29 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,29 +1,44 @@
[tool.pytest.ini_options]
markers = [
"incremental: Mark tests as incremental",
"kubevirt: Mark tests as kubevirt tests"
"kubevirt: Mark tests as kubevirt tests",
]
addopts = [ "--pdbcls=IPython.terminal.debugger:TerminalPdb" ]
addopts = [
"--pdbcls=IPython.terminal.debugger:TerminalPdb",
"--cov-config=pyproject.toml",
"--cov-report=html",
"--cov-report=term",
"--cov=ocp_resources",
]

[tool.coverage.run]
omit = ["tests/*"]

[tool.coverage.report]
skip_empty = true

[tool.coverage.html]
directory = ".tests_coverage"

[tool.ruff]
preview = true
line-length = 120
fix = true
output-format = "grouped"

[tool.ruff.format]
exclude = [ ".git", ".venv", ".mypy_cache", ".tox", "__pycache__" ]
[tool.ruff.format]
exclude = [".git", ".venv", ".mypy_cache", ".tox", "__pycache__"]

[tool.mypy]
no_implicit_optional = true
show_error_codes = true
warn_unused_ignores = true

[tool.hatch.build.targets.wheel]
packages = [ "ocp_resources", "class_generator" ]
packages = ["ocp_resources", "class_generator"]

[tool.uv]
dev-dependencies = [ "ipdb>=0.13.13", "ipython>=8.12.3" ]
dev-dependencies = ["ipdb>=0.13.13", "ipython>=8.12.3"]

[project]
requires-python = ">=3.9"
Expand All @@ -32,10 +47,10 @@ version = "11.0.7"
description = "Wrapper around https://github.com/kubernetes-client/python"
readme = "README.md"
license = "Apache-2.0"
keywords = [ "Openshift", "Kubevirt", "Openshift Virtualization" ]
keywords = ["Openshift", "Kubevirt", "Openshift Virtualization"]
classifiers = [
"Programming Language :: Python :: 3",
"Operating System :: OS Independent"
"Operating System :: OS Independent",
]
dependencies = [
"click>=8.1.7",
Expand All @@ -46,41 +61,43 @@ dependencies = [
"kubernetes>=31.0.0",
"packaging>=24.1",
"pyhelper-utils>=0.0.42",
"pytest-cov>=6.0.0",
"pytest>=8.3.3",
"python-benedict>=0.33.2",
"python-simple-logger>=1.0.40",
"requests>=2.32.3",
"rich>=13.9.2",
"ruff>=0.6.9",
"testcontainers>=4.9.0",
"timeout-sampler>=0.0.46",
"xmltodict>=0.13.0"
"xmltodict>=0.13.0",
]

[[project.authors]]
name = "Meni Yakove"
email = "myakove@gmail.com"
[[project.authors]]
name = "Meni Yakove"
email = "myakove@gmail.com"

[[project.authors]]
name = "Ruth Netser"
email = "rnetser@gmail.com"
[[project.authors]]
name = "Ruth Netser"
email = "rnetser@gmail.com"

[[project.maintainers]]
name = "Meni Yakove"
email = "myakove@gmail.com"
[[project.maintainers]]
name = "Meni Yakove"
email = "myakove@gmail.com"

[[project.maintainers]]
name = "Ruth Netser"
email = "rnetser@gmail.com"
[[project.maintainers]]
name = "Ruth Netser"
email = "rnetser@gmail.com"

[project.urls]
homepage = "https://github.com/RedHatQE/openshift-python-wrapper"
documentation = "https://openshift-python-wrapper.readthedocs.io/en/latest/"
Download = "https://pypi.org/project/openshift-python-wrapper/"
"Bug Tracker" = "https://github.com/RedHatQE/openshift-python-wrapper/issues"
[project.urls]
homepage = "https://github.com/RedHatQE/openshift-python-wrapper"
documentation = "https://openshift-python-wrapper.readthedocs.io/en/latest/"
Download = "https://pypi.org/project/openshift-python-wrapper/"
"Bug Tracker" = "https://github.com/RedHatQE/openshift-python-wrapper/issues"

[project.scripts]
class-generator = "class_generator.class_generator:main"
[project.scripts]
class-generator = "class_generator.class_generator:main"

[build-system]
requires = [ "hatchling" ]
requires = ["hatchling"]
build-backend = "hatchling.build"
83 changes: 64 additions & 19 deletions tests/test_resources.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,84 @@
import kubernetes
import pytest
from kubernetes.dynamic import DynamicClient

from ocp_resources.namespace import Namespace
from ocp_resources.virtual_machine import VirtualMachine
from tests.utils import generate_yaml_from_template
from ocp_resources.pod import Pod
from ocp_resources.resource import Resource, get_client
import yaml
from testcontainers.k3s import K3SContainer


@pytest.fixture(scope="session")
def client():
return DynamicClient(client=kubernetes.config.new_client_from_config())
with K3SContainer() as k3s:
yield get_client(config_dict=yaml.safe_load(k3s.config_yaml()))


@pytest.fixture(scope="session")
def namespace():
return Namespace(name="test-namespace")
@pytest.fixture(scope="class")
def namespace(client):
return Namespace(client=client, name="test-namespace")


@pytest.fixture(scope="class")
def pod(client):
yield list(Pod.get(dyn_client=client))[0]


@pytest.mark.incremental
class TestNamespace:
class TestResource:
def test_get(self, client):
for ns in Namespace.get(dyn_client=client):
assert ns.name

def test_create(self, namespace):
namespace.create()
ns = namespace.deploy()
assert ns

def test_kind(self, namespace):
assert namespace.kind == "Namespace"

def test_exists(self, namespace):
assert namespace.exists

def test_instance(self, namespace):
assert namespace.instance

def test_wait_for_condition(self, pod):
pod.wait_for_condition(condition=pod.Condition.READY, status=pod.Condition.Status.FALSE, timeout=5)

def test_wait_for_conditions(self, pod):
pod.wait_for_conditions()

def test_events(self, pod):
events = list(pod.events(timeout=1))
assert events

def test_get_all_cluster_resources(self, client):
for _resources in Resource.get_all_cluster_resources(client=client):
if _resources:
break

def test_get_condition_message(self, pod):
assert pod.get_condition_message(
condition_type=pod.Condition.READY, condition_status=pod.Condition.Status.FALSE
)

def test_wait(self, namespace):
namespace.wait_for_status(status=Namespace.Status.ACTIVE, timeout=30)

def test_get(self, client, namespace):
Namespace.get(name=namespace.name, dyn_client=client)
def test_status(self, namespace):
assert namespace.status == Namespace.Status.ACTIVE

def test_delete(self, namespace):
namespace.delete(wait=True)
def test_update(self, namespace):
ns_dict = namespace.instance.to_dict()
ns_dict["metadata"]["labels"].update({"test": "test"})
namespace.update(resource_dict=ns_dict)
assert namespace.labels["test"] == "test"

def test_update_replace(self, namespace):
ns_dict = namespace.instance.to_dict()
ns_dict["metadata"]["labels"].pop("test")
namespace.update_replace(resource_dict=ns_dict)
assert "test" not in namespace.labels.keys()

@pytest.mark.kubevirt
def test_vm(namespace):
name = "test-vm"
with VirtualMachine(name=name, namespace=namespace.name, body=generate_yaml_from_template(name=name)):
pass
def test_cleanup(self, namespace):
namespace.clean_up(wait=False)
16 changes: 2 additions & 14 deletions tox.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,14 @@ env_list = [
"class-generator",
"resource-tests",
"api-group-order",
"validate-unittests"
"validate-unittests",
]

[env.resource-tests]
description = "Run resource tests on local cluster (k3d)"
passenv = ["KUBECONFIG"]
deps = ["uv"]
commands_pre = [["scripts/k3d-runner.sh", "start"]]
commands = [
[
"uv",
"run",
"pytest",
"tests/test_resources.py",
"-k",
"not kubevirt",
],
]
commands_post = [["scripts/k3d-runner.sh", "stop"]]
allowlist_externals = ["scripts/k3d-runner.sh"]
commands = [["uv", "run", "pytest", "tests/test_resources.py"]]

[env.validate-resources]
description = "Run validation resources tests"
Expand Down
Loading

0 comments on commit 821383c

Please sign in to comment.