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