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