gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/syscall.test (about) 1 # 2011 March 29 2 # 3 # The author disclaims copyright to this source code. In place of 4 # a legal notice, here is a blessing: 5 # 6 # May you do good and not evil. 7 # May you find forgiveness for yourself and forgive others. 8 # May you share freely, never taking more than you give. 9 # 10 #*********************************************************************** 11 # 12 13 set testdir [file dirname $argv0] 14 source $testdir/tester.tcl 15 source $testdir/lock_common.tcl 16 source $testdir/malloc_common.tcl 17 18 if {[llength [info commands test_syscall]]==0} { 19 finish_test 20 return 21 } 22 23 if {[test_syscall defaultvfs] != "unix"} { 24 finish_test 25 return 26 } 27 set testprefix syscall 28 29 #------------------------------------------------------------------------- 30 # Tests for the xSetSystemCall method. 31 # 32 do_test 1.1.1 { 33 list [catch { test_syscall reset open } msg] $msg 34 } {0 {}} 35 do_test 1.1.2 { 36 list [catch { test_syscall reset nosuchcall } msg] $msg 37 } {1 SQLITE_NOTFOUND} 38 do_test 1.1.3 { 39 list [catch { test_syscall reset open } msg] $msg 40 } {0 {}} 41 do_test 1.1.4 { 42 list [catch { test_syscall reset ""} msg] $msg 43 } {1 SQLITE_NOTFOUND} 44 45 do_test 1.2 { test_syscall reset } {} 46 47 do_test 1.3.1 { test_syscall install {open getcwd access} } {} 48 do_test 1.3.2 { test_syscall reset } {} 49 50 #------------------------------------------------------------------------- 51 # Tests for the xGetSystemCall method. 52 # 53 do_test 2.1.1 { test_syscall exists open } 1 54 do_test 2.1.2 { test_syscall exists nosuchcall } 0 55 56 #------------------------------------------------------------------------- 57 # Tests for the xNextSystemCall method. 58 # 59 foreach s { 60 open close access getcwd stat fstat ftruncate 61 fcntl read pread write pwrite fchmod fallocate 62 pread64 pwrite64 unlink openDirectory mkdir rmdir 63 statvfs fchown geteuid umask mmap munmap mremap 64 getpagesize readlink lstat ioctl 65 } { 66 if {[test_syscall exists $s]} {lappend syscall_list $s} 67 } 68 do_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list] 69 70 #------------------------------------------------------------------------- 71 # This test verifies that if a call to open() fails and errno is set to 72 # EINTR, the call is retried. If it succeeds, execution continues as if 73 # nothing happened. 74 # 75 test_syscall reset 76 forcedelete test.db2 77 do_execsql_test 4.1 { 78 CREATE TABLE t1(x, y); 79 INSERT INTO t1 VALUES(1, 2); 80 ATTACH 'test.db2' AS aux; 81 CREATE TABLE aux.t2(x, y); 82 INSERT INTO t2 VALUES(3, 4); 83 } 84 85 db_save_and_close 86 test_syscall install open 87 foreach jrnl [list wal delete] { 88 for {set i 1} {$i < 20} {incr i} { 89 db_restore_and_reopen 90 test_syscall fault $i 0 91 test_syscall errno open EINTR 92 93 do_test 4.2.$jrnl.$i { 94 sqlite3 db test.db 95 execsql { ATTACH 'test.db2' AS aux } 96 execsql "PRAGMA main.journal_mode = $jrnl" 97 execsql "PRAGMA aux.journal_mode = $jrnl" 98 execsql { 99 BEGIN; 100 INSERT INTO t1 VALUES(5, 6); 101 INSERT INTO t2 VALUES(7, 8); 102 COMMIT; 103 } 104 105 db close 106 sqlite3 db test.db 107 execsql { ATTACH 'test.db2' AS aux } 108 execsql { 109 SELECT * FROM t1; 110 SELECT * FROM t2; 111 } 112 } {1 2 5 6 3 4 7 8} 113 } 114 } 115 116 #------------------------------------------------------------------------- 117 # This test verifies that closing database handles does not drop locks 118 # held by other database handles in the same process on the same file. 119 # 120 # The os_unix.c module has to take precautions to prevent this as the 121 # close() system call drops locks held by other file-descriptors on the 122 # same file. From the Linux man page: 123 # 124 # close() closes a file descriptor, so that it no longer refers to any file 125 # and may be reused. Any record locks (see fcntl(2)) held on the file it 126 # was associated with, and owned by the process, are removed (regardless 127 # of the file descriptor that was used to obtain the lock). 128 # 129 catch { db close } 130 forcedelete test.db test.db2 131 132 do_multiclient_test tn { 133 code1 { 134 sqlite3 dbX1 test.db 135 sqlite3 dbX2 test.db 136 } 137 138 do_test syscall-5.$tn.1 { 139 sql1 { 140 CREATE TABLE t1(a, b); 141 INSERT INTO t1 VALUES(1, 2); 142 BEGIN; 143 INSERT INTO t1 VALUES(3, 4); 144 } 145 } {} 146 147 do_test syscall-5.$tn.2 { sql2 { SELECT * FROM t1 } } {1 2} 148 do_test syscall-5.$tn.3 { 149 csql2 { INSERT INTO t1 VALUES(5, 6) } 150 } {1 {database is locked}} 151 152 do_test syscall-5.$tn.4 { 153 code1 { 154 dbX1 close 155 dbX2 close 156 } 157 } {} 158 159 do_test syscall-5.$tn.5 { 160 csql2 { INSERT INTO t1 VALUES(5, 6) } 161 } {1 {database is locked}} 162 163 do_test syscall-5.$tn.6 { sql1 { COMMIT } } {} 164 165 do_test syscall-5.$tn.7 { 166 csql2 { INSERT INTO t1 VALUES(5, 6) } 167 } {0 {}} 168 } 169 170 catch {db close} 171 do_test 6.1 { 172 sqlite3 db1 test.db1 173 sqlite3 db2 test.db2 174 sqlite3 db3 test.db3 175 sqlite3 dbM "" 176 177 db2 close 178 db3 close 179 dbM close 180 db1 close 181 } {} 182 183 do_test 6.2 { 184 sqlite3 db test.db 185 execsql { 186 PRAGMA temp_store = file; 187 188 PRAGMA main.cache_size = 10; 189 PRAGMA temp.cache_size = 10; 190 CREATE TABLE temp.tt(a, b); 191 INSERT INTO tt VALUES(randomblob(500), randomblob(600)); 192 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 193 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 194 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 195 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 196 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 197 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 198 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 199 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 200 } 201 202 db close 203 } {} 204 205 #------------------------------------------------------------------------- 206 # Test that a database file a single byte in size is treated as an empty 207 # file. Whereas a file 2 bytes or larger might be considered corrupt. 208 # 209 catch { db close } 210 forcedelete test.db test.db2 211 212 proc create_db_file {nByte} { 213 set fd [open test.db w] 214 fconfigure $fd -translation binary -encoding binary 215 puts -nonewline $fd [string range "xSQLite" 1 $nByte] 216 close $fd 217 } 218 219 foreach {nByte res} { 220 1 {0 {}} 221 2 {1 {file is not a database}} 222 3 {1 {file is not a database}} 223 } { 224 do_test 7.$nByte { 225 create_db_file $nByte 226 list [catch { 227 sqlite3 db test.db 228 execsql { CREATE TABLE t1(a, b) } 229 } msg] $msg 230 } $res 231 catch { db close } 232 } 233 234 #------------------------------------------------------------------------- 235 # 236 catch { db close } 237 forcedelete test.db test.db2 238 239 do_test 8.1 { 240 sqlite3 db test.db 241 file_control_chunksize_test db main 4096 242 file size test.db 243 } {0} 244 foreach {tn hint size} { 245 1 1000 4096 246 2 1000 4096 247 3 3000 4096 248 4 4096 4096 249 5 4197 8192 250 } { 251 do_test 8.2.$tn { 252 file_control_sizehint_test db main $hint 253 file size test.db 254 } $size 255 } 256 257 do_test 8.3 { 258 db close 259 forcedelete test.db test.db2 260 sqlite3 db test.db 261 file_control_chunksize_test db main 16 262 file size test.db 263 } {0} 264 foreach {tn hint size} { 265 1 5 16 266 2 13 16 267 3 45 48 268 4 48 48 269 5 49 64 270 } { 271 do_test 8.4.$tn { 272 file_control_sizehint_test db main $hint 273 file size test.db 274 } $size 275 } 276 277 test_syscall reset 278 finish_test