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 2008/08/28 08:31:48 danielk1977 Exp $ 16 17set testdir [file dirname $argv0] 18 19source $testdir/tester.tcl 20source $testdir/thread_common.tcl 21if {[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# 29do_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} {} 42do_test thread003.1.2 { 43 expr {([file size test.db] / 1024) > 2000} 44} {1} 45do_test thread003.1.3 { 46 db close 47 file delete -force test2.db 48 sqlite3 db test2.db 49} {} 50do_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} {} 63do_test thread003.1.5 { 64 expr {([file size test.db] / 1024) > 2000} 65} {1} 66do_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# 81set nSecond 30 82puts "Starting thread003.2 (should run for ~$nSecond seconds)" 83do_test thread003.2 { 84 foreach zFile {test.db test2.db} { 85 set SCRIPT [format { 86 set iStart [clock seconds] 87 set iEnd [expr {[clock seconds] + %d}] 88 set ::DB [sqlthread open %s] 89 90 # Set the cache size to 15 pages per cache. 30 available globally. 91 execsql { PRAGMA cache_size = 15 } 92 93 while {[clock seconds] < $iEnd} { 94 set iQuery [expr {int(rand()*5000)}] 95 execsql " SELECT * FROM t1 WHERE a = $iQuery " 96 } 97 98 sqlite3_close $::DB 99 expr 1 100 } $nSecond $zFile] 101 102 unset -nocomplain finished($zFile) 103 thread_spawn finished($zFile) $thread_procs $SCRIPT 104 } 105 foreach zFile {test.db test2.db} { 106 if {![info exists finished($zFile)]} { 107 vwait finished($zFile) 108 } 109 } 110 expr 0 111} {0} 112 113finish_test 114 115 116