File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / test / thread003.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: # 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.1.1.1 2012/02/21 17:04:16 misho 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>