" syd-3 syntax highlighting test suite.
"
" Run headless: vim -es -u NONE -N -S vim/test/syd-3.vim
" Or via: make vimcheck
set nocompatible
set nomore
let s:here = expand('<sfile>:p:h')
let s:root = fnamemodify(s:here, ':h:h')
exec 'set runtimepath^=' . fnameescape(s:root . '/vim')
let s:cases = []
function! s:ok(line, ...) abort
call add(s:cases, {'l': a:line, 'e': 0, 'c': (a:0 >= 1 ? a:1 : ''), 'nc': (a:0 >= 2 ? a:2 : '')})
endfunction
function! s:err(line) abort
call add(s:cases, {'l': a:line, 'e': 1, 'c': '', 'nc': ''})
endfunction
let s:B = 'Boolean'
let s:N = 'Number'
let s:S = 'String'
let s:C = 'Constant'
let s:T = 'Type'
let s:P = 'Special'
call s:ok('lock:on', s:B)
call s:ok('lock:drop', s:B)
call s:ok('l')
call s:ok('lock')
call s:ok('stat')
call s:ok('dump')
call s:ok('panic')
call s:ok('ghost')
call s:ok('ipc:@/run/syd.sock', s:S)
call s:ok('ipc:none')
call s:ok('ipc/uid:1000', s:N)
call s:ok('ipc/uid:none', s:T)
call s:ok('ipc/gid:0', s:N)
call s:ok('ipc/max:64', s:N)
call s:ok('ipc/idle:30', s:N)
call s:ok('ipc/idle:5m', s:N)
call s:ok('config/expand:0', s:N)
call s:ok('config/expand:5m', s:N)
call s:ok('log/level:debug', s:T)
call s:ok('log/verbose:3', s:N)
call s:ok('log/rlimit_burst:5', s:N)
call s:ok('log/rlimit_interval:5s', s:N)
call s:ok('log/lock/new_exec_on:1', s:B)
call s:ok('log/lock/same_exec_off:true', s:B)
call s:ok('pty/row:80', s:N)
call s:ok('pty/col:24', s:N)
call s:ok('pty/col:none', s:T)
call s:ok('mem/max:1G', s:N)
call s:ok('mem/vm_max:512M', s:N)
call s:ok('pid/max:100', s:N)
call s:ok('mem/kill:1', s:B)
call s:ok('pid/kill:0', s:B)
call s:ok('rlimit/nofile:1024')
call s:ok('rlimit/as:1G')
call s:ok('rlimit/nice:10')
call s:ok('rlimit/cpu:30')
call s:ok('segvguard/expiry:5m', s:N)
call s:ok('segvguard/suspension:300', s:N)
call s:ok('segvguard/maxcrashes:3', s:N)
call s:ok('tpe/gid:1000', s:N)
call s:ok('tpe/gid:none')
call s:ok('tpe/negate:on', s:B)
call s:ok('tpe/root_owned:off', s:B)
call s:ok('tpe/root_mount:1', s:B)
call s:ok('tpe/user_owned:true', s:B)
call s:ok('proxy/addr:127.0.0.1', s:C)
call s:ok('proxy/port:8080', s:N)
call s:ok('proxy/ext/host:example.com', s:S)
call s:ok('proxy/ext/port:443', s:N)
call s:ok('proxy/ext/unix:/run/p.sock', s:S)
call s:ok('time:5', s:N)
call s:ok('time:-5', s:N)
call s:ok('time/boot:100', s:N)
call s:ok('time/mono:-42', s:N)
call s:ok('time:none', s:T)
call s:ok('timeout:30', s:N)
call s:ok('timeout:none', s:T)
call s:ok('uts/host:myhost', s:S)
call s:ok('uts/domain:example', s:S)
call s:ok('uts/version:1.0', s:S)
call s:ok('root:/newroot', s:S)
call s:ok('root:tmpfs', s:T)
call s:ok('root:ramfs', s:T)
call s:ok('root:none', s:T)
call s:ok('root/map:on', s:B)
call s:ok('root/fake:off', s:B)
call s:ok('workdir:/home', s:S)
call s:ok('sandbox/fs:on', s:B)
call s:ok('sandbox/readlink:on', s:B)
call s:ok('sandbox/mkbdev:off', s:B)
call s:ok('sandbox/mkcdev:on', s:B)
call s:ok('sandbox/all:on', s:B)
call s:ok('sandbox/all-l:on', s:B)
call s:ok('sandbox/all-x:off', s:B)
call s:ok('sandbox/lpath:on', s:B)
call s:ok('sandbox/bnet:on', s:B)
call s:ok('sandbox/read,write:off', s:B)
call s:ok('sandbox/pty:on', s:B)
call s:ok('sandbox/fs?')
call s:ok('default/fs:deny', s:P)
call s:ok('default/read:allow', s:P)
call s:ok('default/readlink:warn', s:P)
call s:ok('default/block:deny', s:P)
call s:ok('default/segvguard:kill', s:P)
call s:ok('default/all-l:deny', s:P)
call s:ok('default/read,write:deny', s:P)
call s:ok('unshare/mount:on', s:B)
call s:ok('unshare/all:on', s:B)
call s:ok('unshare/mount,net:off', s:B)
call s:ok('unshare/mount?')
call s:ok('trace/allow_unsafe_sys_ptrace:1', s:B)
call s:ok('trace/allow_unsafe_ptrace:1', s:B)
call s:ok('trace/allow_unsafe_kcmp:1', s:B)
call s:ok('trace/allow_unsafe_fcntl:0', s:B)
call s:ok('trace/allow_unsafe_proc_files:on', s:B)
call s:ok('trace/sync_seccomp:1', s:B)
call s:ok('trace/deny_dotdot:on', s:B)
call s:ok('trace/force_cloexec:on', s:B)
call s:ok('trace/allow_safe_bind:on', s:B)
call s:ok('trace/force_umask:022', s:N)
call s:ok('trace/force_umask:off', s:N)
call s:ok('trace/memory_access:2', s:N)
call s:ok('trace/allow_unsafe_namespace:mount,net', s:T)
call s:ok('trace/allow_unsafe_namespace:all', s:T)
call s:ok('setenv!FOO=bar')
call s:ok('unsetenv!FOO')
call s:ok('clearenv!')
call s:ok('passenv+LD_*')
call s:ok('passenv-FOO')
call s:ok('passenv^FOO')
call s:ok('cmd/exec!/bin/echo')
call s:ok('append+/etc/foo', s:S)
call s:ok('mask+/proc:/dev/null')
call s:ok('mask^')
call s:ok('block+1.2.3.0/24')
call s:ok('block-1.2.3.4')
call s:ok('block^')
call s:ok('crypt+/secret')
call s:ok('crypt/key:42', s:N)
call s:ok('crypt/key:-5', s:N)
call s:ok('crypt/key/enc:7', s:N)
call s:ok('crypt/key/mac:9', s:N)
call s:ok('crypt/tmp:/tmp/x', s:S)
call s:ok('force+/usr/bin/x:sha256:deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef:deny')
call s:ok('force-/usr/bin/x')
call s:ok('force^')
call s:ok('setuid+1000:2000')
call s:ok('setgid+1000:2000')
call s:ok('setuid^1000')
call s:ok('bind+/src:/dst')
call s:ok('bind-try+/src:/dst')
call s:ok('bind-/dst')
call s:ok('link+/a:/b')
call s:ok('link-try+/a:/b')
call s:ok('symlink+/a:/b')
call s:ok('symlink-try+/a:/b')
call s:ok('link^')
call s:ok('mkdir+/tmp/d:0755')
call s:ok('mkdir-try+/tmp/d')
call s:ok('mkfile+/tmp/f')
call s:ok('mkfifo+/tmp/f')
call s:ok('mkfifo-try+/tmp/f')
call s:ok('allow/ioctl+0x5401', s:N)
call s:ok('deny/ioctl+TIOCSTI', s:P)
call s:ok('allow/ioctl-0o21505', s:N)
call s:ok('allow/read+/etc/**', s:S)
call s:ok('warn/write+/etc', s:S)
call s:ok('filter/exec+/bin/sh', s:S)
call s:ok('deny/stat+/x', s:S)
call s:ok('panic/create+/x', s:S)
call s:ok('stop/delete+/x', s:S)
call s:ok('abort/rename+/x', s:S)
call s:ok('kill/chmod+/x', s:S)
call s:ok('exit/chown+/x', s:S)
call s:ok('allow/readlink+/etc', s:S)
call s:ok('allow/mkbdev+/dev/x', s:S)
call s:ok('allow/mkcdev+/dev/x', s:S)
call s:ok('allow/all-l+/x', s:S)
call s:ok('allow/all-x+/x', s:S)
call s:ok('allow/read,write+/x', s:S)
call s:ok('allow/net/bind+1.2.3.4!80', s:C, s:S)
call s:ok('allow/net/connect+127.0.0.1!443', s:C, s:S)
call s:ok('allow/net+1.2.3.4!22', s:C, s:S)
call s:ok('allow/net/bind+any!80', '', s:S)
call s:ok('allow/inet+loopback', '', s:S)
call s:ok('allow/net/connect+tcp!127.0.0.1!80', s:T, s:S)
call s:ok('allow/net/connect+udp!9.9.9.9!53', s:T, s:S)
call s:ok('allow/net/bind+tcp6!::1!8080', s:T, s:S)
call s:ok('allow/net/connect+net!10.0.0.0/8!22,80,443', s:T, s:S)
call s:ok('allow/net/connect+udp!loopback!*', s:T, s:S)
call s:ok('allow/net/connect+tcp!*!443', s:T, s:S)
call s:ok('allow/net/connect+unix!/run/foo.sock', s:T)
call s:ok('allow/net/bind+unix!@dbus-*', s:T)
call s:ok('allow/net/bind+unixgram!@dbus-*', s:T)
call s:ok('allow/net/connect+unix!!unnamed', s:T)
call s:ok('allow/net/connect+tcp!${ADDR}!${PORT}', s:T)
call s:ok('allow/net/connect+${ADDR}!${PORT}')
call s:ok('allow/net/connect+${ADDR}@${PORT}')
call s:ok('allow/net/link+route', s:P)
call s:ok('allow/net/link+inet_diag', s:P)
call s:ok('allow/lock/read+/etc', s:S)
call s:ok('allow/lock/mkbdev+/dev', s:S)
call s:ok('allow/lock/connect+22', s:N)
call s:ok('allow/lock/bind+80', s:N)
call s:ok('include /etc/foo.syd-3')
call s:ok('include_profile linux')
call s:ok('domain+@web', s:T)
call s:ok('domain+@web:@default', s:S)
call s:ok('domain+@sandbox:fs', s:S)
call s:ok('domain+@jail:/etc/jail.syd-3', s:S)
call s:ok('domain+@mynet2', s:T)
call s:ok('domain+@${DOM}', s:T)
call s:ok('domain+@web:${SEED}', s:T)
call s:ok('domain-@web', s:T)
call s:ok('domain^')
call s:ok(' domain+@web', s:T)
call s:ok('domain+@a', s:T)
call s:ok('domain+@WebDomain', s:T)
call s:ok('domain+@a_b_2', s:T)
call s:ok('domain+@aaaaaaaaaaaaaaaa', s:T)
call s:ok('domain+@web:@my_other', s:S)
call s:err('domain+@1web')
call s:err('domain+@_web')
call s:err('domain+@my-net')
call s:err('domain+@my.net')
call s:err('domain+@web!')
call s:err('domain+@web/x')
call s:err('domain+@aaaaaaaaaaaaaaaaa')
call s:err('domain+@web:@bad-seed')
call s:err('domain+@web:@1bad')
call s:err('domain-@my-net')
call s:err('move/@my-net/exec+/x')
call s:err('move/@1net/exec+/x')
call s:err('move/@aaaaaaaaaaaaaaaaa/exec+/x')
call s:err('@my-net/allow/read+/etc')
call s:err('@1web/sandbox/exec:on')
call s:err('cmd/move!my-net')
call s:err('cmd/move!@my-net')
call s:err('cmd/move!1web')
call s:ok('move/@net/exec+/usr/bin/curl', s:S)
call s:ok('move/@net/exec+/usr/bin/curl', s:T)
call s:ok('move/@net/exec-/usr/bin/curl', s:S)
call s:ok('move/@net/exec^', s:T)
call s:ok('move/@net/exec^', '', s:S)
call s:ok('move/@net/mmap+/usr/lib/**.so', s:S)
call s:ok('move/@net/chdir+/srv', s:S)
call s:ok('move/@net/exit+/usr/bin/helper', s:S)
call s:ok('move/@net/exec+${BIN}/curl', s:S)
call s:ok('move/@mynet/bind+0.0.0.0/0!8080', s:C)
call s:ok('move/@net/bind+0.0.0.0/0!8080', s:N)
call s:ok('move/@net/connect+127.0.0.1!443', s:C)
call s:ok('move/@net/accept+0.0.0.0/0!1-65535', s:N)
call s:ok('move/@net/bind+any!80', s:T)
call s:ok('move/@net/connect-127.0.0.1!443', s:C)
call s:ok('move/@net/bind^', s:T)
call s:ok('move/@net/bind+/run/app.sock', s:S)
call s:ok('move/@net/bind+/run/app.sock', '', s:C)
call s:ok('move/@net/connect+/run/db.sock', s:S)
call s:ok('move/@net/bind+@my.service', s:S)
call s:ok('move/@net/connect+@dbus-*', s:S)
call s:ok('move/@net/bind+!unnamed', s:S)
call s:ok('move/@net/connect-/run/db.sock', s:S)
call s:ok('move/@db/connect+tcp!10.0.0.7!5432', s:T)
call s:ok('move/@db/connect+tcp!10.0.0.7!5432', s:C)
call s:ok('move/@db/connect+udp!127.0.0.1!53', s:N)
call s:ok('move/@net/bind+unix!/run/app.sock', s:S)
call s:ok('move/@net/bind+unix!@my.service', s:S)
call s:ok('move/@net/bind+unix!!unnamed', s:S)
call s:ok('cmd/move!web', s:T)
call s:ok('cmd/move!@web', s:T)
call s:ok('@web/allow/read+/etc/hosts', s:T)
call s:ok('@web/allow/read+/etc/hosts', s:S)
call s:ok('@web/sandbox/exec:on', s:B)
call s:ok('@web/mem/max:1G', s:N)
call s:ok('@web/default/read:allow', s:P)
call s:ok('@db/move/@net/connect+0.0.0.0/0!5432', s:C)
call s:ok('@db/move/@net/connect+0.0.0.0/0!5432', s:N)
call s:ok('@web/move/@db/exec+/x', s:S)
call s:ok('@mynet/allow/read+/etc', s:T)
call s:ok('@web/allow/net/bind+1.2.3.4!80', s:C)
call s:ok('@web/deny/ioctl+TIOCSTI', s:P)
call s:ok('@web/append+/etc/foo', s:S)
call s:ok('@web/block+1.2.3.0/24', s:C)
call s:ok('@web/force-/usr/bin/x', s:S)
call s:ok('@web/segvguard/maxcrashes:3', s:N)
call s:ok('@web/mask+/proc:/dev/null')
call s:ok('@web/tpe/gid:1000', s:N)
call s:ok('@web/uts/host:myhost', s:S)
call s:ok('@web/mem/kill:1', s:B)
call s:ok('@web/dump')
call s:ok('@web/stat')
call s:ok('@web/sandbox/exec:on', s:B)
call s:ok('@web/sandbox/lock:off', s:B)
call s:ok('@web/sandbox/all:on', s:B)
call s:ok('@web/sandbox/all-l:on', s:B)
call s:ok('@web/sandbox/all-x:on', s:B)
call s:ok('@web/sandbox/read,write:on', s:B)
call s:ok('@web/sandbox/mem:on', s:B)
call s:ok('@web/sandbox/stat:on', s:B)
call s:ok('@web/sandbox/list:on', s:B)
call s:ok('@web/sandbox/chdir:on', s:B)
call s:ok('@web/sandbox/crypt:0', s:B)
call s:ok('@web/sandbox/lock,exec:off', s:B)
call s:ok('@web/sandbox/lock?')
call s:err('totallyunknown:x')
call s:err('bogusdirective')
call s:err('sandbox/raed:on')
call s:err('sandbox/mkdev:on')
call s:err('sandbox/bogus:on')
call s:err('default/boguscap:deny')
call s:err('default/mkdev:deny')
call s:err('unshare/bogus:on')
call s:err('uts/bogus:x')
call s:err('root/bogus:on')
call s:err('ipc/bogus:1')
call s:err('log/bogus:1')
call s:err('log/lock/bogus:1')
call s:err('mem/bogus:1')
call s:err('pid/bogus:1')
call s:err('tpe/bogus:on')
call s:err('segvguard/bogus:1')
call s:err('proxy/bogus:1')
call s:err('proxy/ext/bogus:1')
call s:err('crypt/bogus:1')
call s:err('trace/allow_unsafe_bogus:on')
call s:err('trace/bogus:on')
call s:err('time/bogus:1')
call s:err('warn/ioctl+foo')
call s:err('allow/bogus+/x')
call s:err('allow/net/accept+any')
call s:err('allow/net/bogus+any')
call s:err('allow/lock/bogus+/x')
call s:err('pty/bogus:1')
call s:err('config/bogus:1')
call s:err('mkbogus+/x')
call s:err('domain+web')
call s:err('domain!foo')
call s:err('domain^junk')
call s:err('move/foo+/x')
call s:err('move//exec+/x')
call s:err('move/@net/bogus+/x')
call s:err('move/@net/EXEC+/x')
call s:err('move/@net/exec')
call s:err('move/@net/exec^junk')
call s:err('move/@net/exec+')
call s:err('domain+@')
call s:err('domain-@')
call s:err('cmd/move!')
call s:err('@web/domain+@x')
call s:err('@web/totallyunknown:x')
call s:err('@web/lock:on')
call s:err('@web/timeout:5')
call s:err('@web/time:5')
call s:err('@web/rlimit/nofile:1024')
call s:err('@web/proxy/port:8080')
call s:err('@web/pty/row:80')
call s:err('@web/ipc/uid:0')
call s:err('@web/unshare/mount:on')
call s:err('@web/root:/x')
call s:err('@web/workdir:/x')
call s:err('@web/config/expand:5m')
call s:err('@web/log/level:debug')
call s:err('@web/setenv!FOO=bar')
call s:err('@web/unsetenv!FOO')
call s:err('@web/clearenv!')
call s:err('@web/passenv+LD_*')
call s:err('@web/crypt+/x')
call s:err('@web/setuid+1000:2000')
call s:err('@web/bind+/a:/b')
call s:err('@web/link+/a:/b')
call s:err('@web/mkdir+/d:0755')
call s:err('@web/allow/lock/read+/x')
call s:err('@web/allow/net/link+route')
call s:err('@web/trace/allow_unsafe_ptrace:1')
call s:err('@web/sandbox/lock:on')
call s:err('@web/sandbox/crypt:1')
call s:err('@web/sandbox/proxy:on')
call s:err('@web/sandbox/pty:true')
call s:err('@web/sandbox/exec,lock:on')
let s:g2c = {
\ 'Syd3Boolean': s:B, 'Syd3LockState': s:B,
\ 'Syd3Size': s:N, 'Syd3Duration': s:N, 'Syd3Int': s:N, 'Syd3PidMax': s:N,
\ 'Syd3Gid': s:N, 'Syd3MkMode': s:N, 'Syd3CryptKeyInt': s:N, 'Syd3IoctlNum': s:N,
\ 'Syd3SetInt': s:N, 'Syd3SetDuration': s:N, 'Syd3Umask': s:N, 'Syd3ZeroOrOne': s:N,
\ 'Syd3TimeVal': s:N, 'Syd3RulePort': s:N, 'Syd3RulePortSet': s:N,
\ 'Syd3IpcSocket': s:S, 'Syd3MkPath': s:S, 'Syd3RulePath': s:S, 'Syd3RuleUnix': s:S,
\ 'Syd3SetName': s:S, 'Syd3SetPath': s:S, 'Syd3ProxyStr': s:S, 'Syd3ForcePath': s:S,
\ 'Syd3RuleAddr': s:C, 'Syd3BlockAddr': s:C,
\ 'Syd3None': s:T, 'Syd3RuleAlias': s:T, 'Syd3LogSeverity': s:T, 'Syd3SetTmpfs': s:T,
\ 'Syd3RuleProto': s:T, 'Syd3RuleWild': s:T, 'Syd3MoveProto': s:T,
\ 'Syd3UnsafeNs': s:T, 'Syd3RlimitVal': s:T,
\ 'Syd3LinkFam': s:P, 'Syd3GidNone': s:P, 'Syd3IoctlConst': s:P, 'Syd3DefaultAct': s:P,
\ 'Syd3DomainName': s:T, 'Syd3MoveTo': s:T, 'Syd3CmdMoveName': s:T, 'Syd3DomainAddrName': s:T,
\ 'Syd3DomainSeed': s:S, 'Syd3MovePattern': s:S, 'Syd3MoveUnix': s:S,
\ 'Syd3MoveAddr': s:C, 'Syd3MovePort': s:N,
\ }
let s:lines = map(copy(s:cases), 'v:val.l')
let s:tmp = tempname() . '.syd-3'
call writefile(s:lines, s:tmp)
exec 'edit ' . fnameescape(s:tmp)
setfiletype syd-3
syntax on
doautocmd FileType
let s:out = ['TAP version 13', '1..' . len(s:cases)]
let s:n = 0
let s:fail = 0
for s:case in s:cases
let s:n += 1
let s:colours = {}
let s:haserr = 0
let s:lastcol = col([s:n, '$']) - 1
let s:col = 1
while s:col <= s:lastcol
let s:gname = synIDattr(synID(s:n, s:col, 1), 'name')
if s:gname =~# 'ConfigError'
let s:haserr = 1
endif
if has_key(s:g2c, s:gname)
let s:colours[s:g2c[s:gname]] = 1
endif
let s:col += 1
endwhile
let s:actual = empty(s:colours) ? '-' : join(sort(keys(s:colours)), ',')
let s:reasons = []
if s:case.e && !s:haserr
call add(s:reasons, ['error', 'ok'])
elseif !s:case.e && s:haserr
call add(s:reasons, ['ok', 'error'])
endif
if s:case.c !=# '' && !has_key(s:colours, s:case.c)
call add(s:reasons, [s:case.c, s:actual])
endif
if s:case.nc !=# '' && has_key(s:colours, s:case.nc)
call add(s:reasons, ['not ' . s:case.nc, s:actual])
endif
if empty(s:reasons)
call add(s:out, 'ok ' . s:n . ' - ' . s:case.l)
else
let s:fail += 1
call add(s:out, 'not ok ' . s:n . ' - ' . s:case.l)
for s:r in s:reasons
call add(s:out, '# expected: ' . s:r[0])
call add(s:out, '# actual: ' . s:r[1])
endfor
endif
endfor
call add(s:out, '# ' . len(s:cases) . ' tests, ' . s:fail . ' failures')
enew!
call setline(1, s:out)
%print
if s:fail == 0
qall!
else
cquit!
endif