OLD | NEW |
1 # 2001 September 15 | 1 # 2001 September 15 |
2 # | 2 # |
3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
4 # a legal notice, here is a blessing: | 4 # a legal notice, here is a blessing: |
5 # | 5 # |
6 # May you do good and not evil. | 6 # May you do good and not evil. |
7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
9 # | 9 # |
10 #*********************************************************************** | 10 #*********************************************************************** |
11 # This file implements regression tests for SQLite library. The | 11 # This file implements regression tests for SQLite library. The |
12 # focus of this script is database locks between competing processes. | 12 # focus of this script is database locks between competing processes. |
13 # | 13 # |
14 # $Id: lock2.test,v 1.11 2009/05/01 10:55:34 danielk1977 Exp $ | 14 # $Id: lock2.test,v 1.11 2009/05/01 10:55:34 danielk1977 Exp $ |
15 | 15 |
16 | 16 |
17 set testdir [file dirname $argv0] | 17 set testdir [file dirname $argv0] |
18 source $testdir/tester.tcl | 18 source $testdir/tester.tcl |
| 19 source $testdir/lock_common.tcl |
19 | 20 |
20 # Launch another testfixture process to be controlled by this one. A | |
21 # channel name is returned that may be passed as the first argument to proc | |
22 # 'testfixture' to execute a command. The child testfixture process is shut | |
23 # down by closing the channel. | |
24 proc launch_testfixture {} { | |
25 set prg [info nameofexec] | |
26 if {$prg eq ""} { | |
27 set prg [file join . testfixture] | |
28 } | |
29 set chan [open "|$prg tf_main.tcl" r+] | |
30 fconfigure $chan -buffering line | |
31 return $chan | |
32 } | |
33 | |
34 # Execute a command in a child testfixture process, connected by two-way | |
35 # channel $chan. Return the result of the command, or an error message. | |
36 proc testfixture {chan cmd} { | |
37 puts $chan $cmd | |
38 puts $chan OVER | |
39 set r "" | |
40 while { 1 } { | |
41 set line [gets $chan] | |
42 if { $line == "OVER" } { | |
43 return $r | |
44 } | |
45 if {[eof $chan]} { | |
46 return "ERROR: Child process hung up" | |
47 } | |
48 append r $line | |
49 } | |
50 } | |
51 | |
52 # Write the main loop for the child testfixture processes into file | |
53 # tf_main.tcl. The parent (this script) interacts with the child processes | |
54 # via a two way pipe. The parent writes a script to the stdin of the child | |
55 # process, followed by the word "OVER" on a line of its own. The child | |
56 # process evaluates the script and writes the results to stdout, followed | |
57 # by an "OVER" of its own. | |
58 set f [open tf_main.tcl w] | |
59 puts $f { | |
60 set l [open log w] | |
61 set script "" | |
62 while {![eof stdin]} { | |
63 flush stdout | |
64 set line [gets stdin] | |
65 puts $l "READ $line" | |
66 if { $line == "OVER" } { | |
67 catch {eval $script} result | |
68 puts $result | |
69 puts $l "WRITE $result" | |
70 puts OVER | |
71 puts $l "WRITE OVER" | |
72 flush stdout | |
73 set script "" | |
74 } else { | |
75 append script $line | |
76 append script " ; " | |
77 } | |
78 } | |
79 close $l | |
80 } | |
81 close $f | |
82 | 21 |
83 # Simple locking test case: | 22 # Simple locking test case: |
84 # | 23 # |
85 # lock2-1.1: Connect a second process to the database. | 24 # lock2-1.1: Connect a second process to the database. |
86 # lock2-1.2: Establish a RESERVED lock with this process. | 25 # lock2-1.2: Establish a RESERVED lock with this process. |
87 # lock2-1.3: Get a SHARED lock with the second process. | 26 # lock2-1.3: Get a SHARED lock with the second process. |
88 # lock2-1.4: Try for a RESERVED lock with process 2. This fails. | 27 # lock2-1.4: Try for a RESERVED lock with process 2. This fails. |
89 # lock2-1.5: Try to upgrade the first process to EXCLUSIVE, this fails so | 28 # lock2-1.5: Try to upgrade the first process to EXCLUSIVE, this fails so |
90 # it gets PENDING. | 29 # it gets PENDING. |
91 # lock2-1.6: Release the SHARED lock held by the second process. | 30 # lock2-1.6: Release the SHARED lock held by the second process. |
92 # lock2-1.7: Attempt to reaquire a SHARED lock with the second process. | 31 # lock2-1.7: Attempt to reaquire a SHARED lock with the second process. |
93 # this fails due to the PENDING lock. | 32 # this fails due to the PENDING lock. |
94 # lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE. | 33 # lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE. |
95 # | 34 # |
96 do_test lock2-1.1 { | 35 do_test lock2-1.1 { |
97 set ::tf1 [launch_testfixture] | 36 set ::tf1 [launch_testfixture] |
98 testfixture $::tf1 "sqlite3_test_control_pending_byte $::sqlite_pending_byte" | |
99 testfixture $::tf1 { | 37 testfixture $::tf1 { |
100 sqlite3 db test.db -key xyzzy | 38 sqlite3 db test.db -key xyzzy |
101 db eval {select * from sqlite_master} | 39 db eval {select * from sqlite_master} |
102 } | 40 } |
103 } {} | 41 } {} |
104 do_test lock2-1.1.1 { | 42 do_test lock2-1.1.1 { |
105 execsql {pragma lock_status} | 43 execsql {pragma lock_status} |
106 } {main unlocked temp closed} | 44 } {main unlocked temp closed} |
107 sqlite3_soft_heap_limit 0 | 45 sqlite3_soft_heap_limit 0 |
108 do_test lock2-1.2 { | 46 do_test lock2-1.2 { |
109 execsql { | 47 execsql { |
110 BEGIN; | 48 BEGIN; |
111 CREATE TABLE abc(a, b, c); | 49 CREATE TABLE abc(a, b, c); |
112 } | 50 } |
113 } {} | 51 } {} |
114 do_test lock2-1.3 { | 52 do_test lock2-1.3 { |
115 testfixture $::tf1 { | 53 testfixture $::tf1 { |
116 db eval { | 54 db eval { |
117 BEGIN; | 55 BEGIN; |
118 SELECT * FROM sqlite_master; | 56 SELECT * FROM sqlite_master; |
119 } | 57 } |
120 } | 58 } |
121 } {} | 59 } {} |
122 do_test lock2-1.4 { | 60 do_test lock2-1.4 { |
123 testfixture $::tf1 { | 61 testfixture $::tf1 { |
124 db eval { | 62 catch { db eval { CREATE TABLE def(d, e, f) } } msg |
125 CREATE TABLE def(d, e, f) | 63 set msg |
126 } | |
127 } | 64 } |
128 } {database is locked} | 65 } {database is locked} |
129 do_test lock2-1.5 { | 66 do_test lock2-1.5 { |
130 catchsql { | 67 catchsql { |
131 COMMIT; | 68 COMMIT; |
132 } | 69 } |
133 } {1 {database is locked}} | 70 } {1 {database is locked}} |
134 do_test lock2-1.6 { | 71 do_test lock2-1.6 { |
135 testfixture $::tf1 { | 72 testfixture $::tf1 { |
136 db eval { | 73 db eval { |
137 SELECT * FROM sqlite_master; | 74 SELECT * FROM sqlite_master; |
138 COMMIT; | 75 COMMIT; |
139 } | 76 } |
140 } | 77 } |
141 } {} | 78 } {} |
142 do_test lock2-1.7 { | 79 do_test lock2-1.7 { |
143 testfixture $::tf1 { | 80 testfixture $::tf1 { |
144 db eval { | 81 catch { db eval { |
145 BEGIN; | 82 BEGIN; |
146 SELECT * FROM sqlite_master; | 83 SELECT * FROM sqlite_master; |
147 } | 84 } } msg |
| 85 set msg |
148 } | 86 } |
149 } {database is locked} | 87 } {database is locked} |
150 do_test lock2-1.8 { | 88 do_test lock2-1.8 { |
151 catchsql { | 89 catchsql { |
152 COMMIT; | 90 COMMIT; |
153 } | 91 } |
154 } {0 {}} | 92 } {0 {}} |
155 do_test lock2-1.9 { | 93 do_test lock2-1.9 { |
156 execsql { | 94 execsql { |
157 SELECT * FROM sqlite_master; | 95 SELECT * FROM sqlite_master; |
158 } | 96 } |
159 } "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}" | 97 } "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}" |
| 98 catch flush_async_queue |
160 do_test lock2-1.10 { | 99 do_test lock2-1.10 { |
161 testfixture $::tf1 { | 100 testfixture $::tf1 { |
162 db eval { | 101 db eval { |
163 SELECT * FROM sqlite_master; | 102 SELECT * FROM sqlite_master; |
164 } | 103 } |
165 } | 104 } |
166 } "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}" | 105 } "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}" |
167 | 106 |
168 catch {testfixture $::tf1 {db close}} | 107 catch {testfixture $::tf1 {db close}} |
169 catch {close $::tf1} | 108 catch {close $::tf1} |
170 sqlite3_soft_heap_limit $soft_limit | 109 sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit) |
171 | 110 |
172 finish_test | 111 finish_test |
OLD | NEW |