| Index: third_party/sqlite/src/test/trans2.test
|
| diff --git a/third_party/sqlite/src/test/trans2.test b/third_party/sqlite/src/test/trans2.test
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cfd3e67736c258d73d62a89c060d238a4a92bc7b
|
| --- /dev/null
|
| +++ b/third_party/sqlite/src/test/trans2.test
|
| @@ -0,0 +1,232 @@
|
| +# 2008 August 27
|
| +#
|
| +# The author disclaims copyright to this source code. In place of
|
| +# a legal notice, here is a blessing:
|
| +#
|
| +# May you do good and not evil.
|
| +# May you find forgiveness for yourself and forgive others.
|
| +# May you share freely, never taking more than you give.
|
| +#
|
| +#***********************************************************************
|
| +#
|
| +# This file implements regression tests for SQLite library. The
|
| +# focus of this script is transactions
|
| +#
|
| +# $Id: trans2.test,v 1.1 2008/08/27 18:56:36 drh Exp $
|
| +#
|
| +set testdir [file dirname $argv0]
|
| +source $testdir/tester.tcl
|
| +
|
| +# A procedure to scramble the elements of list $inlist into a random order.
|
| +#
|
| +proc scramble {inlist} {
|
| + set y {}
|
| + foreach x $inlist {
|
| + lappend y [list [expr {rand()}] $x]
|
| + }
|
| + set y [lsort $y]
|
| + set outlist {}
|
| + foreach x $y {
|
| + lappend outlist [lindex $x 1]
|
| + }
|
| + return $outlist
|
| +}
|
| +
|
| +# Generate a UUID using randomness.
|
| +#
|
| +expr srand(1)
|
| +proc random_uuid {} {
|
| + set u {}
|
| + for {set i 0} {$i<5} {incr i} {
|
| + append u [format %06x [expr {int(rand()*16777216)}]]
|
| + }
|
| + return $u
|
| +}
|
| +
|
| +# Compute hashes on the u1 and u2 fields of the sample data.
|
| +#
|
| +proc hash1 {} {
|
| + global data
|
| + set x ""
|
| + foreach rec [lsort -integer -index 0 $data] {
|
| + append x [lindex $rec 1]
|
| + }
|
| + return [md5 $x]
|
| +}
|
| +proc hash2 {} {
|
| + global data
|
| + set x ""
|
| + foreach rec [lsort -integer -index 0 $data] {
|
| + append x [lindex $rec 3]
|
| + }
|
| + return [md5 $x]
|
| +}
|
| +
|
| +# Create the initial data set
|
| +#
|
| +unset -nocomplain data i max_rowid todel n rec max1 id origres newres
|
| +unset -nocomplain inssql modsql s j z
|
| +set data {}
|
| +for {set i 0} {$i<400} {incr i} {
|
| + set rec [list $i [random_uuid] [expr {int(rand()*5000)+1000}] [random_uuid]]
|
| + lappend data $rec
|
| +}
|
| +set max_rowid [expr {$i-1}]
|
| +
|
| +# Create the T1 table used to hold test data. Populate that table with
|
| +# the initial data set and check hashes to make sure everything is correct.
|
| +#
|
| +do_test trans2-1.1 {
|
| + execsql {
|
| + PRAGMA cache_size=100;
|
| + CREATE TABLE t1(
|
| + id INTEGER PRIMARY KEY,
|
| + u1 TEXT UNIQUE,
|
| + z BLOB NOT NULL,
|
| + u2 TEXT UNIQUE
|
| + );
|
| + }
|
| + foreach rec [scramble $data] {
|
| + foreach {id u1 z u2} $rec break
|
| + db eval {INSERT INTO t1 VALUES($id,$u1,zeroblob($z),$u2)}
|
| + }
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| +} [list [hash1] [hash2]]
|
| +
|
| +# Repeat the main test loop multiple times.
|
| +#
|
| +for {set i 2} {$i<=30} {incr i} {
|
| + # Delete one row out of every 10 in the database. This will add
|
| + # many pages to the freelist.
|
| + #
|
| + set todel {}
|
| + set n [expr {[llength $data]/10}]
|
| + set data [scramble $data]
|
| + foreach rec [lrange $data 0 $n] {
|
| + lappend todel [lindex $rec 0]
|
| + }
|
| + set data [lrange $data [expr {$n+1}] end]
|
| + set max1 [lindex [lindex $data 0] 0]
|
| + foreach rec $data {
|
| + set id [lindex $rec 0]
|
| + if {$id>$max1} {set max1 $id}
|
| + }
|
| + set origres [list [hash1] [hash2]]
|
| + do_test trans2-$i.1 {
|
| + db eval "DELETE FROM t1 WHERE id IN ([join $todel ,])"
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| + } $origres
|
| + integrity_check trans2-$i.2
|
| +
|
| + # Begin a transaction and insert many new records.
|
| + #
|
| + set newdata {}
|
| + foreach id $todel {
|
| + set rec [list $id [random_uuid] \
|
| + [expr {int(rand()*5000)+1000}] [random_uuid]]
|
| + lappend newdata $rec
|
| + lappend data $rec
|
| + }
|
| + for {set j 1} {$j<50} {incr j} {
|
| + set id [expr {$max_rowid+$j}]
|
| + lappend todel $id
|
| + set rec [list $id [random_uuid] \
|
| + [expr {int(rand()*5000)+1000}] [random_uuid]]
|
| + lappend newdata $rec
|
| + lappend data $rec
|
| + }
|
| + set max_rowid [expr {$max_rowid+$j-1}]
|
| + set modsql {}
|
| + set inssql {}
|
| + set newres [list [hash1] [hash2]]
|
| + do_test trans2-$i.3 {
|
| + db eval BEGIN
|
| + foreach rec [scramble $newdata] {
|
| + foreach {id u1 z u2} $rec break
|
| + set s "INSERT INTO t1 VALUES($id,'$u1',zeroblob($z),'$u2');"
|
| + append modsql $s\n
|
| + append inssql $s\n
|
| + db eval $s
|
| + }
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| + } $newres
|
| + integrity_check trans2-$i.4
|
| +
|
| + # Do a large update that aborts do to a constraint failure near
|
| + # the end. This stresses the statement journal mechanism.
|
| + #
|
| + do_test trans2-$i.10 {
|
| + catchsql {
|
| + UPDATE t1 SET u1=u1||'x',
|
| + z = CASE WHEN id<$max_rowid
|
| + THEN zeroblob((random()&65535)%5000 + 1000) END;
|
| + }
|
| + } {1 {t1.z may not be NULL}}
|
| + do_test trans2-$i.11 {
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| + } $newres
|
| +
|
| + # Delete all of the newly inserted records. Verify that the database
|
| + # is back to its original state.
|
| + #
|
| + do_test trans2-$i.20 {
|
| + set s "DELETE FROM t1 WHERE id IN ([join $todel ,]);"
|
| + append modsql $s\n
|
| + db eval $s
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| + } $origres
|
| +
|
| + # Do another large update that aborts do to a constraint failure near
|
| + # the end. This stresses the statement journal mechanism.
|
| + #
|
| + do_test trans2-$i.30 {
|
| + catchsql {
|
| + UPDATE t1 SET u1=u1||'x',
|
| + z = CASE WHEN id<$max1
|
| + THEN zeroblob((random()&65535)%5000 + 1000) END;
|
| + }
|
| + } {1 {t1.z may not be NULL}}
|
| + do_test trans2-$i.31 {
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| + } $origres
|
| +
|
| + # Redo the inserts
|
| + #
|
| + do_test trans2-$i.40 {
|
| + db eval $inssql
|
| + append modsql $inssql
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| + } $newres
|
| +
|
| + # Rollback the transaction. Verify that the content is restored.
|
| + #
|
| + do_test trans2-$i.90 {
|
| + db eval ROLLBACK
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| + } $origres
|
| + integrity_check trans2-$i.91
|
| +
|
| + # Repeat all the changes, but this time commit.
|
| + #
|
| + do_test trans2-$i.92 {
|
| + db eval BEGIN
|
| + catchsql {
|
| + UPDATE t1 SET u1=u1||'x',
|
| + z = CASE WHEN id<$max1
|
| + THEN zeroblob((random()&65535)%5000 + 1000) END;
|
| + }
|
| + db eval $modsql
|
| + catchsql {
|
| + UPDATE t1 SET u1=u1||'x',
|
| + z = CASE WHEN id<$max1
|
| + THEN zeroblob((random()&65535)%5000 + 1000) END;
|
| + }
|
| + db eval COMMIT
|
| + db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}
|
| + } $newres
|
| + integrity_check trans2-$i.93
|
| +}
|
| +
|
| +unset -nocomplain data i max_rowid todel n rec max1 id origres newres
|
| +unset -nocomplain inssql modsql s j z
|
| +finish_test
|
|
|