summaryrefslogtreecommitdiffstats
path: root/ext/rbu/rbu12.test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:28:19 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:28:19 +0000
commit18657a960e125336f704ea058e25c27bd3900dcb (patch)
tree17b438b680ed45a996d7b59951e6aa34023783f2 /ext/rbu/rbu12.test
parentInitial commit. (diff)
downloadsqlite3-upstream.tar.xz
sqlite3-upstream.zip
Adding upstream version 3.40.1.upstream/3.40.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ext/rbu/rbu12.test')
-rw-r--r--ext/rbu/rbu12.test234
1 files changed, 234 insertions, 0 deletions
diff --git a/ext/rbu/rbu12.test b/ext/rbu/rbu12.test
new file mode 100644
index 0000000..7816bfe
--- /dev/null
+++ b/ext/rbu/rbu12.test
@@ -0,0 +1,234 @@
+# 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