blob: b616870efe197eaa0b1c974c2d13d4cfe7faf4a1 [file] [log] [blame]
Bram Moolenaar8767f522016-07-01 17:17:39 +02001" Tests for stat functions and checktime
2
Bram Moolenaar82de3c22017-08-17 17:35:36 +02003func CheckFileTime(doSleep)
Bram Moolenaaraddc1562018-11-18 12:25:09 +01004 let fnames = ['Xtest1.tmp', 'Xtest2.tmp', 'Xtest3.tmp']
5 let times = []
Bram Moolenaar82de3c22017-08-17 17:35:36 +02006 let result = 0
Bram Moolenaar8767f522016-07-01 17:17:39 +02007
Bram Moolenaar4b96df52020-01-26 22:00:26 +01008 " Use three files instead of localtim(), with a network filesystem the file
Bram Moolenaaraddc1562018-11-18 12:25:09 +01009 " times may differ at bit
Bram Moolenaara2f28852017-02-01 22:05:28 +010010 let fl = ['Hello World!']
Bram Moolenaaraddc1562018-11-18 12:25:09 +010011 for fname in fnames
12 call writefile(fl, fname)
Bram Moolenaar4c313b12019-08-24 22:58:31 +020013 call add(times, fname->getftime())
Bram Moolenaaraddc1562018-11-18 12:25:09 +010014 if a:doSleep
15 sleep 1
16 endif
17 endfor
Bram Moolenaar8767f522016-07-01 17:17:39 +020018
Bram Moolenaaraddc1562018-11-18 12:25:09 +010019 let time_correct = (times[0] <= times[1] && times[1] <= times[2])
Bram Moolenaar82de3c22017-08-17 17:35:36 +020020 if a:doSleep || time_correct
Bram Moolenaaraddc1562018-11-18 12:25:09 +010021 call assert_true(time_correct, printf('Expected %s <= %s <= %s', times[0], times[1], times[2]))
Bram Moolenaar4c313b12019-08-24 22:58:31 +020022 call assert_equal(strlen(fl[0] . "\n"), fnames[0]->getfsize())
23 call assert_equal('file', fnames[0]->getftype())
Bram Moolenaaraddc1562018-11-18 12:25:09 +010024 call assert_equal('rw-', getfperm(fnames[0])[0:2])
Bram Moolenaar82de3c22017-08-17 17:35:36 +020025 let result = 1
26 endif
Bram Moolenaara2f28852017-02-01 22:05:28 +010027
Bram Moolenaaraddc1562018-11-18 12:25:09 +010028 for fname in fnames
29 call delete(fname)
30 endfor
Bram Moolenaar82de3c22017-08-17 17:35:36 +020031 return result
32endfunc
33
34func Test_existent_file()
35 " On some systems the file timestamp is rounded to a multiple of 2 seconds.
36 " We need to sleep to handle that, but that makes the test slow. First try
37 " without the sleep, and if it fails try again with the sleep.
38 if CheckFileTime(0) == 0
39 call CheckFileTime(1)
40 endif
Bram Moolenaar8767f522016-07-01 17:17:39 +020041endfunc
42
43func Test_existent_directory()
Bram Moolenaara2f28852017-02-01 22:05:28 +010044 let dname = '.'
Bram Moolenaar8767f522016-07-01 17:17:39 +020045
46 call assert_equal(0, getfsize(dname))
47 call assert_equal('dir', getftype(dname))
48 call assert_equal('rwx', getfperm(dname)[0:2])
49endfunc
50
Bram Moolenaar386bc822018-07-07 18:34:12 +020051func SleepForTimestamp()
52 " FAT has a granularity of 2 seconds, otherwise it's usually 1 second
53 if has('win32')
54 sleep 2
55 else
56 sleep 1
57 endif
58endfunc
59
Bram Moolenaar8767f522016-07-01 17:17:39 +020060func Test_checktime()
Bram Moolenaara2f28852017-02-01 22:05:28 +010061 let fname = 'Xtest.tmp'
Bram Moolenaar8767f522016-07-01 17:17:39 +020062
Bram Moolenaara2f28852017-02-01 22:05:28 +010063 let fl = ['Hello World!']
Bram Moolenaar56564962022-10-10 22:39:42 +010064 call writefile(fl, fname, 'D')
Bram Moolenaar8767f522016-07-01 17:17:39 +020065 set autoread
66 exec 'e' fname
Bram Moolenaar386bc822018-07-07 18:34:12 +020067 call SleepForTimestamp()
Bram Moolenaara2f28852017-02-01 22:05:28 +010068 let fl = readfile(fname)
Bram Moolenaar8767f522016-07-01 17:17:39 +020069 let fl[0] .= ' - checktime'
70 call writefile(fl, fname)
71 checktime
72 call assert_equal(fl[0], getline(1))
73endfunc
74
Leah Neukirchen0a7984a2021-10-14 21:27:55 +010075func Test_checktime_fast()
76 CheckFeature nanotime
77
78 let fname = 'Xtest.tmp'
79
80 let fl = ['Hello World!']
Bram Moolenaar56564962022-10-10 22:39:42 +010081 call writefile(fl, fname, 'D')
Leah Neukirchen0a7984a2021-10-14 21:27:55 +010082 set autoread
83 exec 'e' fname
84 let fl = readfile(fname)
85 let fl[0] .= ' - checktime'
86 call writefile(fl, fname)
87 checktime
88 call assert_equal(fl[0], getline(1))
Leah Neukirchen0a7984a2021-10-14 21:27:55 +010089endfunc
90
91func Test_autoread_fast()
92 CheckFeature nanotime
93
Bram Moolenaareaa006d2021-10-15 17:09:50 +010094 " this is timing sensitive
95 let g:test_is_flaky = 1
Leah Neukirchen0a7984a2021-10-14 21:27:55 +010096
Bram Moolenaareaa006d2021-10-15 17:09:50 +010097 new Xautoread
98 setlocal autoread
99 call setline(1, 'foo')
Leah Neukirchen0a7984a2021-10-14 21:27:55 +0100100 w!
Bram Moolenaar944eeb42021-10-18 14:37:13 +0100101 sleep 10m
Bram Moolenaar56564962022-10-10 22:39:42 +0100102 call writefile(['bar'], 'Xautoread', 'D')
Bram Moolenaaraccf4ed2021-10-15 00:38:02 +0100103 sleep 10m
Leah Neukirchen0a7984a2021-10-14 21:27:55 +0100104 checktime
Leah Neukirchen0a7984a2021-10-14 21:27:55 +0100105 call assert_equal('bar', trim(getline(1)))
Leah Neukirchen0a7984a2021-10-14 21:27:55 +0100106endfunc
107
Bram Moolenaar386bc822018-07-07 18:34:12 +0200108func Test_autoread_file_deleted()
109 new Xautoread
110 set autoread
111 call setline(1, 'original')
112 w!
113
114 call SleepForTimestamp()
115 if has('win32')
116 silent !echo changed > Xautoread
117 else
118 silent !echo 'changed' > Xautoread
119 endif
120 checktime
121 call assert_equal('changed', trim(getline(1)))
122
123 call SleepForTimestamp()
124 messages clear
125 if has('win32')
126 silent !del Xautoread
127 else
128 silent !rm Xautoread
129 endif
130 checktime
131 call assert_match('E211:', execute('messages'))
132 call assert_equal('changed', trim(getline(1)))
133
134 call SleepForTimestamp()
135 if has('win32')
136 silent !echo recreated > Xautoread
137 else
138 silent !echo 'recreated' > Xautoread
139 endif
140 checktime
141 call assert_equal('recreated', trim(getline(1)))
142
143 call delete('Xautoread')
144 bwipe!
145endfunc
146
147
Bram Moolenaar8767f522016-07-01 17:17:39 +0200148func Test_nonexistent_file()
Bram Moolenaara2f28852017-02-01 22:05:28 +0100149 let fname = 'Xtest.tmp'
Bram Moolenaar8767f522016-07-01 17:17:39 +0200150
151 call delete(fname)
152 call assert_equal(-1, getftime(fname))
153 call assert_equal(-1, getfsize(fname))
154 call assert_equal('', getftype(fname))
155 call assert_equal('', getfperm(fname))
156endfunc
157
Bram Moolenaar1598f992018-08-09 22:08:57 +0200158func Test_getftype()
159 call assert_equal('file', getftype(v:progpath))
160 call assert_equal('dir', getftype('.'))
161
162 if !has('unix')
163 return
164 endif
165
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100166 silent !ln -s Xlinkfile Xlink
Bram Moolenaar1598f992018-08-09 22:08:57 +0200167 call assert_equal('link', getftype('Xlink'))
168 call delete('Xlink')
169
170 if executable('mkfifo')
171 silent !mkfifo Xfifo
172 call assert_equal('fifo', getftype('Xfifo'))
173 call delete('Xfifo')
174 endif
175
176 for cdevfile in systemlist('find /dev -type c -maxdepth 2 2>/dev/null')
Bram Moolenaarad5db442019-08-30 13:12:25 +0200177 " On Mac /def/fd/2 is found but the type is "fifo"
178 if cdevfile !~ '/dev/fd/'
179 let type = getftype(cdevfile)
180 " ignore empty result, can happen if the file disappeared
181 if type != ''
182 call assert_equal('cdev', type, 'for ' .. cdevfile)
183 endif
Bram Moolenaar3b3a5062018-08-22 20:16:16 +0200184 endif
Bram Moolenaar1598f992018-08-09 22:08:57 +0200185 endfor
186
187 for bdevfile in systemlist('find /dev -type b -maxdepth 2 2>/dev/null')
Bram Moolenaar3b3a5062018-08-22 20:16:16 +0200188 let type = getftype(bdevfile)
189 " ignore empty result, can happen if the file disappeared
190 if type != ''
Bram Moolenaarad5db442019-08-30 13:12:25 +0200191 call assert_equal('bdev', type, 'for ' .. bdevfile)
Bram Moolenaar3b3a5062018-08-22 20:16:16 +0200192 endif
Bram Moolenaar1598f992018-08-09 22:08:57 +0200193 endfor
194
195 " The /run/ directory typically contains socket files.
196 " If it does not, test won't fail but will not test socket files.
197 for socketfile in systemlist('find /run -type s -maxdepth 2 2>/dev/null')
Bram Moolenaar3b3a5062018-08-22 20:16:16 +0200198 let type = getftype(socketfile)
199 " ignore empty result, can happen if the file disappeared
200 if type != ''
Bram Moolenaarad5db442019-08-30 13:12:25 +0200201 call assert_equal('socket', type, 'for ' .. socketfile)
Bram Moolenaar3b3a5062018-08-22 20:16:16 +0200202 endif
Bram Moolenaar1598f992018-08-09 22:08:57 +0200203 endfor
204
205 " TODO: file type 'other' is not tested. How can we test it?
206endfunc
207
Bram Moolenaar8767f522016-07-01 17:17:39 +0200208func Test_win32_symlink_dir()
209 " On Windows, non-admin users cannot create symlinks.
210 " So we use an existing symlink for this test.
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200211 CheckMSWindows
212 " Check if 'C:\Users\All Users' is a symlink to a directory.
213 let res = system('dir C:\Users /a')
214 if match(res, '\C<SYMLINKD> *All Users') >= 0
215 " Get the filetype of the symlink.
216 call assert_equal('dir', getftype('C:\Users\All Users'))
217 else
218 throw 'Skipped: cannot find an existing symlink'
Bram Moolenaar8767f522016-07-01 17:17:39 +0200219 endif
220endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200221
222" vim: shiftwidth=2 sts=2 expandtab