os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/crash3.test
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/crash3.test	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,190 @@
     1.4 +# 2007 August 23
     1.5 +#
     1.6 +# The author disclaims copyright to this source code.  In place of
     1.7 +# a legal notice, here is a blessing:
     1.8 +#
     1.9 +#    May you do good and not evil.
    1.10 +#    May you find forgiveness for yourself and forgive others.
    1.11 +#    May you share freely, never taking more than you give.
    1.12 +#
    1.13 +#***********************************************************************
    1.14 +#
    1.15 +# This file contains tests that verify that SQLite can correctly rollback
    1.16 +# databases after crashes when using the special IO modes triggered 
    1.17 +# by device IOCAP flags.
    1.18 +#
    1.19 +# $Id: crash3.test,v 1.4 2008/07/12 14:52:20 drh Exp $
    1.20 +
    1.21 +set testdir [file dirname $argv0]
    1.22 +source $testdir/tester.tcl
    1.23 +
    1.24 +ifcapable !crashtest {
    1.25 +  finish_test
    1.26 +  return
    1.27 +}
    1.28 +
    1.29 +proc do_test2 {name tcl res1 res2} {
    1.30 +  set script [subst -nocommands {
    1.31 +    do_test $name {
    1.32 +      set res1 {$res1}
    1.33 +      set res2 {$res2}
    1.34 +      set res [eval {$tcl}]
    1.35 +      if {[set res] eq [set res1] || [set res] eq [set res2]} {
    1.36 +        set res "{[set res1]} or {[set res2]}"
    1.37 +      }
    1.38 +      set res
    1.39 +    } {{$res1} or {$res2}}
    1.40 +  }]
    1.41 +  uplevel $script
    1.42 +}
    1.43 +
    1.44 +# This block tests crash-recovery when the IOCAP_ATOMIC flags is set.
    1.45 +#
    1.46 +# Each iteration of the following loop sets up the database to contain
    1.47 +# the following schema and data:
    1.48 +#
    1.49 +#    CREATE TABLE abc(a, b, c);
    1.50 +#    INSERT INTO abc VALUES(1, 2, 3);
    1.51 +#
    1.52 +# Then execute the SQL statement, scheduling a crash for part-way through
    1.53 +# the first sync() of either the database file or the journal file (often
    1.54 +# the journal file is not required - meaning no crash occurs).
    1.55 +#
    1.56 +# After the crash (or absence of a crash), open the database and 
    1.57 +# verify that:
    1.58 +#
    1.59 +#   * The integrity check passes, and
    1.60 +#   * The contents of table abc is either {1 2 3} or the value specified
    1.61 +#     to the right of the SQL statement below.
    1.62 +#
    1.63 +# The procedure is repeated 10 times for each SQL statement. Five times
    1.64 +# with the crash scheduled for midway through the first journal sync (if 
    1.65 +# any), and five times with the crash midway through the database sync.
    1.66 +#
    1.67 +set tn 1
    1.68 +foreach {sql res2} [list \
    1.69 +  {INSERT INTO abc VALUES(4, 5, 6)}                    {1 2 3 4 5 6} \
    1.70 +  {DELETE FROM abc}                                    {}    \
    1.71 +  {INSERT INTO abc SELECT * FROM abc}                  {1 2 3 1 2 3} \
    1.72 +  {UPDATE abc SET a = 2}                               {2 2 3}       \
    1.73 +  {INSERT INTO abc VALUES(4, 5, randstr(1000,1000))}   {n/a} \
    1.74 +  {CREATE TABLE def(d, e, f)}                          {n/a} \
    1.75 +] {
    1.76 +  for {set ii 0} {$ii < 10} {incr ii} {
    1.77 +
    1.78 +    db close
    1.79 +    file delete -force test.db test.db-journal
    1.80 +    sqlite3 db test.db
    1.81 +    do_test crash3-1.$tn.1 {
    1.82 +      execsql {
    1.83 +        PRAGMA page_size = 1024;
    1.84 +        BEGIN;
    1.85 +        CREATE TABLE abc(a, b, c);
    1.86 +        INSERT INTO abc VALUES(1, 2, 3);
    1.87 +        COMMIT;
    1.88 +      }
    1.89 +    } {}
    1.90 +    db close
    1.91 +  
    1.92 +    set crashfile test.db
    1.93 +    if {($ii%2)==0} { append crashfile -journal }
    1.94 +    set rand "SELECT randstr($tn,$tn);"
    1.95 +    do_test crash3-1.$tn.2 [subst {
    1.96 +      crashsql -file $crashfile -char atomic {$rand $sql}
    1.97 +      sqlite3 db test.db
    1.98 +      execsql { PRAGMA integrity_check; }
    1.99 +    }] {ok}
   1.100 +  
   1.101 +    do_test2 crash3-1.$tn.3 {
   1.102 +      execsql { SELECT * FROM abc }
   1.103 +    } {1 2 3} $res2
   1.104 +
   1.105 +    incr tn
   1.106 +  }
   1.107 +}
   1.108 +
   1.109 +# This block tests both the IOCAP_SEQUENTIAL and IOCAP_SAFE_APPEND flags.
   1.110 +#
   1.111 +db close
   1.112 +file delete -force test.db test.db-journal
   1.113 +sqlite3 db test.db
   1.114 +do_test crash3-2.0 {
   1.115 +  execsql {
   1.116 +    BEGIN;
   1.117 +    CREATE TABLE abc(a PRIMARY KEY, b, c);
   1.118 +    CREATE TABLE def(d PRIMARY KEY, e, f);
   1.119 +    PRAGMA default_cache_size = 10;
   1.120 +    INSERT INTO abc VALUES(randstr(10,1000),randstr(10,1000),randstr(10,1000));
   1.121 +    INSERT INTO abc 
   1.122 +      SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
   1.123 +    INSERT INTO abc 
   1.124 +      SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
   1.125 +    INSERT INTO abc 
   1.126 +      SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
   1.127 +    INSERT INTO abc 
   1.128 +      SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
   1.129 +    INSERT INTO abc 
   1.130 +      SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
   1.131 +    INSERT INTO abc 
   1.132 +      SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc;
   1.133 +    COMMIT;
   1.134 +  }
   1.135 +} {}
   1.136 +
   1.137 +set tn 1
   1.138 +foreach {::crashfile ::delay ::char} {
   1.139 +  test.db         1 sequential
   1.140 +  test.db         1 safe_append
   1.141 +  test.db-journal 1 sequential
   1.142 +  test.db-journal 1 safe_append
   1.143 +  test.db-journal 2 safe_append
   1.144 +  test.db-journal 2 sequential
   1.145 +  test.db-journal 3 sequential
   1.146 +  test.db-journal 3 safe_append
   1.147 +} {
   1.148 +  for {set ii 0} {$ii < 100} {incr ii} {
   1.149 +    set ::SQL [subst {
   1.150 +      SELECT randstr($ii,$ii+10);
   1.151 +      BEGIN;
   1.152 +      DELETE FROM abc WHERE random()%5;
   1.153 +      INSERT INTO abc 
   1.154 +        SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) 
   1.155 +        FROM abc
   1.156 +        WHERE (random()%5)==0;
   1.157 +      DELETE FROM def WHERE random()%5;
   1.158 +      INSERT INTO def 
   1.159 +        SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) 
   1.160 +        FROM def
   1.161 +        WHERE (random()%5)==0;
   1.162 +      COMMIT;
   1.163 +    }]
   1.164 +
   1.165 +    do_test crash3-2.$tn.$ii {
   1.166 +      crashsql -file $::crashfile -delay $::delay -char $::char $::SQL
   1.167 +      db close
   1.168 +      sqlite3 db test.db
   1.169 +      execsql {PRAGMA integrity_check}
   1.170 +    } {ok}
   1.171 +  }
   1.172 +  incr tn
   1.173 +}
   1.174 +
   1.175 +# The following block tests an interaction between IOCAP_ATOMIC and
   1.176 +# IOCAP_SEQUENTIAL. At one point, if both flags were set, small
   1.177 +# journal files that contained only a single page, but were required 
   1.178 +# for some other reason (i.e. nTrunk) were not being written to
   1.179 +# disk.
   1.180 +#
   1.181 +for {set ii 0} {$ii < 10} {incr ii} {
   1.182 +  db close
   1.183 +  file delete -force test.db test.db-journal
   1.184 +  crashsql -file test.db -char {sequential atomic} {
   1.185 +    CREATE TABLE abc(a, b, c);
   1.186 +  }
   1.187 +  sqlite3 db test.db
   1.188 +  do_test crash3-3.$ii {
   1.189 +    execsql {PRAGMA integrity_check}
   1.190 +  } {ok}
   1.191 +}
   1.192 +
   1.193 +finish_test