Ejemplo n.º 1
0
    def test_process_state_events_with_pid(self):
        from supervisor.states import ProcessStates
        from 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, "")
Ejemplo n.º 2
0
    def test_process_state_events_starting_and_backoff(self):
        from supervisor.states import ProcessStates
        from 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")
Ejemplo n.º 3
0
 def test_handle_listener_state_busy_gobbles(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     process.listener_state = EventListenerStates.BUSY
     class Dummy:
         pass
     process.group = Dummy()
     process.group.config = Dummy()
     from 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)
Ejemplo n.º 4
0
 def test_handle_result_rejectevent(self):
     from supervisor.events import subscribe
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     L = []
     def doit(event):
         L.append(event)
     from supervisor import events
     subscribe(events.EventRejectedEvent, doit)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     def rejected(event, result):
         from 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')
Ejemplo n.º 5
0
 def test_process_state_events_starting_and_backoff(self):
     from supervisor.states import ProcessStates
     from 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')
Ejemplo n.º 6
0
 def test_handle_listener_state_change_busy_to_unknown(self):
     from supervisor.events import EventRejectedEvent
     from 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 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)
Ejemplo n.º 7
0
 def test_handle_result_accept(self):
     from supervisor.events import subscribe
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     L = []
     def doit(event):
         L.append(event)
     from supervisor import events
     subscribe(events.EventRejectedEvent, doit)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     def handle(event, result):
         pass
     class Dummy:
         pass
     process.group = Dummy()
     process.group.config = Dummy()
     process.group.config.result_handler = handle
     process.listener_state = EventListenerStates.BUSY
     dispatcher.handle_result('foo')
     self.assertEqual(len(L), 0)
     self.assertEqual(process.listener_state,
                      EventListenerStates.ACKNOWLEDGED)
     result = options.logger.data[0]
     self.assertTrue(result.endswith('BUSY -> ACKNOWLEDGED (processed)'))
Ejemplo n.º 8
0
    def test_toggle_capturemode_sends_event(self):
        executable = "/bin/cat"
        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 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")
Ejemplo n.º 9
0
 def test_handle_result_exception(self):
     from supervisor.events import subscribe
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     L = []
     def doit(event):
         L.append(event)
     from supervisor import events
     subscribe(events.EventRejectedEvent, doit)
     from 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)
     result = options.logger.data[0]
     self.assertTrue(result.endswith('BUSY -> UNKNOWN'))
Ejemplo n.º 10
0
    def test_handle_listener_state_change_busy_to_unknown(self):
        from supervisor.events import EventRejectedEvent
        from 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 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: BUSY -> UNKNOWN (bad result line \'bogus data\')')
        self.assertEqual(process.listener_state,
                         EventListenerStates.UNKNOWN)
        self.assertEqual(events[0].process, process)
        self.assertEqual(events[0].event, current_event)
Ejemplo n.º 11
0
 def test_handle_result_exception(self):
     from supervisor.events import subscribe
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     L = []
     def doit(event):
         L.append(event)
     from supervisor import events
     subscribe(events.EventRejectedEvent, doit)
     from 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')
