def test_handle_listener_state_change_busy_to_unknown(self):
     from docker_supervisor.events import EventRejectedEvent
     from docker_supervisor.events import subscribe
     events = []
     def doit(event):
         events.append(event)
     subscribe(EventRejectedEvent, doit)
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     from docker_supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     process.listener_state = EventListenerStates.BUSY
     current_event = DummyEvent()
     process.event = current_event
     dispatcher.state_buffer = 'bogus data\n'
     self.assertEqual(dispatcher.handle_listener_state_change(), None)
     self.assertEqual(dispatcher.state_buffer, '')
     self.assertEqual(options.logger.data[0],
             "process1: bad result line: 'bogus data'")
     self.assertEqual(options.logger.data[1],
             'process1: BUSY -> UNKNOWN')
     self.assertEqual(options.logger.data[2],
                      'process1: has entered the UNKNOWN state and will '
                      'no longer receive events, this usually indicates '
                      'the process violated the eventlistener protocol')
     self.assertEqual(process.listener_state,
                      EventListenerStates.UNKNOWN)
     self.assertEqual(events[0].process, process)
     self.assertEqual(events[0].event, current_event)
 def test_handle_result_exception(self):
     from docker_supervisor.events import subscribe
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     L = []
     def doit(event):
         L.append(event)
     from docker_supervisor import events
     subscribe(events.EventRejectedEvent, doit)
     from docker_supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     def exception(event, result):
         raise ValueError
     class Dummy:
         pass
     process.group = Dummy()
     process.group.config = Dummy()
     process.group.config.result_handler = exception
     process.group.result_handler = exception
     process.listener_state = EventListenerStates.BUSY
     dispatcher.handle_result('foo')
     self.assertEqual(len(L), 1)
     self.assertEqual(L[0].__class__, events.EventRejectedEvent)
     self.assertEqual(process.listener_state,
                      EventListenerStates.UNKNOWN)
     self.assertEqual(options.logger.data[0],
                      'process1: event caused an error')
     self.assertEqual(options.logger.data[1],
                      'process1: BUSY -> UNKNOWN')
     self.assertEqual(options.logger.data[2],
                      'process1: has entered the UNKNOWN state and will '
                      'no longer receive events, this usually indicates '
                      'the process violated the eventlistener protocol')
 def test_handle_result_rejectevent(self):
     from docker_supervisor.events import subscribe
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     L = []
     def doit(event):
         L.append(event)
     from docker_supervisor import events
     subscribe(events.EventRejectedEvent, doit)
     from docker_supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     def rejected(event, result):
         from docker_supervisor.dispatchers import RejectEvent
         raise RejectEvent(result)
     class Dummy:
         pass
     process.group = Dummy()
     process.group.config = Dummy()
     process.group.config.result_handler = rejected
     process.listener_state = EventListenerStates.BUSY
     dispatcher.handle_result('foo')
     self.assertEqual(len(L), 1)
     self.assertEqual(L[0].__class__, events.EventRejectedEvent)
     self.assertEqual(process.listener_state,
                      EventListenerStates.ACKNOWLEDGED)
     self.assertEqual(options.logger.data[0],
                      'process1: event was rejected')
     self.assertEqual(options.logger.data[1],
                      'process1: BUSY -> ACKNOWLEDGED')
