sessionfault2.test 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. # 2016 March 31
  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. # The focus of this file is testing the session module.
  13. #
  14. if {![info exists testdir]} {
  15. set testdir [file join [file dirname [info script]] .. .. test]
  16. }
  17. source [file join [file dirname [info script]] session_common.tcl]
  18. source $testdir/tester.tcl
  19. ifcapable !session {finish_test; return}
  20. set testprefix sessionfault2
  21. if 1 {
  22. do_execsql_test 1.0.0 {
  23. CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
  24. INSERT INTO t1 VALUES(1, 1);
  25. INSERT INTO t1 VALUES(2, 2);
  26. INSERT INTO t1 VALUES(3, 3);
  27. CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
  28. INSERT INTO t2 VALUES(1, 1);
  29. INSERT INTO t2 VALUES(2, 2);
  30. INSERT INTO t2 VALUES(3, 3);
  31. }
  32. faultsim_save_and_close
  33. faultsim_restore_and_reopen
  34. do_test 1.0.1 {
  35. set ::C [changeset_from_sql {
  36. UPDATE t1 SET b=4 WHERE a=3;
  37. UPDATE t1 SET b=3 WHERE a=2;
  38. UPDATE t1 SET b=2 WHERE a=1;
  39. UPDATE t2 SET b=0 WHERE a=1;
  40. UPDATE t2 SET b=1 WHERE a=2;
  41. UPDATE t2 SET b=2 WHERE a=3;
  42. }]
  43. set {} {}
  44. } {}
  45. proc xConflict args { return "OMIT" }
  46. do_faultsim_test 1 -faults oom-p* -prep {
  47. faultsim_restore_and_reopen
  48. } -body {
  49. sqlite3changeset_apply db $::C xConflict
  50. } -test {
  51. faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  52. faultsim_integrity_check
  53. catch { db eval ROLLBACK }
  54. set res [db eval {
  55. SELECT * FROM t1;
  56. SELECT * FROM t2;
  57. }]
  58. if {$testrc==0} {
  59. if {$res != "1 2 2 3 3 4 1 0 2 1 3 2"} { error "data error" }
  60. } else {
  61. if {
  62. $res != "1 2 2 3 3 4 1 0 2 1 3 2"
  63. && $res != "1 1 2 2 3 3 1 1 2 2 3 3"
  64. } { error "data error!! $res" }
  65. }
  66. }
  67. #-------------------------------------------------------------------------
  68. # OOM when applying a changeset for which one of the tables has a name
  69. # 99 bytes in size. This happens to cause an extra malloc in within the
  70. # sessions_strm permutation.
  71. #
  72. reset_db
  73. set nm [string repeat t 99]
  74. do_execsql_test 2.0.0 [string map "%TBL% $nm" {
  75. CREATE TABLE %TBL%(a PRIMARY KEY, b UNIQUE);
  76. }]
  77. faultsim_save_and_close
  78. faultsim_restore_and_reopen
  79. do_test 1.0.1 {
  80. set ::C [changeset_from_sql [string map "%TBL% $nm" {
  81. INSERT INTO %TBL% VALUES(1, 2);
  82. INSERT INTO %TBL% VALUES(3, 4);
  83. }]]
  84. set {} {}
  85. } {}
  86. proc xConflict args { return "OMIT" }
  87. do_faultsim_test 2 -faults oom-p* -prep {
  88. faultsim_restore_and_reopen
  89. } -body {
  90. sqlite3changeset_apply db $::C xConflict
  91. } -test {
  92. faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  93. faultsim_integrity_check
  94. }
  95. #-------------------------------------------------------------------------
  96. # OOM when collecting and apply a changeset that uses sqlite_stat1.
  97. #
  98. reset_db
  99. forcedelete test.db2
  100. sqlite3 db2 test.db2
  101. do_common_sql {
  102. CREATE TABLE t1(a PRIMARY KEY, b UNIQUE, c);
  103. CREATE INDEX i1 ON t1(c);
  104. INSERT INTO t1 VALUES(1, 2, 3);
  105. INSERT INTO t1 VALUES(4, 5, 6);
  106. INSERT INTO t1 VALUES(7, 8, 9);
  107. CREATE TABLE t2(a, b, c);
  108. INSERT INTO t2 VALUES(1, 2, 3);
  109. INSERT INTO t2 VALUES(4, 5, 6);
  110. INSERT INTO t2 VALUES(7, 8, 9);
  111. ANALYZE;
  112. }
  113. faultsim_save_and_close
  114. db2 close
  115. do_faultsim_test 1.1 -faults oom-* -prep {
  116. catch {db2 close}
  117. catch {db close}
  118. faultsim_restore_and_reopen
  119. sqlite3 db2 test.db2
  120. } -body {
  121. do_then_apply_sql -ignorenoop {
  122. INSERT INTO sqlite_stat1 VALUES('x', 'y', 45);
  123. UPDATE sqlite_stat1 SET stat = 123 WHERE tbl='t1' AND idx='i1';
  124. UPDATE sqlite_stat1 SET stat = 456 WHERE tbl='t2';
  125. }
  126. } -test {
  127. faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  128. faultsim_integrity_check
  129. if {$testrc==0} { compare_db db db2 }
  130. }
  131. #-------------------------------------------------------------------------
  132. # OOM when collecting and using a rebase changeset.
  133. #
  134. reset_db
  135. do_execsql_test 2.0 {
  136. CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c));
  137. CREATE TABLE t4(x PRIMARY KEY, y, z);
  138. INSERT INTO t3 VALUES(1, 2, 3);
  139. INSERT INTO t3 VALUES(4, 2, 5);
  140. INSERT INTO t3 VALUES(7, 2, 9);
  141. INSERT INTO t4 VALUES('a', 'b', 'c');
  142. INSERT INTO t4 VALUES('d', 'e', 'f');
  143. INSERT INTO t4 VALUES('g', 'h', 'i');
  144. }
  145. faultsim_save_and_close
  146. db2 close
  147. proc xConflict {ret args} { return $ret }
  148. do_test 2.1 {
  149. faultsim_restore_and_reopen
  150. set C1 [changeset_from_sql {
  151. INSERT INTO t3 VALUES(10, 11, 12);
  152. UPDATE t4 SET y='j' WHERE x='g';
  153. DELETE FROM t4 WHERE x='a';
  154. }]
  155. faultsim_restore_and_reopen
  156. set C2 [changeset_from_sql {
  157. INSERT INTO t3 VALUES(1000, 11, 12);
  158. DELETE FROM t4 WHERE x='g';
  159. }]
  160. faultsim_restore_and_reopen
  161. sqlite3changeset_apply db $C1 [list xConflict OMIT]
  162. faultsim_save_and_close
  163. } {}
  164. do_faultsim_test 2.2 -faults oom* -prep {
  165. catch {db2 close}
  166. catch {db close}
  167. faultsim_restore_and_reopen
  168. sqlite3 db2 test.db2
  169. } -body {
  170. set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
  171. set {} {}
  172. } -test {
  173. faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  174. }
  175. do_faultsim_test 2.3 -faults oom* -prep {
  176. catch {db2 close}
  177. catch {db close}
  178. faultsim_restore_and_reopen
  179. sqlite3 db2 test.db2
  180. } -body {
  181. set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]]
  182. set {} {}
  183. } -test {
  184. faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  185. }
  186. do_faultsim_test 2.4 -faults oom* -prep {
  187. catch {db2 close}
  188. catch {db close}
  189. faultsim_restore_and_reopen
  190. set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]]
  191. } -body {
  192. sqlite3rebaser_create R
  193. R configure $::rebase
  194. R rebase $::C1
  195. set {} {}
  196. } -test {
  197. catch { R delete }
  198. faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  199. }
  200. do_faultsim_test 2.5 -faults oom* -prep {
  201. catch {db2 close}
  202. catch {db close}
  203. faultsim_restore_and_reopen
  204. set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
  205. } -body {
  206. sqlite3rebaser_create R
  207. R configure $::rebase
  208. R rebase $::C1
  209. set {} {}
  210. } -test {
  211. catch { R delete }
  212. faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  213. }
  214. }
  215. reset_db
  216. do_execsql_test 3.0 {
  217. CREATE TABLE t1(x PRIMARY KEY, y, z);
  218. INSERT INTO t1 VALUES(3, 1, 4);
  219. INSERT INTO t1 VALUES(1, 5, 9);
  220. }
  221. faultsim_save_and_close
  222. proc xConflict {ret args} { return $ret }
  223. do_test 3.1 {
  224. faultsim_restore_and_reopen
  225. execsql { BEGIN; UPDATE t1 SET z=11; }
  226. set C1 [changeset_from_sql {
  227. UPDATE t1 SET z=10 WHERE x=1;
  228. }]
  229. execsql { ROLLBACK }
  230. execsql { BEGIN; UPDATE t1 SET z=11; }
  231. set C2 [changeset_from_sql {
  232. UPDATE t1 SET z=55 WHERE x=1;
  233. }]
  234. execsql { ROLLBACK }
  235. set ::rebase1 [sqlite3changeset_apply_v2 db $::C1 [list xConflict OMIT]]
  236. set ::rebase2 [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
  237. set {} {}
  238. execsql { SELECT * FROM t1 }
  239. } {3 1 4 1 5 9}
  240. do_faultsim_test 3.2 -faults oom* -prep {
  241. faultsim_restore_and_reopen
  242. } -body {
  243. sqlite3rebaser_create R
  244. R configure $::rebase1
  245. R configure $::rebase2
  246. set {} {}
  247. } -test {
  248. catch { R delete }
  249. faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
  250. }
  251. finish_test