Ejemplo n.º 12
0
 def test_handle_listener_state_change_busy_to_insufficient(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     process.listener_state = EventListenerStates.BUSY
     dispatcher.state_buffer = 'bogus data yo'
     self.assertEqual(dispatcher.handle_listener_state_change(), None)
     self.assertEqual(dispatcher.state_buffer, 'bogus data yo')
     self.assertEqual(process.listener_state, EventListenerStates.BUSY)
Ejemplo n.º 13
0
 def test_handle_listener_state_change_from_unknown(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     process.listener_state = EventListenerStates.UNKNOWN
     dispatcher.state_buffer = 'whatever'
     self.assertEqual(dispatcher.handle_listener_state_change(), None)
     self.assertEqual(dispatcher.state_buffer, '')
     self.assertEqual(options.logger.data, [])
     self.assertEqual(process.listener_state, EventListenerStates.UNKNOWN)
Ejemplo n.º 14
0
    def test_handle_listener_state_change_acknowledged_to_ready(self):
        options = DummyOptions()
        config = DummyPConfig(options, "process1", "/bin/process1")
        process = DummyProcess(config)
        from supervisor.dispatchers import EventListenerStates

        dispatcher = self._makeOne(process)
        process.listener_state = EventListenerStates.ACKNOWLEDGED
        dispatcher.state_buffer = "READY\n"
        self.assertEqual(dispatcher.handle_listener_state_change(), None)
        self.assertEqual(dispatcher.state_buffer, "")
        self.assertEqual(options.logger.data[0], "process1: ACKNOWLEDGED -> READY")
        self.assertEqual(process.listener_state, EventListenerStates.READY)
Ejemplo n.º 15
0
 def test_handle_listener_state_change_ready_to_unknown(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     process.listener_state = EventListenerStates.READY
     dispatcher.state_buffer = 'bogus data yo'
     self.assertEqual(dispatcher.handle_listener_state_change(), None)
     self.assertEqual(dispatcher.state_buffer, '')
     self.assertEqual(options.logger.data[0],
                      'process1: READY -> UNKNOWN')
     self.assertEqual(process.listener_state, EventListenerStates.UNKNOWN)
Ejemplo n.º 16
0
 def test_handle_listener_state_change_acknowledged_to_insufficient(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     process.listener_state = EventListenerStates.ACKNOWLEDGED
     dispatcher.state_buffer = 'RE'
     self.assertEqual(dispatcher.handle_listener_state_change(), None)
     self.assertEqual(dispatcher.state_buffer, 'RE')
     self.assertEqual(options.logger.data, [])
     self.assertEqual(process.listener_state,
                      EventListenerStates.ACKNOWLEDGED)
    def test_handler_writes_chars_when_response_is_STDIN(self):
        options = DummyOptions()
        config = DummyPConfig(options, 'cat', 'bin/cat')

        process = DummyProcess(config)
        process.pid = 42
        process.killing = False

        event = DummyEvent()
        event.process = process

        response = 'STDIN:foobar'
        supervisor_twiddler.resulthandler.stdin_write_handler(event, response)
        self.assertEqual(process.stdin_buffer, 'foobar')
Ejemplo n.º 18
0
    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 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_write_fails_silently_if_process_is_killing(self):
        options = DummyOptions()
        config = DummyPConfig(options, 'cat', 'bin/cat')

        process = DummyProcess(config)
        process.pid = 42
        process.killing = True

        event = DummyEvent()
        event.process = process

        response = 'STDIN:foobar'
        supervisor_twiddler.resulthandler.stdin_write_handler(event, response)
        self.assertEqual(process.stdin_buffer, '')
    def test_write_encodes_unicode_as_utf8(self):
        options = DummyOptions()
        config = DummyPConfig(options, 'cat', 'bin/cat')

        process = DummyProcess(config)
        process.pid = 42
        process.killing = False

        event = DummyEvent()
        event.process = process

        response = _u(_b('STDIN:foobar'))
        supervisor_twiddler.resulthandler.stdin_write_handler(event, response)
        self.assertEqual(process.stdin_buffer, 'foobar')
Ejemplo n.º 21
0
 def test_plog_stdout_event(self):
     options = DummyOptions()
     pconfig1 = DummyPConfig(options, 'process1', 'process1','/bin/process1')
     process1 = DummyProcess(pconfig1)
     from supervisor.events import ProcessLogStdoutEvent
     class DummyGroup:
         config = pconfig1
     process1.group = DummyGroup
     event = ProcessLogStdoutEvent(process1, 1, 'yo')
     headers, payload = self._deserialize(event.payload())
     self.assertEqual(headers['processname'], 'process1', headers)
     self.assertEqual(headers['groupname'], 'process1', headers)
     self.assertEqual(headers['pid'], '1', headers)
     self.assertEqual(payload, 'yo')
Ejemplo n.º 22
0
 def test_pcomm_stderr_event(self):
     options = DummyOptions()
     pconfig1 = DummyPConfig(options, 'process1', 'process1','/bin/process1')
     process1 = DummyProcess(pconfig1)
     class DummyGroup:
         config = pconfig1
     process1.group = DummyGroup
     from supervisor.events import ProcessCommunicationStderrEvent
     event = ProcessCommunicationStderrEvent(process1, 1, 'yo')
     headers, payload = self._deserialize(str(event))
     self.assertEqual(headers['processname'], 'process1', headers)
     self.assertEqual(headers['groupname'], 'process1', headers)
     self.assertEqual(headers['pid'], '1', headers)
     self.assertEqual(payload, 'yo')
Ejemplo n.º 23
0
    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 = 1
        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_removeProcessFromGroup_raises_still_running_when_process_has_pid(self):
        pconfig = DummyPConfig(None, 'foo', '/bin/foo')
        process = DummyProcess(pconfig)
        process.pid = 42

        gconfig = DummyPGroupConfig(None, pconfigs=[pconfig])
        pgroup = DummyProcessGroup(gconfig)
        pgroup.processes = { 'process_with_pid': process }

        supervisord = DummySupervisor(process_groups = {'group_name': pgroup})
        interface = self.makeOne(supervisord)

        self.assertRPCError(SupervisorFaults.STILL_RUNNING,
                            interface.removeProcessFromGroup,
                            'group_name', 'process_with_pid')
Ejemplo n.º 25
0
 def test_handle_listener_state_change_acknowledged_gobbles(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     process.listener_state = EventListenerStates.ACKNOWLEDGED
     dispatcher.state_buffer = 'READY\ngarbage\n'
     self.assertEqual(dispatcher.handle_listener_state_change(), None)
     self.assertEqual(dispatcher.state_buffer, '')
     self.assertEqual(options.logger.data[0],
                      'process1: ACKNOWLEDGED -> READY')
     self.assertEqual(options.logger.data[1],
                      'process1: READY -> UNKNOWN')
     self.assertEqual(process.listener_state, EventListenerStates.UNKNOWN)
Ejemplo n.º 26
0
    def test_pcomm_stdout_event(self):
        options = DummyOptions()
        pconfig1 = DummyPConfig(options, "process1", "process1", "/bin/process1")
        process1 = DummyProcess(pconfig1)
        from supervisor.events import ProcessCommunicationStdoutEvent

        class DummyGroup:
            config = pconfig1

        process1.group = DummyGroup
        event = ProcessCommunicationStdoutEvent(process1, 1, "yo")
        headers, payload = self._deserialize(str(event))
        self.assertEqual(headers["processname"], "process1", headers)
        self.assertEqual(headers["groupname"], "process1", headers)
        self.assertEqual(headers["pid"], "1", headers)
        self.assertEqual(payload, "yo")
Ejemplo n.º 27
0
    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')
Ejemplo n.º 28
0
 def test_handle_listener_state_change_ready_to_unknown(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     from supervisor.dispatchers import EventListenerStates
     dispatcher = self._makeOne(process)
     process.listener_state = EventListenerStates.READY
     dispatcher.state_buffer = 'bogus data yo'
     self.assertEqual(dispatcher.handle_listener_state_change(), None)
     self.assertEqual(dispatcher.state_buffer, '')
     self.assertEqual(options.logger.data[0],
                      'process1: READY -> UNKNOWN')
     self.assertEqual(options.logger.data[1],
                      '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)
Ejemplo n.º 29
0
 def test_handle_sigusr2(self):
     options = DummyOptions()
     options._signal = signal.SIGUSR2
     pconfig1 = DummyPConfig(options, 'process1', 'process1','/bin/process1')
     from supervisor.process import ProcessStates
     process1 = DummyProcess(pconfig1, state=ProcessStates.STOPPING)
     process1.delay = time.time() - 1
     supervisord = self._makeOne(options)
     pconfigs = [DummyPConfig(options, 'foo', 'foo', '/bin/foo')]
     options.process_group_configs = DummyPGroupConfig(
         options, 'foo',
         pconfigs=pconfigs)
     supervisord.handle_signal()
     self.assertEqual(supervisord.options.mood, 1)
     self.assertEqual(options.logs_reopened, True)
     self.assertEqual(options.logger.data[0],
                      'received SIGUSR2 indicating log reopen request')
Ejemplo n.º 30
0
    def test_handle_listener_state_change_acknowledged_to_unknown(self):
        options = DummyOptions()
        config = DummyPConfig(options, "process1", "/bin/process1")
        process = DummyProcess(config)
        from supervisor.dispatchers import EventListenerStates

        dispatcher = self._makeOne(process)
        process.listener_state = EventListenerStates.ACKNOWLEDGED
        dispatcher.state_buffer = "bogus data yo"
        self.assertEqual(dispatcher.handle_listener_state_change(), None)
        self.assertEqual(dispatcher.state_buffer, "")
        self.assertEqual(options.logger.data[0], "process1: ACKNOWLEDGED -> UNKNOWN")
        self.assertEqual(
            options.logger.data[1],
            "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)
Ejemplo n.º 31
0
 def test_handle_listener_state_change_busy_to_unknown(self):
     from supervisor.events import EventRejectedEvent
     from 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 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: BUSY -> UNKNOWN (bad result line \'bogus data\')')
     self.assertEqual(process.listener_state,
                      EventListenerStates.UNKNOWN)
     self.assertEqual(events[0].process, process)
     self.assertEqual(events[0].event, current_event)
Ejemplo n.º 32
0
    def test_process_state_exited_event_unexpected(self):
        from supervisor import events
        from supervisor.states import ProcessStates
        options = DummyOptions()
        pconfig1 = DummyPConfig(options, 'process1', 'process1',
                                '/bin/process1')
        process1 = DummyProcess(pconfig1)

        class DummyGroup:
            config = pconfig1

        process1.group = DummyGroup
        process1.pid = 1
        event = events.ProcessStateExitedEvent(process1,
                                               ProcessStates.STARTING,
                                               expected=False)
        headers, payload = self._deserialize(str(event))
        self.assertEqual(len(headers), 5)
        self.assertEqual(headers['processname'], 'process1')
        self.assertEqual(headers['groupname'], 'process1')
        self.assertEqual(headers['pid'], '1')
        self.assertEqual(headers['from_state'], 'STARTING')
        self.assertEqual(headers['expected'], '0')
        self.assertEqual(payload, '')
Ejemplo n.º 33
0
 def test_process_state_events_with_pid(self):
     from supervisor.states import ProcessStates
     from 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, '')
Ejemplo n.º 34
0
    def test_removeProcessFromGroup_deletes_the_process(self):
        pconfig = DummyPConfig(None, 'foo', '/bin/foo')
        process = DummyProcess(pconfig, ProcessStates.STOPPED)

        gconfig = DummyPGroupConfig(None, pconfigs=[pconfig])
        pgroup = DummyProcessGroup(gconfig)
        pgroup.processes = {'process_name': process}

        supervisord = DummySupervisor(process_groups={'group_name': pgroup})
        interface = self.makeOne(supervisord)

        result = interface.removeProcessFromGroup('group_name', 'process_name')
        self.assertTrue(result)
        self.assertTrue(pgroup.processes.get('process_name') is None)
        self.assertEqual('removeProcessFromGroup', interface.update_text)
Ejemplo n.º 35
0
    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 supervisor import events
        events.subscribe(events.EventTypes.PROCESS_LOG_STDERR, doit)
        dispatcher.record_output()

        self.assertEqual(len(L), 0)
Ejemplo n.º 36
0
 def test_exit(self):
     options = DummyOptions()
     supervisord = self._makeOne(options)
     pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
     process = DummyProcess(pconfig)
     gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
     pgroup = DummyProcessGroup(gconfig)
     L = []
     def callback():
         L.append(1)
     supervisord.process_groups = {'foo': pgroup}
     supervisord.options.mood = 0
     supervisord.options.test = True
     from supervisor.medusa import asyncore_25 as asyncore
     self.assertRaises(asyncore.ExitNow, supervisord.runforever)
     self.assertEqual(pgroup.all_stopped, True)
Ejemplo n.º 37
0
 def test_record_output_capturemode_string_not_longer_than_token(self):
     # stdout/stderr goes to the process log and the main log,
     # in capturemode, the length of the data needs to be longer
     # than the capture token to make it out.
     options = DummyOptions()
     config = DummyPConfig(options,
                           'process1',
                           '/bin/process1',
                           stdout_logfile='/tmp/foo',
                           stdout_capture_maxbytes=100)
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     dispatcher.output_buffer = 'a'
     dispatcher.record_output()
     self.assertEqual(dispatcher.childlog.data, [])
     self.assertEqual(dispatcher.output_buffer, 'a')
Ejemplo n.º 38
0
 def test_exit_delayed(self):
     options = DummyOptions()
     supervisord = self._makeOne(options)
     pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
     process = DummyProcess(pconfig)
     gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
     pgroup = DummyProcessGroup(gconfig)
     pgroup.unstopped_processes = [process]
     L = []
     def callback():
         L.append(1)
     supervisord.process_groups = {'foo': pgroup}
     supervisord.options.mood = SupervisorStates.RESTARTING
     supervisord.options.test = True
     supervisord.runforever()
     self.assertNotEqual(supervisord.lastshutdownreport, 0)
Ejemplo n.º 39
0
 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 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, '')
Ejemplo n.º 40
0
    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 supervisor.events import ProcessCommunicationEvent
        from 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 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(read_file(logfile), '')
            self.assertEqual(dispatcher.output_buffer, '')
            self.assertEqual(len(events), 1)

            event = events[0]
            from 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
Ejemplo n.º 41
0
 def test_runforever_select_dispatcher_exitnow(self):
     options = DummyOptions()
     supervisord = self._makeOne(options)
     pconfig = DummyPConfig(
         options,
         'foo',
         '/bin/foo',
     )
     process = DummyProcess(pconfig)
     gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
     pgroup = DummyProcessGroup(gconfig)
     from 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)
Ejemplo n.º 42
0
    def test_remove_process_group(self):
        options = DummyOptions()
        pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
        gconfig = DummyPGroupConfig(options, 'foo', pconfigs=[pconfig])
        supervisord = self._makeOne(options)

        self.assertRaises(KeyError, supervisord.remove_process_group, 'asdf')

        supervisord.add_process_group(gconfig)
        result = supervisord.remove_process_group('foo')
        self.assertEqual(supervisord.process_groups, {})
        self.assertTrue(result)

        supervisord.add_process_group(gconfig)
        supervisord.process_groups['foo'].unstopped_processes = [DummyProcess(None)]
        result = supervisord.remove_process_group('foo')
        self.assertEqual(list(supervisord.process_groups.keys()), ['foo'])
        self.assertTrue(not result)
Ejemplo n.º 43
0
 def test_record_output_capturemode_string_longer_than_token(self):
     # stdout/stderr goes to the process log and the main log,
     # in capturemode, the length of the data needs to be longer
     # than the capture token to make it out.
     options = DummyOptions()
     from supervisor import loggers
     options.loglevel = loggers.LevelsByName.TRAC
     config = DummyPConfig(options, 'process1', '/bin/process1',
                           stdout_logfile='/tmp/foo',
                           stdout_capture_maxbytes=100)
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     dispatcher.output_buffer = 'stdout string longer than a token'
     dispatcher.record_output()
     self.assertEqual(dispatcher.childlog.data,
                      ['stdout string longer than a token'])
     self.assertEqual(options.logger.data[0],
          "'process1' stdout output:\nstdout string longer than a token")
Ejemplo n.º 44
0
    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 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') 
Ejemplo n.º 45
0
 def test_runforever_select_dispatchers(self):
     options = DummyOptions()
     supervisord = self._makeOne(options)
     pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
     process = DummyProcess(pconfig)
     gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
     pgroup = DummyProcessGroup(gconfig)
     readable = DummyDispatcher(readable=True)
     writable = DummyDispatcher(writable=True)
     error = DummyDispatcher(writable=True, error=OSError)
     pgroup.dispatchers = {6:readable, 7:writable, 8:error}
     supervisord.process_groups = {'foo': pgroup}
     options.select_result = [6], [7, 8], []
     options.test = True
     supervisord.runforever()
     self.assertEqual(pgroup.transitioned, True)
     self.assertEqual(readable.read_event_handled, True)
     self.assertEqual(writable.write_event_handled, True)
     self.assertEqual(error.error_handled, True)
Ejemplo n.º 46
0
    def test_remove_process_group_event(self):
        from supervisor import events
        L = []
        def callback(event):
            L.append(1)
        events.subscribe(events.ProcessGroupRemovedEvent, callback)
        options = DummyOptions()
        pconfig = DummyPConfig(options, 'foo', '/bin/foo', '/tmp')
        gconfig = DummyPGroupConfig(options, 'foo', pconfigs=[pconfig])
        options.process_group_configs = [gconfig]
        supervisord = self._makeOne(options)

        supervisord.add_process_group(gconfig)
        supervisord.process_groups['foo'].stopped_processes = [DummyProcess(None)]
        supervisord.remove_process_group('foo')
        options.test = True
        supervisord.runforever()

        self.assertEqual(L, [1])
Ejemplo n.º 47
0
    def test_reap_more_than_once(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(recursionguard=99)
        self.assertEqual(process.finished, (1, 1))
Ejemplo n.º 48
0
    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')
Ejemplo n.º 49
0
    def test_strip_ansi(self):
        options = DummyOptions()
        options.strip_ansi = True
        config = DummyPConfig(options, 'process1', '/bin/process1',
                              stdout_logfile=os.path.join(tempfile.gettempdir(), 'foo.txt'))
        process = DummyProcess(config)
        dispatcher = self._makeOne(process)
        ansi = '\x1b[34mHello world... this is longer than a token!\x1b[0m'
        noansi = 'Hello world... this is longer than a token!'

        dispatcher.output_buffer = ansi
        dispatcher.record_output()
        self.assertEqual(len(dispatcher.childlog.data), 1)
        self.assertEqual(dispatcher.childlog.data[0], noansi)

        options.strip_ansi = False

        dispatcher.output_buffer = ansi
        dispatcher.record_output()
        self.assertEqual(len(dispatcher.childlog.data), 2)
        self.assertEqual(dispatcher.childlog.data[1], ansi)
Ejemplo n.º 50
0
    def test_strip_ansi(self):
        options = DummyOptions()
        options.strip_ansi = True
        config = DummyPConfig(options, 'process1', '/bin/process1',
                              stdout_logfile='/tmp/foo')
        process = DummyProcess(config)
        dispatcher = self._makeOne(process)
        ansi = '\x1b[34mHello world... this is longer than a token!\x1b[0m'
        noansi = 'Hello world... this is longer than a token!'

        options.readfd_result = ansi
        dispatcher.handle_read_event()
        self.assertEqual(len(dispatcher.childlog.data), 1)
        self.assertEqual(dispatcher.childlog.data[0], noansi)

        options.strip_ansi = False

        options.readfd_result = ansi
        dispatcher.handle_read_event()
        self.assertEqual(len(dispatcher.childlog.data), 2)
        self.assertEqual(dispatcher.childlog.data[1], ansi)
Ejemplo n.º 51
0
 def test_writable(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     self.assertEqual(dispatcher.writable(), False)
Ejemplo n.º 52
0
 def test_writable_closed_withdata(self):
     process = DummyProcess(None)
     dispatcher = self._makeOne(process)
     dispatcher.input_buffer = ''
     dispatcher.closed = True
     self.assertEqual(dispatcher.writable(), False)
Ejemplo n.º 53
0
    def test_stdout_capturemode_multiple_buffers(self):
        from supervisor.events import ProcessCommunicationEvent
        from supervisor.events import subscribe
        events = []

        def doit(event):
            events.append(event)

        subscribe(ProcessCommunicationEvent, doit)
        import string
        letters = string.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 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 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:
                os.remove(logfile)
            except (OSError, IOError):
                pass
Ejemplo n.º 54
0
 def test_writable_open_nodata(self):
     process = DummyProcess(None)
     dispatcher = self._makeOne(process)
     dispatcher.input_buffer = 'a'
     dispatcher.closed = False
     self.assertEqual(dispatcher.writable(), True)
Ejemplo n.º 55
0
 def test_readable(self):
     process = DummyProcess(None)
     dispatcher = self._makeOne(process)
     self.assertEqual(dispatcher.readable(), False)
Ejemplo n.º 56
0
 def test_handle_read_event(self):
     process = DummyProcess(None)
     dispatcher = self._makeOne(process)
     self.assertRaises(NotImplementedError, dispatcher.handle_read_event)
Ejemplo n.º 57
0
 def test_handle_write_event(self):
     options = DummyOptions()
     config = DummyPConfig(options, 'process1', '/bin/process1')
     process = DummyProcess(config)
     dispatcher = self._makeOne(process)
     self.assertRaises(NotImplementedError, dispatcher.handle_write_event)