Merge trunk into this branch.
[sqlite.git] / test / thread001.test
blob1390f0d991532b914f123239f32aad4a5aff2f61
1 # 2007 September 7
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # $Id: thread001.test,v 1.10 2009/03/26 14:48:07 danielk1977 Exp $
14 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 if {[run_thread_tests]==0} { finish_test ; return }
18 ifcapable !shared_cache { finish_test ; return }
20 set ::enable_shared_cache [sqlite3_enable_shared_cache]
22 set ::NTHREAD 10
24 # Run this test three times: 
25
26 #    1) All threads use the same database handle.
27 #    2) All threads use their own database handles.
28 #    3) All threads use their own database handles, shared-cache is enabled.
32 foreach {tn same_db shared_cache} [list \
33          1  1       0                   \
34          2  0       0                   \
35          3  0       1                   \
36 ] {
37   # Empty the database.
38   #
39   catchsql { DROP TABLE ab; }
41   do_test thread001.$tn.0 {
42     db close
43     sqlite3_enable_shared_cache $shared_cache
44     sqlite3_enable_shared_cache $shared_cache
45   } $shared_cache
46   sqlite3 db test.db -fullmutex 1 -key xyzzy
48   set dbconfig ""
49   if {$same_db} {
50     set dbconfig [list set ::DB [sqlite3_connection_pointer db]]
51   }
53   # Set up a database and a schema. The database contains a single
54   # table with two columns. The first column ("a") is an INTEGER PRIMARY 
55   # KEY. The second contains the md5sum of all rows in the table with
56   # a smaller value stored in column "a".
57   #
58   do_test thread001.$tn.1 {
59     execsql {
60       CREATE TABLE ab(a INTEGER PRIMARY KEY, b);
61       CREATE INDEX ab_i ON ab(b);
62       INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab;
63       SELECT count(*) FROM ab;
64     }
65   } {1}
66   do_test thread001.$tn.2 {
67     execsql {
68       SELECT 
69         (SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
70         (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
71     }
72   } {1}
73   do_test thread001.$tn.3 {
74     execsql { PRAGMA integrity_check }
75   } {ok}
77   set thread_program {
78     #sqlthread parent {puts STARTING..}
79     set needToClose 0
80     if {![info exists ::DB]} {
81       set ::DB [sqlthread open test.db xyzzy]
82       #sqlthread parent "puts \"OPEN $::DB\""
83       set needToClose 1
84     }
85   
86     for {set i 0} {$i < 100} {incr i} {
87       # Test that the invariant is true.
88       do_test t1 {
89         execsql {
90           SELECT 
91             (SELECT md5sum(a, b) FROM ab WHERE +a < (SELECT max(a) FROM ab)) ==
92             (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
93         }
94       } {1}
95   
96       # Add another row to the database.
97       execsql { INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab }
98     }
99   
100     if {$needToClose} {
101       #sqlthread parent "puts \"CLOSE $::DB\""
102       sqlite3_close $::DB
103     }
104     #sqlthread parent "puts \"DONE\""
105   
106     list OK
107   }
108   
109   # Kick off $::NTHREAD threads:
110   #
111   array unset finished
112   for {set i 0} {$i < $::NTHREAD} {incr i} {
113     thread_spawn finished($i) $dbconfig $thread_procs $thread_program
114   }
115   
116   # Wait for all threads to finish,  then check they all returned "OK".
117   #
118   for {set i 0} {$i < $::NTHREAD} {incr i} {
119     if {![info exists finished($i)]} {
120       vwait finished($i)
121     }
122     do_test thread001.$tn.4.$i {
123       set ::finished($i)
124     } OK
125   }
126   
127   # Check the database still looks Ok.
128   #
129   do_test thread001.$tn.5 {
130     execsql { SELECT count(*) FROM ab; }
131   } [expr {1 + $::NTHREAD*100}]
132   do_test thread001.$tn.6 {
133     execsql {
134       SELECT 
135         (SELECT md5sum(a, b) FROM ab WHERE +a < (SELECT max(a) FROM ab)) ==
136         (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
137     }
138   } {1}
139   do_test thread001.$tn.7 {
140     execsql { PRAGMA integrity_check }
141   } {ok}
144 sqlite3_enable_shared_cache $::enable_shared_cache
145 catch { db close }
146 set sqlite_open_file_count 0
147 finish_test