Beispiel #4
0
 def __init__(self, config):
     ProcessGroupBase.__init__(self, config)
     self.event_buffer = []
     for event_type in self.config.pool_events:
         events.subscribe(event_type, self._acceptEvent)
     events.subscribe(events.EventRejectedEvent, self.handle_rejected)
     self.serial = -1
     self.last_dispatch = 0
     self.dispatch_throttle = 0  # in seconds: .00195 is an interesting one
    def test_runforever_emits_generic_specific_event(self):
        from docker_supervisor import events
        L = []

        def callback(event):
            L.append(2)

        events.subscribe(events.SupervisorRunningEvent, callback)
        options = DummyOptions()
        options.test = True
        supervisord = self._makeOne(options)
        supervisord.runforever()
        self.assertEqual(L, [2])
    def test_runforever_emits_generic_startup_event(self):
        from docker_supervisor import events
        L = []

        def callback(event):
            L.append(1)

        events.subscribe(events.SupervisorStateChangeEvent, callback)
        options = DummyOptions()
        supervisord = self._makeOne(options)
        options.test = True
        supervisord.runforever()
        self.assertEqual(L, [1])
    def test_record_output_does_not_emit_stderr_event_when_disabled(self):
        options = DummyOptions()
        config = DummyPConfig(options, 'process1', '/bin/process1',
                              stderr_events_enabled=False)
        process = DummyProcess(config)
        dispatcher = self._makeOne(process, 'stderr')
        dispatcher.output_buffer = 'hello from stderr'

        L = []
        def doit(event):
            L.append(event)
        from docker_supervisor import events
        events.subscribe(events.EventTypes.PROCESS_LOG_STDERR, doit)
        dispatcher.record_output()

        self.assertEqual(len(L), 0)
    def test_add_process_group_event(self):
        from docker_supervisor import events
        L = []

        def callback(event):
            L.append(1)

        events.subscribe(events.ProcessGroupAddedEvent, callback)
        options = DummyOptions()
        pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
        gconfig = DummyPGroupConfig(options, 'foo', pconfigs=[pconfig])
        options.process_group_configs = [gconfig]
        supervisord = self._makeOne(options)

        supervisord.add_process_group(gconfig)

        options.test = True
        supervisord.runforever()
        self.assertEqual(L, [1])
    def test_stdout_capturemode_single_buffer(self):
        # mike reported that comm events that took place within a single
        # output buffer were broken 8/20/2007
        from docker_supervisor.events import ProcessCommunicationEvent
        from docker_supervisor.events import subscribe
        events = []
        def doit(event):
            events.append(event)
        subscribe(ProcessCommunicationEvent, doit)
        BEGIN_TOKEN = ProcessCommunicationEvent.BEGIN_TOKEN
        END_TOKEN = ProcessCommunicationEvent.END_TOKEN
        data = BEGIN_TOKEN + 'hello' + END_TOKEN
        options = DummyOptions()
        from docker_supervisor.loggers import getLogger
        options.getLogger = getLogger # actually use real logger
        logfile = '/tmp/log'
        config = DummyPConfig(options, 'process1', '/bin/process1',
                              stdout_logfile=logfile,
                              stdout_capture_maxbytes=1000)
        process = DummyProcess(config)
        dispatcher = self._makeOne(process)

        try:
            dispatcher.output_buffer = data
            dispatcher.record_output()
            self.assertEqual(open(logfile, 'r').read(), '')
            self.assertEqual(dispatcher.output_buffer, '')
            self.assertEqual(len(events), 1)

            event = events[0]
            from docker_supervisor.events import ProcessCommunicationStdoutEvent
            self.assertEqual(event.__class__, ProcessCommunicationStdoutEvent)
            self.assertEqual(event.process, process)
            self.assertEqual(event.channel, 'stdout')
            self.assertEqual(event.data, 'hello')

        finally:
            try:
                dispatcher.capturelog.close()
                dispatcher.childlog.close()
                os.remove(logfile)
            except (OSError, IOError):
                pass
    def test_record_output_emits_stdout_event_when_enabled(self):
        options = DummyOptions()
        config = DummyPConfig(options, 'process1', '/bin/process1',
                              stdout_events_enabled=True)
        process = DummyProcess(config)
        dispatcher = self._makeOne(process, 'stdout')
        dispatcher.output_buffer = 'hello from stdout'

        L = []
        def doit(event):
            L.append(event)
        from docker_supervisor import events
        events.subscribe(events.EventTypes.PROCESS_LOG_STDOUT, doit)
        dispatcher.record_output()

        self.assertEqual(len(L), 1)
        event = L[0]
        self.assertEqual(event.process, process)
        self.assertEqual(event.data, 'hello from stdout')
 def test_toggle_capturemode_sends_event(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1',
                           stdout_logfile='/tmp/foo',
                           stdout_capture_maxbytes=500)
     process = DummyProcess(config)
     process.pid = 4000
     dispatcher = self._makeOne(process)
     dispatcher.capturemode = True
     dispatcher.capturelog.data = ['hallooo']
     L = []
     def doit(event):
         L.append(event)
     from docker_supervisor import events
     events.subscribe(events.EventTypes.PROCESS_COMMUNICATION, doit)
     dispatcher.toggle_capturemode()
     self.assertEqual(len(L), 1)
     event = L[0]
     self.assertEqual(event.process, process)
     self.assertEqual(event.pid, 4000)
     self.assertEqual(event.data, 'hallooo')
    def test_runforever_stopping_emits_events(self):
        options = DummyOptions()
        supervisord = self._makeOne(options)
        gconfig = DummyPGroupConfig(options)
        pgroup = DummyProcessGroup(gconfig)
        supervisord.process_groups = {'foo': pgroup}
        supervisord.options.mood = -1
        L = []

        def callback(event):
            L.append(event)

        from docker_supervisor import events
        events.subscribe(events.SupervisorStateChangeEvent, callback)
        from docker_supervisor.medusa import asyncore_25 as asyncore
        options.test = True
        self.assertRaises(asyncore.ExitNow, supervisord.runforever)
        self.assertTrue(pgroup.all_stopped)
        self.assertTrue(isinstance(L[0], events.SupervisorRunningEvent))
        self.assertTrue(isinstance(L[0], events.SupervisorStateChangeEvent))
        self.assertTrue(isinstance(L[1], events.SupervisorStoppingEvent))
        self.assertTrue(isinstance(L[1], events.SupervisorStateChangeEvent))
    def test_tick(self):
        from docker_supervisor import events
        L = []

        def callback(event):
            L.append(event)

        events.subscribe(events.TickEvent, callback)
        options = DummyOptions()
        supervisord = self._makeOne(options)

        supervisord.tick(now=0)
        self.assertEqual(supervisord.ticks[5], 0)
        self.assertEqual(supervisord.ticks[60], 0)
        self.assertEqual(supervisord.ticks[3600], 0)
        self.assertEqual(len(L), 0)

        supervisord.tick(now=6)
        self.assertEqual(supervisord.ticks[5], 5)
        self.assertEqual(supervisord.ticks[60], 0)
        self.assertEqual(supervisord.ticks[3600], 0)
        self.assertEqual(len(L), 1)
        self.assertEqual(L[-1].__class__, events.Tick5Event)

        supervisord.tick(now=61)
        self.assertEqual(supervisord.ticks[5], 60)
        self.assertEqual(supervisord.ticks[60], 60)
        self.assertEqual(supervisord.ticks[3600], 0)
        self.assertEqual(len(L), 3)
        self.assertEqual(L[-1].__class__, events.Tick60Event)

        supervisord.tick(now=3601)
        self.assertEqual(supervisord.ticks[5], 3600)
        self.assertEqual(supervisord.ticks[60], 3600)
        self.assertEqual(supervisord.ticks[3600], 3600)
        self.assertEqual(len(L), 6)
        self.assertEqual(L[-1].__class__, events.Tick3600Event)
 def test_subscribe(self):
     from docker_supervisor import events
     events.subscribe(None, None)
     self.assertEqual(events.callbacks, [(None, None)])
    def test_stdout_capturemode_multiple_buffers(self):
        from docker_supervisor.events import ProcessCommunicationEvent
        from docker_supervisor.events import subscribe
        events = []
        def doit(event):
            events.append(event)
        subscribe(ProcessCommunicationEvent, doit)
        import string
        # ascii_letters for python 3
        letters = getattr(string, "letters", string.ascii_letters)
        digits = string.digits * 4
        BEGIN_TOKEN = ProcessCommunicationEvent.BEGIN_TOKEN
        END_TOKEN = ProcessCommunicationEvent.END_TOKEN
        data = (letters +  BEGIN_TOKEN + digits + END_TOKEN + letters)

        # boundaries that split tokens
        broken = data.split(':')
        first = broken[0] + ':'
        second = broken[1] + ':'
        third = broken[2]

        options = DummyOptions()
        from docker_supervisor.loggers import getLogger
        options.getLogger = getLogger # actually use real logger
        logfile = '/tmp/log'
        config = DummyPConfig(options, 'process1', '/bin/process1',
                              stdout_logfile=logfile,
                              stdout_capture_maxbytes=10000)
        process = DummyProcess(config)
        dispatcher = self._makeOne(process)
        try:
            dispatcher.output_buffer = first
            dispatcher.record_output()
            [ x.flush() for x in dispatcher.childlog.handlers]
            self.assertEqual(open(logfile, 'r').read(), letters)
            self.assertEqual(dispatcher.output_buffer, first[len(letters):])
            self.assertEqual(len(events), 0)

            dispatcher.output_buffer += second
            dispatcher.record_output()
            self.assertEqual(len(events), 0)
            [ x.flush() for x in dispatcher.childlog.handlers]
            self.assertEqual(open(logfile, 'r').read(), letters)
            self.assertEqual(dispatcher.output_buffer, first[len(letters):])
            self.assertEqual(len(events), 0)

            dispatcher.output_buffer += third
            dispatcher.record_output()
            [ x.flush() for x in dispatcher.childlog.handlers]
            self.assertEqual(open(logfile, 'r').read(), letters *2)
            self.assertEqual(len(events), 1)
            event = events[0]
            from docker_supervisor.events import ProcessCommunicationStdoutEvent
            self.assertEqual(event.__class__, ProcessCommunicationStdoutEvent)
            self.assertEqual(event.process, process)
            self.assertEqual(event.channel, 'stdout')
            self.assertEqual(event.data, digits)

        finally:
            try:
                dispatcher.capturelog.close()
                dispatcher.childlog.close()
                os.remove(logfile)
            except (OSError, IOError):
                pass