syscall.test 7.0 KB

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