diff options
Diffstat (limited to '')
-rw-r--r-- | test/walmode.test | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/test/walmode.test b/test/walmode.test new file mode 100644 index 0000000..f760823 --- /dev/null +++ b/test/walmode.test @@ -0,0 +1,393 @@ +# 2010 April 19 +# +# 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 operation of the library in +# "PRAGMA journal_mode=WAL" mode. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl + +# If the library was compiled without WAL support, check that the +# "PRAGMA journal_mode=WAL" treats "WAL" as an unrecognized mode. +# +ifcapable !wal { + + do_test walmode-0.1 { + execsql { PRAGMA journal_mode = wal } + } {delete} + do_test walmode-0.2 { + execsql { PRAGMA main.journal_mode = wal } + } {delete} + do_test walmode-0.3 { + execsql { PRAGMA main.journal_mode } + } {delete} + + finish_test + return +} + +do_test walmode-1.1 { + set sqlite_sync_count 0 + execsql { PRAGMA page_size = 1024 } + execsql { PRAGMA journal_mode = wal } +} {wal} +do_test walmode-1.2 { + file size test.db +} {1024} + +if {[atomic_batch_write test.db]==0} { + set expected_sync_count 3 + if {$::tcl_platform(platform)!="windows"} { + ifcapable dirsync { + incr expected_sync_count + } + } + do_test walmode-1.3 { + set sqlite_sync_count + } $expected_sync_count +} + +do_test walmode-1.4 { + file exists test.db-wal +} {0} +do_test walmode-1.5 { + execsql { CREATE TABLE t1(a, b) } + file size test.db +} {1024} +do_test walmode-1.6 { + file exists test.db-wal +} {1} +do_test walmode-1.7 { + db close + file exists test.db-wal +} {0} + +# There is now a database file with the read and write versions set to 2 +# in the file system. This file should default to WAL mode. +# +do_test walmode-2.1 { + sqlite3 db test.db + file exists test.db-wal +} {0} +do_test walmode-2.2 { + execsql { SELECT * FROM sqlite_master } + file exists test.db-wal +} {1} +do_test walmode-2.3 { + db close + file exists test.db-wal +} {0} + +# If the first statement executed is "PRAGMA journal_mode = wal", and +# the file is already configured for WAL (read and write versions set +# to 2), then there should be no need to write the database. The +# statement should cause the client to connect to the log file. +# +set sqlite_sync_count 0 +do_test walmode-3.1 { + sqlite3 db test.db + execsql { PRAGMA journal_mode = wal } +} {wal} +do_test walmode-3.2 { + list $sqlite_sync_count [file exists test.db-wal] [file size test.db-wal] +} {0 1 0} + +# Test that changing back to journal_mode=persist works. +# +do_test walmode-4.1 { + execsql { INSERT INTO t1 VALUES(1, 2) } + execsql { PRAGMA journal_mode = persist } +} {persist} +if {[atomic_batch_write test.db]==0} { + do_test walmode-4.2 { + list [file exists test.db-journal] [file exists test.db-wal] + } {1 0} +} +do_test walmode-4.3 { + execsql { SELECT * FROM t1 } +} {1 2} +do_test walmode-4.4 { + db close + sqlite3 db test.db + execsql { SELECT * FROM t1 } +} {1 2} +if {[atomic_batch_write test.db]==0} { + do_test walmode-4.5 { + list [file exists test.db-journal] [file exists test.db-wal] + } {1 0} +} + +# Test that nothing goes wrong if a connection is prevented from changing +# from WAL to rollback mode because a second connection has the database +# open. Or from rollback to WAL. +# +do_test walmode-4.6 { + sqlite3 db2 test.db + execsql { PRAGMA main.journal_mode } db2 +} {delete} +do_test walmode-4.7 { + execsql { PRAGMA main.journal_mode = wal } db +} {wal} +do_test walmode-4.8 { + execsql { SELECT * FROM t1 } db2 +} {1 2} +do_test walmode-4.9 { + catchsql { PRAGMA journal_mode = delete } db +} {1 {database is locked}} +do_test walmode-4.10 { + execsql { PRAGMA main.journal_mode } db +} {wal} + +do_test walmode-4.11 { + db2 close + execsql { PRAGMA journal_mode = delete } db +} {delete} +do_test walmode-4.12 { + execsql { PRAGMA main.journal_mode } db +} {delete} +do_test walmode-4.13 { + list [file exists test.db-journal] [file exists test.db-wal] +} {0 0} +do_test walmode-4.14 { + sqlite3 db2 test.db + execsql { + BEGIN; + SELECT * FROM t1; + } db2 +} {1 2} + +do_test walmode-4.16 { execsql { PRAGMA main.journal_mode } db } {delete} +do_test walmode-4.17 { execsql { PRAGMA main.journal_mode } db2 } {delete} + +do_test walmode-4.17 { + catchsql { PRAGMA main.journal_mode = wal } db +} {1 {database is locked}} +do_test walmode-4.18 { + execsql { PRAGMA main.journal_mode } db +} {delete} +catch { db close } +catch { db2 close } + +# Test that it is not possible to change a temporary or in-memory database +# to WAL mode. WAL mode is for persistent file-backed databases only. +# +# walmode-5.1.*: Try to set journal_mode=WAL on [sqlite3 db :memory:] database. +# walmode-5.2.*: Try to set journal_mode=WAL on [sqlite3 db ""] database. +# walmode-5.3.*: Try to set temp.journal_mode=WAL. +# +do_test walmode-5.1.1 { + sqlite3 db :memory: + execsql { PRAGMA main.journal_mode } +} {memory} +do_test walmode-5.1.2 { + execsql { PRAGMA main.journal_mode = wal } +} {memory} +do_test walmode-5.1.3 { + execsql { + BEGIN; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + COMMIT; + SELECT * FROM t1; + PRAGMA main.journal_mode; + } +} {1 2 memory} +do_test walmode-5.1.4 { + execsql { PRAGMA main.journal_mode = wal } +} {memory} +do_test walmode-5.1.5 { + execsql { + INSERT INTO t1 VALUES(3, 4); + SELECT * FROM t1; + PRAGMA main.journal_mode; + } +} {1 2 3 4 memory} + +if {$TEMP_STORE>=2} { + set tempJrnlMode memory +} else { + set tempJrnlMode delete +} +do_test walmode-5.2.1 { + sqlite3 db "" + execsql { PRAGMA main.journal_mode } +} $tempJrnlMode +do_test walmode-5.2.2 { + execsql { PRAGMA main.journal_mode = wal } +} $tempJrnlMode +do_test walmode-5.2.3 { + execsql { + BEGIN; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + COMMIT; + SELECT * FROM t1; + PRAGMA main.journal_mode; + } +} [list 1 2 $tempJrnlMode] +do_test walmode-5.2.4 { + execsql { PRAGMA main.journal_mode = wal } +} $tempJrnlMode +do_test walmode-5.2.5 { + execsql { + INSERT INTO t1 VALUES(3, 4); + SELECT * FROM t1; + PRAGMA main.journal_mode; + } +} [list 1 2 3 4 $tempJrnlMode] + +do_test walmode-5.3.1 { + sqlite3 db test.db + execsql { PRAGMA temp.journal_mode } +} $tempJrnlMode +do_test walmode-5.3.2 { + execsql { PRAGMA temp.journal_mode = wal } +} $tempJrnlMode +do_test walmode-5.3.3 { + execsql { + BEGIN; + CREATE TEMP TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + COMMIT; + SELECT * FROM t1; + PRAGMA temp.journal_mode; + } +} [list 1 2 $tempJrnlMode] +do_test walmode-5.3.4 { + execsql { PRAGMA temp.journal_mode = wal } +} $tempJrnlMode +do_test walmode-5.3.5 { + execsql { + INSERT INTO t1 VALUES(3, 4); + SELECT * FROM t1; + PRAGMA temp.journal_mode; + } +} [list 1 2 3 4 $tempJrnlMode] + + +#------------------------------------------------------------------------- +# Test changing to WAL mode from journal_mode=off or journal_mode=memory +# +foreach {tn mode} { + 1 off + 2 memory + 3 persist + 4 delete + 5 truncate +} { + do_test walmode-6.$tn { + faultsim_delete_and_reopen + execsql " + PRAGMA journal_mode = $mode; + PRAGMA journal_mode = wal; + " + } [list $mode wal] +} +db close + +#------------------------------------------------------------------------- +# Test the effect of a "PRAGMA journal_mode" command being the first +# thing executed by a new connection. This means that the schema is not +# loaded when sqlite3_prepare_v2() is called to compile the statement. +# +do_test walmode-7.0 { + forcedelete test.db + sqlite3 db test.db + execsql { + PRAGMA journal_mode = WAL; + CREATE TABLE t1(a, b); + } +} {wal} +foreach {tn sql result} { + 1 "PRAGMA journal_mode" wal + 2 "PRAGMA main.journal_mode" wal + 3 "PRAGMA journal_mode = delete" delete + 4 "PRAGMA journal_mode" delete + 5 "PRAGMA main.journal_mode" delete + 6 "PRAGMA journal_mode = wal" wal + 7 "PRAGMA journal_mode" wal + 8 "PRAGMA main.journal_mode" wal + + 9 "PRAGMA journal_mode" wal + 10 "PRAGMA main.journal_mode" wal + 11 "PRAGMA main.journal_mode = delete" delete + 12 "PRAGMA journal_mode" delete + 13 "PRAGMA main.journal_mode" delete + 14 "PRAGMA main.journal_mode = wal" wal + 15 "PRAGMA journal_mode" wal + 16 "PRAGMA main.journal_mode" wal +} { + do_test walmode-7.$tn { + db close + sqlite3 db test.db + execsql $sql + } $result +} +db close + +#------------------------------------------------------------------------- +# Test the effect of a "PRAGMA journal_mode" command on an attached +# database. +# +faultsim_delete_and_reopen +do_execsql_test walmode-8.1 { + CREATE TABLE t1(a, b); + PRAGMA journal_mode = WAL; + ATTACH 'test.db2' AS two; + CREATE TABLE two.t2(a, b); +} {wal} +do_execsql_test walmode-8.2 { PRAGMA main.journal_mode } {wal} +do_execsql_test walmode-8.3 { PRAGMA two.journal_mode } {delete} +do_execsql_test walmode-8.4 { PRAGMA two.journal_mode = DELETE } {delete} + +db close +sqlite3 db test.db +do_execsql_test walmode-8.5 { ATTACH 'test.db2' AS two } {} +do_execsql_test walmode-8.6 { PRAGMA main.journal_mode } {wal} +do_execsql_test walmode-8.7 { PRAGMA two.journal_mode } {delete} +do_execsql_test walmode-8.8 { INSERT INTO two.t2 DEFAULT VALUES } {} +do_execsql_test walmode-8.9 { PRAGMA two.journal_mode } {delete} +do_execsql_test walmode-8.10 { INSERT INTO t1 DEFAULT VALUES } {} +do_execsql_test walmode-8.11 { PRAGMA main.journal_mode } {wal} +do_execsql_test walmode-8.12 { PRAGMA journal_mode } {wal} + +# Change to WAL mode on test2.db and make sure (in the tests that follow) +# that this mode change persists. +do_test walmode-8.x1 { + execsql { + PRAGMA two.journal_mode=WAL; + PRAGMA two.journal_mode; + } +} {wal wal} + +db close +sqlite3 db test.db +do_execsql_test walmode-8.13 { PRAGMA journal_mode = WAL } {wal} +do_execsql_test walmode-8.14 { ATTACH 'test.db2' AS two } {} +do_execsql_test walmode-8.15 { PRAGMA main.journal_mode } {wal} +do_execsql_test walmode-8.16 { PRAGMA two.journal_mode } {wal} +do_execsql_test walmode-8.17 { INSERT INTO two.t2 DEFAULT VALUES } {} +do_execsql_test walmode-8.18 { PRAGMA two.journal_mode } {wal} + +sqlite3 db2 test.db2 +do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 } {wal} +db2 close + +do_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete} +do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {delete} +do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {delete} +do_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL } {wal} +do_execsql_test walmode-8.21 { PRAGMA main.journal_mode } {wal} +do_execsql_test walmode-8.22 { PRAGMA two.journal_mode } {wal} + +finish_test |