Annotation of embedaddon/sqlite3/test/thread003.test, revision 1.1.1.1

1.1       misho       1: # 2007 September 10
                      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 contains tests that attempt to break the pcache module
                     13: #   by bombarding it with simultaneous requests from multiple threads.
                     14: #     
                     15: # $Id: thread003.test,v 1.8 2009/03/26 14:48:07 danielk1977 Exp $
                     16: 
                     17: set testdir [file dirname $argv0]
                     18: 
                     19: source $testdir/tester.tcl
                     20: if {[run_thread_tests]==0} { finish_test ; return }
                     21: 
                     22: # Set up a couple of different databases full of pseudo-randomly 
                     23: # generated data.
                     24: #
                     25: do_test thread003.1.1 {
                     26:   execsql {
                     27:     BEGIN;
                     28:     CREATE TABLE t1(a, b, c);
                     29:   }
                     30:   for {set ii 0} {$ii < 5000} {incr ii} {
                     31:     execsql {INSERT INTO t1 VALUES($ii, randomblob(200), randomblob(200))}
                     32:   }
                     33:   execsql { 
                     34:     CREATE INDEX i1 ON t1(a, b); 
                     35:     COMMIT;
                     36:   }
                     37: } {}
                     38: do_test thread003.1.2 {
                     39:   expr {([file size test.db] / 1024) > 2000}
                     40: } {1}
                     41: do_test thread003.1.3 {
                     42:   db close
                     43:   forcedelete test2.db
                     44:   sqlite3 db test2.db
                     45: } {}
                     46: do_test thread003.1.4 {
                     47:   execsql {
                     48:     BEGIN;
                     49:     CREATE TABLE t1(a, b, c);
                     50:   }
                     51:   for {set ii 0} {$ii < 5000} {incr ii} {
                     52:     execsql {INSERT INTO t1 VALUES($ii, randomblob(200), randomblob(200))}
                     53:   }
                     54:   execsql { 
                     55:     CREATE INDEX i1 ON t1(a, b); 
                     56:     COMMIT;
                     57:   }
                     58: } {}
                     59: do_test thread003.1.5 {
                     60:   expr {([file size test.db] / 1024) > 2000}
                     61: } {1}
                     62: do_test thread003.1.6 {
                     63:   db close
                     64: } {}
                     65: 
                     66: 
                     67: # This test opens a connection on each of the large (>2MB) database files
                     68: # created by the previous block. The connections do not share a cache.
                     69: # Both "cache_size" parameters are set to 15, so there is a maximum of
                     70: # 30 pages available globally.
                     71: #
                     72: # Then, in separate threads, the databases are randomly queried over and
                     73: # over again. This will force the connections to recycle clean pages from
                     74: # each other. If there is a thread-safety problem, a segfault or assertion
                     75: # failure may eventually occur.
                     76: #
                     77: set nSecond 30
                     78: puts "Starting thread003.2 (should run for ~$nSecond seconds)"
                     79: do_test thread003.2 {
                     80:   foreach zFile {test.db test2.db} {
                     81:     set SCRIPT [format {
                     82:       set iEnd [expr {[clock_seconds] + %d}]
                     83:       set ::DB [sqlthread open %s xyzzy]
                     84:   
                     85:       # Set the cache size to 15 pages per cache. 30 available globally.
                     86:       execsql { PRAGMA cache_size = 15 }
                     87:   
                     88:       while {[clock_seconds] < $iEnd} {
                     89:         set iQuery [expr {int(rand()*5000)}]
                     90:         execsql " SELECT * FROM t1 WHERE a = $iQuery "
                     91:       }
                     92:   
                     93:       sqlite3_close $::DB
                     94:       expr 1
                     95:     } $nSecond $zFile]
                     96:   
                     97:     unset -nocomplain finished($zFile)
                     98:     thread_spawn finished($zFile) $thread_procs $SCRIPT
                     99:   }
                    100:   foreach zFile {test.db test2.db} {
                    101:     if {![info exists finished($zFile)]} {
                    102:       vwait finished($zFile)
                    103:     }
                    104:   }
                    105:   expr 0
                    106: } {0}
                    107: 
                    108: # This test is the same as the test above, except that each thread also
                    109: # writes to the database. This causes pages to be moved back and forth 
                    110: # between the caches internal dirty and clean lists, which is another
                    111: # opportunity for a thread-related bug to present itself.
                    112: #
                    113: set nSecond 30
                    114: puts "Starting thread003.3 (should run for ~$nSecond seconds)"
                    115: do_test thread003.3 {
                    116:   foreach zFile {test.db test2.db} {
                    117:     set SCRIPT [format {
                    118:       set iStart [clock_seconds]
                    119:       set iEnd [expr {[clock_seconds] + %d}]
                    120:       set ::DB [sqlthread open %s xyzzy]
                    121:   
                    122:       # Set the cache size to 15 pages per cache. 30 available globally.
                    123:       execsql { PRAGMA cache_size = 15 }
                    124:   
                    125:       while {[clock_seconds] < $iEnd} {
                    126:         set iQuery [expr {int(rand()*5000)}]
                    127:         execsql "SELECT * FROM t1 WHERE a = $iQuery"
                    128:         execsql "UPDATE t1 SET b = randomblob(200) 
                    129:                  WHERE a < $iQuery AND a > $iQuery + 20
                    130:         "
                    131:       }
                    132:   
                    133:       sqlite3_close $::DB
                    134:       expr 1
                    135:     } $nSecond $zFile]
                    136:   
                    137:     unset -nocomplain finished($zFile)
                    138:     thread_spawn finished($zFile) $thread_procs $SCRIPT
                    139:   }
                    140:   foreach zFile {test.db test2.db} {
                    141:     if {![info exists finished($zFile)]} {
                    142:       vwait finished($zFile)
                    143:     }
                    144:   }
                    145:   expr 0
                    146: } {0}
                    147: 
                    148: # In this test case, one thread is continually querying the database.
                    149: # The other thread does not have a database connection, but calls
                    150: # sqlite3_release_memory() over and over again.
                    151: #
                    152: set nSecond 30
                    153: puts "Starting thread003.4 (should run for ~$nSecond seconds)"
                    154: unset -nocomplain finished(1)
                    155: unset -nocomplain finished(2)
                    156: do_test thread003.4 {
                    157:   thread_spawn finished(1) $thread_procs [format {
                    158:     set iEnd [expr {[clock_seconds] + %d}]
                    159:     set ::DB [sqlthread open test.db xyzzy]
                    160: 
                    161:     # Set the cache size to 15 pages per cache. 30 available globally.
                    162:     execsql { PRAGMA cache_size = 15 }
                    163: 
                    164:     while {[clock_seconds] < $iEnd} {
                    165:       set iQuery [expr {int(rand()*5000)}]
                    166:       execsql "SELECT * FROM t1 WHERE a = $iQuery"
                    167:     }
                    168: 
                    169:     sqlite3_close $::DB
                    170:     expr 1
                    171:   } $nSecond] 
                    172:   thread_spawn finished(2) [format {
                    173:     set iEnd [expr {[clock_seconds] + %d}]
                    174: 
                    175:     while {[clock_seconds] < $iEnd} {
                    176:       sqlite3_release_memory 1000
                    177:     }
                    178:   } $nSecond]
                    179:   
                    180:   foreach ii {1 2} {
                    181:     if {![info exists finished($ii)]} {
                    182:       vwait finished($ii)
                    183:     }
                    184:   }
                    185:   expr 0
                    186: } {0}
                    187: 
                    188: set sqlite_open_file_count 0
                    189: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>