Skip to content

Commit 080b9a5

Browse files
committed
Avoid leaking process in tests
1 parent 47d77a6 commit 080b9a5

File tree

1 file changed

+46
-40
lines changed

1 file changed

+46
-40
lines changed

test/framework/run.py

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
@author: Kenneth Hoste (Ghent University)
3131
@author: Stijn De Weirdt (Ghent University)
3232
"""
33+
import contextlib
3334
import glob
3435
import os
3536
import re
@@ -70,6 +71,7 @@ def tearDown(self):
7071
def test_get_output_from_process(self):
7172
"""Test for get_output_from_process utility function."""
7273

74+
@contextlib.contextmanager
7375
def get_proc(cmd, asynchronous=False):
7476
if asynchronous:
7577
proc = asyncprocess.Popen(cmd, shell=True, stdout=asyncprocess.PIPE, stderr=asyncprocess.STDOUT,
@@ -78,56 +80,60 @@ def get_proc(cmd, asynchronous=False):
7880
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
7981
stdin=subprocess.PIPE, close_fds=True, executable='/bin/bash')
8082

81-
return proc
83+
try:
84+
yield proc
85+
finally:
86+
# Make sure to close the process and its pipes
87+
proc.communicate(timeout=1)
8288

8389
# get all output at once
84-
proc = get_proc("echo hello")
85-
out = get_output_from_process(proc)
86-
self.assertEqual(out, 'hello\n')
90+
with get_proc("echo hello") as proc:
91+
out = get_output_from_process(proc)
92+
self.assertEqual(out, 'hello\n')
8793

8894
# first get 100 bytes, then get the rest all at once
89-
proc = get_proc("echo hello")
90-
out = get_output_from_process(proc, read_size=100)
91-
self.assertEqual(out, 'hello\n')
92-
out = get_output_from_process(proc)
93-
self.assertEqual(out, '')
95+
with get_proc("echo hello") as proc:
96+
out = get_output_from_process(proc, read_size=100)
97+
self.assertEqual(out, 'hello\n')
98+
out = get_output_from_process(proc)
99+
self.assertEqual(out, '')
94100

95101
# get output in small bits, keep trying to get output (which shouldn't fail)
96-
proc = get_proc("echo hello")
97-
out = get_output_from_process(proc, read_size=1)
98-
self.assertEqual(out, 'h')
99-
out = get_output_from_process(proc, read_size=3)
100-
self.assertEqual(out, 'ell')
101-
out = get_output_from_process(proc, read_size=2)
102-
self.assertEqual(out, 'o\n')
103-
out = get_output_from_process(proc, read_size=1)
104-
self.assertEqual(out, '')
105-
out = get_output_from_process(proc, read_size=10)
106-
self.assertEqual(out, '')
107-
out = get_output_from_process(proc)
108-
self.assertEqual(out, '')
102+
with get_proc("echo hello") as proc:
103+
out = get_output_from_process(proc, read_size=1)
104+
self.assertEqual(out, 'h')
105+
out = get_output_from_process(proc, read_size=3)
106+
self.assertEqual(out, 'ell')
107+
out = get_output_from_process(proc, read_size=2)
108+
self.assertEqual(out, 'o\n')
109+
out = get_output_from_process(proc, read_size=1)
110+
self.assertEqual(out, '')
111+
out = get_output_from_process(proc, read_size=10)
112+
self.assertEqual(out, '')
113+
out = get_output_from_process(proc)
114+
self.assertEqual(out, '')
109115

110116
# can also get output asynchronously (read_size is *ignored* in that case)
111117
async_cmd = "echo hello; read reply; echo $reply"
112118

113-
proc = get_proc(async_cmd, asynchronous=True)
114-
out = get_output_from_process(proc, asynchronous=True)
115-
self.assertEqual(out, 'hello\n')
116-
asyncprocess.send_all(proc, 'test123\n')
117-
out = get_output_from_process(proc)
118-
self.assertEqual(out, 'test123\n')
119-
120-
proc = get_proc(async_cmd, asynchronous=True)
121-
out = get_output_from_process(proc, asynchronous=True, read_size=1)
122-
# read_size is ignored when getting output asynchronously, we're getting more than 1 byte!
123-
self.assertEqual(out, 'hello\n')
124-
asyncprocess.send_all(proc, 'test123\n')
125-
out = get_output_from_process(proc, read_size=3)
126-
self.assertEqual(out, 'tes')
127-
out = get_output_from_process(proc, read_size=2)
128-
self.assertEqual(out, 't1')
129-
out = get_output_from_process(proc)
130-
self.assertEqual(out, '23\n')
119+
with get_proc(async_cmd, asynchronous=True) as proc:
120+
out = get_output_from_process(proc, asynchronous=True)
121+
self.assertEqual(out, 'hello\n')
122+
asyncprocess.send_all(proc, 'test123\n')
123+
out = get_output_from_process(proc)
124+
self.assertEqual(out, 'test123\n')
125+
126+
with get_proc(async_cmd, asynchronous=True) as proc:
127+
out = get_output_from_process(proc, asynchronous=True, read_size=1)
128+
# read_size is ignored when getting output asynchronously, we're getting more than 1 byte!
129+
self.assertEqual(out, 'hello\n')
130+
asyncprocess.send_all(proc, 'test123\n')
131+
out = get_output_from_process(proc, read_size=3)
132+
self.assertEqual(out, 'tes')
133+
out = get_output_from_process(proc, read_size=2)
134+
self.assertEqual(out, 't1')
135+
out = get_output_from_process(proc)
136+
self.assertEqual(out, '23\n')
131137

132138
def test_run_cmd(self):
133139
"""Basic test for run_cmd function."""

0 commit comments

Comments
 (0)