File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / test / crash3.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: # 2007 August 23
    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: #
   12: # This file contains tests that verify that SQLite can correctly rollback
   13: # databases after crashes when using the special IO modes triggered 
   14: # by device IOCAP flags.
   15: #
   16: # $Id: crash3.test,v 1.1.1.1 2012/02/21 17:04:16 misho Exp $
   17: 
   18: set testdir [file dirname $argv0]
   19: source $testdir/tester.tcl
   20: 
   21: ifcapable !crashtest {
   22:   finish_test
   23:   return
   24: }
   25: 
   26: proc do_test2 {name tcl res1 res2} {
   27:   set script [subst -nocommands {
   28:     do_test $name {
   29:       set res1 {$res1}
   30:       set res2 {$res2}
   31:       set res [eval {$tcl}]
   32:       if {[set res] eq [set res1] || [set res] eq [set res2]} {
   33:         set res "{[set res1]} or {[set res2]}"
   34:       }
   35:       set res
   36:     } {{$res1} or {$res2}}
   37:   }]
   38:   uplevel $script
   39: }
   40: 
   41: # This block tests crash-recovery when the IOCAP_ATOMIC flags is set.
   42: #
   43: # Each iteration of the following loop sets up the database to contain
   44: # the following schema and data:
   45: #
   46: #    CREATE TABLE abc(a, b, c);
   47: #    INSERT INTO abc VALUES(1, 2, 3);
   48: #
   49: # Then execute the SQL statement, scheduling a crash for part-way through
   50: # the first sync() of either the database file or the journal file (often
   51: # the journal file is not required - meaning no crash occurs).
   52: #
   53: # After the crash (or absence of a crash), open the database and 
   54: # verify that:
   55: #
   56: #   * The integrity check passes, and
   57: #   * The contents of table abc is either {1 2 3} or the value specified
   58: #     to the right of the SQL statement below.
   59: #
   60: # The procedure is repeated 10 times for each SQL statement. Five times
   61: # with the crash scheduled for midway through the first journal sync (if 
   62: # any), and five times with the crash midway through the database sync.
   63: #
   64: set tn 1
   65: foreach {sql res2} [list \
   66:   {INSERT INTO abc VALUES(4, 5, 6)}                    {1 2 3 4 5 6} \
   67:   {DELETE FROM abc}                                    {}    \
   68:   {INSERT INTO abc SELECT * FROM abc}                  {1 2 3 1 2 3} \
   69:   {UPDATE abc SET a = 2}                               {2 2 3}       \
   70:   {INSERT INTO abc VALUES(4, 5, randstr(1000,1000))}   {n/a} \
   71:   {CREATE TABLE def(d, e, f)}                          {n/a} \
   72: ] {
   73:   for {set ii 0} {$ii < 10} {incr ii} {
   74: 
   75:     db close
   76:     forcedelete test.db test.db-journal
   77:     sqlite3 db test.db
   78:     do_test crash3-1.$tn.1 {
   79:       execsql {
   80:         PRAGMA page_size = 1024;
   81:         BEGIN;
   82:         CREATE TABLE abc(a, b, c);
   83:         INSERT INTO abc VALUES(1, 2, 3);
   84:         COMMIT;
   85:       }
   86:     } {}
   87:     db close
   88:   
   89:     set crashfile test.db
   90:     if {($ii%2)==0} { append crashfile -journal }
   91:     set rand "SELECT randstr($tn,$tn);"
   92:     do_test crash3-1.$tn.2 [subst {
   93:       crashsql -file $crashfile -char atomic {$rand $sql}
   94:       sqlite3 db test.db
   95:       execsql { PRAGMA integrity_check; }
   96:     }] {ok}
   97:   
   98:     do_test2 crash3-1.$tn.3 {
   99:       execsql { SELECT * FROM abc }
  100:     } {1 2 3} $res2
  101: 
  102:     incr tn
  103:   }
  104: }
  105: 
  106: # This block tests both the IOCAP_SEQUENTIAL and IOCAP_SAFE_APPEND flags.
  107: #
  108: db close
  109: forcedelete test.db test.db-journal
  110: sqlite3 db test.db
  111: do_test crash3-2.0 {
  112:   execsql {
  113:     BEGIN;
  114:     CREATE TABLE abc(a PRIMARY KEY, b, c);
  115:     CREATE TABLE def(d PRIMARY KEY, e, f);
  116:     PRAGMA default_cache_size = 10;
  117:     INSERT INTO abc VALUES(randstr(10,1000),randstr(10,1000),randstr(10,1000));
  118:     INSERT INTO abc 
  119:       SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
  120:     INSERT INTO abc 
  121:       SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
  122:     INSERT INTO abc 
  123:       SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
  124:     INSERT INTO abc 
  125:       SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
  126:     INSERT INTO abc 
  127:       SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
  128:     INSERT INTO abc 
  129:       SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
  130:     COMMIT;
  131:   }
  132: } {}
  133: 
  134: set tn 1
  135: foreach {::crashfile ::delay ::char} {
  136:   test.db         1 sequential
  137:   test.db         1 safe_append
  138:   test.db-journal 1 sequential
  139:   test.db-journal 1 safe_append
  140:   test.db-journal 2 safe_append
  141:   test.db-journal 2 sequential
  142:   test.db-journal 3 sequential
  143:   test.db-journal 3 safe_append
  144: } {
  145:   for {set ii 0} {$ii < 100} {incr ii} {
  146:     set ::SQL [subst {
  147:       SELECT randstr($ii,$ii+10);
  148:       BEGIN;
  149:       DELETE FROM abc WHERE random()%5;
  150:       INSERT INTO abc 
  151:         SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) 
  152:         FROM abc
  153:         WHERE (random()%5)==0;
  154:       DELETE FROM def WHERE random()%5;
  155:       INSERT INTO def 
  156:         SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) 
  157:         FROM def
  158:         WHERE (random()%5)==0;
  159:       COMMIT;
  160:     }]
  161: 
  162:     do_test crash3-2.$tn.$ii {
  163:       crashsql -file $::crashfile -delay $::delay -char $::char $::SQL
  164:       db close
  165:       sqlite3 db test.db
  166:       execsql {PRAGMA integrity_check}
  167:     } {ok}
  168:   }
  169:   incr tn
  170: }
  171: 
  172: # The following block tests an interaction between IOCAP_ATOMIC and
  173: # IOCAP_SEQUENTIAL. At one point, if both flags were set, small
  174: # journal files that contained only a single page, but were required 
  175: # for some other reason (i.e. nTrunk) were not being written to
  176: # disk.
  177: #
  178: for {set ii 0} {$ii < 10} {incr ii} {
  179:   db close
  180:   forcedelete test.db test.db-journal
  181:   crashsql -file test.db -char {sequential atomic} {
  182:     CREATE TABLE abc(a, b, c);
  183:   }
  184:   sqlite3 db test.db
  185:   do_test crash3-3.$ii {
  186:     execsql {PRAGMA integrity_check}
  187:   } {ok}
  188: }
  189: 
  190: finish_test

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