| # 2014-05-07 |
| # |
| # The author disclaims copyright to this source code. In place of |
| # a legal notice, here is a blessing: |
| # |
| # May you do good and not evil. |
| # May you find forgiveness for yourself and forgive others. |
| # May you share freely, never taking more than you give. |
| # |
| #*********************************************************************** |
| # |
| # This file implements regression tests for SQLite library. The |
| # focus of this file is testing the nolock=1 and immutable=1 query |
| # parameters and the SQLITE_IOCAP_IMMUTABLE device characteristic. |
| # |
| |
| set testdir [file dirname $argv0] |
| source $testdir/tester.tcl |
| |
| unset -nocomplain tvfs_calls |
| proc tvfs_reset {} { |
| global tvfs_calls |
| array set tvfs_calls {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} |
| } |
| proc tvfs_callback {op args} { |
| global tvfs_calls |
| incr tvfs_calls($op) |
| return SQLITE_OK |
| } |
| tvfs_reset |
| |
| testvfs tvfs |
| tvfs script tvfs_callback |
| tvfs filter {xLock xUnlock xCheckReservedLock xAccess} |
| |
| ############################################################################ |
| # Verify that the nolock=1 query parameter for URI filenames disables all |
| # calls to xLock and xUnlock for rollback databases. |
| # |
| do_test nolock-1.0 { |
| db close |
| forcedelete test.db |
| tvfs_reset |
| sqlite db test.db -vfs tvfs |
| db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);} |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) |
| } {xLock 7 xUnlock 5 xCheckReservedLock 0} |
| |
| do_test nolock-1.1 { |
| db close |
| forcedelete test.db |
| tvfs_reset |
| sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1 |
| db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);} |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) |
| } {xLock 7 xUnlock 5 xCheckReservedLock 0} |
| |
| do_test nolock-1.2 { |
| db close |
| forcedelete test.db |
| tvfs_reset |
| sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1 |
| db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);} |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) |
| } {xLock 0 xUnlock 0 xCheckReservedLock 0} |
| |
| do_test nolock-1.3 { |
| db close |
| tvfs_reset |
| sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1 -readonly 1 |
| db eval {SELECT * FROM t1} |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) |
| } {xLock 2 xUnlock 2 xCheckReservedLock 0} |
| |
| do_test nolock-1.4 { |
| db close |
| tvfs_reset |
| sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1 -readonly 1 |
| db eval {SELECT * FROM t1} |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) |
| } {xLock 0 xUnlock 0 xCheckReservedLock 0} |
| |
| ############################################################################# |
| # Verify that immutable=1 disables both locking and xAccess calls to the |
| # journal files. |
| # |
| do_test nolock-2.0 { |
| db close |
| forcedelete test.db |
| # begin by creating a test database |
| sqlite3 db test.db |
| db eval { |
| CREATE TABLE t1(a,b); |
| INSERT INTO t1 VALUES('hello','world'); |
| CREATE TABLE t2(x,y); |
| INSERT INTO t2 VALUES(12345,67890); |
| SELECT * FROM t1, t2; |
| } |
| } {hello world 12345 67890} |
| do_test nolock-2.1 { |
| tvfs_reset |
| sqlite3 db2 test.db -vfs tvfs |
| db2 eval {SELECT * FROM t1, t2} |
| } {hello world 12345 67890} |
| do_test nolock-2.2 { |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ |
| xAccess $::tvfs_calls(xAccess) |
| } {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4} |
| |
| |
| do_test nolock-2.11 { |
| db2 close |
| tvfs_reset |
| sqlite3 db2 file:test.db?immutable=0 -vfs tvfs -uri 1 |
| db2 eval {SELECT * FROM t1, t2} |
| } {hello world 12345 67890} |
| do_test nolock-2.12 { |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ |
| xAccess $::tvfs_calls(xAccess) |
| } {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4} |
| |
| |
| do_test nolock-2.21 { |
| db2 close |
| tvfs_reset |
| sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1 |
| db2 eval {SELECT * FROM t1, t2} |
| } {hello world 12345 67890} |
| do_test nolock-2.22 { |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ |
| xAccess $::tvfs_calls(xAccess) |
| } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} |
| |
| do_test nolock-2.31 { |
| db2 close |
| tvfs_reset |
| sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1 -readonly 1 |
| db2 eval {SELECT * FROM t1, t2} |
| } {hello world 12345 67890} |
| do_test nolock-2.32 { |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ |
| xAccess $::tvfs_calls(xAccess) |
| } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} |
| |
| ############################################################################ |
| # Verify that the SQLITE_IOCAP_IMMUTABLE flag works |
| # |
| do_test nolock-3.1 { |
| db2 close |
| tvfs devchar immutable |
| tvfs_reset |
| sqlite3 db2 test.db -vfs tvfs |
| db2 eval {SELECT * FROM t1, t2} |
| } {hello world 12345 67890} |
| do_test nolock-3.2 { |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ |
| xAccess $::tvfs_calls(xAccess) |
| } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} |
| |
| do_test nolock-3.11 { |
| db2 close |
| tvfs_reset |
| sqlite3 db2 test.db -vfs tvfs -readonly 1 |
| db2 eval {SELECT * FROM t1, t2} |
| } {hello world 12345 67890} |
| do_test nolock-3.12 { |
| list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \ |
| xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \ |
| xAccess $::tvfs_calls(xAccess) |
| } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} |
| |
| db2 close |
| db close |
| tvfs delete |
| |
| if {[permutation]!="inmemory_journal"} { |
| # 2016-03-11: Make sure all works when transitioning to WAL mode |
| # under nolock. |
| # |
| do_test nolock-4.1 { |
| forcedelete test.db |
| sqlite3 db file:test.db?nolock=1 -uri 1 |
| db eval { |
| PRAGMA journal_mode=WAL; |
| CREATE TABLE t1(x); |
| INSERT INTO t1 VALUES('youngling'); |
| SELECT * FROM t1; |
| } |
| } {delete youngling} |
| db close |
| |
| do_test nolock-4.2 { |
| forcedelete test.db |
| sqlite3 db test.db |
| db eval { |
| PRAGMA journal_mode=WAL; |
| CREATE TABLE t1(x); |
| INSERT INTO t1 VALUES('catbird'); |
| SELECT * FROM t1; |
| } |
| } {wal catbird} |
| do_test nolock-4.3 { |
| db close |
| sqlite3 db file:test.db?nolock=1 -uri 1 |
| set rc [catch {db eval {SELECT * FROM t1}} msg] |
| lappend rc $msg |
| } {1 {unable to open database file}} |
| } |
| |
| finish_test |