diff options
Diffstat (limited to 'distbuild')
-rw-r--r-- | distbuild/helper_router.py | 4 | ||||
-rw-r--r-- | distbuild/json_router.py | 2 | ||||
-rw-r--r-- | distbuild/mainloop.py | 65 | ||||
-rw-r--r-- | distbuild/sockserv.py | 4 |
4 files changed, 70 insertions, 5 deletions
diff --git a/distbuild/helper_router.py b/distbuild/helper_router.py index 5578f750..22096b81 100644 --- a/distbuild/helper_router.py +++ b/distbuild/helper_router.py @@ -40,7 +40,7 @@ class HelperResult(object): class HelperRouter(distbuild.StateMachine): - '''Route JSON messages between helpers and other state machines. + '''Route JSON messages between controller and its helper. This state machine relays and schedules access to one distbuild-helper process. The helper process connects to a socket, which causes an @@ -51,7 +51,7 @@ class HelperRouter(distbuild.StateMachine): Other state machines in the same mainloop as HelperRouter can request work from the helper process by emitting an event: - * event source: the distbuild.HelperProcess class + * event source: the distbuild.HelperRouter class * event: distbuild.HelperRequest instance The HelperRequest event gets a message to be serialised as JSON. diff --git a/distbuild/json_router.py b/distbuild/json_router.py index d9c32a9c..0f41bfc6 100644 --- a/distbuild/json_router.py +++ b/distbuild/json_router.py @@ -22,7 +22,7 @@ import distbuild class JsonRouter(distbuild.StateMachine): - '''Route JSON messages between clients and helpers. + '''Route JSON messages between controller, worker and worker helper(s). This state machine receives JSON messages from clients and helpers, and routes messages between them. diff --git a/distbuild/mainloop.py b/distbuild/mainloop.py index e7c0cc3b..d48d60ec 100644 --- a/distbuild/mainloop.py +++ b/distbuild/mainloop.py @@ -132,3 +132,68 @@ class MainLoop(object): event_source, event = self._events.pop(0) yield event_source, event + + +class TestableMainLoop(MainLoop): + '''Special mainloop class with extra hooks for tests to use. + + When writing a test, you often need to wait until a certain event has + happened, then examine that event. The run_until_event() and + run_until_new_state_machine() functions allow this. + + ''' + def __init__(self): + super(TestableMainLoop, self).__init__() + + self._machines_added_this_cycle = [] + self._events_sent_this_cycle = [] + + def add_state_machine(self, machine): + # Overriding the base class to monitor new state machines. + super(TestableMainLoop, self).add_state_machine(machine) + self._machines_added_this_cycle.append(machine) + + def queue_event(self, event_source, event): + # Overriding the base class to monitor new events. + super(TestableMainLoop, self).queue_event(event_source, event) + self._events_sent_this_cycle.append((event_source, event)) + + def run_until_event(self, target_event_source, target_event_type): + '''Run the main loop continuously until a given event happens. + + All queued messages will be processed before the loop exits. + + ''' + logging.debug('Running main loop until a %s event from %s.', + target_event_type, target_event_source) + while self._machines: + self._events_sent_this_cycle = [] + + self._run_once() + + for event_source, event in self._events_sent_this_cycle: + if target_event_source == event_source: + if isinstance(event, target_event_type): + logging.debug( + 'Received %s from %s, exiting loop.', event, + event_source) + return event + + def run_until_new_state_machine(self, target_machine_type): + '''Run the main loop continuously until a new state machine appears. + + All queued messages will be processed before the loop exits. + + ''' + logging.debug('Running main loop until a new %s appears.', + target_machine_type) + while self._machines: + self._machines_added_this_cycle = [] + + self._run_once() + + for machine in self._machines_added_this_cycle: + if type(machine) == target_machine_type: + logging.debug( + 'Found new machine %s, exiting loop.', machine) + return machine diff --git a/distbuild/sockserv.py b/distbuild/sockserv.py index c9979328..998cfb11 100644 --- a/distbuild/sockserv.py +++ b/distbuild/sockserv.py @@ -35,10 +35,10 @@ class ListenServer(StateMachine): def setup(self): src = ListeningSocketEventSource(self._addr, self._port) + _, self._port = src.sock.getsockname() if self._port_file: - host, port = src.sock.getsockname() with open(self._port_file, 'w') as f: - f.write('%s\n' % port) + f.write('%s\n' % self._port) self.mainloop.add_event_source(src) spec = [ |