blob: 8679a16872d0b49fccca64e0750190e4411a48e9 [file] [log] [blame]
Bram Moolenaard7ece102016-02-02 23:23:02 +01001" Test for channel functions.
2scriptencoding utf-8
3
Bram Moolenaare2469252016-02-04 10:54:34 +01004if !has('channel')
5 finish
6endif
7
8" This test requires the Python command to run the test server.
Bram Moolenaara8343c12016-02-04 22:09:48 +01009" This most likely only works on Unix and Windows.
Bram Moolenaara0f9cd12016-02-03 20:13:24 +010010if has('unix')
Bram Moolenaar835dc632016-02-07 14:27:38 +010011 " We also need the job feature or the pkill command to make sure the server
12 " can be stopped.
13 if !(executable('python') && (has('job') || executable('pkill')))
Bram Moolenaara0f9cd12016-02-03 20:13:24 +010014 finish
15 endif
Bram Moolenaarb6a77372016-02-15 22:55:28 +010016 let s:python = 'python'
Bram Moolenaara8343c12016-02-04 22:09:48 +010017elseif has('win32')
Bram Moolenaarb6a77372016-02-15 22:55:28 +010018 " Use Python Launcher for Windows (py.exe) if available.
19 if executable('py.exe')
20 let s:python = 'py.exe'
21 elseif executable('python.exe')
22 let s:python = 'python.exe'
23 else
Bram Moolenaara0f9cd12016-02-03 20:13:24 +010024 finish
25 endif
26else
Bram Moolenaard6a8d482016-02-10 20:32:20 +010027 " Can't run this test.
Bram Moolenaard7ece102016-02-02 23:23:02 +010028 finish
29endif
30
Bram Moolenaare74e8e72016-02-16 22:01:30 +010031let s:chopt = {}
Bram Moolenaar3b05b132016-02-03 23:25:07 +010032
Bram Moolenaard6a8d482016-02-10 20:32:20 +010033" Run "testfunc" after sarting the server and stop the server afterwards.
Bram Moolenaar81661fb2016-02-18 22:23:34 +010034func s:run_server(testfunc, ...)
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +010035 " The Python program writes the port number in Xportnr.
36 call delete("Xportnr")
37
Bram Moolenaar81661fb2016-02-18 22:23:34 +010038 if a:0 == 1
39 let arg = ' ' . a:1
40 else
41 let arg = ''
42 endif
43 let cmd = s:python . " test_channel.py" . arg
44
Bram Moolenaard6a8d482016-02-10 20:32:20 +010045 try
46 if has('job')
Bram Moolenaar65edff82016-02-21 16:40:11 +010047 let s:job = job_start(cmd, {"stoponexit": "hup"})
48 call job_setoptions(s:job, {"stoponexit": "kill"})
Bram Moolenaard6a8d482016-02-10 20:32:20 +010049 elseif has('win32')
Bram Moolenaar81661fb2016-02-18 22:23:34 +010050 exe 'silent !start cmd /c start "test_channel" ' . cmd
Bram Moolenaard6a8d482016-02-10 20:32:20 +010051 else
Bram Moolenaar81661fb2016-02-18 22:23:34 +010052 exe 'silent !' . cmd . '&'
Bram Moolenaard7ece102016-02-02 23:23:02 +010053 endif
Bram Moolenaard7ece102016-02-02 23:23:02 +010054
Bram Moolenaard6a8d482016-02-10 20:32:20 +010055 " Wait for up to 2 seconds for the port number to be there.
Bram Moolenaard6a8d482016-02-10 20:32:20 +010056 let l = []
Bram Moolenaar9fe885e2016-03-08 16:06:55 +010057 for i in range(200)
Bram Moolenaard6a8d482016-02-10 20:32:20 +010058 try
59 let l = readfile("Xportnr")
60 catch
61 endtry
62 if len(l) >= 1
63 break
64 endif
Bram Moolenaar9fe885e2016-03-08 16:06:55 +010065 sleep 10m
66 endfor
Bram Moolenaard6a8d482016-02-10 20:32:20 +010067 call delete("Xportnr")
68
69 if len(l) == 0
70 " Can't make the connection, give up.
71 call assert_false(1, "Can't start test_channel.py")
72 return -1
73 endif
74 let port = l[0]
75
76 call call(function(a:testfunc), [port])
77 catch
78 call assert_false(1, "Caught exception: " . v:exception)
79 finally
Bram Moolenaara0f9cd12016-02-03 20:13:24 +010080 call s:kill_server()
Bram Moolenaard6a8d482016-02-10 20:32:20 +010081 endtry
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +010082endfunc
83
84func s:kill_server()
Bram Moolenaar835dc632016-02-07 14:27:38 +010085 if has('job')
Bram Moolenaard6a8d482016-02-10 20:32:20 +010086 if exists('s:job')
87 call job_stop(s:job)
88 unlet s:job
89 endif
Bram Moolenaar835dc632016-02-07 14:27:38 +010090 elseif has('win32')
Bram Moolenaarb6a77372016-02-15 22:55:28 +010091 call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq test_channel"')
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +010092 else
Bram Moolenaar608a8912016-02-03 22:39:51 +010093 call system("pkill -f test_channel.py")
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +010094 endif
95endfunc
96
Bram Moolenaara07fec92016-02-05 21:04:08 +010097let s:responseMsg = ''
98func s:RequestHandler(handle, msg)
99 let s:responseHandle = a:handle
100 let s:responseMsg = a:msg
101endfunc
102
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100103" Wait for up to a second for "expr" to become true.
104func s:waitFor(expr)
105 for i in range(100)
Bram Moolenaard9d473e2016-03-08 19:07:22 +0100106 try
107 if eval(a:expr)
108 return
109 endif
110 catch
111 endtry
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100112 sleep 10m
113 endfor
114endfunc
115
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100116func s:communicate(port)
117 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100118 if ch_status(handle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100119 call assert_false(1, "Can't open channel")
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100120 return
121 endif
Bram Moolenaar839fd112016-03-06 21:34:03 +0100122 if has('job')
Bram Moolenaar03602ec2016-03-20 20:57:45 +0100123 " check that getjob without a job is handled correctly
Bram Moolenaar839fd112016-03-06 21:34:03 +0100124 call assert_equal('no process', string(ch_getjob(handle)))
125 endif
Bram Moolenaar03602ec2016-03-20 20:57:45 +0100126 let dict = ch_info(handle)
127 call assert_true(dict.id != 0)
128 call assert_equal('open', dict.status)
129 call assert_equal(a:port, string(dict.port))
130 call assert_equal('open', dict.sock_status)
131 call assert_equal('socket', dict.sock_io)
132
Bram Moolenaard7ece102016-02-02 23:23:02 +0100133 " Simple string request and reply.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100134 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
Bram Moolenaard7ece102016-02-02 23:23:02 +0100135
Bram Moolenaarac74d5e2016-03-20 14:31:00 +0100136 " Malformed command should be ignored.
Bram Moolenaarba61ac02016-03-20 16:40:37 +0100137 call assert_equal('ok', ch_evalexpr(handle, 'malformed1'))
138 call assert_equal('ok', ch_evalexpr(handle, 'malformed2'))
139 call assert_equal('ok', ch_evalexpr(handle, 'malformed3'))
140
141 " split command should work
142 call assert_equal('ok', ch_evalexpr(handle, 'split'))
143 call s:waitFor('exists("g:split")')
144 call assert_equal(123, g:split)
Bram Moolenaarac74d5e2016-03-20 14:31:00 +0100145
Bram Moolenaard7ece102016-02-02 23:23:02 +0100146 " Request that triggers sending two ex commands. These will usually be
147 " handled before getting the response, but it's not guaranteed, thus wait a
148 " tiny bit for the commands to get executed.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100149 call assert_equal('ok', ch_evalexpr(handle, 'make change'))
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100150 call s:waitFor('"added2" == getline("$")')
Bram Moolenaard7ece102016-02-02 23:23:02 +0100151 call assert_equal('added1', getline(line('$') - 1))
152 call assert_equal('added2', getline('$'))
153
Bram Moolenaarc4dcd602016-03-26 22:56:46 +0100154 " Request command "foo bar", which fails silently.
155 call assert_equal('ok', ch_evalexpr(handle, 'bad command'))
156 call s:waitFor('v:errmsg =~ "E492"')
Bram Moolenaarea6553b2016-03-27 15:13:38 +0200157 call assert_match('E492:.*foo bar', v:errmsg)
Bram Moolenaarc4dcd602016-03-26 22:56:46 +0100158
Bram Moolenaarda94fdf2016-03-03 18:09:10 +0100159 call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100}))
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100160 call s:waitFor('"added more" == getline("$")')
Bram Moolenaarf4160862016-02-05 23:09:12 +0100161 call assert_equal('added more', getline('$'))
162
Bram Moolenaara07fec92016-02-05 21:04:08 +0100163 " Send a request with a specific handler.
Bram Moolenaar910b8aa2016-02-16 21:03:07 +0100164 call ch_sendexpr(handle, 'hello!', {'callback': 's:RequestHandler'})
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100165 call s:waitFor('exists("s:responseHandle")')
Bram Moolenaar77073442016-02-13 23:23:53 +0100166 if !exists('s:responseHandle')
167 call assert_false(1, 's:responseHandle was not set')
168 else
169 call assert_equal(handle, s:responseHandle)
Bram Moolenaar9186a272016-02-23 19:34:01 +0100170 unlet s:responseHandle
Bram Moolenaar77073442016-02-13 23:23:53 +0100171 endif
Bram Moolenaara07fec92016-02-05 21:04:08 +0100172 call assert_equal('got it', s:responseMsg)
173
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100174 let s:responseMsg = ''
Bram Moolenaar910b8aa2016-02-16 21:03:07 +0100175 call ch_sendexpr(handle, 'hello!', {'callback': function('s:RequestHandler')})
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100176 call s:waitFor('exists("s:responseHandle")')
Bram Moolenaar77073442016-02-13 23:23:53 +0100177 if !exists('s:responseHandle')
178 call assert_false(1, 's:responseHandle was not set')
179 else
180 call assert_equal(handle, s:responseHandle)
Bram Moolenaar9186a272016-02-23 19:34:01 +0100181 unlet s:responseHandle
Bram Moolenaar77073442016-02-13 23:23:53 +0100182 endif
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100183 call assert_equal('got it', s:responseMsg)
184
Bram Moolenaar38fd4bb2016-03-06 16:38:28 +0100185 " Collect garbage, tests that our handle isn't collected.
Bram Moolenaar574860b2016-05-24 17:33:34 +0200186 call test_garbagecollect_now()
Bram Moolenaar38fd4bb2016-03-06 16:38:28 +0100187
Bram Moolenaar40ea1da2016-02-19 22:33:35 +0100188 " check setting options (without testing the effect)
189 call ch_setoptions(handle, {'callback': 's:NotUsed'})
Bram Moolenaar1f6ef662016-02-19 22:59:44 +0100190 call ch_setoptions(handle, {'timeout': 1111})
Bram Moolenaarb6b52522016-02-20 23:30:07 +0100191 call ch_setoptions(handle, {'mode': 'json'})
Bram Moolenaar40ea1da2016-02-19 22:33:35 +0100192 call assert_fails("call ch_setoptions(handle, {'waittime': 111})", "E475")
Bram Moolenaar0ba75a92016-02-19 23:21:26 +0100193 call ch_setoptions(handle, {'callback': ''})
Bram Moolenaar40ea1da2016-02-19 22:33:35 +0100194
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100195 " Send an eval request that works.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100196 call assert_equal('ok', ch_evalexpr(handle, 'eval-works'))
Bram Moolenaara02b3212016-02-04 21:03:33 +0100197 sleep 10m
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100198 call assert_equal([-1, 'foo123'], ch_evalexpr(handle, 'eval-result'))
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100199
Bram Moolenaarfa8b2e12016-03-26 22:19:27 +0100200 " Send an eval request with special characters.
201 call assert_equal('ok', ch_evalexpr(handle, 'eval-special'))
202 sleep 10m
203 call assert_equal([-2, "foo\x7f\x10\x01bar"], ch_evalexpr(handle, 'eval-result'))
204
205 " Send an eval request to get a line with special characters.
206 call setline(3, "a\nb\<CR>c\x01d\x7fe")
207 call assert_equal('ok', ch_evalexpr(handle, 'eval-getline'))
208 sleep 10m
209 call assert_equal([-3, "a\nb\<CR>c\x01d\x7fe"], ch_evalexpr(handle, 'eval-result'))
210
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100211 " Send an eval request that fails.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100212 call assert_equal('ok', ch_evalexpr(handle, 'eval-fails'))
Bram Moolenaara02b3212016-02-04 21:03:33 +0100213 sleep 10m
Bram Moolenaarfa8b2e12016-03-26 22:19:27 +0100214 call assert_equal([-4, 'ERROR'], ch_evalexpr(handle, 'eval-result'))
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100215
Bram Moolenaar55fab432016-02-07 16:53:13 +0100216 " Send an eval request that works but can't be encoded.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100217 call assert_equal('ok', ch_evalexpr(handle, 'eval-error'))
Bram Moolenaar55fab432016-02-07 16:53:13 +0100218 sleep 10m
Bram Moolenaarfa8b2e12016-03-26 22:19:27 +0100219 call assert_equal([-5, 'ERROR'], ch_evalexpr(handle, 'eval-result'))
Bram Moolenaar55fab432016-02-07 16:53:13 +0100220
Bram Moolenaar66624ff2016-02-03 23:59:43 +0100221 " Send a bad eval request. There will be no response.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100222 call assert_equal('ok', ch_evalexpr(handle, 'eval-bad'))
Bram Moolenaara02b3212016-02-04 21:03:33 +0100223 sleep 10m
Bram Moolenaarfa8b2e12016-03-26 22:19:27 +0100224 call assert_equal([-5, 'ERROR'], ch_evalexpr(handle, 'eval-result'))
Bram Moolenaar66624ff2016-02-03 23:59:43 +0100225
Bram Moolenaarf4160862016-02-05 23:09:12 +0100226 " Send an expr request
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100227 call assert_equal('ok', ch_evalexpr(handle, 'an expr'))
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100228 call s:waitFor('"three" == getline("$")')
Bram Moolenaarf4160862016-02-05 23:09:12 +0100229 call assert_equal('one', getline(line('$') - 2))
230 call assert_equal('two', getline(line('$') - 1))
231 call assert_equal('three', getline('$'))
232
233 " Request a redraw, we don't check for the effect.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100234 call assert_equal('ok', ch_evalexpr(handle, 'redraw'))
235 call assert_equal('ok', ch_evalexpr(handle, 'redraw!'))
Bram Moolenaarf4160862016-02-05 23:09:12 +0100236
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100237 call assert_equal('ok', ch_evalexpr(handle, 'empty-request'))
Bram Moolenaarf4160862016-02-05 23:09:12 +0100238
Bram Moolenaar6f3a5442016-02-20 19:56:13 +0100239 " Reading while there is nothing available.
Bram Moolenaar9186a272016-02-23 19:34:01 +0100240 call assert_equal(v:none, ch_read(handle, {'timeout': 0}))
241 let start = reltime()
242 call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
243 let elapsed = reltime(start)
244 call assert_true(reltimefloat(elapsed) > 0.3)
245 call assert_true(reltimefloat(elapsed) < 0.6)
Bram Moolenaar6f3a5442016-02-20 19:56:13 +0100246
247 " Send without waiting for a response, then wait for a response.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100248 call ch_sendexpr(handle, 'wait a bit')
Bram Moolenaar6f3a5442016-02-20 19:56:13 +0100249 let resp = ch_read(handle)
250 call assert_equal(type([]), type(resp))
251 call assert_equal(type(11), type(resp[0]))
252 call assert_equal('waited', resp[1])
253
Bram Moolenaard7ece102016-02-02 23:23:02 +0100254 " make the server quit, can't check if this works, should not hang.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100255 call ch_sendexpr(handle, '!quit!')
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100256endfunc
Bram Moolenaard7ece102016-02-02 23:23:02 +0100257
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100258func Test_communicate()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100259 call ch_log('Test_communicate()')
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100260 call s:run_server('s:communicate')
Bram Moolenaard7ece102016-02-02 23:23:02 +0100261endfunc
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100262
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100263" Test that we can open two channels.
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100264func s:two_channels(port)
Bram Moolenaar39b21272016-02-10 23:28:21 +0100265 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100266 if ch_status(handle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100267 call assert_false(1, "Can't open channel")
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100268 return
269 endif
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100270
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100271 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100272
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100273 let newhandle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100274 if ch_status(newhandle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100275 call assert_false(1, "Can't open second channel")
276 return
277 endif
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100278 call assert_equal('got it', ch_evalexpr(newhandle, 'hello!'))
279 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100280
281 call ch_close(handle)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100282 call assert_equal('got it', ch_evalexpr(newhandle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100283
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100284 call ch_close(newhandle)
285endfunc
286
287func Test_two_channels()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100288 call ch_log('Test_two_channels()')
Bram Moolenaarbfa1ffc2016-02-13 18:40:30 +0100289 call s:run_server('s:two_channels')
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100290endfunc
291
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100292" Test that a server crash is handled gracefully.
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100293func s:server_crash(port)
294 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100295 if ch_status(handle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100296 call assert_false(1, "Can't open channel")
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100297 return
298 endif
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100299
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100300 call ch_evalexpr(handle, '!crash!')
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100301
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100302 sleep 10m
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100303endfunc
304
305func Test_server_crash()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100306 call ch_log('Test_server_crash()')
Bram Moolenaarbfa1ffc2016-02-13 18:40:30 +0100307 call s:run_server('s:server_crash')
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100308endfunc
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100309
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100310"""""""""
311
Bram Moolenaarf6157282016-02-10 21:07:14 +0100312let s:reply = ""
313func s:Handler(chan, msg)
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100314 unlet s:reply
Bram Moolenaarf6157282016-02-10 21:07:14 +0100315 let s:reply = a:msg
316endfunc
317
318func s:channel_handler(port)
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100319 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100320 if ch_status(handle) == "fail"
Bram Moolenaarf6157282016-02-10 21:07:14 +0100321 call assert_false(1, "Can't open channel")
322 return
323 endif
324
325 " Test that it works while waiting on a numbered message.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100326 call assert_equal('ok', ch_evalexpr(handle, 'call me'))
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100327 call s:waitFor('"we called you" == s:reply')
Bram Moolenaarf6157282016-02-10 21:07:14 +0100328 call assert_equal('we called you', s:reply)
329
330 " Test that it works while not waiting on a numbered message.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100331 call ch_sendexpr(handle, 'call me again')
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100332 call s:waitFor('"we did call you" == s:reply')
Bram Moolenaarf6157282016-02-10 21:07:14 +0100333 call assert_equal('we did call you', s:reply)
334endfunc
335
336func Test_channel_handler()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100337 call ch_log('Test_channel_handler()')
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100338 let s:chopt.callback = 's:Handler'
Bram Moolenaarf6157282016-02-10 21:07:14 +0100339 call s:run_server('s:channel_handler')
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100340 let s:chopt.callback = function('s:Handler')
341 call s:run_server('s:channel_handler')
342 unlet s:chopt.callback
Bram Moolenaarf6157282016-02-10 21:07:14 +0100343endfunc
344
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100345"""""""""
346
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100347let s:ch_reply = ''
348func s:ChHandler(chan, msg)
349 unlet s:ch_reply
350 let s:ch_reply = a:msg
351endfunc
352
353let s:zero_reply = ''
354func s:OneHandler(chan, msg)
355 unlet s:zero_reply
356 let s:zero_reply = a:msg
357endfunc
358
359func s:channel_zero(port)
360 let handle = ch_open('localhost:' . a:port, s:chopt)
361 if ch_status(handle) == "fail"
362 call assert_false(1, "Can't open channel")
363 return
364 endif
365
366 " Check that eval works.
367 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
368
369 " Check that eval works if a zero id message is sent back.
370 let s:ch_reply = ''
371 call assert_equal('sent zero', ch_evalexpr(handle, 'send zero'))
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100372 if s:has_handler
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100373 call s:waitFor('"zero index" == s:ch_reply')
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100374 call assert_equal('zero index', s:ch_reply)
375 else
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100376 sleep 20m
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100377 call assert_equal('', s:ch_reply)
378 endif
379
380 " Check that handler works if a zero id message is sent back.
381 let s:ch_reply = ''
382 let s:zero_reply = ''
383 call ch_sendexpr(handle, 'send zero', {'callback': 's:OneHandler'})
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100384 call s:waitFor('"sent zero" == s:zero_reply')
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100385 if s:has_handler
386 call assert_equal('zero index', s:ch_reply)
387 else
388 call assert_equal('', s:ch_reply)
389 endif
390 call assert_equal('sent zero', s:zero_reply)
391endfunc
392
393func Test_zero_reply()
394 call ch_log('Test_zero_reply()')
395 " Run with channel handler
396 let s:has_handler = 1
397 let s:chopt.callback = 's:ChHandler'
398 call s:run_server('s:channel_zero')
399 unlet s:chopt.callback
400
401 " Run without channel handler
402 let s:has_handler = 0
403 call s:run_server('s:channel_zero')
404endfunc
405
406"""""""""
407
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100408let s:reply1 = ""
409func s:HandleRaw1(chan, msg)
410 unlet s:reply1
411 let s:reply1 = a:msg
412endfunc
413
414let s:reply2 = ""
415func s:HandleRaw2(chan, msg)
416 unlet s:reply2
417 let s:reply2 = a:msg
418endfunc
419
420let s:reply3 = ""
421func s:HandleRaw3(chan, msg)
422 unlet s:reply3
423 let s:reply3 = a:msg
424endfunc
425
426func s:raw_one_time_callback(port)
427 let handle = ch_open('localhost:' . a:port, s:chopt)
428 if ch_status(handle) == "fail"
429 call assert_false(1, "Can't open channel")
430 return
431 endif
432 call ch_setoptions(handle, {'mode': 'raw'})
433
434 " The message are sent raw, we do our own JSON strings here.
435 call ch_sendraw(handle, "[1, \"hello!\"]", {'callback': 's:HandleRaw1'})
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100436 call s:waitFor('s:reply1 != ""')
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100437 call assert_equal("[1, \"got it\"]", s:reply1)
438 call ch_sendraw(handle, "[2, \"echo something\"]", {'callback': 's:HandleRaw2'})
439 call ch_sendraw(handle, "[3, \"wait a bit\"]", {'callback': 's:HandleRaw3'})
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100440 call s:waitFor('s:reply2 != ""')
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100441 call assert_equal("[2, \"something\"]", s:reply2)
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100442 " wait for the 200 msec delayed reply
443 call s:waitFor('s:reply3 != ""')
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100444 call assert_equal("[3, \"waited\"]", s:reply3)
445endfunc
446
447func Test_raw_one_time_callback()
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100448 call ch_log('Test_raw_one_time_callback()')
449 call s:run_server('s:raw_one_time_callback')
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100450endfunc
451
452"""""""""
453
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100454" Test that trying to connect to a non-existing port fails quickly.
455func Test_connect_waittime()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100456 call ch_log('Test_connect_waittime()')
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100457 let start = reltime()
Bram Moolenaara4833262016-02-09 23:33:25 +0100458 let handle = ch_open('localhost:9876', s:chopt)
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100459 if ch_status(handle) != "fail"
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100460 " Oops, port does exists.
461 call ch_close(handle)
462 else
463 let elapsed = reltime(start)
Bram Moolenaar74f5e652016-02-07 21:44:49 +0100464 call assert_true(reltimefloat(elapsed) < 1.0)
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100465 endif
466
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100467 " We intend to use a socket that doesn't exist and wait for half a second
468 " before giving up. If the socket does exist it can fail in various ways.
469 " Check for "Connection reset by peer" to avoid flakyness.
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100470 let start = reltime()
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100471 try
472 let handle = ch_open('localhost:9867', {'waittime': 500})
473 if ch_status(handle) != "fail"
474 " Oops, port does exists.
475 call ch_close(handle)
476 else
Bram Moolenaarac42afd2016-03-12 13:48:49 +0100477 " Failed connection should wait about 500 msec. Can be longer if the
478 " computer is busy with other things.
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100479 let elapsed = reltime(start)
480 call assert_true(reltimefloat(elapsed) > 0.3)
Bram Moolenaarac42afd2016-03-12 13:48:49 +0100481 call assert_true(reltimefloat(elapsed) < 1.5)
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100482 endif
483 catch
484 if v:exception !~ 'Connection reset by peer'
485 call assert_false(1, "Caught exception: " . v:exception)
486 endif
487 endtry
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100488endfunc
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100489
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100490"""""""""
491
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100492func Test_raw_pipe()
493 if !has('job')
494 return
495 endif
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100496 call ch_log('Test_raw_pipe()')
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100497 let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
498 call assert_equal("run", job_status(job))
499 try
Bram Moolenaar151f6562016-03-07 21:19:38 +0100500 " For a change use the job where a channel is expected.
501 call ch_sendraw(job, "echo something\n")
502 let msg = ch_readraw(job)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100503 call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
504
Bram Moolenaar151f6562016-03-07 21:19:38 +0100505 call ch_sendraw(job, "double this\n")
506 let msg = ch_readraw(job)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100507 call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g'))
508
Bram Moolenaar151f6562016-03-07 21:19:38 +0100509 let reply = ch_evalraw(job, "quit\n", {'timeout': 100})
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100510 call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g'))
511 finally
512 call job_stop(job)
513 endtry
Bram Moolenaar8950a562016-03-12 15:22:55 +0100514
515 let s:job = job
516 call s:waitFor('"dead" == job_status(s:job)')
517 let info = job_info(job)
518 call assert_equal("dead", info.status)
519 call assert_equal("term", info.stoponexit)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100520endfunc
521
522func Test_nl_pipe()
Bram Moolenaard8070362016-02-15 21:56:54 +0100523 if !has('job')
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100524 return
525 endif
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100526 call ch_log('Test_nl_pipe()')
Bram Moolenaar1adda342016-03-12 15:39:40 +0100527 let job = job_start([s:python, "test_channel_pipe.py"])
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100528 call assert_equal("run", job_status(job))
529 try
530 let handle = job_getchannel(job)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100531 call ch_sendraw(handle, "echo something\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100532 call assert_equal("something", ch_readraw(handle))
533
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100534 call ch_sendraw(handle, "echoerr wrong\n")
535 call assert_equal("wrong", ch_readraw(handle, {'part': 'err'}))
536
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100537 call ch_sendraw(handle, "double this\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100538 call assert_equal("this", ch_readraw(handle))
539 call assert_equal("AND this", ch_readraw(handle))
540
Bram Moolenaarbbe8d912016-06-05 16:10:57 +0200541 call ch_sendraw(handle, "split this line\n")
542 call assert_equal("this linethis linethis line", ch_readraw(handle))
543
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100544 let reply = ch_evalraw(handle, "quit\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100545 call assert_equal("Goodbye!", reply)
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100546 finally
547 call job_stop(job)
548 endtry
549endfunc
Bram Moolenaar3bece9f2016-02-15 20:39:46 +0100550
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100551func Test_nl_err_to_out_pipe()
552 if !has('job')
553 return
554 endif
Bram Moolenaar5a6ec522016-03-12 15:51:44 +0100555 call ch_logfile('Xlog')
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100556 call ch_log('Test_nl_err_to_out_pipe()')
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100557 let job = job_start(s:python . " test_channel_pipe.py", {'err_io': 'out'})
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100558 call assert_equal("run", job_status(job))
559 try
560 let handle = job_getchannel(job)
561 call ch_sendraw(handle, "echo something\n")
562 call assert_equal("something", ch_readraw(handle))
563
564 call ch_sendraw(handle, "echoerr wrong\n")
565 call assert_equal("wrong", ch_readraw(handle))
566 finally
567 call job_stop(job)
Bram Moolenaar5a6ec522016-03-12 15:51:44 +0100568 call ch_logfile('')
569 let loglines = readfile('Xlog')
570 call assert_true(len(loglines) > 10)
571 let found_test = 0
572 let found_send = 0
573 let found_recv = 0
574 let found_stop = 0
575 for l in loglines
576 if l =~ 'Test_nl_err_to_out_pipe'
577 let found_test = 1
578 endif
579 if l =~ 'SEND on.*echo something'
580 let found_send = 1
581 endif
582 if l =~ 'RECV on.*something'
583 let found_recv = 1
584 endif
585 if l =~ 'Stopping job with'
586 let found_stop = 1
587 endif
588 endfor
589 call assert_equal(1, found_test)
590 call assert_equal(1, found_send)
591 call assert_equal(1, found_recv)
592 call assert_equal(1, found_stop)
593 call delete('Xlog')
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100594 endtry
595endfunc
596
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100597func Test_nl_read_file()
598 if !has('job')
599 return
600 endif
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100601 call ch_log('Test_nl_read_file()')
602 call writefile(['echo something', 'echoerr wrong', 'double this'], 'Xinput')
603 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100604 \ {'in_io': 'file', 'in_name': 'Xinput'})
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100605 call assert_equal("run", job_status(job))
606 try
607 let handle = job_getchannel(job)
608 call assert_equal("something", ch_readraw(handle))
609 call assert_equal("wrong", ch_readraw(handle, {'part': 'err'}))
610 call assert_equal("this", ch_readraw(handle))
611 call assert_equal("AND this", ch_readraw(handle))
612 finally
613 call job_stop(job)
614 call delete('Xinput')
615 endtry
616endfunc
617
Bram Moolenaare98d1212016-03-08 15:37:41 +0100618func Test_nl_write_out_file()
619 if !has('job')
620 return
621 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100622 call ch_log('Test_nl_write_out_file()')
623 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100624 \ {'out_io': 'file', 'out_name': 'Xoutput'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100625 call assert_equal("run", job_status(job))
626 try
627 let handle = job_getchannel(job)
628 call ch_sendraw(handle, "echo line one\n")
629 call ch_sendraw(handle, "echo line two\n")
630 call ch_sendraw(handle, "double this\n")
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100631 call s:waitFor('len(readfile("Xoutput")) > 2')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100632 call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))
633 finally
634 call job_stop(job)
635 call delete('Xoutput')
636 endtry
637endfunc
638
639func Test_nl_write_err_file()
640 if !has('job')
641 return
642 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100643 call ch_log('Test_nl_write_err_file()')
644 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100645 \ {'err_io': 'file', 'err_name': 'Xoutput'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100646 call assert_equal("run", job_status(job))
647 try
648 let handle = job_getchannel(job)
649 call ch_sendraw(handle, "echoerr line one\n")
650 call ch_sendraw(handle, "echoerr line two\n")
651 call ch_sendraw(handle, "doubleerr this\n")
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100652 call s:waitFor('len(readfile("Xoutput")) > 2')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100653 call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))
654 finally
655 call job_stop(job)
656 call delete('Xoutput')
657 endtry
658endfunc
659
660func Test_nl_write_both_file()
661 if !has('job')
662 return
663 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100664 call ch_log('Test_nl_write_both_file()')
665 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100666 \ {'out_io': 'file', 'out_name': 'Xoutput', 'err_io': 'out'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100667 call assert_equal("run", job_status(job))
668 try
669 let handle = job_getchannel(job)
670 call ch_sendraw(handle, "echoerr line one\n")
671 call ch_sendraw(handle, "echo line two\n")
672 call ch_sendraw(handle, "double this\n")
673 call ch_sendraw(handle, "doubleerr that\n")
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100674 call s:waitFor('len(readfile("Xoutput")) > 5')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100675 call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 'AND that'], readfile('Xoutput'))
676 finally
677 call job_stop(job)
678 call delete('Xoutput')
679 endtry
680endfunc
681
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200682func BufCloseCb(ch)
683 let s:bufClosed = 'yes'
684endfunc
685
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200686func Run_test_pipe_to_buffer(use_name, nomod)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100687 if !has('job')
688 return
689 endif
690 call ch_log('Test_pipe_to_buffer()')
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200691 let s:bufClosed = 'no'
692 let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100693 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100694 let options['out_name'] = 'pipe-output'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100695 let firstline = 'Reading from channel output...'
696 else
697 sp pipe-output
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100698 let options['out_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100699 quit
700 let firstline = ''
701 endif
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200702 if a:nomod
703 let options['out_modifiable'] = 0
704 endif
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100705 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100706 call assert_equal("run", job_status(job))
707 try
708 let handle = job_getchannel(job)
709 call ch_sendraw(handle, "echo line one\n")
710 call ch_sendraw(handle, "echo line two\n")
711 call ch_sendraw(handle, "double this\n")
712 call ch_sendraw(handle, "quit\n")
713 sp pipe-output
Bram Moolenaare38a2f72016-06-02 20:07:09 +0200714 call s:waitFor('line("$") >= 6 && s:bufClosed == "yes"')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100715 call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$'))
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200716 if a:nomod
717 call assert_equal(0, &modifiable)
718 else
719 call assert_equal(1, &modifiable)
720 endif
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200721 call assert_equal('yes', s:bufClosed)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100722 bwipe!
723 finally
724 call job_stop(job)
725 endtry
726endfunc
727
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100728func Test_pipe_to_buffer_name()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200729 call Run_test_pipe_to_buffer(1, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100730endfunc
731
732func Test_pipe_to_buffer_nr()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200733 call Run_test_pipe_to_buffer(0, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100734endfunc
735
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200736func Test_pipe_to_buffer_name_nomod()
737 call Run_test_pipe_to_buffer(1, 1)
738endfunc
739
740func Run_test_pipe_err_to_buffer(use_name, nomod)
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100741 if !has('job')
742 return
743 endif
744 call ch_log('Test_pipe_err_to_buffer()')
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100745 let options = {'err_io': 'buffer'}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100746 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100747 let options['err_name'] = 'pipe-err'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100748 let firstline = 'Reading from channel error...'
749 else
750 sp pipe-err
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100751 let options['err_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100752 quit
753 let firstline = ''
754 endif
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200755 if a:nomod
756 let options['err_modifiable'] = 0
757 endif
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100758 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100759 call assert_equal("run", job_status(job))
760 try
761 let handle = job_getchannel(job)
762 call ch_sendraw(handle, "echoerr line one\n")
763 call ch_sendraw(handle, "echoerr line two\n")
764 call ch_sendraw(handle, "doubleerr this\n")
765 call ch_sendraw(handle, "quit\n")
766 sp pipe-err
767 call s:waitFor('line("$") >= 5')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100768 call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this'], getline(1, '$'))
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200769 if a:nomod
770 call assert_equal(0, &modifiable)
771 else
772 call assert_equal(1, &modifiable)
773 endif
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100774 bwipe!
775 finally
776 call job_stop(job)
777 endtry
778endfunc
779
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100780func Test_pipe_err_to_buffer_name()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200781 call Run_test_pipe_err_to_buffer(1, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100782endfunc
783
784func Test_pipe_err_to_buffer_nr()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200785 call Run_test_pipe_err_to_buffer(0, 0)
786endfunc
787
788func Test_pipe_err_to_buffer_name_nomod()
789 call Run_test_pipe_err_to_buffer(1, 1)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100790endfunc
791
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100792func Test_pipe_both_to_buffer()
793 if !has('job')
794 return
795 endif
796 call ch_log('Test_pipe_both_to_buffer()')
797 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100798 \ {'out_io': 'buffer', 'out_name': 'pipe-err', 'err_io': 'out'})
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100799 call assert_equal("run", job_status(job))
800 try
801 let handle = job_getchannel(job)
802 call ch_sendraw(handle, "echo line one\n")
803 call ch_sendraw(handle, "echoerr line two\n")
804 call ch_sendraw(handle, "double this\n")
805 call ch_sendraw(handle, "doubleerr that\n")
806 call ch_sendraw(handle, "quit\n")
807 sp pipe-err
808 call s:waitFor('line("$") >= 7')
809 call assert_equal(['Reading from channel output...', 'line one', 'line two', 'this', 'AND this', 'that', 'AND that', 'Goodbye!'], getline(1, '$'))
810 bwipe!
811 finally
812 call job_stop(job)
813 endtry
814endfunc
815
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100816func Run_test_pipe_from_buffer(use_name)
Bram Moolenaar014069a2016-03-03 22:51:40 +0100817 if !has('job')
818 return
819 endif
Bram Moolenaar014069a2016-03-03 22:51:40 +0100820 call ch_log('Test_pipe_from_buffer()')
821
822 sp pipe-input
823 call setline(1, ['echo one', 'echo two', 'echo three'])
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200824 let options = {'in_io': 'buffer', 'block_write': 1}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100825 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100826 let options['in_name'] = 'pipe-input'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100827 else
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100828 let options['in_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100829 endif
Bram Moolenaar014069a2016-03-03 22:51:40 +0100830
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100831 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar014069a2016-03-03 22:51:40 +0100832 call assert_equal("run", job_status(job))
833 try
834 let handle = job_getchannel(job)
835 call assert_equal('one', ch_read(handle))
836 call assert_equal('two', ch_read(handle))
837 call assert_equal('three', ch_read(handle))
838 bwipe!
839 finally
840 call job_stop(job)
841 endtry
Bram Moolenaar014069a2016-03-03 22:51:40 +0100842endfunc
843
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100844func Test_pipe_from_buffer_name()
845 call Run_test_pipe_from_buffer(1)
846endfunc
847
848func Test_pipe_from_buffer_nr()
849 call Run_test_pipe_from_buffer(0)
850endfunc
851
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100852func Test_pipe_to_nameless_buffer()
853 if !has('job')
854 return
855 endif
856 call ch_log('Test_pipe_to_nameless_buffer()')
857 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100858 \ {'out_io': 'buffer'})
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100859 call assert_equal("run", job_status(job))
860 try
861 let handle = job_getchannel(job)
862 call ch_sendraw(handle, "echo line one\n")
863 call ch_sendraw(handle, "echo line two\n")
864 exe ch_getbufnr(handle, "out") . 'sbuf'
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100865 call s:waitFor('line("$") >= 3')
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100866 call assert_equal(['Reading from channel output...', 'line one', 'line two'], getline(1, '$'))
867 bwipe!
868 finally
869 call job_stop(job)
870 endtry
871endfunc
872
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100873func Test_pipe_to_buffer_json()
874 if !has('job')
875 return
876 endif
877 call ch_log('Test_pipe_to_buffer_json()')
878 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100879 \ {'out_io': 'buffer', 'out_mode': 'json'})
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100880 call assert_equal("run", job_status(job))
881 try
882 let handle = job_getchannel(job)
883 call ch_sendraw(handle, "echo [0, \"hello\"]\n")
884 call ch_sendraw(handle, "echo [-2, 12.34]\n")
885 exe ch_getbufnr(handle, "out") . 'sbuf'
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100886 call s:waitFor('line("$") >= 3')
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100887 call assert_equal(['Reading from channel output...', '[0,"hello"]', '[-2,12.34]'], getline(1, '$'))
888 bwipe!
889 finally
890 call job_stop(job)
891 endtry
892endfunc
893
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100894" Wait a little while for the last line, minus "offset", to equal "line".
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100895func s:wait_for_last_line(line, offset)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100896 for i in range(100)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100897 if getline(line('$') - a:offset) == a:line
898 break
899 endif
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100900 sleep 10m
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100901 endfor
902endfunc
903
904func Test_pipe_io_two_buffers()
905 if !has('job')
906 return
907 endif
908 call ch_log('Test_pipe_io_two_buffers()')
909
910 " Create two buffers, one to read from and one to write to.
911 split pipe-output
912 set buftype=nofile
913 split pipe-input
914 set buftype=nofile
915
916 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100917 \ {'in_io': 'buffer', 'in_name': 'pipe-input', 'in_top': 0,
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200918 \ 'out_io': 'buffer', 'out_name': 'pipe-output',
919 \ 'block_write': 1})
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100920 call assert_equal("run", job_status(job))
921 try
922 exe "normal Gaecho hello\<CR>"
923 exe bufwinnr('pipe-output') . "wincmd w"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100924 call s:wait_for_last_line('hello', 0)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100925 call assert_equal('hello', getline('$'))
926
927 exe bufwinnr('pipe-input') . "wincmd w"
928 exe "normal Gadouble this\<CR>"
929 exe bufwinnr('pipe-output') . "wincmd w"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100930 call s:wait_for_last_line('AND this', 0)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100931 call assert_equal('this', getline(line('$') - 1))
932 call assert_equal('AND this', getline('$'))
933
934 bwipe!
935 exe bufwinnr('pipe-input') . "wincmd w"
936 bwipe!
937 finally
938 call job_stop(job)
939 endtry
940endfunc
941
942func Test_pipe_io_one_buffer()
943 if !has('job')
944 return
945 endif
946 call ch_log('Test_pipe_io_one_buffer()')
947
948 " Create one buffer to read from and to write to.
949 split pipe-io
950 set buftype=nofile
951
952 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100953 \ {'in_io': 'buffer', 'in_name': 'pipe-io', 'in_top': 0,
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200954 \ 'out_io': 'buffer', 'out_name': 'pipe-io',
955 \ 'block_write': 1})
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100956 call assert_equal("run", job_status(job))
957 try
958 exe "normal Goecho hello\<CR>"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100959 call s:wait_for_last_line('hello', 1)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100960 call assert_equal('hello', getline(line('$') - 1))
961
962 exe "normal Gadouble this\<CR>"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100963 call s:wait_for_last_line('AND this', 1)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100964 call assert_equal('this', getline(line('$') - 2))
965 call assert_equal('AND this', getline(line('$') - 1))
966
967 bwipe!
968 finally
969 call job_stop(job)
970 endtry
971endfunc
972
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100973func Test_pipe_null()
974 if !has('job')
975 return
976 endif
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100977 call ch_log('Test_pipe_null()')
978
979 " We cannot check that no I/O works, we only check that the job starts
980 " properly.
981 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100982 \ {'in_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100983 call assert_equal("run", job_status(job))
984 try
985 call assert_equal('something', ch_read(job))
986 finally
987 call job_stop(job)
988 endtry
989
990 let job = job_start(s:python . " test_channel_pipe.py err-out",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100991 \ {'out_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100992 call assert_equal("run", job_status(job))
993 try
994 call assert_equal('err-out', ch_read(job, {"part": "err"}))
995 finally
996 call job_stop(job)
997 endtry
998
999 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +01001000 \ {'err_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +01001001 call assert_equal("run", job_status(job))
1002 try
1003 call assert_equal('something', ch_read(job))
1004 finally
1005 call job_stop(job)
1006 endtry
1007
1008 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +01001009 \ {'out_io': 'null', 'err_io': 'out'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +01001010 call assert_equal("run", job_status(job))
1011 call job_stop(job)
1012
1013 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +01001014 \ {'in_io': 'null', 'out_io': 'null', 'err_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +01001015 call assert_equal("run", job_status(job))
1016 call assert_equal('channel fail', string(job_getchannel(job)))
1017 call assert_equal('fail', ch_status(job))
1018 call job_stop(job)
1019endfunc
1020
Bram Moolenaaradb78a72016-06-27 21:10:31 +02001021func Test_pipe_to_buffer_raw()
1022 if !has('job')
1023 return
1024 endif
1025 call ch_log('Test_raw_pipe_to_buffer()')
1026 let options = {'out_mode': 'raw', 'out_io': 'buffer', 'out_name': 'testout'}
1027 split testout
1028 let job = job_start([s:python, '-c',
1029 \ 'import sys; [sys.stdout.write(".") and sys.stdout.flush() for _ in range(10000)]'], options)
1030 call assert_equal("run", job_status(job))
1031 call s:waitFor('len(join(getline(2,line("$")),"") >= 10000')
1032 try
1033 for line in getline(2, '$')
1034 let line = substitute(line, '^\.*', '', '')
1035 call assert_equal('', line)
1036 endfor
1037 finally
1038 call job_stop(job)
1039 bwipe!
1040 endtry
1041endfunc
1042
Bram Moolenaarde279892016-03-11 22:19:44 +01001043func Test_reuse_channel()
1044 if !has('job')
1045 return
1046 endif
1047 call ch_log('Test_reuse_channel()')
1048
1049 let job = job_start(s:python . " test_channel_pipe.py")
1050 call assert_equal("run", job_status(job))
1051 let handle = job_getchannel(job)
1052 try
1053 call ch_sendraw(handle, "echo something\n")
1054 call assert_equal("something", ch_readraw(handle))
1055 finally
1056 call job_stop(job)
1057 endtry
1058
1059 let job = job_start(s:python . " test_channel_pipe.py", {'channel': handle})
1060 call assert_equal("run", job_status(job))
1061 let handle = job_getchannel(job)
1062 try
1063 call ch_sendraw(handle, "echo again\n")
1064 call assert_equal("again", ch_readraw(handle))
1065 finally
1066 call job_stop(job)
1067 endtry
1068endfunc
1069
Bram Moolenaar75f72652016-03-20 22:16:56 +01001070func Test_out_cb()
1071 if !has('job')
1072 return
1073 endif
1074 call ch_log('Test_out_cb()')
1075
1076 let dict = {'thisis': 'dict: '}
1077 func dict.outHandler(chan, msg) dict
1078 let s:outmsg = self.thisis . a:msg
1079 endfunc
1080 func dict.errHandler(chan, msg) dict
1081 let s:errmsg = self.thisis . a:msg
1082 endfunc
1083 let job = job_start(s:python . " test_channel_pipe.py",
1084 \ {'out_cb': dict.outHandler,
1085 \ 'out_mode': 'json',
1086 \ 'err_cb': dict.errHandler,
1087 \ 'err_mode': 'json'})
1088 call assert_equal("run", job_status(job))
1089 try
1090 let s:outmsg = ''
1091 let s:errmsg = ''
1092 call ch_sendraw(job, "echo [0, \"hello\"]\n")
1093 call ch_sendraw(job, "echoerr [0, \"there\"]\n")
1094 call s:waitFor('s:outmsg != ""')
1095 call assert_equal("dict: hello", s:outmsg)
1096 call s:waitFor('s:errmsg != ""')
1097 call assert_equal("dict: there", s:errmsg)
1098 finally
1099 call job_stop(job)
1100 endtry
1101endfunc
1102
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001103func Test_out_close_cb()
1104 if !has('job')
1105 return
1106 endif
1107 call ch_log('Test_out_close_cb()')
1108
1109 let s:counter = 1
Bram Moolenaard75263c2016-04-30 16:07:23 +02001110 let s:msg1 = ''
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001111 let s:closemsg = 0
1112 func! OutHandler(chan, msg)
Bram Moolenaard75263c2016-04-30 16:07:23 +02001113 if s:counter == 1
1114 let s:msg1 = a:msg
Bram Moolenaard75263c2016-04-30 16:07:23 +02001115 endif
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001116 let s:counter += 1
1117 endfunc
1118 func! CloseHandler(chan)
1119 let s:closemsg = s:counter
1120 let s:counter += 1
1121 endfunc
1122 let job = job_start(s:python . " test_channel_pipe.py quit now",
1123 \ {'out_cb': 'OutHandler',
1124 \ 'close_cb': 'CloseHandler'})
1125 call assert_equal("run", job_status(job))
1126 try
Bram Moolenaar715d2852016-04-30 17:06:31 +02001127 call s:waitFor('s:closemsg != 0 && s:msg1 != ""')
Bram Moolenaard75263c2016-04-30 16:07:23 +02001128 call assert_equal('quit', s:msg1)
Bram Moolenaar715d2852016-04-30 17:06:31 +02001129 call assert_equal(2, s:closemsg)
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001130 finally
1131 call job_stop(job)
1132 delfunc OutHandler
1133 delfunc CloseHandler
1134 endtry
1135endfunc
1136
Bram Moolenaar437905c2016-04-26 19:01:05 +02001137func Test_read_in_close_cb()
1138 if !has('job')
1139 return
1140 endif
1141 call ch_log('Test_read_in_close_cb()')
1142
1143 let s:received = ''
1144 func! CloseHandler(chan)
1145 let s:received = ch_read(a:chan)
1146 endfunc
1147 let job = job_start(s:python . " test_channel_pipe.py quit now",
1148 \ {'close_cb': 'CloseHandler'})
1149 call assert_equal("run", job_status(job))
1150 try
1151 call s:waitFor('s:received != ""')
1152 call assert_equal('quit', s:received)
1153 finally
1154 call job_stop(job)
1155 delfunc CloseHandler
1156 endtry
1157endfunc
1158
Bram Moolenaard46ae142016-02-16 13:33:52 +01001159""""""""""
1160
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001161let s:unletResponse = ''
1162func s:UnletHandler(handle, msg)
1163 let s:unletResponse = a:msg
1164 unlet s:channelfd
1165endfunc
1166
1167" Test that "unlet handle" in a handler doesn't crash Vim.
1168func s:unlet_handle(port)
1169 let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar910b8aa2016-02-16 21:03:07 +01001170 call ch_sendexpr(s:channelfd, "test", {'callback': function('s:UnletHandler')})
Bram Moolenaar9fe885e2016-03-08 16:06:55 +01001171 call s:waitFor('"what?" == s:unletResponse')
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001172 call assert_equal('what?', s:unletResponse)
1173endfunc
1174
1175func Test_unlet_handle()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001176 call ch_log('Test_unlet_handle()')
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001177 call s:run_server('s:unlet_handle')
1178endfunc
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001179
Bram Moolenaard46ae142016-02-16 13:33:52 +01001180""""""""""
1181
1182let s:unletResponse = ''
1183func s:CloseHandler(handle, msg)
1184 let s:unletResponse = a:msg
1185 call ch_close(s:channelfd)
1186endfunc
1187
1188" Test that "unlet handle" in a handler doesn't crash Vim.
1189func s:close_handle(port)
1190 let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar910b8aa2016-02-16 21:03:07 +01001191 call ch_sendexpr(s:channelfd, "test", {'callback': function('s:CloseHandler')})
Bram Moolenaar9fe885e2016-03-08 16:06:55 +01001192 call s:waitFor('"what?" == s:unletResponse')
Bram Moolenaard46ae142016-02-16 13:33:52 +01001193 call assert_equal('what?', s:unletResponse)
1194endfunc
1195
1196func Test_close_handle()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001197 call ch_log('Test_close_handle()')
Bram Moolenaard46ae142016-02-16 13:33:52 +01001198 call s:run_server('s:close_handle')
1199endfunc
1200
1201""""""""""
1202
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001203func Test_open_fail()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001204 call ch_log('Test_open_fail()')
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001205 silent! let ch = ch_open("noserver")
1206 echo ch
1207 let d = ch
1208endfunc
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001209
1210""""""""""
1211
1212func s:open_delay(port)
1213 " Wait up to a second for the port to open.
1214 let s:chopt.waittime = 1000
1215 let channel = ch_open('localhost:' . a:port, s:chopt)
1216 unlet s:chopt.waittime
1217 if ch_status(channel) == "fail"
1218 call assert_false(1, "Can't open channel")
1219 return
1220 endif
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001221 call assert_equal('got it', ch_evalexpr(channel, 'hello!'))
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001222 call ch_close(channel)
1223endfunc
1224
1225func Test_open_delay()
1226 call ch_log('Test_open_delay()')
1227 " The server will wait half a second before creating the port.
1228 call s:run_server('s:open_delay', 'delay')
1229endfunc
Bram Moolenaarece61b02016-02-20 21:39:05 +01001230
1231"""""""""
1232
1233function MyFunction(a,b,c)
1234 let s:call_ret = [a:a, a:b, a:c]
1235endfunc
1236
1237function s:test_call(port)
1238 let handle = ch_open('localhost:' . a:port, s:chopt)
1239 if ch_status(handle) == "fail"
1240 call assert_false(1, "Can't open channel")
1241 return
1242 endif
1243
Bram Moolenaar9fe885e2016-03-08 16:06:55 +01001244 let s:call_ret = []
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001245 call assert_equal('ok', ch_evalexpr(handle, 'call-func'))
Bram Moolenaar9fe885e2016-03-08 16:06:55 +01001246 call s:waitFor('len(s:call_ret) > 0')
Bram Moolenaarece61b02016-02-20 21:39:05 +01001247 call assert_equal([1, 2, 3], s:call_ret)
1248endfunc
1249
1250func Test_call()
1251 call ch_log('Test_call()')
1252 call s:run_server('s:test_call')
1253endfunc
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001254
1255"""""""""
1256
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001257let s:job_exit_ret = 'not yet'
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001258function MyExitCb(job, status)
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001259 let s:job_exit_ret = 'done'
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001260endfunc
1261
1262function s:test_exit_callback(port)
Bram Moolenaard6c2f052016-03-14 23:22:59 +01001263 call job_setoptions(s:job, {'exit_cb': 'MyExitCb'})
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001264 let s:exit_job = s:job
Bram Moolenaard6c2f052016-03-14 23:22:59 +01001265 call assert_equal('MyExitCb', job_info(s:job)['exit_cb'])
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001266endfunc
1267
1268func Test_exit_callback()
1269 if has('job')
Bram Moolenaar9730f742016-02-28 19:50:51 +01001270 call ch_log('Test_exit_callback()')
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001271 call s:run_server('s:test_exit_callback')
1272
Bram Moolenaar9730f742016-02-28 19:50:51 +01001273 " wait up to a second for the job to exit
1274 for i in range(100)
1275 if s:job_exit_ret == 'done'
1276 break
1277 endif
1278 sleep 10m
1279 " calling job_status() triggers the callback
1280 call job_status(s:exit_job)
1281 endfor
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001282
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001283 call assert_equal('done', s:job_exit_ret)
Bram Moolenaar8950a562016-03-12 15:22:55 +01001284 call assert_equal('dead', job_info(s:exit_job).status)
Bram Moolenaar9730f742016-02-28 19:50:51 +01001285 unlet s:exit_job
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001286 endif
1287endfunc
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001288
1289"""""""""
1290
1291let s:ch_close_ret = 'alive'
1292function MyCloseCb(ch)
1293 let s:ch_close_ret = 'closed'
1294endfunc
1295
1296function s:test_close_callback(port)
1297 let handle = ch_open('localhost:' . a:port, s:chopt)
1298 if ch_status(handle) == "fail"
1299 call assert_false(1, "Can't open channel")
1300 return
1301 endif
Bram Moolenaard6c2f052016-03-14 23:22:59 +01001302 call ch_setoptions(handle, {'close_cb': 'MyCloseCb'})
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001303
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001304 call assert_equal('', ch_evalexpr(handle, 'close me'))
Bram Moolenaar9fe885e2016-03-08 16:06:55 +01001305 call s:waitFor('"closed" == s:ch_close_ret')
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001306 call assert_equal('closed', s:ch_close_ret)
1307endfunc
1308
1309func Test_close_callback()
1310 call ch_log('Test_close_callback()')
1311 call s:run_server('s:test_close_callback')
1312endfunc
1313
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001314function s:test_close_partial(port)
1315 let handle = ch_open('localhost:' . a:port, s:chopt)
1316 if ch_status(handle) == "fail"
1317 call assert_false(1, "Can't open channel")
1318 return
1319 endif
1320 let s:d = {}
1321 func s:d.closeCb(ch) dict
1322 let self.close_ret = 'closed'
1323 endfunc
1324 call ch_setoptions(handle, {'close_cb': s:d.closeCb})
1325
1326 call assert_equal('', ch_evalexpr(handle, 'close me'))
1327 call s:waitFor('"closed" == s:d.close_ret')
1328 call assert_equal('closed', s:d.close_ret)
1329 unlet s:d
1330endfunc
1331
1332func Test_close_partial()
1333 call ch_log('Test_close_partial()')
1334 call s:run_server('s:test_close_partial')
1335endfunc
1336
Bram Moolenaar80385682016-03-27 19:13:35 +02001337func Test_job_start_invalid()
1338 call assert_fails('call job_start($x)', 'E474:')
1339 call assert_fails('call job_start("")', 'E474:')
1340endfunc
1341
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001342" This was leaking memory.
Bram Moolenaar0e4c1de2016-04-07 21:40:38 +02001343func Test_partial_in_channel_cycle()
1344 let d = {}
1345 let d.a = function('string', [d])
1346 try
1347 let d.b = ch_open('nowhere:123', {'close_cb': d.a})
1348 catch
1349 call assert_exception('E901:')
1350 endtry
1351 unlet d
1352endfunc
1353
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001354func Test_using_freed_memory()
1355 let g:a = job_start(['ls'])
1356 sleep 10m
Bram Moolenaar574860b2016-05-24 17:33:34 +02001357 call test_garbagecollect_now()
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001358endfunc
1359
Bram Moolenaarb8aefa42016-06-10 23:02:56 +02001360func Test_collapse_buffers()
1361 if !executable('cat')
1362 return
1363 endif
1364 sp test_channel.vim
1365 let g:linecount = line('$')
1366 close
1367 split testout
1368 1,$delete
1369 call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'})
1370 call s:waitFor('line("$") > g:linecount')
1371 call assert_true(line('$') > g:linecount)
1372 bwipe!
1373endfunc
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001374
1375
Bram Moolenaar9730f742016-02-28 19:50:51 +01001376" Uncomment this to see what happens, output is in src/testdir/channellog.
1377" call ch_logfile('channellog', 'w')