Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 1 | " Tests for stat functions and checktime |
| 2 | |
Bram Moolenaar | 6d91bcb | 2020-08-12 18:50:36 +0200 | [diff] [blame] | 3 | source check.vim |
| 4 | |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 5 | func CheckFileTime(doSleep) |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 6 | let fnames = ['Xtest1.tmp', 'Xtest2.tmp', 'Xtest3.tmp'] |
| 7 | let times = [] |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 8 | let result = 0 |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 9 | |
Bram Moolenaar | 4b96df5 | 2020-01-26 22:00:26 +0100 | [diff] [blame] | 10 | " Use three files instead of localtim(), with a network filesystem the file |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 11 | " times may differ at bit |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 12 | let fl = ['Hello World!'] |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 13 | for fname in fnames |
| 14 | call writefile(fl, fname) |
Bram Moolenaar | 4c313b1 | 2019-08-24 22:58:31 +0200 | [diff] [blame] | 15 | call add(times, fname->getftime()) |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 16 | if a:doSleep |
| 17 | sleep 1 |
| 18 | endif |
| 19 | endfor |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 20 | |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 21 | let time_correct = (times[0] <= times[1] && times[1] <= times[2]) |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 22 | if a:doSleep || time_correct |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 23 | call assert_true(time_correct, printf('Expected %s <= %s <= %s', times[0], times[1], times[2])) |
Bram Moolenaar | 4c313b1 | 2019-08-24 22:58:31 +0200 | [diff] [blame] | 24 | call assert_equal(strlen(fl[0] . "\n"), fnames[0]->getfsize()) |
| 25 | call assert_equal('file', fnames[0]->getftype()) |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 26 | call assert_equal('rw-', getfperm(fnames[0])[0:2]) |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 27 | let result = 1 |
| 28 | endif |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 29 | |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 30 | for fname in fnames |
| 31 | call delete(fname) |
| 32 | endfor |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 33 | return result |
| 34 | endfunc |
| 35 | |
| 36 | func Test_existent_file() |
| 37 | " On some systems the file timestamp is rounded to a multiple of 2 seconds. |
| 38 | " We need to sleep to handle that, but that makes the test slow. First try |
| 39 | " without the sleep, and if it fails try again with the sleep. |
| 40 | if CheckFileTime(0) == 0 |
| 41 | call CheckFileTime(1) |
| 42 | endif |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 43 | endfunc |
| 44 | |
| 45 | func Test_existent_directory() |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 46 | let dname = '.' |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 47 | |
| 48 | call assert_equal(0, getfsize(dname)) |
| 49 | call assert_equal('dir', getftype(dname)) |
| 50 | call assert_equal('rwx', getfperm(dname)[0:2]) |
| 51 | endfunc |
| 52 | |
Bram Moolenaar | 386bc82 | 2018-07-07 18:34:12 +0200 | [diff] [blame] | 53 | func SleepForTimestamp() |
| 54 | " FAT has a granularity of 2 seconds, otherwise it's usually 1 second |
| 55 | if has('win32') |
| 56 | sleep 2 |
| 57 | else |
| 58 | sleep 1 |
| 59 | endif |
| 60 | endfunc |
| 61 | |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 62 | func Test_checktime() |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 63 | let fname = 'Xtest.tmp' |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 64 | |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 65 | let fl = ['Hello World!'] |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 66 | call writefile(fl, fname) |
| 67 | set autoread |
| 68 | exec 'e' fname |
Bram Moolenaar | 386bc82 | 2018-07-07 18:34:12 +0200 | [diff] [blame] | 69 | call SleepForTimestamp() |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 70 | let fl = readfile(fname) |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 71 | let fl[0] .= ' - checktime' |
| 72 | call writefile(fl, fname) |
| 73 | checktime |
| 74 | call assert_equal(fl[0], getline(1)) |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 75 | |
| 76 | call delete(fname) |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 77 | endfunc |
| 78 | |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 79 | func Test_checktime_fast() |
| 80 | CheckFeature nanotime |
| 81 | |
| 82 | let fname = 'Xtest.tmp' |
| 83 | |
| 84 | let fl = ['Hello World!'] |
| 85 | call writefile(fl, fname) |
| 86 | set autoread |
| 87 | exec 'e' fname |
| 88 | let fl = readfile(fname) |
| 89 | let fl[0] .= ' - checktime' |
| 90 | call writefile(fl, fname) |
| 91 | checktime |
| 92 | call assert_equal(fl[0], getline(1)) |
| 93 | |
| 94 | call delete(fname) |
| 95 | endfunc |
| 96 | |
| 97 | func Test_autoread_fast() |
| 98 | CheckFeature nanotime |
| 99 | |
| 100 | new Xautoread |
| 101 | set autoread |
| 102 | call setline(1, 'foo') |
| 103 | |
| 104 | w! |
| 105 | silent !echo bar > Xautoread |
Bram Moolenaar | accf4ed | 2021-10-15 00:38:02 +0100 | [diff] [blame] | 106 | sleep 10m |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 107 | checktime |
| 108 | |
| 109 | call assert_equal('bar', trim(getline(1))) |
| 110 | call delete('Xautoread') |
| 111 | endfunc |
| 112 | |
Bram Moolenaar | 386bc82 | 2018-07-07 18:34:12 +0200 | [diff] [blame] | 113 | func Test_autoread_file_deleted() |
| 114 | new Xautoread |
| 115 | set autoread |
| 116 | call setline(1, 'original') |
| 117 | w! |
| 118 | |
| 119 | call SleepForTimestamp() |
| 120 | if has('win32') |
| 121 | silent !echo changed > Xautoread |
| 122 | else |
| 123 | silent !echo 'changed' > Xautoread |
| 124 | endif |
| 125 | checktime |
| 126 | call assert_equal('changed', trim(getline(1))) |
| 127 | |
| 128 | call SleepForTimestamp() |
| 129 | messages clear |
| 130 | if has('win32') |
| 131 | silent !del Xautoread |
| 132 | else |
| 133 | silent !rm Xautoread |
| 134 | endif |
| 135 | checktime |
| 136 | call assert_match('E211:', execute('messages')) |
| 137 | call assert_equal('changed', trim(getline(1))) |
| 138 | |
| 139 | call SleepForTimestamp() |
| 140 | if has('win32') |
| 141 | silent !echo recreated > Xautoread |
| 142 | else |
| 143 | silent !echo 'recreated' > Xautoread |
| 144 | endif |
| 145 | checktime |
| 146 | call assert_equal('recreated', trim(getline(1))) |
| 147 | |
| 148 | call delete('Xautoread') |
| 149 | bwipe! |
| 150 | endfunc |
| 151 | |
| 152 | |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 153 | func Test_nonexistent_file() |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 154 | let fname = 'Xtest.tmp' |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 155 | |
| 156 | call delete(fname) |
| 157 | call assert_equal(-1, getftime(fname)) |
| 158 | call assert_equal(-1, getfsize(fname)) |
| 159 | call assert_equal('', getftype(fname)) |
| 160 | call assert_equal('', getfperm(fname)) |
| 161 | endfunc |
| 162 | |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 163 | func Test_getftype() |
| 164 | call assert_equal('file', getftype(v:progpath)) |
| 165 | call assert_equal('dir', getftype('.')) |
| 166 | |
| 167 | if !has('unix') |
| 168 | return |
| 169 | endif |
| 170 | |
| 171 | silent !ln -s Xfile Xlink |
| 172 | call assert_equal('link', getftype('Xlink')) |
| 173 | call delete('Xlink') |
| 174 | |
| 175 | if executable('mkfifo') |
| 176 | silent !mkfifo Xfifo |
| 177 | call assert_equal('fifo', getftype('Xfifo')) |
| 178 | call delete('Xfifo') |
| 179 | endif |
| 180 | |
| 181 | for cdevfile in systemlist('find /dev -type c -maxdepth 2 2>/dev/null') |
Bram Moolenaar | ad5db44 | 2019-08-30 13:12:25 +0200 | [diff] [blame] | 182 | " On Mac /def/fd/2 is found but the type is "fifo" |
| 183 | if cdevfile !~ '/dev/fd/' |
| 184 | let type = getftype(cdevfile) |
| 185 | " ignore empty result, can happen if the file disappeared |
| 186 | if type != '' |
| 187 | call assert_equal('cdev', type, 'for ' .. cdevfile) |
| 188 | endif |
Bram Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 189 | endif |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 190 | endfor |
| 191 | |
| 192 | for bdevfile in systemlist('find /dev -type b -maxdepth 2 2>/dev/null') |
Bram Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 193 | let type = getftype(bdevfile) |
| 194 | " ignore empty result, can happen if the file disappeared |
| 195 | if type != '' |
Bram Moolenaar | ad5db44 | 2019-08-30 13:12:25 +0200 | [diff] [blame] | 196 | call assert_equal('bdev', type, 'for ' .. bdevfile) |
Bram Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 197 | endif |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 198 | endfor |
| 199 | |
| 200 | " The /run/ directory typically contains socket files. |
| 201 | " If it does not, test won't fail but will not test socket files. |
| 202 | for socketfile in systemlist('find /run -type s -maxdepth 2 2>/dev/null') |
Bram Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 203 | let type = getftype(socketfile) |
| 204 | " ignore empty result, can happen if the file disappeared |
| 205 | if type != '' |
Bram Moolenaar | ad5db44 | 2019-08-30 13:12:25 +0200 | [diff] [blame] | 206 | call assert_equal('socket', type, 'for ' .. socketfile) |
Bram Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 207 | endif |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 208 | endfor |
| 209 | |
| 210 | " TODO: file type 'other' is not tested. How can we test it? |
| 211 | endfunc |
| 212 | |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 213 | func Test_win32_symlink_dir() |
| 214 | " On Windows, non-admin users cannot create symlinks. |
| 215 | " So we use an existing symlink for this test. |
Bram Moolenaar | 6d91bcb | 2020-08-12 18:50:36 +0200 | [diff] [blame] | 216 | CheckMSWindows |
| 217 | " Check if 'C:\Users\All Users' is a symlink to a directory. |
| 218 | let res = system('dir C:\Users /a') |
| 219 | if match(res, '\C<SYMLINKD> *All Users') >= 0 |
| 220 | " Get the filetype of the symlink. |
| 221 | call assert_equal('dir', getftype('C:\Users\All Users')) |
| 222 | else |
| 223 | throw 'Skipped: cannot find an existing symlink' |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 224 | endif |
| 225 | endfunc |
Bram Moolenaar | 6d91bcb | 2020-08-12 18:50:36 +0200 | [diff] [blame] | 226 | |
| 227 | " vim: shiftwidth=2 sts=2 expandtab |