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>