CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
exclusive.test541 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. The focus12# of these tests is exclusive access mode (i.e. the thing activated by 13# "PRAGMA locking_mode = EXCLUSIVE").14#15# $Id: exclusive.test,v 1.15 2009/06/26 12:30:40 danielk1977 Exp $16 17set testdir [file dirname $argv0]18source $testdir/tester.tcl19 20ifcapable {!pager_pragmas} {21  finish_test22  return23}24 25forcedelete test2.db-journal26forcedelete test2.db27forcedelete test3.db-journal28forcedelete test3.db29forcedelete test4.db-journal30forcedelete test4.db31 32#----------------------------------------------------------------------33# Test cases exclusive-1.X test the PRAGMA logic.34#35do_test exclusive-1.0 {36  execsql {37    pragma locking_mode;38    pragma main.locking_mode;39    pragma temp.locking_mode;40  } 41} [list normal normal exclusive]42do_test exclusive-1.1 {43  execsql {44    pragma locking_mode = exclusive;45  } 46} {exclusive}47do_test exclusive-1.2 {48  execsql {49    pragma locking_mode;50    pragma main.locking_mode;51    pragma temp.locking_mode;52  } 53} [list exclusive exclusive exclusive]54do_test exclusive-1.3 {55  execsql {56    pragma locking_mode = normal;57  } 58} {normal}59do_test exclusive-1.4 {60  execsql {61    pragma locking_mode;62    pragma main.locking_mode;63    pragma temp.locking_mode;64  } 65} [list normal normal exclusive]66do_test exclusive-1.5 {67  execsql {68    pragma locking_mode = invalid;69  } 70} {normal}71do_test exclusive-1.6 {72  execsql {73    pragma locking_mode;74    pragma main.locking_mode;75    pragma temp.locking_mode;76  } 77} [list normal normal exclusive]78ifcapable attach {79  do_test exclusive-1.7 {80    execsql {81      pragma locking_mode = exclusive;82      ATTACH 'test2.db' as aux;83    }84    execsql {85      pragma main.locking_mode;86      pragma aux.locking_mode;87    }88  } {exclusive exclusive}89  do_test exclusive-1.8 {90    execsql {91      pragma main.locking_mode = normal;92    }93    execsql {94      pragma main.locking_mode;95      pragma temp.locking_mode;96      pragma aux.locking_mode;97    }98  } [list normal exclusive exclusive]99  do_test exclusive-1.9 {100    execsql {101      pragma locking_mode;102    }103  } {exclusive}104  do_test exclusive-1.10 {105    execsql {106      ATTACH 'test3.db' as aux2;107    }108    execsql {109      pragma main.locking_mode;110      pragma aux.locking_mode;111      pragma aux2.locking_mode;112    }113  } {normal exclusive exclusive}114  do_test exclusive-1.11 {115    execsql {116      pragma aux.locking_mode = normal;117    }118    execsql {119      pragma main.locking_mode;120      pragma aux.locking_mode;121      pragma aux2.locking_mode;122    }123  } {normal normal exclusive}124  do_test exclusive-1.12 {125    execsql {126      pragma locking_mode = normal;127    }128    execsql {129      pragma main.locking_mode;130      pragma temp.locking_mode;131      pragma aux.locking_mode;132      pragma aux2.locking_mode;133    }134  } [list normal exclusive normal normal]135  do_test exclusive-1.13 {136    execsql {137      ATTACH 'test4.db' as aux3;138    }139    execsql {140      pragma main.locking_mode;141      pragma temp.locking_mode;142      pragma aux.locking_mode;143      pragma aux2.locking_mode;144      pragma aux3.locking_mode;145    }146  } [list normal exclusive normal normal normal]147  148  do_test exclusive-1.99 {149    execsql {150      DETACH aux;151      DETACH aux2;152      DETACH aux3;153    }154  } {}155}156 157#----------------------------------------------------------------------158# Test cases exclusive-2.X verify that connections in exclusive 159# locking_mode do not relinquish locks.160#161do_test exclusive-2.0 {162  execsql {163    CREATE TABLE abc(a, b, c);164    INSERT INTO abc VALUES(1, 2, 3);165    PRAGMA locking_mode = exclusive;166  }167} {exclusive}168do_test exclusive-2.1 {169  sqlite3 db2 test.db170  execsql {171    INSERT INTO abc VALUES(4, 5, 6);172    SELECT * FROM abc;173  } db2174} {1 2 3 4 5 6}175do_test exclusive-2.2 {176  # This causes connection 'db' (in exclusive mode) to establish 177  # a shared-lock on the db. The other connection should now be178  # locked out as a writer.179  execsql {180    SELECT * FROM abc;181  } db182} {1 2 3 4 5 6}183do_test exclusive-2.4 {184  execsql {185    SELECT * FROM abc;186  } db2187} {1 2 3 4 5 6}188do_test exclusive-2.5 {189  catchsql {190    INSERT INTO abc VALUES(7, 8, 9);191  } db2192} {1 {database is locked}}193sqlite3_soft_heap_limit 0194do_test exclusive-2.6 {195  # Because connection 'db' only has a shared-lock, the other connection196  # will be able to get a RESERVED, but will fail to upgrade to EXCLUSIVE.197  execsql {198    BEGIN;199    INSERT INTO abc VALUES(7, 8, 9);200  } db2201  catchsql {202    COMMIT203  } db2204} {1 {database is locked}}205do_test exclusive-2.7 {206  catchsql {207    COMMIT208  } db2209} {1 {database is locked}}210do_test exclusive-2.8 {211  execsql {212    ROLLBACK;213  } db2214} {}215sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)216 217do_test exclusive-2.9 {218  # Write the database to establish the exclusive lock with connection 'db.219  execsql {220    INSERT INTO abc VALUES(7, 8, 9);221  } db222  catchsql {223    SELECT * FROM abc;224  } db2225} {1 {database is locked}}226do_test exclusive-2.10 {227  # Changing the locking-mode does not release any locks.228  execsql {229    PRAGMA locking_mode = normal;230  } db231  catchsql {232    SELECT * FROM abc;233  } db2234} {1 {database is locked}}235do_test exclusive-2.11 {236  # After changing the locking mode, accessing the db releases locks.237  execsql {238    SELECT * FROM abc;239  } db240  execsql {241    SELECT * FROM abc;242  } db2243} {1 2 3 4 5 6 7 8 9}244db2 close245 246#----------------------------------------------------------------------247# Tests exclusive-3.X - test that a connection in exclusive mode 248# truncates instead of deletes the journal file when committing 249# a transaction.250#251# These tests are not run on windows because the windows backend252# opens the journal file for exclusive access, preventing its contents 253# from being inspected externally.254#255if {$tcl_platform(platform) != "windows"256 && [atomic_batch_write test.db]==0257} {258 259  # Return a list of two booleans (either 0 or 1). The first is true260  # if the named file exists. The second is true only if the file261  # exists and the first 28 bytes contain at least one non-zero byte.262  #263  proc filestate {fname} {264    set exists 0265    set content 0266    if {[file exists $fname]} {267      set exists 1268      set hdr [hexio_read $fname 0 28]269      set content [expr {0==[string match $hdr [string repeat 0 56]]}]270    }271    list $exists $content272  }273 274  do_test exclusive-3.0 {275    filestate test.db-journal276  } {0 0}277  do_test exclusive-3.1 {278    execsql {279      PRAGMA locking_mode = exclusive;280      BEGIN;281      DELETE FROM abc;282    }283    filestate test.db-journal284  } {1 1}285  do_test exclusive-3.2 {286    execsql {287      COMMIT;288    }289    filestate test.db-journal290  } {1 0}291  do_test exclusive-3.3 {292    execsql {293      INSERT INTO abc VALUES('A', 'B', 'C');294      SELECT * FROM abc;295    }296  } {A B C}297  do_test exclusive-3.4 {298    execsql {299      BEGIN;300      UPDATE abc SET a = 1, b = 2, c = 3;301      ROLLBACK;302      SELECT * FROM abc;303    }304  } {A B C}305  do_test exclusive-3.5 {306    filestate test.db-journal307  } {1 0}308  do_test exclusive-3.6 {309    execsql {310      PRAGMA locking_mode = normal;311      SELECT * FROM abc;312    }313    filestate test.db-journal314  } {0 0}315}316 317#----------------------------------------------------------------------318# Tests exclusive-4.X - test that rollback works correctly when319# in exclusive-access mode.320#321 322# The following procedure computes a "signature" for table "t3".  If323# T3 changes in any way, the signature should change.  324#325# This is used to test ROLLBACK.  We gather a signature for t3, then326# make lots of changes to t3, then rollback and take another signature.327# The two signatures should be the same.328#329proc signature {} {330  return [db eval {SELECT count(*), md5sum(x) FROM t3}]331}332 333do_test exclusive-4.0 {334  execsql { PRAGMA locking_mode = exclusive; }335  execsql { PRAGMA default_cache_size = 10; }336  execsql {337    BEGIN;338    CREATE TABLE t3(x TEXT);339    INSERT INTO t3 VALUES(randstr(10,400));340    INSERT INTO t3 VALUES(randstr(10,400));341    INSERT INTO t3 SELECT randstr(10,400) FROM t3;342    INSERT INTO t3 SELECT randstr(10,400) FROM t3;343    INSERT INTO t3 SELECT randstr(10,400) FROM t3;344    INSERT INTO t3 SELECT randstr(10,400) FROM t3;345    COMMIT;346  }347  execsql {SELECT count(*) FROM t3;}348} {32}349 350set ::X [signature]351do_test exclusive-4.1 {352  execsql {353    BEGIN;354    DELETE FROM t3 WHERE random()%10!=0;355    INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;356    INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;357    SELECT count(*) FROM t3;358    ROLLBACK;359  }360  signature361} $::X362 363do_test exclusive-4.2 {364  execsql {365    BEGIN;366    DELETE FROM t3 WHERE random()%10!=0;367    INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;368    DELETE FROM t3 WHERE random()%10!=0;369    INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;370    ROLLBACK;371  }372  signature373} $::X374 375do_test exclusive-4.3 {376  execsql {377    INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;378  }379} {}380 381do_test exclusive-4.4 {382  catch {set ::X [signature]}383} {0}384do_test exclusive-4.5 {385  execsql {386    PRAGMA locking_mode = NORMAL;387    DROP TABLE t3;388    DROP TABLE abc;389  }390} {normal}391 392#----------------------------------------------------------------------393# Tests exclusive-5.X - test that statement journals are truncated394# instead of deleted when in exclusive access mode.395#396if {[atomic_batch_write test.db]==0} {397 398# Close and reopen the database so that the temp database is no399# longer active.400#401db close402sqlite3 db test.db403 404# if we're using proxy locks, we use 3 filedescriptors for a db405# that is open but NOT writing changes, normally406# sqlite uses 1 (proxy locking adds the conch and the local lock)407set using_proxy 0408foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {409  set using_proxy $value410}411set extrafds 0412if {$using_proxy!=0} {413  set extrafds 2414} 415 416do_test exclusive-5.0 {417  execsql {418    CREATE TABLE abc(a UNIQUE, b UNIQUE, c UNIQUE);419    BEGIN;420    INSERT INTO abc VALUES(1, 2, 3);421    INSERT INTO abc SELECT a+1, b+1, c+1 FROM abc;422  }423} {}424do_test exclusive-5.1 {425  # Three files are open: The db, journal and statement-journal.426  # (2016-03-04) The statement-journal is now opened lazily427  set sqlite_open_file_count428  expr $sqlite_open_file_count-$extrafds429} {2}430do_test exclusive-5.2 {431  execsql {432    COMMIT;433  }434  # One file open: the db.435  set sqlite_open_file_count436  expr $sqlite_open_file_count-$extrafds437} {1}438do_test exclusive-5.3 {439  execsql {440    PRAGMA locking_mode = exclusive;441    BEGIN;442    INSERT INTO abc VALUES(5, 6, 7);443  }444  # Two files open: the db and journal.445  set sqlite_open_file_count446  expr $sqlite_open_file_count-$extrafds447} {2}448do_test exclusive-5.4 {449  execsql {450    INSERT INTO abc SELECT a+10, b+10, c+10 FROM abc;451  }452  # Three files are open: The db, journal and statement-journal.453  # 2016-03-04: The statement-journal open is deferred454  set sqlite_open_file_count455  expr $sqlite_open_file_count-$extrafds456} {2}457do_test exclusive-5.5 {458  execsql {459    COMMIT;460  }461  # Three files are still open: The db, journal and statement-journal.462  # 2016-03-04: The statement-journal open is deferred463  set sqlite_open_file_count464  expr $sqlite_open_file_count-$extrafds465} {2}466do_test exclusive-5.6 {467  execsql {468    PRAGMA locking_mode = normal;469    SELECT * FROM abc;470  }471} {normal 1 2 3 2 3 4 5 6 7 11 12 13 12 13 14 15 16 17}472do_test exclusive-5.7 {473  # Just the db open.474  set sqlite_open_file_count475  expr $sqlite_open_file_count-$extrafds476} {1}477 478#-------------------------------------------------------------------------479 480do_execsql_test exclusive-6.1 {481  CREATE TABLE t4(a, b);482  INSERT INTO t4 VALUES('Eden', 1955);483  BEGIN;484    INSERT INTO t4 VALUES('Macmillan', 1957);485    INSERT INTO t4 VALUES('Douglas-Home', 1963);486    INSERT INTO t4 VALUES('Wilson', 1964);487}488do_test exclusive-6.2 {489  forcedelete test2.db test2.db-journal490  copy_file test.db test2.db491  copy_file test.db-journal test2.db-journal492  sqlite3 db test2.db493} {}494 495do_execsql_test exclusive-6.3 {496  PRAGMA locking_mode = EXCLUSIVE;497  SELECT * FROM t4;498} {exclusive Eden 1955}499 500do_test exclusive-6.4 {501  db close502  forcedelete test.db test.db-journal503  set fd [open test.db-journal w]504  puts $fd x505  close $fd506  sqlite3 db test.db507} {}508 509do_execsql_test exclusive-6.5 {510  PRAGMA locking_mode = EXCLUSIVE;511  SELECT * FROM sqlite_master;512} {exclusive}513 514# 2019-12-26 ticket fb3b3024ea238d5c515if {[permutation]!="journaltest"} {516  # The custom VFS used by the "journaltest" permutation cannot open the517  # shared-memory file. So, while it is able to switch the db file to518  # journal_mode=WAL when locking_mode=EXCLUSIVE, it can no longer access519  # it once the locking_mode is changed back to NORMAL.520  do_test exclusive-7.1 {521    db close522    forcedelete test.db test.db-journal test.db-wal523    sqlite3 db test.db524    # The following sequence of pragmas would trigger an assert()525    # associated with Pager.changeCountDone inside of assert_pager_state(),526    # prior to the fix.527    db eval {528      PRAGMA locking_mode = EXCLUSIVE;529      PRAGMA journal_mode = WAL;530      PRAGMA locking_mode = NORMAL;531      PRAGMA user_version;532      PRAGMA journal_mode = DELETE;533    }534  } {exclusive wal normal 0 delete}535}536 537 538} ;# atomic_batch_write==0539 540finish_test541