xref: /sqlite-3.40.0/test/walblock.test (revision 62ca61ee)
1363fc9e7Sdan# 2015 Mar 17
2363fc9e7Sdan#
3363fc9e7Sdan# The author disclaims copyright to this source code.  In place of
4363fc9e7Sdan# a legal notice, here is a blessing:
5363fc9e7Sdan#
6363fc9e7Sdan#    May you do good and not evil.
7363fc9e7Sdan#    May you find forgiveness for yourself and forgive others.
8363fc9e7Sdan#    May you share freely, never taking more than you give.
9363fc9e7Sdan#
10363fc9e7Sdan#***********************************************************************
11363fc9e7Sdan#
12363fc9e7Sdan
13363fc9e7Sdanset testdir [file dirname $argv0]
14363fc9e7Sdansource $testdir/tester.tcl
15363fc9e7Sdansource $testdir/lock_common.tcl
16363fc9e7Sdansource $testdir/wal_common.tcl
17363fc9e7Sdan
18*62ca61eeSdrhfinish_test; return;    #  Feature currently not implemented.
19363fc9e7Sdanifcapable !wal {finish_test ; return }
20363fc9e7Sdanif {$::tcl_platform(platform)!="unix"} { finish_test ; return }
21363fc9e7Sdanset testprefix walblock
22363fc9e7Sdan
23363fc9e7Sdancatch { db close }
24363fc9e7Sdantestvfs tvfs -fullshm 1
25363fc9e7Sdanforeach f [glob test.db*] { forcedelete $f }
26363fc9e7Sdan
27363fc9e7Sdansqlite3 db test.db -vfs tvfs
28363fc9e7Sdando_execsql_test 1.1.0 {
29363fc9e7Sdan  CREATE TABLE t1(x, y);
30363fc9e7Sdan  INSERT INTO t1 VALUES(1, 2);
31363fc9e7Sdan  INSERT INTO t1 VALUES(3, 4);
32363fc9e7Sdan  INSERT INTO t1 VALUES(5, 6);
33363fc9e7Sdan  PRAGMA journal_mode = wal;
34363fc9e7Sdan  INSERT INTO t1 VALUES(7, 8);
35363fc9e7Sdan} {wal}
36363fc9e7Sdan
37363fc9e7Sdando_test 1.1.1 {
38363fc9e7Sdan  lsort [glob test.db*]
39363fc9e7Sdan} {test.db test.db-shm test.db-wal}
40363fc9e7Sdan
41363fc9e7Sdando_test 1.1.2 {
42363fc9e7Sdan  set C [launch_testfixture]
43363fc9e7Sdan  testfixture $C {
44363fc9e7Sdan    sqlite3 db test.db
45363fc9e7Sdan    db eval { SELECT * FROM t1 }
46363fc9e7Sdan  }
47363fc9e7Sdan} {1 2 3 4 5 6 7 8}
48363fc9e7Sdan
49363fc9e7Sdando_test 1.1.3 {
50363fc9e7Sdan  set ::out [list]
51363fc9e7Sdan  testfixture $C {
52363fc9e7Sdan    db eval { SELECT * FROM t1 }
53363fc9e7Sdan  } [list set ::out]
54363fc9e7Sdan  set ::out
55363fc9e7Sdan} {}
56363fc9e7Sdan
57363fc9e7Sdando_test 1.1.4 {
58363fc9e7Sdan  vwait ::out
59363fc9e7Sdan  set ::out
60363fc9e7Sdan} {1 2 3 4 5 6 7 8}
61363fc9e7Sdan
62363fc9e7Sdan#
63363fc9e7Sdan# Test that if a read client cannot read the wal-index header because a
64363fc9e7Sdan# write client is in the middle of updating it, the reader blocks until
65363fc9e7Sdan# the writer finishes.
66363fc9e7Sdan#
67363fc9e7Sdan#   1. Open a write transaction using client [db] in this process.
68363fc9e7Sdan#
69363fc9e7Sdan#   2. Attempt to commit the write transaction. Intercept the xShmBarrier()
70363fc9e7Sdan#      call made by the writer between updating the two copies of the
71363fc9e7Sdan#      wal-index header.
72363fc9e7Sdan#
73363fc9e7Sdan#   3. Within the xShmBarrier() callback, make an asynchronous request to
74363fc9e7Sdan#      the other process to read from the database. It should block, as it
75363fc9e7Sdan#      cannot get read the wal-index header.
76363fc9e7Sdan#
77363fc9e7Sdan#   4. Still in xShmBarrier(), wait for 5 seconds. Check that the other
78363fc9e7Sdan#      process has not answered the request.
79363fc9e7Sdan#
80363fc9e7Sdan#   5: Finish committing the transaction. Then wait for 0.5 seconds more.
81363fc9e7Sdan#      Ensure that the second process has by this stage read the database
82363fc9e7Sdan#      and that the snapshot it read included the transaction committed in
83363fc9e7Sdan#      step (4).
84363fc9e7Sdan#
85363fc9e7Sdando_execsql_test 1.2.1 {
86363fc9e7Sdan  BEGIN;
87363fc9e7Sdan    INSERT INTO t1 VALUES(9, 10);
88363fc9e7Sdan} {}
89363fc9e7Sdan
90363fc9e7Sdantvfs script barrier_callback
91363fc9e7Sdantvfs filter xShmBarrier
92363fc9e7Sdanproc barrier_callback {method args} {
93363fc9e7Sdan  set ::out ""
94363fc9e7Sdan  testfixture $::C { db eval { SELECT * FROM t1 } } {set ::out}
95363fc9e7Sdan
96d2f99333Sdan  do_test "1.2.2.(blocking 10 seconds)" {
97363fc9e7Sdan    set ::continue 0
98d2f99333Sdan    after 10000 {set ::continue 1}
99363fc9e7Sdan    vwait ::continue
100363fc9e7Sdan    set ::out
101363fc9e7Sdan  } {}
102363fc9e7Sdan}
103363fc9e7Sdan
104363fc9e7Sdanexecsql COMMIT
105363fc9e7Sdan
106363fc9e7Sdando_test "1.2.3.(blocking 0.5 seconds)" {
107363fc9e7Sdan  set ::continue 0
108363fc9e7Sdan  after 500 {set ::continue 1}
109363fc9e7Sdan  vwait ::continue
110363fc9e7Sdan  set ::out
111363fc9e7Sdan} {1 2 3 4 5 6 7 8 9 10}
112363fc9e7Sdan
113363fc9e7Sdan
114363fc9e7Sdanfinish_test
115