patch 9.1.1110: Vim tests are slow and flaky
Problem: Vim tests are slow and flaky at the same time due to reliance
on timeouts which are unreliable.
Solution: improve Vim test performance and reduce flakiness
(Yee Cheng Chin)
A lot of Vim tests currently rely on waiting a specific amount of time
before asserting a condition. This is bad because 1) it is slow, as the
timeout is hardcoded, 2) it's unreliable as a resource-starved runner
may overshoot the timeout. Also, there are a lot of builtin sleep
commands in commonly used utilities like VerifyScreenDump and WaitFor()
which leads to a lot of unnecessary idle time.
Fix these issues by doing the following:
1. Make utilities like VerifyScreenDump and WaitFor use the lowest wait
time possible (1 ms). This essentially turns it into a spin wait. On
fast machines, these will finish very quickly. For existing tests
that had an implicit reliance on the old timeouts (e.g.
VerifyScreenDump had a 50ms wait before), fix the tests to wait that
specific amount explicitly.
2. Fix tests that sleep or wait for long amounts of time to instead
explicitly use a callback mechanism to be notified when a child
terminal job has finished. This allows the test to only take as much
time as possible instead of having to hard code an unreliable
timeout.
With these fixes, tests should 1) completely quickly on fast machines,
and 2) on slow machines they will still run to completion albeit slowly.
Note that previoulsy both were not true. The hardcoded timeouts meant
that on fast machines the tests were mostly idling wasting time, whereas
on slow machines, the timeouts often were not generous enough to allow
them to run to completion.
closes: #16615
Signed-off-by: Yee Cheng Chin <ychin.git@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/crash/ex_redraw_crash b/src/testdir/crash/ex_redraw_crash
deleted file mode 100644
index eda294c..0000000
--- a/src/testdir/crash/ex_redraw_crash
+++ /dev/null
Binary files differ
diff --git a/src/testdir/runtest.vim b/src/testdir/runtest.vim
index 429e750..c14f44e 100644
--- a/src/testdir/runtest.vim
+++ b/src/testdir/runtest.vim
@@ -265,6 +265,9 @@
" buffers.
%bwipe!
+ " Clear all children notifications in case there are stale ones left
+ let g:child_notification = 0
+
" The test may change the current directory. Save and restore the
" directory after executing the test.
let save_cwd = getcwd()
diff --git a/src/testdir/screendump.vim b/src/testdir/screendump.vim
index 84b4864..744f2ab 100644
--- a/src/testdir/screendump.vim
+++ b/src/testdir/screendump.vim
@@ -52,14 +52,14 @@
let filter = 'dumps/' . a:filename . '.vim'
let testfile = 'failed/' . a:filename . '.dump'
- let max_loops = get(a:options, 'wait', 1000) / 10
+ let max_loops = get(a:options, 'wait', 1000) / 1
" Starting a terminal to make a screendump is always considered flaky.
let g:test_is_flaky = 1
let g:giveup_same_error = 0
" wait for the pending updates to be handled.
- call TermWait(a:buf)
+ call TermWait(a:buf, 0)
" Redraw to execute the code that updates the screen. Otherwise we get the
" text and attributes only from the internal buffer.
@@ -80,8 +80,8 @@
let i = 0
while 1
- " leave some time for updating the original window
- sleep 50m
+ " leave a bit of time for updating the original window while we spin wait.
+ sleep 1m
call delete(testfile)
call term_dumpwrite(a:buf, testfile, a:options)
diff --git a/src/testdir/shared.vim b/src/testdir/shared.vim
index 8ae6fa0..f459d87 100644
--- a/src/testdir/shared.vim
+++ b/src/testdir/shared.vim
@@ -136,6 +136,34 @@
endif
endfunc
+" Callback function to be invoked by a child terminal job. The parent could
+" then wait for the notification using WaitForChildNotification()
+let g:child_notification = 0
+func Tapi_notify_parent(bufnum, arglist)
+ let g:child_notification = 1
+endfunc
+
+" Generates a command that we can pass to a terminal job that it uses to
+" notify us. Argument 'escape' will specify whether to escape the double
+" quote.
+func TermNotifyParentCmd(escape)
+ call assert_false(has("win32"), 'Windows does not support terminal API right now. Use another method to synchronize timing.')
+ let cmd = '\033]51;["call", "Tapi_notify_parent", []]\007'
+ if a:escape
+ return escape(cmd, '"')
+ endif
+ return cmd
+endfunc
+
+" Wait for a child process to notify us. This allows us to sequence events in
+" conjunction with the child. Currently the only supported notification method
+" is for a terminal job to call Tapi_notify_parent() using terminal API.
+func WaitForChildNotification(...)
+ let timeout = get(a:000, 0, 5000)
+ call WaitFor({-> g:child_notification == 1}, timeout)
+ let g:child_notification = 0
+endfunc
+
" Wait for up to five seconds for "expr" to become true. "expr" can be a
" stringified expression to evaluate, or a funcref without arguments.
" Using a lambda works best. Example:
@@ -162,7 +190,7 @@
" A second argument can be used to specify a different timeout in msec.
"
" Return zero for success, one for failure (like the assert function).
-func WaitForAssert(assert, ...)
+func g:WaitForAssert(assert, ...)
let timeout = get(a:000, 0, 5000)
if s:WaitForCommon(v:null, a:assert, timeout) < 0
return 1
@@ -200,11 +228,11 @@
call remove(v:errors, -1)
endif
- sleep 10m
+ sleep 1m
if exists('*reltimefloat')
let slept = float2nr(reltimefloat(reltime(start)) * 1000)
else
- let slept += 10
+ let slept += 1
endif
endwhile
diff --git a/src/testdir/term_util.vim b/src/testdir/term_util.vim
index 67b21cb..19362aa 100644
--- a/src/testdir/term_util.vim
+++ b/src/testdir/term_util.vim
@@ -157,14 +157,14 @@
call assert_equal("running", term_getstatus(a:buf))
" Wait for all the pending updates to terminal to complete
- call TermWait(a:buf)
+ call TermWait(a:buf, 1)
" CTRL-O : works both in Normal mode and Insert mode to start a command line.
" In Command-line it's inserted, the CTRL-U removes it again.
call term_sendkeys(a:buf, "\<C-O>:\<C-U>qa!\<cr>")
" Wait for all the pending updates to terminal to complete
- call TermWait(a:buf)
+ call TermWait(a:buf, 1)
" Wait for the terminal to end.
call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
diff --git a/src/testdir/test_balloon.vim b/src/testdir/test_balloon.vim
index 80d5831..3db37a7 100644
--- a/src/testdir/test_balloon.vim
+++ b/src/testdir/test_balloon.vim
@@ -36,6 +36,7 @@
call TermWait(buf, 50)
call term_sendkeys(buf, 'll')
call term_sendkeys(buf, ":call Trigger()\<CR>")
+ sleep 150m " Wait for balloon to show up (100ms balloondelay time)
call VerifyScreenDump(buf, 'Test_balloon_eval_term_01', {})
" Make sure the balloon still shows after 'updatetime' passed and CursorHold
diff --git a/src/testdir/test_crash.vim b/src/testdir/test_crash.vim
index c83ddf2..85b1290 100644
--- a/src/testdir/test_crash.vim
+++ b/src/testdir/test_crash.vim
@@ -4,11 +4,15 @@
CheckScreendump
+" Run the command in terminal and wait for it to complete via notification
+func s:RunCommandAndWait(buf, cmd)
+ call term_sendkeys(a:buf, a:cmd .. "; printf '" .. TermNotifyParentCmd(v:false) .. "'\<cr>")
+ call WaitForChildNotification()
+endfunc
+
func Test_crash1()
CheckNotBSD
CheckExecutable dash
- " Test 7 fails on Mac ...
- CheckNotMac
" The following used to crash Vim
let opts = #{cmd: 'sh'}
@@ -19,70 +23,59 @@
let file = 'crash/poc_huaf1'
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 1: [OK]" > X_crash1_result.txt' .. "\<cr>")
- call TermWait(buf, 50)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 1: [OK]" > X_crash1_result.txt')
let file = 'crash/poc_huaf2'
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 2: [OK]" >> X_crash1_result.txt' .. "\<cr>")
- call TermWait(buf, 50)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 2: [OK]" >> X_crash1_result.txt')
let file = 'crash/poc_huaf3'
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 3: [OK]" >> X_crash1_result.txt' .. "\<cr>")
- call TermWait(buf, 100)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 3: [OK]" >> X_crash1_result.txt')
let file = 'crash/bt_quickfix_poc'
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 4: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 4: [OK]" >> X_crash1_result.txt')
" clean up
call delete('Xerr')
- " This test takes a bit longer
- call TermWait(buf, 1000)
let file = 'crash/poc_tagfunc.vim'
let args = printf(cmn_args, vim, file)
" using || because this poc causes vim to exit with exitstatus != 0
- call term_sendkeys(buf, args ..
- \ ' || echo "crash 5: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call s:RunCommandAndWait(buf, args ..
+ \ ' || echo "crash 5: [OK]" >> X_crash1_result.txt')
- call TermWait(buf, 100)
let file = 'crash/bt_quickfix1_poc'
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 6: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 6: [OK]" >> X_crash1_result.txt')
" clean up
call delete('X')
- call TermWait(buf, 3000)
let file = 'crash/vim_regsub_both_poc'
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 7: [OK]" >> X_crash1_result.txt' .. "\<cr>")
- call TermWait(buf, 3000)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 7: [OK]" >> X_crash1_result.txt')
let file = 'crash/vim_msg_trunc_poc'
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' || echo "crash 8: [OK]" >> X_crash1_result.txt' .. "\<cr>")
- call TermWait(buf, 3000)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' || echo "crash 8: [OK]" >> X_crash1_result.txt')
let file = 'crash/crash_scrollbar'
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 9: [OK]" >> X_crash1_result.txt' .. "\<cr>")
- call TermWait(buf, 1000)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 9: [OK]" >> X_crash1_result.txt')
let file = 'crash/editing_arg_idx_POC_1'
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' || echo "crash 10: [OK]" >> X_crash1_result.txt' .. "\<cr>")
- call TermWait(buf, 1000)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' || echo "crash 10: [OK]" >> X_crash1_result.txt')
call delete('Xerr')
call delete('@')
@@ -113,7 +106,6 @@
func Test_crash1_2()
CheckNotBSD
CheckExecutable dash
- let g:test_is_flaky = 1
" The following used to crash Vim
let opts = #{cmd: 'sh'}
@@ -125,37 +117,32 @@
let file = 'crash/poc1'
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 1: [OK]" > '.. result .. "\<cr>")
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 1: [OK]" > '.. result)
let file = 'crash/poc_win_enter_ext'
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 2: [OK]" >> '.. result .. "\<cr>")
- call TermWait(buf, 350)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 2: [OK]" >> '.. result)
let file = 'crash/poc_suggest_trie_walk'
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' && echo "crash 3: [OK]" >> '.. result .. "\<cr>")
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' && echo "crash 3: [OK]" >> '.. result)
let file = 'crash/poc_did_set_langmap'
let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' ; echo "crash 4: [OK]" >> '.. result .. "\<cr>")
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' ; echo "crash 4: [OK]" >> '.. result)
let file = 'crash/reverse_text_overflow'
let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args ..
- \ ' ; echo "crash 5: [OK]" >> '.. result .. "\<cr>")
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args ..
+ \ ' ; echo "crash 5: [OK]" >> '.. result)
" clean up
exe buf .. "bw!"
@@ -181,64 +168,49 @@
let buf = RunVimInTerminal('sh', #{cmd: 'sh'})
let file = 'crash/poc_ex_substitute'
- let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args)
let file = 'crash/poc_uaf_exec_instructions'
- let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args)
let file = 'crash/poc_uaf_check_argument_types'
- let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args)
let file = 'crash/double_free'
- let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 50)
+ call s:RunCommandAndWait(buf, args)
let file = 'crash/dialog_changed_uaf'
- let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args)
let file = 'crash/nullpointer'
- let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 50)
+ call s:RunCommandAndWait(buf, args)
let file = 'crash/heap_overflow3'
let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args)
let file = 'crash/heap_overflow_glob2regpat'
let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 50)
+ call s:RunCommandAndWait(buf, args)
let file = 'crash/nullptr_regexp_nfa'
let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 50)
-
- let file = 'crash/ex_redraw_crash'
- let cmn_args = "%s -u NONE -i NONE -n -m -X -Z -e -s -S %s -c ':qa!'"
- let args = printf(cmn_args, vim, file)
- call term_sendkeys(buf, args)
- call TermWait(buf, 150)
+ call s:RunCommandAndWait(buf, args)
" clean up
exe buf .. "bw!"
diff --git a/src/testdir/test_listlbr_utf8.vim b/src/testdir/test_listlbr_utf8.vim
index 693f201..bd0578e 100644
--- a/src/testdir/test_listlbr_utf8.vim
+++ b/src/testdir/test_listlbr_utf8.vim
@@ -370,6 +370,7 @@
func Test_visual_ends_before_showbreak()
CheckScreendump
+ " Redraw at the end is necessary due to https://github.com/vim/vim/issues/16620
let lines =<< trim END
vim9script
&wrap = true
@@ -377,6 +378,7 @@
&showbreak = '↪ '
['xxxxx ' .. 'y'->repeat(&columns - 6) .. ' zzzz']->setline(1)
normal! wvel
+ redraw
END
call writefile(lines, 'XvisualEndsBeforeShowbreak', 'D')
let buf = RunVimInTerminal('-S XvisualEndsBeforeShowbreak', #{rows: 6})
diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim
index c241937..67bd95f 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -751,15 +751,15 @@
call writefile(code, 'Xfoo', 'D')
let v:statusmsg = ''
- ta func1
+ silent ta func1
call assert_match('E435:', v:statusmsg)
call assert_equal(2, line('.'))
let v:statusmsg = ''
- ta func2
+ silent ta func2
call assert_match('E435:', v:statusmsg)
call assert_equal(4, line('.'))
let v:statusmsg = ''
- ta func3
+ silent ta func3
call assert_match('E435:', v:statusmsg)
call assert_equal(5, line('.'))
call assert_fails('ta func4', 'E434:')
@@ -1625,7 +1625,7 @@
let v:statusmsg = ''
let @/ = ''
- ta y
+ silent ta y
call assert_match('E435:', v:statusmsg)
call assert_equal(2, line('.'))
call assert_match('<y', @/)
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index d3744fa..9dbdfda 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -60,8 +60,8 @@
close
if has("unix")
- terminal ++hidden ++open sleep 1
- sleep 1
+ terminal ++hidden ++open echo
+ call WaitForAssert({-> assert_equal('terminal', &buftype)})
call assert_fails("echo b:done", 'E121:')
endif
diff --git a/src/testdir/test_terminal2.vim b/src/testdir/test_terminal2.vim
index 5c4563c..542f2ec 100644
--- a/src/testdir/test_terminal2.vim
+++ b/src/testdir/test_terminal2.vim
@@ -292,11 +292,6 @@
func Test_termwinscroll_topline2()
" calling the terminal API doesn't work on Windows
CheckNotMSWindows
- let g:test_is_flaky = 1
- let g:print_complete = 0
- func! Tapi_print_complete(bufnum, arglist)
- let g:print_complete = 1
- endfunc
set termwinscroll=50000 mouse=a
set shell=sh
@@ -310,17 +305,15 @@
let num1 = &termwinscroll / 1000 * 999
call writefile(range(num1), 'Xtext', 'D')
call term_sendkeys(buf, "cat Xtext\<CR>")
- call term_sendkeys(buf, 'printf ''\033]51;["call", "Tapi_print_complete", []]\007''' .. "\<cr>")
+ call term_sendkeys(buf, "printf '" .. TermNotifyParentCmd(v:false) .. "'\<cr>")
let rows = term_getsize(buf)[0]
let cnt = 0
- while !g:print_complete && cnt <= 1000
- " max number of runs
+ while !g:child_notification && cnt <= 50000
+ " Spin wait to process the terminal print as quickly as possible. This is
+ " more efficient than calling WaitForChildNotification() as we don't want
+ " to sleep here as the print is I/O-bound.
let cnt += 1
- " sleep a bit, to give the the terminal some time to finish
-
- " It may take a while to finish on a slow system
- " so wait a bit and handle the callback
- call term_wait(buf)
+ call term_wait(buf, 0)
endwhile
call WaitForAssert({-> assert_match(string(num1 - 1), term_getline(buf, rows - 1) .. '\|' .. term_getline(buf, rows - 2))})
call feedkeys("\<C-W>N", 'xt')
@@ -347,8 +340,6 @@
exe buf . 'bwipe!'
set termwinscroll& mouse& sh&
- delfunc Tapi_print_complete
- unlet! g:print_complete
endfunc
" Resizing the terminal window caused an ml_get error.
diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim
index 5865d18..0e5f70b 100644
--- a/src/testdir/test_terminal3.vim
+++ b/src/testdir/test_terminal3.vim
@@ -75,22 +75,30 @@
let lines = [
\ 'call setline(1, range(20))',
+ \ 'func NotifyParent()',
+ \ ' call echoraw("' .. TermNotifyParentCmd(v:true) .. '")',
+ \ 'endfunc',
\ 'func OpenTerm()',
\ ' set noruler',
- \ " call term_start('cat', #{vertical: 1, " .. a:highlight_opt .. "})",
+ \ " call term_start('cat', #{vertical: 1, "
+ \ .. 'exit_cb: {->NotifyParent()}, '
+ \ .. a:highlight_opt .. "})",
+ \ ' call NotifyParent()',
\ ] + a:open_cmds + [
\ 'endfunc',
- \ ] + a:highlight_cmds
+ \ ] + a:highlight_cmds + [
+ \ 'call NotifyParent()',
+ \ ]
call writefile(lines, 'XtermStart', 'D')
let buf = RunVimInTerminal('-S XtermStart', #{rows: 15})
- call TermWait(buf, 100)
+ call WaitForChildNotification()
call term_sendkeys(buf, ":call OpenTerm()\<CR>")
- call TermWait(buf, 50)
+ call WaitForChildNotification()
call term_sendkeys(buf, "hello\<CR>")
call VerifyScreenDump(buf, 'Test_terminal_color_' .. a:group_name, {})
call term_sendkeys(buf, "\<C-D>")
- call TermWait(buf, 50)
+ call WaitForChildNotification()
call StopVimInTerminal(buf)
endfunc
@@ -270,11 +278,11 @@
\ ]
call writefile(lines, 'XtermPopup', 'D')
let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15})
- call TermWait(buf, 200)
+ call TermWait(buf,0)
call term_sendkeys(buf, ":call OpenTerm(0)\<CR>")
- call TermWait(buf, 800)
+ call TermWait(buf,0)
call term_sendkeys(buf, ":\<CR>")
- call TermWait(buf, 500)
+ call TermWait(buf,0)
call term_sendkeys(buf, "\<C-W>:echo getwinvar(g:winid, \"&buftype\") win_gettype(g:winid)\<CR>")
call VerifyScreenDump(buf, 'Test_terminal_popup_1', {})
@@ -282,16 +290,16 @@
call VerifyScreenDump(buf, 'Test_terminal_popup_2', {})
call term_sendkeys(buf, ":call OpenTerm(1)\<CR>")
- call TermWait(buf, 800)
+ call TermWait(buf,0)
call term_sendkeys(buf, ":set hlsearch\<CR>")
- call TermWait(buf, 500)
+ call TermWait(buf,0)
call term_sendkeys(buf, "/edit\<CR>")
call VerifyScreenDump(buf, 'Test_terminal_popup_3', {})
call term_sendkeys(buf, "\<C-W>:call HidePopup()\<CR>")
call VerifyScreenDump(buf, 'Test_terminal_popup_4', {})
call term_sendkeys(buf, "\<CR>")
- call TermWait(buf, 50)
+ call TermWait(buf,0)
call term_sendkeys(buf, "\<C-W>:call ClosePopup()\<CR>")
call VerifyScreenDump(buf, 'Test_terminal_popup_5', {})
@@ -307,9 +315,9 @@
call term_sendkeys(buf, "A")
call VerifyScreenDump(buf, 'Test_terminal_popup_8', {})
- call TermWait(buf, 50)
+ call TermWait(buf,0)
call term_sendkeys(buf, ":q\<CR>")
- call TermWait(buf, 250) " wait for terminal to vanish
+ call WaitForAssert({-> assert_equal(0, match(term_getline(buf, 6), '^5\s*$'))}, 250) " wait for terminal to vanish
call StopVimInTerminal(buf)
endfunc
@@ -353,27 +361,32 @@
let lines = [
\ 'call setline(1, range(20))',
+ \ 'func NotifyParent(...)',
+ \ ' call echoraw("' .. TermNotifyParentCmd(v:true) .. '")',
+ \ 'endfunc',
\ 'func OpenTerm()',
- \ " let s:buf = term_start('cat', #{hidden: 1, "
+ \ " let s:buf = term_start('cat', #{hidden: 1, term_finish: 'close', "
\ .. a:highlight_opt .. "})",
- \ ' let g:winid = popup_create(s:buf, #{border: [], '
- \ .. a:popup_opt .. '})',
- \ ] + a:popup_cmds + [
+ \ ' let g:winid = popup_create(s:buf, #{border: [], '
+ \ .. 'callback: {->NotifyParent()}, '
+ \ .. a:popup_opt .. '})',
+ \ ] + a:popup_cmds + [
+ \ ' call NotifyParent()',
\ 'endfunc',
- \ ] + a:highlight_cmds
+ \ ] + a:highlight_cmds + [
+ \ 'call NotifyParent()',
+ \ ]
call writefile(lines, 'XtermPopup', 'D')
let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15})
- call TermWait(buf, 100)
+ call WaitForChildNotification()
call term_sendkeys(buf, ":set noruler\<CR>")
call term_sendkeys(buf, ":call OpenTerm()\<CR>")
- call TermWait(buf, 50)
+ call WaitForChildNotification()
call term_sendkeys(buf, "hello\<CR>")
call VerifyScreenDump(buf, 'Test_terminal_popup_' .. a:group_name, {})
call term_sendkeys(buf, "\<C-D>")
- call TermWait(buf, 50)
- call term_sendkeys(buf, ":q\<CR>")
- call TermWait(buf, 50) " wait for terminal to vanish
+ call WaitForChildNotification()
call StopVimInTerminal(buf)
endfunc
diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim
index 4bde75f..d2f621c 100644
--- a/src/testdir/test_timers.vim
+++ b/src/testdir/test_timers.vim
@@ -44,11 +44,15 @@
let slept = WaitFor('g:val == 3')
call assert_equal(3, g:val)
if has('reltime')
+ " Timer has an internal 1ms allowance in calculating due time, so it's
+ " possible for each timer to undershoot by 1ms resulting in only 49*3=147
+ " ms elapsed. Additionally we started the timer before we called
+ " WaitFor(), so the reported time could be a couple more ms below 147.
if has('mac')
- " Mac on Travis can be slow.
- call assert_inrange(149, 400, slept)
+ " Mac in CI can be slow.
+ call assert_inrange(145, 400, slept)
else
- call assert_inrange(149, 250, slept)
+ call assert_inrange(145, 250, slept)
endif
else
call assert_inrange(80, 200, slept)
@@ -143,13 +147,13 @@
# Another timer will fire in half a second and close it early after stopping
# all timers.
var pop = popup_create('Popup', {time: 10000})
- var tmr = timer_start(500, (_) => {
+ var tmr = timer_start(100, (_) => {
timer_stopall()
popup_clear()
})
- sleep 1
+ sleep 100m
+ g:WaitForAssert(() => assert_equal([], popup_list()), 1000)
assert_equal([], timer_info(tmr))
- assert_equal([], popup_list())
enddef
func Test_timer_paused()
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index 03335a4..6c2ef59 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1559,10 +1559,12 @@
func Test_visual_hl_with_showbreak()
CheckScreendump
+ " Redraw at the end is necessary due to https://github.com/vim/vim/issues/16620
let lines =<< trim END
setlocal showbreak=+
call setline(1, repeat('a', &columns + 10))
normal g$v4lo
+ redraw
END
call writefile(lines, 'XTest_visual_sbr', 'D')