# Path: houston/util.py
# class TimeoutError(Exception):
#     @staticmethod
#     def produce(msg=None):
#         raise TimeoutError(msg)
# 
# def printflush(s):
#     print(s)
#     sys.stdout.flush()
# 
# Path: houston/mission.py
# class Mission(object):
#     """
#     A mission is represented as a sequence of commands that are carried out in
#     a given environment and initial state.
#     """
#     configuration = attr.ib(type=Configuration)
#     environment = attr.ib(type=Environment)
#     initial_state = attr.ib(type=State)
#     commands = attr.ib(type=Tuple[Command], converter=tuple)
#     system = attr.ib(type=Type[System])
# 
#     @staticmethod
#     def from_dict(jsn: Dict[str, Any]) -> 'Mission':
#         system = System.get_by_name(jsn['system'])
#         env = Environment.from_json(jsn['environment'])
#         config = system.configuration.from_dict(jsn['configuration'])
#         initial_state = system.state.from_dict(jsn['initial_state'])
#         cmds = tuple(Command.from_dict(c) for c in jsn['commands'])
#         return Mission(config, env, initial_state, cmds, system)
# 
#     def is_empty(self) -> bool:
#         """
#         Returns True if this mission contains no commands.
#         """
#         return self.commands == ()
# 
#     def __iter__(self) -> Iterator[Command]:
#         """
#         Returns an iterator over the commands contained in this mission.
#         """
#         yield from self.commands
# 
#     @property
#     def size(self) -> int:
#         """
#         The number of commands in this mission.
#         """
#         return len(self.commands)
# 
#     def extended(self, cmd: Command) -> 'Mission':
#         """
#         Returns a variant of this mission with a given command added onto the
#         end.
#         """
#         cmds = self.commands + (cmd,)
#         return Mission(self.environment, self.initial_state, cmds, self.system)
# 
#     def to_dict(self) -> Dict[str, Any]:
#         return {
#             'configuration': self.configuration.to_dict(),
#             'environment': self.environment.to_json(),
#             'initial_state': self.initial_state.to_dict(),
#             'commands': [c.to_dict() for c in self.commands],
#             'system': self.system.name}
# 
#     def run(self,
#             bz: BugZooClient,
#             snapshot_or_name: Union[str, Snapshot]
#             ) -> 'MissionOutcome':
#         """
#         Creates a sandbox and runs the commands and returns the outcome.
#         """
#         with self.system.sandbox.for_snapshot(bz,
#                                               snapshot_or_name,
#                                               self.initial_state,
#                                               self.environment,
#                                               self.configuration) as sandbox:
#             outcome = sandbox.run(self.commands)
#             return outcome


from typing import Optional, Tuple
from bugzoo.client import Client as BugZooClient
from .util import TimeoutError, printflush
from .mission import Mission
import logging
import threading
import time
import signal

        for runner in self.__runners:
            if runner is not None:
                runner.shutdown()
        self.__runners = []

    @property
    def system(self) -> 'System':
        """
        The system under test.
        """
        return self.__system

    @property
    def size(self) -> int:
        """
        The number of independent threads being used by the pool to run
        tests.
        """
        return self.__runners.length()

    def report(self, mission, outcome, coverage=None) -> None:
        """
        Used to report the outcome of a mission.

        WARNING: It is the responsibility of the callback to guarantee
            thread safety (if necessary).
        """
        self.__callback(mission, outcome, coverage)


# Path: houston/util.py
# class TimeoutError(Exception):
#     @staticmethod
#     def produce(msg=None):
#         raise TimeoutError(msg)
# 
# def printflush(s):
#     print(s)
#     sys.stdout.flush()
# 
# Path: houston/mission.py
# class Mission(object):
#     """
#     A mission is represented as a sequence of commands that are carried out in
#     a given environment and initial state.
#     """
#     configuration = attr.ib(type=Configuration)
#     environment = attr.ib(type=Environment)
#     initial_state = attr.ib(type=State)
#     commands = attr.ib(type=Tuple[Command], converter=tuple)
#     system = attr.ib(type=Type[System])
# 
#     @staticmethod
#     def from_dict(jsn: Dict[str, Any]) -> 'Mission':
#         system = System.get_by_name(jsn['system'])
#         env = Environment.from_json(jsn['environment'])
#         config = system.configuration.from_dict(jsn['configuration'])
#         initial_state = system.state.from_dict(jsn['initial_state'])
#         cmds = tuple(Command.from_dict(c) for c in jsn['commands'])
#         return Mission(config, env, initial_state, cmds, system)
# 
#     def is_empty(self) -> bool:
#         """
#         Returns True if this mission contains no commands.
#         """
#         return self.commands == ()
# 
#     def __iter__(self) -> Iterator[Command]:
#         """
#         Returns an iterator over the commands contained in this mission.
#         """
#         yield from self.commands
# 
#     @property
#     def size(self) -> int:
#         """
#         The number of commands in this mission.
#         """
#         return len(self.commands)
# 
#     def extended(self, cmd: Command) -> 'Mission':
#         """
#         Returns a variant of this mission with a given command added onto the
#         end.
#         """
#         cmds = self.commands + (cmd,)
#         return Mission(self.environment, self.initial_state, cmds, self.system)
# 
#     def to_dict(self) -> Dict[str, Any]:
#         return {
#             'configuration': self.configuration.to_dict(),
#             'environment': self.environment.to_json(),
#             'initial_state': self.initial_state.to_dict(),
#             'commands': [c.to_dict() for c in self.commands],
#             'system': self.system.name}
# 
#     def run(self,
#             bz: BugZooClient,
#             snapshot_or_name: Union[str, Snapshot]
#             ) -> 'MissionOutcome':
#         """
#         Creates a sandbox and runs the commands and returns the outcome.
#         """
#         with self.system.sandbox.for_snapshot(bz,
#                                               snapshot_or_name,
#                                               self.initial_state,
#                                               self.environment,
#                                               self.configuration) as sandbox:
#             outcome = sandbox.run(self.commands)
#             return outcome


# Path: houston/runner.py
from typing import Optional, Tuple
from bugzoo.client import Client as BugZooClient
from .util import TimeoutError, printflush
from .mission import Mission
import logging
import threading
import time
import signal


        for runner in self.__runners:
            if runner is not None:
                runner.shutdown()
        self.__runners = []

    @property
    def system(self) -> 'System':
        """
        The system under test.
        """
        return self.__system

    @property
    def size(self) -> int:
        """
        The number of independent threads being used by the pool to run
        tests.
        """
        return self.__runners.length()

    def report(self, mission, outcome, coverage=None) -> None:
        """
        Used to report the outcome of a mission.

        WARNING: It is the responsibility of the callback to guarantee
            thread safety (if necessary).
        """
        self.__callback(mission, outcome, coverage)


    def fetch(self) -> Tuple[int, Optional[Mission]]: