##// END OF EJS Templates
Fix the signal handler that was breaking the test
Itamar Turner-Trauring -
Show More
@@ -1,189 +1,195 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Tests for platutils.py
3 Tests for platutils.py
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import sys
17 import sys
18 import signal
18 import os
19 import os
19 import time
20 import time
20 from _thread import interrupt_main # Py 3
21 from _thread import interrupt_main # Py 3
21 import threading
22 import threading
22 from unittest import SkipTest
23 from unittest import SkipTest
23
24
24 import nose.tools as nt
25 import nose.tools as nt
25
26
26 from IPython.utils.process import (find_cmd, FindCmdError, arg_split,
27 from IPython.utils.process import (find_cmd, FindCmdError, arg_split,
27 system, getoutput, getoutputerror,
28 system, getoutput, getoutputerror,
28 get_output_error_code)
29 get_output_error_code)
29 from IPython.utils.capture import capture_output
30 from IPython.utils.capture import capture_output
30 from IPython.testing import decorators as dec
31 from IPython.testing import decorators as dec
31 from IPython.testing import tools as tt
32 from IPython.testing import tools as tt
32
33
33 python = os.path.basename(sys.executable)
34 python = os.path.basename(sys.executable)
34
35
35 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
36 # Tests
37 # Tests
37 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
38
39
39
40
40 @dec.skip_win32
41 @dec.skip_win32
41 def test_find_cmd_ls():
42 def test_find_cmd_ls():
42 """Make sure we can find the full path to ls."""
43 """Make sure we can find the full path to ls."""
43 path = find_cmd('ls')
44 path = find_cmd('ls')
44 nt.assert_true(path.endswith('ls'))
45 nt.assert_true(path.endswith('ls'))
45
46
46
47
47 def has_pywin32():
48 def has_pywin32():
48 try:
49 try:
49 import win32api
50 import win32api
50 except ImportError:
51 except ImportError:
51 return False
52 return False
52 return True
53 return True
53
54
54
55
55 @dec.onlyif(has_pywin32, "This test requires win32api to run")
56 @dec.onlyif(has_pywin32, "This test requires win32api to run")
56 def test_find_cmd_pythonw():
57 def test_find_cmd_pythonw():
57 """Try to find pythonw on Windows."""
58 """Try to find pythonw on Windows."""
58 path = find_cmd('pythonw')
59 path = find_cmd('pythonw')
59 assert path.lower().endswith('pythonw.exe'), path
60 assert path.lower().endswith('pythonw.exe'), path
60
61
61
62
62 @dec.onlyif(lambda : sys.platform != 'win32' or has_pywin32(),
63 @dec.onlyif(lambda : sys.platform != 'win32' or has_pywin32(),
63 "This test runs on posix or in win32 with win32api installed")
64 "This test runs on posix or in win32 with win32api installed")
64 def test_find_cmd_fail():
65 def test_find_cmd_fail():
65 """Make sure that FindCmdError is raised if we can't find the cmd."""
66 """Make sure that FindCmdError is raised if we can't find the cmd."""
66 nt.assert_raises(FindCmdError,find_cmd,'asdfasdf')
67 nt.assert_raises(FindCmdError,find_cmd,'asdfasdf')
67
68
68
69
69 @dec.skip_win32
70 @dec.skip_win32
70 def test_arg_split():
71 def test_arg_split():
71 """Ensure that argument lines are correctly split like in a shell."""
72 """Ensure that argument lines are correctly split like in a shell."""
72 tests = [['hi', ['hi']],
73 tests = [['hi', ['hi']],
73 [u'hi', [u'hi']],
74 [u'hi', [u'hi']],
74 ['hello there', ['hello', 'there']],
75 ['hello there', ['hello', 'there']],
75 # \u01ce == \N{LATIN SMALL LETTER A WITH CARON}
76 # \u01ce == \N{LATIN SMALL LETTER A WITH CARON}
76 # Do not use \N because the tests crash with syntax error in
77 # Do not use \N because the tests crash with syntax error in
77 # some cases, for example windows python2.6.
78 # some cases, for example windows python2.6.
78 [u'h\u01cello', [u'h\u01cello']],
79 [u'h\u01cello', [u'h\u01cello']],
79 ['something "with quotes"', ['something', '"with quotes"']],
80 ['something "with quotes"', ['something', '"with quotes"']],
80 ]
81 ]
81 for argstr, argv in tests:
82 for argstr, argv in tests:
82 nt.assert_equal(arg_split(argstr), argv)
83 nt.assert_equal(arg_split(argstr), argv)
83
84
84 @dec.skip_if_not_win32
85 @dec.skip_if_not_win32
85 def test_arg_split_win32():
86 def test_arg_split_win32():
86 """Ensure that argument lines are correctly split like in a shell."""
87 """Ensure that argument lines are correctly split like in a shell."""
87 tests = [['hi', ['hi']],
88 tests = [['hi', ['hi']],
88 [u'hi', [u'hi']],
89 [u'hi', [u'hi']],
89 ['hello there', ['hello', 'there']],
90 ['hello there', ['hello', 'there']],
90 [u'h\u01cello', [u'h\u01cello']],
91 [u'h\u01cello', [u'h\u01cello']],
91 ['something "with quotes"', ['something', 'with quotes']],
92 ['something "with quotes"', ['something', 'with quotes']],
92 ]
93 ]
93 for argstr, argv in tests:
94 for argstr, argv in tests:
94 nt.assert_equal(arg_split(argstr), argv)
95 nt.assert_equal(arg_split(argstr), argv)
95
96
96
97
97 class SubProcessTestCase(tt.TempFileMixin):
98 class SubProcessTestCase(tt.TempFileMixin):
98 def setUp(self):
99 def setUp(self):
99 """Make a valid python temp file."""
100 """Make a valid python temp file."""
100 lines = [ "import sys",
101 lines = [ "import sys",
101 "print('on stdout', end='', file=sys.stdout)",
102 "print('on stdout', end='', file=sys.stdout)",
102 "print('on stderr', end='', file=sys.stderr)",
103 "print('on stderr', end='', file=sys.stderr)",
103 "sys.stdout.flush()",
104 "sys.stdout.flush()",
104 "sys.stderr.flush()"]
105 "sys.stderr.flush()"]
105 self.mktmp('\n'.join(lines))
106 self.mktmp('\n'.join(lines))
106
107
107 def test_system(self):
108 def test_system(self):
108 status = system('%s "%s"' % (python, self.fname))
109 status = system('%s "%s"' % (python, self.fname))
109 self.assertEqual(status, 0)
110 self.assertEqual(status, 0)
110
111
111 def test_system_quotes(self):
112 def test_system_quotes(self):
112 status = system('%s -c "import sys"' % python)
113 status = system('%s -c "import sys"' % python)
113 self.assertEqual(status, 0)
114 self.assertEqual(status, 0)
114
115
115 def assert_interrupts(self, command):
116 def assert_interrupts(self, command):
116 """
117 """
117 Interrupt a subprocess after a second.
118 Interrupt a subprocess after a second.
118 """
119 """
119 if threading.main_thread() != threading.current_thread():
120 if threading.main_thread() != threading.current_thread():
120 raise nt.SkipTest("Can't run this test if not in main thread.")
121 raise nt.SkipTest("Can't run this test if not in main thread.")
121
122
123 # Some tests can overwrite SIGINT handler (by using pdb for example),
124 # which then breaks this test, so just make sure it's operating
125 # normally.
126 signal.signal(signal.SIGINT, signal.default_int_handler)
127
122 def interrupt():
128 def interrupt():
123 # Wait for subprocess to start:
129 # Wait for subprocess to start:
124 time.sleep(0.5)
130 time.sleep(0.5)
125 interrupt_main()
131 interrupt_main()
126
132
127 threading.Thread(target=interrupt).start()
133 threading.Thread(target=interrupt).start()
128 start = time.time()
134 start = time.time()
129 try:
135 try:
130 result = command()
136 result = command()
131 except KeyboardInterrupt:
137 except KeyboardInterrupt:
132 # Success!
138 # Success!
133 return
139 pass
134 end = time.time()
140 end = time.time()
135 self.assertTrue(
141 self.assertTrue(
136 end - start < 2, "Process didn't die quickly: %s" % (end - start)
142 end - start < 2, "Process didn't die quickly: %s" % (end - start)
137 )
143 )
138 return result
144 return result
139
145
140 def test_system_interrupt(self):
146 def test_system_interrupt(self):
141 """
147 """
142 When interrupted in the way ipykernel interrupts IPython, the
148 When interrupted in the way ipykernel interrupts IPython, the
143 subprocess is interrupted.
149 subprocess is interrupted.
144 """
150 """
145 def command():
151 def command():
146 return system('%s -c "import time; time.sleep(5)"' % python)
152 return system('%s -c "import time; time.sleep(5)"' % python)
147
153
148 status = self.assert_interrupts(command)
154 status = self.assert_interrupts(command)
149 self.assertNotEqual(
155 self.assertNotEqual(
150 status, 0, "The process wasn't interrupted. Status: %s" % (status,)
156 status, 0, "The process wasn't interrupted. Status: %s" % (status,)
151 )
157 )
152
158
153 def test_getoutput(self):
159 def test_getoutput(self):
154 out = getoutput('%s "%s"' % (python, self.fname))
160 out = getoutput('%s "%s"' % (python, self.fname))
155 # we can't rely on the order the line buffered streams are flushed
161 # we can't rely on the order the line buffered streams are flushed
156 try:
162 try:
157 self.assertEqual(out, 'on stderron stdout')
163 self.assertEqual(out, 'on stderron stdout')
158 except AssertionError:
164 except AssertionError:
159 self.assertEqual(out, 'on stdouton stderr')
165 self.assertEqual(out, 'on stdouton stderr')
160
166
161 def test_getoutput_quoted(self):
167 def test_getoutput_quoted(self):
162 out = getoutput('%s -c "print (1)"' % python)
168 out = getoutput('%s -c "print (1)"' % python)
163 self.assertEqual(out.strip(), '1')
169 self.assertEqual(out.strip(), '1')
164
170
165 #Invalid quoting on windows
171 #Invalid quoting on windows
166 @dec.skip_win32
172 @dec.skip_win32
167 def test_getoutput_quoted2(self):
173 def test_getoutput_quoted2(self):
168 out = getoutput("%s -c 'print (1)'" % python)
174 out = getoutput("%s -c 'print (1)'" % python)
169 self.assertEqual(out.strip(), '1')
175 self.assertEqual(out.strip(), '1')
170 out = getoutput("%s -c 'print (\"1\")'" % python)
176 out = getoutput("%s -c 'print (\"1\")'" % python)
171 self.assertEqual(out.strip(), '1')
177 self.assertEqual(out.strip(), '1')
172
178
173 def test_getoutput_error(self):
179 def test_getoutput_error(self):
174 out, err = getoutputerror('%s "%s"' % (python, self.fname))
180 out, err = getoutputerror('%s "%s"' % (python, self.fname))
175 self.assertEqual(out, 'on stdout')
181 self.assertEqual(out, 'on stdout')
176 self.assertEqual(err, 'on stderr')
182 self.assertEqual(err, 'on stderr')
177
183
178 def test_get_output_error_code(self):
184 def test_get_output_error_code(self):
179 quiet_exit = '%s -c "import sys; sys.exit(1)"' % python
185 quiet_exit = '%s -c "import sys; sys.exit(1)"' % python
180 out, err, code = get_output_error_code(quiet_exit)
186 out, err, code = get_output_error_code(quiet_exit)
181 self.assertEqual(out, '')
187 self.assertEqual(out, '')
182 self.assertEqual(err, '')
188 self.assertEqual(err, '')
183 self.assertEqual(code, 1)
189 self.assertEqual(code, 1)
184 out, err, code = get_output_error_code('%s "%s"' % (python, self.fname))
190 out, err, code = get_output_error_code('%s "%s"' % (python, self.fname))
185 self.assertEqual(out, 'on stdout')
191 self.assertEqual(out, 'on stdout')
186 self.assertEqual(err, 'on stderr')
192 self.assertEqual(err, 'on stderr')
187 self.assertEqual(code, 0)
193 self.assertEqual(code, 0)
188
194
189
195
General Comments 0
You need to be logged in to leave comments. Login now