sessionnoop.test 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. # 2021 Februar 20
  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.
  12. #
  13. if {![info exists testdir]} {
  14. set testdir [file join [file dirname [info script]] .. .. test]
  15. }
  16. source [file join [file dirname [info script]] session_common.tcl]
  17. source $testdir/tester.tcl
  18. ifcapable !session {finish_test; return}
  19. set testprefix sessionnoop
  20. #-------------------------------------------------------------------------
  21. # Test plan:
  22. #
  23. # 1.*: Test that concatenating changesets cannot produce a noop UPDATE.
  24. # 2.*: Test that rebasing changesets cannot produce a noop UPDATE.
  25. # 3.*: Test that sqlite3changeset_apply() ignores noop UPDATE changes.
  26. #
  27. do_execsql_test 1.0 {
  28. CREATE TABLE t1(a PRIMARY KEY, b, c, d);
  29. INSERT INTO t1 VALUES(1, 1, 1, 1);
  30. INSERT INTO t1 VALUES(2, 2, 2, 2);
  31. INSERT INTO t1 VALUES(3, 3, 3, 3);
  32. }
  33. proc do_concat_test {tn sql1 sql2 res} {
  34. uplevel [list do_test $tn [subst -nocommands {
  35. set C1 [changeset_from_sql {$sql1}]
  36. set C2 [changeset_from_sql {$sql2}]
  37. set C3 [sqlite3changeset_concat [set C1] [set C2]]
  38. set got [list]
  39. sqlite3session_foreach elem [set C3] { lappend got [set elem] }
  40. set got
  41. }] [list {*}$res]]
  42. }
  43. do_concat_test 1.1 {
  44. UPDATE t1 SET c=c+1;
  45. } {
  46. UPDATE t1 SET c=c-1;
  47. } {
  48. }
  49. #-------------------------------------------------------------------------
  50. reset_db
  51. do_execsql_test 2.0 {
  52. CREATE TABLE t1(a PRIMARY KEY, b, c);
  53. INSERT INTO t1 VALUES(1, 1, 1);
  54. INSERT INTO t1 VALUES(2, 2, 2);
  55. INSERT INTO t1 VALUES(3, 3, 3);
  56. }
  57. proc do_rebase_test {tn sql_local sql_remote conflict_res expected} {
  58. proc xConflict {args} [list return $conflict_res]
  59. uplevel [list \
  60. do_test $tn [subst -nocommands {
  61. execsql BEGIN
  62. set c_remote [changeset_from_sql {$sql_remote}]
  63. execsql ROLLBACK
  64. execsql BEGIN
  65. set c_local [changeset_from_sql {$sql_local}]
  66. set base [sqlite3changeset_apply_v2 db [set c_remote] xConflict]
  67. execsql ROLLBACK
  68. sqlite3rebaser_create R
  69. R config [set base]
  70. set res [list]
  71. sqlite3session_foreach elem [R rebase [set c_local]] {
  72. lappend res [set elem]
  73. }
  74. R delete
  75. set res
  76. }] [list {*}$expected]
  77. ]
  78. }
  79. do_rebase_test 2.1 {
  80. UPDATE t1 SET c=2 WHERE a=1; -- local
  81. } {
  82. UPDATE t1 SET c=3 WHERE a=1; -- remote
  83. } OMIT {
  84. {UPDATE t1 0 X.. {i 1 {} {} i 3} {{} {} {} {} i 2}}
  85. }
  86. do_rebase_test 2.2 {
  87. UPDATE t1 SET c=2 WHERE a=1; -- local
  88. } {
  89. UPDATE t1 SET c=3 WHERE a=1; -- remote
  90. } REPLACE {
  91. }
  92. do_rebase_test 2.3.1 {
  93. UPDATE t1 SET c=4 WHERE a=1; -- local
  94. } {
  95. UPDATE t1 SET c=4 WHERE a=1 -- remote
  96. } OMIT {
  97. {UPDATE t1 0 X.. {i 1 {} {} i 4} {{} {} {} {} i 4}}
  98. }
  99. do_rebase_test 2.3.2 {
  100. UPDATE t1 SET c=5 WHERE a=1; -- local
  101. } {
  102. UPDATE t1 SET c=5 WHERE a=1 -- remote
  103. } REPLACE {
  104. }
  105. #-------------------------------------------------------------------------
  106. #
  107. reset_db
  108. do_execsql_test 3.0 {
  109. CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  110. INSERT INTO t1 VALUES(1, 1, 1);
  111. INSERT INTO t1 VALUES(2, 2, 2);
  112. INSERT INTO t1 VALUES(3, 3, 3);
  113. INSERT INTO t1 VALUES(4, 4, 4);
  114. }
  115. # Arg $pkstr contains one character for each column in the table. An
  116. # "X" for PK column, or a "." for a non-PK.
  117. #
  118. proc mk_tbl_header {name pkstr} {
  119. set ret [binary format H2c 54 [string length $pkstr]]
  120. foreach i [split $pkstr {}] {
  121. if {$i=="X"} {
  122. append ret [binary format H2 01]
  123. } else {
  124. if {$i!="."} {error "bad pkstr: $pkstr ($i)"}
  125. append ret [binary format H2 00]
  126. }
  127. }
  128. append ret $name
  129. append ret [binary format H2 00]
  130. set ret
  131. }
  132. proc mk_update_change {args} {
  133. set ret [binary format H2H2 17 00]
  134. foreach a $args {
  135. if {$a==""} {
  136. append ret [binary format H2 00]
  137. } else {
  138. append ret [binary format H2W 01 $a]
  139. }
  140. }
  141. set ret
  142. }
  143. proc xConflict {args} { return "ABORT" }
  144. do_test 3.1 {
  145. set C [mk_tbl_header t1 X..]
  146. append C [mk_update_change 1 {} 1 {} {} 500]
  147. append C [mk_update_change 2 {} {} {} {} {}]
  148. append C [mk_update_change 3 3 {} {} 600 {}]
  149. append C [mk_update_change 4 {} {} {} {} {}]
  150. sqlite3changeset_apply_v2 db $C xConflict
  151. } {}
  152. do_execsql_test 3.2 {
  153. SELECT * FROM t1
  154. } {
  155. 1 1 500
  156. 2 2 2
  157. 3 600 3
  158. 4 4 4
  159. }
  160. finish_test