##// END OF EJS Templates
catch KeyboardInterrupt in parallel tests teardown...
MinRK -
Show More
@@ -1,130 +1,136 b''
1 1 """toplevel setup/teardown for parallel tests."""
2 2 from __future__ import print_function
3 3
4 4 #-------------------------------------------------------------------------------
5 5 # Copyright (C) 2011 The IPython Development Team
6 6 #
7 7 # Distributed under the terms of the BSD License. The full license is in
8 8 # the file COPYING, distributed as part of this software.
9 9 #-------------------------------------------------------------------------------
10 10
11 11 #-------------------------------------------------------------------------------
12 12 # Imports
13 13 #-------------------------------------------------------------------------------
14 14
15 15 import os
16 16 import tempfile
17 17 import time
18 18 from subprocess import Popen, PIPE, STDOUT
19 19
20 20 import nose
21 21
22 22 from IPython.utils.path import get_ipython_dir
23 23 from IPython.parallel import Client
24 24 from IPython.parallel.apps.launcher import (LocalProcessLauncher,
25 25 ipengine_cmd_argv,
26 26 ipcontroller_cmd_argv,
27 27 SIGKILL,
28 28 ProcessStateError,
29 29 )
30 30
31 31 # globals
32 32 launchers = []
33 33 blackhole = open(os.devnull, 'w')
34 34
35 35 # Launcher class
36 36 class TestProcessLauncher(LocalProcessLauncher):
37 37 """subclass LocalProcessLauncher, to prevent extra sockets and threads being created on Windows"""
38 38 def start(self):
39 39 if self.state == 'before':
40 40 # Store stdout & stderr to show with failing tests.
41 41 # This is defined in IPython.testing.iptest
42 42 self.process = Popen(self.args,
43 43 stdout=nose.iptest_stdstreams_fileno(), stderr=STDOUT,
44 44 env=os.environ,
45 45 cwd=self.work_dir
46 46 )
47 47 self.notify_start(self.process.pid)
48 48 self.poll = self.process.poll
49 49 else:
50 50 s = 'The process was already started and has state: %r' % self.state
51 51 raise ProcessStateError(s)
52 52
53 53 # nose setup/teardown
54 54
55 55 def setup():
56 56 cluster_dir = os.path.join(get_ipython_dir(), 'profile_iptest')
57 57 engine_json = os.path.join(cluster_dir, 'security', 'ipcontroller-engine.json')
58 58 client_json = os.path.join(cluster_dir, 'security', 'ipcontroller-client.json')
59 59 for json in (engine_json, client_json):
60 60 if os.path.exists(json):
61 61 os.remove(json)
62 62
63 63 cp = TestProcessLauncher()
64 64 cp.cmd_and_args = ipcontroller_cmd_argv + \
65 65 ['--profile=iptest', '--log-level=20', '--ping=250', '--dictdb']
66 66 cp.start()
67 67 launchers.append(cp)
68 68 tic = time.time()
69 69 while not os.path.exists(engine_json) or not os.path.exists(client_json):
70 70 if cp.poll() is not None:
71 71 raise RuntimeError("The test controller exited with status %s" % cp.poll())
72 72 elif time.time()-tic > 15:
73 73 raise RuntimeError("Timeout waiting for the test controller to start.")
74 74 time.sleep(0.1)
75 75 add_engines(1)
76 76
77 77 def add_engines(n=1, profile='iptest', total=False):
78 78 """add a number of engines to a given profile.
79 79
80 80 If total is True, then already running engines are counted, and only
81 81 the additional engines necessary (if any) are started.
82 82 """
83 83 rc = Client(profile=profile)
84 84 base = len(rc)
85 85
86 86 if total:
87 87 n = max(n - base, 0)
88 88
89 89 eps = []
90 90 for i in range(n):
91 91 ep = TestProcessLauncher()
92 92 ep.cmd_and_args = ipengine_cmd_argv + [
93 93 '--profile=%s' % profile,
94 94 '--log-level=50',
95 95 '--InteractiveShell.colors=nocolor'
96 96 ]
97 97 ep.start()
98 98 launchers.append(ep)
99 99 eps.append(ep)
100 100 tic = time.time()
101 101 while len(rc) < base+n:
102 102 if any([ ep.poll() is not None for ep in eps ]):
103 103 raise RuntimeError("A test engine failed to start.")
104 104 elif time.time()-tic > 15:
105 105 raise RuntimeError("Timeout waiting for engines to connect.")
106 106 time.sleep(.1)
107 107 rc.spin()
108 108 rc.close()
109 109 return eps
110 110
111 111 def teardown():
112 time.sleep(1)
112 try:
113 time.sleep(1)
114 except KeyboardInterrupt:
115 return
113 116 while launchers:
114 117 p = launchers.pop()
115 118 if p.poll() is None:
116 119 try:
117 120 p.stop()
118 121 except Exception as e:
119 122 print(e)
120 123 pass
121 124 if p.poll() is None:
122 time.sleep(.25)
125 try:
126 time.sleep(.25)
127 except KeyboardInterrupt:
128 return
123 129 if p.poll() is None:
124 130 try:
125 131 print('cleaning up test process...')
126 132 p.signal(SIGKILL)
127 133 except:
128 134 print("couldn't shutdown process: ", p)
129 135 blackhole.close()
130 136
General Comments 0
You need to be logged in to leave comments. Login now