:mod:`tcs_proxy` -- Proxy to the TCS modules ============================================ Testing code that uses `TCS logging `_ and the `TCS subsystem interface `_ outside of HET is not possible. Therefore one need to create classes that mocks the original and a way to easily switch between the development and the production environment. The :mod:`tcs_lib.tcs_proxy` provides a proxy between an application and the TCS systems. It is a thin layer that initialize the necessary objects and allow easy access to them in a transparent and flexible way. After importing the module:: from tcs_lib import tcs_proxy we must initialize the proxy before being able to use it:: tcs_proxy.init(conf, section='urls') ``conf`` is a `configuration object `_ containing in the section ``section`` all the entries needed to create the logging object and the necessary TCS subsystems. The configuration entries necessary to initialize the proxy are described in :func:`~tcs_lib._tcs_proxy.TCSProxy.init`. An example configuration to use to initialize the logger and two TCS subsystems is: .. code-block:: cfg [urls] # url to use for the TCS logger, if the module implementing it is found tcs_log = tcp://127.0.0.1:5555 # if the TCS logger is not found, use a mock object and use the file of the # next option to configuration the python loggers to used for the mocks tcs_log_mock_path = /path/to/conf_file.cfg # We also want two TCS subsystems called tcs and virus subsystem_names = tcs, virus # the tcs subsystem url. But we don't need the tcs_mock_path since the # configuration is already in ``tcs_log_mock_path`` tcs = tcp://127.0.0.1:5556 # and now the virus subsystem virus = tcp://127.0.0.1:5557 # for virus we might have a difference logger configuration file for the # mock object virus_mock_path = /path/to/virus_logger.cfg After the initialisation, the following attributes become available: * :attr:`tcs_proxy.tcs_log`: this attribute refers either to an instance of :class:`TCSLog.TCSLog` or a wrapper around a standard python logger that exposes the ``log_*`` methods listend in :class:`~tcs_lib._tcs_proxy._MockTCSLog` * :attr:`tcs_proxy.tcs`, :attr:`tcs_proxy.virus`: these attributes refer either to instances of :class:`tcssubsystem.TCSSubSystem` or of a mock class that echoes the method called and their arguments via a standard python logger. Besides those, the TCS proxy exposes also an other attribute: :attr:`tcs_proxy.errors`. If the :mod:`tcssubsystem` is importable, this attribute is an alias of the module itself: i.e. ``tcs_proxy.errors.error`` is equivalent to ``tcssubsystem.error``. If the module is not found, any variable name is associated with :exc:`Exception`: i.e. both ``tcs_proxy.errors.error`` and ``tcs_proxy.errors.MyPersonalError`` are equivalent to :exc:`Exception`. This attribute allows to catch and/or raise TCS exceptions, when available, or generic ones otherwise. As said the mock objects use `python loggers `_ to log messages and method calls, whose names are ``{mod_name}.{name}`` where ``mod_name`` is the value of :attr:`tcs_proxy.mod_name`, defaulting to ``tcs_lib.tcs_proxy``, and ``name`` is either ``tcs_log`` or the name of the TCS subsystem. For other software using the proxy it might be preferable to set the ``mod_name`` **before** initializing it, in order to *own* the loggers. So for a package ``my_package`` I advice to do the following:: from tcs_lib import tcs_proxy tcs_proxy.mod_name = 'my_package.tcs_proxy' tcs_proxy.init(conf, section='urls') The initialised proxies can be cleared using the :meth:`~tcs_lib._tcs_proxy.TCSProxy.clear` function. The TCS proxy will be also marked as not initialized. .. note:: Assigning ``tcs_proxy.mod_name = 'my_package.tcs_proxy'`` after initializing the proxy results in :exc:`AttributeError`. If necessary it is possible to :meth:`~tcs_lib._tcs_proxy.TCSProxy.clear` the proxy, set the ``mod_name`` and then re-initialize. Implementation -------------- .. automodule:: tcs_lib._tcs_proxy :members: :private-members: :show-inheritance: :member-order: bysource :special-members: __call__, __getattr__, __getitem__