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