Exemplo n.º 1
0
def watch_dir(tmpdir):
    """Instanciate a directory watcher and stop it after its use."""
    watched_directory = Path(tmpdir)
    test_file1 = watched_directory / 'tmp_test_file1'
    recursive_dir = watched_directory / 'test_folder'
    test_file2 = recursive_dir / 'tmp_test_file2'

    class EventSaver:
        """Mock class for testing callback function."""
        def __init__(self):
            self.called = 0
            self.argument = None

        def save_argument(self, path: Path) -> None:
            self.called += 1
            self.argument = path

    event_saver = EventSaver()

    # Watch a temporary directory
    dir_watcher = DirectoryWatcher(
        directory=watched_directory,
        on_modified=event_saver.save_argument,
    )

    yield (
        watched_directory,
        recursive_dir,
        test_file1,
        test_file2,
        dir_watcher,
        event_saver,
    )

    dir_watcher.stop()

    # Cleanup files
    if test_file1.is_file():
        os.remove(test_file1)
    if test_file2.is_file():
        os.remove(test_file2)
    if recursive_dir.is_dir():
        shutil.rmtree(recursive_dir)
Exemplo n.º 2
0
def test_logging_of_os_errors(monkeypatch, tmpdir, caplog):
    """Filesystem watcher can fail due to limits, and it should be logged."""
    def raiser(self):
        raise OSError('inotify watch limit reached')

    monkeypatch.setattr(
        Observer,
        name='start',
        value=raiser,
    )

    dir_watcher = DirectoryWatcher(
        directory=tmpdir,
        on_modified=lambda x: x,
    )

    caplog.clear()
    dir_watcher.start()
    assert 'inotify watch limit reached' in caplog.record_tuples[0][2]

    dir_watcher.stop()
Exemplo n.º 3
0
def watch_dir():
    """Instanciate a directory watcher and stop it after its use."""
    class EventSaver:
        """Mock class for testing callback function."""

        def __init__(self):
            self.called = 0

        def save_argument(self, path: Path) -> None:
            self.called += 1
            self.argument = path

    event_saver = EventSaver()

    # Watch a temporary directory
    watched_directory = Path('/tmp/astrality')
    dir_watcher = DirectoryWatcher(
        directory=watched_directory,
        on_modified=event_saver.save_argument,
    )

    yield dir_watcher, event_saver

    dir_watcher.stop()
Exemplo n.º 4
0
    def __init__(
        self,
        config: AstralityYAMLConfigDict = {},
        modules: Dict[str, ModuleConfigDict] = {},
        context: Context = Context(),
        directory: Path = Path(__file__).parent / 'tests' / 'test_config',
        dry_run: bool = False,
    ) -> None:
        """Initialize a ModuleManager object from `astrality.yml` dict."""
        self.config_directory = directory
        self.application_config = config
        self.application_context = context
        self.dry_run = dry_run

        self.startup_done = False
        self.last_module_events: Dict[str, str] = {}

        # Get module configurations which are externally defined
        self.global_modules_config = GlobalModulesConfig(
            config=config.get('modules', {}),
            config_directory=self.config_directory,
        )
        self.reprocess_modified_files = \
            self.global_modules_config.reprocess_modified_files

        self.modules: Dict[str, Module] = {}

        # Insert externally managed modules
        for external_module_source \
                in self.global_modules_config.external_module_sources:
            # Insert context defined in external configuration
            module_context = external_module_source.context(
                context=self.application_context,
            )
            self.application_context.reverse_update(module_context)

            module_configs = external_module_source.modules(
                context=self.application_context,
            )
            module_directory = external_module_source.directory

            for module_name, module_config in module_configs.items():
                if module_name \
                        not in self.global_modules_config.enabled_modules:
                    continue

                if not Module.valid_module(
                    name=module_name,
                    config=module_config,
                    requires_timeout=self.global_modules_config.
                    requires_timeout,  # noqa
                    requires_working_directory=module_directory,
                ):
                    continue

                module = Module(
                    name=module_name,
                    module_config=module_config,
                    module_directory=module_directory,
                    replacer=self.interpolate_string,
                    context_store=self.application_context,
                    global_modules_config=self.global_modules_config,
                    dry_run=dry_run,
                )
                self.modules[module.name] = module

        # Insert modules defined in `astrality.yml`
        for module_name, module_config in modules.items():
            # Check if this module should be included
            if module_name not in self.global_modules_config.enabled_modules:
                continue

            if not Module.valid_module(
                name=module_name,
                config=module_config,
                requires_timeout=self.global_modules_config.requires_timeout,
                requires_working_directory=self.config_directory,
            ):
                continue

            module = Module(
                name=module_name,
                module_config=module_config,
                module_directory=self.config_directory,
                replacer=self.interpolate_string,
                context_store=self.application_context,
                global_modules_config=self.global_modules_config,
                dry_run=dry_run,
            )
            self.modules[module.name] = module

        # Remove modules which depends on other missing modules
        Requirement.pop_missing_module_dependencies(self.modules)

        # Initialize the config directory watcher, but don't start it yet
        self.directory_watcher = DirectoryWatcher(
            directory=self.config_directory,
            on_modified=self.file_system_modified,
        )

        logger.info('Enabled modules: ' + ', '.join(self.modules.keys()))
