File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / test / walcrash.test
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:16 2012 UTC (12 years, 4 months ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    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:     }
  241:   } {1 {child process exited abnormally}}
  242: 
  243:   do_test walcrash-6.$i.2 {
  244:     sqlite3 db test.db
  245:     execsql { SELECT count(*)==34 OR count(*)==35 FROM t1 WHERE x != 1 }
  246:   } {1}
  247:   do_test walcrash-6.$i.3 { execsql { PRAGMA main.integrity_check } } {ok}
  248:   do_test walcrash-6.$i.4 { execsql { PRAGMA main.journal_mode } } {wal}
  249: 
  250:   db close
  251: }
  252: 
  253: #-------------------------------------------------------------------------
  254: # This test case simulates a crash while checkpointing the database. Page
  255: # 1 is one of the pages overwritten by the checkpoint. This is a special
  256: # case because it means the content of page 1 may be damaged. SQLite will
  257: # have to determine:
  258: #
  259: #   (a) that the database is a WAL database, and 
  260: #   (b) the database page-size
  261: #
  262: # based on the log file.
  263: #
  264: for {set i 1} {$i < $REPEATS} {incr i} {
  265:   forcedelete test.db test.db-wal
  266: 
  267:   # Select a page-size for this test.
  268:   #
  269:   set pgsz [lindex {512 1024 2048 4096 8192 16384} [expr $i%6]]
  270: 
  271:   do_test walcrash-7.$i.1 {
  272:     crashsql -delay 3 -file test.db -seed [incr seed] -blocksize 512 "
  273:       PRAGMA page_size = $pgsz;
  274:       PRAGMA journal_mode = wal;
  275:       BEGIN;
  276:         CREATE TABLE t1(a, b);
  277:         INSERT INTO t1 VALUES(1, 2);
  278:       COMMIT;
  279:       PRAGMA wal_checkpoint;
  280:       CREATE INDEX i1 ON t1(a);
  281:       PRAGMA wal_checkpoint;
  282:     "
  283:   } {1 {child process exited abnormally}}
  284: 
  285:   do_test walcrash-7.$i.2 {
  286:     sqlite3 db test.db
  287:     execsql { SELECT b FROM t1 WHERE a = 1 }
  288:   } {2}
  289:   do_test walcrash-7.$i.3 { execsql { PRAGMA main.integrity_check } } {ok}
  290:   do_test walcrash-7.$i.4 { execsql { PRAGMA main.journal_mode } } {wal}
  291: 
  292:   db close
  293: }
  294: 
  295: finish_test
  296: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>