|
1 # 2003 December 18 |
|
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: thread1.test,v 1.7 2004/06/19 00:16:31 drh Exp $ |
|
15 |
|
16 |
|
17 set testdir [file dirname $argv0] |
|
18 source $testdir/tester.tcl |
|
19 |
|
20 # Skip this whole file if the thread testing code is not enabled |
|
21 # |
|
22 if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} { |
|
23 finish_test |
|
24 return |
|
25 } |
|
26 |
|
27 # Create some data to work with |
|
28 # |
|
29 do_test thread1-1.1 { |
|
30 execsql { |
|
31 CREATE TABLE t1(a,b); |
|
32 INSERT INTO t1 VALUES(1,'abcdefgh'); |
|
33 INSERT INTO t1 SELECT a+1, b||b FROM t1; |
|
34 INSERT INTO t1 SELECT a+2, b||b FROM t1; |
|
35 INSERT INTO t1 SELECT a+4, b||b FROM t1; |
|
36 SELECT count(*), max(length(b)) FROM t1; |
|
37 } |
|
38 } {8 64} |
|
39 |
|
40 # Interleave two threads on read access. Then make sure a third |
|
41 # thread can write the database. In other words: |
|
42 # |
|
43 # read-lock A |
|
44 # read-lock B |
|
45 # unlock A |
|
46 # unlock B |
|
47 # write-lock C |
|
48 # |
|
49 # At one point, the write-lock of C would fail on Linux. |
|
50 # |
|
51 do_test thread1-1.2 { |
|
52 thread_create A test.db |
|
53 thread_create B test.db |
|
54 thread_create C test.db |
|
55 thread_compile A {SELECT a FROM t1} |
|
56 thread_step A |
|
57 thread_result A |
|
58 } SQLITE_ROW |
|
59 do_test thread1-1.3 { |
|
60 thread_argc A |
|
61 } 1 |
|
62 do_test thread1-1.4 { |
|
63 thread_argv A 0 |
|
64 } 1 |
|
65 do_test thread1-1.5 { |
|
66 thread_compile B {SELECT b FROM t1} |
|
67 thread_step B |
|
68 thread_result B |
|
69 } SQLITE_ROW |
|
70 do_test thread1-1.6 { |
|
71 thread_argc B |
|
72 } 1 |
|
73 do_test thread1-1.7 { |
|
74 thread_argv B 0 |
|
75 } abcdefgh |
|
76 do_test thread1-1.8 { |
|
77 thread_finalize A |
|
78 thread_result A |
|
79 } SQLITE_OK |
|
80 do_test thread1-1.9 { |
|
81 thread_finalize B |
|
82 thread_result B |
|
83 } SQLITE_OK |
|
84 do_test thread1-1.10 { |
|
85 thread_compile C {CREATE TABLE t2(x,y)} |
|
86 thread_step C |
|
87 thread_result C |
|
88 } SQLITE_DONE |
|
89 do_test thread1-1.11 { |
|
90 thread_finalize C |
|
91 thread_result C |
|
92 } SQLITE_OK |
|
93 do_test thread1-1.12 { |
|
94 catchsql {SELECT name FROM sqlite_master} |
|
95 execsql {SELECT name FROM sqlite_master} |
|
96 } {t1 t2} |
|
97 |
|
98 |
|
99 # |
|
100 # The following tests - thread1-2.* - test the following scenario: |
|
101 # |
|
102 # 1: Read-lock thread A |
|
103 # 2: Read-lock thread B |
|
104 # 3: Attempt to write in thread C -> SQLITE_BUSY |
|
105 # 4: Check db write failed from main thread. |
|
106 # 5: Unlock from thread A. |
|
107 # 6: Attempt to write in thread C -> SQLITE_BUSY |
|
108 # 7: Check db write failed from main thread. |
|
109 # 8: Unlock from thread B. |
|
110 # 9: Attempt to write in thread C -> SQLITE_DONE |
|
111 # 10: Finalize the write from thread C |
|
112 # 11: Check db write succeeded from main thread. |
|
113 # |
|
114 do_test thread1-2.1 { |
|
115 thread_halt * |
|
116 thread_create A test.db |
|
117 thread_compile A {SELECT a FROM t1} |
|
118 thread_step A |
|
119 thread_result A |
|
120 } SQLITE_ROW |
|
121 do_test thread1-2.2 { |
|
122 thread_create B test.db |
|
123 thread_compile B {SELECT b FROM t1} |
|
124 thread_step B |
|
125 thread_result B |
|
126 } SQLITE_ROW |
|
127 do_test thread1-2.3 { |
|
128 thread_create C test.db |
|
129 thread_compile C {INSERT INTO t2 VALUES(98,99)} |
|
130 thread_step C |
|
131 thread_result C |
|
132 thread_finalize C |
|
133 thread_result C |
|
134 } SQLITE_BUSY |
|
135 |
|
136 do_test thread1-2.4 { |
|
137 execsql {SELECT * FROM t2} |
|
138 } {} |
|
139 |
|
140 do_test thread1-2.5 { |
|
141 thread_finalize A |
|
142 thread_result A |
|
143 } SQLITE_OK |
|
144 do_test thread1-2.6 { |
|
145 thread_compile C {INSERT INTO t2 VALUES(98,99)} |
|
146 thread_step C |
|
147 thread_result C |
|
148 thread_finalize C |
|
149 thread_result C |
|
150 } SQLITE_BUSY |
|
151 do_test thread1-2.7 { |
|
152 execsql {SELECT * FROM t2} |
|
153 } {} |
|
154 do_test thread1-2.8 { |
|
155 thread_finalize B |
|
156 thread_result B |
|
157 } SQLITE_OK |
|
158 do_test thread1-2.9 { |
|
159 thread_compile C {INSERT INTO t2 VALUES(98,99)} |
|
160 thread_step C |
|
161 thread_result C |
|
162 } SQLITE_DONE |
|
163 do_test thread1-2.10 { |
|
164 thread_finalize C |
|
165 thread_result C |
|
166 } SQLITE_OK |
|
167 do_test thread1-2.11 { |
|
168 execsql {SELECT * FROM t2} |
|
169 } {98 99} |
|
170 |
|
171 thread_halt * |
|
172 finish_test |