Skip to content

Commit a56867a

Browse files
Copilotrchiodo
andauthored
test: add debugger integration coverage for pytest processpool child sessions
Agent-Logs-Url: https://github.com/microsoft/vscode-python-debugger/sessions/573cd841-8f08-4cd0-8021-229e2380164f Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>
1 parent 0c86597 commit a56867a

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import os
2+
import random
3+
import time
4+
from concurrent.futures import ProcessPoolExecutor, wait as futures_wait
5+
6+
7+
def worker_func() -> int:
8+
time_to_sleep = random.randint(1, 2) / 10
9+
time.sleep(time_to_sleep)
10+
return int(time_to_sleep * 10)
11+
12+
13+
def library_function() -> None:
14+
futures = []
15+
with ProcessPoolExecutor(max_workers=4) as pool:
16+
for _ in range(8):
17+
futures.append(pool.submit(worker_func))
18+
done, _ = futures_wait(futures)
19+
for fut in done:
20+
_ = fut.result()
21+
22+
23+
def test_library_process_pool() -> None:
24+
library_function()
25+
done_file = os.environ.get("DEBUG_DONE_FILE")
26+
if done_file:
27+
with open(done_file, "w", encoding="utf-8") as fp:
28+
fp.write("done")

src/test/unittest/adapter/adapter.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ function resolveWSFile(wsRoot: string, ...filePath: string[]): string {
2121

2222
suite('Debugger Integration', () => {
2323
const file = resolveWSFile(WS_ROOT, 'pythonFiles', 'debugging', 'wait_for_file.py');
24+
const processPoolTestFile = resolveWSFile(WS_ROOT, 'pythonFiles', 'debugging', 'test_pytest_processpool.py');
2425
const doneFile = resolveWSFile(WS_ROOT, 'should-not-exist');
2526
const outFile = resolveWSFile(WS_ROOT, 'output.txt');
27+
const processPoolDoneFile = resolveWSFile(WS_ROOT, 'pytest-processpool-debug-done.txt');
2628
const resource = vscode.Uri.file(file);
2729
const defaultScriptArgs = [doneFile];
2830
let workspaceRoot: vscode.WorkspaceFolder;
@@ -107,4 +109,36 @@ suite('Debugger Integration', () => {
107109
});
108110
}
109111
});
112+
113+
suite('pytest multiprocess test debugging', () => {
114+
test('processpool test reaches code after worker joins in debug-test session', async function () {
115+
this.timeout(120_000);
116+
fix.addFSCleanup(processPoolDoneFile);
117+
118+
const config = {
119+
type: 'python',
120+
name: 'debug pytest processpool',
121+
request: 'launch',
122+
module: 'pytest',
123+
args: ['-s', processPoolTestFile, '-k', 'test_library_process_pool'],
124+
console: 'integratedTerminal',
125+
purpose: ['debug-test'],
126+
subProcess: true,
127+
cwd: WS_ROOT,
128+
env: {
129+
DEBUG_DONE_FILE: processPoolDoneFile,
130+
},
131+
};
132+
133+
const session = fix.resolveDebuggerWithConfig(config, workspaceRoot);
134+
await session.start();
135+
const result = await session.waitUntilDone();
136+
137+
expect(result.exitCode).to.equal(0, 'bad exit code');
138+
expect(await fs.pathExists(processPoolDoneFile)).to.equal(
139+
true,
140+
'pytest test did not reach code after process pool join',
141+
);
142+
});
143+
});
110144
});

src/test/unittest/utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ class DebuggerSession {
277277
}
278278

279279
export class DebuggerFixture extends PythonFixture {
280+
public resolveDebuggerWithConfig(
281+
config: vscode.DebugConfiguration,
282+
wsRoot?: vscode.WorkspaceFolder,
283+
): DebuggerSession {
284+
const id = debuggers.track(config);
285+
const session = new DebuggerSession(id, config, wsRoot);
286+
debuggers.setDAPHandler(id, (src, msg) => session.handleDAPMessage(src, msg));
287+
return session;
288+
}
289+
280290
public resolveDebugger(
281291
configName: string,
282292
file: string,

0 commit comments

Comments
 (0)