xref: /sqlite-3.40.0/test/thread2.test (revision 64b1bea3)
1# 2006 January 14
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# This file implements regression tests for SQLite library.  The
12# focus of this script is multithreading behavior
13#
14# $Id: thread2.test,v 1.1 2006/01/15 02:30:58 drh Exp $
15
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20# Skip this whole file if the thread testing code is not enabled
21#
22if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
23  finish_test
24  return
25}
26if {![info exists threadsOverrideEachOthersLocks]} {
27  finish_test
28  return
29}
30
31# Create some data to work with
32#
33do_test thread1-1.1 {
34  execsql {
35    CREATE TABLE t1(a,b);
36    INSERT INTO t1 VALUES(1,'abcdefgh');
37    INSERT INTO t1 SELECT a+1, b||b FROM t1;
38    INSERT INTO t1 SELECT a+2, b||b FROM t1;
39    INSERT INTO t1 SELECT a+4, b||b FROM t1;
40    SELECT count(*), max(length(b)) FROM t1;
41  }
42} {8 64}
43
44# Use the thread_swap command to move the database connections between
45# threads, then verify that they still work.
46#
47do_test thread2-1.2 {
48  db close
49  thread_create A test.db
50  thread_create B test.db
51  thread_swap A B
52  thread_compile A {SELECT a FROM t1 LIMIT 1}
53  thread_result A
54} {SQLITE_OK}
55do_test thread2-1.3 {
56  thread_step A
57  thread_result A
58} {SQLITE_ROW}
59do_test thread2-1.4 {
60  thread_argv A 0
61} {1}
62do_test thread2-1.5 {
63  thread_finalize A
64  thread_result A
65} {SQLITE_OK}
66do_test thread2-1.6 {
67  thread_compile B {SELECT a FROM t1 LIMIT 1}
68  thread_result B
69} {SQLITE_OK}
70do_test thread2-1.7 {
71  thread_step B
72  thread_result B
73} {SQLITE_ROW}
74do_test thread2-1.8 {
75  thread_argv B 0
76} {1}
77do_test thread2-1.9 {
78  thread_finalize B
79  thread_result B
80} {SQLITE_OK}
81
82# Swap them again.
83#
84do_test thread2-2.2 {
85  thread_swap A B
86  thread_compile A {SELECT a FROM t1 LIMIT 1}
87  thread_result A
88} {SQLITE_OK}
89do_test thread2-2.3 {
90  thread_step A
91  thread_result A
92} {SQLITE_ROW}
93do_test thread2-2.4 {
94  thread_argv A 0
95} {1}
96do_test thread2-2.5 {
97  thread_finalize A
98  thread_result A
99} {SQLITE_OK}
100do_test thread2-2.6 {
101  thread_compile B {SELECT a FROM t1 LIMIT 1}
102  thread_result B
103} {SQLITE_OK}
104do_test thread2-2.7 {
105  thread_step B
106  thread_result B
107} {SQLITE_ROW}
108do_test thread2-2.8 {
109  thread_argv B 0
110} {1}
111do_test thread2-2.9 {
112  thread_finalize B
113  thread_result B
114} {SQLITE_OK}
115thread_halt A
116thread_halt B
117
118# Save the original (correct) value of threadsOverrideEachOthersLocks
119# so that it can be restored.  If this value is left set incorrectly, lots
120# of things will go wrong in future tests.
121#
122set orig_threadOverride $threadsOverrideEachOthersLocks
123
124# Pretend we are on a system (like RedHat9) were threads do not
125# override each others locks.
126#
127set threadsOverrideEachOthersLocks 0
128
129# Verify that we can move database connections between threads as
130# long as no locks are held.
131#
132do_test thread2-3.1 {
133  thread_create A test.db
134  set DB [thread_db_get A]
135  thread_halt A
136} {}
137do_test thread2-3.2 {
138  set STMT [sqlite3_prepare $DB {SELECT a FROM t1 LIMIT 1} -1 TAIL]
139  sqlite3_step $STMT
140} SQLITE_ROW
141do_test thread2-3.3 {
142  sqlite3_column_int $STMT 0
143} 1
144do_test thread2-3.4 {
145  sqlite3_finalize $STMT
146} SQLITE_OK
147do_test thread2-3.5 {
148  set STMT [sqlite3_prepare $DB {SELECT max(a) FROM t1} -1 TAIL]
149  sqlite3_step $STMT
150} SQLITE_ROW
151do_test thread2-3.6 {
152  sqlite3_column_int $STMT 0
153} 8
154do_test thread2-3.7 {
155  sqlite3_finalize $STMT
156} SQLITE_OK
157do_test thread2-3.8 {
158  sqlite3_close $DB
159} {SQLITE_OK}
160
161do_test thread2-3.10 {
162  thread_create A test.db
163  thread_compile A {SELECT a FROM t1 LIMIT 1}
164  thread_step A
165  thread_finalize A
166  set DB [thread_db_get A]
167  thread_halt A
168} {}
169do_test thread2-3.11 {
170  set STMT [sqlite3_prepare $DB {SELECT a FROM t1 LIMIT 1} -1 TAIL]
171  sqlite3_step $STMT
172} SQLITE_ROW
173do_test thread2-3.12 {
174  sqlite3_column_int $STMT 0
175} 1
176do_test thread2-3.13 {
177  sqlite3_finalize $STMT
178} SQLITE_OK
179do_test thread2-3.14 {
180  sqlite3_close $DB
181} SQLITE_OK
182
183do_test thread2-3.20 {
184  thread_create A test.db
185  thread_compile A {SELECT a FROM t1 LIMIT 3}
186  thread_step A
187  set STMT [thread_stmt_get A]
188  set DB [thread_db_get A]
189  thread_halt A
190} {}
191do_test thread2-3.21 {
192  sqlite3_step $STMT
193} SQLITE_ROW
194do_test thread2-3.22 {
195  sqlite3_column_int $STMT 0
196} 2
197do_test thread2-3.23 {
198  # The unlock fails here.  But because we never check the return
199  # code from sqlite3OsUnlock (because we cannot do anything about it
200  # if it fails) we do not realize that an error has occurred.
201  sqlite3_finalize $STMT
202} SQLITE_OK
203do_test thread2-3.25 {
204  sqlite3_close $DB
205} SQLITE_OK
206
207do_test thread2-3.30 {
208  thread_create A test.db
209  thread_compile A {BEGIN}
210  thread_step A
211  thread_finalize A
212  thread_compile A {SELECT a FROM t1 LIMIT 1}
213  thread_step A
214  thread_finalize A
215  set DB [thread_db_get A]
216  thread_halt A
217} {}
218do_test thread2-3.31 {
219  set STMT [sqlite3_prepare $DB {INSERT INTO t1 VALUES(99,'error')} -1 TAIL]
220  sqlite3_step $STMT
221} SQLITE_ERROR
222do_test thread2-3.32 {
223  sqlite3_finalize $STMT
224} SQLITE_MISUSE
225do_test thread2-3.33 {
226  sqlite3_close $DB
227} SQLITE_OK
228
229# VERY important to set the override flag back to its true value.
230#
231set threadsOverrideEachOthersLocks $orig_threadOverride
232
233# Also important to halt the worker threads, which are using spin
234# locks and eating away CPU cycles.
235#
236thread_halt *
237finish_test
238