Example #1
0
 def setUp(self):
     self.poller = PollerSpy()
     self.scale_workers = ScaleWorkersSpy()
     self.create_poller = lambda: self.poller
     self.monitor = Monitor(self.create_poller, self.emit,
                            self.scale_workers,
                            self.poller.has_next_message)
     self.emmited_messages = []
Example #2
0
class Main(ObjectBase):

    monitor = None
    cfg_general = None
    cfg_monitor = None
    cfg_modules = None
    __cfg_file_config = 'config.json'
    __cfg_file_monitor = 'monitor.json'
    __cfg_file_modules = 'modules.json'

    def __init__(self, args_get):
        self._daemon_mode = False
        self._timer_check = 0
        self.__sys_path_append([self._modules_dir])
        self.__args_set(args_get)
        self.__init_config()
        self.__init_monitor()
        self.__args_cmd(args_get)

    def __init_config(self):
        self.cfg_general = ConfigControl(self._config_file)
        self.cfg_general.read()
        if self.__check_config():
            self.__default_conf()
            self.__read_config()
        else:
            raise Exception("Error load config.")

    def __check_config(self):
        if self.cfg_general:
            return True
        return False

    def __default_conf(self):
        if self.__check_config:
            if not self.cfg_general.is_exist_conf(['daemon', 'timer_check']):
                self.cfg_general.set_conf(['daemon', 'timer_check'], 300)

            if not self.cfg_general.is_exist_conf(['global', 'debug']):
                self.cfg_general.set_conf(['global', 'debug'], False)

            return True
        return False

    def __read_config(self):

        if self.__verbose:
            self.debug.enabled = True
            self.debug.level = DebugLevel.null
        else:
            self.debug.level = DebugLevel.info
            # TODO: Actualizar configuracin para que use level
            self.debug.enabled = True
            # self.debug.enabled = self.cfg_general.get_conf(['global', 'debug'], self.debug.enabled)

        if self.__timer_check_force:
            self._timer_check = self.__timer_check_force
        else:
            self._timer_check = self.cfg_general.get_conf(['daemon', 'timer_check'], self._timer_check)

    @staticmethod
    def __sys_path_append(list_dir):
        for f in list_dir:
            if os.path.isdir(f):
                if f not in sys.path:
                    sys.path.append(f)

    def __init_monitor(self):
        self.monitor = Monitor(self._dir, self._config_dir, self._modules_dir, self._var_dir)

    @property
    def _is_mode_dev(self):
        if self._dir.find('src') != -1:
            return True
        return False

    @property
    def _dir(self):
        """Path run program.

        Returns:
        str: Returning value

        """
        return os.path.dirname(os.path.abspath(__file__))

    @property
    def _modules_dir(self):
        """Path modules.

        Returns:
        str: Returning value

        """
        return os.path.join(self._dir, 'watchfuls')

    @property
    def _lib_dir(self):
        """Path lib's.

        Returns:
        str: Returning value

        """
        return os.path.join(self._dir, 'lib')

    @property
    def _config_dir(self):
        """Path config files.

        Returns:
        str: Returning value

        """
        if self.__path_config:
            return self.__path_config
        elif self._is_mode_dev:
            return os.path.normpath(os.path.join(self._dir, '../data/'))
        else:
            return '/etc/watchful/'

    @property
    def _var_dir(self):
        """Path /var/lib...

        Returns:
        str: Returning value

        """
        if self._is_mode_dev:
            return '/var/lib/watchful/dev/'
        else:
            return '/var/lib/watchful/'

    @property
    def _config_file(self):
        return os.path.join(self._config_dir, self.__cfg_file_config)

    def __args_set(self, args_get):
        if args_get:
            for key, value in args_get.items():
                if key == 'path':
                    self.__path_config = value

                elif key == 'verbose':
                    self.__verbose = value

                elif key == 'timer_check':
                    self.__timer_check_force = value

                elif key == 'daemon_mode':
                    self.__daemon_mode = value

    def __args_cmd(self, args_get):
        if args_get:
            for key, value in args_get.items():
                if key == 'clear_status':
                    if value:
                        if self.monitor:
                            self.monitor.clear_status()

    @property
    def _daemon_mode(self):
        return self.__daemon_mode

    @_daemon_mode.setter
    def _daemon_mode(self, val):
        self.__daemon_mode = val

    @property
    def _timer_check(self):
        if self.__timer_check:
            return self.__timer_check
        return 0

    @_timer_check.setter
    def _timer_check(self, val):
        if not val:
            val = 0
        elif isinstance(val, str):
            if not val.isnumeric():
                val = 0
            else:
                val = int(val)
        elif isinstance(val, float):
            val = int(val)
        elif not isinstance(val, int):
            val = 0

        if int(val) < 0:
            val = 0

        self.__timer_check = int(val)

    def start(self):
        if not self._daemon_mode:
            self.debug.print("* Main >> Run Mode Single Process")
            self.monitor.check()
        else:
            self.debug.print("* Main >> Run Mode Daemon")
            while True:
                self.monitor.check()
                if self._timer_check == 0:
                    break
                self.debug.print("* Main >> Waiting {0} seconds...".format(args['timer_check']))
                try:
                    time.sleep(self._timer_check)
                except KeyboardInterrupt:
                    self.debug.print("* Main >> Process cancel  by the user!!", DebugLevel.info)
                    try:
                        sys.exit(0)
                    except SystemExit:
                        os._exit(0)
                except Exception as e:
                    self.debug.exception(e)
