github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/walfault.test (about)

     1  # 2010 May 03
     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.
    14  #
    15  
    16  set testdir [file dirname $argv0]
    17  source $testdir/tester.tcl
    18  source $testdir/malloc_common.tcl
    19  source $testdir/lock_common.tcl
    20  
    21  ifcapable !wal {finish_test ; return }
    22  
    23  #-------------------------------------------------------------------------
    24  # This test case, walfault-1-*, simulates faults while executing a
    25  #
    26  #   PRAGMA journal_mode = WAL;
    27  #
    28  # statement immediately after creating a new database.
    29  #
    30  do_test walfault-1-pre-1 {
    31    faultsim_delete_and_reopen
    32    faultsim_save_and_close
    33  } {}
    34  do_faultsim_test walfault-1 -prep {
    35    faultsim_restore_and_reopen
    36  } -body {
    37    db eval { PRAGMA main.journal_mode = WAL }
    38  } -test {
    39  
    40    faultsim_test_result {0 wal}
    41  
    42    # Test that the connection that encountered an error as part of 
    43    # "PRAGMA journal_mode = WAL" and a new connection use the same
    44    # journal mode when accessing the database.
    45    #
    46    # If "PRAGMA journal_mode" is executed immediately, connection [db] (the 
    47    # one that hit the error in journal_mode="WAL") might return "wal" even 
    48    # if it failed to switch the database to WAL mode. This is not considered 
    49    # a problem. When it tries to read the database, connection [db] correctly 
    50    # recognizes that it is a rollback database and switches back to a 
    51    # rollback compatible journal mode.
    52    #
    53    if {[permutation] != "inmemory_journal"} {
    54      set jm  [db one  {SELECT * FROM sqlite_master ; PRAGMA main.journal_mode}]
    55      sqlite3 db2 test.db
    56      set jm2 [db2 one {SELECT * FROM sqlite_master ; PRAGMA main.journal_mode}]
    57      db2 close
    58    
    59      if { $jm!=$jm2 } { error "Journal modes do not match: $jm $jm2" }
    60      if { $testrc==0 && $jm!="wal" } { error "Journal mode is not WAL" }
    61    }
    62  }
    63  
    64  #--------------------------------------------------------------------------
    65  # Test case walfault-2-* tests fault injection during recovery of a 
    66  # short WAL file (a dozen frames or thereabouts).
    67  #
    68  do_test walfault-2-pre-1 {
    69    sqlite3 db test.db
    70    execsql {
    71      PRAGMA journal_mode = WAL;
    72      BEGIN;
    73        CREATE TABLE x(y, z, UNIQUE(y, z));
    74        INSERT INTO x VALUES(randomblob(100), randomblob(100));
    75      COMMIT;
    76      PRAGMA wal_checkpoint;
    77  
    78      INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x;
    79      INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x;
    80      INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x;
    81    }
    82    execsql {
    83      SELECT count(*) FROM x
    84    }
    85  } {8}
    86  do_test walfault-2-pre-2 {
    87    faultsim_save_and_close
    88    faultsim_restore_and_reopen
    89    execsql { SELECT count(*) FROM x }
    90  } {8}
    91  do_faultsim_test walfault-2 -prep {
    92    faultsim_restore_and_reopen
    93  } -body {
    94    execsql { SELECT count(*) FROM x }
    95  } -test {
    96    faultsim_test_result {0 8}
    97    faultsim_integrity_check
    98  }
    99  
   100  #--------------------------------------------------------------------------
   101  # Test fault injection while writing and checkpointing a small WAL file.
   102  #
   103  do_test walfault-3-pre-1 {
   104    sqlite3 db test.db
   105    execsql {
   106      PRAGMA auto_vacuum = 1;
   107      PRAGMA journal_mode = WAL;
   108      CREATE TABLE abc(a PRIMARY KEY);
   109      INSERT INTO abc VALUES(randomblob(1500));
   110    }
   111    db close
   112    faultsim_save_and_close
   113  } {}
   114  do_faultsim_test walfault-3 -prep {
   115    faultsim_restore_and_reopen
   116  } -body {
   117    db eval {
   118      DELETE FROM abc;
   119      PRAGMA wal_checkpoint;
   120    }
   121    set {} {}
   122  } -test {
   123    faultsim_test_result {0 {}}
   124  }
   125  
   126  #--------------------------------------------------------------------------
   127  #
   128  if {[permutation] != "inmemory_journal"} {
   129    faultsim_delete_and_reopen
   130    faultsim_save_and_close
   131    do_faultsim_test walfault-4 -prep {
   132      faultsim_restore_and_reopen
   133    } -body {
   134      execsql {
   135        PRAGMA auto_vacuum = 0;
   136        PRAGMA journal_mode = WAL;
   137        CREATE TABLE t1(a PRIMARY KEY, b);
   138        INSERT INTO t1 VALUES('a', 'b');
   139        PRAGMA wal_checkpoint;
   140        SELECT * FROM t1;
   141      }
   142    } -test {
   143      # Update: The following changed from {0 {wal 0 7 7 a b}} as a result
   144      # of PSOW being set by default.
   145      faultsim_test_result {0 {wal 0 5 5 a b}}
   146      faultsim_integrity_check
   147    } 
   148  }
   149  
   150  #--------------------------------------------------------------------------
   151  #
   152  do_test walfault-5-pre-1 {
   153    faultsim_delete_and_reopen
   154    execsql {
   155      PRAGMA page_size = 512;
   156      PRAGMA journal_mode = WAL;
   157    }
   158    faultsim_save_and_close
   159  } {}
   160  do_faultsim_test walfault-5 -faults shmerr* -prep {
   161    faultsim_restore_and_reopen
   162    execsql { PRAGMA wal_autocheckpoint = 0 }
   163    shmfault filter xShmMap
   164  } -body {
   165    execsql {
   166      CREATE TABLE t1(x);
   167      BEGIN;
   168        INSERT INTO t1 VALUES(randomblob(400));           /* 1 */
   169        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 2 */
   170        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 4 */
   171        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 8 */
   172        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 16 */
   173        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 32 */
   174        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 64 */
   175        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 128 */
   176        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 256 */
   177        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 512 */
   178        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 1024 */
   179        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 2048 */
   180        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 4096 */
   181        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 8192 */
   182        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 16384 */
   183      COMMIT;
   184      SELECT count(*) FROM t1;
   185    }
   186  } -test {
   187    faultsim_test_result {0 16384}
   188    faultsim_integrity_check
   189  }
   190  
   191  #--------------------------------------------------------------------------
   192  #
   193  do_test walfault-6-pre-1 {
   194    faultsim_delete_and_reopen
   195    execsql {
   196      PRAGMA page_size = 512;
   197      PRAGMA journal_mode = WAL;
   198      PRAGMA wal_autocheckpoint = 0;
   199      CREATE TABLE t1(x);
   200      BEGIN;
   201        INSERT INTO t1 VALUES(randomblob(400));           /* 1 */
   202        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 2 */
   203        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 4 */
   204        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 8 */
   205        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 16 */
   206        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 32 */
   207        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 64 */
   208        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 128 */
   209        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 256 */
   210        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 512 */
   211        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 1024 */
   212        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 2048 */
   213        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 4096 */
   214        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 8192 */
   215        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 16384 */
   216      COMMIT;
   217    }
   218    faultsim_save_and_close
   219  } {}
   220  do_faultsim_test walfault-6 -faults shmerr* -prep {
   221    faultsim_restore_and_reopen
   222    shmfault filter xShmMap
   223  } -body {
   224    execsql { SELECT count(*) FROM t1 }
   225  } -test {
   226    faultsim_test_result {0 16384}
   227    faultsim_integrity_check
   228    set n [db one {SELECT count(*) FROM t1}]
   229    if {$n != 16384 && $n != 0} { error "Incorrect number of rows: $n" }
   230  }
   231  
   232  #--------------------------------------------------------------------------
   233  #
   234  do_test walfault-7-pre-1 {
   235    faultsim_delete_and_reopen
   236    execsql {
   237      PRAGMA page_size = 512;
   238      PRAGMA journal_mode = WAL;
   239      PRAGMA wal_autocheckpoint = 0;
   240      CREATE TABLE t1(x);
   241      BEGIN;
   242        INSERT INTO t1 VALUES(randomblob(400));           /* 1 */
   243        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 2 */
   244        INSERT INTO t1 SELECT randomblob(400) FROM t1;    /* 4 */
   245      COMMIT;
   246    }
   247    faultsim_save_and_close
   248  } {}
   249  do_faultsim_test walfault-7 -prep {
   250    faultsim_restore_and_reopen
   251  } -body {
   252    execsql { SELECT count(*) FROM t1 }
   253  } -test {
   254    faultsim_test_result {0 4}
   255    set n [db one {SELECT count(*) FROM t1}]
   256    if {$n != 4 && $n != 0} { error "Incorrect number of rows: $n" }
   257  }
   258  
   259  #--------------------------------------------------------------------------
   260  #
   261  do_test walfault-8-pre-1 {
   262    faultsim_delete_and_reopen
   263    execsql {
   264      PRAGMA journal_mode = WAL;
   265      CREATE TABLE abc(a PRIMARY KEY);
   266      INSERT INTO abc VALUES(randomblob(900));
   267    }
   268    faultsim_save_and_close
   269  } {}
   270  do_faultsim_test walfault-8 -prep {
   271    faultsim_restore_and_reopen
   272    execsql { PRAGMA cache_size = 10 }
   273  } -body {
   274    execsql {
   275      BEGIN;
   276        INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 1 */
   277        --INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 2 */
   278        --INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 4 */
   279        --INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 8 */
   280      ROLLBACK;
   281      SELECT count(*) FROM abc;
   282    }
   283  } -test {
   284    faultsim_test_result {0 1}
   285  
   286    faultsim_integrity_check
   287    catch { db eval ROLLBACK }
   288    faultsim_integrity_check
   289  
   290    set n [db one {SELECT count(*) FROM abc}]
   291    if {$n != 1} { error "Incorrect number of rows: $n" }
   292  }
   293  
   294  #--------------------------------------------------------------------------
   295  #
   296  do_test walfault-9-pre-1 {
   297    faultsim_delete_and_reopen
   298    execsql {
   299      PRAGMA journal_mode = WAL;
   300      CREATE TABLE abc(a PRIMARY KEY);
   301      INSERT INTO abc VALUES(randomblob(900));
   302    }
   303    faultsim_save_and_close
   304  } {}
   305  do_faultsim_test walfault-9 -prep {
   306    #if {$iFail<73} { set iFail 73 }
   307    #if {$iFail>73} { exit }
   308    
   309    faultsim_restore_and_reopen
   310    execsql { PRAGMA cache_size = 10 }
   311  } -body {
   312    execsql {
   313      BEGIN;
   314        INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 1 */
   315        SAVEPOINT spoint;
   316          INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 2 */
   317          INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 4 */
   318          INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 8 */
   319        ROLLBACK TO spoint;
   320      COMMIT;
   321      SELECT count(*) FROM abc;
   322    }
   323  } -test {
   324    faultsim_test_result {0 2}
   325    faultsim_integrity_check
   326  
   327    catch { db eval { ROLLBACK TO spoint } }
   328    catch { db eval { COMMIT } }
   329    set n [db one {SELECT count(*) FROM abc}]
   330    if {$n != 1 && $n != 2} { error "Incorrect number of rows: $n" }
   331  }
   332  
   333  do_test walfault-10-pre1 {
   334    faultsim_delete_and_reopen
   335    execsql {
   336      PRAGMA journal_mode = WAL;
   337      PRAGMA wal_autocheckpoint = 0;
   338      CREATE TABLE z(zz INTEGER PRIMARY KEY, zzz BLOB);
   339      CREATE INDEX zzzz ON z(zzz);
   340      INSERT INTO z VALUES(NULL, randomblob(800));
   341      INSERT INTO z VALUES(NULL, randomblob(800));
   342      INSERT INTO z SELECT NULL, randomblob(800) FROM z;
   343      INSERT INTO z SELECT NULL, randomblob(800) FROM z;
   344      INSERT INTO z SELECT NULL, randomblob(800) FROM z;
   345      INSERT INTO z SELECT NULL, randomblob(800) FROM z;
   346      INSERT INTO z SELECT NULL, randomblob(800) FROM z;
   347    }
   348    faultsim_save_and_close
   349  } {}
   350  do_faultsim_test walfault-10 -prep {
   351    faultsim_restore_and_reopen
   352    execsql {
   353      PRAGMA cache_size = 10;
   354      BEGIN;
   355        UPDATE z SET zzz = randomblob(799);
   356    }
   357  
   358    set ::stmt [sqlite3_prepare db "SELECT zzz FROM z WHERE zz IN (1, 2, 3)" -1]
   359    sqlite3_step $::stmt
   360  } -body {
   361    execsql { INSERT INTO z VALUES(NULL, NULL) }
   362  } -test {
   363    sqlite3_finalize $::stmt
   364    faultsim_integrity_check
   365  
   366    faultsim_test_result {0 {}}
   367    catch { db eval { ROLLBACK } }
   368    faultsim_integrity_check
   369  
   370    set n [db eval {SELECT count(*), sum(length(zzz)) FROM z}]
   371    if {$n != "64 51200"} { error "Incorrect data: $n" }
   372  }
   373  
   374  #--------------------------------------------------------------------------
   375  # Test fault injection while checkpointing a large WAL file, if the 
   376  # checkpoint is the first operation run after opening the database.
   377  # This means that some of the required wal-index pages are mapped as part of
   378  # the checkpoint process, which means there are a few more opportunities
   379  # for IO errors.
   380  #
   381  # To speed this up, IO errors are only simulated within xShmMap() calls.
   382  #
   383  do_test walfault-11-pre-1 {
   384    sqlite3 db test.db
   385    execsql {
   386      PRAGMA journal_mode = WAL;
   387      PRAGMA wal_autocheckpoint = 0;
   388      BEGIN;
   389        CREATE TABLE abc(a PRIMARY KEY);
   390        INSERT INTO abc VALUES(randomblob(1500));
   391        INSERT INTO abc VALUES(randomblob(1500));
   392        INSERT INTO abc SELECT randomblob(1500) FROM abc;   --    4
   393        INSERT INTO abc SELECT randomblob(1500) FROM abc;   --    8
   394        INSERT INTO abc SELECT randomblob(1500) FROM abc;   --   16
   395        INSERT INTO abc SELECT randomblob(1500) FROM abc;   --   32
   396        INSERT INTO abc SELECT randomblob(1500) FROM abc;   --   64
   397        INSERT INTO abc SELECT randomblob(1500) FROM abc;   --  128
   398        INSERT INTO abc SELECT randomblob(1500) FROM abc;   --  256
   399        INSERT INTO abc SELECT randomblob(1500) FROM abc;   --  512
   400        INSERT INTO abc SELECT randomblob(1500) FROM abc;   -- 1024
   401        INSERT INTO abc SELECT randomblob(1500) FROM abc;   -- 2048
   402        INSERT INTO abc SELECT randomblob(1500) FROM abc;   -- 4096
   403      COMMIT;
   404    }
   405    faultsim_save_and_close
   406  } {}
   407  do_faultsim_test walfault-11 -faults shmerr* -prep {
   408    catch { db2 close }
   409    faultsim_restore_and_reopen
   410    shmfault filter xShmMap
   411  } -body {
   412    db eval { SELECT count(*) FROM abc }
   413    sqlite3 db2 test.db -vfs shmfault
   414    db2 eval { PRAGMA wal_checkpoint }
   415    set {} {}
   416  } -test {
   417    faultsim_test_result {0 {}}
   418  }
   419  
   420  #-------------------------------------------------------------------------
   421  # Test the handling of the various IO/OOM/SHM errors that may occur during 
   422  # a log recovery operation undertaken as part of a call to 
   423  # sqlite3_wal_checkpoint().
   424  # 
   425  do_test walfault-12-pre-1 {
   426    faultsim_delete_and_reopen
   427    execsql {
   428      PRAGMA journal_mode = WAL;
   429      PRAGMA wal_autocheckpoint = 0;
   430      BEGIN;
   431        CREATE TABLE abc(a PRIMARY KEY);
   432        INSERT INTO abc VALUES(randomblob(1500));
   433        INSERT INTO abc VALUES(randomblob(1500));
   434      COMMIT;
   435    }
   436    faultsim_save_and_close
   437  } {}
   438  do_faultsim_test walfault-12 -prep {
   439    if {[info commands shmfault] == ""} {
   440      testvfs shmfault -default true
   441    }
   442    faultsim_restore_and_reopen
   443    db eval { SELECT * FROM sqlite_master }
   444    shmfault shm test.db [string repeat "\000" 40]
   445  } -body {
   446    set rc [sqlite3_wal_checkpoint db]
   447    if {$rc != "SQLITE_OK"} { error [sqlite3_errmsg db] }
   448  } -test {
   449    db close
   450    faultsim_test_result {0 {}}
   451  }
   452  
   453  #-------------------------------------------------------------------------
   454  # Test simple recovery, reading and writing a database file using a 
   455  # heap-memory wal-index.
   456  # 
   457  do_test walfault-13-pre-1 {
   458    faultsim_delete_and_reopen
   459    execsql {
   460      PRAGMA journal_mode = WAL;
   461      PRAGMA wal_autocheckpoint = 0;
   462      BEGIN;
   463        CREATE TABLE abc(a PRIMARY KEY);
   464        INSERT INTO abc VALUES(randomblob(1500));
   465        INSERT INTO abc VALUES(randomblob(1500));
   466      COMMIT;
   467    }
   468    faultsim_save_and_close
   469    delete_file sv_test.db-shm
   470  } {}
   471  
   472  do_faultsim_test walfault-13.1 -prep {
   473    faultsim_restore_and_reopen
   474  } -body {
   475    db eval { PRAGMA locking_mode = exclusive }
   476    db eval { SELECT count(*) FROM abc }
   477  } -test {
   478    faultsim_test_result {0 2}
   479    if {[file exists test.db-shm]} { error "Not using heap-memory mode" }
   480    faultsim_integrity_check
   481  }
   482  
   483  do_faultsim_test walfault-13.2 -prep {
   484    faultsim_restore_and_reopen
   485    db eval { PRAGMA locking_mode = exclusive }
   486  } -body {
   487    db eval { PRAGMA journal_mode = delete }
   488  } -test {
   489    faultsim_test_result {0 delete}
   490    if {[file exists test.db-shm]} { error "Not using heap-memory mode" }
   491    faultsim_integrity_check
   492  }
   493  
   494  do_test walfault-13-pre-2 {
   495    faultsim_delete_and_reopen
   496    execsql {
   497      BEGIN;
   498        CREATE TABLE abc(a PRIMARY KEY);
   499        INSERT INTO abc VALUES(randomblob(1500));
   500        INSERT INTO abc VALUES(randomblob(1500));
   501      COMMIT;
   502    }
   503    faultsim_save_and_close
   504  } {}
   505  
   506  do_faultsim_test walfault-13.3 -prep {
   507    faultsim_restore_and_reopen
   508  } -body {
   509    db eval { 
   510      PRAGMA locking_mode = exclusive;
   511      PRAGMA journal_mode = WAL;
   512      INSERT INTO abc VALUES(randomblob(1500));
   513    }
   514  } -test {
   515    faultsim_test_result {0 {exclusive wal}}
   516    if {[file exists test.db-shm]} { error "Not using heap-memory mode" }
   517    faultsim_integrity_check
   518    set nRow [db eval {SELECT count(*) FROM abc}]
   519    if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" }
   520  }
   521  
   522  #-------------------------------------------------------------------------
   523  # Test fault-handling when wrapping around to the start of a WAL file.
   524  #
   525  do_test walfault-14-pre {
   526    faultsim_delete_and_reopen
   527    execsql {
   528      PRAGMA auto_vacuum = 0;
   529      PRAGMA journal_mode = WAL;
   530      BEGIN;
   531        CREATE TABLE abc(a PRIMARY KEY);
   532        INSERT INTO abc VALUES(randomblob(1500));
   533        INSERT INTO abc VALUES(randomblob(1500));
   534      COMMIT;
   535    }
   536    faultsim_save_and_close
   537  } {}
   538  do_faultsim_test walfault-14 -prep {
   539    faultsim_restore_and_reopen
   540  } -body {
   541    db eval { 
   542      PRAGMA wal_checkpoint = full;
   543      INSERT INTO abc VALUES(randomblob(1500));
   544    }
   545  } -test {
   546    faultsim_test_result {0 {0 9 9}}
   547    faultsim_integrity_check
   548    set nRow [db eval {SELECT count(*) FROM abc}]
   549    if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" }
   550  }
   551  
   552  #-------------------------------------------------------------------------
   553  # Test fault-handling when switching out of exclusive-locking mode.
   554  #
   555  do_test walfault-15-pre {
   556    faultsim_delete_and_reopen
   557    execsql {
   558      PRAGMA auto_vacuum = 0;
   559      PRAGMA journal_mode = WAL;
   560      BEGIN;
   561        CREATE TABLE abc(a PRIMARY KEY);
   562        INSERT INTO abc VALUES(randomblob(1500));
   563        INSERT INTO abc VALUES(randomblob(1500));
   564      COMMIT;
   565    }
   566    faultsim_save_and_close
   567  } {}
   568  do_faultsim_test walfault-15 -prep {
   569    faultsim_restore_and_reopen
   570    execsql {
   571      SELECT count(*) FROM abc;
   572      PRAGMA locking_mode = exclusive;
   573      BEGIN;
   574        INSERT INTO abc VALUES(randomblob(1500));
   575      COMMIT;
   576    }
   577  } -body {
   578    db eval { 
   579      PRAGMA locking_mode = normal;
   580      BEGIN;
   581        INSERT INTO abc VALUES(randomblob(1500));
   582      COMMIT;
   583    }
   584  } -test {
   585    faultsim_integrity_check
   586    set nRow [db eval {SELECT count(*) FROM abc}]
   587    if {$nRow!=3 && $nRow!=4} { error "Bad db content" }
   588  }
   589  
   590  finish_test