Source code for univention.testing.ucr

# SPDX-FileCopyrightText: 2013-2025 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

"""
BETA VERSION

Wrapper around Univention Configuration Registry that is able to revert
the UCR status after usage. For usage examples look at the end of this
file.

.. warning::
    changes to the ConfigRegistry object will also trigger the evaluation of templates
    and therefore changes in configuration files created by UCR!

.. warning:: The API is currently under development and may change before next UCS release!
"""


import copy
from types import TracebackType
from typing import Any, Self

import univention.config_registry
from univention.config_registry import ConfigRegistry


[docs] class UCSTestConfigRegistry(ConfigRegistry): """ Extension to ConfigRegistry to be able to clean up after several changes to UCR variables have been done. """ def __init__(self, *args: Any, **kwargs: Any) -> None: """initialise object""" ConfigRegistry.__init__(self, *args, **kwargs) self.__original_registry: dict[int, dict[str, str]] | None = None
[docs] def ucr_update(self, *args): return univention.config_registry.frontend.ucr_update(*args)
[docs] def handler_set(self, *args): return univention.config_registry.handler_set(*args)
[docs] def handler_unset(self, *args): return univention.config_registry.handler_unset(*args)
[docs] def load(self) -> None: """call load() of superclass and save original registry values""" ConfigRegistry.load(self) if self.__original_registry is None: self.__original_registry = { regtype: copy.deepcopy(dict(reg)) for (regtype, reg) in self._walk() }
[docs] def revert_to_original_registry(self) -> None: """revert UCR values back to original state""" # load current values again to perform correct comparison self.load() assert self.__original_registry is not None for regtype, option in ( (ConfigRegistry.NORMAL, ''), (ConfigRegistry.LDAP, 'ldap-policy'), (ConfigRegistry.FORCED, 'force'), (ConfigRegistry.SCHEDULE, 'schedule'), ): # remove new variables keylist = set(self._registry[regtype]) - set(self.__original_registry[regtype]) if keylist: self.handler_unset(list(keylist), {option: True}) # add/revert existing variables changes = [ f'{key}={origval}' for key, origval in self.__original_registry[regtype].items() if origval != self._registry[regtype].get(key) ] if changes: self.handler_set(changes, {option: True}) # load new/original values self.load()
def __enter__(self) -> Self: self.load() return self def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> None: self.revert_to_original_registry()
if __name__ == '__main__': import time # Usage variant 1 "the manual way" print('Loading UCR...') ucr = UCSTestConfigRegistry() ucr.load() print('Setting some variables...') ucr.handler_set(['foo/bar=ding/dong']) ucr.handler_set(['repository/online/server=ftp.debian.org']) ucr.handler_unset(['server/role']) print('Waiting for 3 seconds...') time.sleep(3) print('Cleanup...') ucr.revert_to_original_registry() # Usage variant 2 "with statement" with UCSTestConfigRegistry() as ucr2: print('Old values...') print(ucr2.get('foo/bar', '<unset>')) print(ucr2.get('repository/online/server', '<unset>')) print(ucr2.get('server/role', '<unset>')) print('Setting some variables...') ucr2.handler_set(['foo/bar=ding/dong']) ucr2.handler_set(['repository/online/server=ftp.debian.org']) ucr2.handler_unset(['server/role']) print('Waiting for 3 seconds...') time.sleep(3) print('Cleanup...')