Example #3
0
 def __init_monitor(self):
     self.monitor = Monitor(self._dir, self._config_dir, self._modules_dir, self._var_dir)
Example #4
0
class TestMonitor(unittest.TestCase):
    def setUp(self):
        self.poller = PollerSpy()
        self.scale_workers = ScaleWorkersSpy()
        self.create_poller = lambda: self.poller
        self.monitor = Monitor(self.create_poller, self.emit,
                               self.scale_workers,
                               self.poller.has_next_message)
        self.emmited_messages = []

    def test_monitor_forwards_messages_to_socketio(self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "STARTED",
                                      1).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING",
                                      2).SerializeToString(),
        ]
        self.run_monitor(messages)

        expected_messages = [
            {
                "address": "tcp://127.0.0.1:1",
                "model": "en-GB",
                "status": "STARTED",
                "time": 1
            },
            {
                "address": "tcp://127.0.0.1:1",
                "model": "en-GB",
                "status": "WORKING",
                "time": 2
            },
        ]

        self.assertThatMonitorForwardedMessages(expected_messages)

    def test_monitor_saves_worker_statuses(self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "STARTED",
                                      1).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:2", "en-GB", "WORKING",
                                      2).SerializeToString(),
        ]
        self.run_monitor(messages)

        expected_messages = [
            {
                "address": "tcp://127.0.0.1:1",
                "model": "en-GB",
                "status": "STARTED",
                "time": 1
            },
            {
                "address": "tcp://127.0.0.1:2",
                "model": "en-GB",
                "status": "WORKING",
                "time": 2
            },
        ]

        self.assertEqual(expected_messages, self.monitor.get_statuses())

    def test_monitor_will_add_new_workers_when_all_workers_are_working(self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING",
                                      1).SerializeToString()
        ]
        self.run_monitor(messages)

        expected_messages = [{"en-GB": +1}]
        self.assertEqual(expected_messages, self.scale_workers.scaling_history)

    def test_monitor_will_not_add_new_workers_when_it_is_currently_adding_new_workers(
            self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING",
                                      1).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING",
                                      2).SerializeToString()
        ]
        self.run_monitor(messages)

        expected_messages = [{"en-GB": +1}, {}]
        self.assertEqual(expected_messages, self.scale_workers.scaling_history)

    def test_monitor_will_add_new_workers_when_it_finished_scaling_and_it_needs_new_workers(
            self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING",
                                      1).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING",
                                      2).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:2", "en-GB", "STARTED",
                                      3).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING",
                                      4).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:2", "en-GB", "WORKING",
                                      5).SerializeToString()
        ]
        self.run_monitor(messages)

        expected_messages = [{"en-GB": +1}, {}, {}, {}, {"en-GB": +1}]
        self.assertEqual(expected_messages, self.scale_workers.scaling_history)

    def run_monitor(self, messages):
        self.poller.add_messages([{"master": message} for message in messages])
        self.monitor.run()

    def assertThatMonitorForwardedMessages(self, messages):
        forwarded_messages = self.emmited_messages
        self.assertEqual(messages, forwarded_messages)

    def emit(self, message):
        self.emmited_messages.append(message)
