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