def __init__(self, adapter_args, name="noname"):
        """
        Test session.

        Parameters
        ----------
        adapter_args : DaArgs
            [description]
        """
        self.session_name = name  # type: str
        self._adapter_args = adapter_args  # type: DaArgs
        self._adapter_obj = None  # type: Union[DebugAdapter, None]
        self._adapter_thread = None  # type: Union[Thread, None]
        # self._client = None  # type: ClientDa
        self._client_stream = None  # type: Union[JsonIOStream, None]
        self._client_socket = None  # type: Union[socket.socket, None]
        self.session_timeline = timeline.Timeline("Timeline of \"%s\"" % self.session_name)
        self._message_factory = MessageFactory()
        self._reader_thread = None  # type: Union[Thread, None]
        self._ongoing_request = None  # used for catching responses. Will set to None after every recorded responce
        self._last_response = None
        self.__stop = False
        self.client_busy = Lock()
Exemple #2
0
    def __init__(self, debug_config=None):
        assert Session.tmpdir is not None
        watchdog.start()

        self.id = next(Session._counter)
        log.info("Starting {0}", self)

        self.client_id = "vscode"

        self.debuggee = None
        """psutil.Popen instance for the debuggee process."""

        self.adapter = None
        """psutil.Popen instance for the adapter process."""

        self.adapter_endpoints = None
        """Name of the file that contains the adapter endpoints information.

        This file is generated by the adapter when it opens the listener sockets,
        and deleted by it when it exits.
        """

        self.channel = None
        """JsonMessageChannel to the adapter."""

        self.captured_output = {"stdout", "stderr"}
        """Before the debuggee is spawned, this is the set of stdio streams that
        should be captured once it is spawned.

        After it is spawned, this is a CapturedOutput object capturing those streams.
        """

        self.backchannel = None
        """The BackChannel object to talk to the debuggee.

        Must be explicitly created with open_backchannel().
        """

        self.scratchpad = comms.ScratchPad(self)
        """The ScratchPad object to talk to the debuggee."""

        self.start_request = None
        """The "launch" or "attach" request that started executing code in this session.
        """

        self.expected_exit_code = 0
        """The expected exit code for the debuggee process.

        If None, the debuggee is not expected to exit when the Session is closed.

        If not None, this is validated against both exit_code and debuggee.returncode.
        """

        self.exit_code = None
        """The actual exit code for the debuggee process, as received from DAP.
        """

        self.config = config.DebugConfig(
            debug_config if debug_config is not None else {
                "justMyCode": True,
                "name": "Test",
                "type": "python"
            })
        """The debug configuration for this session."""

        self.before_request = lambda command, arguments: None
        """Invoked for every outgoing request in this session, allowing any final
        tweaks to the request before it is sent.
        """

        self.log_dir = (None if log.log_dir is None else
                        py.path.local(log.log_dir) / str(self))
        """The log directory for this session. Passed via DEBUGPY_LOG_DIR to all spawned
        child processes.

        If set to None, DEBUGPY_LOG_DIR is not automatically added, but tests can still
        provide it manually.
        """

        self.tmpdir = Session.tmpdir / str(self)
        self.tmpdir.ensure(dir=True)

        self.timeline = timeline.Timeline(str(self))
        self.ignore_unobserved.extend([
            timeline.Event("module"),
            timeline.Event("continued"),
            timeline.Event("debugpyWaitingForServer"),
            timeline.Event("thread",
                           some.dict.containing({"reason": "started"})),
            timeline.Event("thread", some.dict.containing({"reason":
                                                           "exited"})),
            timeline.Event("output",
                           some.dict.containing({"category": "stdout"})),
            timeline.Event("output",
                           some.dict.containing({"category": "stderr"})),
            timeline.Event("output",
                           some.dict.containing({"category": "console"})),
        ])

        # Expose some common members of timeline directly - these should be the ones
        # that are the most straightforward to use, and are difficult to use incorrectly.
        # Conversely, most tests should restrict themselves to this subset of the API,
        # and avoid calling members of timeline directly unless there is a good reason.
        self.new = self.timeline.new
        self.observe = self.timeline.observe
        self.wait_for_next = self.timeline.wait_for_next
        self.proceed = self.timeline.proceed
        self.expect_new = self.timeline.expect_new
        self.expect_realized = self.timeline.expect_realized
        self.all_occurrences_of = self.timeline.all_occurrences_of
        self.observe_all = self.timeline.observe_all

        spawn_adapter = self.spawn_adapter
        self.spawn_adapter = lambda *args, **kwargs: spawn_adapter(
            *args, **kwargs)
        self.spawn_adapter.env = util.Env()

        spawn_debuggee = self.spawn_debuggee
        self.spawn_debuggee = lambda *args, **kwargs: spawn_debuggee(
            *args, **kwargs)
        self.spawn_debuggee.env = util.Env()