patch 7.4.1351
Problem:    When the port isn't opened yet when ch_open() is called it may
            fail instead of waiting for the specified time.
Solution:   Loop when select() succeeds but when connect() failed. Also use
            channel logging for jobs.  Add ch_log().
diff --git a/src/testdir/test_channel.py b/src/testdir/test_channel.py
index ce6d5c1..ec231e8c 100644
--- a/src/testdir/test_channel.py
+++ b/src/testdir/test_channel.py
@@ -9,6 +9,7 @@
 import json
 import socket
 import sys
+import time
 import threading
 
 try:
@@ -158,9 +159,25 @@
 class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
     pass
 
+def writePortInFile(port):
+    # Write the port number in Xportnr, so that the test knows it.
+    f = open("Xportnr", "w")
+    f.write("{}".format(port))
+    f.close()
+
 if __name__ == "__main__":
     HOST, PORT = "localhost", 0
 
+    # Wait half a second before opening the port to test waittime in ch_open().
+    # We do want to get the port number, get that first.  We cannot open the
+    # socket, guess a port is free.
+    if len(sys.argv) >= 2 and sys.argv[1] == 'delay':
+        PORT = 13684
+        writePortInFile(PORT)
+
+        print("Wait for it...")
+        time.sleep(0.5)
+
     server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
     ip, port = server.server_address
 
@@ -169,10 +186,7 @@
     server_thread = threading.Thread(target=server.serve_forever)
     server_thread.start()
 
-    # Write the port number in Xportnr, so that the test knows it.
-    f = open("Xportnr", "w")
-    f.write("{}".format(port))
-    f.close()
+    writePortInFile(port)
 
     print("Listening on port {}".format(port))
 
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index 85a257a..f6ec36b 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -31,17 +31,24 @@
 let s:chopt = {}
 
 " Run "testfunc" after sarting the server and stop the server afterwards.
-func s:run_server(testfunc)
+func s:run_server(testfunc, ...)
   " The Python program writes the port number in Xportnr.
   call delete("Xportnr")
 
+  if a:0 == 1
+    let arg = ' ' . a:1
+  else
+    let arg = ''
+  endif
+  let cmd = s:python . " test_channel.py" . arg
+
   try
     if has('job')
-      let s:job = job_start(s:python . " test_channel.py")
+      let s:job = job_start(cmd)
     elseif has('win32')
-      exe 'silent !start cmd /c start "test_channel" ' . s:python . ' test_channel.py'
+      exe 'silent !start cmd /c start "test_channel" ' . cmd
     else
-      exe 'silent !' . s:python . ' test_channel.py&'
+      exe 'silent !' . cmd . '&'
     endif
 
     " Wait for up to 2 seconds for the port number to be there.
@@ -175,6 +182,7 @@
 endfunc
 
 func Test_communicate()
+  call ch_log('Test_communicate()')
   call s:run_server('s:communicate')
 endfunc
 
@@ -203,6 +211,7 @@
 endfunc
 
 func Test_two_channels()
+  call ch_log('Test_two_channels()')
   call s:run_server('s:two_channels')
 endfunc
 
@@ -220,6 +229,7 @@
 endfunc
 
 func Test_server_crash()
+  call ch_log('Test_server_crash()')
   call s:run_server('s:server_crash')
 endfunc
 
@@ -248,6 +258,7 @@
 endfunc
 
 func Test_channel_handler()
+  call ch_log('Test_channel_handler()')
   let s:chopt.callback = 's:Handler'
   call s:run_server('s:channel_handler')
   let s:chopt.callback = function('s:Handler')
@@ -261,9 +272,10 @@
     " TODO: Make this work again for MS-Windows.
     return
   endif
+  call ch_log('Test_connect_waittime()')
   let start = reltime()
   let handle = ch_open('localhost:9876', s:chopt)
-  if ch_status(handle) == "fail"
+  if ch_status(handle) != "fail"
     " Oops, port does exists.
     call ch_close(handle)
   else
@@ -272,7 +284,7 @@
   endif
 
   let start = reltime()
-  let handle = ch_open('localhost:9867', {'waittime': 2000})
+  let handle = ch_open('localhost:9867', {'waittime': 500})
   if ch_status(handle) != "fail"
     " Oops, port does exists.
     call ch_close(handle)
@@ -280,7 +292,7 @@
     " Failed connection doesn't wait the full time on Unix.
     " TODO: why is MS-Windows different?
     let elapsed = reltime(start)
-    call assert_true(reltimefloat(elapsed) < (has('unix') ? 1.0 : 3.0))
+    call assert_true(reltimefloat(elapsed) < 1.0)
   endif
 endfunc
 
@@ -288,6 +300,7 @@
   if !has('job')
     return
   endif
+  call ch_log('Test_raw_pipe()')
   let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
   call assert_equal("run", job_status(job))
   try
@@ -311,6 +324,7 @@
   if !has('job')
     return
   endif
+  call ch_log('Test_nl_pipe()')
   let job = job_start(s:python . " test_channel_pipe.py")
   call assert_equal("run", job_status(job))
   try
@@ -346,6 +360,7 @@
 endfunc
 
 func Test_unlet_handle()
+  call ch_log('Test_unlet_handle()')
   call s:run_server('s:unlet_handle')
 endfunc
 
@@ -366,13 +381,36 @@
 endfunc
 
 func Test_close_handle()
+  call ch_log('Test_close_handle()')
   call s:run_server('s:close_handle')
 endfunc
 
 """"""""""
 
 func Test_open_fail()
+  call ch_log('Test_open_fail()')
   silent! let ch = ch_open("noserver")
   echo ch
   let d = ch
 endfunc
+
+""""""""""
+
+func s:open_delay(port)
+  " Wait up to a second for the port to open.
+  let s:chopt.waittime = 1000
+  let channel = ch_open('localhost:' . a:port, s:chopt)
+  unlet s:chopt.waittime
+  if ch_status(channel) == "fail"
+    call assert_false(1, "Can't open channel")
+    return
+  endif
+  call assert_equal('got it', ch_sendexpr(channel, 'hello!'))
+  call ch_close(channel)
+endfunc
+
+func Test_open_delay()
+  call ch_log('Test_open_delay()')
+  " The server will wait half a second before creating the port.
+  call s:run_server('s:open_delay', 'delay')
+endfunc