1# 2014-05-07 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# This file implements regression tests for SQLite library. The 13# focus of this file is testing the nolock=1 and immutable=1 query 14# parameters and the SQLITE_IOCAP_IMMUTABLE device characteristic. 15# 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20unset -nocomplain tvfs_calls 21proc tvfs_reset {} { 22 global tvfs_calls 23 array set tvfs_calls {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} 24} 25proc tvfs_callback {op args} { 26 global tvfs_calls 27 incr tvfs_calls($op) 28 return SQLITE_OK 29} 30tvfs_reset 31 32testvfs tvfs 33tvfs script tvfs_callback 34tvfs filter {xLock xUnlock xCheckReservedLock xAccess} 35 36############################################################################ 37# Verify that the nolock=1 query parameter for URI filenames disables all 38# calls to xLock and xUnlock for rollback databases. 39# 40do_test nolock-1.0 { 41 db close 42 forcedelete test.db 43 tvfs_reset 44 sqlite db test.db -vfs tvfs 45 db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);} 46 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 47 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) 48} {xLock 7 xUnlock 5 xCheckReservedLock 0} 49 50do_test nolock-1.1 { 51 db close 52 forcedelete test.db 53 tvfs_reset 54 sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1 55 db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);} 56 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 57 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) 58} {xLock 7 xUnlock 5 xCheckReservedLock 0} 59 60do_test nolock-1.2 { 61 db close 62 forcedelete test.db 63 tvfs_reset 64 sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1 65 db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);} 66 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 67 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) 68} {xLock 0 xUnlock 0 xCheckReservedLock 0} 69 70do_test nolock-1.3 { 71 db close 72 tvfs_reset 73 sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1 -readonly 1 74 db eval {SELECT * FROM t1} 75 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 76 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) 77} {xLock 2 xUnlock 2 xCheckReservedLock 0} 78 79do_test nolock-1.4 { 80 db close 81 tvfs_reset 82 sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1 -readonly 1 83 db eval {SELECT * FROM t1} 84 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 85 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) 86} {xLock 0 xUnlock 0 xCheckReservedLock 0} 87 88############################################################################# 89# Verify that immutable=1 disables both locking and xAccess calls to the 90# journal files. 91# 92do_test nolock-2.0 { 93 db close 94 forcedelete test.db 95 # begin by creating a test database 96 sqlite3 db test.db 97 db eval { 98 CREATE TABLE t1(a,b); 99 INSERT INTO t1 VALUES('hello','world'); 100 CREATE TABLE t2(x,y); 101 INSERT INTO t2 VALUES(12345,67890); 102 SELECT * FROM t1, t2; 103 } 104} {hello world 12345 67890} 105do_test nolock-2.1 { 106 tvfs_reset 107 sqlite3 db2 test.db -vfs tvfs 108 db2 eval {SELECT * FROM t1, t2} 109} {hello world 12345 67890} 110do_test nolock-2.2 { 111 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 112 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ 113 xAccess $::tvfs_calls(xAccess) 114} {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4} 115 116 117do_test nolock-2.11 { 118 db2 close 119 tvfs_reset 120 sqlite3 db2 file:test.db?immutable=0 -vfs tvfs -uri 1 121 db2 eval {SELECT * FROM t1, t2} 122} {hello world 12345 67890} 123do_test nolock-2.12 { 124 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 125 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ 126 xAccess $::tvfs_calls(xAccess) 127} {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4} 128 129 130do_test nolock-2.21 { 131 db2 close 132 tvfs_reset 133 sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1 134 db2 eval {SELECT * FROM t1, t2} 135} {hello world 12345 67890} 136do_test nolock-2.22 { 137 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 138 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ 139 xAccess $::tvfs_calls(xAccess) 140} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} 141 142do_test nolock-2.31 { 143 db2 close 144 tvfs_reset 145 sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1 -readonly 1 146 db2 eval {SELECT * FROM t1, t2} 147} {hello world 12345 67890} 148do_test nolock-2.32 { 149 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 150 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ 151 xAccess $::tvfs_calls(xAccess) 152} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} 153 154############################################################################ 155# Verify that the SQLITE_IOCAP_IMMUTABLE flag works 156# 157do_test nolock-3.1 { 158 db2 close 159 tvfs devchar immutable 160 tvfs_reset 161 sqlite3 db2 test.db -vfs tvfs 162 db2 eval {SELECT * FROM t1, t2} 163} {hello world 12345 67890} 164do_test nolock-3.2 { 165 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 166 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ 167 xAccess $::tvfs_calls(xAccess) 168} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} 169 170do_test nolock-3.11 { 171 db2 close 172 tvfs_reset 173 sqlite3 db2 test.db -vfs tvfs -readonly 1 174 db2 eval {SELECT * FROM t1, t2} 175} {hello world 12345 67890} 176do_test nolock-3.12 { 177 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ 178 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ 179 xAccess $::tvfs_calls(xAccess) 180} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} 181 182db2 close 183db close 184tvfs delete 185 186if {[permutation]!="inmemory_journal"} { 187 # 2016-03-11: Make sure all works when transitioning to WAL mode 188 # under nolock. 189 # 190 do_test nolock-4.1 { 191 forcedelete test.db 192 sqlite3 db file:test.db?nolock=1 -uri 1 193 db eval { 194 PRAGMA journal_mode=WAL; 195 CREATE TABLE t1(x); 196 INSERT INTO t1 VALUES('youngling'); 197 SELECT * FROM t1; 198 } 199 } {delete youngling} 200 db close 201 202 do_test nolock-4.2 { 203 forcedelete test.db 204 sqlite3 db test.db 205 db eval { 206 PRAGMA journal_mode=WAL; 207 CREATE TABLE t1(x); 208 INSERT INTO t1 VALUES('catbird'); 209 SELECT * FROM t1; 210 } 211 } {wal catbird} 212 do_test nolock-4.3 { 213 db close 214 sqlite3 db file:test.db?nolock=1 -uri 1 215 set rc [catch {db eval {SELECT * FROM t1}} msg] 216 lappend rc $msg 217 } {1 {unable to open database file}} 218} 219 220finish_test 221