Annotation of embedaddon/sqlite3/test/tkt2409.test, revision 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>