fix issue where memory PRAGMA cipher_memory_security would report OFF when it was...
[sqlcipher.git] / ext / rbu / rbu12.test
blob7816bfe89f91c9b1be03097cb50d0ee16c8c216d
1 # 2015 February 16
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
13 if {![info exists testdir]} {
14   set testdir [file join [file dirname [info script]] .. .. test]
16 source $testdir/tester.tcl
17 source $testdir/lock_common.tcl
18 set ::testprefix rbu12
20 set setup_sql {
21   DROP TABLE IF EXISTS xx;
22   DROP TABLE IF EXISTS xy;
23   CREATE TABLE xx(a, b, c PRIMARY KEY);
24   INSERT INTO xx VALUES(1, 2, 3);
25   CREATE TABLE xy(a, b, c PRIMARY KEY);
27   ATTACH 'rbu.db' AS rbu;
28     DROP TABLE IF EXISTS data_xx;
29     CREATE TABLE rbu.data_xx(a, b, c, rbu_control);
30     INSERT INTO data_xx VALUES(4, 5, 6, 0);
31     INSERT INTO data_xx VALUES(7, 8, 9, 0);
32     CREATE TABLE rbu.data_xy(a, b, c, rbu_control);
33     INSERT INTO data_xy VALUES(10, 11, 12, 0);
34   DETACH rbu;
37 do_multiclient_test tn {
39   # Initialize a target (test.db) and rbu (rbu.db) database.
40   #
41   forcedelete rbu.db
42   sql1 $setup_sql
44   # Using connection 2, open a read transaction on the target database.
45   # RBU will still be able to generate "test.db-oal", but it will not be
46   # able to rename it to "test.db-wal".
47   #
48   do_test 1.$tn.1 {
49     sql2 { BEGIN; SELECT * FROM xx; }
50   } {1 2 3}
51   do_test 1.$tn.2 {
52     sqlite3rbu rbu test.db rbu.db
53     while 1 {
54       set res [rbu step]
55       if {$res!="SQLITE_OK"} break
56     }
57     set res
58   } {SQLITE_BUSY}
60   do_test 1.$tn.3 { sql2 { SELECT * FROM xx; } } {1 2 3}
61   do_test 1.$tn.4 { sql2 { SELECT * FROM xy; } } {}
62   do_test 1.$tn.5 {
63     list [file exists test.db-wal] [file exists test.db-oal]
64   } {0 1}
65   do_test 1.$tn.6 { sql2 COMMIT } {}
67   # The rbu object that hit the SQLITE_BUSY error above cannot be reused.
68   # It is stuck in a permanent SQLITE_BUSY state at this point.
69   #
70   do_test 1.$tn.7 { rbu step } {SQLITE_BUSY}
71   do_test 1.$tn.8 { 
72     list [catch { rbu close } msg] $msg 
73   } {1 SQLITE_BUSY}
75   do_test 1.$tn.9.1 { sql2 { BEGIN EXCLUSIVE } } {}
76   do_test 1.$tn.9.2 {
77     sqlite3rbu rbu test.db rbu.db
78     rbu step
79   } {SQLITE_BUSY}
80   do_test 1.$tn.9.3 {
81     list [catch { rbu close } msg] $msg 
82   } {1 {SQLITE_BUSY - database is locked}}
83   do_test 1.$tn.9.4 { sql2 COMMIT } {}
85   sqlite3rbu rbu test.db rbu.db
86   do_test 1.$tn.10.1 { sql2 { BEGIN EXCLUSIVE } } {}
87   do_test 1.$tn.10.2 {
88     rbu step
89   } {SQLITE_BUSY}
90   do_test 1.$tn.10.3 {
91     list [catch { rbu close } msg] $msg 
92   } {1 SQLITE_BUSY}
93   do_test 1.$tn.10.4 { sql2 COMMIT } {}
95   # A new rbu object can finish the work though.
96   #
97   do_test 1.$tn.11 {
98     sqlite3rbu rbu test.db rbu.db
99     rbu step
100   } {SQLITE_OK}
101   do_test 1.$tn.12 {
102     list [file exists test.db-wal] [file exists test.db-oal]
103   } {1 0}
104   do_test 1.$tn.13 {
105     while 1 {
106       set res [rbu step]
107       if {$res!="SQLITE_OK"} break
108     }
109     set res
110   } {SQLITE_DONE}
112   do_test 1.$tn.14 {
113     rbu close
114   } {SQLITE_DONE}
117 do_multiclient_test tn {
119   # Initialize a target (test.db) and rbu (rbu.db) database.
120   #
121   forcedelete rbu.db
122   sql1 $setup_sql
124   do_test 2.$tn.1 {
125     sqlite3rbu rbu test.db rbu.db
126     while {[file exists test.db-wal]==0} {
127       if {[rbu step]!="SQLITE_OK"} {error "problem here...."}
128     }
129     rbu close
130   } {SQLITE_OK}
133   do_test 2.$tn.2 { sql2 { BEGIN IMMEDIATE } } {}
135   do_test 2.$tn.3 { 
136     sqlite3rbu rbu test.db rbu.db
137     rbu step 
138   } {SQLITE_BUSY}
140   do_test 2.$tn.4 { list [catch { rbu close } msg] $msg } {1 SQLITE_BUSY}
142   do_test 2.$tn.5 { 
143     sql2 { SELECT * FROM xx ; COMMIT }
144   } {1 2 3 4 5 6 7 8 9}
146   do_test 2.$tn.6 {
147     sqlite3rbu rbu test.db rbu.db
148     rbu step
149     rbu close
150   } {SQLITE_OK}
152   do_test 2.$tn.7 { sql2 { BEGIN EXCLUSIVE } } {}
154   do_test 2.$tn.8 { 
155     sqlite3rbu rbu test.db rbu.db
156     rbu step 
157   } {SQLITE_BUSY}
158   do_test 2.$tn.9 { list [catch { rbu close } msg] $msg } {1 SQLITE_BUSY}
159   do_test 2.$tn.10 { 
160     sql2 { SELECT * FROM xx ; COMMIT }
161   } {1 2 3 4 5 6 7 8 9}
163   do_test 2.$tn.11 {
164     sqlite3rbu rbu test.db rbu.db
165     while {[rbu step]=="SQLITE_OK"} {}
166     rbu close
167   } {SQLITE_DONE}
171 #-------------------------------------------------------------------------
172 # Test that "PRAGMA data_version" works when an RBU client writes the
173 # database.
175 do_multiclient_test tn {
177   # Initialize a target (test.db) and rbu (rbu.db) database.
178   #
179   forcedelete rbu.db
180   sql1 $setup_sql
182   # Check the initial database contains table "xx" with a single row.
183   # Also save the current values of "PRAGMA data-version" for [db1] 
184   # and [db2].
185   #
186   do_test 2.$tn.1 {
187     list [sql1 { SELECT count(*) FROM xx }] [sql2 { SELECT count(*) FROM xx }]
188   } {1 1}
189   set V1 [sql1 {PRAGMA data_version}] 
190   set V2 [sql2 {PRAGMA data_version}]
192   # Check the values of data-version have not magically changed.
193   #
194   do_test 2.$tn.2 {
195     list [sql1 {PRAGMA data_version}] [sql2 {PRAGMA data_version}]
196   } [list $V1 $V2]
198   # Start stepping the RBU. From the point of view of [db1] and [db2], the 
199   # data-version values remain unchanged until the database contents are
200   # modified. At which point the values are incremented.
201   #
202   sqlite3rbu rbu test.db rbu.db
203   set x 0
204   while {[db one {SELECT count(*) FROM xx}]==1} {
205     do_test 2.$tn.3.[incr x] {
206       list [sql1 {PRAGMA data_version}] [sql2 {PRAGMA data_version}]
207     } [list $V1 $V2]
208     rbu step
209   }
210   do_test 2.$tn.5.1 { expr {$V1 < [sql1 {PRAGMA data_version}]} } 1
211   do_test 2.$tn.5.2 { expr {$V2 < [sql2 {PRAGMA data_version}]} } 1
213   # Check the db contents is as expected.
214   #
215   do_test 2.$tn.4 {
216     list [sql1 {SELECT count(*) FROM xx}] [sql2 {SELECT count(*) FROM xx}]
217   } {3 3}
219   set V1 [sql1 {PRAGMA data_version}] 
220   set V2 [sql2 {PRAGMA data_version}]
222   # Finish applying the RBU (i.e. do the incremental checkpoint). Check that
223   # this does not cause the data-version values to change.
224   #
225   while {[rbu step]=="SQLITE_OK"} { }
226   rbu close
228   do_test 2.$tn.6 {
229     list [sql1 {PRAGMA data_version}] [sql2 {PRAGMA data_version}]
230   } [list $V1 $V2]
234 finish_test