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

     1  # 2010 February 8
     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 when
    13  # recovering a database following a simulated system failure in 
    14  # "PRAGMA journal_mode=WAL" mode.
    15  #
    16  
    17  #
    18  # These are 'warm-body' tests of database recovery used while developing 
    19  # the WAL code. They serve to prove that a few really simple cases work:
    20  #
    21  # walcrash-1.*: Recover a database.
    22  # walcrash-2.*: Recover a database where the failed transaction spanned more
    23  #               than one page.
    24  # walcrash-3.*: Recover multiple databases where the failed transaction 
    25  #               was a multi-file transaction.
    26  #
    27  
    28  set testdir [file dirname $argv0]
    29  source $testdir/tester.tcl
    30  ifcapable !wal {finish_test ; return }
    31  
    32  db close
    33  
    34  set seed 0
    35  set REPEATS 100
    36  
    37  # walcrash-1.*
    38  #
    39  for {set i 1} {$i < $REPEATS} {incr i} {
    40    forcedelete test.db test.db-wal
    41    do_test walcrash-1.$i.1 {
    42      crashsql -delay 4 -file test.db-wal -seed [incr seed] {
    43        PRAGMA journal_mode = WAL;
    44        CREATE TABLE t1(a, b);
    45        INSERT INTO t1 VALUES(1, 1);
    46        INSERT INTO t1 VALUES(2, 3);
    47        INSERT INTO t1 VALUES(3, 6);
    48      }
    49    } {1 {child process exited abnormally}}
    50    do_test walcrash-1.$i.2 {
    51      sqlite3 db test.db
    52      execsql { SELECT sum(a)==max(b) FROM t1 }
    53    } {1}
    54    integrity_check walcrash-1.$i.3
    55    db close
    56    
    57    do_test walcrash-1.$i.4 {
    58      crashsql -delay 2 -file test.db-wal -seed [incr seed] {
    59        INSERT INTO t1 VALUES(4, (SELECT sum(a) FROM t1) + 4);
    60        INSERT INTO t1 VALUES(5, (SELECT sum(a) FROM t1) + 5);
    61      }
    62    } {1 {child process exited abnormally}}
    63    do_test walcrash-1.$i.5 {
    64      sqlite3 db test.db
    65      execsql { SELECT sum(a)==max(b) FROM t1 }
    66    } {1}
    67    integrity_check walcrash-1.$i.6
    68    do_test walcrash-1.$i.7 {
    69      execsql { PRAGMA main.journal_mode }
    70    } {wal}
    71    db close
    72  }
    73  
    74  # walcrash-2.*
    75  #
    76  for {set i 1} {$i < $REPEATS} {incr i} {
    77    forcedelete test.db test.db-wal
    78    do_test walcrash-2.$i.1 {
    79      crashsql -delay 5 -file test.db-wal -seed [incr seed] {
    80        PRAGMA journal_mode = WAL;
    81        CREATE TABLE t1(a PRIMARY KEY, b);
    82        INSERT INTO t1 VALUES(1, 2);
    83        INSERT INTO t1 VALUES(3, 4);
    84        INSERT INTO t1 VALUES(5, 9);
    85      }
    86    } {1 {child process exited abnormally}}
    87    do_test walcrash-2.$i.2 {
    88      sqlite3 db test.db
    89      execsql { SELECT sum(a)==max(b) FROM t1 }
    90    } {1}
    91    integrity_check walcrash-2.$i.3
    92    db close
    93    
    94    do_test walcrash-2.$i.4 {
    95      crashsql -delay 2 -file test.db-wal -seed [incr seed] {
    96        INSERT INTO t1 VALUES(6, (SELECT sum(a) FROM t1) + 6);
    97        INSERT INTO t1 VALUES(7, (SELECT sum(a) FROM t1) + 7);
    98      }
    99    } {1 {child process exited abnormally}}
   100    do_test walcrash-2.$i.5 {
   101      sqlite3 db test.db
   102      execsql { SELECT sum(a)==max(b) FROM t1 }
   103    } {1}
   104    integrity_check walcrash-2.$i.6
   105    do_test walcrash-2.$i.6 {
   106      execsql { PRAGMA main.journal_mode }
   107    } {wal}
   108    db close
   109  }
   110  
   111  # walcrash-3.*
   112  #
   113  # for {set i 1} {$i < $REPEATS} {incr i} {
   114  #   forcedelete test.db test.db-wal
   115  #   forcedelete test2.db test2.db-wal
   116  # 
   117  #   do_test walcrash-3.$i.1 {
   118  #     crashsql -delay 2 -file test2.db-wal -seed [incr seed] {
   119  #       PRAGMA journal_mode = WAL;
   120  #       ATTACH 'test2.db' AS aux;
   121  #       CREATE TABLE t1(a PRIMARY KEY, b);
   122  #       CREATE TABLE aux.t2(a PRIMARY KEY, b);
   123  #       BEGIN;
   124  #         INSERT INTO t1 VALUES(1, 2);
   125  #         INSERT INTO t2 VALUES(1, 2);
   126  #       COMMIT;
   127  #     }
   128  #   } {1 {child process exited abnormally}}
   129  # 
   130  #   do_test walcrash-3.$i.2 {
   131  #     sqlite3_wal db test.db
   132  #     execsql { 
   133  #       ATTACH 'test2.db' AS aux;
   134  #       SELECT * FROM t1 EXCEPT SELECT * FROM t2;
   135  #     }
   136  #   } {}
   137  #   do_test walcrash-3.$i.3 { execsql { PRAGMA main.integrity_check } } {ok}
   138  #   do_test walcrash-3.$i.4 { execsql { PRAGMA aux.integrity_check  } } {ok}
   139  # 
   140  #   db close
   141  # }
   142  
   143  # walcrash-4.*
   144  #
   145  for {set i 1} {$i < $REPEATS} {incr i} {
   146    forcedelete test.db test.db-wal
   147    forcedelete test2.db test2.db-wal
   148  
   149    do_test walcrash-4.$i.1 {
   150      crashsql -delay 4 -file test.db-wal -seed [incr seed] -blocksize 4096 {
   151        PRAGMA journal_mode = WAL;
   152        PRAGMA page_size = 1024;
   153        CREATE TABLE t1(a PRIMARY KEY, b);
   154        INSERT INTO t1 VALUES(1, 2);
   155        INSERT INTO t1 VALUES(3, 4);
   156      }
   157    } {1 {child process exited abnormally}}
   158  
   159    do_test walcrash-4.$i.2 {
   160      sqlite3 db test.db
   161      execsql { 
   162        SELECT * FROM t1 WHERE a = 1;
   163      }
   164    } {1 2}
   165    do_test walcrash-4.$i.3 { execsql { PRAGMA main.integrity_check } } {ok}
   166    do_test walcrash-4.$i.4 { execsql { PRAGMA main.journal_mode } } {wal}
   167  
   168    db close
   169  }
   170  
   171  # walcrash-5.*
   172  #
   173  for {set i 1} {$i < $REPEATS} {incr i} {
   174    forcedelete test.db test.db-wal
   175    forcedelete test2.db test2.db-wal
   176  
   177    do_test walcrash-5.$i.1 {
   178      crashsql -delay 13 -file test.db-wal -seed [incr seed] -blocksize 4096 {
   179        PRAGMA journal_mode = WAL;
   180        PRAGMA page_size = 1024;
   181        BEGIN;
   182          CREATE TABLE t1(x PRIMARY KEY);
   183          INSERT INTO t1 VALUES(randomblob(900));
   184          INSERT INTO t1 VALUES(randomblob(900));
   185          INSERT INTO t1 SELECT randomblob(900) FROM t1;           /* 4 */
   186        COMMIT;
   187        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 8 */
   188        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 12 */
   189        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 16 */
   190        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 20 */
   191        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 24 */
   192        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 28 */
   193        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 32 */
   194  
   195        PRAGMA wal_checkpoint;
   196        INSERT INTO t1 VALUES(randomblob(900));
   197        INSERT INTO t1 VALUES(randomblob(900));
   198        INSERT INTO t1 VALUES(randomblob(900));
   199      }
   200    } {1 {child process exited abnormally}}
   201  
   202    do_test walcrash-5.$i.2 {
   203      sqlite3 db test.db
   204      execsql { SELECT count(*)==33 OR count(*)==34 FROM t1 WHERE x != 1 }
   205    } {1}
   206    do_test walcrash-5.$i.3 { execsql { PRAGMA main.integrity_check } } {ok}
   207    do_test walcrash-5.$i.4 { execsql { PRAGMA main.journal_mode } } {wal}
   208  
   209    db close
   210  }
   211  
   212  # walcrash-6.*
   213  #
   214  for {set i 1} {$i < $REPEATS} {incr i} {
   215    forcedelete test.db test.db-wal
   216    forcedelete test2.db test2.db-wal
   217  
   218    do_test walcrash-6.$i.1 {
   219      crashsql -delay 14 -file test.db-wal -seed [incr seed] -blocksize 512 {
   220        PRAGMA journal_mode = WAL;
   221        PRAGMA page_size = 1024;
   222        BEGIN;
   223          CREATE TABLE t1(x PRIMARY KEY);
   224          INSERT INTO t1 VALUES(randomblob(900));
   225          INSERT INTO t1 VALUES(randomblob(900));
   226          INSERT INTO t1 SELECT randomblob(900) FROM t1;           /* 4 */
   227        COMMIT;
   228        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 8 */
   229        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 12 */
   230        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 16 */
   231        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 20 */
   232        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 24 */
   233        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 28 */
   234        INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 32 */
   235  
   236        PRAGMA wal_checkpoint;
   237        INSERT INTO t1 VALUES(randomblob(9000));
   238        INSERT INTO t1 VALUES(randomblob(9000));
   239        INSERT INTO t1 VALUES(randomblob(9000));
   240        INSERT INTO t1 VALUES(randomblob(9000));
   241      }
   242    } {1 {child process exited abnormally}}
   243  
   244    do_test walcrash-6.$i.2 {
   245      sqlite3 db test.db
   246      execsql { SELECT count(*) BETWEEN 34 AND 36 FROM t1 WHERE x != 1 }
   247    } {1}
   248    do_test walcrash-6.$i.3 { execsql { PRAGMA main.integrity_check } } {ok}
   249    do_test walcrash-6.$i.4 { execsql { PRAGMA main.journal_mode } } {wal}
   250  
   251    db close
   252  }
   253  
   254  #-------------------------------------------------------------------------
   255  # This test case simulates a crash while checkpointing the database. Page
   256  # 1 is one of the pages overwritten by the checkpoint. This is a special
   257  # case because it means the content of page 1 may be damaged. SQLite will
   258  # have to determine:
   259  #
   260  #   (a) that the database is a WAL database, and 
   261  #   (b) the database page-size
   262  #
   263  # based on the log file.
   264  #
   265  for {set i 1} {$i < $REPEATS} {incr i} {
   266    forcedelete test.db test.db-wal
   267  
   268    # Select a page-size for this test.
   269    #
   270    set pgsz [lindex {512 1024 2048 4096 8192 16384} [expr $i%6]]
   271  
   272    do_test walcrash-7.$i.1 {
   273      crashsql -delay 3 -file test.db -seed [incr seed] -blocksize 512 "
   274        PRAGMA page_size = $pgsz;
   275        PRAGMA journal_mode = wal;
   276        BEGIN;
   277          CREATE TABLE t1(a, b);
   278          INSERT INTO t1 VALUES(1, 2);
   279        COMMIT;
   280        PRAGMA wal_checkpoint;
   281        CREATE INDEX i1 ON t1(a);
   282        PRAGMA wal_checkpoint;
   283      "
   284    } {1 {child process exited abnormally}}
   285  
   286    do_test walcrash-7.$i.2 {
   287      sqlite3 db test.db
   288      execsql { SELECT b FROM t1 WHERE a = 1 }
   289    } {2}
   290    do_test walcrash-7.$i.3 { execsql { PRAGMA main.integrity_check } } {ok}
   291    do_test walcrash-7.$i.4 { execsql { PRAGMA main.journal_mode } } {wal}
   292  
   293    db close
   294  }
   295  
   296  finish_test