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")
def test_tick(self): from 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_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)
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)'))
def setup_state_event_callback(self): def process_state_event_cb(event): logger.debug("EVENT CALLBACK: %s" % (event)) eventlistener = self.rpc.supervisord.process_groups[ dependent_startup_service_name] eventlistener._acceptEvent(event, head=False) event_type = event.__class__ serial = event.serial pool_serial = event.pool_serials[dependent_startup_service_name] envelope = eventlistener._eventEnvelope(event_type, serial, pool_serial, str(event)) logger.debug("Writing event envelope to stdin: %s" % envelope) self.stdin_wrapper.write(envelope) eventlistener.event_buffer.pop(0) self.listener_process.event = event del events.callbacks[:] for event in [ # 'PROCESS_STATE', 'PROCESS_STATE_STOPPED', 'PROCESS_STATE_EXITED', 'PROCESS_STATE_STARTING', 'PROCESS_STATE_STOPPING', 'PROCESS_STATE_BACKOFF', 'PROCESS_STATE_FATAL', 'PROCESS_STATE_RUNNING', 'PROCESS_STATE_UNKNOWN' ]: events.subscribe(getattr(events.EventTypes, event), process_state_event_cb)
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')
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)
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')
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) result = options.logger.data[0] self.assertTrue(result.endswith('BUSY -> ACKNOWLEDGED (rejected)'))
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)
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) self.assertEqual(options.logger.data[0], 'process1: event was processed') self.assertEqual(options.logger.data[1], 'process1: BUSY -> ACKNOWLEDGED')
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'))
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')
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 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 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 __init__(self, supvisors): """ Initialization of the attributes. """ self.supvisors = supvisors # shortcuts for source code readability supvisors_short_cuts(self, ['fsm', 'info_source', 'logger', 'statistician']) self.address = self.supvisors.address_mapper.local_address # subscribe to internal events events.subscribe(events.SupervisorRunningEvent, self.on_running) events.subscribe(events.SupervisorStoppingEvent, self.on_stopping) events.subscribe(events.ProcessStateEvent, self.on_process) events.subscribe(events.Tick5Event, self.on_tick) events.subscribe(events.RemoteCommunicationEvent, self.on_remote_event)
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(open(logfile, "r").read(), "") 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
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)
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
def test_add_process_group_event(self): from 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_add_process_group_emits_event(self): from supervisor import events L = [] def callback(event): L.append(1) events.subscribe(events.ProcessGroupAddedEvent, 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) options.test = True supervisord.runforever() self.assertEqual(L, [1])
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')
def __init__(self, supervisord, host, environment, subEnv, urls, urlIndex, clusterId, pod, returnProxy, exitwithprocess, logger): self.supervisord = supervisord self.host = host self.env = environment self.subEnv = subEnv self.urls = urls self.urlIndex = urlIndex self.clusterId = clusterId self.pod = pod self.returnProxy = returnProxy self.exitwithprocess = exitwithprocess self.logger = logger self.supervisorid = supervisord.options.identifier self.connection = None self.configerror = None self.configadded = [] self.configupdated = [] self.configremoved = [] self.since = None self.repubSecs = 59 * 60 # every 1 hours self.lastRepub = 0 self.closed = False # cope with order of group delete and update self.deletedGroups = set() if self.supervisorid == "supervisor": raise Exception( "You must set the identifier in the supervisor config to something unique" ) self.cgroupPattern = re.compile(r"docker[-/]([0-9a-f]+)") # subscribe to what we're interested in events.subscribe(events.SupervisorStateChangeEvent, tryTo(self.onSupervisorStateChange, logger)) events.subscribe(events.ProcessStateEvent, tryTo(self.onProcessStateChange, logger)) events.subscribe(events.ProcessGroupAddedEvent, tryTo(self.onGroupAdd, logger)) events.subscribe(events.ProcessGroupRemovedEvent, tryTo(self.onGroupRemove, logger)) events.subscribe(events.Tick5Event, tryTo(self.onTick, logger))
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', 'foo', '/bin/foo') 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])
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 = SupervisorStates.SHUTDOWN L = [] def callback(event): L.append(event) from supervisor import events events.subscribe(events.SupervisorStateChangeEvent, callback) from 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_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 supervisor import events events.subscribe(events.SupervisorStateChangeEvent, callback) from 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 __init__(self, supvisors): """ Initialization of the attributes. """ self.supvisors = supvisors # shortcuts for source code readability supvisors_short_cuts(self, ['fsm', 'info_source', 'logger', 'statistician']) # test if statistics collector can be created for local host try: from supvisors.statscollector import instant_statistics self.collector = instant_statistics except ImportError: self.logger.warn('psutil not installed. this Supvisors will not publish statistics') self.collector = None # other attributes self.address = self.supvisors.address_mapper.local_address self.publisher = None self.main_loop = None # subscribe to internal events events.subscribe(events.SupervisorRunningEvent, self.on_running) events.subscribe(events.SupervisorStoppingEvent, self.on_stopping) events.subscribe(events.ProcessStateEvent, self.on_process) events.subscribe(events.Tick5Event, self.on_tick) events.subscribe(events.RemoteCommunicationEvent, self.on_remote_event)
def test_toggle_capturemode_sends_event(self): options = DummyOptions() config = DummyPConfig(options, 'process1', '/bin/process1', stdout_logfile=os.path.join(tempfile.gettempdir(), 'foo.txt'), stdout_capture_maxbytes=500) process = DummyProcess(config) process.pid = 4000 dispatcher = self._makeOne(process) dispatcher.capturemode = True dispatcher.capturelog.getvalue = lambda: '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')
def __init__(self, supvisors): """ Initialization of the attributes. """ self.supvisors = supvisors # shortcuts for source code readability supvisors_short_cuts(self, ['fsm', 'info_source', 'logger', 'statistician']) # test if statistics collector can be created for local host try: from supvisors.statscollector import instant_statistics self.collector = instant_statistics except ImportError: self.logger.warn('psutil not installed') self.logger.warn('this Supvisors will not publish statistics') self.collector = None # other attributes self.address = self.supvisors.address_mapper.local_address self.publisher = None self.main_loop = None # subscribe to internal events events.subscribe(events.SupervisorRunningEvent, self.on_running) events.subscribe(events.SupervisorStoppingEvent, self.on_stopping) events.subscribe(events.ProcessStateEvent, self.on_process) events.subscribe(events.Tick5Event, self.on_tick) events.subscribe(events.RemoteCommunicationEvent, self.on_remote_event)
def _subscribe(self): for event_type in self.config.pool_events: events.subscribe(event_type, self._acceptEvent) events.subscribe(events.EventRejectedEvent, self.handle_rejected)
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 # 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 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 ] with open(logfile, 'r') as f: self.assertEqual(f.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 ] with open(logfile, 'r') as f: self.assertEqual(f.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 ] with open(logfile, 'r') as f: self.assertEqual(f.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: dispatcher.capturelog.close() dispatcher.childlog.close() os.remove(logfile) except (OSError, IOError): pass
def test_subscribe(self): from supervisor import events events.subscribe(None, None) self.assertEqual(events.callbacks, [(None, None)])
def _start(self): subscribe(Event, self._handle_event)
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
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