diff options
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/test/exclusive.test')
-rw-r--r-- | libraries/sqlite/unix/sqlite-3.5.1/test/exclusive.test | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/test/exclusive.test b/libraries/sqlite/unix/sqlite-3.5.1/test/exclusive.test new file mode 100644 index 0000000..20e012f --- /dev/null +++ b/libraries/sqlite/unix/sqlite-3.5.1/test/exclusive.test | |||
@@ -0,0 +1,449 @@ | |||
1 | # 2007 March 24 | ||
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 focus | ||
12 | # of these tests is exclusive access mode (i.e. the thing activated by | ||
13 | # "PRAGMA locking_mode = EXCLUSIVE"). | ||
14 | # | ||
15 | # $Id: exclusive.test,v 1.6 2007/08/12 20:07:59 drh Exp $ | ||
16 | |||
17 | set testdir [file dirname $argv0] | ||
18 | source $testdir/tester.tcl | ||
19 | |||
20 | ifcapable {!pager_pragmas} { | ||
21 | finish_test | ||
22 | return | ||
23 | } | ||
24 | |||
25 | file delete -force test2.db-journal | ||
26 | file delete -force test2.db | ||
27 | file delete -force test3.db-journal | ||
28 | file delete -force test3.db | ||
29 | file delete -force test4.db-journal | ||
30 | file delete -force test4.db | ||
31 | |||
32 | # The locking mode for the TEMP table is always "exclusive" for | ||
33 | # on-disk tables and "normal" for in-memory tables. | ||
34 | # | ||
35 | if {[info exists TEMP_STORE] && $TEMP_STORE>=2} { | ||
36 | set temp_mode normal | ||
37 | } else { | ||
38 | set temp_mode exclusive | ||
39 | } | ||
40 | |||
41 | #---------------------------------------------------------------------- | ||
42 | # Test cases exclusive-1.X test the PRAGMA logic. | ||
43 | # | ||
44 | do_test exclusive-1.0 { | ||
45 | execsql { | ||
46 | pragma locking_mode; | ||
47 | pragma main.locking_mode; | ||
48 | pragma temp.locking_mode; | ||
49 | } | ||
50 | } [list normal normal $temp_mode] | ||
51 | do_test exclusive-1.1 { | ||
52 | execsql { | ||
53 | pragma locking_mode = exclusive; | ||
54 | } | ||
55 | } {exclusive} | ||
56 | do_test exclusive-1.2 { | ||
57 | execsql { | ||
58 | pragma locking_mode; | ||
59 | pragma main.locking_mode; | ||
60 | pragma temp.locking_mode; | ||
61 | } | ||
62 | } [list exclusive exclusive $temp_mode] | ||
63 | do_test exclusive-1.3 { | ||
64 | execsql { | ||
65 | pragma locking_mode = normal; | ||
66 | } | ||
67 | } {normal} | ||
68 | do_test exclusive-1.4 { | ||
69 | execsql { | ||
70 | pragma locking_mode; | ||
71 | pragma main.locking_mode; | ||
72 | pragma temp.locking_mode; | ||
73 | } | ||
74 | } [list normal normal $temp_mode] | ||
75 | do_test exclusive-1.5 { | ||
76 | execsql { | ||
77 | pragma locking_mode = invalid; | ||
78 | } | ||
79 | } {normal} | ||
80 | do_test exclusive-1.6 { | ||
81 | execsql { | ||
82 | pragma locking_mode; | ||
83 | pragma main.locking_mode; | ||
84 | pragma temp.locking_mode; | ||
85 | } | ||
86 | } [list normal normal $temp_mode] | ||
87 | do_test exclusive-1.7 { | ||
88 | execsql { | ||
89 | pragma locking_mode = exclusive; | ||
90 | ATTACH 'test2.db' as aux; | ||
91 | } | ||
92 | execsql { | ||
93 | pragma main.locking_mode; | ||
94 | pragma aux.locking_mode; | ||
95 | } | ||
96 | } {exclusive exclusive} | ||
97 | do_test exclusive-1.8 { | ||
98 | execsql { | ||
99 | pragma main.locking_mode = normal; | ||
100 | } | ||
101 | execsql { | ||
102 | pragma main.locking_mode; | ||
103 | pragma temp.locking_mode; | ||
104 | pragma aux.locking_mode; | ||
105 | } | ||
106 | } [list normal $temp_mode exclusive] | ||
107 | do_test exclusive-1.9 { | ||
108 | execsql { | ||
109 | pragma locking_mode; | ||
110 | } | ||
111 | } {exclusive} | ||
112 | do_test exclusive-1.10 { | ||
113 | execsql { | ||
114 | ATTACH 'test3.db' as aux2; | ||
115 | } | ||
116 | execsql { | ||
117 | pragma main.locking_mode; | ||
118 | pragma aux.locking_mode; | ||
119 | pragma aux2.locking_mode; | ||
120 | } | ||
121 | } {normal exclusive exclusive} | ||
122 | do_test exclusive-1.11 { | ||
123 | execsql { | ||
124 | pragma aux.locking_mode = normal; | ||
125 | } | ||
126 | execsql { | ||
127 | pragma main.locking_mode; | ||
128 | pragma aux.locking_mode; | ||
129 | pragma aux2.locking_mode; | ||
130 | } | ||
131 | } {normal normal exclusive} | ||
132 | do_test exclusive-1.12 { | ||
133 | execsql { | ||
134 | pragma locking_mode = normal; | ||
135 | } | ||
136 | execsql { | ||
137 | pragma main.locking_mode; | ||
138 | pragma temp.locking_mode; | ||
139 | pragma aux.locking_mode; | ||
140 | pragma aux2.locking_mode; | ||
141 | } | ||
142 | } [list normal $temp_mode normal normal] | ||
143 | do_test exclusive-1.13 { | ||
144 | execsql { | ||
145 | ATTACH 'test4.db' as aux3; | ||
146 | } | ||
147 | execsql { | ||
148 | pragma main.locking_mode; | ||
149 | pragma temp.locking_mode; | ||
150 | pragma aux.locking_mode; | ||
151 | pragma aux2.locking_mode; | ||
152 | pragma aux3.locking_mode; | ||
153 | } | ||
154 | } [list normal $temp_mode normal normal normal] | ||
155 | |||
156 | do_test exclusive-1.99 { | ||
157 | execsql { | ||
158 | DETACH aux; | ||
159 | DETACH aux2; | ||
160 | DETACH aux3; | ||
161 | } | ||
162 | } {} | ||
163 | |||
164 | #---------------------------------------------------------------------- | ||
165 | # Test cases exclusive-2.X verify that connections in exclusive | ||
166 | # locking_mode do not relinquish locks. | ||
167 | # | ||
168 | do_test exclusive-2.0 { | ||
169 | execsql { | ||
170 | CREATE TABLE abc(a, b, c); | ||
171 | INSERT INTO abc VALUES(1, 2, 3); | ||
172 | PRAGMA locking_mode = exclusive; | ||
173 | } | ||
174 | } {exclusive} | ||
175 | do_test exclusive-2.1 { | ||
176 | sqlite3 db2 test.db | ||
177 | execsql { | ||
178 | INSERT INTO abc VALUES(4, 5, 6); | ||
179 | SELECT * FROM abc; | ||
180 | } db2 | ||
181 | } {1 2 3 4 5 6} | ||
182 | do_test exclusive-2.2 { | ||
183 | # This causes connection 'db' (in exclusive mode) to establish | ||
184 | # a shared-lock on the db. The other connection should now be | ||
185 | # locked out as a writer. | ||
186 | execsql { | ||
187 | SELECT * FROM abc; | ||
188 | } db | ||
189 | } {1 2 3 4 5 6} | ||
190 | do_test exclusive-2.4 { | ||
191 | execsql { | ||
192 | SELECT * FROM abc; | ||
193 | } db2 | ||
194 | } {1 2 3 4 5 6} | ||
195 | do_test exclusive-2.5 { | ||
196 | catchsql { | ||
197 | INSERT INTO abc VALUES(7, 8, 9); | ||
198 | } db2 | ||
199 | } {1 {database is locked}} | ||
200 | sqlite3_soft_heap_limit 0 | ||
201 | do_test exclusive-2.6 { | ||
202 | # Because connection 'db' only has a shared-lock, the other connection | ||
203 | # will be able to get a RESERVED, but will fail to upgrade to EXCLUSIVE. | ||
204 | execsql { | ||
205 | BEGIN; | ||
206 | INSERT INTO abc VALUES(7, 8, 9); | ||
207 | } db2 | ||
208 | catchsql { | ||
209 | COMMIT | ||
210 | } db2 | ||
211 | } {1 {database is locked}} | ||
212 | do_test exclusive-2.7 { | ||
213 | catchsql { | ||
214 | COMMIT | ||
215 | } db2 | ||
216 | } {1 {database is locked}} | ||
217 | do_test exclusive-2.8 { | ||
218 | execsql { | ||
219 | ROLLBACK; | ||
220 | } db2 | ||
221 | } {} | ||
222 | sqlite3_soft_heap_limit $soft_limit | ||
223 | |||
224 | do_test exclusive-2.9 { | ||
225 | # Write the database to establish the exclusive lock with connection 'db. | ||
226 | execsql { | ||
227 | INSERT INTO abc VALUES(7, 8, 9); | ||
228 | } db | ||
229 | catchsql { | ||
230 | SELECT * FROM abc; | ||
231 | } db2 | ||
232 | } {1 {database is locked}} | ||
233 | do_test exclusive-2.10 { | ||
234 | # Changing the locking-mode does not release any locks. | ||
235 | execsql { | ||
236 | PRAGMA locking_mode = normal; | ||
237 | } db | ||
238 | catchsql { | ||
239 | SELECT * FROM abc; | ||
240 | } db2 | ||
241 | } {1 {database is locked}} | ||
242 | do_test exclusive-2.11 { | ||
243 | # After changing the locking mode, accessing the db releases locks. | ||
244 | execsql { | ||
245 | SELECT * FROM abc; | ||
246 | } db | ||
247 | execsql { | ||
248 | SELECT * FROM abc; | ||
249 | } db2 | ||
250 | } {1 2 3 4 5 6 7 8 9} | ||
251 | db2 close | ||
252 | |||
253 | #---------------------------------------------------------------------- | ||
254 | # Tests exclusive-3.X - test that a connection in exclusive mode | ||
255 | # truncates instead of deletes the journal file when committing | ||
256 | # a transaction. | ||
257 | # | ||
258 | proc filestate {fname} { | ||
259 | set exists 0 | ||
260 | set content 0 | ||
261 | if {[file exists $fname]} { | ||
262 | set exists 1 | ||
263 | set content [expr {[file size $fname] > 0}] | ||
264 | } | ||
265 | list $exists $content | ||
266 | } | ||
267 | do_test exclusive-3.0 { | ||
268 | filestate test.db-journal | ||
269 | } {0 0} | ||
270 | do_test exclusive-3.1 { | ||
271 | execsql { | ||
272 | PRAGMA locking_mode = exclusive; | ||
273 | BEGIN; | ||
274 | DELETE FROM abc; | ||
275 | } | ||
276 | filestate test.db-journal | ||
277 | } {1 1} | ||
278 | do_test exclusive-3.2 { | ||
279 | execsql { | ||
280 | COMMIT; | ||
281 | } | ||
282 | filestate test.db-journal | ||
283 | } {1 0} | ||
284 | do_test exclusive-3.3 { | ||
285 | execsql { | ||
286 | INSERT INTO abc VALUES('A', 'B', 'C'); | ||
287 | SELECT * FROM abc; | ||
288 | } | ||
289 | } {A B C} | ||
290 | do_test exclusive-3.4 { | ||
291 | execsql { | ||
292 | BEGIN; | ||
293 | UPDATE abc SET a = 1, b = 2, c = 3; | ||
294 | ROLLBACK; | ||
295 | SELECT * FROM abc; | ||
296 | } | ||
297 | } {A B C} | ||
298 | do_test exclusive-3.5 { | ||
299 | filestate test.db-journal | ||
300 | } {1 0} | ||
301 | do_test exclusive-3.6 { | ||
302 | execsql { | ||
303 | PRAGMA locking_mode = normal; | ||
304 | SELECT * FROM abc; | ||
305 | } | ||
306 | filestate test.db-journal | ||
307 | } {0 0} | ||
308 | |||
309 | #---------------------------------------------------------------------- | ||
310 | # Tests exclusive-4.X - test that rollback works correctly when | ||
311 | # in exclusive-access mode. | ||
312 | # | ||
313 | |||
314 | # The following procedure computes a "signature" for table "t3". If | ||
315 | # T3 changes in any way, the signature should change. | ||
316 | # | ||
317 | # This is used to test ROLLBACK. We gather a signature for t3, then | ||
318 | # make lots of changes to t3, then rollback and take another signature. | ||
319 | # The two signatures should be the same. | ||
320 | # | ||
321 | proc signature {} { | ||
322 | return [db eval {SELECT count(*), md5sum(x) FROM t3}] | ||
323 | } | ||
324 | |||
325 | do_test exclusive-4.0 { | ||
326 | execsql { PRAGMA locking_mode = exclusive; } | ||
327 | execsql { PRAGMA default_cache_size = 10; } | ||
328 | execsql { | ||
329 | BEGIN; | ||
330 | CREATE TABLE t3(x TEXT); | ||
331 | INSERT INTO t3 VALUES(randstr(10,400)); | ||
332 | INSERT INTO t3 VALUES(randstr(10,400)); | ||
333 | INSERT INTO t3 SELECT randstr(10,400) FROM t3; | ||
334 | INSERT INTO t3 SELECT randstr(10,400) FROM t3; | ||
335 | INSERT INTO t3 SELECT randstr(10,400) FROM t3; | ||
336 | INSERT INTO t3 SELECT randstr(10,400) FROM t3; | ||
337 | COMMIT; | ||
338 | } | ||
339 | execsql {SELECT count(*) FROM t3;} | ||
340 | } {32} | ||
341 | |||
342 | set ::X [signature] | ||
343 | do_test exclusive-4.1 { | ||
344 | execsql { | ||
345 | BEGIN; | ||
346 | DELETE FROM t3 WHERE random()%10!=0; | ||
347 | INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; | ||
348 | INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; | ||
349 | SELECT count(*) FROM t3; | ||
350 | ROLLBACK; | ||
351 | } | ||
352 | signature | ||
353 | } $::X | ||
354 | |||
355 | do_test exclusive-4.2 { | ||
356 | execsql { | ||
357 | BEGIN; | ||
358 | DELETE FROM t3 WHERE random()%10!=0; | ||
359 | INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; | ||
360 | DELETE FROM t3 WHERE random()%10!=0; | ||
361 | INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; | ||
362 | ROLLBACK; | ||
363 | } | ||
364 | signature | ||
365 | } $::X | ||
366 | |||
367 | do_test exclusive-4.3 { | ||
368 | execsql { | ||
369 | INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0; | ||
370 | } | ||
371 | } {} | ||
372 | |||
373 | do_test exclusive-4.4 { | ||
374 | catch {set ::X [signature]} | ||
375 | } {0} | ||
376 | do_test exclusive-4.5 { | ||
377 | execsql { | ||
378 | PRAGMA locking_mode = NORMAL; | ||
379 | DROP TABLE t3; | ||
380 | DROP TABLE abc; | ||
381 | } | ||
382 | } {normal} | ||
383 | |||
384 | #---------------------------------------------------------------------- | ||
385 | # Tests exclusive-5.X - test that statement journals are truncated | ||
386 | # instead of deleted when in exclusive access mode. | ||
387 | # | ||
388 | |||
389 | # Close and reopen the database so that the temp database is no | ||
390 | # longer active. | ||
391 | # | ||
392 | db close | ||
393 | sqlite db test.db | ||
394 | |||
395 | |||
396 | do_test exclusive-5.0 { | ||
397 | execsql { | ||
398 | CREATE TABLE abc(a UNIQUE, b UNIQUE, c UNIQUE); | ||
399 | BEGIN; | ||
400 | INSERT INTO abc VALUES(1, 2, 3); | ||
401 | INSERT INTO abc SELECT a+1, b+1, c+1 FROM abc; | ||
402 | } | ||
403 | } {} | ||
404 | do_test exclusive-5.1 { | ||
405 | # Three files are open: The db, journal and statement-journal. | ||
406 | set sqlite_open_file_count | ||
407 | } {3} | ||
408 | do_test exclusive-5.2 { | ||
409 | execsql { | ||
410 | COMMIT; | ||
411 | } | ||
412 | # One file open: the db. | ||
413 | set sqlite_open_file_count | ||
414 | } {1} | ||
415 | do_test exclusive-5.3 { | ||
416 | execsql { | ||
417 | PRAGMA locking_mode = exclusive; | ||
418 | BEGIN; | ||
419 | INSERT INTO abc VALUES(5, 6, 7); | ||
420 | } | ||
421 | # Two files open: the db and journal. | ||
422 | set sqlite_open_file_count | ||
423 | } {2} | ||
424 | do_test exclusive-5.4 { | ||
425 | execsql { | ||
426 | INSERT INTO abc SELECT a+10, b+10, c+10 FROM abc; | ||
427 | } | ||
428 | # Three files are open: The db, journal and statement-journal. | ||
429 | set sqlite_open_file_count | ||
430 | } {3} | ||
431 | do_test exclusive-5.5 { | ||
432 | execsql { | ||
433 | COMMIT; | ||
434 | } | ||
435 | # Three files are still open: The db, journal and statement-journal. | ||
436 | set sqlite_open_file_count | ||
437 | } {3} | ||
438 | do_test exclusive-5.6 { | ||
439 | execsql { | ||
440 | PRAGMA locking_mode = normal; | ||
441 | SELECT * FROM abc; | ||
442 | } | ||
443 | } {normal 1 2 3 2 3 4 5 6 7 11 12 13 12 13 14 15 16 17} | ||
444 | do_test exclusive-5.7 { | ||
445 | # Just the db open. | ||
446 | set sqlite_open_file_count | ||
447 | } {1} | ||
448 | |||
449 | finish_test | ||