| OLD | NEW |
| (Empty) |
| 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 | |
| 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 encrypted or is not a database}} | |
| 222 3 {1 {file is encrypted or 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 | |
| OLD | NEW |