def test_builtin_channels(self): b = ProcessBus() listeners = [ l for l in b.listeners if l != 'log' and not l.endswith('_ERROR') ] self.responses, expected = [], [] for channel in listeners: if channel != 'log': for index, priority in enumerate([100, 50, 0, 51]): b.subscribe(channel, self.get_listener(channel, index), priority) try: for channel in listeners: if channel != 'log': b.publish(channel) expected.extend( [msg % (i, channel, ()) for i in (2, 1, 3, 0)]) assert self.responses == expected finally: # Exit so the atexit handler doesn't complain. b.transition('EXITED')
def test_idle_to_run(self): b = ProcessBus() self.log(b, level=20) self.responses = [] num = 3 for index in range(num): b.subscribe('START', self.get_listener('START', index)) b.transition('RUN') try: # The start method MUST call all 'start' listeners. assert (set(self.responses) == set( [msg % (i, 'START', None) for i in range(num)])) # The transition method MUST move the state to RUN # (or START_ERROR, if errors occur) assert b.state == 'RUN' # The start method MUST log its states. self.assertLog([ 'Bus state: ENTER', 'Bus state: IDLE', 'Bus state: START', 'Bus state: RUN' ]) finally: # Exit so the atexit handler doesn't complain. b.transition('EXITED')
def test_idle_to_exit(self): b = ProcessBus() self.log(b, level=20) self.responses = [] num = 3 for index in range(num): b.subscribe('EXIT', self.get_listener('EXIT', index)) b.subscribe('EXITED', self.get_listener('EXITED', index)) b.transition('EXITED') # The bus MUST call all 'EXIT' listeners, # and then all 'EXITED' listeners. assert (set(self.responses) == set([msg % (i, 'EXIT', None) for i in range(num)] + [msg % (i, 'EXITED', None) for i in range(num)])) # The bus MUST move the state to EXITED assert b.state == 'EXITED' # The bus MUST log its states. self.assertLog([ 'Bus state: ENTER', 'Bus state: IDLE', 'Bus state: EXIT', 'Waiting for child threads to terminate...', 'Bus state: EXITED' ])
def test_idle_to_exit(self): b = ProcessBus() self.log(b, level=20) self.responses = [] num = 3 for index in range(num): b.subscribe('EXIT', self.get_listener('EXIT', index)) b.subscribe('EXITED', self.get_listener('EXITED', index)) b.transition('EXITED') # The bus MUST call all 'EXIT' listeners, # and then all 'EXITED' listeners. self.assertEqual( set(self.responses), set([msg % (i, 'EXIT', None) for i in range(num)] + [msg % (i, 'EXITED', None) for i in range(num)]) ) # The bus MUST move the state to EXITED self.assertEqual(b.state, 'EXITED') # The bus MUST log its states. self.assertLog([ 'Bus state: ENTER', 'Bus state: IDLE', 'Bus state: EXIT', 'Waiting for child threads to terminate...', 'Bus state: EXITED' ])
def test_idle_to_run(self): b = ProcessBus() self.log(b, level=20) self.responses = [] num = 3 for index in range(num): b.subscribe('START', self.get_listener('START', index)) b.transition('RUN') try: # The start method MUST call all 'start' listeners. self.assertEqual( set(self.responses), set([msg % (i, 'START', None) for i in range(num)]) ) # The transition method MUST move the state to RUN # (or START_ERROR, if errors occur) self.assertEqual(b.state, 'RUN') # The start method MUST log its states. self.assertLog([ 'Bus state: ENTER', 'Bus state: IDLE', 'Bus state: START', 'Bus state: RUN' ]) finally: # Exit so the atexit handler doesn't complain. b.transition('EXITED')
def test_keyboard_interrupt(self): bus = ProcessBus() Handler.bus = bus service = WebService(address=('127.0.0.1', 38002), handler_class=Handler) adapter = servers.ServerPlugin(bus, service, service.address) adapter.subscribe() # Raise a keyboard interrupt in the HTTP server's main thread. bus.transition('RUN') resp = service.do_GET('/ctrlc') assertEqual(resp.status, 200) bus.block() assertEqual(bus.state, 'EXITED')
def test_run_to_idle(self): b = ProcessBus() b.transition('RUN') self.log(b, level=20) try: self.responses = [] num = 3 for index in range(num): b.subscribe('STOP', self.get_listener('STOP', index)) b.transition('IDLE') # The idle transition MUST call all 'stop' listeners. self.assertEqual( set(self.responses), set(msg % (i, 'STOP', None) for i in range(num)) ) # The idle method MUST move the state to IDLE self.assertEqual(b.state, 'IDLE') # The idle method MUST log its states. self.assertLog([ 'Bus state: STOP', 'Bus state: IDLE' ]) finally: # Exit so the atexit handler doesn't complain. b.transition('EXITED')
def test_start_with_callback(self): b = ProcessBus() self.log(b) try: events = [] def f(*args, **kwargs): events.append(('f', args, kwargs)) def g(): events.append('g') b.subscribe('RUN', g) b.start_with_callback(f, (1, 3, 5), {'foo': 'bar'}) # Give wait() time to run f() time.sleep(0.2) # The callback method MUST wait for the STARTED state. assert b.state == 'RUN' # The callback method MUST run after all start methods. assert events == ['g', ('f', (1, 3, 5), {'foo': 'bar'})] finally: b.transition('EXITED')
def test_start_with_callback(self): b = ProcessBus() self.log(b) try: events = [] def f(*args, **kwargs): events.append(('f', args, kwargs)) def g(): events.append('g') b.subscribe('RUN', g) b.start_with_callback(f, (1, 3, 5), {'foo': 'bar'}) # Give wait() time to run f() time.sleep(0.2) # The callback method MUST wait for the STARTED state. self.assertEqual(b.state, 'RUN') # The callback method MUST run after all start methods. self.assertEqual(events, ['g', ('f', (1, 3, 5), {'foo': 'bar'})]) finally: b.transition('EXITED')
def test_builtin_channels(self): b = ProcessBus() listeners = [l for l in b.listeners if l != 'log' and not l.endswith('_ERROR')] self.responses, expected = [], [] for channel in listeners: if channel != 'log': for index, priority in enumerate([100, 50, 0, 51]): b.subscribe(channel, self.get_listener(channel, index), priority) try: for channel in listeners: if channel != 'log': b.publish(channel) expected.extend([msg % (i, channel, ()) for i in (2, 1, 3, 0)]) self.assertEqual(self.responses, expected) finally: # Exit so the atexit handler doesn't complain. b.transition('EXITED')
def test_thread_manager(self): bus = ProcessBus() class Handler(WebHandler): def do_GET(self): if self.path == '/': self.respond('Hello World') else: self.respond(status=404) Handler.bus = bus service = WebService(address=('127.0.0.1', 38001), handler_class=Handler) WebAdapter(bus, service).subscribe() tm = tasks.ThreadManager(bus) tm.subscribe() assertEqual(len(tm.threads), 0) # Test server start bus.transition('RUN') try: assertEqual(bus.state, 'RUN') assertEqual(service.ready, True) assertEqual(len(tm.threads), 0) assertEqual(service.do_GET('/').read(), b'Hello World') assertEqual(len(tm.threads), 1) # Test bus stop. This will also stop the WebService. bus.transition('IDLE') assertEqual(bus.state, 'IDLE') # Verify that our custom stop function was called assertEqual(len(tm.threads), 0) finally: bus.transition('EXITED')