Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions sssd_test_framework/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import Any, Mapping, Tuple, Type
from typing import Any, Mapping, Self, Tuple, Type

import pytest
from pytest_mh import (
Expand Down Expand Up @@ -99,9 +99,9 @@ def export(self) -> dict:
return d

@classmethod
def _CreateFromArgs(cls, item: pytest.Function, args: Tuple, kwargs: Mapping[str, Any]) -> TopologyMark:
def CreateFromArgs(cls, item: pytest.Function, args: Tuple, kwargs: Mapping[str, Any]) -> Self:
"""
Create :class:`TopologyMark` from pytest marker arguments.
Create :class:`TopologyMark` from pytest.mark.topology arguments.

.. warning::

Expand All @@ -113,7 +113,7 @@ def _CreateFromArgs(cls, item: pytest.Function, args: Tuple, kwargs: Mapping[str
:type item: pytest.Function
:raises ValueError: If the marker is invalid.
:return: Instance of TopologyMark.
:rtype: TopologyMark
:rtype: Self
"""
# First three parameters are positional, the rest are keyword arguments.
if len(args) != 2 and len(args) != 3:
Expand Down
112 changes: 7 additions & 105 deletions sssd_test_framework/hosts/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@

from __future__ import annotations

from abc import ABC, abstractmethod
from pathlib import PurePath
from typing import Any

import ldap
from ldap.ldapobject import ReconnectLDAPObject
from pytest_mh import MultihostHost
from pytest_mh.conn import Powershell
from pytest_mh import MultihostBackupHost, MultihostHost
from pytest_mh.utils.fs import LinuxFileSystem
from pytest_mh.utils.services import SystemdServices

Expand All @@ -18,17 +15,20 @@

__all__ = [
"BaseHost",
"BaseBackupHost",
"BaseDomainHost",
"BaseLDAPDomainHost",
]


class BaseHost(MultihostHost[SSSDMultihostDomain]):
class BaseHost(MultihostBackupHost[SSSDMultihostDomain]):
"""
Base class for all SSSD hosts.
"""

def __init__(self, *args, **kwargs) -> None:
# restore is handled in topology controllers
super().__init__(*args, auto_restore=False, **kwargs)

@property
def features(self) -> dict[str, bool]:
"""
Expand All @@ -37,105 +37,7 @@ def features(self) -> dict[str, bool]:
return {}


class BaseBackupHost(BaseHost, ABC):
"""
Base class for all hosts that supports automatic backup and restore.

A backup of the host is created before starting a test case and all changes
done in the test case to the host are automatically reverted when the test
run is finished.

.. warning::

There might be some limitations on what data can and can not be restored
that depends on particular host. See the documentation of each host
class to learn if a full or partial restoration is done.
"""

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

self.backup_data: Any | None = None
"""Backup data of vanilla state of this host."""

def pytest_setup(self) -> None:
# Make sure required services are running
try:
self.start()
except NotImplementedError:
pass

# Create backup of initial state
self.backup_data = self.backup()

def pytest_teardown(self) -> None:
self.remove_backup(self.backup_data)

def remove_backup(self, backup_data: Any | None) -> None:
"""
Remove backup data from the host.

:param backup_data: Backup data.
:type backup_data: Any | None
"""
if backup_data is None:
return

if isinstance(backup_data, PurePath):
path = str(backup_data)
else:
raise TypeError(f"Only PurePath is supported as backup_data, got {type(backup_data)}")

if isinstance(self.conn.shell, Powershell):
self.conn.exec(["Remove-Item", "-Force", "-Recurse", path])
else:
self.conn.exec(["rm", "-fr", path])

@abstractmethod
def start(self) -> None:
"""
Start required services.

:raises NotImplementedError: If start operation is not supported.
"""
pass

@abstractmethod
def stop(self) -> None:
"""
Stop required services.

:raises NotImplementedError: If stop operation is not supported.
"""
pass

@abstractmethod
def backup(self) -> Any:
"""
Backup backend data.

Returns directory or file path where the backup is stored (as PurePath)
or any Python data relevant for the backup. This data is passed to
:meth:`restore` which will use this information to restore the host to
its original state.

:return: Backup data.
:rtype: Any
"""
pass

@abstractmethod
def restore(self, backup_data: Any | None) -> None:
"""
Restore backend data.

:param backup_data: Backup data.
:type backup_data: Any | None
"""
pass


class BaseDomainHost(BaseBackupHost):
class BaseDomainHost(BaseHost):
"""
Base class for all domain (backend) hosts.

Expand Down
4 changes: 2 additions & 2 deletions sssd_test_framework/hosts/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

from pytest_mh.conn import ProcessLogLevel

from .base import BaseBackupHost, BaseLinuxHost
from .base import BaseHost, BaseLinuxHost

__all__ = [
"ClientHost",
]


class ClientHost(BaseBackupHost, BaseLinuxHost):
class ClientHost(BaseHost, BaseLinuxHost):
"""
SSSD client host object.

Expand Down
4 changes: 2 additions & 2 deletions sssd_test_framework/hosts/nfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

from pytest_mh.conn import ProcessLogLevel

from .base import BaseBackupHost, BaseLinuxHost
from .base import BaseHost, BaseLinuxHost

__all__ = [
"NFSHost",
]


class NFSHost(BaseBackupHost, BaseLinuxHost):
class NFSHost(BaseHost, BaseLinuxHost):
"""
NFS server host object.

Expand Down
Loading