crash4.test 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # 2008 January 8
  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. # This file contains additional tests to verify that SQLite database
  13. # file survive a power loss or OS crash.
  14. #
  15. # $Id: crash4.test,v 1.3 2008/01/16 17:46:38 drh Exp $
  16. set testdir [file dirname $argv0]
  17. source $testdir/tester.tcl
  18. ifcapable !crashtest {
  19. finish_test
  20. return
  21. }
  22. # A sequence of SQL commands:
  23. #
  24. set sql_cmd_list {
  25. {CREATE TABLE a(id INTEGER, name CHAR(50))}
  26. {INSERT INTO a(id,name) VALUES(1,'one')}
  27. {INSERT INTO a(id,name) VALUES(2,'two')}
  28. {INSERT INTO a(id,name) VALUES(3,'three')}
  29. {INSERT INTO a(id,name) VALUES(4,'four')}
  30. {INSERT INTO a(id,name) VALUES(5,'five')}
  31. {INSERT INTO a(id,name) VALUES(6,'six')}
  32. {INSERT INTO a(id,name) VALUES(7,'seven')}
  33. {INSERT INTO a(id,name) VALUES(8,'eight')}
  34. {INSERT INTO a(id,name) VALUES(9,'nine')}
  35. {INSERT INTO a(id,name) VALUES(10,'ten')}
  36. {UPDATE A SET name='new text for row 3' WHERE id=3}
  37. }
  38. # Assume that a database is created by evaluating the SQL statements
  39. # in $sql_cmd_list. Compute a set of checksums that capture the state
  40. # of the database after each statement. Also include a checksum for
  41. # the state of the database prior to any of these statements.
  42. #
  43. set crash4_cksum_set {}
  44. lappend crash4_cksum_set [allcksum db]
  45. foreach cmd $sql_cmd_list {
  46. db eval $cmd
  47. lappend crash4_cksum_set [allcksum db]
  48. }
  49. # Run the sequence of SQL statements shown above repeatedly.
  50. # Close and reopen the database right before the UPDATE statement.
  51. # On each repetition, introduce database corruption typical of
  52. # what might be seen in a power loss or OS crash.
  53. #
  54. # Slowly increase the delay before the crash, repeating the test
  55. # over and over. Stop testing when the entire sequence of SQL
  56. # statements runs to completing without hitting the crash.
  57. #
  58. for {set cnt 1; set fin 0} {!$fin} {incr cnt} {
  59. db close
  60. forcedelete test.db test.db-journal
  61. do_test crash4-1.$cnt.1 {
  62. set seed [expr {int(abs(rand()*10000))}]
  63. set delay [expr {int($cnt/50)+1}]
  64. set file [expr {($cnt&1)?"test.db":"test.db-journal"}]
  65. set c [crashsql -delay $delay -file $file -seed $seed -tclbody {
  66. db eval {CREATE TABLE a(id INTEGER, name CHAR(50))}
  67. db eval {INSERT INTO a(id,name) VALUES(1,'one')}
  68. db eval {INSERT INTO a(id,name) VALUES(2,'two')}
  69. db eval {INSERT INTO a(id,name) VALUES(3,'three')}
  70. db eval {INSERT INTO a(id,name) VALUES(4,'four')}
  71. db eval {INSERT INTO a(id,name) VALUES(5,'five')}
  72. db eval {INSERT INTO a(id,name) VALUES(6,'six')}
  73. db eval {INSERT INTO a(id,name) VALUES(7,'seven')}
  74. db eval {INSERT INTO a(id,name) VALUES(8,'eight')}
  75. db eval {INSERT INTO a(id,name) VALUES(9,'nine')}
  76. db eval {INSERT INTO a(id,name) VALUES(10,'ten')}
  77. db close
  78. sqlite3 db test.db
  79. db eval {UPDATE A SET name='new text for row 3' WHERE id=3}
  80. db close
  81. } {}]
  82. if {$c==[list 0 {}]} {
  83. set ::fin 1
  84. set c [list 1 {child process exited abnormally}]
  85. }
  86. set c
  87. } {1 {child process exited abnormally}}
  88. sqlite3 db test.db
  89. integrity_check crash4-1.$cnt.2
  90. do_test crash4-1.$cnt.3 {
  91. set x [lsearch $::crash4_cksum_set [allcksum db]]
  92. expr {$x>=0}
  93. } {1}
  94. }
  95. finish_test