Annotation of embedaddon/sqlite3/test/ioerr2.test, revision 1.1.1.1

1.1       misho       1: # 2007 April 2
                      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 for correct handling of I/O errors
                     13: # such as writes failing because the disk is full.
                     14: # 
                     15: # The tests in this file use special facilities that are only
                     16: # available in the SQLite test fixture.
                     17: #
                     18: # $Id: ioerr2.test,v 1.12 2009/06/05 17:09:12 drh Exp $
                     19: 
                     20: set testdir [file dirname $argv0]
                     21: source $testdir/tester.tcl
                     22: 
                     23: ifcapable !integrityck {
                     24:   finish_test
                     25:   return
                     26: }
                     27: 
                     28: do_test ioerr2-1.1 {
                     29:   execsql {
                     30:     PRAGMA cache_size = 10;
                     31:     PRAGMA default_cache_size = 10;
                     32:     CREATE TABLE t1(a, b, PRIMARY KEY(a, b));
                     33:     INSERT INTO t1 VALUES(randstr(400,400),randstr(400,400));
                     34:     INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2
                     35:     INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 4
                     36:     INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 8
                     37:     INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 16
                     38:     INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 32
                     39:   }
                     40: } {}
                     41: 
                     42: set ::cksum [execsql {SELECT md5sum(a, b) FROM t1}]
                     43: proc check_db {testname} {
                     44: 
                     45:   # Make sure no I/O errors are simulated in this proc.
                     46:   set ::sqlite_io_error_hit 0
                     47:   set ::sqlite_io_error_persist 0
                     48:   set ::sqlite_io_error_pending 0
                     49: 
                     50:   # Run an integrity-check. If "disk I/O error" is returned, the
                     51:   # pager must be in error state. In this case open a new database
                     52:   # connection. Otherwise, try a ROLLBACK, in case a transaction 
                     53:   # is still active.
                     54:   set rc [catch {execsql {PRAGMA integrity_check}} msg]
                     55:   if {$rc && ($msg eq "disk I/O error" || $msg eq "database is locked")} {
                     56:     db close
                     57:     sqlite3 db test.db
                     58:     set refcnt 0
                     59:   } else {
                     60:     if {$rc || $msg ne "ok"} {
                     61:       error $msg
                     62:     }
                     63:     catch {execsql ROLLBACK}
                     64:   }
                     65: 
                     66:   # Check that the database checksum is still $::cksum, and that
                     67:   # the integrity-check passes.
                     68:   set ck [execsql {SELECT md5sum(a, b) FROM t1}]
                     69:   do_test ${testname}.cksum [list set ck $ck] $::cksum
                     70:   integrity_check ${testname}.integrity
                     71:   do_test ${testname}.refcnt {
                     72:     lindex [sqlite3_pager_refcounts db] 0
                     73:   } 0
                     74: }
                     75: 
                     76: check_db ioerr2-2
                     77: 
                     78: set sql {
                     79:   PRAGMA cache_size = 10;
                     80:   PRAGMA default_cache_size = 10;
                     81:   BEGIN;
                     82:   DELETE FROM t1 WHERE (oid%7)==0;
                     83:   INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) 
                     84:     WHERE (random()%7)==0;
                     85:   UPDATE t1 SET a = randstr(400,400), b = randstr(400,400) 
                     86:     WHERE (random()%7)==0;
                     87:   ROLLBACK;
                     88: }
                     89: 
                     90: foreach bPersist [list 0 1] {
                     91:   set ::go 1
                     92:   for {set ::N 1} {$::go} {incr ::N} {
                     93:     db close
                     94:     sqlite3 db test.db
                     95:     set ::sqlite_io_error_hit 0
                     96:     set ::sqlite_io_error_persist $bPersist
                     97:     set ::sqlite_io_error_pending $::N
                     98: 
                     99:     foreach {::go res} [catchsql $sql] {}
                    100:     check_db ioerr2-3.$bPersist.$::N
                    101:   }
                    102: }
                    103: foreach bPersist [list 0 1] {
                    104:   set ::go 1
                    105:   for {set ::N 1} {$::go} {incr ::N} {
                    106:     set ::sqlite_io_error_hit 0
                    107:     set ::sqlite_io_error_persist $bPersist
                    108:     set ::sqlite_io_error_pending $::N
                    109: 
                    110:     foreach {::go res} [catchsql $sql] {}
                    111:     check_db ioerr2-4.[expr {$bPersist+2}].$::N
                    112:   }
                    113: }
                    114: 
                    115: do_test ioerr2-5 {
                    116:   execsql {
                    117:     CREATE TABLE t2 AS SELECT * FROM t1;
                    118:     PRAGMA temp_store = memory;
                    119:   }
                    120:   set ::sqlite_io_error_persist 0
                    121:   set ::go 1
                    122:   set rc [catch {
                    123:     for {set ::N 2} {$::N<200} {incr ::N} {
                    124:       db eval {SELECT * FROM t1 WHERE rowid IN (1, 5, 10, 15, 20)} {
                    125:         set ::sqlite_io_error_hit 0
                    126:         set ::sqlite_io_error_pending $::N
                    127:         set sql {UPDATE t2 SET b = randstr(400,400)}
                    128:         foreach {::go res} [catchsql $sql] {}
                    129:       }
                    130:     }
                    131:   } msg]
                    132:   list $rc $msg
                    133: } {1 {callback requested query abort}}
                    134: 
                    135: if {$::tcl_platform(platform) == "unix"} {
                    136:   # Cause the call to xAccess used by [pragma temp_store_directory] to
                    137:   # determine if the specified directory is writable to fail. This causes
                    138:   # SQLite to report "not a writable directory", which is probably the
                    139:   # right answer.
                    140:   #
                    141:   do_test ioerr2-6 {
                    142:     set ::sqlite_io_error_hit 0
                    143:     set ::sqlite_io_error_pending 1
                    144:     catchsql {PRAGMA temp_store_directory = '/tmp/'}
                    145:   } {1 {not a writable directory}}
                    146: }
                    147: 
                    148: do_ioerr_test ioerr2-7 -persist 0 -sqlprep {
                    149:   PRAGMA cache_size = 10;
                    150:   PRAGMA auto_vacuum = 1;
                    151:   CREATE TABLE ab(a, b);
                    152:   CREATE TABLE de(d, e);
                    153:   INSERT INTO ab VALUES(1, randstr(200,200));
                    154:   INSERT INTO ab SELECT a+1, randstr(200,200) FROM ab;
                    155:   INSERT INTO ab SELECT a+2, randstr(200,200) FROM ab;
                    156:   INSERT INTO ab SELECT a+4, randstr(200,200) FROM ab;
                    157:   INSERT INTO ab SELECT a+8, randstr(200,200) FROM ab;
                    158:   INSERT INTO ab SELECT a+16, randstr(200,200) FROM ab;
                    159:   INSERT INTO ab SELECT a+32, randstr(200,200) FROM ab;
                    160:   INSERT INTO ab SELECT a+64, randstr(200,200) FROM ab;
                    161:   INSERT INTO de SELECT * FROM ab;
                    162: } -sqlbody {
                    163:   BEGIN;
                    164:   UPDATE ab SET b = randstr(200,200);
                    165:   UPDATE de SET e = randstr(200,200) WHERE d = (SELECT max(d) FROM de);
                    166:   DELETE FROM ab;
                    167:   COMMIT;
                    168: }
                    169: 
                    170: finish_test

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