CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
exclusive2.test325 linesDownload Raw Back to test
1# 2007 March 242#3# The author disclaims copyright to this source code.  In place of4# a legal notice, here is a blessing:5#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.9#10#***********************************************************************11# This file implements regression tests for SQLite library.12#13# $Id: exclusive2.test,v 1.10 2008/11/27 02:22:11 drh Exp $14 15set testdir [file dirname $argv0]16source $testdir/tester.tcl17 18# Do not use a codec for tests in this file, as the database file is19# manipulated directly using tcl scripts (using the [hexio_write] command).20#21do_not_use_codec22 23ifcapable {!pager_pragmas} {24  finish_test25  return26}27 28# Tests in this file verify that locking_mode=exclusive causes SQLite to29# use cached pages even if the database is changed on disk. This doesn't30# work with mmap.31if {[permutation]=="mmap"} {32  finish_test33  return34}35 36# This module does not work right if the cache spills at unexpected37# moments.  So disable the soft-heap-limit.38#39sqlite3_soft_heap_limit 040 41proc pagerChangeCounter {filename new {fd ""}} {42  if {$fd==""} {43    set fd [open $filename RDWR]44    fconfigure $fd -translation binary45    set needClose 146  } else {47    set needClose 048  }49  if {$new ne ""} {50    seek $fd 2451    set a [expr {($new&0xFF000000)>>24}]52    set b [expr {($new&0x00FF0000)>>16}]53    set c [expr {($new&0x0000FF00)>>8}]54    set d [expr {($new&0x000000FF)}]55    puts -nonewline $fd [binary format cccc $a $b $c $d]56    flush $fd57  }58 59  seek $fd 2460  foreach {a b c d} [list 0 0 0 0] {}61  binary scan [read $fd 4] cccc a b c d62  set  ret [expr ($a&0x000000FF)<<24]63  incr ret [expr ($b&0x000000FF)<<16]64  incr ret [expr ($c&0x000000FF)<<8]65  incr ret [expr ($d&0x000000FF)<<0]66 67  if {$needClose} {close $fd}68  return $ret69}70 71proc readPagerChangeCounter {filename} {72  set fd [open $filename RDONLY]73  fconfigure $fd -translation binary74 75  seek $fd 2476  foreach {a b c d} [list 0 0 0 0] {}77  binary scan [read $fd 4] cccc a b c d78  set  ret [expr ($a&0x000000FF)<<24]79  incr ret [expr ($b&0x000000FF)<<16]80  incr ret [expr ($c&0x000000FF)<<8]81  incr ret [expr ($d&0x000000FF)<<0]82 83  close $fd84  return $ret85}86 87 88proc t1sig {{db db}} {89  execsql {SELECT count(*), md5sum(a) FROM t1} $db90}91do_test exclusive2-1.0 {92  readPagerChangeCounter test.db93} {0}94 95#-----------------------------------------------------------------------96# The following tests - exclusive2-1.X - check that:97#98# 1-3:   Build a database with connection 1, calculate a signature.99# 4-7:   Modify the database using a second connection in a way that100#        does not modify the freelist, then reset the pager change-counter101#        to the value it had before the modifications.102# 8:     Check that using the first connection, the database signature103#        is still the same. This is because it uses the in-memory cache.104#        It can't tell the db has changed because we reset the change-counter.105# 9:     Increment the change-counter.106# 10:    Ensure that the first connection now sees the updated database. It107#        sees the change-counter has been incremented and discards the 108#        invalid in-memory cache.109#110# This will only work if the database cache is large enough to hold 111# the entire database. In the case of 1024 byte pages, this means112# the cache size must be at least 17. Otherwise, some pages will be113# loaded from the database file in step 8.114#115# For similar reasons, this test does not work with the memsubsys1 permutation.116# Permutation memsubsys1 configures the pcache subsystem to use a static117# allocation of 24 pages (shared between all pagers). This is not enough for118# this test.119#120do_test exclusive2-1.1 {121  execsql {122    BEGIN;123    CREATE TABLE t1(a, b);124    INSERT INTO t1(a, b) VALUES(randstr(10, 400), 0);125    INSERT INTO t1(a, b) VALUES(randstr(10, 400), 0);126    INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1;127    INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1;128    INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1;129    INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1;130    INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1;131    COMMIT;132    SELECT count(*) FROM t1;133  }134} {64}135do_test exclusive2-1.2.1 {136  # Make sure the pager cache is large enough to store the 137  # entire database.138  set nPage [expr [file size test.db]/1024]139  if {$::SQLITE_DEFAULT_CACHE_SIZE < $nPage} {140    execsql "PRAGMA cache_size = $nPage"141  }142  expr {[execsql {PRAGMA cache_size}] >= $nPage}143} {1}144do_test exclusive2-1.2 {145  set ::sig [t1sig]146  readPagerChangeCounter test.db147} {1}148do_test exclusive2-1.3 {149  t1sig150} $::sig151do_test exclusive2-1.4 {152  sqlite3 db2 test.db153  t1sig db2154} $::sig155do_test exclusive2-1.5 {156  execsql {157    UPDATE t1 SET b=a, a=0;158  } db2159  expr {[t1sig db2] eq $::sig}160} 0161do_test exclusive2-1.6 {162  readPagerChangeCounter test.db163} {2}164do_test exclusive2-1.7 {165  pagerChangeCounter test.db 1166} {1}167if {[permutation] != "memsubsys1"} {168  do_test exclusive2-1.9 {169    t1sig170    expr {[t1sig] eq $::sig}171  } {1}172}173do_test exclusive2-1.10 {174  pagerChangeCounter test.db 2175} {2}176do_test exclusive2-1.11 {177  expr {[t1sig] eq $::sig}178} {0}179db2 close180 181#--------------------------------------------------------------------182# These tests - exclusive2-2.X - are similar to exclusive2-1.X, 183# except that they are run with locking_mode=EXCLUSIVE.184#185# 1-3:   Build a database with exclusive-access connection 1, 186#        calculate a signature.187# 4:     Corrupt the database by writing 10000 bytes of garbage188#        starting at the beginning of page 2. Check that connection 1189#        still works. It should be accessing the in-memory cache.190# 5-6:   Modify the dataase change-counter. Connection 1 still works191#        entirely from in-memory cache, because it doesn't check the192#        change-counter.193# 7-8    Set the locking-mode back to normal. After the db is unlocked,194#        SQLite detects the modified change-counter and discards the195#        in-memory cache. Then it finds the corruption caused in step 4....196#197# As above, this test is only applicable if the pager cache is198# large enough to hold the entire database. With 1024 byte pages,199# this means 19 pages.  We also need to disable the soft-heap-limit200# to prevent memory-induced cache spills.201#202do_test exclusive2-2.1 {203  execsql {PRAGMA cache_size=1000;}204  execsql {PRAGMA locking_mode = exclusive;}205  execsql {206    BEGIN;207    DELETE FROM t1;208    INSERT INTO t1(a) VALUES(randstr(10, 400));209    INSERT INTO t1(a) VALUES(randstr(10, 400));210    INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;211    INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;212    INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;213    INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;214    INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;215    COMMIT;216    SELECT count(*) FROM t1;217  }218} {64}219do_test exclusive2-2.2.1 {220  # Make sure the pager cache is large enough to store the 221  # entire database.222  set nPage [expr [file size test.db]/1024]223  if {$::SQLITE_DEFAULT_CACHE_SIZE < $nPage} {224    execsql "PRAGMA cache_size = $nPage"225  }226  expr {[execsql {PRAGMA cache_size}] >= $nPage}227} {1}228do_test exclusive2-2.2 {229  set ::sig [t1sig]230  readPagerChangeCounter test.db231} {3}232do_test exclusive2-2.3 {233  t1sig234} $::sig235 236do_test exclusive2-2.4 {237  set ::fd [open test.db RDWR]238  fconfigure $::fd -translation binary239  seek $::fd 1024240  puts -nonewline $::fd [string repeat [binary format c 0] 10000]241  flush $::fd242  t1sig243} $::sig244 245do_test exclusive2-2.5 {246  pagerChangeCounter test.db 5 $::fd247} {5}248do_test exclusive2-2.6 {249  t1sig250} $::sig251do_test exclusive2-2.7 {252  execsql {PRAGMA locking_mode = normal}253  t1sig254} $::sig255 256do_test exclusive2-2.8 {257  set rc [catch {t1sig} msg]258  list $rc $msg259} {1 {database disk image is malformed}}260 261#--------------------------------------------------------------------262# These tests - exclusive2-3.X - verify that the pager change-counter263# is only incremented by the first change when in exclusive access264# mode. In normal mode, the change-counter is incremented once265# per write-transaction.266#267 268db close269catch {close $::fd}270forcedelete test.db271forcedelete test.db-journal272 273do_test exclusive2-3.0 {274  sqlite3 db test.db275  execsql {276    BEGIN;277    CREATE TABLE t1(a UNIQUE);278    INSERT INTO t1 VALUES(randstr(200, 200));279    INSERT INTO t1 VALUES(randstr(200, 200));280    COMMIT;281  }282  readPagerChangeCounter test.db283} {1}284do_test exclusive2-3.1 {285  execsql {286    INSERT INTO t1 VALUES(randstr(200, 200));287  }288  readPagerChangeCounter test.db289} {2}290do_test exclusive2-3.2 {291  execsql {292    INSERT INTO t1 VALUES(randstr(200, 200));293  }294  readPagerChangeCounter test.db295} {3}296do_test exclusive2-3.3 {297  execsql {298    PRAGMA locking_mode = exclusive;299    INSERT INTO t1 VALUES(randstr(200, 200));300  }301  readPagerChangeCounter test.db302} {4}303do_test exclusive2-3.4 {304  execsql {305    INSERT INTO t1 VALUES(randstr(200, 200));306  }307  readPagerChangeCounter test.db308} {4}309do_test exclusive2-3.5 {310  execsql {311    PRAGMA locking_mode = normal;312    INSERT INTO t1 VALUES(randstr(200, 200));313  }314  readPagerChangeCounter test.db315} {4}316do_test exclusive2-3.6 {317  execsql {318    INSERT INTO t1 VALUES(randstr(200, 200));319  }320  readPagerChangeCounter test.db321} {5}322sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)323 324finish_test325