xref: /sqlite-3.40.0/test/walprotocol.test (revision cddfc392)
1be7721d1Sdan# 2016 February 4
2be7721d1Sdan#
3be7721d1Sdan# The author disclaims copyright to this source code.  In place of
4be7721d1Sdan# a legal notice, here is a blessing:
5be7721d1Sdan#
6be7721d1Sdan#    May you do good and not evil.
7be7721d1Sdan#    May you find forgiveness for yourself and forgive others.
8be7721d1Sdan#    May you share freely, never taking more than you give.
9be7721d1Sdan#
10be7721d1Sdan#***********************************************************************
11be7721d1Sdan# This file implements regression tests for SQLite library.  The
12be7721d1Sdan# focus of this file is testing the operation of the library in
13be7721d1Sdan# "PRAGMA journal_mode=WAL" mode.
14be7721d1Sdan#
15be7721d1Sdan# More specifically, it tests "locking protocol" errors - errors that
16be7721d1Sdan# may be caused if one or more SQLite clients does not follow the expected
17be7721d1Sdan# locking protocol when accessing a wal-mode database. These tests take
18be7721d1Sdan# quite a while to run.
19be7721d1Sdan#
20be7721d1Sdan
21be7721d1Sdanset testdir [file dirname $argv0]
22be7721d1Sdansource $testdir/tester.tcl
23be7721d1Sdansource $testdir/lock_common.tcl
24be7721d1Sdansource $testdir/wal_common.tcl
25be7721d1Sdanifcapable !wal {finish_test ; return }
26be7721d1Sdan
27be7721d1Sdanset testprefix walprotocol
28be7721d1Sdan
29be7721d1Sdan#-------------------------------------------------------------------------
30be7721d1Sdan# When recovering the contents of a WAL file, a process obtains the WRITER
31be7721d1Sdan# lock, then locks all other bytes before commencing recovery. If it fails
32be7721d1Sdan# to lock all other bytes (because some other process is holding a read
33be7721d1Sdan# lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the
34be7721d1Sdan# caller. Test this (test case 1.3).
35be7721d1Sdan#
36be7721d1Sdan# Also test the effect of hitting an SQLITE_BUSY while attempting to obtain
37be7721d1Sdan# the WRITER lock (should be the same). Test case 1.4.
38be7721d1Sdan#
39be7721d1Sdando_execsql_test 1.0 {
40be7721d1Sdan  PRAGMA journal_mode = wal;
41be7721d1Sdan  CREATE TABLE x(y);
42be7721d1Sdan  INSERT INTO x VALUES('z');
43be7721d1Sdan} {wal}
44be7721d1Sdan
45be7721d1Sdanproc lock_callback {method filename handle lock} {
46be7721d1Sdan  lappend ::locks $lock
47be7721d1Sdan}
48be7721d1Sdando_test 1.1 {
49be7721d1Sdan  testvfs T
50be7721d1Sdan  T filter xShmLock
51be7721d1Sdan  T script lock_callback
52be7721d1Sdan  set ::locks [list]
53be7721d1Sdan  sqlite3 db test.db -vfs T
54be7721d1Sdan  execsql { SELECT * FROM x }
55*cddfc392Sdan  lrange $::locks 0 11
56*cddfc392Sdan} [list {0 1 lock exclusive} {1 2 lock exclusive}     \
57*cddfc392Sdan        {4 1 lock exclusive} {4 1 unlock exclusive}   \
58*cddfc392Sdan        {5 1 lock exclusive} {5 1 unlock exclusive}   \
59*cddfc392Sdan        {6 1 lock exclusive} {6 1 unlock exclusive}   \
60*cddfc392Sdan        {7 1 lock exclusive} {7 1 unlock exclusive}   \
61*cddfc392Sdan        {1 2 unlock exclusive}   \
62*cddfc392Sdan        {0 1 unlock exclusive}  \
63be7721d1Sdan]
64be7721d1Sdando_test 1.2 {
65be7721d1Sdan  db close
66be7721d1Sdan  set ::locks [list]
67be7721d1Sdan  sqlite3 db test.db -vfs T
68be7721d1Sdan  execsql { SELECT * FROM x }
69*cddfc392Sdan  lrange $::locks 0 11
70*cddfc392Sdan} [list {0 1 lock exclusive} {1 2 lock exclusive}     \
71*cddfc392Sdan        {4 1 lock exclusive} {4 1 unlock exclusive}   \
72*cddfc392Sdan        {5 1 lock exclusive} {5 1 unlock exclusive}   \
73*cddfc392Sdan        {6 1 lock exclusive} {6 1 unlock exclusive}   \
74*cddfc392Sdan        {7 1 lock exclusive} {7 1 unlock exclusive}   \
75*cddfc392Sdan        {1 2 unlock exclusive}   \
76*cddfc392Sdan        {0 1 unlock exclusive}  \
77be7721d1Sdan]
78be7721d1Sdanproc lock_callback {method filename handle lock} {
7963025906Sdan  if {$lock == "1 2 lock exclusive"} { return SQLITE_BUSY }
80be7721d1Sdan  return SQLITE_OK
81be7721d1Sdan}
82d62c07d4Smistachkinputs "# Warning: This next test case causes SQLite to call xSleep(1) 100 times."
83be7721d1Sdanputs "# Normally this equates to a delay of roughly 10 seconds, but if SQLite"
84be7721d1Sdanputs "# is built on unix without HAVE_USLEEP defined, it may be much longer."
85be7721d1Sdando_test 1.3 {
86be7721d1Sdan  db close
87be7721d1Sdan  set ::locks [list]
88be7721d1Sdan  sqlite3 db test.db -vfs T
89be7721d1Sdan  catchsql { SELECT * FROM x }
90be7721d1Sdan} {1 {locking protocol}}
91be7721d1Sdan
92be7721d1Sdanputs "# Warning: Same again!"
93be7721d1Sdanproc lock_callback {method filename handle lock} {
94be7721d1Sdan  if {$lock == "0 1 lock exclusive"} { return SQLITE_BUSY }
95be7721d1Sdan  return SQLITE_OK
96be7721d1Sdan}
97be7721d1Sdando_test 1.4 {
98be7721d1Sdan  db close
99be7721d1Sdan  set ::locks [list]
100be7721d1Sdan  sqlite3 db test.db -vfs T
101be7721d1Sdan  catchsql { SELECT * FROM x }
102be7721d1Sdan} {1 {locking protocol}}
10363025906Sdan
10463025906Sdanputs "# Warning: Third time!"
10563025906Sdanproc lock_callback {method filename handle lock} {
10663025906Sdan  if {$lock == "4 4 lock exclusive"} { return SQLITE_BUSY }
10763025906Sdan  return SQLITE_OK
10863025906Sdan}
10963025906Sdando_test 1.5 {
11063025906Sdan  db close
11163025906Sdan  set ::locks [list]
11263025906Sdan  sqlite3 db test.db -vfs T
11363025906Sdan  catchsql { SELECT * FROM x }
114*cddfc392Sdan} {0 z}
115be7721d1Sdandb close
116be7721d1SdanT delete
117be7721d1Sdan
118be7721d1Sdan#-------------------------------------------------------------------------
119be7721d1Sdan#
120be7721d1Sdando_test 2.1 {
121be7721d1Sdan  forcedelete test.db test.db-journal test.db wal
122be7721d1Sdan  sqlite3 db test.db
123be7721d1Sdan  sqlite3 db2 test.db
124be7721d1Sdan  execsql {
125be7721d1Sdan    PRAGMA auto_vacuum = off;
126be7721d1Sdan    PRAGMA journal_mode = WAL;
127be7721d1Sdan    CREATE TABLE b(c);
128be7721d1Sdan    INSERT INTO b VALUES('Tehran');
129be7721d1Sdan    INSERT INTO b VALUES('Qom');
130be7721d1Sdan    INSERT INTO b VALUES('Markazi');
131be7721d1Sdan    PRAGMA wal_checkpoint;
132be7721d1Sdan  }
133be7721d1Sdan} {wal 0 5 5}
134be7721d1Sdando_test 2.2 {
135be7721d1Sdan  execsql { SELECT * FROM b }
136be7721d1Sdan} {Tehran Qom Markazi}
137be7721d1Sdando_test 2.3 {
138be7721d1Sdan  db eval { SELECT * FROM b } {
139be7721d1Sdan    db eval { INSERT INTO b VALUES('Qazvin') }
140be7721d1Sdan    set r [db2 eval { SELECT * FROM b }]
141be7721d1Sdan    break
142be7721d1Sdan  }
143be7721d1Sdan  set r
144be7721d1Sdan} {Tehran Qom Markazi Qazvin}
145be7721d1Sdando_test 2.4 {
146be7721d1Sdan  execsql {
147be7721d1Sdan    INSERT INTO b VALUES('Gilan');
148be7721d1Sdan    INSERT INTO b VALUES('Ardabil');
149be7721d1Sdan  }
150be7721d1Sdan} {}
151be7721d1Sdandb2 close
152be7721d1Sdan
153be7721d1Sdanfaultsim_save_and_close
154be7721d1Sdantestvfs T -default 1
155be7721d1Sdanfaultsim_restore_and_reopen
156be7721d1SdanT filter xShmLock
157be7721d1SdanT script lock_callback
158be7721d1Sdan
159be7721d1Sdanproc lock_callback {method file handle spec} {
16063025906Sdan  if {$spec == "1 2 unlock exclusive"} {
161be7721d1Sdan    T filter {}
162be7721d1Sdan    set ::r [catchsql { SELECT * FROM b } db2]
163be7721d1Sdan  }
164be7721d1Sdan}
165be7721d1Sdansqlite3 db test.db
166be7721d1Sdansqlite3 db2 test.db
16763025906Sdanputs "# Warning: Another slow test!"
168be7721d1Sdando_test 2.5 {
169be7721d1Sdan  execsql { SELECT * FROM b }
170be7721d1Sdan} {Tehran Qom Markazi Qazvin Gilan Ardabil}
171be7721d1Sdando_test 2.6 {
172be7721d1Sdan  set ::r
173*cddfc392Sdan} {0 {Tehran Qom Markazi Qazvin Gilan Ardabil}}
174be7721d1Sdan
175be7721d1Sdandb close
176be7721d1Sdandb2 close
177be7721d1Sdan
178be7721d1Sdanfaultsim_restore_and_reopen
179be7721d1Sdansqlite3 db2 test.db
180be7721d1SdanT filter xShmLock
181be7721d1SdanT script lock_callback
182be7721d1Sdanproc lock_callback {method file handle spec} {
18363025906Sdan  if {$spec == "1 2 unlock exclusive"} {
184be7721d1Sdan    T filter {}
185be7721d1Sdan    set ::r [catchsql { SELECT * FROM b } db2]
186be7721d1Sdan  }
187be7721d1Sdan}
188be7721d1Sdanunset ::r
18963025906Sdanputs "# Warning: Last one!"
190be7721d1Sdando_test 2.7 {
191be7721d1Sdan  execsql { SELECT * FROM b }
192be7721d1Sdan} {Tehran Qom Markazi Qazvin Gilan Ardabil}
193be7721d1Sdando_test 2.8 {
194be7721d1Sdan  set ::r
195*cddfc392Sdan} {0 {Tehran Qom Markazi Qazvin Gilan Ardabil}}
196be7721d1Sdan
197be7721d1Sdandb close
198be7721d1Sdandb2 close
199be7721d1SdanT delete
200be7721d1Sdan
201be7721d1Sdanfinish_test
202