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>