############################################################################### # # stress.eagle -- # # Written by Joe Mistachkin. # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle package require Eagle.Library package require Eagle.Test runTestPrologue ############################################################################### package require System.Data.SQLite.Test runSQLiteTestPrologue ############################################################################### runTest {test stress-1.1 {multithreaded stress testing} -setup { proc showTest { indicator } { puts -nonewline stdout $indicator; flush stdout after [expr {int(rand() * 1000)}] } ############################################################################# proc failThisTest { error } { set level [expr {[info level] - 1}] puts stdout ""; flush stdout puts stdout [appendArgs [info level $level] ": " $error]; flush stdout puts stdout ""; flush stdout exit Failure; # halt all testing now. } ############################################################################# set count(0) 1 set count(1) 10 if {[info exists argv] && [llength $argv] > 0} then { parse options [list \ [list null MustHaveIntegerValue -1 -1 -count0 $count(0)] \ [list null MustHaveIntegerValue -1 -1 -count1 $count(1)]] $argv set count(0) $options(-count0,value) set count(1) $options(-count1,value) } ############################################################################# tputs $test_channel [appendArgs \ "---- workloads will repeat " $count(0) " time(s)...\n"] tputs $test_channel [appendArgs \ "---- workloads will have " $count(1) " iteration(s)...\n"] ############################################################################# set fileName(1) "file::memory:?cache=shared" set fileName(2) [file join [getDatabaseDirectory] stress.db] ############################################################################# setupDb $fileName(1) "" "" "" "" "" false true srcDb setupDb $fileName(2) ############################################################################# set workload(1) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #1, CREATE TABLE statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 2} {$index <= $count} {incr index} { sql execute $db [appendArgs \ "CREATE TABLE IF NOT EXISTS t" $index "(x PRIMARY KEY, y, z);"] showTest 1 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(2) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #2, DROP TABLE statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 2} {$index <= $count} {incr index} { sql execute $db [appendArgs \ "DROP TABLE IF EXISTS t" $index \;] showTest 2 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(3) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #3, "small" SELECT statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 1} {$index <= $count} {incr index} { sql execute -execute reader $db [appendArgs \ "SELECT x, y FROM " $table " WHERE z = 'small';"] showTest 3 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(4) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #4, "big" SELECT statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 1} {$index <= $count} {incr index} { sql execute -execute reader $db [appendArgs \ "SELECT x, y FROM " $table " WHERE z = 'big';"] showTest 4 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(5) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #5, "small" INSERT statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 1} {$index <= $count} {incr index} { sql execute $db [appendArgs \ "INSERT INTO " $table "(x, y, z) VALUES('" \ [format %lX [expr {random()}]] "', '" \ [base64 encode -- [expr {randstr(10000)}]] \ "', 'small');"] showTest 5 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(6) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #6, "big" INSERT statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 1} {$index <= $count} {incr index} { sql execute $db [appendArgs \ "INSERT INTO " $table "(x, y, z) VALUES('" \ [format %lX [expr {random()}]] \ "', RANDOMBLOB(10000000), 'big');"] showTest 6 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(7) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #7, "small" UPDATE statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 1} {$index <= $count} {incr index} { sql execute $db [appendArgs "UPDATE " $table \ " SET y = '" [base64 encode -- [expr {randstr(10000)}]] \ "' WHERE x LIKE '" [format %X $index] "%' AND z = 'small';"] showTest 7 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(8) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #8, "big" UPDATE statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 1} {$index <= $count} {incr index} { sql execute $db [appendArgs "UPDATE " $table \ " SET y = RANDOMBLOB(10000000) WHERE x LIKE '" \ [format %X $index] "%' AND z = 'big';"] showTest 8 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(9) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #9, "small" DELETE statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 1} {$index <= $count} {incr index} { sql execute $db [appendArgs "DELETE FROM " $table \ " WHERE x LIKE '" [format %X $index] "%' AND z = 'small';"] showTest 9 } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(10) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #10, "big" DELETE statements. # setupDb $dstFileName "" "" "" "" "" false if {[catch { for {set index 1} {$index <= $count} {incr index} { sql execute $db [appendArgs "DELETE FROM " $table \ " WHERE x LIKE '" [format %X $index] "%' AND z = 'big';"] showTest A } } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(11) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #11, VACUUM statement. # setupDb $dstFileName "" "" "" "" "" false if {[catch { sql execute $db "VACUUM;" showTest B } error]} then { if {[regexp -- {\sno such table: t1\s} $error]} then { showTest * } else { failThisTest $error } } cleanupDb $dstFileName db false false }] ############################################################################# set workload(12) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #12, backup to in-memory database. # set id [object invoke Interpreter.GetActive NextId] set code [compileCSharpWith [subst { using System; using System.Data.SQLite; using System.Text; namespace _Dynamic${id} { public static class Test${id} { public static void BackupAndGetData() { using (SQLiteConnection source = new SQLiteConnection( "FullUri=${srcFileName};")) { source.Open(); using (SQLiteConnection destination = new SQLiteConnection( "FullUri=${dstFileName};")) { destination.Open(); source.BackupDatabase(destination, "main", "main", -1, null, 0); } } } ///////////////////////////////////////////////////////////////////// public static void Main() { // do nothing. } } } }] true true true results errors System.Data.SQLite.dll] if {$code eq "Ok"} then { object invoke _Dynamic${id}.Test${id} BackupAndGetData } else { error $errors } showTest C }] ############################################################################# set workload(13) [list [list srcFileName dstFileName table count] { # # NOTE: Workload #13, backup from an in-memory database. # set id [object invoke Interpreter.GetActive NextId] set code [compileCSharpWith [subst { using System; using System.Data.SQLite; using System.Text; namespace _Dynamic${id} { public static class Test${id} { public static void BackupAndGetData() { using (SQLiteConnection source = new SQLiteConnection( "FullUri=${dstFileName};")) { source.Open(); using (SQLiteConnection destination = new SQLiteConnection( "FullUri=${srcFileName};")) { destination.Open(); source.BackupDatabase(destination, "main", "main", -1, null, 0); } } } ///////////////////////////////////////////////////////////////////// public static void Main() { // do nothing. } } } }] true true true results errors System.Data.SQLite.dll] if {$code eq "Ok"} then { object invoke _Dynamic${id}.Test${id} BackupAndGetData } else { error $errors } showTest D }] } -body { for {set index(0) 0} {$index(0) < $count(0)} {incr index(0)} { sql execute $db "CREATE TABLE IF NOT EXISTS t1(x PRIMARY KEY, y, z);" unset -nocomplain thread foreach index(1) [array names workload] { set thread($index(1)) [object create -alias System.Threading.Thread \ [list apply $workload($index(1)) $fileName(1) $fileName(2) t1 \ $count(1)]] } foreach index(1) [array names thread] { $thread($index(1)) Start } foreach index(1) [array names thread] { $thread($index(1)) Join } } puts stdout "" } -cleanup { rename failThisTest "" rename showTest "" cleanupDb $fileName(2) cleanupDb $fileName(1) srcDb unset -nocomplain thread index workload srcDb db fileName options count } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result {}} ############################################################################### runSQLiteTestEpilogue runTestEpilogue