A test debug session. Manages the lifetime of the adapter and the debuggee processes, captures debuggee stdio output, establishes a DAP message channel to the debuggee, and records all DAP messages in that channel on a Timeline object. Must be used in a with-statement for proper cleanup
| 26 | |
| 27 | |
| 28 | class Session(object): |
| 29 | """A test debug session. Manages the lifetime of the adapter and the debuggee |
| 30 | processes, captures debuggee stdio output, establishes a DAP message channel to |
| 31 | the debuggee, and records all DAP messages in that channel on a Timeline object. |
| 32 | |
| 33 | Must be used in a with-statement for proper cleanup. On successful exit - if no |
| 34 | exception escapes from the with-statement - the session will: |
| 35 | |
| 36 | 1. Invoke wait_for_exit(), unless expected_exit_code is None. |
| 37 | 2. Invoke disconnect(). |
| 38 | 3. Wait for the adapter process to exit. |
| 39 | 4. Finalize and closes the timeline |
| 40 | |
| 41 | If the exit is due to an exception, the session will: |
| 42 | |
| 43 | 1. Invoke disconnect(force=True). |
| 44 | 2. Kill the debuggee and the adapter processes. |
| 45 | |
| 46 | Example:: |
| 47 | |
| 48 | with debug.Session() as session: |
| 49 | # Neither debuggee nor adapter are spawned yet. Initial configuration. |
| 50 | session.log_dir = ... |
| 51 | session.config.update({...}) |
| 52 | |
| 53 | with session.launch(...): |
| 54 | # Debuggee and adapter are spawned, but there is no code executing |
| 55 | # in the debuggee yet. |
| 56 | session.set_breakpoints(...) |
| 57 | |
| 58 | # Code is executing in the debuggee. |
| 59 | session.wait_for_stop(expected_frames=[...]) |
| 60 | assert session.get_variable(...) == ... |
| 61 | session.request_continue() |
| 62 | |
| 63 | # Session is disconnected from the debuggee, and both the debuggee and the |
| 64 | # adapter processes have exited. |
| 65 | assert session.exit_code == ... |
| 66 | """ |
| 67 | |
| 68 | tmpdir = None |
| 69 | """Temporary directory in which Sessions can create the temp files they need. |
| 70 | |
| 71 | Automatically set to tmpdir for the current test by pytest_fixtures.test_wrapper(). |
| 72 | """ |
| 73 | |
| 74 | @classmethod |
| 75 | def reset_counter(cls): |
| 76 | cls._counter = itertools.count(1) |
| 77 | |
| 78 | def __init__(self, debug_config=None): |
| 79 | assert Session.tmpdir is not None |
| 80 | watchdog.start() |
| 81 | |
| 82 | self.id = next(Session._counter) |
| 83 | log.info("Starting {0}", self) |
| 84 | |
| 85 | self.client_id = "vscode" |
no outgoing calls
no test coverage detected
searching dependent graphs…