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'
        ])
Example #4
0
    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'
        ])
Example #5
0
    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')
Example #6
0
    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')
Example #7
0
    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')
Example #9
0
    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')
Example #10
0
    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')
Example #11
0
    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')