Skip to content

Commit 7003a5d

Browse files
zzzyxwvutchrisbra
authored andcommitted
runtime(syntax-tests): Apply stronger synchronisation between buffers
The current lightweight synchronisation with ":redraw" needs further reinforcement in the light of v9.1.1110. And, with v9.1.0820, make another synchronisation point _before_ the first (or only) screenful is dumped. Also add a script to regenerate all screendumps. closes: #16632 Signed-off-by: Aliaksei Budavei <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent ff15925 commit 7003a5d

4 files changed

Lines changed: 292 additions & 39 deletions

File tree

Filelist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ RT_SCRIPTS = \
878878
runtime/syntax/testdir/input/setup/*.* \
879879
runtime/syntax/testdir/dumps/*.dump \
880880
runtime/syntax/testdir/dumps/*.vim \
881+
runtime/syntax/testdir/tools/* \
881882
runtime/syntax/generator/Makefile \
882883
runtime/syntax/generator/README.md \
883884
runtime/syntax/generator/gen_syntax_vim.vim \

runtime/syntax/Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# To run the test manually:
44
# ../../src/vim -u 'testdir/runtest.vim' --cmd 'breakadd func RunTest'
55

6-
# Override this if needed, the default assumes Vim was build in the src dir.
6+
# Override this if needed, the default assumes Vim was built in the src dir.
77
#VIMPROG = vim
88
VIMPROG = ../../src/vim
99

@@ -13,6 +13,10 @@ VIMRUNTIME = ../..
1313
# Uncomment this line to use valgrind for memory leaks and extra warnings.
1414
# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=45 --log-file=valgrind.$*
1515

16+
# Trace ruler liveness on demand.
17+
# VIM_SYNTAX_TEST_LOG = `pwd`/testdir/failed/00-TRACE_LOG
18+
19+
# ENVVARS = LC_ALL=C VIM_SYNTAX_TEST_LOG="$(VIM_SYNTAX_TEST_LOG)"
1620
# ENVVARS = LC_ALL=C LANG=C LANGUAGE=C
1721
# Run the syntax tests with a C locale
1822
ENVVARS = LC_ALL=C
@@ -31,6 +35,9 @@ test:
3135
@# the "vimcmd" file is used by the screendump utils
3236
@echo "../$(VIMPROG)" > testdir/vimcmd
3337
@echo "$(RUN_VIMTEST)" >> testdir/vimcmd
38+
@# Trace ruler liveness on demand.
39+
@#mkdir -p testdir/failed
40+
@#touch "$(VIM_SYNTAX_TEST_LOG)"
3441
VIMRUNTIME=$(VIMRUNTIME) $(ENVVARS) $(VIMPROG) --clean --not-a-term $(DEBUGLOG) -u testdir/runtest.vim > /dev/null
3542
@rm -f testdir/Xfilter
3643
@# FIXME: Temporarily show the whole file to find out what goes wrong

runtime/syntax/testdir/runtest.vim

Lines changed: 157 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ let s:messagesFname = fnameescape(syntaxDir .. '/testdir/messages')
1515

1616
let s:messages = []
1717

18+
" Erase the cursor line and do not advance the cursor.
19+
def EraseLineAndReturnCarriage(rname: string)
20+
const full_width: number = winwidth(0)
21+
const half_width: number = full_width - (full_width + 1) / 2
22+
if (strlen(rname) + strlen('Test' .. "\x20\x20" .. 'FAILED')) > half_width
23+
echon "\r" .. repeat("\x20", full_width) .. "\r"
24+
else
25+
echon repeat("\x20", half_width) .. "\r"
26+
endif
27+
enddef
28+
1829
" Add one message to the list of messages
1930
func Message(msg)
2031
echomsg a:msg
@@ -30,22 +41,23 @@ endfunc
3041

3142
" Append s:messages to the messages file and make it empty.
3243
func AppendMessages(header)
33-
exe 'split ' .. s:messagesFname
44+
silent exe 'split ' .. s:messagesFname
3445
call append(line('$'), '')
3546
call append(line('$'), a:header)
3647
call append(line('$'), s:messages)
3748
let s:messages = []
38-
wq
49+
silent wq
3950
endfunc
4051

4152
" Relevant messages are written to the "messages" file.
4253
" If the file already exists it is appended to.
43-
exe 'split ' .. s:messagesFname
54+
silent exe 'split ' .. s:messagesFname
4455
call append(line('$'), repeat('=-', 70))
4556
call append(line('$'), '')
4657
let s:test_run_message = 'Test run on ' .. strftime("%Y %b %d %H:%M:%S")
4758
call append(line('$'), s:test_run_message)
48-
wq
59+
silent wq
60+
echo "\n"
4961

5062
if syntaxDir !~ '[/\\]runtime[/\\]syntax\>'
5163
call Fatal('Current directory must be "runtime/syntax"')
@@ -88,26 +100,127 @@ func HandleSwapExists()
88100
endif
89101
endfunc
90102

91-
def IsWinNumOneAtEOF(in_name_and_out_name: string): bool
92-
# Expect defaults from term_util#RunVimInTerminal().
103+
" Trace ruler liveness on demand.
104+
if !empty($VIM_SYNTAX_TEST_LOG) && filewritable($VIM_SYNTAX_TEST_LOG)
105+
def s:TraceRulerLiveness(context: string, times: number, tail: string)
106+
writefile([printf('%s: %4d: %s', context, times, tail)],
107+
$VIM_SYNTAX_TEST_LOG,
108+
'a')
109+
enddef
110+
else
111+
def s:TraceRulerLiveness(_: string, _: number, _: string)
112+
enddef
113+
endif
114+
115+
" See ":help 'ruler'".
116+
def s:CannotSeeLastLine(ruler: list<string>): bool
117+
return !(get(ruler, -1, '') ==# 'All' || get(ruler, -1, '') ==# 'Bot')
118+
enddef
119+
120+
def s:CannotDumpNextPage(buf: number, prev_ruler: list<string>, ruler: list<string>): bool
121+
return !(ruler !=# prev_ruler &&
122+
len(ruler) == 2 &&
123+
ruler[1] =~# '\%(\d%\|\<Bot\)$' &&
124+
get(term_getcursor(buf), 0) != 20)
125+
enddef
126+
127+
def s:CannotDumpFirstPage(buf: number, _: list<string>, ruler: list<string>): bool
128+
return !(len(ruler) == 2 &&
129+
ruler[1] =~# '\%(\<All\|\<Top\)$' &&
130+
get(term_getcursor(buf), 0) != 20)
131+
enddef
132+
133+
def s:CannotDumpShellFirstPage(buf: number, _: list<string>, ruler: list<string>): bool
134+
return !(len(ruler) > 3 &&
135+
get(ruler, -1, '') =~# '\%(\<All\|\<Top\)$' &&
136+
get(term_getcursor(buf), 0) != 20)
137+
enddef
138+
139+
" Poll for updates of the cursor position in the terminal buffer occupying the
140+
" first window. (ALWAYS call the function or its equivalent before calling
141+
" "VerifyScreenDump()" *and* after calling any number of "term_sendkeys()".)
142+
def s:TermPollRuler(
143+
CannotDumpPage: func, # (TYPE FOR LEGACY CONTEXT CALL SITES.)
144+
buf: number,
145+
in_name_and_out_name: string): list<string>
146+
# Expect defaults from "term_util#RunVimInTerminal()".
93147
if winwidth(1) != 75 || winheight(1) != 20
94148
ch_log(printf('Aborting for %s: (75 x 20) != (%d x %d)',
95149
in_name_and_out_name,
96150
winwidth(1),
97151
winheight(1)))
98-
return true
152+
return ['0,0-1', 'All']
99153
endif
100-
# A two-fold role: (1) redraw whenever the first test file is of 19 lines or
101-
# less long (not applicable to c.c); (2) redraw in case the terminal buffer
102-
# cannot redraw itself just yet (else expect extra files generated).
154+
# A two-fold role for redrawing:
155+
# (*) in case the terminal buffer cannot redraw itself just yet;
156+
# (*) to avoid extra "real estate" checks.
103157
redraw
104-
const pos: string = join([
105-
screenstring(20, 71),
106-
screenstring(20, 72),
107-
screenstring(20, 73),
108-
screenstring(20, 74),
109-
screenstring(20, 75)], '')
110-
return (pos == ' All ' || pos == ' Bot ')
158+
# The contents of "ruler".
159+
var ruler: list<string> = []
160+
# Attempts at most, targeting ASan-instrumented Vim builds.
161+
var times: number = 2048
162+
# Check "real estate" of the terminal buffer. Read and compare its ruler
163+
# line and let "Xtestscript#s:AssertCursorForwardProgress()" do the rest.
164+
# Note that the cursor ought to be advanced after each successive call of
165+
# this function yet its relative position need not be changed (e.g. "0%").
166+
while CannotDumpPage(ruler) && times > 0
167+
ruler = split(term_getline(buf, 20))
168+
sleep 1m
169+
times -= 1
170+
if times % 8 == 0
171+
redraw
172+
endif
173+
endwhile
174+
TraceRulerLiveness('P', (2048 - times), in_name_and_out_name)
175+
return ruler
176+
enddef
177+
178+
" Prevent "s:TermPollRuler()" from prematurely reading the cursor position,
179+
" which is available at ":edit", after outracing the loading of syntax etc. in
180+
" the terminal buffer. (Call the function before calling "VerifyScreenDump()"
181+
" for the first time.)
182+
def s:TermWaitAndPollRuler(buf: number, in_name_and_out_name: string): list<string>
183+
# Expect defaults from "term_util#RunVimInTerminal()".
184+
if winwidth(1) != 75 || winheight(1) != 20
185+
ch_log(printf('Aborting for %s: (75 x 20) != (%d x %d)',
186+
in_name_and_out_name,
187+
winwidth(1),
188+
winheight(1)))
189+
return ['0,0-1', 'All']
190+
endif
191+
# The contents of "ruler".
192+
var ruler: string = ''
193+
# Attempts at most, targeting ASan-instrumented Vim builds.
194+
var times: number = 32768
195+
# Check "real estate" of the terminal buffer. Expect a known token to be
196+
# rendered in the terminal buffer; its prefix must be "is_" so that buffer
197+
# variables from "sh.vim" can be matched (see "Xtestscript#ShellInfo()").
198+
# Verify that the whole line is available!
199+
while ruler !~# '^is_.\+\s\%(All\|Top\)$' && times > 0
200+
ruler = term_getline(buf, 20)
201+
sleep 1m
202+
times -= 1
203+
if times % 16 == 0
204+
redraw
205+
endif
206+
endwhile
207+
TraceRulerLiveness('W', (32768 - times), in_name_and_out_name)
208+
if strpart(ruler, 0, 8) !=# 'is_nonce'
209+
# Retain any of "b:is_(bash|dash|kornshell|posix|sh)" entries and let
210+
# "CannotDumpShellFirstPage()" win the cursor race.
211+
return TermPollRuler(
212+
function(CannotDumpShellFirstPage, [buf, []]),
213+
buf,
214+
in_name_and_out_name)
215+
else
216+
# Clear the "is_nonce" token and let "CannotDumpFirstPage()" win any
217+
# race.
218+
term_sendkeys(buf, ":redraw!\<CR>")
219+
endif
220+
return TermPollRuler(
221+
function(CannotDumpFirstPage, [buf, []]),
222+
buf,
223+
in_name_and_out_name)
111224
enddef
112225

113226
func RunTest()
@@ -337,41 +450,44 @@ func RunTest()
337450
" load filetype specific settings
338451
call term_sendkeys(buf, ":call LoadFiletype('" .. filetype .. "')\<CR>")
339452

453+
" Make a synchronisation point between buffers by requesting to echo
454+
" a known token in the terminal buffer and asserting its availability
455+
" with "s:TermWaitAndPollRuler()".
340456
if filetype == 'sh'
341457
call term_sendkeys(buf, ":call ShellInfo()\<CR>")
458+
else
459+
call term_sendkeys(buf, ":echo 'is_nonce'\<CR>")
342460
endif
343461

344-
" Screendump at the start of the file: failed/root_00.dump
345462
let root_00 = root .. '_00'
346463
let in_name_and_out_name = fname .. ': failed/' .. root_00 .. '.dump'
464+
" Queue up all "term_sendkeys()"es and let them finish before returning
465+
" from "s:TermWaitAndPollRuler()".
466+
let ruler = s:TermWaitAndPollRuler(buf, in_name_and_out_name)
347467
call ch_log('First screendump for ' .. in_name_and_out_name)
468+
" Make a screendump at the start of the file: failed/root_00.dump
348469
let fail = VerifyScreenDump(buf, root_00, {})
349470

350-
" Make a Screendump every 18 lines of the file: failed/root_NN.dump
351-
let nr = 1
352-
let root_next = printf('%s_%02d', root, nr)
353-
let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump'
354-
355471
" Accommodate the next code block to "buf"'s contingency for self
356472
" wipe-out.
357473
try
358-
if !IsWinNumOneAtEOF(in_name_and_out_name)
359-
call term_sendkeys(buf, ":call ScrollToSecondPage((18 * 75 + 1), 19, 5) | redraw!\<CR>")
360-
call ch_log('Next screendump for ' .. in_name_and_out_name)
361-
let fail += VerifyScreenDump(buf, root_next, {})
474+
let nr = 0
475+
let keys_a = ":call ScrollToSecondPage((18 * 75 + 1), 19, 5) | redraw!\<CR>"
476+
let keys_b = ":call ScrollToNextPage((18 * 75 + 1), 19, 5) | redraw!\<CR>"
477+
while s:CannotSeeLastLine(ruler)
478+
call term_sendkeys(buf, keys_a)
479+
let keys_a = keys_b
362480
let nr += 1
363481
let root_next = printf('%s_%02d', root, nr)
364482
let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump'
365-
366-
while !IsWinNumOneAtEOF(in_name_and_out_name)
367-
call term_sendkeys(buf, ":call ScrollToNextPage((18 * 75 + 1), 19, 5) | redraw!\<CR>")
368-
call ch_log('Next screendump for ' .. in_name_and_out_name)
369-
let fail += VerifyScreenDump(buf, root_next, {})
370-
let nr += 1
371-
let root_next = printf('%s_%02d', root, nr)
372-
let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump'
373-
endwhile
374-
endif
483+
let ruler = s:TermPollRuler(
484+
\ function('s:CannotDumpNextPage', [buf, ruler]),
485+
\ buf,
486+
\ in_name_and_out_name)
487+
call ch_log('Next screendump for ' .. in_name_and_out_name)
488+
" Make a screendump of every 18 lines of the file: failed/root_NN.dump
489+
let fail += VerifyScreenDump(buf, root_next, {})
490+
endwhile
375491
call StopVimInTerminal(buf)
376492
finally
377493
call delete('Xtestscript')
@@ -413,6 +529,8 @@ func RunTest()
413529
let skipped_count += 1
414530
endif
415531

532+
call EraseLineAndReturnCarriage(root)
533+
416534
" Append messages to the file "testdir/messages"
417535
call AppendMessages('Input file ' .. fname .. ':')
418536

@@ -421,6 +539,7 @@ func RunTest()
421539
endif
422540
endfor
423541

542+
call EraseLineAndReturnCarriage('')
424543
call Message(s:test_run_message)
425544
call Message('OK: ' .. ok_count)
426545
call Message('FAILED: ' .. len(failed_tests) .. ': ' .. string(failed_tests))
@@ -446,4 +565,4 @@ endif
446565

447566
qall!
448567

449-
" vim:ts=8
568+
" vim:sw=2:ts=8:noet:

0 commit comments

Comments
 (0)