os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/exclusive.test
changeset 0 bde4ae8d615e
     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