xref: /sqlite-3.40.0/test/thread003.test (revision 51d2d036)
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