Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 1 | " Tests for stat functions and checktime |
| 2 | |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 3 | func CheckFileTime(doSleep) |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 4 | let fnames = ['Xtest1.tmp', 'Xtest2.tmp', 'Xtest3.tmp'] |
| 5 | let times = [] |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 6 | let result = 0 |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 7 | |
Bram Moolenaar | 4b96df5 | 2020-01-26 22:00:26 +0100 | [diff] [blame] | 8 | " Use three files instead of localtim(), with a network filesystem the file |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 9 | " times may differ at bit |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 10 | let fl = ['Hello World!'] |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 11 | for fname in fnames |
| 12 | call writefile(fl, fname) |
Bram Moolenaar | 4c313b1 | 2019-08-24 22:58:31 +0200 | [diff] [blame] | 13 | call add(times, fname->getftime()) |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 14 | if a:doSleep |
| 15 | sleep 1 |
| 16 | endif |
| 17 | endfor |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 18 | |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 19 | let time_correct = (times[0] <= times[1] && times[1] <= times[2]) |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 20 | if a:doSleep || time_correct |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 21 | 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] | 22 | call assert_equal(strlen(fl[0] . "\n"), fnames[0]->getfsize()) |
| 23 | call assert_equal('file', fnames[0]->getftype()) |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 24 | call assert_equal('rw-', getfperm(fnames[0])[0:2]) |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 25 | let result = 1 |
| 26 | endif |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 27 | |
Bram Moolenaar | addc156 | 2018-11-18 12:25:09 +0100 | [diff] [blame] | 28 | for fname in fnames |
| 29 | call delete(fname) |
| 30 | endfor |
Bram Moolenaar | 82de3c2 | 2017-08-17 17:35:36 +0200 | [diff] [blame] | 31 | return result |
| 32 | endfunc |
| 33 | |
| 34 | func 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 Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 41 | endfunc |
| 42 | |
| 43 | func Test_existent_directory() |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 44 | let dname = '.' |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 45 | |
| 46 | call assert_equal(0, getfsize(dname)) |
| 47 | call assert_equal('dir', getftype(dname)) |
| 48 | call assert_equal('rwx', getfperm(dname)[0:2]) |
| 49 | endfunc |
| 50 | |
Bram Moolenaar | 386bc82 | 2018-07-07 18:34:12 +0200 | [diff] [blame] | 51 | func 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 |
| 58 | endfunc |
| 59 | |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 60 | func Test_checktime() |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 61 | let fname = 'Xtest.tmp' |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 62 | |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 63 | let fl = ['Hello World!'] |
Bram Moolenaar | 5656496 | 2022-10-10 22:39:42 +0100 | [diff] [blame] | 64 | call writefile(fl, fname, 'D') |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 65 | set autoread |
| 66 | exec 'e' fname |
Bram Moolenaar | 386bc82 | 2018-07-07 18:34:12 +0200 | [diff] [blame] | 67 | call SleepForTimestamp() |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 68 | let fl = readfile(fname) |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 69 | let fl[0] .= ' - checktime' |
| 70 | call writefile(fl, fname) |
| 71 | checktime |
| 72 | call assert_equal(fl[0], getline(1)) |
| 73 | endfunc |
| 74 | |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 75 | func Test_checktime_fast() |
| 76 | CheckFeature nanotime |
| 77 | |
| 78 | let fname = 'Xtest.tmp' |
| 79 | |
| 80 | let fl = ['Hello World!'] |
Bram Moolenaar | 5656496 | 2022-10-10 22:39:42 +0100 | [diff] [blame] | 81 | call writefile(fl, fname, 'D') |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 82 | 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 Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 89 | endfunc |
| 90 | |
| 91 | func Test_autoread_fast() |
| 92 | CheckFeature nanotime |
| 93 | |
Bram Moolenaar | eaa006d | 2021-10-15 17:09:50 +0100 | [diff] [blame] | 94 | " this is timing sensitive |
| 95 | let g:test_is_flaky = 1 |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 96 | |
Bram Moolenaar | eaa006d | 2021-10-15 17:09:50 +0100 | [diff] [blame] | 97 | new Xautoread |
| 98 | setlocal autoread |
| 99 | call setline(1, 'foo') |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 100 | w! |
Bram Moolenaar | 944eeb4 | 2021-10-18 14:37:13 +0100 | [diff] [blame] | 101 | sleep 10m |
Bram Moolenaar | 5656496 | 2022-10-10 22:39:42 +0100 | [diff] [blame] | 102 | call writefile(['bar'], 'Xautoread', 'D') |
Bram Moolenaar | accf4ed | 2021-10-15 00:38:02 +0100 | [diff] [blame] | 103 | sleep 10m |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 104 | checktime |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 105 | call assert_equal('bar', trim(getline(1))) |
Leah Neukirchen | 0a7984a | 2021-10-14 21:27:55 +0100 | [diff] [blame] | 106 | endfunc |
| 107 | |
Bram Moolenaar | 386bc82 | 2018-07-07 18:34:12 +0200 | [diff] [blame] | 108 | func 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! |
| 145 | endfunc |
| 146 | |
| 147 | |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 148 | func Test_nonexistent_file() |
Bram Moolenaar | a2f2885 | 2017-02-01 22:05:28 +0100 | [diff] [blame] | 149 | let fname = 'Xtest.tmp' |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 150 | |
| 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)) |
| 156 | endfunc |
| 157 | |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 158 | func 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 Moolenaar | b18b496 | 2022-09-02 21:55:50 +0100 | [diff] [blame] | 166 | silent !ln -s Xlinkfile Xlink |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 167 | 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 Moolenaar | ad5db44 | 2019-08-30 13:12:25 +0200 | [diff] [blame] | 177 | " 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 Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 184 | endif |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 185 | endfor |
| 186 | |
| 187 | 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] | 188 | let type = getftype(bdevfile) |
| 189 | " ignore empty result, can happen if the file disappeared |
| 190 | if type != '' |
Bram Moolenaar | ad5db44 | 2019-08-30 13:12:25 +0200 | [diff] [blame] | 191 | call assert_equal('bdev', type, 'for ' .. bdevfile) |
Bram Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 192 | endif |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 193 | 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 Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 198 | let type = getftype(socketfile) |
| 199 | " ignore empty result, can happen if the file disappeared |
| 200 | if type != '' |
Bram Moolenaar | ad5db44 | 2019-08-30 13:12:25 +0200 | [diff] [blame] | 201 | call assert_equal('socket', type, 'for ' .. socketfile) |
Bram Moolenaar | 3b3a506 | 2018-08-22 20:16:16 +0200 | [diff] [blame] | 202 | endif |
Bram Moolenaar | 1598f99 | 2018-08-09 22:08:57 +0200 | [diff] [blame] | 203 | endfor |
| 204 | |
| 205 | " TODO: file type 'other' is not tested. How can we test it? |
| 206 | endfunc |
| 207 | |
Bram Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 208 | func Test_win32_symlink_dir() |
| 209 | " On Windows, non-admin users cannot create symlinks. |
| 210 | " So we use an existing symlink for this test. |
Bram Moolenaar | 6d91bcb | 2020-08-12 18:50:36 +0200 | [diff] [blame] | 211 | 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 Moolenaar | 8767f52 | 2016-07-01 17:17:39 +0200 | [diff] [blame] | 219 | endif |
| 220 | endfunc |
Bram Moolenaar | 6d91bcb | 2020-08-12 18:50:36 +0200 | [diff] [blame] | 221 | |
| 222 | " vim: shiftwidth=2 sts=2 expandtab |