/ Check-in [87b4ac4b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add crash4.test with additional crash testing. (CVS 4695)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 87b4ac4b73fb84411ced9e9a859dd0e2d211c4b3
User & Date: drh 2008-01-08 16:03:50
Context
2008-01-08
18:57
Finish registerizing the core logic of INSERT and UPDATE. (CVS 4696) check-in: 5fd10367 user: drh tags: trunk
16:03
Add crash4.test with additional crash testing. (CVS 4695) check-in: 87b4ac4b user: drh tags: trunk
15:18
Add additional randomness to crash tests. (CVS 4694) check-in: 3ccce1f5 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added test/crash4.test.

































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# 2008 January 8
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains additional tests to verify that SQLite database
# file survive a power loss or OS crash.
#
# $Id: crash4.test,v 1.1 2008/01/08 16:03:50 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !crashtest {
  finish_test
  return
}

# Generate a checksum based on the contents of the database. If the
# checksum of two databases is the same, and the integrity-check passes
# for both, the two databases are identical.
#
proc cksum {db} {
  set ret [list]
  ifcapable tempdb {
    set sql {
      SELECT name FROM sqlite_master WHERE type = 'table' UNION
      SELECT name FROM sqlite_temp_master WHERE type = 'table' UNION
      SELECT 'sqlite_master' UNION
      SELECT 'sqlite_temp_master'
    }
  } else {
    set sql {
      SELECT name FROM sqlite_master WHERE type = 'table' UNION
      SELECT 'sqlite_master'
    }
  }
  set tbllist [$db eval $sql]
  set txt {}
  foreach tbl $tbllist {
    append txt [$db eval "SELECT * FROM $tbl"]
  }
  return [md5 $txt]
}

# A sequence of SQL commands:
#
set sql_cmd_list {
  {CREATE TABLE a(id INTEGER, name CHAR(50))}
  {INSERT INTO a(id,name) VALUES(1,'one')}
  {INSERT INTO a(id,name) VALUES(2,'two')}
  {INSERT INTO a(id,name) VALUES(3,'three')}
  {INSERT INTO a(id,name) VALUES(4,'four')}
  {INSERT INTO a(id,name) VALUES(5,'five')}
  {INSERT INTO a(id,name) VALUES(6,'six')}
  {INSERT INTO a(id,name) VALUES(7,'seven')}
  {INSERT INTO a(id,name) VALUES(8,'eight')}
  {INSERT INTO a(id,name) VALUES(9,'nine')}
  {INSERT INTO a(id,name) VALUES(10,'ten')}
  {UPDATE A SET name='new text for row 3' WHERE id=3}
}

# Assume that a database is created by evaluating the SQL statements
# in $sql_cmd_list.  Compute a set of checksums that capture the state
# of the database after each statement.  Also include a checksum for
# the state of the database prior to any of these statements.
#
set crash4_cksum_set {}
lappend crash4_cksum_set [cksum db]
foreach cmd $sql_cmd_list {
  db eval $cmd
  lappend crash4_cksum_set [cksum db]
}

# Run the sequence of SQL statements shown above repeatedly.
# Close and reopen the database right before the UPDATE statement.
# On each repetition, introduce database corruption typical of
# what might be seen in a power loss or OS crash.  
#
# Slowly increase the delay before the crash, repeating the test
# over and over.  Stop testing when the entire sequence of SQL
# statements runs to completing without hitting the crash.
#
for {set cnt 1; set fin 0} {!$fin} {incr cnt} {
  db close
  file delete -force test.db test.db-journal
  do_test crash4-1.$cnt.1 {
    set seed [expr {int(abs(rand()*10000))}]
    set delay [expr {int($cnt/50)+1}]
    set file [expr {($cnt&1)?"test.db":"test.db-journal"}]
    set c [crashsql -delay $delay -file $file -seed $seed -tclbody {
      db eval {CREATE TABLE a(id INTEGER, name CHAR(50))}
      db eval {INSERT INTO a(id,name) VALUES(1,'one')}
      db eval {INSERT INTO a(id,name) VALUES(2,'two')}
      db eval {INSERT INTO a(id,name) VALUES(3,'three')}
      db eval {INSERT INTO a(id,name) VALUES(4,'four')}
      db eval {INSERT INTO a(id,name) VALUES(5,'five')}
      db eval {INSERT INTO a(id,name) VALUES(6,'six')}
      db eval {INSERT INTO a(id,name) VALUES(7,'seven')}
      db eval {INSERT INTO a(id,name) VALUES(8,'eight')}
      db eval {INSERT INTO a(id,name) VALUES(9,'nine')}
      db eval {INSERT INTO a(id,name) VALUES(10,'ten')}
      db close
      sqlite3 db test.db
      db eval {UPDATE A SET name='new text for row 3' WHERE id=3}
      db close
    } {}]
    if {$c==[list 0 {}]} {
      set ::fin 1
      set c [list 1 {child process exited abnormally}]
    }
    set c
  } {1 {child process exited abnormally}}
  sqlite3 db test.db
  integrity_check crash4-1.$cnt.2
  do_test crash4-1.$cnt.3 {
    set x [lsearch $::crash4_cksum_set [cksum db]]
    expr {$x>=0}
  } {1}
}

