From ead0eae5f0085884ce5d7b9dc3e34406e4860c50 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Thu, 26 Nov 2020 11:20:21 +0100 Subject: [PATCH 01/14] Improved hosting --- .../configuration/base/configuration_base.py | 1 - src/sh_edraft/configuration/configuration.py | 2 ++ src/sh_edraft/hosting/__init__.py | 1 + src/sh_edraft/hosting/application_host.py | 18 ++++++++++--- src/sh_edraft/hosting/base/__init__.py | 1 + .../hosting/base/application_host_base.py | 16 ++++++++++++ .../hosting/base/environment_base.py | 25 +++++++++++++++++++ src/sh_edraft/hosting/hosting_environment.py | 20 +++++++++++++++ src/sh_edraft/hosting/model/__init__.py | 2 ++ .../hosting/model/environment_name.py | 9 +++++++ src/sh_edraft/logging/base/logger_base.py | 8 +----- src/sh_edraft/logging/logger.py | 11 ++++---- .../publishing/base/publisher_base.py | 7 +----- src/sh_edraft/publishing/model/__init__.py | 2 ++ src/sh_edraft/publishing/publisher.py | 5 +++- src/sh_edraft/service/service_provider.py | 10 +++++--- src/tests/logging/logger.py | 6 ++--- src/tests/publishing/publisher.py | 9 +++---- .../service_providing/service_provider.py | 8 +++--- 19 files changed, 124 insertions(+), 37 deletions(-) create mode 100644 src/sh_edraft/hosting/base/environment_base.py create mode 100644 src/sh_edraft/hosting/hosting_environment.py create mode 100644 src/sh_edraft/hosting/model/environment_name.py diff --git a/src/sh_edraft/configuration/base/configuration_base.py b/src/sh_edraft/configuration/base/configuration_base.py index 4db03091..03d74dd6 100644 --- a/src/sh_edraft/configuration/base/configuration_base.py +++ b/src/sh_edraft/configuration/base/configuration_base.py @@ -10,7 +10,6 @@ class ConfigurationBase(ServiceBase): @abstractmethod def __init__(self): ServiceBase.__init__(self) - self._config: dict[type, object] = {} @property @abstractmethod diff --git a/src/sh_edraft/configuration/configuration.py b/src/sh_edraft/configuration/configuration.py index 67140807..b3743aff 100644 --- a/src/sh_edraft/configuration/configuration.py +++ b/src/sh_edraft/configuration/configuration.py @@ -9,6 +9,8 @@ class Configuration(ConfigurationBase): def __init__(self): super().__init__() + self._config: dict[type, object] = {} + @property def config(self): return self._config diff --git a/src/sh_edraft/hosting/__init__.py b/src/sh_edraft/hosting/__init__.py index ceeb2b0e..2a8b8615 100644 --- a/src/sh_edraft/hosting/__init__.py +++ b/src/sh_edraft/hosting/__init__.py @@ -1,3 +1,4 @@ # imports: from .application_host import ApplicationHost +from .hosting_environment import HostingEnvironment diff --git a/src/sh_edraft/hosting/application_host.py b/src/sh_edraft/hosting/application_host.py index f9b8fbf9..0316a2f2 100644 --- a/src/sh_edraft/hosting/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -1,17 +1,29 @@ from datetime import datetime from sh_edraft.hosting.base.application_host_base import ApplicationHostBase +from sh_edraft.hosting.base.environment_base import EnvironmentBase from sh_edraft.service.service_provider import ServiceProvider class ApplicationHost(ApplicationHostBase): - - def __init__(self): + + def __init__(self, name: str, env: EnvironmentBase): ApplicationHostBase.__init__(self) - self._services = ServiceProvider() + self._name: str = name + self._environment: EnvironmentBase = env + + self._services = ServiceProvider(self) self._start_time: datetime = datetime.now() self._end_time: datetime = datetime.now() + @property + def name(self) -> str: + return self._name + + @property + def environment(self) -> EnvironmentBase: + return self._environment + @property def services(self): return self._services diff --git a/src/sh_edraft/hosting/base/__init__.py b/src/sh_edraft/hosting/base/__init__.py index 96c21b77..cc2f2b01 100644 --- a/src/sh_edraft/hosting/base/__init__.py +++ b/src/sh_edraft/hosting/base/__init__.py @@ -1,2 +1,3 @@ # imports: from .application_host_base import ApplicationHostBase +from .environment_base import EnvironmentBase diff --git a/src/sh_edraft/hosting/base/application_host_base.py b/src/sh_edraft/hosting/base/application_host_base.py index 20dbd9a5..3e735665 100644 --- a/src/sh_edraft/hosting/base/application_host_base.py +++ b/src/sh_edraft/hosting/base/application_host_base.py @@ -1,17 +1,28 @@ from abc import ABC, abstractmethod from datetime import datetime +from sh_edraft.hosting.base.environment_base import EnvironmentBase + class ApplicationHostBase(ABC): @abstractmethod def __init__(self): pass + + @property + @abstractmethod + def name(self) -> str: pass + + @property + @abstractmethod + def environment(self) -> EnvironmentBase: pass @property @abstractmethod def start_time(self) -> datetime: pass @start_time.setter + @abstractmethod def start_time(self, start_time: datetime): pass @property @@ -19,4 +30,9 @@ class ApplicationHostBase(ABC): def end_time(self): pass @end_time.setter + @abstractmethod def end_time(self, end_time: datetime): pass + + @property + @abstractmethod + def date_time_now(self) -> datetime: pass diff --git a/src/sh_edraft/hosting/base/environment_base.py b/src/sh_edraft/hosting/base/environment_base.py new file mode 100644 index 00000000..99cfaa18 --- /dev/null +++ b/src/sh_edraft/hosting/base/environment_base.py @@ -0,0 +1,25 @@ +from abc import ABC, abstractmethod + +from sh_edraft.hosting.model.environment_name import EnvironmentName + + +class EnvironmentBase(ABC): + + @abstractmethod + def __init__(self): pass + + @property + @abstractmethod + def name(self) -> EnvironmentName: pass + + @name.setter + @abstractmethod + def name(self, name: EnvironmentName): pass + + @property + @abstractmethod + def content_root_path(self) -> str: pass + + @content_root_path.setter + @abstractmethod + def content_root_path(self, content_root_path: str): pass diff --git a/src/sh_edraft/hosting/hosting_environment.py b/src/sh_edraft/hosting/hosting_environment.py new file mode 100644 index 00000000..c771cf81 --- /dev/null +++ b/src/sh_edraft/hosting/hosting_environment.py @@ -0,0 +1,20 @@ +from sh_edraft.hosting.base.environment_base import EnvironmentBase +from sh_edraft.hosting.model.environment_name import EnvironmentName + + +class HostingEnvironment(EnvironmentBase): + + def __init__(self, name: EnvironmentName, crp: str): + EnvironmentBase.__init__(self) + + self._name = name + self._content_root_path = crp + + @property + def name(self) -> EnvironmentName: + return self._name + + @property + def content_root_path(self) -> str: + return self._content_root_path + diff --git a/src/sh_edraft/hosting/model/__init__.py b/src/sh_edraft/hosting/model/__init__.py index e69de29b..b8692da2 100644 --- a/src/sh_edraft/hosting/model/__init__.py +++ b/src/sh_edraft/hosting/model/__init__.py @@ -0,0 +1,2 @@ +# imports: +from .environment_name import EnvironmentName \ No newline at end of file diff --git a/src/sh_edraft/hosting/model/environment_name.py b/src/sh_edraft/hosting/model/environment_name.py new file mode 100644 index 00000000..18abcbb5 --- /dev/null +++ b/src/sh_edraft/hosting/model/environment_name.py @@ -0,0 +1,9 @@ +from enum import Enum + + +class EnvironmentName(Enum): + + production = 'production' + staging = 'staging' + testing = 'testing' + development = 'development' diff --git a/src/sh_edraft/logging/base/logger_base.py b/src/sh_edraft/logging/base/logger_base.py index 47949898..2dc5de50 100644 --- a/src/sh_edraft/logging/base/logger_base.py +++ b/src/sh_edraft/logging/base/logger_base.py @@ -1,20 +1,14 @@ from abc import abstractmethod -from sh_edraft.hosting.application_host import ApplicationHost -from sh_edraft.logging.model.logging_settings import LoggingSettings from sh_edraft.service.base.service_base import ServiceBase -from sh_edraft.time.model.time_format_settings import TimeFormatSettings class LoggerBase(ServiceBase): @abstractmethod - def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings): + def __init__(self): ServiceBase.__init__(self) - self._log_settings: LoggingSettings = logging_settings - self._time_format_settings: TimeFormatSettings = time_format - @abstractmethod def header(self, string: str): pass diff --git a/src/sh_edraft/logging/logger.py b/src/sh_edraft/logging/logger.py index f7a0a361..6305725a 100644 --- a/src/sh_edraft/logging/logger.py +++ b/src/sh_edraft/logging/logger.py @@ -1,10 +1,9 @@ import datetime import os import traceback -from collections import Callable from string import Template -from sh_edraft.hosting.application_host import ApplicationHost +from sh_edraft.hosting.base import ApplicationHostBase from sh_edraft.logging.base.logger_base import LoggerBase from sh_edraft.logging.model import LoggingSettings from sh_edraft.logging.model.logging_level import LoggingLevel @@ -14,10 +13,12 @@ from sh_edraft.utils.console import Console class Logger(LoggerBase): - def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_host: ApplicationHost): - LoggerBase.__init__(self, logging_settings, time_format) + def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_host: ApplicationHostBase): + LoggerBase.__init__(self) - self._app_host: ApplicationHost = app_host + self._log_settings: LoggingSettings = logging_settings + self._time_format_settings: TimeFormatSettings = time_format + self._app_host = app_host self._log = Template(self._log_settings.filename).substitute( date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), diff --git a/src/sh_edraft/publishing/base/publisher_base.py b/src/sh_edraft/publishing/base/publisher_base.py index f2038018..f3f899ca 100644 --- a/src/sh_edraft/publishing/base/publisher_base.py +++ b/src/sh_edraft/publishing/base/publisher_base.py @@ -1,19 +1,14 @@ from abc import abstractmethod -from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.publishing.model.publish_settings_model import PublishSettingsModel from sh_edraft.service.base.service_base import ServiceBase class PublisherBase(ServiceBase): @abstractmethod - def __init__(self, logger: LoggerBase, publish_settings: PublishSettingsModel): + def __init__(self): ServiceBase.__init__(self) - self._logger: LoggerBase = logger - self._publish_settings: PublishSettingsModel = publish_settings - @property @abstractmethod def source_path(self) -> str: pass diff --git a/src/sh_edraft/publishing/model/__init__.py b/src/sh_edraft/publishing/model/__init__.py index 91e2bd18..4017b71c 100644 --- a/src/sh_edraft/publishing/model/__init__.py +++ b/src/sh_edraft/publishing/model/__init__.py @@ -22,6 +22,8 @@ from collections import namedtuple # imports: from .template import Template from .template_enum import TemplateEnum +from .publish_settings_model import PublishSettingsModel +from .publish_settings_name import PublishSettingsName VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=5) diff --git a/src/sh_edraft/publishing/publisher.py b/src/sh_edraft/publishing/publisher.py index 1e7f55e6..573c11f5 100644 --- a/src/sh_edraft/publishing/publisher.py +++ b/src/sh_edraft/publishing/publisher.py @@ -11,7 +11,10 @@ from sh_edraft.publishing.model.template import Template class Publisher(PublisherBase): def __init__(self, logger: LoggerBase, publish_settings: PublishSettingsModel): - super().__init__(logger, publish_settings) + PublisherBase.__init__(self) + + self._logger: LoggerBase = logger + self._publish_settings: PublishSettingsModel = publish_settings @property def source_path(self) -> str: diff --git a/src/sh_edraft/service/service_provider.py b/src/sh_edraft/service/service_provider.py index 66cb567e..2467ec46 100644 --- a/src/sh_edraft/service/service_provider.py +++ b/src/sh_edraft/service/service_provider.py @@ -11,8 +11,9 @@ from sh_edraft.service.base.service_base import ServiceBase class ServiceProvider(ServiceProviderBase): - def __init__(self): + def __init__(self, app_host: ApplicationHostBase): super().__init__() + self._app_host: ApplicationHostBase = app_host self._config = Configuration() @property @@ -27,10 +28,13 @@ class ServiceProvider(ServiceProviderBase): for param in sig.parameters.items(): parameter = param[1] if parameter.name != 'self' and parameter.annotation != Parameter.empty: - if issubclass(parameter.annotation, ServiceBase): + if issubclass(parameter.annotation, ApplicationHostBase): + params.append(self._app_host) + + elif issubclass(parameter.annotation, ServiceBase): params.append(self.get_service(parameter.annotation)) - elif issubclass(parameter.annotation, ConfigurationModelBase) or issubclass(parameter.annotation, ApplicationHostBase): + elif issubclass(parameter.annotation, ConfigurationModelBase): params.append(self._config.get_config_by_type(parameter.annotation)) return service(*params) diff --git a/src/tests/logging/logger.py b/src/tests/logging/logger.py index 37ea1346..d7222426 100644 --- a/src/tests/logging/logger.py +++ b/src/tests/logging/logger.py @@ -1,10 +1,10 @@ import os import shutil import unittest -from datetime import datetime from string import Template -from sh_edraft.hosting import ApplicationHost +from sh_edraft.hosting import ApplicationHost, HostingEnvironment +from sh_edraft.hosting.model import EnvironmentName from sh_edraft.logging import Logger from sh_edraft.logging.model import LoggingSettings from sh_edraft.time.model import TimeFormatSettings @@ -13,7 +13,7 @@ from sh_edraft.time.model import TimeFormatSettings class LoggerTest(unittest.TestCase): def setUp(self): - self._app_host = ApplicationHost() + self._app_host = ApplicationHost('CPL_Test', HostingEnvironment(EnvironmentName.testing, './')) self._services = self._app_host.services self._services.create() diff --git a/src/tests/publishing/publisher.py b/src/tests/publishing/publisher.py index ff64d0ae..cb721a41 100644 --- a/src/tests/publishing/publisher.py +++ b/src/tests/publishing/publisher.py @@ -2,14 +2,13 @@ import os import shutil import unittest -from sh_edraft.hosting import ApplicationHost +from sh_edraft.hosting import ApplicationHost, HostingEnvironment +from sh_edraft.hosting.model import EnvironmentName from sh_edraft.logging import Logger -from sh_edraft.logging.base import LoggerBase from sh_edraft.logging.model import LoggingSettings from sh_edraft.publishing import Publisher -from sh_edraft.publishing.base import PublisherBase from sh_edraft.publishing.model import Template -from sh_edraft.publishing.model.publish_settings_model import PublishSettingsModel +from sh_edraft.publishing.model import PublishSettingsModel from sh_edraft.coding.model import Version from sh_edraft.time.model import TimeFormatSettings @@ -79,7 +78,7 @@ class PublisherTest(unittest.TestCase): def setUp(self): self._config() - self._app_host = ApplicationHost() + self._app_host = ApplicationHost('CPL_Test', HostingEnvironment(EnvironmentName.testing, './')) self._logger = Logger(self._log_settings, self._time_format_settings, self._app_host) self._logger.create() diff --git a/src/tests/service_providing/service_provider.py b/src/tests/service_providing/service_provider.py index 1c136976..a6626763 100644 --- a/src/tests/service_providing/service_provider.py +++ b/src/tests/service_providing/service_provider.py @@ -1,12 +1,14 @@ import unittest from sh_edraft.hosting import ApplicationHost +from sh_edraft.hosting import HostingEnvironment +from sh_edraft.hosting.model import EnvironmentName from sh_edraft.logging import Logger from sh_edraft.logging.base import LoggerBase from sh_edraft.logging.model import LoggingSettings from sh_edraft.publishing import Publisher from sh_edraft.publishing.base import PublisherBase -from sh_edraft.publishing.model.publish_settings_model import PublishSettingsModel +from sh_edraft.publishing.model import PublishSettingsModel from sh_edraft.service import ServiceProvider from sh_edraft.service.base import ServiceBase from sh_edraft.time.model import TimeFormatSettings @@ -15,7 +17,7 @@ from sh_edraft.time.model import TimeFormatSettings class ServiceProviderTest(unittest.TestCase): def setUp(self): - self._app_host = ApplicationHost() + self._app_host = ApplicationHost('CPL_Test', HostingEnvironment(EnvironmentName.testing, './')) self._services = self._app_host.services self._services.create() @@ -59,7 +61,7 @@ class ServiceProviderTest(unittest.TestCase): def test_create(self): print(f'{__name__}.test_create:') - provider = ServiceProvider() + provider = ServiceProvider(self._app_host) self.assertIsNotNone(provider) provider.create() self.assertIsNotNone(provider) From c815e75282bba8b7164b43de0247bc4003f7840d Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Thu, 26 Nov 2020 11:21:57 +0100 Subject: [PATCH 02/14] Improved tests --- src/tests/logging/logger.py | 3 -- src/tests/publisher.py | 59 ------------------------------------- 2 files changed, 62 deletions(-) delete mode 100644 src/tests/publisher.py diff --git a/src/tests/logging/logger.py b/src/tests/logging/logger.py index d7222426..e41a1491 100644 --- a/src/tests/logging/logger.py +++ b/src/tests/logging/logger.py @@ -14,8 +14,6 @@ class LoggerTest(unittest.TestCase): def setUp(self): self._app_host = ApplicationHost('CPL_Test', HostingEnvironment(EnvironmentName.testing, './')) - self._services = self._app_host.services - self._services.create() self._log_settings = LoggingSettings() self._log_settings.from_dict({ @@ -38,7 +36,6 @@ class LoggerTest(unittest.TestCase): shutil.rmtree(self._log_settings.path) def _check_general_requirements(self): - self.assertIsNotNone(self._services) self.assertIsNotNone(self._log_settings) self.assertIsNotNone(self._time_format_settings) diff --git a/src/tests/publisher.py b/src/tests/publisher.py deleted file mode 100644 index 847d76b4..00000000 --- a/src/tests/publisher.py +++ /dev/null @@ -1,59 +0,0 @@ -import os - -from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.publishing.base import PublisherBase -from sh_edraft.service.base import ServiceProviderBase -from sh_edraft.coding.model import Version -from sh_edraft.publishing import Publisher -from sh_edraft.publishing.model import Template - - -class PublisherTest: - - @staticmethod - def start(services: ServiceProviderBase): - version = Version(2020, 12, 5).to_dict() - templates = [ - Template( - '../../publish_templates/*_template.txt', - '*', - '', - '', - '2020', - 'sh-edraft.de', - 'MIT', - ', see LICENSE for more details.', - '', - 'Sven Heidemann', - version - ), - Template( - '../../publish_templates/*_template.txt', - 'sh_edraft', - 'common python library', - 'Library to share common classes and models used at sh-edraft.de', - '2020', - 'sh-edraft.de', - 'MIT', - ', see LICENSE for more details.', - '', - 'Sven Heidemann', - version - ) - ] - - source = '../' - dist = '../../dist' - - services.add_transient(Publisher, services.get_service(LoggerBase), source, dist, templates) - publisher: Publisher = services.get_service(PublisherBase) - - publisher.exclude('../tests/') - publisher.include('../../LICENSE') - publisher.include('../../README.md') - - publisher.create() - publisher.publish() - - if not os.path.isdir(dist): - raise Exception(f'{__name__}: Dist path was not created') From 1c753aaaea7b1277e7bb5ceef57314bb17a2afb3 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Thu, 26 Nov 2020 11:55:55 +0100 Subject: [PATCH 03/14] Added logic to create application --- src/sh_edraft/configuration/__init__.py | 1 + src/sh_edraft/configuration/base/__init__.py | 1 + src/sh_edraft/hosting/application_host.py | 15 ++++++---- .../hosting/base/application_base.py | 16 ++++++++++ src/sh_edraft/hosting/hosting_environment.py | 9 +++--- .../service/base/service_provider_base.py | 4 --- src/sh_edraft/service/service_provider.py | 4 +++ src/tests_dev/__init__.py | 0 src/tests_dev/main.py | 30 +++++++++++++++++++ 9 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 src/sh_edraft/hosting/base/application_base.py create mode 100644 src/tests_dev/__init__.py create mode 100644 src/tests_dev/main.py diff --git a/src/sh_edraft/configuration/__init__.py b/src/sh_edraft/configuration/__init__.py index 10389a5b..0aaef2f3 100644 --- a/src/sh_edraft/configuration/__init__.py +++ b/src/sh_edraft/configuration/__init__.py @@ -20,6 +20,7 @@ __version__ = '2020.12.5' from collections import namedtuple # imports: +from .configuration import Configuration VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=5) diff --git a/src/sh_edraft/configuration/base/__init__.py b/src/sh_edraft/configuration/base/__init__.py index b6b73bcd..a9585439 100644 --- a/src/sh_edraft/configuration/base/__init__.py +++ b/src/sh_edraft/configuration/base/__init__.py @@ -20,6 +20,7 @@ __version__ = '2020.12.5' from collections import namedtuple # imports: +from .configuration_base import ConfigurationBase from .configuration_model_base import ConfigurationModelBase VersionInfo = namedtuple('VersionInfo', 'major minor micro') diff --git a/src/sh_edraft/hosting/application_host.py b/src/sh_edraft/hosting/application_host.py index 0316a2f2..f0f611f2 100644 --- a/src/sh_edraft/hosting/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -1,17 +1,20 @@ from datetime import datetime +from sh_edraft.hosting.hosting_environment import HostingEnvironment from sh_edraft.hosting.base.application_host_base import ApplicationHostBase from sh_edraft.hosting.base.environment_base import EnvironmentBase +from sh_edraft.service.base import ServiceProviderBase from sh_edraft.service.service_provider import ServiceProvider class ApplicationHost(ApplicationHostBase): - def __init__(self, name: str, env: EnvironmentBase): + def __init__(self, name: str, args: list[str]): ApplicationHostBase.__init__(self) self._name: str = name - self._environment: EnvironmentBase = env + self._environment = HostingEnvironment() + self._args: list[str] = args self._services = ServiceProvider(self) self._start_time: datetime = datetime.now() self._end_time: datetime = datetime.now() @@ -24,10 +27,6 @@ class ApplicationHost(ApplicationHostBase): def environment(self) -> EnvironmentBase: return self._environment - @property - def services(self): - return self._services - @property def end_time(self) -> datetime: return self._end_time @@ -47,3 +46,7 @@ class ApplicationHost(ApplicationHostBase): @property def date_time_now(self) -> datetime: return datetime.now() + + @property + def services(self) -> ServiceProviderBase: + return self._services diff --git a/src/sh_edraft/hosting/base/application_base.py b/src/sh_edraft/hosting/base/application_base.py new file mode 100644 index 00000000..96997c6b --- /dev/null +++ b/src/sh_edraft/hosting/base/application_base.py @@ -0,0 +1,16 @@ +from abc import ABC, abstractmethod + + +class ApplicationBase(ABC): + + @abstractmethod + def __init__(self): pass + + @abstractmethod + def create_configuration(self): pass + + @abstractmethod + def create_services(self): pass + + @abstractmethod + def main(self): pass diff --git a/src/sh_edraft/hosting/hosting_environment.py b/src/sh_edraft/hosting/hosting_environment.py index c771cf81..763ef5cc 100644 --- a/src/sh_edraft/hosting/hosting_environment.py +++ b/src/sh_edraft/hosting/hosting_environment.py @@ -1,14 +1,16 @@ +from typing import Optional + from sh_edraft.hosting.base.environment_base import EnvironmentBase from sh_edraft.hosting.model.environment_name import EnvironmentName class HostingEnvironment(EnvironmentBase): - def __init__(self, name: EnvironmentName, crp: str): + def __init__(self, name: EnvironmentName = None, crp: str = None): EnvironmentBase.__init__(self) - self._name = name - self._content_root_path = crp + self._name: Optional[EnvironmentName] = name + self._content_root_path: Optional[str] = crp @property def name(self) -> EnvironmentName: @@ -17,4 +19,3 @@ class HostingEnvironment(EnvironmentBase): @property def content_root_path(self) -> str: return self._content_root_path - diff --git a/src/sh_edraft/service/base/service_provider_base.py b/src/sh_edraft/service/base/service_provider_base.py index 9deb0918..fe5e0f91 100644 --- a/src/sh_edraft/service/base/service_provider_base.py +++ b/src/sh_edraft/service/base/service_provider_base.py @@ -11,10 +11,6 @@ class ServiceProviderBase(ServiceBase): def __init__(self): ServiceBase.__init__(self) - self._transient_services: dict[Type[ServiceBase], Type[ServiceBase]] = {} - self._scoped_services: dict[Type[ServiceBase], Type[ServiceBase]] = {} - self._singleton_services: dict[Type[ServiceBase], ServiceBase] = {} - @property @abstractmethod def config(self): pass diff --git a/src/sh_edraft/service/service_provider.py b/src/sh_edraft/service/service_provider.py index 2467ec46..5c5b0819 100644 --- a/src/sh_edraft/service/service_provider.py +++ b/src/sh_edraft/service/service_provider.py @@ -16,6 +16,10 @@ class ServiceProvider(ServiceProviderBase): self._app_host: ApplicationHostBase = app_host self._config = Configuration() + self._transient_services: dict[Type[ServiceBase], Type[ServiceBase]] = {} + self._scoped_services: dict[Type[ServiceBase], Type[ServiceBase]] = {} + self._singleton_services: dict[Type[ServiceBase], ServiceBase] = {} + @property def config(self): return self._config diff --git a/src/tests_dev/__init__.py b/src/tests_dev/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests_dev/main.py b/src/tests_dev/main.py new file mode 100644 index 00000000..1b9c7cd1 --- /dev/null +++ b/src/tests_dev/main.py @@ -0,0 +1,30 @@ +import sys + +from sh_edraft.hosting import ApplicationHost +from sh_edraft.hosting.base.application_base import ApplicationBase + + +class Program(ApplicationBase): + + def __init__(self): + ApplicationBase.__init__(self) + + self._app_host = ApplicationHost('CPL_DEV_Test', sys.argv) + self._config = self._app_host.services.config + self._services = self._app_host.services + + def create_configuration(self): + self._config.create() + + def create_services(self): + self._services.create() + + def main(self): + print('RUN') + + +if __name__ == '__main__': + program = Program() + program.create_configuration() + program.create_services() + program.main() From 1e0d7d60a5022ab6c1c30d6e17617af0020e6604 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Thu, 26 Nov 2020 17:14:18 +0100 Subject: [PATCH 04/14] Bugfixes --- src/sh_edraft/hosting/application_host.py | 5 +++-- src/sh_edraft/hosting/hosting_environment.py | 10 +++++++++- src/tests_dev/main.py | 4 +--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/sh_edraft/hosting/application_host.py b/src/sh_edraft/hosting/application_host.py index f0f611f2..e9a4ecc4 100644 --- a/src/sh_edraft/hosting/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -1,3 +1,4 @@ +import sys from datetime import datetime from sh_edraft.hosting.hosting_environment import HostingEnvironment @@ -9,12 +10,12 @@ from sh_edraft.service.service_provider import ServiceProvider class ApplicationHost(ApplicationHostBase): - def __init__(self, name: str, args: list[str]): + def __init__(self, name: str): ApplicationHostBase.__init__(self) self._name: str = name self._environment = HostingEnvironment() - self._args: list[str] = args + self._args: list[str] = sys.argv self._services = ServiceProvider(self) self._start_time: datetime = datetime.now() self._end_time: datetime = datetime.now() diff --git a/src/sh_edraft/hosting/hosting_environment.py b/src/sh_edraft/hosting/hosting_environment.py index 763ef5cc..91c011d0 100644 --- a/src/sh_edraft/hosting/hosting_environment.py +++ b/src/sh_edraft/hosting/hosting_environment.py @@ -6,7 +6,7 @@ from sh_edraft.hosting.model.environment_name import EnvironmentName class HostingEnvironment(EnvironmentBase): - def __init__(self, name: EnvironmentName = None, crp: str = None): + def __init__(self, name: EnvironmentName = None, crp: str = './'): EnvironmentBase.__init__(self) self._name: Optional[EnvironmentName] = name @@ -16,6 +16,14 @@ class HostingEnvironment(EnvironmentBase): def name(self) -> EnvironmentName: return self._name + @name.setter + def name(self, name: EnvironmentName): + self._name = name + @property def content_root_path(self) -> str: return self._content_root_path + + @content_root_path.setter + def content_root_path(self, content_root_path: str): + self._content_root_path = content_root_path diff --git a/src/tests_dev/main.py b/src/tests_dev/main.py index 1b9c7cd1..6516be08 100644 --- a/src/tests_dev/main.py +++ b/src/tests_dev/main.py @@ -1,5 +1,3 @@ -import sys - from sh_edraft.hosting import ApplicationHost from sh_edraft.hosting.base.application_base import ApplicationBase @@ -9,7 +7,7 @@ class Program(ApplicationBase): def __init__(self): ApplicationBase.__init__(self) - self._app_host = ApplicationHost('CPL_DEV_Test', sys.argv) + self._app_host = ApplicationHost('CPL_DEV_Test') self._config = self._app_host.services.config self._services = self._app_host.services From cd7c12bba43710049b0681d15323a0ad2023ab14 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Thu, 26 Nov 2020 17:57:51 +0100 Subject: [PATCH 05/14] Improved dev test --- src/tests_dev/main.py | 23 +---------------------- src/tests_dev/program.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 22 deletions(-) create mode 100644 src/tests_dev/program.py diff --git a/src/tests_dev/main.py b/src/tests_dev/main.py index 6516be08..02718764 100644 --- a/src/tests_dev/main.py +++ b/src/tests_dev/main.py @@ -1,25 +1,4 @@ -from sh_edraft.hosting import ApplicationHost -from sh_edraft.hosting.base.application_base import ApplicationBase - - -class Program(ApplicationBase): - - def __init__(self): - ApplicationBase.__init__(self) - - self._app_host = ApplicationHost('CPL_DEV_Test') - self._config = self._app_host.services.config - self._services = self._app_host.services - - def create_configuration(self): - self._config.create() - - def create_services(self): - self._services.create() - - def main(self): - print('RUN') - +from tests_dev.program import Program if __name__ == '__main__': program = Program() diff --git a/src/tests_dev/program.py b/src/tests_dev/program.py new file mode 100644 index 00000000..59f95aa8 --- /dev/null +++ b/src/tests_dev/program.py @@ -0,0 +1,21 @@ +from sh_edraft.hosting import ApplicationHost +from sh_edraft.hosting.base.application_base import ApplicationBase + + +class Program(ApplicationBase): + + def __init__(self): + ApplicationBase.__init__(self) + + self._app_host = ApplicationHost('CPL_DEV_Test') + self._config = self._app_host.services.config + self._services = self._app_host.services + + def create_configuration(self): + self._config.create() + + def create_services(self): + self._services.create() + + def main(self): + print('RUN') From c6d1dce577011f223a69a7e2c0e661b8033aa3d6 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Thu, 26 Nov 2020 18:58:08 +0100 Subject: [PATCH 06/14] Improved service providing and app hosting --- .../configuration/base/configuration_base.py | 14 ++++--- src/sh_edraft/hosting/application_host.py | 41 ++++++------------- src/sh_edraft/hosting/application_runtime.py | 38 +++++++++++++++++ src/sh_edraft/hosting/base/__init__.py | 1 + .../hosting/base/application_base.py | 3 ++ .../hosting/base/application_host_base.py | 23 +++-------- .../hosting/base/application_runtime_base.py | 34 +++++++++++++++ .../service/base/service_provider_base.py | 4 -- src/sh_edraft/service/service_provider.py | 25 ++++------- src/tests_dev/main.py | 1 + src/tests_dev/program.py | 13 +++--- 11 files changed, 118 insertions(+), 79 deletions(-) create mode 100644 src/sh_edraft/hosting/application_runtime.py create mode 100644 src/sh_edraft/hosting/base/application_runtime_base.py diff --git a/src/sh_edraft/configuration/base/configuration_base.py b/src/sh_edraft/configuration/base/configuration_base.py index 03d74dd6..06c8bfe8 100644 --- a/src/sh_edraft/configuration/base/configuration_base.py +++ b/src/sh_edraft/configuration/base/configuration_base.py @@ -1,15 +1,14 @@ -from abc import abstractmethod +from abc import abstractmethod, ABC from collections import Callable +from typing import Type from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase -from sh_edraft.service.base.service_base import ServiceBase -class ConfigurationBase(ServiceBase): +class ConfigurationBase(ABC): @abstractmethod - def __init__(self): - ServiceBase.__init__(self) + def __init__(self): pass @property @abstractmethod @@ -19,4 +18,7 @@ class ConfigurationBase(ServiceBase): def add_config_by_type(self, key_type: type, value: object): pass @abstractmethod - def get_config_by_type(self, search_type: ConfigurationModelBase) -> Callable[ConfigurationModelBase]: pass + def get_config_by_type(self, search_type: Type[ConfigurationModelBase]) -> Callable[ConfigurationModelBase]: pass + + @abstractmethod + def create(self): pass diff --git a/src/sh_edraft/hosting/application_host.py b/src/sh_edraft/hosting/application_host.py index e9a4ecc4..edfa6613 100644 --- a/src/sh_edraft/hosting/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -1,11 +1,12 @@ import sys from datetime import datetime -from sh_edraft.hosting.hosting_environment import HostingEnvironment +from sh_edraft.configuration.configuration import Configuration +from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.hosting.application_runtime import ApplicationRuntime from sh_edraft.hosting.base.application_host_base import ApplicationHostBase -from sh_edraft.hosting.base.environment_base import EnvironmentBase -from sh_edraft.service.base import ServiceProviderBase from sh_edraft.service.service_provider import ServiceProvider +from sh_edraft.service.base.service_provider_base import ServiceProviderBase class ApplicationHost(ApplicationHostBase): @@ -13,41 +14,25 @@ class ApplicationHost(ApplicationHostBase): def __init__(self, name: str): ApplicationHostBase.__init__(self) self._name: str = name - self._environment = HostingEnvironment() - self._args: list[str] = sys.argv - self._services = ServiceProvider(self) + + self._config = Configuration() + self._app_runtime = ApplicationRuntime(self._config) + self._services = ServiceProvider(self._app_runtime) + self._start_time: datetime = datetime.now() self._end_time: datetime = datetime.now() @property def name(self) -> str: return self._name - - @property - def environment(self) -> EnvironmentBase: - return self._environment @property - def end_time(self) -> datetime: - return self._end_time + def configuration(self) -> ConfigurationBase: + return self._config - @end_time.setter - def end_time(self, end_time: datetime): - self._end_time = end_time - - @property - def start_time(self) -> datetime: - return self._start_time - - @start_time.setter - def start_time(self, start_time: datetime): - self._start_time = start_time - - @property - def date_time_now(self) -> datetime: - return datetime.now() - @property def services(self) -> ServiceProviderBase: return self._services + + def create(self): pass diff --git a/src/sh_edraft/hosting/application_runtime.py b/src/sh_edraft/hosting/application_runtime.py new file mode 100644 index 00000000..e94ca901 --- /dev/null +++ b/src/sh_edraft/hosting/application_runtime.py @@ -0,0 +1,38 @@ +from datetime import datetime + +from sh_edraft.configuration.base import ConfigurationBase +from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase + + +class ApplicationRuntime(ApplicationRuntimeBase): + + def __init__(self, config: ConfigurationBase): + ApplicationRuntimeBase.__init__(self) + + self._configuration = config + self._start_time: datetime = datetime.now() + self._end_time: datetime = datetime.now() + + @property + def configuration(self) -> ConfigurationBase: + return self._configuration + + @property + def start_time(self) -> datetime: + return self._start_time + + @start_time.setter + def start_time(self, start_time: datetime): + self._start_time = start_time + + @property + def end_time(self) -> datetime: + return self._end_time + + @end_time.setter + def end_time(self, end_time: datetime): + self._end_time = end_time + + @property + def date_time_now(self) -> datetime: + return datetime.now() diff --git a/src/sh_edraft/hosting/base/__init__.py b/src/sh_edraft/hosting/base/__init__.py index cc2f2b01..2bafd17e 100644 --- a/src/sh_edraft/hosting/base/__init__.py +++ b/src/sh_edraft/hosting/base/__init__.py @@ -1,3 +1,4 @@ # imports: from .application_host_base import ApplicationHostBase from .environment_base import EnvironmentBase +from .application_base import ApplicationBase diff --git a/src/sh_edraft/hosting/base/application_base.py b/src/sh_edraft/hosting/base/application_base.py index 96997c6b..00f72997 100644 --- a/src/sh_edraft/hosting/base/application_base.py +++ b/src/sh_edraft/hosting/base/application_base.py @@ -6,6 +6,9 @@ class ApplicationBase(ABC): @abstractmethod def __init__(self): pass + @abstractmethod + def create_application_host(self): pass + @abstractmethod def create_configuration(self): pass diff --git a/src/sh_edraft/hosting/base/application_host_base.py b/src/sh_edraft/hosting/base/application_host_base.py index 3e735665..0ed3b6e4 100644 --- a/src/sh_edraft/hosting/base/application_host_base.py +++ b/src/sh_edraft/hosting/base/application_host_base.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod -from datetime import datetime -from sh_edraft.hosting.base.environment_base import EnvironmentBase +from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.service.base.service_provider_base import ServiceProviderBase class ApplicationHostBase(ABC): @@ -12,27 +12,14 @@ class ApplicationHostBase(ABC): @property @abstractmethod def name(self) -> str: pass - - @property - @abstractmethod - def environment(self) -> EnvironmentBase: pass @property @abstractmethod - def start_time(self) -> datetime: pass - - @start_time.setter - @abstractmethod - def start_time(self, start_time: datetime): pass + def configuration(self) -> ConfigurationBase: pass @property @abstractmethod - def end_time(self): pass + def services(self) -> ServiceProviderBase: pass - @end_time.setter @abstractmethod - def end_time(self, end_time: datetime): pass - - @property - @abstractmethod - def date_time_now(self) -> datetime: pass + def create(self): pass diff --git a/src/sh_edraft/hosting/base/application_runtime_base.py b/src/sh_edraft/hosting/base/application_runtime_base.py new file mode 100644 index 00000000..c7d364d6 --- /dev/null +++ b/src/sh_edraft/hosting/base/application_runtime_base.py @@ -0,0 +1,34 @@ +from abc import ABC, abstractmethod +from datetime import datetime + +from sh_edraft.configuration.base import ConfigurationBase + + +class ApplicationRuntimeBase(ABC): + + @abstractmethod + def __init__(self): pass + + @property + @abstractmethod + def configuration(self) -> ConfigurationBase: pass + + @property + @abstractmethod + def start_time(self) -> datetime: pass + + @start_time.setter + @abstractmethod + def start_time(self, start_time: datetime): pass + + @property + @abstractmethod + def end_time(self): pass + + @end_time.setter + @abstractmethod + def end_time(self, end_time: datetime): pass + + @property + @abstractmethod + def date_time_now(self) -> datetime: pass diff --git a/src/sh_edraft/service/base/service_provider_base.py b/src/sh_edraft/service/base/service_provider_base.py index fe5e0f91..d9dfa000 100644 --- a/src/sh_edraft/service/base/service_provider_base.py +++ b/src/sh_edraft/service/base/service_provider_base.py @@ -11,10 +11,6 @@ class ServiceProviderBase(ServiceBase): def __init__(self): ServiceBase.__init__(self) - @property - @abstractmethod - def config(self): pass - @abstractmethod def add_transient(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): pass diff --git a/src/sh_edraft/service/service_provider.py b/src/sh_edraft/service/service_provider.py index 5c5b0819..36548cfe 100644 --- a/src/sh_edraft/service/service_provider.py +++ b/src/sh_edraft/service/service_provider.py @@ -2,28 +2,22 @@ from collections import Callable from inspect import signature, Parameter from typing import Type -from sh_edraft.configuration.configuration import Configuration -from sh_edraft.hosting.base.application_host_base import ApplicationHostBase from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase +from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase from sh_edraft.service.base.service_provider_base import ServiceProviderBase from sh_edraft.service.base.service_base import ServiceBase class ServiceProvider(ServiceProviderBase): - def __init__(self, app_host: ApplicationHostBase): - super().__init__() - self._app_host: ApplicationHostBase = app_host - self._config = Configuration() + def __init__(self, app_runtime: ApplicationRuntimeBase): + ServiceProviderBase.__init__(self) + self._app_runtime: ApplicationRuntimeBase = app_runtime self._transient_services: dict[Type[ServiceBase], Type[ServiceBase]] = {} self._scoped_services: dict[Type[ServiceBase], Type[ServiceBase]] = {} self._singleton_services: dict[Type[ServiceBase], ServiceBase] = {} - @property - def config(self): - return self._config - def create(self): pass def _create_instance(self, service: Callable[ServiceBase]) -> ServiceBase: @@ -32,21 +26,16 @@ class ServiceProvider(ServiceProviderBase): for param in sig.parameters.items(): parameter = param[1] if parameter.name != 'self' and parameter.annotation != Parameter.empty: - if issubclass(parameter.annotation, ApplicationHostBase): - params.append(self._app_host) + if issubclass(parameter.annotation, ApplicationRuntimeBase): + params.append(self._app_runtime) elif issubclass(parameter.annotation, ServiceBase): params.append(self.get_service(parameter.annotation)) elif issubclass(parameter.annotation, ConfigurationModelBase): - params.append(self._config.get_config_by_type(parameter.annotation)) + params.append(self._app_runtime.configuration.get_config_by_type(parameter.annotation)) return service(*params) - # try: - # instance.init(args) - # return instance - # except Exception as e: - # print(colored(f'Argument error\n{e}', 'red')) def add_transient(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): self._transient_services[service_type] = service diff --git a/src/tests_dev/main.py b/src/tests_dev/main.py index 02718764..cfb45c60 100644 --- a/src/tests_dev/main.py +++ b/src/tests_dev/main.py @@ -2,6 +2,7 @@ from tests_dev.program import Program if __name__ == '__main__': program = Program() + program.create_application_host() program.create_configuration() program.create_services() program.main() diff --git a/src/tests_dev/program.py b/src/tests_dev/program.py index 59f95aa8..69d2796b 100644 --- a/src/tests_dev/program.py +++ b/src/tests_dev/program.py @@ -1,5 +1,7 @@ +from typing import Optional + from sh_edraft.hosting import ApplicationHost -from sh_edraft.hosting.base.application_base import ApplicationBase +from sh_edraft.hosting.base import ApplicationBase class Program(ApplicationBase): @@ -7,15 +9,16 @@ class Program(ApplicationBase): def __init__(self): ApplicationBase.__init__(self) + self._app_host: Optional[ApplicationHost] = None + + def create_application_host(self): self._app_host = ApplicationHost('CPL_DEV_Test') - self._config = self._app_host.services.config - self._services = self._app_host.services def create_configuration(self): - self._config.create() + self._app_host.configuration.create() def create_services(self): - self._services.create() + self._app_host.services.create() def main(self): print('RUN') From 7d4efe7bdaf6f2b42443504d8e4f05a5e593095d Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Thu, 26 Nov 2020 19:17:05 +0100 Subject: [PATCH 07/14] Improved service providing and app hosting --- src/sh_edraft/hosting/application_host.py | 9 +++- src/sh_edraft/hosting/application_runtime.py | 14 +++++-- .../hosting/base/application_host_base.py | 5 +++ .../hosting/base/application_runtime_base.py | 7 +++- src/sh_edraft/hosting/hosting_environment.py | 2 +- src/sh_edraft/logging/logger.py | 34 +++++++++++---- .../service/base/service_provider_base.py | 2 +- src/sh_edraft/service/service_provider.py | 2 +- src/tests_dev/program.py | 41 ++++++++++++++++++- 9 files changed, 97 insertions(+), 19 deletions(-) diff --git a/src/sh_edraft/hosting/application_host.py b/src/sh_edraft/hosting/application_host.py index edfa6613..f1342626 100644 --- a/src/sh_edraft/hosting/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -3,6 +3,8 @@ from datetime import datetime from sh_edraft.configuration.configuration import Configuration from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.hosting.base.environment_base import EnvironmentBase +from sh_edraft.hosting.hosting_environment import HostingEnvironment from sh_edraft.hosting.application_runtime import ApplicationRuntime from sh_edraft.hosting.base.application_host_base import ApplicationHostBase from sh_edraft.service.service_provider import ServiceProvider @@ -17,7 +19,8 @@ class ApplicationHost(ApplicationHostBase): self._args: list[str] = sys.argv self._config = Configuration() - self._app_runtime = ApplicationRuntime(self._config) + self._environment = HostingEnvironment() + self._app_runtime = ApplicationRuntime(self._config, self._environment) self._services = ServiceProvider(self._app_runtime) self._start_time: datetime = datetime.now() @@ -27,6 +30,10 @@ class ApplicationHost(ApplicationHostBase): def name(self) -> str: return self._name + @property + def environment(self) -> EnvironmentBase: + return self._environment + @property def configuration(self) -> ConfigurationBase: return self._config diff --git a/src/sh_edraft/hosting/application_runtime.py b/src/sh_edraft/hosting/application_runtime.py index e94ca901..3252ecbe 100644 --- a/src/sh_edraft/hosting/application_runtime.py +++ b/src/sh_edraft/hosting/application_runtime.py @@ -1,21 +1,27 @@ from datetime import datetime -from sh_edraft.configuration.base import ConfigurationBase +from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.hosting.base.environment_base import EnvironmentBase from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase class ApplicationRuntime(ApplicationRuntimeBase): - def __init__(self, config: ConfigurationBase): + def __init__(self, config: ConfigurationBase, runtime: EnvironmentBase): ApplicationRuntimeBase.__init__(self) - self._configuration = config + self._app_runtime = runtime + self._app_configuration = config self._start_time: datetime = datetime.now() self._end_time: datetime = datetime.now() + + @property + def environment(self) -> EnvironmentBase: + return self._app_runtime @property def configuration(self) -> ConfigurationBase: - return self._configuration + return self._app_configuration @property def start_time(self) -> datetime: diff --git a/src/sh_edraft/hosting/base/application_host_base.py b/src/sh_edraft/hosting/base/application_host_base.py index 0ed3b6e4..4e6c88e5 100644 --- a/src/sh_edraft/hosting/base/application_host_base.py +++ b/src/sh_edraft/hosting/base/application_host_base.py @@ -1,6 +1,7 @@ from abc import ABC, abstractmethod from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.hosting.base.environment_base import EnvironmentBase from sh_edraft.service.base.service_provider_base import ServiceProviderBase @@ -13,6 +14,10 @@ class ApplicationHostBase(ABC): @abstractmethod def name(self) -> str: pass + @property + @abstractmethod + def environment(self) -> EnvironmentBase: pass + @property @abstractmethod def configuration(self) -> ConfigurationBase: pass diff --git a/src/sh_edraft/hosting/base/application_runtime_base.py b/src/sh_edraft/hosting/base/application_runtime_base.py index c7d364d6..8d5ec5cc 100644 --- a/src/sh_edraft/hosting/base/application_runtime_base.py +++ b/src/sh_edraft/hosting/base/application_runtime_base.py @@ -1,7 +1,8 @@ from abc import ABC, abstractmethod from datetime import datetime -from sh_edraft.configuration.base import ConfigurationBase +from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.hosting.base.environment_base import EnvironmentBase class ApplicationRuntimeBase(ABC): @@ -9,6 +10,10 @@ class ApplicationRuntimeBase(ABC): @abstractmethod def __init__(self): pass + @property + @abstractmethod + def environment(self) -> EnvironmentBase: pass + @property @abstractmethod def configuration(self) -> ConfigurationBase: pass diff --git a/src/sh_edraft/hosting/hosting_environment.py b/src/sh_edraft/hosting/hosting_environment.py index 91c011d0..e1ecc15b 100644 --- a/src/sh_edraft/hosting/hosting_environment.py +++ b/src/sh_edraft/hosting/hosting_environment.py @@ -6,7 +6,7 @@ from sh_edraft.hosting.model.environment_name import EnvironmentName class HostingEnvironment(EnvironmentBase): - def __init__(self, name: EnvironmentName = None, crp: str = './'): + def __init__(self, name: EnvironmentName = EnvironmentName.production, crp: str = './'): EnvironmentBase.__init__(self) self._name: Optional[EnvironmentName] = name diff --git a/src/sh_edraft/logging/logger.py b/src/sh_edraft/logging/logger.py index 6305725a..51137ce0 100644 --- a/src/sh_edraft/logging/logger.py +++ b/src/sh_edraft/logging/logger.py @@ -3,7 +3,7 @@ import os import traceback from string import Template -from sh_edraft.hosting.base import ApplicationHostBase +from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase from sh_edraft.logging.base.logger_base import LoggerBase from sh_edraft.logging.model import LoggingSettings from sh_edraft.logging.model.logging_level import LoggingLevel @@ -13,16 +13,16 @@ from sh_edraft.utils.console import Console class Logger(LoggerBase): - def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_host: ApplicationHostBase): + def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_runtime: ApplicationRuntimeBase): LoggerBase.__init__(self) + self._app_runtime = app_runtime self._log_settings: LoggingSettings = logging_settings self._time_format_settings: TimeFormatSettings = time_format - self._app_host = app_host self._log = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) self._path = self._log_settings.path self._level = self._log_settings.level @@ -47,7 +47,7 @@ class Logger(LoggerBase): if not os.path.exists(self._path): os.mkdir(self._path) except Exception as e: - self.fatal(__name__, 'Cannot create log dir', ex=e) + self._fatal_console(__name__, 'Cannot create log dir', ex=e) """ create new log file """ try: @@ -57,16 +57,19 @@ class Logger(LoggerBase): Console.write_line(f'[{__name__}]: Using log file: {path}') f.close() except Exception as e: - self.fatal(__name__, 'Cannot open log file', ex=e) + self._fatal_console(__name__, 'Cannot open log file', ex=e) def _append_log(self, string): try: # open log file and append always + if not os.path.isdir(self._path): + self._fatal_console(__name__, 'Log directory not found') + with open(self._path + self._log, "a+", encoding="utf-8") as f: f.write(string + '\n') f.close() except Exception as e: - self.error(__name__, f'Cannot append log file, message: {string}', ex=e) + self._fatal_console(__name__, f'Cannot append log file, message: {string}', ex=e) def _get_string(self, name: str, level: LoggingLevel, message: str) -> str: log_level = level.name @@ -156,3 +159,18 @@ class Logger(LoggerBase): Console.write_line(output, 'red') exit() + + def _fatal_console(self, name: str, message: str, ex: Exception = None): + output = '' + if ex is not None: + tb = traceback.format_exc() + self.error(name, message) + output = self._get_string(name, LoggingLevel.ERROR, f'{ex} -> {tb}') + else: + output = self._get_string(name, LoggingLevel.ERROR, message) + + # check if message can be shown in console + if self._console.value >= LoggingLevel.FATAL.value: + Console.write_line(output, 'red') + + exit() diff --git a/src/sh_edraft/service/base/service_provider_base.py b/src/sh_edraft/service/base/service_provider_base.py index d9dfa000..58d3a64f 100644 --- a/src/sh_edraft/service/base/service_provider_base.py +++ b/src/sh_edraft/service/base/service_provider_base.py @@ -18,7 +18,7 @@ class ServiceProviderBase(ServiceBase): def add_scoped(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): pass @abstractmethod - def add_singleton(self, service_type: Type[ServiceBase], service: ServiceBase): pass + def add_singleton(self, service_type: Type[ServiceBase], service: Callable[ServiceBase]): pass @abstractmethod def get_service(self, instance_type: Type[ServiceBase]) -> Callable[ServiceBase]: pass diff --git a/src/sh_edraft/service/service_provider.py b/src/sh_edraft/service/service_provider.py index 36548cfe..40173ea0 100644 --- a/src/sh_edraft/service/service_provider.py +++ b/src/sh_edraft/service/service_provider.py @@ -43,7 +43,7 @@ class ServiceProvider(ServiceProviderBase): def add_scoped(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): self._scoped_services[service_type] = service - def add_singleton(self, service_type: Type[ServiceBase], service: ServiceBase): + def add_singleton(self, service_type: Type[ServiceBase], service: Callable[ServiceBase]): for known_service in self._singleton_services: if type(known_service) == type(service_type): raise Exception(f'Service with type {type(service_type)} already exists') diff --git a/src/tests_dev/program.py b/src/tests_dev/program.py index 69d2796b..5c8a6356 100644 --- a/src/tests_dev/program.py +++ b/src/tests_dev/program.py @@ -1,7 +1,14 @@ from typing import Optional +from sh_edraft.configuration.base import ConfigurationBase from sh_edraft.hosting import ApplicationHost from sh_edraft.hosting.base import ApplicationBase +from sh_edraft.hosting.model import EnvironmentName +from sh_edraft.logging import Logger +from sh_edraft.logging.base import LoggerBase +from sh_edraft.logging.model import LoggingSettings +from sh_edraft.service.base import ServiceProviderBase +from sh_edraft.time.model import TimeFormatSettings class Program(ApplicationBase): @@ -11,14 +18,44 @@ class Program(ApplicationBase): self._app_host: Optional[ApplicationHost] = None + self._services: Optional[ServiceProviderBase] = None + self._configuration: Optional[ConfigurationBase] = None + def create_application_host(self): self._app_host = ApplicationHost('CPL_DEV_Test') + self._services = self._app_host.services + self._configuration = self._app_host.configuration + + self._app_host.environment.name = EnvironmentName.development def create_configuration(self): - self._app_host.configuration.create() + self._configuration.create() + + log_settings = LoggingSettings() + log_settings.from_dict({ + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }) + + time_format_settings = TimeFormatSettings() + time_format_settings.from_dict({ + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }) + + self._configuration.add_config_by_type(LoggingSettings, log_settings) + self._configuration.add_config_by_type(TimeFormatSettings, time_format_settings) def create_services(self): - self._app_host.services.create() + self._services.create() + self._services.add_singleton(LoggerBase, Logger) + logger: Logger = self._services.get_service(LoggerBase) + logger.create() + logger.header(self._app_host.name) def main(self): print('RUN') From e76b293f605989bd07c0103521908569824aaddb Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 27 Nov 2020 11:24:47 +0100 Subject: [PATCH 08/14] Bugfixes in unittests --- .../configuration/base/configuration_base.py | 4 -- src/sh_edraft/configuration/configuration.py | 4 -- src/sh_edraft/hosting/application_host.py | 9 ++- .../hosting/base/application_host_base.py | 7 ++- src/tests/logging/logger.py | 60 ++++++++++--------- src/tests/publishing/publisher.py | 11 ++-- .../service_providing/service_provider.py | 22 +++---- 7 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/sh_edraft/configuration/base/configuration_base.py b/src/sh_edraft/configuration/base/configuration_base.py index 06c8bfe8..40c68555 100644 --- a/src/sh_edraft/configuration/base/configuration_base.py +++ b/src/sh_edraft/configuration/base/configuration_base.py @@ -10,10 +10,6 @@ class ConfigurationBase(ABC): @abstractmethod def __init__(self): pass - @property - @abstractmethod - def config(self) -> dict[type, object]: pass - @abstractmethod def add_config_by_type(self, key_type: type, value: object): pass diff --git a/src/sh_edraft/configuration/configuration.py b/src/sh_edraft/configuration/configuration.py index b3743aff..39e1767d 100644 --- a/src/sh_edraft/configuration/configuration.py +++ b/src/sh_edraft/configuration/configuration.py @@ -11,10 +11,6 @@ class Configuration(ConfigurationBase): self._config: dict[type, object] = {} - @property - def config(self): - return self._config - def create(self): pass def add_config_by_type(self, key_type: type, value: object): diff --git a/src/sh_edraft/hosting/application_host.py b/src/sh_edraft/hosting/application_host.py index f1342626..09eafb99 100644 --- a/src/sh_edraft/hosting/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -3,6 +3,7 @@ from datetime import datetime from sh_edraft.configuration.configuration import Configuration from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase from sh_edraft.hosting.base.environment_base import EnvironmentBase from sh_edraft.hosting.hosting_environment import HostingEnvironment from sh_edraft.hosting.application_runtime import ApplicationRuntime @@ -30,13 +31,17 @@ class ApplicationHost(ApplicationHostBase): def name(self) -> str: return self._name + @property + def configuration(self) -> ConfigurationBase: + return self._config + @property def environment(self) -> EnvironmentBase: return self._environment @property - def configuration(self) -> ConfigurationBase: - return self._config + def application_runtime(self) -> ApplicationRuntimeBase: + return self._app_runtime @property def services(self) -> ServiceProviderBase: diff --git a/src/sh_edraft/hosting/base/application_host_base.py b/src/sh_edraft/hosting/base/application_host_base.py index 4e6c88e5..117ec546 100644 --- a/src/sh_edraft/hosting/base/application_host_base.py +++ b/src/sh_edraft/hosting/base/application_host_base.py @@ -1,6 +1,7 @@ from abc import ABC, abstractmethod from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase from sh_edraft.hosting.base.environment_base import EnvironmentBase from sh_edraft.service.base.service_provider_base import ServiceProviderBase @@ -14,13 +15,17 @@ class ApplicationHostBase(ABC): @abstractmethod def name(self) -> str: pass + @property + @abstractmethod + def configuration(self) -> ConfigurationBase: pass + @property @abstractmethod def environment(self) -> EnvironmentBase: pass @property @abstractmethod - def configuration(self) -> ConfigurationBase: pass + def application_runtime(self) -> ApplicationRuntimeBase: pass @property @abstractmethod diff --git a/src/tests/logging/logger.py b/src/tests/logging/logger.py index e41a1491..1fb3d3a7 100644 --- a/src/tests/logging/logger.py +++ b/src/tests/logging/logger.py @@ -2,18 +2,24 @@ import os import shutil import unittest from string import Template +from typing import cast -from sh_edraft.hosting import ApplicationHost, HostingEnvironment -from sh_edraft.hosting.model import EnvironmentName +from sh_edraft.hosting import ApplicationHost from sh_edraft.logging import Logger from sh_edraft.logging.model import LoggingSettings +from sh_edraft.service import ServiceProvider from sh_edraft.time.model import TimeFormatSettings class LoggerTest(unittest.TestCase): def setUp(self): - self._app_host = ApplicationHost('CPL_Test', HostingEnvironment(EnvironmentName.testing, './')) + app_host = ApplicationHost('CPL_Test') + self._app_runtime = app_host.application_runtime + self._config = app_host.configuration + self._config.create() + self._services: ServiceProvider = cast(ServiceProvider, app_host.services) + self._services.create() self._log_settings = LoggingSettings() self._log_settings.from_dict({ @@ -41,25 +47,25 @@ class LoggerTest(unittest.TestCase): def test_create(self): print(f'{__name__}.test_create:') - logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger = Logger(self._log_settings, self._time_format_settings, self._app_runtime) logger.create() self.assertTrue(os.path.isdir(self._log_settings.path)) log_file = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) self.assertTrue(os.path.isfile(self._log_settings.path + log_file)) def test_header(self): print(f'{__name__}.test_header:') - logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger = Logger(self._log_settings, self._time_format_settings, self._app_runtime) logger.create() logger.header('HeaderTest:') log_file = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) log_content = [] @@ -75,13 +81,13 @@ class LoggerTest(unittest.TestCase): def test_trace(self): print(f'{__name__}.test_trace:') - logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger = Logger(self._log_settings, self._time_format_settings, self._app_runtime) logger.create() logger.trace(__name__, f'{__name__}.test_trace:') log_file = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) log_content = [] @@ -97,13 +103,13 @@ class LoggerTest(unittest.TestCase): def test_debug(self): print(f'{__name__}.test_debug:') - logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger = Logger(self._log_settings, self._time_format_settings, self._app_runtime) logger.create() logger.debug(__name__, f'{__name__}.test_debug:') log_file = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) log_content = [] @@ -119,13 +125,13 @@ class LoggerTest(unittest.TestCase): def test_info(self): print(f'{__name__}.test_info:') - logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger = Logger(self._log_settings, self._time_format_settings, self._app_runtime) logger.create() logger.info(__name__, f'{__name__}.test_info:') log_file = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) log_content = [] @@ -141,13 +147,13 @@ class LoggerTest(unittest.TestCase): def test_warn(self): print(f'{__name__}.test_warn:') - logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger = Logger(self._log_settings, self._time_format_settings, self._app_runtime) logger.create() logger.warn(__name__, f'{__name__}.test_warn:') log_file = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) log_content = [] @@ -163,13 +169,13 @@ class LoggerTest(unittest.TestCase): def test_error(self): print(f'{__name__}.test_error:') - logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger = Logger(self._log_settings, self._time_format_settings, self._app_runtime) logger.create() logger.error(__name__, f'{__name__}.test_error:') log_file = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) log_content = [] @@ -185,14 +191,14 @@ class LoggerTest(unittest.TestCase): def test_fatal(self): print(f'{__name__}.test_fatal:') - logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger = Logger(self._log_settings, self._time_format_settings, self._app_runtime) logger.create() with self.assertRaises(SystemExit): logger.fatal(__name__, f'{__name__}.test_fatal:') log_file = Template(self._log_settings.filename).substitute( - date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), - start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) ) log_content = [] diff --git a/src/tests/publishing/publisher.py b/src/tests/publishing/publisher.py index cb721a41..a9e91254 100644 --- a/src/tests/publishing/publisher.py +++ b/src/tests/publishing/publisher.py @@ -15,7 +15,7 @@ from sh_edraft.time.model import TimeFormatSettings class PublisherTest(unittest.TestCase): - def _config(self): + def _configure(self): self._log_settings = LoggingSettings() self._log_settings.from_dict({ "Path": "logs/", @@ -76,10 +76,12 @@ class PublisherTest(unittest.TestCase): }) def setUp(self): - self._config() + self._configure() - self._app_host = ApplicationHost('CPL_Test', HostingEnvironment(EnvironmentName.testing, './')) - self._logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + app_host = ApplicationHost('CPL_Test') + self._app_runtime = app_host.application_runtime + + self._logger = Logger(self._log_settings, self._time_format_settings, app_host.application_runtime) self._logger.create() def tearDown(self): @@ -92,3 +94,4 @@ class PublisherTest(unittest.TestCase): publisher.create() self.assertTrue(os.path.isdir(self._dist_path)) + self.assertEqual(publisher._publish_settings, self._publish_settings_model) diff --git a/src/tests/service_providing/service_provider.py b/src/tests/service_providing/service_provider.py index a6626763..6efbcfbb 100644 --- a/src/tests/service_providing/service_provider.py +++ b/src/tests/service_providing/service_provider.py @@ -1,8 +1,8 @@ import unittest +from collections import Callable +from typing import Type, cast from sh_edraft.hosting import ApplicationHost -from sh_edraft.hosting import HostingEnvironment -from sh_edraft.hosting.model import EnvironmentName from sh_edraft.logging import Logger from sh_edraft.logging.base import LoggerBase from sh_edraft.logging.model import LoggingSettings @@ -17,8 +17,10 @@ from sh_edraft.time.model import TimeFormatSettings class ServiceProviderTest(unittest.TestCase): def setUp(self): - self._app_host = ApplicationHost('CPL_Test', HostingEnvironment(EnvironmentName.testing, './')) - self._services = self._app_host.services + self._app_host = ApplicationHost('CPL_Test') + self._config = self._app_host.configuration + self._config.create() + self._services: ServiceProvider = cast(ServiceProvider, self._app_host.services) self._services.create() self._log_settings = LoggingSettings() @@ -28,7 +30,7 @@ class ServiceProviderTest(unittest.TestCase): "ConsoleLogLevel": "TRACE", "FileLogLevel": "TRACE" }) - self._services.config.add_config_by_type(LoggingSettings, self._log_settings) + self._config.add_config_by_type(LoggingSettings, self._log_settings) self._time_format_settings = TimeFormatSettings() self._time_format_settings.from_dict({ @@ -37,8 +39,8 @@ class ServiceProviderTest(unittest.TestCase): "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" }) - self._services.config.add_config_by_type(TimeFormatSettings, self._time_format_settings) - self._services.config.add_config_by_type(ApplicationHost, self._app_host) + self._config.add_config_by_type(TimeFormatSettings, self._time_format_settings) + self._config.add_config_by_type(ApplicationHost, self._app_host) self._publish_settings_model = PublishSettingsModel() self._publish_settings_model.from_dict({ @@ -49,7 +51,7 @@ class ServiceProviderTest(unittest.TestCase): "ExcludedFiles": [], "TemplateEnding": "_template.txt", }) - self._services.config.add_config_by_type(PublishSettingsModel, self._publish_settings_model) + self._config.add_config_by_type(PublishSettingsModel, self._publish_settings_model) def _check_general_requirements(self): self.assertIsNotNone(self._services) @@ -61,7 +63,7 @@ class ServiceProviderTest(unittest.TestCase): def test_create(self): print(f'{__name__}.test_create:') - provider = ServiceProvider(self._app_host) + provider = ServiceProvider(self._app_host.application_runtime) self.assertIsNotNone(provider) provider.create() self.assertIsNotNone(provider) @@ -108,7 +110,7 @@ class ServiceProviderTest(unittest.TestCase): self.assertEqual(logger._log_settings, self._log_settings) self.assertEqual(logger._time_format_settings, self._time_format_settings) - self.assertEqual(logger._app_host, self._app_host) + self.assertEqual(logger._app_runtime, self._app_host.application_runtime) def test_add_scoped(self): print(f'{__name__}.test_add_scoped:') From 0df6d469ab94131663b69a9a85d41fea82dc22c6 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 27 Nov 2020 18:12:09 +0100 Subject: [PATCH 09/14] Bugfixes in logger --- src/sh_edraft/logging/logger.py | 4 ++-- src/tests/logging/logger.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sh_edraft/logging/logger.py b/src/sh_edraft/logging/logger.py index 51137ce0..01b58937 100644 --- a/src/sh_edraft/logging/logger.py +++ b/src/sh_edraft/logging/logger.py @@ -146,9 +146,9 @@ class Logger(LoggerBase): if ex is not None: tb = traceback.format_exc() self.error(name, message) - output = self._get_string(name, LoggingLevel.ERROR, f'{ex} -> {tb}') + output = self._get_string(name, LoggingLevel.FATAL, f'{ex} -> {tb}') else: - output = self._get_string(name, LoggingLevel.ERROR, message) + output = self._get_string(name, LoggingLevel.FATAL, message) # check if message can be written to log if self._level.value >= LoggingLevel.FATAL.value: diff --git a/src/tests/logging/logger.py b/src/tests/logging/logger.py index 1fb3d3a7..8187ec85 100644 --- a/src/tests/logging/logger.py +++ b/src/tests/logging/logger.py @@ -210,4 +210,4 @@ class LoggerTest(unittest.TestCase): print('Cannot open log file', e) self.assertGreater(len(log_content), 0) - self.assertTrue(log_content[len(log_content) - 1].endswith(f'[ ERROR ] [ {__name__} ]: {__name__}.test_fatal:\n')) + self.assertTrue(log_content[len(log_content) - 1].endswith(f'[ FATAL ] [ {__name__} ]: {__name__}.test_fatal:\n')) From ff577b121efbab3f45549bd8c54400984cbd457a Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 27 Nov 2020 18:18:07 +0100 Subject: [PATCH 10/14] Bugfixes in app runtime --- src/sh_edraft/hosting/application_runtime.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sh_edraft/hosting/application_runtime.py b/src/sh_edraft/hosting/application_runtime.py index 3252ecbe..e4ce40c1 100644 --- a/src/sh_edraft/hosting/application_runtime.py +++ b/src/sh_edraft/hosting/application_runtime.py @@ -7,22 +7,22 @@ from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBa class ApplicationRuntime(ApplicationRuntimeBase): - def __init__(self, config: ConfigurationBase, runtime: EnvironmentBase): + def __init__(self, config: ConfigurationBase, environment: EnvironmentBase): ApplicationRuntimeBase.__init__(self) - self._app_runtime = runtime + self._environment = environment self._app_configuration = config self._start_time: datetime = datetime.now() self._end_time: datetime = datetime.now() @property def environment(self) -> EnvironmentBase: - return self._app_runtime - + return self._environment + @property def configuration(self) -> ConfigurationBase: return self._app_configuration - + @property def start_time(self) -> datetime: return self._start_time From 44ffb4e5741ee9352161d5df4fde9b9d21e53f4e Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sat, 28 Nov 2020 15:13:54 +0100 Subject: [PATCH 11/14] Added logic to load config from json & improved hosting and service providing --- .../configuration/base/configuration_base.py | 18 +++- .../base/configuration_model_base.py | 3 + src/sh_edraft/configuration/configuration.py | 100 ++++++++++++++++-- src/sh_edraft/configuration/model/__init__.py | 3 + .../model/configuration_variable_name.py | 12 +++ src/sh_edraft/environment/__init__.py | 3 + src/sh_edraft/environment/base/__init__.py | 3 + .../environment/base/environment_base.py | 45 ++++++++ .../environment/hosting_environment.py | 52 +++++++++ src/sh_edraft/environment/model/__init__.py | 3 + .../model/environment_name.py | 0 src/sh_edraft/hosting/__init__.py | 2 +- src/sh_edraft/hosting/application_host.py | 18 +--- src/sh_edraft/hosting/application_runtime.py | 8 +- src/sh_edraft/hosting/base/__init__.py | 4 +- .../hosting/base/application_host_base.py | 9 -- .../hosting/base/application_runtime_base.py | 5 - .../hosting/base/environment_base.py | 25 ----- src/sh_edraft/hosting/hosting_environment.py | 29 ----- src/sh_edraft/hosting/model/__init__.py | 1 - src/sh_edraft/logging/model/__init__.py | 1 + .../logging/model/logging_settings.py | 13 ++- .../logging/model/logging_settings_name.py | 3 +- src/sh_edraft/service/service_provider.py | 2 +- .../time/model/time_format_settings.py | 3 +- .../time/model/time_format_settings_names.py | 1 - src/tests_dev/appsettings.development.json | 8 ++ src/tests_dev/appsettings.json | 15 +++ src/tests_dev/program.py | 37 ++----- 29 files changed, 285 insertions(+), 141 deletions(-) create mode 100644 src/sh_edraft/configuration/model/__init__.py create mode 100644 src/sh_edraft/configuration/model/configuration_variable_name.py create mode 100644 src/sh_edraft/environment/__init__.py create mode 100644 src/sh_edraft/environment/base/__init__.py create mode 100644 src/sh_edraft/environment/base/environment_base.py create mode 100644 src/sh_edraft/environment/hosting_environment.py create mode 100644 src/sh_edraft/environment/model/__init__.py rename src/sh_edraft/{hosting => environment}/model/environment_name.py (100%) delete mode 100644 src/sh_edraft/hosting/base/environment_base.py delete mode 100644 src/sh_edraft/hosting/hosting_environment.py create mode 100644 src/tests_dev/appsettings.development.json create mode 100644 src/tests_dev/appsettings.json diff --git a/src/sh_edraft/configuration/base/configuration_base.py b/src/sh_edraft/configuration/base/configuration_base.py index 40c68555..bf44a8c1 100644 --- a/src/sh_edraft/configuration/base/configuration_base.py +++ b/src/sh_edraft/configuration/base/configuration_base.py @@ -3,6 +3,7 @@ from collections import Callable from typing import Type from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase +from sh_edraft.environment.base.environment_base import EnvironmentBase class ConfigurationBase(ABC): @@ -10,11 +11,24 @@ class ConfigurationBase(ABC): @abstractmethod def __init__(self): pass + @property @abstractmethod - def add_config_by_type(self, key_type: type, value: object): pass + def environment(self) -> EnvironmentBase: pass @abstractmethod - def get_config_by_type(self, search_type: Type[ConfigurationModelBase]) -> Callable[ConfigurationModelBase]: pass + def add_environment_variables(self, prefix: str): pass + + @abstractmethod + def add_argument_variables(self): pass + + @abstractmethod + def add_json_file(self, name: str, optional: bool = None): pass + + @abstractmethod + def add_configuration(self, key_type: type, value: object): pass + + @abstractmethod + def get_configuration(self, search_type: Type[ConfigurationModelBase]) -> Callable[ConfigurationModelBase]: pass @abstractmethod def create(self): pass diff --git a/src/sh_edraft/configuration/base/configuration_model_base.py b/src/sh_edraft/configuration/base/configuration_model_base.py index 06b65ba5..9772a648 100644 --- a/src/sh_edraft/configuration/base/configuration_model_base.py +++ b/src/sh_edraft/configuration/base/configuration_model_base.py @@ -3,5 +3,8 @@ from abc import ABC, abstractmethod class ConfigurationModelBase(ABC): + @abstractmethod + def __init__(self): pass + @abstractmethod def from_dict(self, settings: dict): pass diff --git a/src/sh_edraft/configuration/configuration.py b/src/sh_edraft/configuration/configuration.py index 39e1767d..8c02be21 100644 --- a/src/sh_edraft/configuration/configuration.py +++ b/src/sh_edraft/configuration/configuration.py @@ -1,25 +1,113 @@ -from collections import Callable +import json +import os +import sys from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.configuration.model.configuration_variable_name import ConfigurationVariableName +from sh_edraft.environment.base.environment_base import EnvironmentBase +from sh_edraft.environment.hosting_environment import HostingEnvironment +from sh_edraft.utils import Console class Configuration(ConfigurationBase): def __init__(self): - super().__init__() + ConfigurationBase.__init__(self) - self._config: dict[type, object] = {} + self._hosting_environment = HostingEnvironment() + self._config: dict[type, ConfigurationModelBase] = {} - def create(self): pass + @property + def environment(self) -> EnvironmentBase: + return self._hosting_environment - def add_config_by_type(self, key_type: type, value: object): + @staticmethod + def _print_info(name: str, message: str): + Console.write_line(f'[{name}] {message}', 'green') + + @staticmethod + def _print_warn(name: str, message: str): + Console.write_line(f'[{name}] {message}', 'yellow') + + @staticmethod + def _print_error(name: str, message: str): + Console.write_line(f'[{name}] {message}', 'red') + + def _set_variable(self, name: str, value: str): + if name == ConfigurationVariableName.environment.value: + self._hosting_environment.environment_name = value + + elif name == ConfigurationVariableName.name.value: + self._hosting_environment.application_name = value + + elif name == ConfigurationVariableName.customer.value: + self._hosting_environment.customer = value + + def add_environment_variables(self, prefix: str): + for variable in ConfigurationVariableName.to_list(): + var_name = f'{prefix}{variable}' + if var_name in [key.upper() for key in os.environ.keys()]: + self._set_variable(variable, os.environ[var_name]) + + def add_argument_variables(self): + for arg in sys.argv[1:]: + try: + argument = arg.split('--')[1].split('=')[0].upper() + value = arg.split('=')[1] + + if argument not in ConfigurationVariableName.to_list(): + raise Exception(f'Invalid argument name: {argument}') + + self._set_variable(argument, value) + except Exception as e: + self._print_error(__name__, f'Invalid argument: {arg} -> {e}') + exit() + + def add_json_file(self, name: str, optional: bool = None): + if self._hosting_environment.content_root_path.endswith('/') and not name.startswith('/'): + file_path = f'{self._hosting_environment.content_root_path}{name}' + else: + file_path = f'{self._hosting_environment.content_root_path}/{name}' + + if not os.path.isfile(file_path): + if not optional: + self._print_error(__name__, f'File not found: {file_path}') + exit() + + self._print_warn(__name__, f'Not Loaded config file: {file_path}') + return None + + config_from_file = self._load_json_file(file_path) + for sub in ConfigurationModelBase.__subclasses__(): + for key, value in config_from_file.items(): + if sub.__name__ == key: + configuration = sub() + configuration.from_dict(value) + self.add_configuration(sub, configuration) + + def _load_json_file(self, file: str) -> dict: + try: + # open config file, create if not exists + with open(file, encoding='utf-8') as cfg: + # load json + json_cfg = json.load(cfg) + self._print_info(__name__, f'Loaded config file: {file}') + return json_cfg + except Exception as e: + self._print_error(__name__, f'Cannot load config file: {file}! -> {e}') + return {} + + def add_configuration(self, key_type: type, value: object): self._config[key_type] = value - def get_config_by_type(self, search_type: type) -> Callable[ConfigurationModelBase]: + def get_configuration(self, search_type: type) -> ConfigurationModelBase: if search_type not in self._config: raise Exception(f'Config model by type {search_type} not found') for config_model in self._config: if config_model == search_type: return self._config[config_model] + + def create(self): + pass diff --git a/src/sh_edraft/configuration/model/__init__.py b/src/sh_edraft/configuration/model/__init__.py new file mode 100644 index 00000000..a3c9f248 --- /dev/null +++ b/src/sh_edraft/configuration/model/__init__.py @@ -0,0 +1,3 @@ +# imports: + +from .configuration_variable_name import ConfigurationVariableName diff --git a/src/sh_edraft/configuration/model/configuration_variable_name.py b/src/sh_edraft/configuration/model/configuration_variable_name.py new file mode 100644 index 00000000..c89deb88 --- /dev/null +++ b/src/sh_edraft/configuration/model/configuration_variable_name.py @@ -0,0 +1,12 @@ +from enum import Enum + + +class ConfigurationVariableName(Enum): + + environment = 'ENVIRONMENT' + name = 'NAME' + customer = 'CUSTOMER' + + @staticmethod + def to_list(): + return [var.value for var in ConfigurationVariableName] diff --git a/src/sh_edraft/environment/__init__.py b/src/sh_edraft/environment/__init__.py new file mode 100644 index 00000000..28c021f3 --- /dev/null +++ b/src/sh_edraft/environment/__init__.py @@ -0,0 +1,3 @@ +# imports: + +from .hosting_environment import HostingEnvironment diff --git a/src/sh_edraft/environment/base/__init__.py b/src/sh_edraft/environment/base/__init__.py new file mode 100644 index 00000000..fec6499d --- /dev/null +++ b/src/sh_edraft/environment/base/__init__.py @@ -0,0 +1,3 @@ +# imports: + +from .environment_base import EnvironmentBase diff --git a/src/sh_edraft/environment/base/environment_base.py b/src/sh_edraft/environment/base/environment_base.py new file mode 100644 index 00000000..9d78d598 --- /dev/null +++ b/src/sh_edraft/environment/base/environment_base.py @@ -0,0 +1,45 @@ +from abc import ABC, abstractmethod + +from sh_edraft.environment.model.environment_name import EnvironmentName + + +class EnvironmentBase(ABC): + + @abstractmethod + def __init__(self): pass + + @property + @abstractmethod + def environment_name(self) -> EnvironmentName: pass + + @environment_name.setter + @abstractmethod + def environment_name(self, environment_name: EnvironmentName): pass + + @property + @abstractmethod + def application_name(self) -> str: pass + + @application_name.setter + @abstractmethod + def application_name(self, application_name: str): pass + + @property + @abstractmethod + def customer(self) -> str: pass + + @customer.setter + @abstractmethod + def customer(self, customer: str): pass + + @property + @abstractmethod + def content_root_path(self) -> str: pass + + @content_root_path.setter + @abstractmethod + def content_root_path(self, content_root_path: str): pass + + @property + @abstractmethod + def host_name(self) -> str: pass diff --git a/src/sh_edraft/environment/hosting_environment.py b/src/sh_edraft/environment/hosting_environment.py new file mode 100644 index 00000000..3840a3d2 --- /dev/null +++ b/src/sh_edraft/environment/hosting_environment.py @@ -0,0 +1,52 @@ +from socket import gethostname +from typing import Optional + +from sh_edraft.environment.base.environment_base import EnvironmentBase +from sh_edraft.environment.model.environment_name import EnvironmentName + + +class HostingEnvironment(EnvironmentBase): + + def __init__(self, name: EnvironmentName = EnvironmentName.production, crp: str = './'): + EnvironmentBase.__init__(self) + + self._environment_name: Optional[EnvironmentName] = name + self._app_name: Optional[str] = None + self._customer: Optional[str] = None + self._content_root_path: Optional[str] = crp + + @property + def environment_name(self) -> EnvironmentName: + return self._environment_name + + @environment_name.setter + def environment_name(self, environment_name: EnvironmentName): + self._environment_name = environment_name + + @property + def application_name(self) -> str: + return self._app_name if self._app_name is not None else '' + + @application_name.setter + def application_name(self, application_name: str): + self._app_name = application_name + + @property + def customer(self) -> str: + return self._customer if self._customer is not None else '' + + @customer.setter + def customer(self, customer: str): + self._customer = customer + + @property + def content_root_path(self) -> str: + return self._content_root_path + + @content_root_path.setter + def content_root_path(self, content_root_path: str): + self._content_root_path = content_root_path + + @property + def host_name(self): + return gethostname() diff --git a/src/sh_edraft/environment/model/__init__.py b/src/sh_edraft/environment/model/__init__.py new file mode 100644 index 00000000..3204981f --- /dev/null +++ b/src/sh_edraft/environment/model/__init__.py @@ -0,0 +1,3 @@ +# imports: + +from .environment_name import EnvironmentName diff --git a/src/sh_edraft/hosting/model/environment_name.py b/src/sh_edraft/environment/model/environment_name.py similarity index 100% rename from src/sh_edraft/hosting/model/environment_name.py rename to src/sh_edraft/environment/model/environment_name.py diff --git a/src/sh_edraft/hosting/__init__.py b/src/sh_edraft/hosting/__init__.py index 2a8b8615..ec999843 100644 --- a/src/sh_edraft/hosting/__init__.py +++ b/src/sh_edraft/hosting/__init__.py @@ -1,4 +1,4 @@ # imports: from .application_host import ApplicationHost -from .hosting_environment import HostingEnvironment +from .application_runtime import ApplicationRuntime diff --git a/src/sh_edraft/hosting/application_host.py b/src/sh_edraft/hosting/application_host.py index 09eafb99..1960b419 100644 --- a/src/sh_edraft/hosting/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -4,8 +4,6 @@ from datetime import datetime from sh_edraft.configuration.configuration import Configuration from sh_edraft.configuration.base.configuration_base import ConfigurationBase from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase -from sh_edraft.hosting.base.environment_base import EnvironmentBase -from sh_edraft.hosting.hosting_environment import HostingEnvironment from sh_edraft.hosting.application_runtime import ApplicationRuntime from sh_edraft.hosting.base.application_host_base import ApplicationHostBase from sh_edraft.service.service_provider import ServiceProvider @@ -14,31 +12,19 @@ from sh_edraft.service.base.service_provider_base import ServiceProviderBase class ApplicationHost(ApplicationHostBase): - def __init__(self, name: str): + def __init__(self): ApplicationHostBase.__init__(self) - self._name: str = name - self._args: list[str] = sys.argv - self._config = Configuration() - self._environment = HostingEnvironment() - self._app_runtime = ApplicationRuntime(self._config, self._environment) + self._app_runtime = ApplicationRuntime(self._config) self._services = ServiceProvider(self._app_runtime) self._start_time: datetime = datetime.now() self._end_time: datetime = datetime.now() - @property - def name(self) -> str: - return self._name - @property def configuration(self) -> ConfigurationBase: return self._config - @property - def environment(self) -> EnvironmentBase: - return self._environment - @property def application_runtime(self) -> ApplicationRuntimeBase: return self._app_runtime diff --git a/src/sh_edraft/hosting/application_runtime.py b/src/sh_edraft/hosting/application_runtime.py index e4ce40c1..5e903bb5 100644 --- a/src/sh_edraft/hosting/application_runtime.py +++ b/src/sh_edraft/hosting/application_runtime.py @@ -1,24 +1,18 @@ from datetime import datetime from sh_edraft.configuration.base.configuration_base import ConfigurationBase -from sh_edraft.hosting.base.environment_base import EnvironmentBase from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase class ApplicationRuntime(ApplicationRuntimeBase): - def __init__(self, config: ConfigurationBase, environment: EnvironmentBase): + def __init__(self, config: ConfigurationBase): ApplicationRuntimeBase.__init__(self) - self._environment = environment self._app_configuration = config self._start_time: datetime = datetime.now() self._end_time: datetime = datetime.now() - @property - def environment(self) -> EnvironmentBase: - return self._environment - @property def configuration(self) -> ConfigurationBase: return self._app_configuration diff --git a/src/sh_edraft/hosting/base/__init__.py b/src/sh_edraft/hosting/base/__init__.py index 2bafd17e..dfb25a31 100644 --- a/src/sh_edraft/hosting/base/__init__.py +++ b/src/sh_edraft/hosting/base/__init__.py @@ -1,4 +1,4 @@ # imports: -from .application_host_base import ApplicationHostBase -from .environment_base import EnvironmentBase from .application_base import ApplicationBase +from .application_host_base import ApplicationHostBase +from .application_runtime_base import ApplicationRuntimeBase diff --git a/src/sh_edraft/hosting/base/application_host_base.py b/src/sh_edraft/hosting/base/application_host_base.py index 117ec546..4ee8c0f5 100644 --- a/src/sh_edraft/hosting/base/application_host_base.py +++ b/src/sh_edraft/hosting/base/application_host_base.py @@ -2,7 +2,6 @@ from abc import ABC, abstractmethod from sh_edraft.configuration.base.configuration_base import ConfigurationBase from sh_edraft.hosting.base.application_runtime_base import ApplicationRuntimeBase -from sh_edraft.hosting.base.environment_base import EnvironmentBase from sh_edraft.service.base.service_provider_base import ServiceProviderBase @@ -10,19 +9,11 @@ class ApplicationHostBase(ABC): @abstractmethod def __init__(self): pass - - @property - @abstractmethod - def name(self) -> str: pass @property @abstractmethod def configuration(self) -> ConfigurationBase: pass - @property - @abstractmethod - def environment(self) -> EnvironmentBase: pass - @property @abstractmethod def application_runtime(self) -> ApplicationRuntimeBase: pass diff --git a/src/sh_edraft/hosting/base/application_runtime_base.py b/src/sh_edraft/hosting/base/application_runtime_base.py index 8d5ec5cc..fd644270 100644 --- a/src/sh_edraft/hosting/base/application_runtime_base.py +++ b/src/sh_edraft/hosting/base/application_runtime_base.py @@ -2,7 +2,6 @@ from abc import ABC, abstractmethod from datetime import datetime from sh_edraft.configuration.base.configuration_base import ConfigurationBase -from sh_edraft.hosting.base.environment_base import EnvironmentBase class ApplicationRuntimeBase(ABC): @@ -10,10 +9,6 @@ class ApplicationRuntimeBase(ABC): @abstractmethod def __init__(self): pass - @property - @abstractmethod - def environment(self) -> EnvironmentBase: pass - @property @abstractmethod def configuration(self) -> ConfigurationBase: pass diff --git a/src/sh_edraft/hosting/base/environment_base.py b/src/sh_edraft/hosting/base/environment_base.py deleted file mode 100644 index 99cfaa18..00000000 --- a/src/sh_edraft/hosting/base/environment_base.py +++ /dev/null @@ -1,25 +0,0 @@ -from abc import ABC, abstractmethod - -from sh_edraft.hosting.model.environment_name import EnvironmentName - - -class EnvironmentBase(ABC): - - @abstractmethod - def __init__(self): pass - - @property - @abstractmethod - def name(self) -> EnvironmentName: pass - - @name.setter - @abstractmethod - def name(self, name: EnvironmentName): pass - - @property - @abstractmethod - def content_root_path(self) -> str: pass - - @content_root_path.setter - @abstractmethod - def content_root_path(self, content_root_path: str): pass diff --git a/src/sh_edraft/hosting/hosting_environment.py b/src/sh_edraft/hosting/hosting_environment.py deleted file mode 100644 index e1ecc15b..00000000 --- a/src/sh_edraft/hosting/hosting_environment.py +++ /dev/null @@ -1,29 +0,0 @@ -from typing import Optional - -from sh_edraft.hosting.base.environment_base import EnvironmentBase -from sh_edraft.hosting.model.environment_name import EnvironmentName - - -class HostingEnvironment(EnvironmentBase): - - def __init__(self, name: EnvironmentName = EnvironmentName.production, crp: str = './'): - EnvironmentBase.__init__(self) - - self._name: Optional[EnvironmentName] = name - self._content_root_path: Optional[str] = crp - - @property - def name(self) -> EnvironmentName: - return self._name - - @name.setter - def name(self, name: EnvironmentName): - self._name = name - - @property - def content_root_path(self) -> str: - return self._content_root_path - - @content_root_path.setter - def content_root_path(self, content_root_path: str): - self._content_root_path = content_root_path diff --git a/src/sh_edraft/hosting/model/__init__.py b/src/sh_edraft/hosting/model/__init__.py index b8692da2..52f86f25 100644 --- a/src/sh_edraft/hosting/model/__init__.py +++ b/src/sh_edraft/hosting/model/__init__.py @@ -1,2 +1 @@ # imports: -from .environment_name import EnvironmentName \ No newline at end of file diff --git a/src/sh_edraft/logging/model/__init__.py b/src/sh_edraft/logging/model/__init__.py index 6712752d..8c8ce494 100644 --- a/src/sh_edraft/logging/model/__init__.py +++ b/src/sh_edraft/logging/model/__init__.py @@ -22,6 +22,7 @@ from collections import namedtuple # imports: from .logging_level import LoggingLevel from .logging_settings import LoggingSettings +from .logging_settings_name import LoggingSettingsName VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=5) diff --git a/src/sh_edraft/logging/model/logging_settings.py b/src/sh_edraft/logging/model/logging_settings.py index c5d1d77e..47889dea 100644 --- a/src/sh_edraft/logging/model/logging_settings.py +++ b/src/sh_edraft/logging/model/logging_settings.py @@ -2,7 +2,7 @@ import traceback from typing import Optional from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase -from sh_edraft.logging.model.logging_settings_name import LogSettingsName +from sh_edraft.logging.model.logging_settings_name import LoggingSettingsName from sh_edraft.utils.console import Console from sh_edraft.logging.model.logging_level import LoggingLevel @@ -11,7 +11,6 @@ class LoggingSettings(ConfigurationModelBase): def __init__(self): ConfigurationModelBase.__init__(self) - self._path: Optional[str] = None self._filename: Optional[str] = None self._console: Optional[LoggingLevel] = None @@ -51,10 +50,10 @@ class LoggingSettings(ConfigurationModelBase): def from_dict(self, settings: dict): try: - self._path = settings[LogSettingsName.path.value] - self._filename = settings[LogSettingsName.filename.value] - self._console = LoggingLevel[settings[LogSettingsName.console_level.value]] - self._level = LoggingLevel[settings[LogSettingsName.file_level.value]] + self._path = settings[LoggingSettingsName.path.value] + self._filename = settings[LoggingSettingsName.filename.value] + self._console = LoggingLevel[settings[LoggingSettingsName.console_level.value]] + self._level = LoggingLevel[settings[LoggingSettingsName.file_level.value]] except Exception as e: - Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {LogSettingsName.log.value} settings', 'red') + Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings', 'red') Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}', 'red') diff --git a/src/sh_edraft/logging/model/logging_settings_name.py b/src/sh_edraft/logging/model/logging_settings_name.py index 3bd90037..323e5735 100644 --- a/src/sh_edraft/logging/model/logging_settings_name.py +++ b/src/sh_edraft/logging/model/logging_settings_name.py @@ -1,9 +1,8 @@ from enum import Enum -class LogSettingsName(Enum): +class LoggingSettingsName(Enum): - log = 'Log' path = 'Path' filename = 'Filename' console_level = 'ConsoleLogLevel' diff --git a/src/sh_edraft/service/service_provider.py b/src/sh_edraft/service/service_provider.py index 40173ea0..4207b0f5 100644 --- a/src/sh_edraft/service/service_provider.py +++ b/src/sh_edraft/service/service_provider.py @@ -33,7 +33,7 @@ class ServiceProvider(ServiceProviderBase): params.append(self.get_service(parameter.annotation)) elif issubclass(parameter.annotation, ConfigurationModelBase): - params.append(self._app_runtime.configuration.get_config_by_type(parameter.annotation)) + params.append(self._app_runtime.configuration.get_configuration(parameter.annotation)) return service(*params) diff --git a/src/sh_edraft/time/model/time_format_settings.py b/src/sh_edraft/time/model/time_format_settings.py index f092e27b..64508ef2 100644 --- a/src/sh_edraft/time/model/time_format_settings.py +++ b/src/sh_edraft/time/model/time_format_settings.py @@ -9,6 +9,7 @@ from sh_edraft.utils.console import Console class TimeFormatSettings(ConfigurationModelBase): def __init__(self): + ConfigurationModelBase.__init__(self) self._date_format: Optional[str] = None self._time_format: Optional[str] = None self._date_time_format: Optional[str] = None @@ -55,5 +56,5 @@ class TimeFormatSettings(ConfigurationModelBase): self._date_time_format = settings[TimeFormatSettingsNames.date_time_format.value] self._date_time_log_format = settings[TimeFormatSettingsNames.date_time_log_format.value] except Exception as e: - Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {TimeFormatSettingsNames.formats.value} settings') + Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings') Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}', 'red') diff --git a/src/sh_edraft/time/model/time_format_settings_names.py b/src/sh_edraft/time/model/time_format_settings_names.py index 4afc21cd..3858de10 100644 --- a/src/sh_edraft/time/model/time_format_settings_names.py +++ b/src/sh_edraft/time/model/time_format_settings_names.py @@ -3,7 +3,6 @@ from enum import Enum class TimeFormatSettingsNames(Enum): - formats = 'TimeFormats' date_format = 'DateFormat' time_format = 'TimeFormat' date_time_format = 'DateTimeFormat' diff --git a/src/tests_dev/appsettings.development.json b/src/tests_dev/appsettings.development.json new file mode 100644 index 00000000..62ec6c61 --- /dev/null +++ b/src/tests_dev/appsettings.development.json @@ -0,0 +1,8 @@ +{ + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + } +} \ No newline at end of file diff --git a/src/tests_dev/appsettings.json b/src/tests_dev/appsettings.json new file mode 100644 index 00000000..fd8ddf6c --- /dev/null +++ b/src/tests_dev/appsettings.json @@ -0,0 +1,15 @@ +{ + "TimeFormatSettings": { + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }, + + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "ERROR", + "FileLogLevel": "WARN" + } +} \ No newline at end of file diff --git a/src/tests_dev/program.py b/src/tests_dev/program.py index 5c8a6356..7d4e7494 100644 --- a/src/tests_dev/program.py +++ b/src/tests_dev/program.py @@ -3,12 +3,9 @@ from typing import Optional from sh_edraft.configuration.base import ConfigurationBase from sh_edraft.hosting import ApplicationHost from sh_edraft.hosting.base import ApplicationBase -from sh_edraft.hosting.model import EnvironmentName from sh_edraft.logging import Logger from sh_edraft.logging.base import LoggerBase -from sh_edraft.logging.model import LoggingSettings from sh_edraft.service.base import ServiceProviderBase -from sh_edraft.time.model import TimeFormatSettings class Program(ApplicationBase): @@ -22,40 +19,28 @@ class Program(ApplicationBase): self._configuration: Optional[ConfigurationBase] = None def create_application_host(self): - self._app_host = ApplicationHost('CPL_DEV_Test') + self._app_host = ApplicationHost() self._services = self._app_host.services self._configuration = self._app_host.configuration - self._app_host.environment.name = EnvironmentName.development - def create_configuration(self): self._configuration.create() - - log_settings = LoggingSettings() - log_settings.from_dict({ - "Path": "logs/", - "Filename": "log_$start_time.log", - "ConsoleLogLevel": "TRACE", - "FileLogLevel": "TRACE" - }) - - time_format_settings = TimeFormatSettings() - time_format_settings.from_dict({ - "DateFormat": "%Y-%m-%d", - "TimeFormat": "%H:%M:%S", - "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", - "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" - }) - - self._configuration.add_config_by_type(LoggingSettings, log_settings) - self._configuration.add_config_by_type(TimeFormatSettings, time_format_settings) + self._configuration.add_environment_variables('PYTHON_') + self._configuration.add_environment_variables('CPL_') + self._configuration.add_argument_variables() + self._configuration.add_json_file(f'appsettings.json') + self._configuration.add_json_file(f'appsettings.{self._configuration.environment.environment_name}.json') + self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True) def create_services(self): self._services.create() self._services.add_singleton(LoggerBase, Logger) logger: Logger = self._services.get_service(LoggerBase) logger.create() - logger.header(self._app_host.name) + logger.header(f'{self._configuration.environment.application_name}:') + logger.debug(__name__, f'Host: {self._configuration.environment.host_name}') + logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}') + logger.debug(__name__, f'Customer: {self._configuration.environment.customer}') def main(self): print('RUN') From b14446272abdd7b9bfe7ff5913f143fa3173a48a Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 29 Nov 2020 11:32:35 +0100 Subject: [PATCH 12/14] Improved configuration and testing --- src/sh_edraft/configuration/configuration.py | 2 +- src/sh_edraft/publishing/model/__init__.py | 2 +- .../model/publish_settings_model.py | 2 +- src/sh_edraft/publishing/publisher.py | 6 +-- src/tests/appsettings.development.json | 8 +++ src/tests/appsettings.json | 15 ++++++ src/tests/appsettings.testing.json | 17 ++++++ src/tests/publishing/publisher.py | 4 +- .../service_providing/service_provider.py | 54 +++++-------------- src/tests/tester.py | 22 ++++---- 10 files changed, 73 insertions(+), 59 deletions(-) create mode 100644 src/tests/appsettings.development.json create mode 100644 src/tests/appsettings.json create mode 100644 src/tests/appsettings.testing.json diff --git a/src/sh_edraft/configuration/configuration.py b/src/sh_edraft/configuration/configuration.py index 8c02be21..0b311d6e 100644 --- a/src/sh_edraft/configuration/configuration.py +++ b/src/sh_edraft/configuration/configuration.py @@ -98,7 +98,7 @@ class Configuration(ConfigurationBase): self._print_error(__name__, f'Cannot load config file: {file}! -> {e}') return {} - def add_configuration(self, key_type: type, value: object): + def add_configuration(self, key_type: type, value: ConfigurationModelBase): self._config[key_type] = value def get_configuration(self, search_type: type) -> ConfigurationModelBase: diff --git a/src/sh_edraft/publishing/model/__init__.py b/src/sh_edraft/publishing/model/__init__.py index 4017b71c..98f26949 100644 --- a/src/sh_edraft/publishing/model/__init__.py +++ b/src/sh_edraft/publishing/model/__init__.py @@ -22,7 +22,7 @@ from collections import namedtuple # imports: from .template import Template from .template_enum import TemplateEnum -from .publish_settings_model import PublishSettingsModel +from .publish_settings_model import PublishSettings from .publish_settings_name import PublishSettingsName VersionInfo = namedtuple('VersionInfo', 'major minor micro') diff --git a/src/sh_edraft/publishing/model/publish_settings_model.py b/src/sh_edraft/publishing/model/publish_settings_model.py index 898d01d9..3886262d 100644 --- a/src/sh_edraft/publishing/model/publish_settings_model.py +++ b/src/sh_edraft/publishing/model/publish_settings_model.py @@ -7,7 +7,7 @@ from sh_edraft.publishing.model.publish_settings_name import PublishSettingsName from sh_edraft.utils import Console -class PublishSettingsModel(ConfigurationModelBase): +class PublishSettings(ConfigurationModelBase): def __init__(self): ConfigurationModelBase.__init__(self) diff --git a/src/sh_edraft/publishing/publisher.py b/src/sh_edraft/publishing/publisher.py index 573c11f5..2e922f36 100644 --- a/src/sh_edraft/publishing/publisher.py +++ b/src/sh_edraft/publishing/publisher.py @@ -4,17 +4,17 @@ from string import Template as stringTemplate from sh_edraft.logging.base.logger_base import LoggerBase from sh_edraft.publishing.base.publisher_base import PublisherBase -from sh_edraft.publishing.model.publish_settings_model import PublishSettingsModel +from sh_edraft.publishing.model.publish_settings_model import PublishSettings from sh_edraft.publishing.model.template import Template class Publisher(PublisherBase): - def __init__(self, logger: LoggerBase, publish_settings: PublishSettingsModel): + def __init__(self, logger: LoggerBase, publish_settings: PublishSettings): PublisherBase.__init__(self) self._logger: LoggerBase = logger - self._publish_settings: PublishSettingsModel = publish_settings + self._publish_settings: PublishSettings = publish_settings @property def source_path(self) -> str: diff --git a/src/tests/appsettings.development.json b/src/tests/appsettings.development.json new file mode 100644 index 00000000..62ec6c61 --- /dev/null +++ b/src/tests/appsettings.development.json @@ -0,0 +1,8 @@ +{ + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + } +} \ No newline at end of file diff --git a/src/tests/appsettings.json b/src/tests/appsettings.json new file mode 100644 index 00000000..fd8ddf6c --- /dev/null +++ b/src/tests/appsettings.json @@ -0,0 +1,15 @@ +{ + "TimeFormatSettings": { + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }, + + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "ERROR", + "FileLogLevel": "WARN" + } +} \ No newline at end of file diff --git a/src/tests/appsettings.testing.json b/src/tests/appsettings.testing.json new file mode 100644 index 00000000..3b586a2c --- /dev/null +++ b/src/tests/appsettings.testing.json @@ -0,0 +1,17 @@ +{ + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }, + + "PublishSettings": { + "SourcePath": "../", + "DistPath": "../../dist", + "Templates": [], + "IncludedFiles": [], + "ExcludedFiles": [], + "TemplateEnding": "_template.txt" + } +} \ No newline at end of file diff --git a/src/tests/publishing/publisher.py b/src/tests/publishing/publisher.py index a9e91254..47bc67b2 100644 --- a/src/tests/publishing/publisher.py +++ b/src/tests/publishing/publisher.py @@ -8,7 +8,7 @@ from sh_edraft.logging import Logger from sh_edraft.logging.model import LoggingSettings from sh_edraft.publishing import Publisher from sh_edraft.publishing.model import Template -from sh_edraft.publishing.model import PublishSettingsModel +from sh_edraft.publishing.model import PublishSettings from sh_edraft.coding.model import Version from sh_edraft.time.model import TimeFormatSettings @@ -65,7 +65,7 @@ class PublisherTest(unittest.TestCase): self._source_path = '../' self._dist_path = '../../dist' - self._publish_settings_model = PublishSettingsModel() + self._publish_settings_model = PublishSettings() self._publish_settings_model.from_dict({ "SourcePath": self._source_path, "DistPath": self._dist_path, diff --git a/src/tests/service_providing/service_provider.py b/src/tests/service_providing/service_provider.py index 6efbcfbb..4ddc5734 100644 --- a/src/tests/service_providing/service_provider.py +++ b/src/tests/service_providing/service_provider.py @@ -1,58 +1,30 @@ import unittest -from collections import Callable -from typing import Type, cast +from typing import cast from sh_edraft.hosting import ApplicationHost from sh_edraft.logging import Logger from sh_edraft.logging.base import LoggerBase -from sh_edraft.logging.model import LoggingSettings from sh_edraft.publishing import Publisher from sh_edraft.publishing.base import PublisherBase -from sh_edraft.publishing.model import PublishSettingsModel from sh_edraft.service import ServiceProvider from sh_edraft.service.base import ServiceBase -from sh_edraft.time.model import TimeFormatSettings class ServiceProviderTest(unittest.TestCase): def setUp(self): - self._app_host = ApplicationHost('CPL_Test') + self._app_host = ApplicationHost() self._config = self._app_host.configuration self._config.create() + self._config.add_environment_variables('PYTHON_') + self._config.add_environment_variables('CPL_') + self._config.add_argument_variables() + self._config.add_json_file(f'appsettings.json') + self._config.add_json_file(f'appsettings.{self._config.environment.environment_name}.json') + self._config.add_json_file(f'appsettings.{self._config.environment.host_name}.json', optional=True) self._services: ServiceProvider = cast(ServiceProvider, self._app_host.services) self._services.create() - self._log_settings = LoggingSettings() - self._log_settings.from_dict({ - "Path": "logs/", - "Filename": "log_$start_time.log", - "ConsoleLogLevel": "TRACE", - "FileLogLevel": "TRACE" - }) - self._config.add_config_by_type(LoggingSettings, self._log_settings) - - self._time_format_settings = TimeFormatSettings() - self._time_format_settings.from_dict({ - "DateFormat": "%Y-%m-%d", - "TimeFormat": "%H:%M:%S", - "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", - "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" - }) - self._config.add_config_by_type(TimeFormatSettings, self._time_format_settings) - self._config.add_config_by_type(ApplicationHost, self._app_host) - - self._publish_settings_model = PublishSettingsModel() - self._publish_settings_model.from_dict({ - "SourcePath": "../", - "DistPath": "../../dist", - "Templates": [], - "IncludedFiles": [], - "ExcludedFiles": [], - "TemplateEnding": "_template.txt", - }) - self._config.add_config_by_type(PublishSettingsModel, self._publish_settings_model) - def _check_general_requirements(self): self.assertIsNotNone(self._services) @@ -79,7 +51,9 @@ class ServiceProviderTest(unittest.TestCase): for service_type in self._services._singleton_services: service = self._services._singleton_services[service_type] if service_type == LoggerBase and ( - isinstance(service, Logger) and isinstance(service, LoggerBase) and isinstance(service, ServiceBase) + isinstance(service, Logger) and + isinstance(service, LoggerBase) and + isinstance(service, ServiceBase) ): if not found: found = True @@ -90,7 +64,9 @@ class ServiceProviderTest(unittest.TestCase): for service_type in self._services._singleton_services: service = self._services._singleton_services[service_type] if service_type == PublisherBase and ( - isinstance(service, Publisher) and isinstance(service, PublisherBase) and isinstance(service, ServiceBase) + isinstance(service, Publisher) and + isinstance(service, PublisherBase) and + isinstance(service, ServiceBase) ): if not found: found = True @@ -108,8 +84,6 @@ class ServiceProviderTest(unittest.TestCase): self.assertTrue(isinstance(logger, LoggerBase)) self.assertTrue(isinstance(logger, ServiceBase)) - self.assertEqual(logger._log_settings, self._log_settings) - self.assertEqual(logger._time_format_settings, self._time_format_settings) self.assertEqual(logger._app_runtime, self._app_host.application_runtime) def test_add_scoped(self): diff --git a/src/tests/tester.py b/src/tests/tester.py index dfb11e49..f5326d02 100644 --- a/src/tests/tester.py +++ b/src/tests/tester.py @@ -1,7 +1,7 @@ import unittest -from tests.logging.logger import LoggerTest -from tests.publishing.publisher import PublisherTest +# from tests.logging.logger import LoggerTest +# from tests.publishing.publisher import PublisherTest from tests.service_providing.service_provider import ServiceProviderTest @@ -21,17 +21,17 @@ class Tester: self._suite.addTest(ServiceProviderTest('test_get_transient')) # logging - self._suite.addTest(LoggerTest('test_create')) - self._suite.addTest(LoggerTest('test_header')) - self._suite.addTest(LoggerTest('test_trace')) - self._suite.addTest(LoggerTest('test_debug')) - self._suite.addTest(LoggerTest('test_info')) - self._suite.addTest(LoggerTest('test_warn')) - self._suite.addTest(LoggerTest('test_error')) - self._suite.addTest(LoggerTest('test_fatal')) + # self._suite.addTest(LoggerTest('test_create')) + # self._suite.addTest(LoggerTest('test_header')) + # self._suite.addTest(LoggerTest('test_trace')) + # self._suite.addTest(LoggerTest('test_debug')) + # self._suite.addTest(LoggerTest('test_info')) + # self._suite.addTest(LoggerTest('test_warn')) + # self._suite.addTest(LoggerTest('test_error')) + # self._suite.addTest(LoggerTest('test_fatal')) # publishing - self._suite.addTest(PublisherTest('test_create')) + # self._suite.addTest(PublisherTest('test_create')) def start(self): runner = unittest.TextTestRunner() From fea84418d3db97da0ccc3ea8b79be49ba6952bde Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 29 Nov 2020 16:38:58 +0100 Subject: [PATCH 13/14] Fixed testing errors --- src/tests/logging/logger.py | 31 ++++++++++--------------- src/tests/publishing/publisher.py | 38 +++++++++++++------------------ src/tests/tester.py | 22 +++++++++--------- 3 files changed, 39 insertions(+), 52 deletions(-) diff --git a/src/tests/logging/logger.py b/src/tests/logging/logger.py index 8187ec85..4a17331e 100644 --- a/src/tests/logging/logger.py +++ b/src/tests/logging/logger.py @@ -14,28 +14,21 @@ from sh_edraft.time.model import TimeFormatSettings class LoggerTest(unittest.TestCase): def setUp(self): - app_host = ApplicationHost('CPL_Test') - self._app_runtime = app_host.application_runtime - self._config = app_host.configuration + self._app_host = ApplicationHost() + self._config = self._app_host.configuration self._config.create() - self._services: ServiceProvider = cast(ServiceProvider, app_host.services) + self._config.add_environment_variables('PYTHON_') + self._config.add_environment_variables('CPL_') + self._config.add_argument_variables() + self._config.add_json_file(f'appsettings.json') + self._config.add_json_file(f'appsettings.{self._config.environment.environment_name}.json') + self._config.add_json_file(f'appsettings.{self._config.environment.host_name}.json', optional=True) + self._services: ServiceProvider = cast(ServiceProvider, self._app_host.services) self._services.create() - self._log_settings = LoggingSettings() - self._log_settings.from_dict({ - "Path": "logs/", - "Filename": "log_$start_time.log", - "ConsoleLogLevel": "TRACE", - "FileLogLevel": "TRACE" - }) - - self._time_format_settings = TimeFormatSettings() - self._time_format_settings.from_dict({ - "DateFormat": "%Y-%m-%d", - "TimeFormat": "%H:%M:%S", - "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", - "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" - }) + self._app_runtime = self._app_host.application_runtime + self._log_settings: LoggingSettings = self._config.get_configuration(LoggingSettings) + self._time_format_settings: TimeFormatSettings = self._config.get_configuration(TimeFormatSettings) def tearDown(self): if os.path.isdir(self._log_settings.path): diff --git a/src/tests/publishing/publisher.py b/src/tests/publishing/publisher.py index 47bc67b2..4e87c8c1 100644 --- a/src/tests/publishing/publisher.py +++ b/src/tests/publishing/publisher.py @@ -2,8 +2,7 @@ import os import shutil import unittest -from sh_edraft.hosting import ApplicationHost, HostingEnvironment -from sh_edraft.hosting.model import EnvironmentName +from sh_edraft.hosting import ApplicationHost from sh_edraft.logging import Logger from sh_edraft.logging.model import LoggingSettings from sh_edraft.publishing import Publisher @@ -16,22 +15,6 @@ from sh_edraft.time.model import TimeFormatSettings class PublisherTest(unittest.TestCase): def _configure(self): - self._log_settings = LoggingSettings() - self._log_settings.from_dict({ - "Path": "logs/", - "Filename": "log_$start_time.log", - "ConsoleLogLevel": "TRACE", - "FileLogLevel": "TRACE" - }) - - self._time_format_settings = TimeFormatSettings() - self._time_format_settings.from_dict({ - "DateFormat": "%Y-%m-%d", - "TimeFormat": "%H:%M:%S", - "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", - "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" - }) - self._version = Version(2020, 12, 5).to_dict() templates = [ Template( @@ -76,12 +59,23 @@ class PublisherTest(unittest.TestCase): }) def setUp(self): + self._app_host = ApplicationHost() + self._config = self._app_host.configuration + self._config.create() + self._config.add_environment_variables('PYTHON_') + self._config.add_environment_variables('CPL_') + self._config.add_argument_variables() + self._config.add_json_file(f'appsettings.json') + self._config.add_json_file(f'appsettings.{self._config.environment.environment_name}.json') + self._config.add_json_file(f'appsettings.{self._config.environment.host_name}.json', optional=True) + + self._app_runtime = self._app_host.application_runtime + self._configure() - app_host = ApplicationHost('CPL_Test') - self._app_runtime = app_host.application_runtime - - self._logger = Logger(self._log_settings, self._time_format_settings, app_host.application_runtime) + self._log_settings: LoggingSettings = self._config.get_configuration(LoggingSettings) + self._time_format_settings: TimeFormatSettings = self._config.get_configuration(TimeFormatSettings) + self._logger = Logger(self._log_settings, self._time_format_settings, self._app_host.application_runtime) self._logger.create() def tearDown(self): diff --git a/src/tests/tester.py b/src/tests/tester.py index f5326d02..dfb11e49 100644 --- a/src/tests/tester.py +++ b/src/tests/tester.py @@ -1,7 +1,7 @@ import unittest -# from tests.logging.logger import LoggerTest -# from tests.publishing.publisher import PublisherTest +from tests.logging.logger import LoggerTest +from tests.publishing.publisher import PublisherTest from tests.service_providing.service_provider import ServiceProviderTest @@ -21,17 +21,17 @@ class Tester: self._suite.addTest(ServiceProviderTest('test_get_transient')) # logging - # self._suite.addTest(LoggerTest('test_create')) - # self._suite.addTest(LoggerTest('test_header')) - # self._suite.addTest(LoggerTest('test_trace')) - # self._suite.addTest(LoggerTest('test_debug')) - # self._suite.addTest(LoggerTest('test_info')) - # self._suite.addTest(LoggerTest('test_warn')) - # self._suite.addTest(LoggerTest('test_error')) - # self._suite.addTest(LoggerTest('test_fatal')) + self._suite.addTest(LoggerTest('test_create')) + self._suite.addTest(LoggerTest('test_header')) + self._suite.addTest(LoggerTest('test_trace')) + self._suite.addTest(LoggerTest('test_debug')) + self._suite.addTest(LoggerTest('test_info')) + self._suite.addTest(LoggerTest('test_warn')) + self._suite.addTest(LoggerTest('test_error')) + self._suite.addTest(LoggerTest('test_fatal')) # publishing - # self._suite.addTest(PublisherTest('test_create')) + self._suite.addTest(PublisherTest('test_create')) def start(self): runner = unittest.TextTestRunner() From 16516b7fe635f96b42547eb6bb66cbc3357aee0a Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 29 Nov 2020 17:29:16 +0100 Subject: [PATCH 14/14] Improved testing --- src/sh_edraft/configuration/configuration.py | 3 +- .../environment/base/environment_base.py | 6 +- .../environment/hosting_environment.py | 8 +- src/sh_edraft/hosting/application_host.py | 1 - src/sh_edraft/service/__init__.py | 4 +- src/sh_edraft/service/base/__init__.py | 4 +- src/sh_edraft/service/model/__init__.py | 4 +- src/tests/appsettings.edrafts-pc.json | 8 ++ .../{logging => configuration}/__init__.py | 0 src/tests/configuration/config.py | 93 +++++++++++++++++++ src/tests/{publishing => hosting}/__init__.py | 0 src/tests/hosting/app_host.py | 33 +++++++ src/tests/services/__init__.py | 0 src/tests/services/logging/__init__.py | 0 src/tests/{ => services}/logging/logger.py | 0 src/tests/services/publishing/__init__.py | 0 .../{ => services}/publishing/publisher.py | 1 + src/tests/tester.py | 18 +++- src/tests_dev/program.py | 17 ++-- 19 files changed, 173 insertions(+), 27 deletions(-) create mode 100644 src/tests/appsettings.edrafts-pc.json rename src/tests/{logging => configuration}/__init__.py (100%) create mode 100644 src/tests/configuration/config.py rename src/tests/{publishing => hosting}/__init__.py (100%) create mode 100644 src/tests/hosting/app_host.py create mode 100644 src/tests/services/__init__.py create mode 100644 src/tests/services/logging/__init__.py rename src/tests/{ => services}/logging/logger.py (100%) create mode 100644 src/tests/services/publishing/__init__.py rename src/tests/{ => services}/publishing/publisher.py (98%) diff --git a/src/sh_edraft/configuration/configuration.py b/src/sh_edraft/configuration/configuration.py index 0b311d6e..dc0ef33f 100644 --- a/src/sh_edraft/configuration/configuration.py +++ b/src/sh_edraft/configuration/configuration.py @@ -7,6 +7,7 @@ from sh_edraft.configuration.base.configuration_base import ConfigurationBase from sh_edraft.configuration.model.configuration_variable_name import ConfigurationVariableName from sh_edraft.environment.base.environment_base import EnvironmentBase from sh_edraft.environment.hosting_environment import HostingEnvironment +from sh_edraft.environment.model import EnvironmentName from sh_edraft.utils import Console @@ -36,7 +37,7 @@ class Configuration(ConfigurationBase): def _set_variable(self, name: str, value: str): if name == ConfigurationVariableName.environment.value: - self._hosting_environment.environment_name = value + self._hosting_environment.environment_name = EnvironmentName(value) elif name == ConfigurationVariableName.name.value: self._hosting_environment.application_name = value diff --git a/src/sh_edraft/environment/base/environment_base.py b/src/sh_edraft/environment/base/environment_base.py index 9d78d598..f5dc9266 100644 --- a/src/sh_edraft/environment/base/environment_base.py +++ b/src/sh_edraft/environment/base/environment_base.py @@ -1,7 +1,5 @@ from abc import ABC, abstractmethod -from sh_edraft.environment.model.environment_name import EnvironmentName - class EnvironmentBase(ABC): @@ -10,11 +8,11 @@ class EnvironmentBase(ABC): @property @abstractmethod - def environment_name(self) -> EnvironmentName: pass + def environment_name(self) -> str: pass @environment_name.setter @abstractmethod - def environment_name(self, environment_name: EnvironmentName): pass + def environment_name(self, environment_name: str): pass @property @abstractmethod diff --git a/src/sh_edraft/environment/hosting_environment.py b/src/sh_edraft/environment/hosting_environment.py index 3840a3d2..2f2021ff 100644 --- a/src/sh_edraft/environment/hosting_environment.py +++ b/src/sh_edraft/environment/hosting_environment.py @@ -16,12 +16,12 @@ class HostingEnvironment(EnvironmentBase): self._content_root_path: Optional[str] = crp @property - def environment_name(self) -> EnvironmentName: - return self._environment_name + def environment_name(self) -> str: + return str(self._environment_name.value) @environment_name.setter - def environment_name(self, environment_name: EnvironmentName): - self._environment_name = environment_name + def environment_name(self, environment_name: str): + self._environment_name = EnvironmentName(environment_name) @property def application_name(self) -> str: diff --git a/src/sh_edraft/hosting/application_host.py b/src/sh_edraft/hosting/application_host.py index 1960b419..e5e6b362 100644 --- a/src/sh_edraft/hosting/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -1,4 +1,3 @@ -import sys from datetime import datetime from sh_edraft.configuration.configuration import Configuration diff --git a/src/sh_edraft/service/__init__.py b/src/sh_edraft/service/__init__.py index dbc93593..52003f0b 100644 --- a/src/sh_edraft/service/__init__.py +++ b/src/sh_edraft/service/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.service +sh_edraft.services ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.service """ -__title__ = 'sh_edraft.service' +__title__ = 'sh_edraft.services' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/service/base/__init__.py b/src/sh_edraft/service/base/__init__.py index e2c43c24..6ce7f45b 100644 --- a/src/sh_edraft/service/base/__init__.py +++ b/src/sh_edraft/service/base/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.service.base +sh_edraft.services.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.service.base """ -__title__ = 'sh_edraft.service.base' +__title__ = 'sh_edraft.services.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/service/model/__init__.py b/src/sh_edraft/service/model/__init__.py index 96c24ada..b95fe3c2 100644 --- a/src/sh_edraft/service/model/__init__.py +++ b/src/sh_edraft/service/model/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.service.base +sh_edraft.services.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.service.base """ -__title__ = 'sh_edraft.service.base' +__title__ = 'sh_edraft.services.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/tests/appsettings.edrafts-pc.json b/src/tests/appsettings.edrafts-pc.json new file mode 100644 index 00000000..62ec6c61 --- /dev/null +++ b/src/tests/appsettings.edrafts-pc.json @@ -0,0 +1,8 @@ +{ + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + } +} \ No newline at end of file diff --git a/src/tests/logging/__init__.py b/src/tests/configuration/__init__.py similarity index 100% rename from src/tests/logging/__init__.py rename to src/tests/configuration/__init__.py diff --git a/src/tests/configuration/config.py b/src/tests/configuration/config.py new file mode 100644 index 00000000..27218978 --- /dev/null +++ b/src/tests/configuration/config.py @@ -0,0 +1,93 @@ +import os +import unittest +from typing import cast + +from sh_edraft.configuration import Configuration +from sh_edraft.environment.model import EnvironmentName +from sh_edraft.hosting import ApplicationHost +from sh_edraft.logging.model import LoggingSettings, LoggingLevel +from sh_edraft.publishing.model import PublishSettings +from sh_edraft.time.model import TimeFormatSettings + + +class ConfigTest(unittest.TestCase): + + def setUp(self): + self._app_host = ApplicationHost() + self._config = cast(Configuration, self._app_host.configuration) + + def test_create(self): + print(f'{__name__}.test_create:') + self.assertIsNotNone(self._config) + self._config.create() + self.assertIsNotNone(self._config) + + self.assertEqual(len(self._config._config), 0) + self.assertIsNotNone(self._app_host.application_runtime) + + def test_env_vars(self): + print(f'{__name__}.test_env_vars:') + self._config.add_environment_variables('PYTHON_') + self._config.add_environment_variables('CPL_') + + def test_arguments(self): + print(f'{__name__}.test_arguments:') + self._config.add_argument_variables() + self.assertEqual(self._config.environment.environment_name, EnvironmentName.testing.value) + + def test_appsettings(self): + print(f'{__name__}.test_appsettings:') + self._config.add_json_file(f'appsettings.json') + + time_formats: TimeFormatSettings = cast(TimeFormatSettings, self._config.get_configuration(TimeFormatSettings)) + self.assertIsNotNone(time_formats) + self.assertEqual(time_formats.date_format, '%Y-%m-%d') + self.assertEqual(time_formats.time_format, '%H:%M:%S') + self.assertEqual(time_formats.date_time_format, '%Y-%m-%d %H:%M:%S.%f') + self.assertEqual(time_formats.date_time_log_format, '%Y-%m-%d_%H-%M-%S') + + logging = cast(LoggingSettings, self._config.get_configuration(LoggingSettings)) + self.assertIsNotNone(logging) + self.assertEqual(logging.path, 'logs/') + self.assertEqual(logging.filename, 'log_$start_time.log') + self.assertEqual(logging.console.value, LoggingLevel.ERROR.value) + self.assertEqual(logging.level.value, LoggingLevel.WARN.value) + + with self.assertRaises(Exception): + publish: PublishSettings = cast(PublishSettings, self._config.get_configuration(PublishSettings)) + + def test_appsettings_environment(self): + print(f'{__name__}.test_appsettings_environment:') + self._config.add_argument_variables() + self._config.add_json_file(f'appsettings.{self._config.environment.environment_name}.json') + + logging = cast(LoggingSettings, self._config.get_configuration(LoggingSettings)) + self.assertIsNotNone(logging) + self.assertEqual(logging.path, 'logs/') + self.assertEqual(logging.filename, 'log_$start_time.log') + self.assertEqual(logging.console.value, LoggingLevel.TRACE.value) + self.assertEqual(logging.level.value, LoggingLevel.TRACE.value) + + publish: PublishSettings = cast(PublishSettings, self._config.get_configuration(PublishSettings)) + self.assertIsNotNone(publish) + self.assertEqual(publish.source_path, '../') + self.assertEqual(publish.dist_path, '../../dist') + self.assertEqual(publish.templates, []) + self.assertEqual(publish.included_files, []) + self.assertEqual(publish.excluded_files, []) + self.assertEqual(publish.template_ending, '_template.txt') + + def test_appsettings_host(self): + print(f'{__name__}.test_appsettings_host:') + self._config.add_json_file(f'appsettings.{self._config.environment.host_name}.json') + + def test_appsettings_customer(self): + print(f'{__name__}.test_appsettings_customer:') + file_name = f'appsettings.{self._config.environment.customer}.json' + with self.assertRaises(SystemExit): + if os.path.isfile(f'{self._config.environment.content_root_path}/{file_name}'): + os.remove(f'{self._config.environment.content_root_path}/{file_name}') + + self._config.add_json_file(file_name) + + self._config.add_json_file(file_name, optional=True) diff --git a/src/tests/publishing/__init__.py b/src/tests/hosting/__init__.py similarity index 100% rename from src/tests/publishing/__init__.py rename to src/tests/hosting/__init__.py diff --git a/src/tests/hosting/app_host.py b/src/tests/hosting/app_host.py new file mode 100644 index 00000000..ec940481 --- /dev/null +++ b/src/tests/hosting/app_host.py @@ -0,0 +1,33 @@ +import unittest +import datetime + +from sh_edraft.configuration.base import ConfigurationBase +from sh_edraft.hosting import ApplicationHost +from sh_edraft.hosting.base import ApplicationRuntimeBase +from sh_edraft.service.base import ServiceProviderBase + + +class AppHostTest(unittest.TestCase): + + def setUp(self): + pass + + def test_create(self): + print(f'{__name__}.test_create:') + app_host = ApplicationHost() + self.assertIsNotNone(app_host) + app_host.create() + + self.assertIsNotNone(app_host.configuration) + self.assertTrue(isinstance(app_host.configuration, ConfigurationBase)) + + self.assertIsNotNone(app_host.application_runtime) + self.assertTrue(isinstance(app_host.application_runtime, ApplicationRuntimeBase)) + + self.assertIsNotNone(app_host.services) + self.assertTrue(isinstance(app_host.services, ServiceProviderBase)) + + self.assertIsNotNone(app_host._start_time) + self.assertTrue(isinstance(app_host._start_time, datetime.datetime)) + self.assertIsNotNone(app_host._end_time) + self.assertTrue(isinstance(app_host._end_time, datetime.datetime)) diff --git a/src/tests/services/__init__.py b/src/tests/services/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/services/logging/__init__.py b/src/tests/services/logging/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/logging/logger.py b/src/tests/services/logging/logger.py similarity index 100% rename from src/tests/logging/logger.py rename to src/tests/services/logging/logger.py diff --git a/src/tests/services/publishing/__init__.py b/src/tests/services/publishing/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/publishing/publisher.py b/src/tests/services/publishing/publisher.py similarity index 98% rename from src/tests/publishing/publisher.py rename to src/tests/services/publishing/publisher.py index 4e87c8c1..afb17eaa 100644 --- a/src/tests/publishing/publisher.py +++ b/src/tests/services/publishing/publisher.py @@ -83,6 +83,7 @@ class PublisherTest(unittest.TestCase): shutil.rmtree(self._log_settings.path) def test_create(self): + print(f'{__name__}.test_create:') publisher: Publisher = Publisher(self._logger, self._publish_settings_model) self.assertIsNotNone(publisher) diff --git a/src/tests/tester.py b/src/tests/tester.py index dfb11e49..d7b17030 100644 --- a/src/tests/tester.py +++ b/src/tests/tester.py @@ -1,7 +1,9 @@ import unittest -from tests.logging.logger import LoggerTest -from tests.publishing.publisher import PublisherTest +from tests.configuration.config import ConfigTest +from tests.hosting.app_host import AppHostTest +from tests.services.logging.logger import LoggerTest +from tests.services.publishing.publisher import PublisherTest from tests.service_providing.service_provider import ServiceProviderTest @@ -11,6 +13,18 @@ class Tester: self._suite = unittest.TestSuite() def create(self): + # hosting app host + self._suite.addTest(AppHostTest('test_create')) + + # configuration + self._suite.addTest(ConfigTest('test_create')) + self._suite.addTest(ConfigTest('test_env_vars')) + self._suite.addTest(ConfigTest('test_arguments')) + self._suite.addTest(ConfigTest('test_appsettings')) + self._suite.addTest(ConfigTest('test_appsettings_environment')) + self._suite.addTest(ConfigTest('test_appsettings_host')) + self._suite.addTest(ConfigTest('test_appsettings_customer')) + # providing self._suite.addTest(ServiceProviderTest('test_create')) self._suite.addTest(ServiceProviderTest('test_add_singleton')) diff --git a/src/tests_dev/program.py b/src/tests_dev/program.py index 7d4e7494..2ee1b09b 100644 --- a/src/tests_dev/program.py +++ b/src/tests_dev/program.py @@ -14,14 +14,14 @@ class Program(ApplicationBase): ApplicationBase.__init__(self) self._app_host: Optional[ApplicationHost] = None - self._services: Optional[ServiceProviderBase] = None self._configuration: Optional[ConfigurationBase] = None + self._logger: Optional[LoggerBase] = None def create_application_host(self): self._app_host = ApplicationHost() - self._services = self._app_host.services self._configuration = self._app_host.configuration + self._services = self._app_host.services def create_configuration(self): self._configuration.create() @@ -35,12 +35,11 @@ class Program(ApplicationBase): def create_services(self): self._services.create() self._services.add_singleton(LoggerBase, Logger) - logger: Logger = self._services.get_service(LoggerBase) - logger.create() - logger.header(f'{self._configuration.environment.application_name}:') - logger.debug(__name__, f'Host: {self._configuration.environment.host_name}') - logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}') - logger.debug(__name__, f'Customer: {self._configuration.environment.customer}') + self._logger = self._services.get_service(LoggerBase) + self._logger.create() def main(self): - print('RUN') + self._logger.header(f'{self._configuration.environment.application_name}:') + self._logger.debug(__name__, f'Host: {self._configuration.environment.host_name}') + self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}') + self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}')