def test_io_output_processing_is_raising_exception_when_invalid_type_returned_in_debug_mode(
            self):
        """
        Error handling - when level is "debug", then we should be raising exceptions
        Variant: returned invalid type (not a STR - returned INT)
        """

        mocked_output = []

        io = IO()
        io.set_log_level('debug')
        io._stderr = io._stdout = lambda txt: mocked_output.append(txt)

        def processor_that_raises_exceptions(txt, origin):
            return 123456

        # noinspection PyTypeChecker
        io.add_output_processor(processor_that_raises_exceptions)

        with self.assertRaises(Exception):
            io.info(
                'Face the facts, no thanks, "Your passport lacks stamps Please go back for war, '
                +
                'torture and the death camps" Join the ranks, labeled as illegal people, Cursed by those who '
                + 'suck blood from golden calf’s nipple')
    def test_io_output_processing_does_not_break_on_exception_in_processing_method_when_error_level_is_not_debug(
            self):
        """
        Verify error handling - when level is not "debug", then no any error should be present from processors
        because we cannot mess with the I/O that is written to the console
        """

        mocked_output = []

        io = IO()
        io.set_log_level('info')
        io._stderr = io._stdout = lambda txt: mocked_output.append(txt)

        def processor_that_raises_exceptions(txt, origin):
            raise Exception('Hello')

        io.add_output_processor(processor_that_raises_exceptions)

        io.info(
            '26 Jan 1932 4000 mainly Jewish tenants in New York attacked police reserve forces who were trying '
            +
            'to evict 17 tenants. The mob was led by women on rooftops who directed the action with megaphones '
            + 'and hurled missiles at police.')

        self.assertIn('were trying to evict 17 tenants', str(mocked_output))
    def test_is_log_level_at_least_info(self):
        """Test error level comparison

        Covers: IO.set_log_level() and IO.is_log_level_at_least()
        """

        io = IO()
        io.set_log_level('info')

        self.assertFalse(io.is_log_level_at_least('debug'))
        self.assertTrue(io.is_log_level_at_least('info'))
        self.assertTrue(io.is_log_level_at_least('warning'))
        self.assertTrue(io.is_log_level_at_least('fatal'))
def main():
    io = IO()

    try:
        args = WaitForOutputApp.parse_args()
        io.set_log_level(args['log_level'])

        WaitForOutputApp(container=args['container'], command=args['command'],
                         pattern=args['pattern'], timeout=int(args['timeout']),
                         io=io) \
            .main()
    except ResultSignal as signal:
        io.info(signal.message) if signal.exit_code == 0 else io.error(
            signal.message)
        sys.exit(signal.exit_code)
    def test_io_output_processing_is_raising_exception_in_debug_mode(self):
        """
        Error handling - when level is "debug", then we should be raising exceptions
        """

        mocked_output = []

        io = IO()
        io.set_log_level('debug')
        io._stderr = io._stdout = lambda txt: mocked_output.append(txt)

        def processor_that_raises_exceptions(txt, origin):
            raise Exception('Hello')

        io.add_output_processor(processor_that_raises_exceptions)

        with self.assertRaises(Exception):
            io.info('There will be no shelter here')
    def test_io_output_processing_changes_output(self):
        """
        Tests adding "[stdout]" and "[stderr]" prefixes to the output
        """

        mocked_output = []

        io = IO()
        io.set_log_level('info')
        io._stderr = io._stdout = lambda txt: mocked_output.append(txt)

        # add a processor that will append origin - "stdout" or "stderr"
        io.add_output_processor(
            lambda txt, origin: '[{}]: {}'.format(origin, txt))

        io.info('Hello from stdout')
        io.error('Hello from stderr')

        mocked_output_as_str = " ".join(mocked_output)

        self.assertIn('[stdout]: \x1b', mocked_output_as_str)
        self.assertIn('[stderr]: \x1b', mocked_output_as_str)
    def test_set_log_level_cannot_set_invalid_log_level(self):
        """Checks validation in IO.set_log_level()"""

        io = IO()
        self.assertRaises(Exception, lambda: io.set_log_level('strikebreaker'))
Exemple #8
0
class Controller(object):
    """
    Constructs application context and passes actions to given services that are taking care about the processing
    """

    project_dirs: list
    runner: Runner
    repository: Repository
    config_loader: ConfigLoader
    io: IO

    def __init__(self, project_dir: str, server_port: int,
                 server_path_prefix: str, db_path: str, wait_time: int,
                 timeout: int, log_level: str):

        self.io = IO()
        self.io.set_log_level(log_level)
        self.project_dirs = self._combine_project_dirs(project_dir)
        self.config_loader = ConfigLoader(self.project_dirs, self.io)
        self.repository = Repository(self.project_dirs, db_path)

        self.runner = Runner(dirs=self.project_dirs,
                             config_loader=self.config_loader,
                             repository=self.repository,
                             timeout=timeout,
                             wait_time=wait_time,
                             io=self.io)

        self.scheduler = Scheduler(self.runner, self.repository, self.io)

    def list_enabled_configs(self) -> List[str]:
        return self.repository.get_configured_checks(with_disabled=False)

    def list_available_checks(self) -> List[str]:
        return self.repository.get_available_checks()

    def list_all_configs(self) -> List[str]:
        return self.repository.get_configured_checks(with_disabled=True)

    def spawn_threaded_application(self, refresh_time: int) -> None:
        """
        Spawns a background worker
        """

        self.scheduler.schedule_jobs_in_background(every_seconds=refresh_time)

    @staticmethod
    def get_version() -> dict:
        """
        Gets Infracheck version
        """

        return {"version": get_version(), "python": sys.version}

    def retrieve_checks(self) -> ExecutedChecksResultList:
        """
        Only retrieves results of last checking
        """

        return self.runner.get_checks_results(self.list_enabled_configs())

    def perform_checks(self) -> ExecutedChecksResultList:
        """
        Runs and returns results synchronously
        """

        configs = self.list_enabled_configs()

        self.runner.run_checks(configs)
        return self.runner.get_checks_results(configs)

    @staticmethod
    def _combine_project_dirs(project_dir: str) -> list:
        paths = [
            # directory specified by eg. the "--directory" commandline parameter
            project_dir,

            # standalone application running from cloned repository
            os.path.dirname(os.path.realpath(__file__)) + '/../',

            # official docker container
            '/app',
            '/data',

            # current directory
            os.getcwd(),
        ]

        return list(
            filter(lambda path: os.path.isdir(path + '/configured'), paths))