finish_test

Changes to test/tester.tcl.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
349
350
351
352
353
354
355

356
357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
...
390
391
392
393
394
395
396




397
398
399

400
401
402
403
404
405
406
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.97 2008/01/08 15:18:52 drh Exp $


set tcl_precision 15
set sqlite_pending_byte 0x0010000

# 
# Check the command-line arguments for a default soft-heap-limit.
................................................................................
  if {$::tcl_platform(platform)!="unix"} {
    error "crashsql should only be used on unix"
  }

  set blocksize ""
  set crashdelay 1
  set prngseed 0

  set crashfile ""
  set dc ""
  set sql [lindex $args end]
  
  for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} {
    set z [lindex $args $ii]
    set n [string length $z]
    set z2 [lindex $args [expr $ii+1]]

    if     {$n>1 && [string first $z -delay]==0}     {set crashdelay $z2} \
    elseif {$n>1 && [string first $z -seed]==0}      {set prngseed $z2} \
    elseif {$n>1 && [string first $z -file]==0}      {set crashfile $z2}  \

    elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \
    elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" } \
    else   { error "Unrecognized option: $z" }
  }

  if {$crashfile eq ""} {
    error "Compulsory option -file missing"
................................................................................
  puts $f {btree_set_cache_size $bt 10}
  if {$prngseed} {
    set seed [expr {$prngseed%10007+1}]
    # puts seed=$seed
    puts $f "db eval {SELECT randomblob($seed)}"
  }





  puts $f "db eval {"
  puts $f   "$sql"
  puts $f "}"

  close $f

  set r [catch {
    exec [info nameofexec] crash.tcl >@stdout
  } msg]
  lappend r $msg
}







|







 







>












>







 







>
>
>
>
|
|
|
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
...
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.98 2008/01/08 16:03:50 drh Exp $


set tcl_precision 15
set sqlite_pending_byte 0x0010000

# 
# Check the command-line arguments for a default soft-heap-limit.
................................................................................
  if {$::tcl_platform(platform)!="unix"} {
    error "crashsql should only be used on unix"
  }

  set blocksize ""
  set crashdelay 1
  set prngseed 0
  set tclbody {}
  set crashfile ""
  set dc ""
  set sql [lindex $args end]
  
  for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} {
    set z [lindex $args $ii]
    set n [string length $z]
    set z2 [lindex $args [expr $ii+1]]

    if     {$n>1 && [string first $z -delay]==0}     {set crashdelay $z2} \
    elseif {$n>1 && [string first $z -seed]==0}      {set prngseed $z2} \
    elseif {$n>1 && [string first $z -file]==0}      {set crashfile $z2}  \
    elseif {$n>1 && [string first $z -tclbody]==0}   {set tclbody $z2}  \
    elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \
    elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" } \
    else   { error "Unrecognized option: $z" }
  }

  if {$crashfile eq ""} {
    error "Compulsory option -file missing"
................................................................................
  puts $f {btree_set_cache_size $bt 10}
  if {$prngseed} {
    set seed [expr {$prngseed%10007+1}]
    # puts seed=$seed
    puts $f "db eval {SELECT randomblob($seed)}"
  }

  if {[string length $tclbody]>0} {
    puts $f $tclbody
  }
  if {[string length $sql]>0} {
    puts $f "db eval {"
    puts $f   "$sql"
    puts $f "}"
  }
  close $f

  set r [catch {
    exec [info nameofexec] crash.tcl >@stdout
  } msg]
  lappend r $msg
}