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

1.1       misho       1: # 2007 June 13
                      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.
                     12: #
                     13: # This file implements tests to verify that ticket #2409 has been
                     14: # fixed. More specifically, they verify that if SQLite cannot
                     15: # obtain an EXCLUSIVE lock while trying to spill the cache during
                     16: # any statement other than a COMMIT, an I/O error is returned instead
                     17: # of SQLITE_BUSY.
                     18: #
                     19: # $Id: tkt2409.test,v 1.6 2008/08/28 17:46:19 drh Exp $
                     20: 
                     21: # Test Outline:
                     22: #
                     23: #   tkt-2409-1.*: Cause a cache-spill during an INSERT that is within
                     24: #       a db transaction but does not start a statement transaction.
                     25: #       Verify that the transaction is automatically rolled back
                     26: #       and SQLITE_IOERR_BLOCKED is returned
                     27: #
                     28: #       UPDATE: As of the pcache modifications, failing to upgrade to
                     29: #       an exclusive lock when attempting a cache-spill is no longer an
                     30: #       error. The pcache module allocates more space and keeps working
                     31: #       in memory if this occurs.
                     32: #
                     33: #   tkt-2409-2.*: Cause a cache-spill while updating the change-counter
                     34: #       during a database COMMIT. Verify that the transaction is not
                     35: #       rolled back and SQLITE_BUSY is returned.
                     36: #
                     37: #   tkt-2409-3.*: Similar to 2409-1.*, but using many INSERT statements
                     38: #       within a transaction instead of just one.
                     39: #
                     40: #       UPDATE: Again, pcache now just keeps working in main memory.
                     41: #
                     42: #   tkt-2409-4.*: Similar to 2409-1.*, but rig it so that the
                     43: #       INSERT statement starts a statement transaction. Verify that
                     44: #       SQLITE_BUSY is returned and the transaction is not rolled back.
                     45: #
                     46: #       UPDATE: This time, SQLITE_BUSY is not returned. pcache just uses
                     47: #       more malloc()'d memory.
                     48: #
                     49: 
                     50: set testdir [file dirname $argv0]
                     51: source $testdir/tester.tcl
                     52: 
                     53: ifcapable !pager_pragmas {
                     54:   finish_test
                     55:   return
                     56: }
                     57: 
                     58: sqlite3_extended_result_codes $::DB 1
                     59: 
                     60: # Aquire a read-lock on the database using handle [db2].
                     61: #
                     62: proc read_lock_db {} {
                     63:   if {$::STMT eq ""} {
                     64:     set ::STMT [sqlite3_prepare db2 {SELECT rowid FROM sqlite_master} -1 TAIL]
                     65:     set rc [sqlite3_step $::STMT]
                     66:     if {$rc eq "SQLITE_ERROR"} {
                     67:       unread_lock_db
                     68:       read_lock_db
                     69:     }
                     70:   }
                     71: }
                     72: 
                     73: # Release any read-lock obtained using [read_lock_db]
                     74: #
                     75: proc unread_lock_db {} {
                     76:   if {$::STMT ne ""} {
                     77:     sqlite3_finalize $::STMT
                     78:     set ::STMT ""
                     79:   }
                     80: }
                     81: 
                     82: # Open the db handle used by [read_lock_db].
                     83: #
                     84: sqlite3 db2 test.db
                     85: set ::STMT ""
                     86: 
                     87: do_test tkt2409-1.1 {
                     88:   execsql {
                     89:     PRAGMA cache_size=10;
                     90:     CREATE TABLE t1(x TEXT UNIQUE NOT NULL, y BLOB);
                     91:   }
                     92:   read_lock_db
                     93:   set ::zShort [string repeat 0123456789 1]
                     94:   set ::zLong  [string repeat 0123456789 1500]
                     95:   catchsql {
                     96:     BEGIN;
                     97:     INSERT INTO t1 VALUES($::zShort, $::zLong);
                     98:   }
                     99: } {0 {}}
                    100: 
                    101: do_test tkt2409-1.2 {
                    102:   sqlite3_errcode $::DB
                    103: } {SQLITE_OK}
                    104: 
                    105: # Check the integrity of the cache.
                    106: #
                    107: integrity_check tkt2409-1.3
                    108: 
                    109: # Check that the transaction was rolled back. Because the INSERT
                    110: # statement in which the "I/O error" occured did not open a statement
                    111: # transaction, SQLite had no choice but to roll back the transaction.
                    112: #
                    113: do_test tkt2409-1.4 {
                    114:   unread_lock_db
                    115:   catchsql { ROLLBACK }
                    116: } {0 {}}
                    117: 
                    118: set ::zShort [string repeat 0123456789 1]
                    119: set ::zLong  [string repeat 0123456789 1500]
                    120: set ::rc 1
                    121: for {set iCache 10} {$::rc} {incr iCache} {
                    122:   execsql "PRAGMA cache_size = $iCache"
                    123:   do_test tkt2409-2.1.$iCache {
                    124:     read_lock_db
                    125:     set ::rc [catch {
                    126:       execsql {
                    127:         BEGIN;
                    128:         INSERT INTO t1 VALUES($::zShort, $::zLong);
                    129:       }
                    130:     } msg]
                    131:     expr {($::rc == 1 && $msg eq "disk I/O error") || $::rc == 0}
                    132:   } {1}
                    133: }
                    134: 
                    135: do_test tkt2409-2.2 {
                    136:   catchsql {
                    137:     ROLLBACK;
                    138:     BEGIN;
                    139:     INSERT INTO t1 VALUES($::zShort, $::zLong);
                    140:     COMMIT;
                    141:   }
                    142: } {1 {database is locked}}
                    143: 
                    144: do_test tkt2409-2.3 {
                    145:   unread_lock_db
                    146:   catchsql {
                    147:     COMMIT;
                    148:   }
                    149: } {0 {}}
                    150: 
                    151: 
                    152: do_test tkt2409-3.1 {
                    153:   db close
                    154:   set ::DB [sqlite3 db test.db; sqlite3_connection_pointer db]
                    155:   sqlite3_extended_result_codes $::DB 1
                    156:   execsql {
                    157:     PRAGMA cache_size=10;
                    158:     DELETE FROM t1;
                    159:   }
                    160:   read_lock_db
                    161:   set ::zShort [string repeat 0123456789 1]
                    162:   set ::zLong  [string repeat 0123456789 1500]
                    163:   catchsql {
                    164:     BEGIN;
                    165:     INSERT INTO t1 SELECT $::zShort, $::zLong;
                    166:   }
                    167: } {0 {}}
                    168: 
                    169: do_test tkt2409-3.2 {
                    170:   sqlite3_errcode $::DB
                    171: } {SQLITE_OK}
                    172: 
                    173: # Check the integrity of the cache.
                    174: #
                    175: integrity_check tkt2409-3.3
                    176: 
                    177: # Check that the transaction was rolled back. Because the INSERT
                    178: # statement in which the "I/O error" occured did not open a statement
                    179: # transaction, SQLite had no choice but to roll back the transaction.
                    180: #
                    181: do_test tkt2409-3.4 {
                    182:   unread_lock_db
                    183:   catchsql { ROLLBACK }
                    184: } {0 {}}
                    185: integrity_check tkt2409-3.5
                    186: 
                    187: expr {srand(1)}
                    188: do_test tkt2409-4.1 {
                    189:   execsql {
                    190:     PRAGMA cache_size=20;
                    191:     DROP TABLE t1;
                    192:     CREATE TABLE t1 (x TEXT UNIQUE NOT NULL);
                    193:   }
                    194: 
                    195:   unset -nocomplain t1
                    196:   array unset t1
                    197:   set t1(0) 1
                    198:   set sql ""
                    199:   for {set i 0} {$i<5000} {incr i} {
                    200:     set r 0
                    201:     while {[info exists t1($r)]} {
                    202:       set r [expr {int(rand()*1000000000)}]
                    203:     }
                    204:     set t1($r) 1
                    205:     append sql "INSERT INTO t1 VALUES('some-text-$r');"
                    206:   }
                    207: 
                    208:   read_lock_db
                    209:   execsql BEGIN
                    210:   catchsql $sql
                    211: } {0 {}}
                    212: 
                    213: do_test tkt2409-4.2 {
                    214:   sqlite3_errcode $::DB
                    215: } {SQLITE_OK}
                    216: 
                    217: # Check the integrity of the cache.
                    218: #
                    219: integrity_check tkt2409-4.3
                    220: 
                    221: do_test tkt2409-4.4 {
                    222:   catchsql { ROLLBACK }
                    223: } {0 {}}
                    224: integrity_check tkt2409-4.5
                    225: 
                    226: unread_lock_db
                    227: db2 close
                    228: unset -nocomplain t1
                    229: finish_test

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