gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/walslow.test (about)

     1  # 2010 March 17
     2  #
     3  # The author disclaims copyright to this source code.  In place of
     4  # 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
    12  # focus of this file is testing the operation of the library in
    13  # "PRAGMA journal_mode=WAL" mode. The tests in this file use 
    14  # brute force methods, so may take a while to run.
    15  #
    16  
    17  set testdir [file dirname $argv0]
    18  source $testdir/tester.tcl
    19  source $testdir/wal_common.tcl
    20  source $testdir/lock_common.tcl
    21  
    22  ifcapable !wal {finish_test ; return }
    23  
    24  set testprefix walslow
    25  
    26  proc reopen_db {} {
    27    catch { db close }
    28    forcedelete test.db test.db-wal
    29    sqlite3 db test.db
    30    execsql { PRAGMA journal_mode = wal }
    31  }
    32  
    33  db close
    34  save_prng_state
    35  for {set seed 1} {$seed<10} {incr seed} {
    36    expr srand($seed)
    37    restore_prng_state
    38    reopen_db
    39    do_test walslow-1.seed=$seed.0 {
    40      execsql { CREATE TABLE t1(a, b) }
    41      execsql { CREATE INDEX i1 ON t1(a) }
    42      execsql { CREATE INDEX i2 ON t1(b) }
    43    } {}
    44  
    45    for {set iTest 1} {$iTest < 100} {incr iTest} {
    46  
    47      do_test walslow-1.seed=$seed.$iTest.1 {
    48        set w [expr int(rand()*2000)]
    49        set x [expr int(rand()*2000)]
    50        execsql { INSERT INTO t1 VALUES(randomblob($w), randomblob($x)) }
    51        execsql { PRAGMA integrity_check }
    52      } {ok}
    53  
    54      do_test walslow-1.seed=$seed.$iTest.2 {
    55        execsql "PRAGMA wal_checkpoint;"
    56        execsql { PRAGMA integrity_check }
    57      } {ok}
    58  
    59      do_test walslow-1.seed=$seed.$iTest.3 {
    60        forcedelete testX.db testX.db-wal
    61        copy_file test.db testX.db
    62        copy_file test.db-wal testX.db-wal
    63    
    64        sqlite3 db2 testX.db
    65        execsql { PRAGMA journal_mode = WAL } db2
    66        execsql { PRAGMA integrity_check } db2
    67      } {ok}
    68    
    69      do_test walslow-1.seed=$seed.$iTest.4 {
    70        execsql { SELECT count(*) FROM t1 WHERE a!=b } db2
    71      } [execsql { SELECT count(*) FROM t1 WHERE a!=b }]
    72      db2 close
    73    }
    74  }
    75  
    76  #-------------------------------------------------------------------------
    77  # Test case walslow-3.* tests that the checksum calculation detects single 
    78  # byte changes to frame or frame-header data and considers the frame
    79  # invalid as a result.
    80  #
    81  reset_db
    82  do_test 3.1 {
    83  
    84    execsql {
    85      PRAGMA synchronous = NORMAL;
    86      PRAGMA page_size = 1024;
    87      CREATE TABLE t1(a, b);
    88      INSERT INTO t1 VALUES(1, randomblob(300));
    89      INSERT INTO t1 VALUES(2, randomblob(300));
    90      PRAGMA journal_mode = WAL;
    91      INSERT INTO t1 VALUES(3, randomblob(300));
    92    }
    93  
    94    file size test.db-wal
    95  } [wal_file_size 1 1024]
    96  do_test 3.2 {
    97    forcecopy test.db-wal test2.db-wal
    98    forcecopy test.db test2.db
    99    sqlite3 db2 test2.db
   100    execsql { SELECT a FROM t1 } db2
   101  } {1 2 3}
   102  db2 close
   103  forcecopy test.db test2.db
   104  
   105  foreach incr {1 2 3 20 40 60 80 100 120 140 160 180 200 220 240 253 254 255} {
   106    do_test 3.3.$incr {
   107      set FAIL 0
   108      for {set iOff 0} {$iOff < [wal_file_size 1 1024]} {incr iOff} {
   109  
   110        forcecopy test.db-wal test2.db-wal
   111        set fd [open test2.db-wal r+]
   112        fconfigure $fd -encoding binary
   113        fconfigure $fd -translation binary
   114    
   115        seek $fd $iOff
   116        binary scan [read $fd 1] c x
   117        seek $fd $iOff
   118        puts -nonewline $fd [binary format c [expr {($x+$incr)&0xFF}]]
   119        close $fd
   120      
   121        sqlite3 db2 test2.db
   122        if { [execsql { SELECT a FROM t1 } db2] != "1 2" } {set FAIL 1}
   123        db2 close
   124      }
   125      set FAIL
   126    } {0}
   127  }
   128  
   129  
   130  #-------------------------------------------------------------------------
   131  # Test large log summaries.
   132  #
   133  # In this case "large" usually means a log file that requires a wal-index
   134  # mapping larger than 64KB (the default initial allocation). A 64KB wal-index
   135  # is large enough for a log file that contains approximately 13100 frames.
   136  # So the following tests create logs containing at least this many frames.
   137  #
   138  # 4.1.*: This test case creates a very large log file within the
   139  #        file-system (around 200MB). The log file does not contain
   140  #        any valid frames. Test that the database file can still be
   141  #        opened and queried, and that the invalid log file causes no 
   142  #        problems.
   143  #
   144  # 4.2.*: Test that a process may create a large log file and query
   145  #        the database (including the log file that it itself created).
   146  #
   147  # 4.3.*: Test that if a very large log file is created, and then a
   148  #        second connection is opened on the database file, it is possible
   149  #        to query the database (and the very large log) using the
   150  #        second connection.
   151  #
   152  # 4.4.*: Same test as wal-13.3.*. Except in this case the second
   153  #        connection is opened by an external process.
   154  #
   155  set ::blobcnt 0
   156  proc blob {nByte} {
   157    incr ::blobcnt
   158    return [string range [string repeat "${::blobcnt}x" $nByte] 1 $nByte]
   159  }
   160  
   161  reset_db
   162  do_execsql_test 4.1 {
   163    PRAGMA journal_mode = wal;
   164    CREATE TABLE t1(x, y);
   165    INSERT INTO "t1" VALUES('A',0);
   166    CREATE TABLE t2(x, y);
   167    INSERT INTO "t2" VALUES('B',2);
   168  } {wal}
   169  db close
   170  
   171  do_test 4.1.1 {
   172    list [file exists test.db] [file exists test.db-wal]
   173  } {1 0}
   174  do_test 4.1.2 {
   175    set fd [open test.db-wal w]
   176    seek $fd [expr 200*1024*1024]
   177    puts $fd ""
   178    close $fd
   179    sqlite3 db test.db
   180    execsql { SELECT * FROM t2 }
   181  } {B 2}
   182  do_test 4.1.3 {
   183    db close
   184    file exists test.db-wal
   185  } {0}
   186  
   187  do_test 4.2.1 {
   188    sqlite3 db test.db
   189    execsql { SELECT count(*) FROM t2 }
   190  } {1}
   191  do_test 4.2.2 {
   192    db function blob blob
   193    for {set i 0} {$i < 16} {incr i} {
   194      execsql { INSERT INTO t2 SELECT blob(400), blob(400) FROM t2 }
   195    }
   196    execsql { SELECT count(*) FROM t2 }
   197  } [expr int(pow(2, 16))]
   198  do_test 4.2.3 {
   199    expr [file size test.db-wal] > [wal_file_size 33000 1024]
   200  } 1
   201  
   202  do_multiclient_test tn {
   203    incr tn 2
   204  
   205    do_test 4.$tn.0 {
   206      sql1 {
   207        PRAGMA journal_mode = WAL;
   208        CREATE TABLE t1(x);
   209        INSERT INTO t1 SELECT randomblob(800);
   210      }
   211      sql1 { SELECT count(*) FROM t1 }
   212    } {1}
   213  
   214    for {set ii 1} {$ii<16} {incr ii} {
   215      do_test 4.$tn.$ii.a {
   216        sql2 { INSERT INTO t1 SELECT randomblob(800) FROM t1 }
   217        sql2 { SELECT count(*) FROM t1 }
   218      } [expr (1<<$ii)]
   219      do_test 4.$tn.$ii.b {
   220        sql1 { SELECT count(*) FROM t1 }
   221      } [expr (1<<$ii)]
   222      do_test 4.$tn.$ii.c {
   223        sql1 { SELECT count(*) FROM t1 }
   224      } [expr (1<<$ii)]
   225      do_test 4.$tn.$ii.d {
   226        sql1 { PRAGMA integrity_check }
   227      } {ok}
   228    }
   229  }
   230  
   231  finish_test