Annotation of embedaddon/sqlite3/test/trans2.test, revision 1.1
1.1 ! misho 1: # 2008 August 27
! 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: #
! 12: # This file implements regression tests for SQLite library. The
! 13: # focus of this script is transactions
! 14: #
! 15: # $Id: trans2.test,v 1.1 2008/08/27 18:56:36 drh Exp $
! 16: #
! 17: set testdir [file dirname $argv0]
! 18: source $testdir/tester.tcl
! 19:
! 20: # A procedure to scramble the elements of list $inlist into a random order.
! 21: #
! 22: proc scramble {inlist} {
! 23: set y {}
! 24: foreach x $inlist {
! 25: lappend y [list [expr {rand()}] $x]
! 26: }
! 27: set y [lsort $y]
! 28: set outlist {}
! 29: foreach x $y {
! 30: lappend outlist [lindex $x 1]
! 31: }
! 32: return $outlist
! 33: }
! 34:
! 35: # Generate a UUID using randomness.
! 36: #
! 37: expr srand(1)
! 38: proc random_uuid {} {
! 39: set u {}
! 40: for {set i 0} {$i<5} {incr i} {
! 41: append u [format %06x [expr {int(rand()*16777216)}]]
! 42: }
! 43: return $u
! 44: }
! 45:
! 46: # Compute hashes on the u1 and u2 fields of the sample data.
! 47: #
! 48: proc hash1 {} {
! 49: global data
! 50: set x ""
! 51: foreach rec [lsort -integer -index 0 $data] {
! 52: append x [lindex $rec 1]
! 53: }
! 54: return [md5 $x]
! 55: }
! 56: proc hash2 {} {
! 57: global data
! 58: set x ""
! 59: foreach rec [lsort -integer -index 0 $data] {
! 60: append x [lindex $rec 3]
! 61: }
! 62: return [md5 $x]
! 63: }
! 64:
! 65: # Create the initial data set
! 66: #
! 67: unset -nocomplain data i max_rowid todel n rec max1 id origres newres
! 68: unset -nocomplain inssql modsql s j z
! 69: set data {}
! 70: for {set i 0} {$i<400} {incr i} {
! 71: set rec [list $i [random_uuid] [expr {int(rand()*5000)+1000}] [random_uuid]]
! 72: lappend data $rec
! 73: }
! 74: set max_rowid [expr {$i-1}]
! 75:
! 76: # Create the T1 table used to hold test data. Populate that table with
! 77: # the initial data set and check hashes to make sure everything is correct.
! 78: #
! 79: do_test trans2-1.1 {
! 80: execsql {
! 81: PRAGMA cache_size=100;
! 82: CREATE TABLE t1(
! 83: id INTEGER PRIMARY KEY,
! 84: u1 TEXT UNIQUE,
! 85: z BLOB NOT NULL,
! 86: u2 TEXT UNIQUE
! 87: );
! 88: }
! 89: foreach rec [scramble $data] {
! 90: foreach {id u1 z u2} $rec break
! 91: db eval {INSERT INTO t1 VALUES($id,$u1,zeroblob($z),$u2)}
! 92: }
! 93: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 94: } [list [hash1] [hash2]]
! 95:
! 96: # Repeat the main test loop multiple times.
! 97: #
! 98: for {set i 2} {$i<=30} {incr i} {
! 99: # Delete one row out of every 10 in the database. This will add
! 100: # many pages to the freelist.
! 101: #
! 102: set todel {}
! 103: set n [expr {[llength $data]/10}]
! 104: set data [scramble $data]
! 105: foreach rec [lrange $data 0 $n] {
! 106: lappend todel [lindex $rec 0]
! 107: }
! 108: set data [lrange $data [expr {$n+1}] end]
! 109: set max1 [lindex [lindex $data 0] 0]
! 110: foreach rec $data {
! 111: set id [lindex $rec 0]
! 112: if {$id>$max1} {set max1 $id}
! 113: }
! 114: set origres [list [hash1] [hash2]]
! 115: do_test trans2-$i.1 {
! 116: db eval "DELETE FROM t1 WHERE id IN ([join $todel ,])"
! 117: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 118: } $origres
! 119: integrity_check trans2-$i.2
! 120:
! 121: # Begin a transaction and insert many new records.
! 122: #
! 123: set newdata {}
! 124: foreach id $todel {
! 125: set rec [list $id [random_uuid] \
! 126: [expr {int(rand()*5000)+1000}] [random_uuid]]
! 127: lappend newdata $rec
! 128: lappend data $rec
! 129: }
! 130: for {set j 1} {$j<50} {incr j} {
! 131: set id [expr {$max_rowid+$j}]
! 132: lappend todel $id
! 133: set rec [list $id [random_uuid] \
! 134: [expr {int(rand()*5000)+1000}] [random_uuid]]
! 135: lappend newdata $rec
! 136: lappend data $rec
! 137: }
! 138: set max_rowid [expr {$max_rowid+$j-1}]
! 139: set modsql {}
! 140: set inssql {}
! 141: set newres [list [hash1] [hash2]]
! 142: do_test trans2-$i.3 {
! 143: db eval BEGIN
! 144: foreach rec [scramble $newdata] {
! 145: foreach {id u1 z u2} $rec break
! 146: set s "INSERT INTO t1 VALUES($id,'$u1',zeroblob($z),'$u2');"
! 147: append modsql $s\n
! 148: append inssql $s\n
! 149: db eval $s
! 150: }
! 151: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 152: } $newres
! 153: integrity_check trans2-$i.4
! 154:
! 155: # Do a large update that aborts do to a constraint failure near
! 156: # the end. This stresses the statement journal mechanism.
! 157: #
! 158: do_test trans2-$i.10 {
! 159: catchsql {
! 160: UPDATE t1 SET u1=u1||'x',
! 161: z = CASE WHEN id<$max_rowid
! 162: THEN zeroblob((random()&65535)%5000 + 1000) END;
! 163: }
! 164: } {1 {t1.z may not be NULL}}
! 165: do_test trans2-$i.11 {
! 166: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 167: } $newres
! 168:
! 169: # Delete all of the newly inserted records. Verify that the database
! 170: # is back to its original state.
! 171: #
! 172: do_test trans2-$i.20 {
! 173: set s "DELETE FROM t1 WHERE id IN ([join $todel ,]);"
! 174: append modsql $s\n
! 175: db eval $s
! 176: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 177: } $origres
! 178:
! 179: # Do another large update that aborts do to a constraint failure near
! 180: # the end. This stresses the statement journal mechanism.
! 181: #
! 182: do_test trans2-$i.30 {
! 183: catchsql {
! 184: UPDATE t1 SET u1=u1||'x',
! 185: z = CASE WHEN id<$max1
! 186: THEN zeroblob((random()&65535)%5000 + 1000) END;
! 187: }
! 188: } {1 {t1.z may not be NULL}}
! 189: do_test trans2-$i.31 {
! 190: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 191: } $origres
! 192:
! 193: # Redo the inserts
! 194: #
! 195: do_test trans2-$i.40 {
! 196: db eval $inssql
! 197: append modsql $inssql
! 198: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 199: } $newres
! 200:
! 201: # Rollback the transaction. Verify that the content is restored.
! 202: #
! 203: do_test trans2-$i.90 {
! 204: db eval ROLLBACK
! 205: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 206: } $origres
! 207: integrity_check trans2-$i.91
! 208:
! 209: # Repeat all the changes, but this time commit.
! 210: #
! 211: do_test trans2-$i.92 {
! 212: db eval BEGIN
! 213: catchsql {
! 214: UPDATE t1 SET u1=u1||'x',
! 215: z = CASE WHEN id<$max1
! 216: THEN zeroblob((random()&65535)%5000 + 1000) END;
! 217: }
! 218: db eval $modsql
! 219: catchsql {
! 220: UPDATE t1 SET u1=u1||'x',
! 221: z = CASE WHEN id<$max1
! 222: THEN zeroblob((random()&65535)%5000 + 1000) END;
! 223: }
! 224: db eval COMMIT
! 225: db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
! 226: } $newres
! 227: integrity_check trans2-$i.93
! 228: }
! 229:
! 230: unset -nocomplain data i max_rowid todel n rec max1 id origres newres
! 231: unset -nocomplain inssql modsql s j z
! 232: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>