1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/exclusive.test Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,459 @@
1.4 +# 2007 March 24
1.5 +#
1.6 +# The author disclaims copyright to this source code. In place of
1.7 +# a legal notice, here is a blessing:
1.8 +#
1.9 +# May you do good and not evil.
1.10 +# May you find forgiveness for yourself and forgive others.
1.11 +# May you share freely, never taking more than you give.
1.12 +#
1.13 +#***********************************************************************
1.14 +# This file implements regression tests for SQLite library. The focus
1.15 +# of these tests is exclusive access mode (i.e. the thing activated by
1.16 +# "PRAGMA locking_mode = EXCLUSIVE").
1.17 +#
1.18 +# $Id: exclusive.test,v 1.9 2008/09/24 14:03:43 danielk1977 Exp $
1.19 +
1.20 +set testdir [file dirname $argv0]
1.21 +source $testdir/tester.tcl
1.22 +
1.23 +ifcapable {!pager_pragmas} {
1.24 + finish_test
1.25 + return
1.26 +}
1.27 +
1.28 +file delete -force test2.db-journal
1.29 +file delete -force test2.db
1.30 +file delete -force test3.db-journal
1.31 +file delete -force test3.db
1.32 +file delete -force test4.db-journal
1.33 +file delete -force test4.db
1.34 +
1.35 +# The locking mode for the TEMP table is always "exclusive" for
1.36 +# on-disk tables and "normal" for in-memory tables.
1.37 +#
1.38 +if {[info exists TEMP_STORE] && $TEMP_STORE>=2} {
1.39 + set temp_mode normal
1.40 +} else {
1.41 + set temp_mode exclusive
1.42 +}
1.43 +
1.44 +#----------------------------------------------------------------------
1.45 +# Test cases exclusive-1.X test the PRAGMA logic.
1.46 +#
1.47 +do_test exclusive-1.0 {
1.48 + execsql {
1.49 + pragma locking_mode;
1.50 + pragma main.locking_mode;
1.51 + pragma temp.locking_mode;
1.52 + }
1.53 +} [list normal normal $temp_mode]
1.54 +do_test exclusive-1.1 {
1.55 + execsql {
1.56 + pragma locking_mode = exclusive;
1.57 + }
1.58 +} {exclusive}
1.59 +do_test exclusive-1.2 {
1.60 + execsql {
1.61 + pragma locking_mode;
1.62 + pragma main.locking_mode;
1.63 + pragma temp.locking_mode;
1.64 + }
1.65 +} [list exclusive exclusive $temp_mode]
1.66 +do_test exclusive-1.3 {
1.67 + execsql {
1.68 + pragma locking_mode = normal;
1.69 + }
1.70 +} {normal}
1.71 +do_test exclusive-1.4 {
1.72 + execsql {
1.73 + pragma locking_mode;
1.74 + pragma main.locking_mode;
1.75 + pragma temp.locking_mode;
1.76 + }
1.77 +} [list normal normal $temp_mode]
1.78 +do_test exclusive-1.5 {
1.79 + execsql {
1.80 + pragma locking_mode = invalid;
1.81 + }
1.82 +} {normal}
1.83 +do_test exclusive-1.6 {
1.84 + execsql {
1.85 + pragma locking_mode;
1.86 + pragma main.locking_mode;
1.87 + pragma temp.locking_mode;
1.88 + }
1.89 +} [list normal normal $temp_mode]
1.90 +ifcapable attach {
1.91 + do_test exclusive-1.7 {
1.92 + execsql {
1.93 + pragma locking_mode = exclusive;
1.94 + ATTACH 'test2.db' as aux;
1.95 + }
1.96 + execsql {
1.97 + pragma main.locking_mode;
1.98 + pragma aux.locking_mode;
1.99 + }
1.100 + } {exclusive exclusive}
1.101 + do_test exclusive-1.8 {
1.102 + execsql {
1.103 + pragma main.locking_mode = normal;
1.104 + }
1.105 + execsql {
1.106 + pragma main.locking_mode;
1.107 + pragma temp.locking_mode;
1.108 + pragma aux.locking_mode;
1.109 + }
1.110 + } [list normal $temp_mode exclusive]
1.111 + do_test exclusive-1.9 {
1.112 + execsql {
1.113 + pragma locking_mode;
1.114 + }
1.115 + } {exclusive}
1.116 + do_test exclusive-1.10 {
1.117 + execsql {
1.118 + ATTACH 'test3.db' as aux2;
1.119 + }
1.120 + execsql {
1.121 + pragma main.locking_mode;
1.122 + pragma aux.locking_mode;
1.123 + pragma aux2.locking_mode;
1.124 + }
1.125 + } {normal exclusive exclusive}
1.126 + do_test exclusive-1.11 {
1.127 + execsql {
1.128 + pragma aux.locking_mode = normal;
1.129 + }
1.130 + execsql {
1.131 + pragma main.locking_mode;
1.132 + pragma aux.locking_mode;
1.133 + pragma aux2.locking_mode;
1.134 + }
1.135 + } {normal normal exclusive}
1.136 + do_test exclusive-1.12 {
1.137 + execsql {
1.138 + pragma locking_mode = normal;
1.139 + }
1.140 + execsql {
1.141 + pragma main.locking_mode;
1.142 + pragma temp.locking_mode;
1.143 + pragma aux.locking_mode;
1.144 + pragma aux2.locking_mode;
1.145 + }
1.146 + } [list normal $temp_mode normal normal]
1.147 + do_test exclusive-1.13 {
1.148 + execsql {
1.149 + ATTACH 'test4.db' as aux3;
1.150 + }
1.151 + execsql {
1.152 + pragma main.locking_mode;
1.153 + pragma temp.locking_mode;
1.154 + pragma aux.locking_mode;
1.155 + pragma aux2.locking_mode;
1.156 + pragma aux3.locking_mode;
1.157 + }
1.158 + } [list normal $temp_mode normal normal normal]
1.159 +
1.160 + do_test exclusive-1.99 {
1.161 + execsql {
1.162 + DETACH aux;
1.163 + DETACH aux2;
1.164 + DETACH aux3;
1.165 + }
1.166 + } {}
1.167 +}
1.168 +
1.169 +#----------------------------------------------------------------------
1.170 +# Test cases exclusive-2.X verify that connections in exclusive
1.171 +# locking_mode do not relinquish locks.
1.172 +#
1.173 +do_test exclusive-2.0 {
1.174 + execsql {
1.175 + CREATE TABLE abc(a, b, c);
1.176 + INSERT INTO abc VALUES(1, 2, 3);
1.177 + PRAGMA locking_mode = exclusive;
1.178 + }
1.179 +} {exclusive}
1.180 +do_test exclusive-2.1 {
1.181 + sqlite3 db2 test.db
1.182 + execsql {
1.183 + INSERT INTO abc VALUES(4, 5, 6);
1.184 + SELECT * FROM abc;
1.185 + } db2
1.186 +} {1 2 3 4 5 6}
1.187 +do_test exclusive-2.2 {
1.188 + # This causes connection 'db' (in exclusive mode) to establish
1.189 + # a shared-lock on the db. The other connection should now be
1.190 + # locked out as a writer.
1.191 + execsql {
1.192 + SELECT * FROM abc;
1.193 + } db
1.194 +} {1 2 3 4 5 6}
1.195 +do_test exclusive-2.4 {
1.196 + execsql {
1.197 + SELECT * FROM abc;
1.198 + } db2
1.199 +} {1 2 3 4 5 6}
1.200 +do_test exclusive-2.5 {
1.201 + catchsql {
1.202 + INSERT INTO abc VALUES(7, 8, 9);
1.203 + } db2
1.204 +} {1 {database is locked}}
1.205 +sqlite3_soft_heap_limit 0
1.206 +do_test exclusive-2.6 {
1.207 + # Because connection 'db' only has a shared-lock, the other connection
1.208 + # will be able to get a RESERVED, but will fail to upgrade to EXCLUSIVE.
1.209 + execsql {
1.210 + BEGIN;
1.211 + INSERT INTO abc VALUES(7, 8, 9);
1.212 + } db2
1.213 + catchsql {
1.214 + COMMIT
1.215 + } db2
1.216 +} {1 {database is locked}}
1.217 +do_test exclusive-2.7 {
1.218 + catchsql {
1.219 + COMMIT
1.220 + } db2
1.221 +} {1 {database is locked}}
1.222 +do_test exclusive-2.8 {
1.223 + execsql {
1.224 + ROLLBACK;
1.225 + } db2
1.226 +} {}
1.227 +sqlite3_soft_heap_limit $soft_limit
1.228 +
1.229 +do_test exclusive-2.9 {
1.230 + # Write the database to establish the exclusive lock with connection 'db.
1.231 + execsql {
1.232 + INSERT INTO abc VALUES(7, 8, 9);
1.233 + } db
1.234 + catchsql {
1.235 + SELECT * FROM abc;
1.236 + } db2
1.237 +} {1 {database is locked}}
1.238 +do_test exclusive-2.10 {
1.239 + # Changing the locking-mode does not release any locks.
1.240 + execsql {
1.241 + PRAGMA locking_mode = normal;
1.242 + } db
1.243 + catchsql {
1.244 + SELECT * FROM abc;
1.245 + } db2
1.246 +} {1 {database is locked}}
1.247 +do_test exclusive-2.11 {
1.248 + # After changing the locking mode, accessing the db releases locks.
1.249 + execsql {
1.250 + SELECT * FROM abc;
1.251 + } db
1.252 + execsql {
1.253 + SELECT * FROM abc;
1.254 + } db2
1.255 +} {1 2 3 4 5 6 7 8 9}
1.256 +db2 close
1.257 +
1.258 +#----------------------------------------------------------------------
1.259 +# Tests exclusive-3.X - test that a connection in exclusive mode
1.260 +# truncates instead of deletes the journal file when committing
1.261 +# a transaction.
1.262 +#
1.263 +# These tests are not run on windows because the windows backend
1.264 +# opens the journal file for exclusive access, preventing its contents
1.265 +# from being inspected externally.
1.266 +#
1.267 +if {$tcl_platform(platform) != "windows"} {
1.268 + proc filestate {fname} {
1.269 + set exists 0
1.270 + set content 0
1.271 + if {[file exists $fname]} {
1.272 + set exists 1
1.273 + set hdr [hexio_read $fname 0 28]
1.274 + set content \
1.275 + [expr {$hdr!="00000000000000000000000000000000000000000000000000000000"}]
1.276 + }
1.277 + list $exists $content
1.278 + }
1.279 + do_test exclusive-3.0 {
1.280 + filestate test.db-journal
1.281 + } {0 0}
1.282 + do_test exclusive-3.1 {
1.283 + execsql {
1.284 + PRAGMA locking_mode = exclusive;
1.285 + BEGIN;
1.286 + DELETE FROM abc;
1.287 + }
1.288 + filestate test.db-journal
1.289 + } {1 1}
1.290 + do_test exclusive-3.2 {
1.291 + execsql {
1.292 + COMMIT;
1.293 + }
1.294 + filestate test.db-journal
1.295 + } {1 0}
1.296 + do_test exclusive-3.3 {
1.297 + execsql {
1.298 + INSERT INTO abc VALUES('A', 'B', 'C');
1.299 + SELECT * FROM abc;
1.300 + }
1.301 + } {A B C}
1.302 + do_test exclusive-3.4 {
1.303 + execsql {
1.304 + BEGIN;
1.305 + UPDATE abc SET a = 1, b = 2, c = 3;
1.306 + ROLLBACK;
1.307 + SELECT * FROM abc;
1.308 + }
1.309 + } {A B C}
1.310 + do_test exclusive-3.5 {
1.311 + filestate test.db-journal
1.312 + } {1 0}
1.313 + do_test exclusive-3.6 {
1.314 + execsql {
1.315 + PRAGMA locking_mode = normal;
1.316 + SELECT * FROM abc;
1.317 + }
1.318 + filestate test.db-journal
1.319 + } {0 0}
1.320 +}
1.321 +
1.322 +#----------------------------------------------------------------------
1.323 +# Tests exclusive-4.X - test that rollback works correctly when
1.324 +# in exclusive-access mode.
1.325 +#
1.326 +
1.327 +# The following procedure computes a "signature" for table "t3". If
1.328 +# T3 changes in any way, the signature should change.
1.329 +#
1.330 +# This is used to test ROLLBACK. We gather a signature for t3, then
1.331 +# make lots of changes to t3, then rollback and take another signature.
1.332 +# The two signatures should be the same.
1.333 +#
1.334 +proc signature {} {
1.335 + return [db eval {SELECT count(*), md5sum(x) FROM t3}]
1.336 +}
1.337 +
1.338 +do_test exclusive-4.0 {
1.339 + execsql { PRAGMA locking_mode = exclusive; }
1.340 + execsql { PRAGMA default_cache_size = 10; }
1.341 + execsql {
1.342 + BEGIN;
1.343 + CREATE TABLE t3(x TEXT);
1.344 + INSERT INTO t3 VALUES(randstr(10,400));
1.345 + INSERT INTO t3 VALUES(randstr(10,400));
1.346 + INSERT INTO t3 SELECT randstr(10,400) FROM t3;
1.347 + INSERT INTO t3 SELECT randstr(10,400) FROM t3;
1.348 + INSERT INTO t3 SELECT randstr(10,400) FROM t3;
1.349 + INSERT INTO t3 SELECT randstr(10,400) FROM t3;
1.350 + COMMIT;
1.351 + }
1.352 + execsql {SELECT count(*) FROM t3;}
1.353 +} {32}
1.354 +
1.355 +set ::X [signature]
1.356 +do_test exclusive-4.1 {
1.357 + execsql {
1.358 + BEGIN;
1.359 + DELETE FROM t3 WHERE random()%10!=0;
1.360 + INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
1.361 + INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
1.362 + SELECT count(*) FROM t3;
1.363 + ROLLBACK;
1.364 + }
1.365 + signature
1.366 +} $::X
1.367 +
1.368 +do_test exclusive-4.2 {
1.369 + execsql {
1.370 + BEGIN;
1.371 + DELETE FROM t3 WHERE random()%10!=0;
1.372 + INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
1.373 + DELETE FROM t3 WHERE random()%10!=0;
1.374 + INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
1.375 + ROLLBACK;
1.376 + }
1.377 + signature
1.378 +} $::X
1.379 +
1.380 +do_test exclusive-4.3 {
1.381 + execsql {
1.382 + INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
1.383 + }
1.384 +} {}
1.385 +
1.386 +do_test exclusive-4.4 {
1.387 + catch {set ::X [signature]}
1.388 +} {0}
1.389 +do_test exclusive-4.5 {
1.390 + execsql {
1.391 + PRAGMA locking_mode = NORMAL;
1.392 + DROP TABLE t3;
1.393 + DROP TABLE abc;
1.394 + }
1.395 +} {normal}
1.396 +
1.397 +#----------------------------------------------------------------------
1.398 +# Tests exclusive-5.X - test that statement journals are truncated
1.399 +# instead of deleted when in exclusive access mode.
1.400 +#
1.401 +
1.402 +# Close and reopen the database so that the temp database is no
1.403 +# longer active.
1.404 +#
1.405 +db close
1.406 +sqlite db test.db
1.407 +
1.408 +
1.409 +do_test exclusive-5.0 {
1.410 + execsql {
1.411 + CREATE TABLE abc(a UNIQUE, b UNIQUE, c UNIQUE);
1.412 + BEGIN;
1.413 + INSERT INTO abc VALUES(1, 2, 3);
1.414 + INSERT INTO abc SELECT a+1, b+1, c+1 FROM abc;
1.415 + }
1.416 +} {}
1.417 +do_test exclusive-5.1 {
1.418 + # Three files are open: The db, journal and statement-journal.
1.419 + set sqlite_open_file_count
1.420 +} {3}
1.421 +do_test exclusive-5.2 {
1.422 + execsql {
1.423 + COMMIT;
1.424 + }
1.425 + # One file open: the db.
1.426 + set sqlite_open_file_count
1.427 +} {1}
1.428 +do_test exclusive-5.3 {
1.429 + execsql {
1.430 + PRAGMA locking_mode = exclusive;
1.431 + BEGIN;
1.432 + INSERT INTO abc VALUES(5, 6, 7);
1.433 + }
1.434 + # Two files open: the db and journal.
1.435 + set sqlite_open_file_count
1.436 +} {2}
1.437 +do_test exclusive-5.4 {
1.438 + execsql {
1.439 + INSERT INTO abc SELECT a+10, b+10, c+10 FROM abc;
1.440 + }
1.441 + # Three files are open: The db, journal and statement-journal.
1.442 + set sqlite_open_file_count
1.443 +} {3}
1.444 +do_test exclusive-5.5 {
1.445 + execsql {
1.446 + COMMIT;
1.447 + }
1.448 + # Three files are still open: The db, journal and statement-journal.
1.449 + set sqlite_open_file_count
1.450 +} {3}
1.451 +do_test exclusive-5.6 {
1.452 + execsql {
1.453 + PRAGMA locking_mode = normal;
1.454 + SELECT * FROM abc;
1.455 + }
1.456 +} {normal 1 2 3 2 3 4 5 6 7 11 12 13 12 13 14 15 16 17}
1.457 +do_test exclusive-5.7 {
1.458 + # Just the db open.
1.459 + set sqlite_open_file_count
1.460 +} {1}
1.461 +
1.462 +finish_test