OLD | NEW |
| (Empty) |
1 # 2011 March 29 | |
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 # | |
12 | |
13 set testdir [file dirname $argv0] | |
14 source $testdir/tester.tcl | |
15 source $testdir/lock_common.tcl | |
16 source $testdir/malloc_common.tcl | |
17 | |
18 if {[llength [info commands test_syscall]]==0} { | |
19 finish_test | |
20 return | |
21 } | |
22 | |
23 if {[test_syscall defaultvfs] != "unix"} { | |
24 finish_test | |
25 return | |
26 } | |
27 set testprefix syscall | |
28 | |
29 #------------------------------------------------------------------------- | |
30 # Tests for the xSetSystemCall method. | |
31 # | |
32 do_test 1.1.1 { | |
33 list [catch { test_syscall reset open } msg] $msg | |
34 } {0 {}} | |
35 do_test 1.1.2 { | |
36 list [catch { test_syscall reset nosuchcall } msg] $msg | |
37 } {1 SQLITE_NOTFOUND} | |
38 do_test 1.1.3 { | |
39 list [catch { test_syscall reset open } msg] $msg | |
40 } {0 {}} | |
41 do_test 1.1.4 { | |
42 list [catch { test_syscall reset ""} msg] $msg | |
43 } {1 SQLITE_NOTFOUND} | |
44 | |
45 do_test 1.2 { test_syscall reset } {} | |
46 | |
47 do_test 1.3.1 { test_syscall install {open getcwd access} } {} | |
48 do_test 1.3.2 { test_syscall reset } {} | |
49 | |
50 #------------------------------------------------------------------------- | |
51 # Tests for the xGetSystemCall method. | |
52 # | |
53 do_test 2.1.1 { test_syscall exists open } 1 | |
54 do_test 2.1.2 { test_syscall exists nosuchcall } 0 | |
55 | |
56 #------------------------------------------------------------------------- | |
57 # Tests for the xNextSystemCall method. | |
58 # | |
59 foreach s { | |
60 open close access getcwd stat fstat ftruncate | |
61 fcntl read pread write pwrite fchmod fallocate | |
62 pread64 pwrite64 unlink openDirectory mkdir rmdir | |
63 statvfs fchown umask mmap munmap mremap | |
64 getpagesize | |
65 } { | |
66 if {[test_syscall exists $s]} {lappend syscall_list $s} | |
67 } | |
68 do_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list] | |
69 | |
70 #------------------------------------------------------------------------- | |
71 # This test verifies that if a call to open() fails and errno is set to | |
72 # EINTR, the call is retried. If it succeeds, execution continues as if | |
73 # nothing happened. | |
74 # | |
75 test_syscall reset | |
76 forcedelete test.db2 | |
77 do_execsql_test 4.1 { | |
78 CREATE TABLE t1(x, y); | |
79 INSERT INTO t1 VALUES(1, 2); | |
80 ATTACH 'test.db2' AS aux; | |
81 CREATE TABLE aux.t2(x, y); | |
82 INSERT INTO t2 VALUES(3, 4); | |
83 } | |
84 | |
85 db_save_and_close | |
86 test_syscall install open | |
87 foreach jrnl [list wal delete] { | |
88 for {set i 1} {$i < 20} {incr i} { | |
89 db_restore_and_reopen | |
90 test_syscall fault $i 0 | |
91 test_syscall errno open EINTR | |
92 | |
93 do_test 4.2.$jrnl.$i { | |
94 sqlite3 db test.db | |
95 execsql { ATTACH 'test.db2' AS aux } | |
96 execsql "PRAGMA main.journal_mode = $jrnl" | |
97 execsql "PRAGMA aux.journal_mode = $jrnl" | |
98 execsql { | |
99 BEGIN; | |
100 INSERT INTO t1 VALUES(5, 6); | |
101 INSERT INTO t2 VALUES(7, 8); | |
102 COMMIT; | |
103 } | |
104 | |
105 db close | |
106 sqlite3 db test.db | |
107 execsql { ATTACH 'test.db2' AS aux } | |
108 execsql { | |
109 SELECT * FROM t1; | |
110 SELECT * FROM t2; | |
111 } | |
112 } {1 2 5 6 3 4 7 8} | |
113 } | |
114 } | |
115 | |
116 #------------------------------------------------------------------------- | |
117 # This test verifies that closing database handles does not drop locks | |
118 # held by other database handles in the same process on the same file. | |
119 # | |
120 # The os_unix.c module has to take precautions to prevent this as the | |
121 # close() system call drops locks held by other file-descriptors on the | |
122 # same file. From the Linux man page: | |
123 # | |
124 # close() closes a file descriptor, so that it no longer refers to any file | |
125 # and may be reused. Any record locks (see fcntl(2)) held on the file it | |
126 # was associated with, and owned by the process, are removed (regardless | |
127 # of the file descriptor that was used to obtain the lock). | |
128 # | |
129 catch { db close } | |
130 forcedelete test.db test.db2 | |
131 | |
132 do_multiclient_test tn { | |
133 code1 { | |
134 sqlite3 dbX1 test.db | |
135 sqlite3 dbX2 test.db | |
136 } | |
137 | |
138 do_test syscall-5.$tn.1 { | |
139 sql1 { | |
140 CREATE TABLE t1(a, b); | |
141 INSERT INTO t1 VALUES(1, 2); | |
142 BEGIN; | |
143 INSERT INTO t1 VALUES(3, 4); | |
144 } | |
145 } {} | |
146 | |
147 do_test syscall-5.$tn.2 { sql2 { SELECT * FROM t1 } } {1 2} | |
148 do_test syscall-5.$tn.3 { | |
149 csql2 { INSERT INTO t1 VALUES(5, 6) } | |
150 } {1 {database is locked}} | |
151 | |
152 do_test syscall-5.$tn.4 { | |
153 code1 { | |
154 dbX1 close | |
155 dbX2 close | |
156 } | |
157 } {} | |
158 | |
159 do_test syscall-5.$tn.5 { | |
160 csql2 { INSERT INTO t1 VALUES(5, 6) } | |
161 } {1 {database is locked}} | |
162 | |
163 do_test syscall-5.$tn.6 { sql1 { COMMIT } } {} | |
164 | |
165 do_test syscall-5.$tn.7 { | |
166 csql2 { INSERT INTO t1 VALUES(5, 6) } | |
167 } {0 {}} | |
168 } | |
169 | |
170 catch {db close} | |
171 do_test 6.1 { | |
172 sqlite3 db1 test.db1 | |
173 sqlite3 db2 test.db2 | |
174 sqlite3 db3 test.db3 | |
175 sqlite3 dbM "" | |
176 | |
177 db2 close | |
178 db3 close | |
179 dbM close | |
180 db1 close | |
181 } {} | |
182 | |
183 do_test 6.2 { | |
184 sqlite3 db test.db | |
185 execsql { | |
186 PRAGMA temp_store = file; | |
187 | |
188 PRAGMA main.cache_size = 10; | |
189 PRAGMA temp.cache_size = 10; | |
190 CREATE TABLE temp.tt(a, b); | |
191 INSERT INTO tt VALUES(randomblob(500), randomblob(600)); | |
192 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; | |
193 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; | |
194 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; | |
195 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; | |
196 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; | |
197 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; | |
198 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; | |
199 INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; | |
200 } | |
201 | |
202 db close | |
203 } {} | |
204 | |
205 #------------------------------------------------------------------------- | |
206 # Test that a database file a single byte in size is treated as an empty | |
207 # file. Whereas a file 2 bytes or larger might be considered corrupt. | |
208 # | |
209 catch { db close } | |
210 forcedelete test.db test.db2 | |
211 | |
212 proc create_db_file {nByte} { | |
213 set fd [open test.db w] | |
214 fconfigure $fd -translation binary -encoding binary | |
215 puts -nonewline $fd [string range "xSQLite" 1 $nByte] | |
216 close $fd | |
217 } | |
218 | |
219 foreach {nByte res} { | |
220 1 {0 {}} | |
221 2 {1 {file is encrypted or is not a database}} | |
222 3 {1 {file is encrypted or is not a database}} | |
223 } { | |
224 do_test 7.$nByte { | |
225 create_db_file $nByte | |
226 list [catch { | |
227 sqlite3 db test.db | |
228 execsql { CREATE TABLE t1(a, b) } | |
229 } msg] $msg | |
230 } $res | |
231 catch { db close } | |
232 } | |
233 | |
234 #------------------------------------------------------------------------- | |
235 # | |
236 catch { db close } | |
237 forcedelete test.db test.db2 | |
238 | |
239 do_test 8.1 { | |
240 sqlite3 db test.db | |
241 file_control_chunksize_test db main 4096 | |
242 file size test.db | |
243 } {0} | |
244 foreach {tn hint size} { | |
245 1 1000 4096 | |
246 2 1000 4096 | |
247 3 3000 4096 | |
248 4 4096 4096 | |
249 5 4197 8192 | |
250 } { | |
251 do_test 8.2.$tn { | |
252 file_control_sizehint_test db main $hint | |
253 file size test.db | |
254 } $size | |
255 } | |
256 | |
257 do_test 8.3 { | |
258 db close | |
259 forcedelete test.db test.db2 | |
260 sqlite3 db test.db | |
261 file_control_chunksize_test db main 16 | |
262 file size test.db | |
263 } {0} | |
264 foreach {tn hint size} { | |
265 1 5 16 | |
266 2 13 16 | |
267 3 45 48 | |
268 4 48 48 | |
269 5 49 64 | |
270 } { | |
271 do_test 8.4.$tn { | |
272 file_control_sizehint_test db main $hint | |
273 file size test.db | |
274 } $size | |
275 } | |
276 | |
277 test_syscall reset | |
278 finish_test | |
OLD | NEW |