Merge sqlite-release(3.30.1) into prerelease-integration
[sqlcipher.git] / test / walprotocol2.test
blob0792c9aae00501fb8e70c274a5563f7fe36ef751
1 # 2018 July 4
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
13 set testdir [file dirname $argv0]
14 source $testdir/tester.tcl
15 source $testdir/lock_common.tcl
16 source $testdir/wal_common.tcl
17 ifcapable !wal {finish_test ; return }
19 set testprefix walprotocol2
21 #-------------------------------------------------------------------------
22 # When recovering the contents of a WAL file, a process obtains the WRITER
23 # lock, then locks all other bytes before commencing recovery. If it fails
24 # to lock all other bytes (because some other process is holding a read
25 # lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the 
26 # caller. Test this (test case 1.3).
28 # Also test the effect of hitting an SQLITE_BUSY while attempting to obtain
29 # the WRITER lock (should be the same). Test case 1.4.
30
31 do_execsql_test 1.0 {
32   PRAGMA journal_mode = wal;
33   CREATE TABLE x(y);
34   INSERT INTO x VALUES('z');
35 } {wal}
37 db close
39 proc lock_callback {method filename handle lock} {
40   # puts "$method $filename $handle $lock"
42 testvfs T
43 T filter xShmLock 
44 T script lock_callback
46 sqlite3 db  test.db -vfs T
47 sqlite3 db2 test.db -vfs T
49 do_execsql_test 2.0 {
50   SELECT * FROM x;
51 } {z}
52 do_execsql_test -db db2 2.1 {
53   SELECT * FROM x;
54 } {z}
56 #---------------------------------------------------------------
57 # Attempt a "BEGIN EXCLUSIVE" using connection handle [db]. This
58 # causes SQLite to open a read transaction, then a write transaction.
59 # Rig the xShmLock() callback so that just before the EXCLUSIVE lock
60 # for the write transaction is taken, connection [db2] jumps in and
61 # modifies the database. This causes the "BEGIN EXCLUSIVE" to throw
62 # an SQLITE_BUSY_SNAPSHOT error.
64 proc lock_callback {method filename handle lock} {
65   if {$lock=="0 1 lock exclusive"} {
66     proc lock_callback {method filename handle lock} {}
67     db2 eval { INSERT INTO x VALUES('y') }
68   }
70 do_catchsql_test 2.2 {
71   BEGIN EXCLUSIVE;
72 } {1 {database is locked}}
73 do_test 2.3 {
74   sqlite3_extended_errcode db
75 } {SQLITE_BUSY}
77 #---------------------------------------------------------------
78 # Same again, but with a busy-handler. This time, following the
79 # SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the 
80 # whole thing retried from the beginning. This time it succeeds.
82 proc lock_callback {method filename handle lock} {
83   if {$lock=="0 1 lock exclusive"} {
84     proc lock_callback {method filename handle lock} {}
85     db2 eval { INSERT INTO x VALUES('x') }
86   }
88 db timeout 10
89 do_catchsql_test 2.4 {
90   BEGIN EXCLUSIVE;
91 } {0 {}}
92 do_execsql_test 2.5 {
93   SELECT * FROM x;
94   COMMIT;
95 } {z y x}
97 finish_test