| Index: third_party/sqlite/sqlite-src-3100200/ext/rbu/rbu12.test
|
| diff --git a/third_party/sqlite/sqlite-src-3100200/ext/rbu/rbu12.test b/third_party/sqlite/sqlite-src-3100200/ext/rbu/rbu12.test
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a83d0891a30b7e5f3f85d8b88416e58f790dd12a
|
| --- /dev/null
|
| +++ b/third_party/sqlite/sqlite-src-3100200/ext/rbu/rbu12.test
|
| @@ -0,0 +1,235 @@
|
| +# 2015 February 16
|
| +#
|
| +# The author disclaims copyright to this source code. In place of
|
| +# a legal notice, here is a blessing:
|
| +#
|
| +# May you do good and not evil.
|
| +# May you find forgiveness for yourself and forgive others.
|
| +# May you share freely, never taking more than you give.
|
| +#
|
| +#***********************************************************************
|
| +#
|
| +
|
| +if {![info exists testdir]} {
|
| + set testdir [file join [file dirname [info script]] .. .. test]
|
| +}
|
| +source $testdir/tester.tcl
|
| +source $testdir/lock_common.tcl
|
| +set ::testprefix rbu12
|
| +
|
| +set setup_sql {
|
| + DROP TABLE IF EXISTS xx;
|
| + DROP TABLE IF EXISTS xy;
|
| + CREATE TABLE xx(a, b, c PRIMARY KEY);
|
| + INSERT INTO xx VALUES(1, 2, 3);
|
| + CREATE TABLE xy(a, b, c PRIMARY KEY);
|
| +
|
| + ATTACH 'rbu.db' AS rbu;
|
| + DROP TABLE IF EXISTS data_xx;
|
| + CREATE TABLE rbu.data_xx(a, b, c, rbu_control);
|
| + INSERT INTO data_xx VALUES(4, 5, 6, 0);
|
| + INSERT INTO data_xx VALUES(7, 8, 9, 0);
|
| + CREATE TABLE rbu.data_xy(a, b, c, rbu_control);
|
| + INSERT INTO data_xy VALUES(10, 11, 12, 0);
|
| + DETACH rbu;
|
| +}
|
| +
|
| +do_multiclient_test tn {
|
| +
|
| + # Initialize a target (test.db) and rbu (rbu.db) database.
|
| + #
|
| + forcedelete rbu.db
|
| + sql1 $setup_sql
|
| +
|
| + # Using connection 2, open a read transaction on the target database.
|
| + # RBU will still be able to generate "test.db-oal", but it will not be
|
| + # able to rename it to "test.db-wal".
|
| + #
|
| + do_test 1.$tn.1 {
|
| + sql2 { BEGIN; SELECT * FROM xx; }
|
| + } {1 2 3}
|
| + do_test 1.$tn.2 {
|
| + sqlite3rbu rbu test.db rbu.db
|
| + while 1 {
|
| + set res [rbu step]
|
| + if {$res!="SQLITE_OK"} break
|
| + }
|
| + set res
|
| + } {SQLITE_BUSY}
|
| +
|
| + do_test 1.$tn.3 { sql2 { SELECT * FROM xx; } } {1 2 3}
|
| + do_test 1.$tn.4 { sql2 { SELECT * FROM xy; } } {}
|
| + do_test 1.$tn.5 {
|
| + list [file exists test.db-wal] [file exists test.db-oal]
|
| + } {0 1}
|
| + do_test 1.$tn.6 { sql2 COMMIT } {}
|
| +
|
| + # The rbu object that hit the SQLITE_BUSY error above cannot be reused.
|
| + # It is stuck in a permanent SQLITE_BUSY state at this point.
|
| + #
|
| + do_test 1.$tn.7 { rbu step } {SQLITE_BUSY}
|
| + do_test 1.$tn.8 {
|
| + list [catch { rbu close } msg] $msg
|
| + } {1 SQLITE_BUSY}
|
| +
|
| + do_test 1.$tn.9.1 { sql2 { BEGIN EXCLUSIVE } } {}
|
| + do_test 1.$tn.9.2 {
|
| + sqlite3rbu rbu test.db rbu.db
|
| + rbu step
|
| + } {SQLITE_BUSY}
|
| + do_test 1.$tn.9.3 {
|
| + list [catch { rbu close } msg] $msg
|
| + } {1 {SQLITE_BUSY - database is locked}}
|
| + do_test 1.$tn.9.4 { sql2 COMMIT } {}
|
| +
|
| + sqlite3rbu rbu test.db rbu.db
|
| + do_test 1.$tn.10.1 { sql2 { BEGIN EXCLUSIVE } } {}
|
| + do_test 1.$tn.10.2 {
|
| + rbu step
|
| + } {SQLITE_BUSY}
|
| + do_test 1.$tn.10.3 {
|
| + list [catch { rbu close } msg] $msg
|
| + } {1 SQLITE_BUSY}
|
| + do_test 1.$tn.10.4 { sql2 COMMIT } {}
|
| +
|
| + # A new rbu object can finish the work though.
|
| + #
|
| + do_test 1.$tn.11 {
|
| + sqlite3rbu rbu test.db rbu.db
|
| + rbu step
|
| + } {SQLITE_OK}
|
| + do_test 1.$tn.12 {
|
| + list [file exists test.db-wal] [file exists test.db-oal]
|
| + } {1 0}
|
| + do_test 1.$tn.13 {
|
| + while 1 {
|
| + set res [rbu step]
|
| + if {$res!="SQLITE_OK"} break
|
| + }
|
| + set res
|
| + } {SQLITE_DONE}
|
| +
|
| + do_test 1.$tn.14 {
|
| + rbu close
|
| + } {SQLITE_DONE}
|
| +}
|
| +
|
| +do_multiclient_test tn {
|
| +
|
| + # Initialize a target (test.db) and rbu (rbu.db) database.
|
| + #
|
| + forcedelete rbu.db
|
| + sql1 $setup_sql
|
| +
|
| + do_test 2.$tn.1 {
|
| + sqlite3rbu rbu test.db rbu.db
|
| + while {[file exists test.db-wal]==0} {
|
| + if {[rbu step]!="SQLITE_OK"} {error "problem here...."}
|
| + }
|
| + rbu close
|
| + } {SQLITE_OK}
|
| +
|
| +
|
| + do_test 2.$tn.2 { sql2 { BEGIN IMMEDIATE } } {}
|
| +
|
| + do_test 2.$tn.3 {
|
| + sqlite3rbu rbu test.db rbu.db
|
| + rbu step
|
| + } {SQLITE_BUSY}
|
| +
|
| + do_test 2.$tn.4 { list [catch { rbu close } msg] $msg } {1 SQLITE_BUSY}
|
| +
|
| + do_test 2.$tn.5 {
|
| + sql2 { SELECT * FROM xx ; COMMIT }
|
| + } {1 2 3 4 5 6 7 8 9}
|
| +
|
| + do_test 2.$tn.6 {
|
| + sqlite3rbu rbu test.db rbu.db
|
| + rbu step
|
| + rbu close
|
| + } {SQLITE_OK}
|
| +
|
| + do_test 2.$tn.7 { sql2 { BEGIN EXCLUSIVE } } {}
|
| +
|
| + do_test 2.$tn.8 {
|
| + sqlite3rbu rbu test.db rbu.db
|
| + rbu step
|
| + } {SQLITE_BUSY}
|
| + do_test 2.$tn.9 { list [catch { rbu close } msg] $msg } {1 SQLITE_BUSY}
|
| + do_test 2.$tn.10 {
|
| + sql2 { SELECT * FROM xx ; COMMIT }
|
| + } {1 2 3 4 5 6 7 8 9}
|
| +
|
| + do_test 2.$tn.11 {
|
| + sqlite3rbu rbu test.db rbu.db
|
| + while {[rbu step]=="SQLITE_OK"} {}
|
| + rbu close
|
| + } {SQLITE_DONE}
|
| +
|
| +}
|
| +
|
| +#-------------------------------------------------------------------------
|
| +# Test that "PRAGMA data_version" works when an RBU client writes the
|
| +# database.
|
| +#
|
| +do_multiclient_test tn {
|
| +
|
| + # Initialize a target (test.db) and rbu (rbu.db) database.
|
| + #
|
| + forcedelete rbu.db
|
| + sql1 $setup_sql
|
| +
|
| + # Check the initial database contains table "xx" with a single row.
|
| + # Also save the current values of "PRAGMA data-version" for [db1]
|
| + # and [db2].
|
| + #
|
| + do_test 2.$tn.1 {
|
| + list [sql1 { SELECT count(*) FROM xx }] [sql2 { SELECT count(*) FROM xx }]
|
| + } {1 1}
|
| + set V1 [sql1 {PRAGMA data_version}]
|
| + set V2 [sql2 {PRAGMA data_version}]
|
| +
|
| + # Check the values of data-version have not magically changed.
|
| + #
|
| + do_test 2.$tn.2 {
|
| + list [sql1 {PRAGMA data_version}] [sql2 {PRAGMA data_version}]
|
| + } [list $V1 $V2]
|
| +
|
| + # Start stepping the RBU. From the point of view of [db1] and [db2], the
|
| + # data-version values remain unchanged until the database contents are
|
| + # modified. At which point the values are incremented.
|
| + #
|
| + sqlite3rbu rbu test.db rbu.db
|
| + set x 0
|
| + while {[db one {SELECT count(*) FROM xx}]==1} {
|
| + do_test 2.$tn.3.[incr x] {
|
| + list [sql1 {PRAGMA data_version}] [sql2 {PRAGMA data_version}]
|
| + } [list $V1 $V2]
|
| + rbu step
|
| + }
|
| + do_test 2.$tn.5.1 { expr {$V1 < [sql1 {PRAGMA data_version}]} } 1
|
| + do_test 2.$tn.5.2 { expr {$V2 < [sql2 {PRAGMA data_version}]} } 1
|
| +
|
| + # Check the db contents is as expected.
|
| + #
|
| + do_test 2.$tn.4 {
|
| + list [sql1 {SELECT count(*) FROM xx}] [sql2 {SELECT count(*) FROM xx}]
|
| + } {3 3}
|
| +
|
| + set V1 [sql1 {PRAGMA data_version}]
|
| + set V2 [sql2 {PRAGMA data_version}]
|
| +
|
| + # Finish applying the RBU (i.e. do the incremental checkpoint). Check that
|
| + # this does not cause the data-version values to change.
|
| + #
|
| + while {[rbu step]=="SQLITE_OK"} { }
|
| + rbu close
|
| +
|
| + do_test 2.$tn.6 {
|
| + list [sql1 {PRAGMA data_version}] [sql2 {PRAGMA data_version}]
|
| + } [list $V1 $V2]
|
| +
|
| +}
|
| +
|
| +finish_test
|
| +
|
|
|