def test_runforever_calls_tick(self):
     options = DummyOptions()
     options.test = True
     supervisord = self._makeOne(options)
     self.assertEqual(len(supervisord.ticks), 0)
     supervisord.runforever()
     self.assertEqual(len(supervisord.ticks), 3)
 def test_handle_sighup(self):
     options = DummyOptions()
     options._signal = signal.SIGHUP
     supervisord = self._makeOne(options)
     supervisord.handle_signal()
     self.assertEqual(supervisord.options.mood, 0)
     self.assertEqual(options.logger.data[0],
                      'received SIGHUP indicating restart request')
 def test_handle_unknown_signal(self):
     options = DummyOptions()
     options._signal = signal.SIGUSR1
     supervisord = self._makeOne(options)
     supervisord.handle_signal()
     self.assertEqual(supervisord.options.mood, 1)
     self.assertEqual(options.logger.data[0],
                      'received SIGUSR1 indicating nothing')
 def test_handle_sigquit(self):
     options = DummyOptions()
     options._signal = signal.SIGQUIT
     supervisord = self._makeOne(options)
     supervisord.handle_signal()
     self.assertEqual(supervisord.options.mood, -1)
     self.assertEqual(options.logger.data[0],
                      'received SIGQUIT indicating exit request')
 def test_runforever_select_uncaught_exception(self):
     options = DummyOptions()
     import errno
     options.select_error = errno.EBADF
     supervisord = self._makeOne(options)
     import select
     options.test = True
     self.assertRaises(select.error, supervisord.runforever)
 def test_runforever_select_eintr(self):
     options = DummyOptions()
     import errno
     options.select_error = errno.EINTR
     supervisord = self._makeOne(options)
     options.test = True
     supervisord.runforever()
     self.assertEqual(options.logger.data[0], 'EINTR encountered in select')
 def test_handle_read_event(self):
     options = DummyOptions()
     options.readfd_result = 'abc'
     config = DummyPConfig(options, 'process1', '/bin/process1',
                           stdout_capture_maxbytes=100)
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     self.assertEqual(dispatcher.handle_read_event(), None)
     self.assertEqual(dispatcher.output_buffer, 'abc')
 def test_handle_write_event_uncaught_raised(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'test', '/test')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     dispatcher.input_buffer = 'halloooo'
     import errno
     options.write_error = errno.EBADF
     self.assertRaises(OSError, dispatcher.handle_write_event)
 def test_handle_read_event_logging_nologs(self):
     options = DummyOptions()
     options.readfd_result = 'supercalifragilisticexpialidocious'
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     # just make sure there are no errors if a child logger doesnt
     # exist
     self.assertEqual(dispatcher.handle_read_event(), None)
     self.assertEqual(dispatcher.childlog, None)
 def test_handle_write_event_over_os_limit(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'test', '/test')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     options.write_accept = 1
     dispatcher.input_buffer = 'a' * 50
     dispatcher.handle_write_event()
     self.assertEqual(len(dispatcher.input_buffer), 49)
     self.assertEqual(options.written[0], 'a')
 def test_handle_read_event_logging_childlog(self):
     options = DummyOptions()
     options.readfd_result = 'supercalifragilisticexpialidocious'
     config = DummyPConfig(options, 'process1', '/bin/process1',
                           stdout_logfile='/tmp/foo')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     self.assertEqual(dispatcher.handle_read_event(), None)
     self.assertEqual(len(dispatcher.childlog.data), 1)
     self.assertEqual(dispatcher.childlog.data[0],
                      'supercalifragilisticexpialidocious')
 def test_handle_sigchld(self):
     options = DummyOptions()
     options._signal = signal.SIGCHLD
     supervisord = self._makeOne(options)
     supervisord.handle_signal()
     self.assertEqual(supervisord.options.mood, 1)
     # supervisor.options.signame(signal.SIGCHLD) may return "SIGCLD"
     # on linux or other systems where SIGCHLD = SIGCLD.
     msgs = ('received SIGCHLD indicating a child quit',
             'received SIGCLD indicating a child quit')
     self.assertTrue(options.logger.data[0] in msgs)
 def test_handle_read_event_nodata(self):
     options = DummyOptions()
     options.readfd_result = ''
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     self.assertEqual(dispatcher.handle_read_event(), None)
     self.assertEqual(dispatcher.state_buffer, '')
     from docker_supervisor.dispatchers import EventListenerStates
     self.assertEqual(dispatcher.process.listener_state,
                      EventListenerStates.ACKNOWLEDGED)
 def test_handle_write_event_epipe_raised(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'test', '/test')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     dispatcher.input_buffer = 'halloooo'
     import errno
     options.write_error = errno.EPIPE
     dispatcher.handle_write_event()
     self.assertEqual(dispatcher.input_buffer, '')
     self.assertTrue(options.logger.data[0].startswith(
         'fd 0 closed, stopped monitoring'))
     self.assertTrue(options.logger.data[0].endswith('(stdin)>'))
    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_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_reap(self):
        options = DummyOptions()
        options.waitpid_return = 1, 1
        pconfig = DummyPConfig(options, 'process', 'process', '/bin/process1')
        process = DummyProcess(pconfig)
        process.drained = False
        process.killing = True
        process.laststop = None
        process.waitstatus = None, None
        options.pidhistory = {1: process}
        supervisord = self._makeOne(options)

        supervisord.reap(once=True)
        self.assertEqual(process.finished, (1, 1))
 def test_handle_read_event_calls_handle_listener_state_change(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1',
                           stdout_logfile='/tmp/foo')
     process = DummyProcess(config)
     from docker_supervisor.dispatchers import EventListenerStates
     process.listener_state = EventListenerStates.ACKNOWLEDGED
     dispatcher = self._makeOne(process)
     options.readfd_result = dispatcher.READY_FOR_EVENTS_TOKEN
     self.assertEqual(dispatcher.handle_read_event(), None)
     self.assertEqual(process.listener_state, EventListenerStates.READY)
     self.assertEqual(dispatcher.state_buffer, '')
     self.assertEqual(len(dispatcher.childlog.data), 1)
     self.assertEqual(dispatcher.childlog.data[0],
                      dispatcher.READY_FOR_EVENTS_TOKEN)
    def test_reap_unknown_pid(self):
        options = DummyOptions()
        options.waitpid_return = 2, 0  # pid, status
        pconfig = DummyPConfig(options, 'process', 'process', '/bin/process1')
        process = DummyProcess(pconfig)
        process.drained = False
        process.killing = True
        process.laststop = None
        process.waitstatus = None, None
        options.pidhistory = {1: process}
        supervisord = self._makeOne(options)

        supervisord.reap(once=True)
        self.assertEqual(process.finished, None)
        self.assertEqual(options.logger.data[0], 'reaped unknown pid 2')
 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')
 def test_readable_closed(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     dispatcher.closed = True
     self.assertEqual(dispatcher.readable(), False)
 def test_handle_listener_state_busy_gobbles(self):
     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
     class Dummy:
         pass
     process.group = Dummy()
     process.group.config = Dummy()
     from docker_supervisor.dispatchers import default_handler
     process.group.config.result_handler = default_handler
     dispatcher.state_buffer = 'RESULT 2\nOKbogus data\n'
     self.assertEqual(dispatcher.handle_listener_state_change(), None)
     self.assertEqual(dispatcher.state_buffer, '')
     self.assertEqual(options.logger.data[0],
                      'process1: event was processed')
     self.assertEqual(options.logger.data[1],
                      'process1: BUSY -> ACKNOWLEDGED')
     self.assertEqual(options.logger.data[2],
                      'process1: ACKNOWLEDGED -> UNKNOWN')
     self.assertEqual(options.logger.data[3],
                      '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)
 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')
示例#25
0
    def test_process_state_events_starting_and_backoff(self):
        from docker_supervisor.states import ProcessStates
        from docker_supervisor import events
        for klass in (
                events.ProcessStateStartingEvent,
                events.ProcessStateBackoffEvent,
        ):
            options = DummyOptions()
            pconfig1 = DummyPConfig(options, 'process1', 'process1',
                                    '/bin/process1')

            class DummyGroup:
                config = pconfig1

            process1 = DummyProcess(pconfig1)
            process1.group = DummyGroup
            event = klass(process1, ProcessStates.STARTING)
            headers, payload = self._deserialize(str(event))
            self.assertEqual(len(headers), 4)
            self.assertEqual(headers['processname'], 'process1')
            self.assertEqual(headers['groupname'], 'process1')
            self.assertEqual(headers['from_state'], 'STARTING')
            self.assertEqual(headers['tries'], '0')
            self.assertEqual(payload, '')
            process1.backoff = 1
            event = klass(process1, ProcessStates.STARTING)
            headers, payload = self._deserialize(str(event))
            self.assertEqual(headers['tries'], '1')
            process1.backoff = 2
            event = klass(process1, ProcessStates.STARTING)
            headers, payload = self._deserialize(str(event))
            self.assertEqual(headers['tries'], '2')
 def test_record_output_log_non_capturemode(self):
     # stdout/stderr goes to the process log and the main log,
     # in non-capturemode, the data length doesn't matter
     options = DummyOptions()
     from docker_supervisor import loggers
     options.loglevel = loggers.LevelsByName.TRAC
     config = DummyPConfig(options, 'process1', '/bin/process1',
                           stdout_logfile='/tmp/foo')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     dispatcher.output_buffer = 'a'
     dispatcher.record_output()
     self.assertEqual(dispatcher.childlog.data, ['a'])
     self.assertEqual(options.logger.data[0],
          "'process1' stdout output:\na")
     self.assertEqual(dispatcher.output_buffer, '')
示例#27
0
    def test_process_state_events_with_pid(self):
        from docker_supervisor.states import ProcessStates
        from docker_supervisor import events
        for klass in (
                events.ProcessStateRunningEvent,
                events.ProcessStateStoppedEvent,
                events.ProcessStateStoppingEvent,
        ):
            options = DummyOptions()
            pconfig1 = DummyPConfig(options, 'process1', 'process1',
                                    '/bin/process1')

            class DummyGroup:
                config = pconfig1

            process1 = DummyProcess(pconfig1)
            process1.group = DummyGroup
            process1.pid = 1
            event = klass(process1, ProcessStates.STARTING)
            headers, payload = self._deserialize(str(event))
            self.assertEqual(len(headers), 4)
            self.assertEqual(headers['processname'], 'process1')
            self.assertEqual(headers['groupname'], 'process1')
            self.assertEqual(headers['from_state'], 'STARTING')
            self.assertEqual(headers['pid'], '1')
            self.assertEqual(payload, '')
 def test_runforever_select_dispatcher_exitnow(self):
     options = DummyOptions()
     supervisord = self._makeOne(options)
     pconfig = DummyPConfig(
         options,
         'foo',
         '/bin/foo',
     )
     gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
     pgroup = DummyProcessGroup(gconfig)
     from docker_supervisor.medusa import asyncore_25 as asyncore
     exitnow = DummyDispatcher(readable=True, error=asyncore.ExitNow)
     pgroup.dispatchers = {6: exitnow}
     supervisord.process_groups = {'foo': pgroup}
     options.select_result = [6], [], []
     options.test = True
     self.assertRaises(asyncore.ExitNow, supervisord.runforever)
示例#29
0
 def test_handle_request_stdout_logfile_missing(self):
     options = DummyOptions()
     pconfig = DummyPConfig(options, 'foo', 'foo', 'it/is/missing')
     supervisord = PopulatedDummySupervisor(options, 'foo', pconfig)
     handler = self._makeOne(supervisord)
     request = DummyRequest('/logtail/foo', None, None, None)
     handler.handle_request(request)
     self.assertEqual(request._error, 410)
    def test_add_process_group(self):
        options = DummyOptions()
        pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
        gconfig = DummyPGroupConfig(options, 'foo', pconfigs=[pconfig])
        options.process_group_configs = [gconfig]
        supervisord = self._makeOne(options)

        self.assertEqual(supervisord.process_groups, {})

        result = supervisord.add_process_group(gconfig)
        self.assertEqual(supervisord.process_groups.keys(), ['foo'])
        self.assertTrue(result)

        group = supervisord.process_groups['foo']
        result = supervisord.add_process_group(gconfig)
        self.assertEqual(group, supervisord.process_groups['foo'])
        self.assertTrue(not result)