xref: /sqlite-3.40.0/test/walblock.test (revision cb6acda9)
1# 2015 Mar 17
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
13set testdir [file dirname $argv0]
14source $testdir/tester.tcl
15source $testdir/lock_common.tcl
16source $testdir/wal_common.tcl
17
18finish_test; return;    #  Feature currently not implemented.
19ifcapable !wal {finish_test ; return }
20if {$::tcl_platform(platform)!="unix"} { finish_test ; return }
21set testprefix walblock
22
23catch { db close }
24testvfs tvfs -fullshm 1
25foreach f [glob test.db*] { forcedelete $f }
26
27sqlite3 db test.db -vfs tvfs
28do_execsql_test 1.1.0 {
29  CREATE TABLE t1(x, y);
30  INSERT INTO t1 VALUES(1, 2);
31  INSERT INTO t1 VALUES(3, 4);
32  INSERT INTO t1 VALUES(5, 6);
33  PRAGMA journal_mode = wal;
34  INSERT INTO t1 VALUES(7, 8);
35} {wal}
36
37do_test 1.1.1 {
38  lsort [glob test.db*]
39} {test.db test.db-shm test.db-wal}
40
41do_test 1.1.2 {
42  set C [launch_testfixture]
43  testfixture $C {
44    sqlite3 db test.db
45    db eval { SELECT * FROM t1 }
46  }
47} {1 2 3 4 5 6 7 8}
48
49do_test 1.1.3 {
50  set ::out [list]
51  testfixture $C {
52    db eval { SELECT * FROM t1 }
53  } [list set ::out]
54  set ::out
55} {}
56
57do_test 1.1.4 {
58  vwait ::out
59  set ::out
60} {1 2 3 4 5 6 7 8}
61
62#
63# Test that if a read client cannot read the wal-index header because a
64# write client is in the middle of updating it, the reader blocks until
65# the writer finishes.
66#
67#   1. Open a write transaction using client [db] in this process.
68#
69#   2. Attempt to commit the write transaction. Intercept the xShmBarrier()
70#      call made by the writer between updating the two copies of the
71#      wal-index header.
72#
73#   3. Within the xShmBarrier() callback, make an asynchronous request to
74#      the other process to read from the database. It should block, as it
75#      cannot get read the wal-index header.
76#
77#   4. Still in xShmBarrier(), wait for 5 seconds. Check that the other
78#      process has not answered the request.
79#
80#   5: Finish committing the transaction. Then wait for 0.5 seconds more.
81#      Ensure that the second process has by this stage read the database
82#      and that the snapshot it read included the transaction committed in
83#      step (4).
84#
85do_execsql_test 1.2.1 {
86  BEGIN;
87    INSERT INTO t1 VALUES(9, 10);
88} {}
89
90tvfs script barrier_callback
91tvfs filter xShmBarrier
92proc barrier_callback {method args} {
93  set ::out ""
94  testfixture $::C { db eval { SELECT * FROM t1 } } {set ::out}
95
96  do_test "1.2.2.(blocking 10 seconds)" {
97    set ::continue 0
98    after 10000 {set ::continue 1}
99    vwait ::continue
100    set ::out
101  } {}
102}
103
104execsql COMMIT
105
106do_test "1.2.3.(blocking 0.5 seconds)" {
107  set ::continue 0
108  after 500 {set ::continue 1}
109  vwait ::continue
110  set ::out
111} {1 2 3 4 5 6 7 8 9 10}
112
113
114finish_test
115