1" Functions shared by several tests. 2 3" Get the name of the Python executable. 4" Also keeps it in s:python. 5func PythonProg() 6 " This test requires the Python command to run the test server. 7 " This most likely only works on Unix and Windows. 8 if has('unix') 9 " We also need the job feature or the pkill command to make sure the server 10 " can be stopped. 11 if !(executable('python') && (has('job') || executable('pkill'))) 12 return '' 13 endif 14 let s:python = 'python' 15 elseif has('win32') 16 " Use Python Launcher for Windows (py.exe) if available. 17 if executable('py.exe') 18 let s:python = 'py.exe' 19 elseif executable('python.exe') 20 let s:python = 'python.exe' 21 else 22 return '' 23 endif 24 else 25 return '' 26 endif 27 return s:python 28endfunc 29 30" Run "cmd". Returns the job if using a job. 31func RunCommand(cmd) 32 let job = 0 33 if has('job') 34 let job = job_start(a:cmd, {"stoponexit": "hup"}) 35 call job_setoptions(job, {"stoponexit": "kill"}) 36 elseif has('win32') 37 exe 'silent !start cmd /c start "test_channel" ' . a:cmd 38 else 39 exe 'silent !' . a:cmd . '&' 40 endif 41 return job 42endfunc 43 44" Read the port number from the Xportnr file. 45func GetPort() 46 let l = [] 47 for i in range(200) 48 try 49 let l = readfile("Xportnr") 50 catch 51 endtry 52 if len(l) >= 1 53 break 54 endif 55 sleep 10m 56 endfor 57 call delete("Xportnr") 58 59 if len(l) == 0 60 " Can't make the connection, give up. 61 return 0 62 endif 63 return l[0] 64endfunc 65 66" Run a Python server for "cmd" and call "testfunc". 67" Always kills the server before returning. 68func RunServer(cmd, testfunc, args) 69 " The Python program writes the port number in Xportnr. 70 call delete("Xportnr") 71 72 if len(a:args) == 1 73 let arg = ' ' . a:args[0] 74 else 75 let arg = '' 76 endif 77 let pycmd = s:python . " " . a:cmd . arg 78 79 try 80 let g:currentJob = RunCommand(pycmd) 81 82 " Wait for up to 2 seconds for the port number to be there. 83 let port = GetPort() 84 if port == 0 85 call assert_false(1, "Can't start " . a:cmd) 86 return 87 endif 88 89 call call(function(a:testfunc), [port]) 90 catch 91 call assert_false(1, "Caught exception: " . v:exception) 92 finally 93 call s:kill_server(a:cmd) 94 endtry 95endfunc 96 97func s:kill_server(cmd) 98 if has('job') 99 if exists('g:currentJob') 100 call job_stop(g:currentJob) 101 unlet g:currentJob 102 endif 103 elseif has('win32') 104 let cmd = substitute(a:cmd, ".py", '', '') 105 call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . cmd . '"') 106 else 107 call system("pkill -f " . a:cmd) 108 endif 109endfunc 110 111" Wait for up to a second for "expr" to become true. 112func WaitFor(expr) 113 for i in range(100) 114 try 115 if eval(a:expr) 116 return 117 endif 118 catch 119 endtry 120 sleep 10m 121 endfor 122endfunc 123