Example #5
0
 def setUp(self):
     self.poller = PollerSpy()
     self.scale_workers = ScaleWorkersSpy()
     self.create_poller = lambda: self.poller
     self.monitor = Monitor(self.create_poller, self.emit, self.scale_workers, self.poller.has_next_message)
     self.emmited_messages = []
Example #6
0
class TestMonitor(unittest.TestCase):

    def setUp(self):
        self.poller = PollerSpy()
        self.scale_workers = ScaleWorkersSpy()
        self.create_poller = lambda: self.poller
        self.monitor = Monitor(self.create_poller, self.emit, self.scale_workers, self.poller.has_next_message)
        self.emmited_messages = []

    def test_monitor_forwards_messages_to_socketio(self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "STARTED", 1).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING", 2).SerializeToString(),
        ]
        self.run_monitor(messages)

        expected_messages = [
            {"address": "tcp://127.0.0.1:1", "model": "en-GB", "status": "STARTED", "time": 1},
            {"address": "tcp://127.0.0.1:1", "model": "en-GB", "status": "WORKING", "time": 2},
        ]

        self.assertThatMonitorForwardedMessages(expected_messages)

    def test_monitor_saves_worker_statuses(self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "STARTED", 1).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:2", "en-GB", "WORKING", 2).SerializeToString(),
        ]
        self.run_monitor(messages)

        expected_messages = [
            {"address": "tcp://127.0.0.1:1", "model": "en-GB", "status": "STARTED", "time": 1},
            {"address": "tcp://127.0.0.1:2", "model": "en-GB", "status": "WORKING", "time": 2},
        ]

        self.assertEqual(expected_messages, self.monitor.get_statuses())

    def test_monitor_will_add_new_workers_when_all_workers_are_working(self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING", 1).SerializeToString()
        ]
        self.run_monitor(messages)

        expected_messages = [
            {"en-GB": +1}
        ]
        self.assertEqual(expected_messages, self.scale_workers.scaling_history)

    def test_monitor_will_not_add_new_workers_when_it_is_currently_adding_new_workers(self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING", 1).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING", 2).SerializeToString()
        ]
        self.run_monitor(messages)

        expected_messages = [{"en-GB": +1}, {}]
        self.assertEqual(expected_messages, self.scale_workers.scaling_history)

    def test_monitor_will_add_new_workers_when_it_finished_scaling_and_it_needs_new_workers(self):
        messages = [
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING", 1).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING", 2).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:2", "en-GB", "STARTED", 3).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:1", "en-GB", "WORKING", 4).SerializeToString(),
            createWorkerStatusMessage("tcp://127.0.0.1:2", "en-GB", "WORKING", 5).SerializeToString()
        ]
        self.run_monitor(messages)

        expected_messages = [{"en-GB": +1}, {}, {}, {}, {"en-GB": +1}]
        self.assertEqual(expected_messages, self.scale_workers.scaling_history)


    def run_monitor(self, messages):
        self.poller.add_messages([{"master": message} for message in messages])
        self.monitor.run()

    def assertThatMonitorForwardedMessages(self, messages):
        forwarded_messages = self.emmited_messages
        self.assertEqual(messages, forwarded_messages)

    def emit(self, message):
        self.emmited_messages.append(message)