File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / test / trans2.test
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:16 2012 UTC (12 years, 10 months ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    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.1.1 2012/02/21 17:04:16 misho 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>