Exemplo n.º 5
0
    def __init__(self, config: ApplicationConfig) -> None:
        """Initialize a ModuleManager object from `astrality.yml` dict."""
        self.config_directory = Path(config['_runtime']['config_directory'])
        self.temp_directory = Path(config['_runtime']['temp_directory'])
        self.application_config = config
        self.application_context: Dict[str, Resolver] = {}

        self.startup_done = False
        self.last_module_events: Dict[str, str] = {}

        # Get module configurations which are externally defined
        self.global_modules_config = GlobalModulesConfig(  # type: ignore
            config=config.get('config/modules', {}),
            config_directory=self.config_directory,
        )
        self.recompile_modified_templates = \
            self.global_modules_config.recompile_modified_templates

        self.modules: Dict[str, Module] = {}

        # Application context is used in compiling external config sources
        application_context = context(config)

        # Insert externally managed modules
        for external_module_source \
                in self.global_modules_config.external_module_sources:
            module_directory = external_module_source.directory

            module_configs = external_module_source.config(
                context=application_context, )

            # Insert context defined in external configuration
            self.application_context.update(context(module_configs))

            for section, options in module_configs.items():
                module_config = {section: options}

                if not Module.valid_class_section(
                        section=module_config,
                        requires_timeout=self.global_modules_config.
                        requires_timeout,  # noqa
                        requires_working_directory=module_directory,
                ) or section not in self.global_modules_config.enabled_modules:
                    continue

                module = Module(
                    module_config=module_config,
                    module_directory=module_directory,
                    replacer=self.interpolate_string,
                    context_store=self.application_context,
                )
                self.modules[module.name] = module

        # Update the context from `astrality.yml`, overwriting any defined
        # contexts in external modules in the case of naming conflicts
        self.application_context.update(application_context)

        # Insert modules defined in `astrality.yml`
        for section, options in config.items():
            module_config = {section: options}

            # Check if this module should be included
            if not Module.valid_class_section(
                    section=module_config,
                    requires_timeout=self.global_modules_config.
                    requires_timeout,
                    requires_working_directory=self.config_directory,
            ) or section not in self.global_modules_config.enabled_modules:
                continue

            module = Module(
                module_config=module_config,
                module_directory=self.config_directory,
                replacer=self.interpolate_string,
                context_store=self.application_context,
            )
            self.modules[module.name] = module

        # Initialize the config directory watcher, but don't start it yet
        self.directory_watcher = DirectoryWatcher(
            directory=self.config_directory,
            on_modified=self.file_system_modified,
        )

        logger.info('Enabled modules: ' + ', '.join(self.modules.keys()))