xref: /sqlite-3.40.0/test/corrupt.test (revision 6a67fe8e)
1# 2004 August 30
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# This file implements tests to make sure SQLite does not crash or
14# segfault if it sees a corrupt database file.
15#
16# $Id: corrupt.test,v 1.5 2005/02/04 04:07:18 danielk1977 Exp $
17
18catch {file delete -force test.db}
19catch {file delete -force test.db-journal}
20
21set testdir [file dirname $argv0]
22source $testdir/tester.tcl
23
24# Construct a large database for testing.
25#
26do_test corrupt-1.1 {
27  execsql {
28    BEGIN;
29    CREATE TABLE t1(x);
30    INSERT INTO t1 VALUES(randstr(10,100));
31    INSERT INTO t1 VALUES(randstr(10,100));
32    INSERT INTO t1 VALUES(randstr(10,100));
33    INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
34    INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
35    INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
36    INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
37    INSERT INTO t1 VALUES(randstr(2100,3000));
38    INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
39    INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
40    INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
41    INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
42    CREATE INDEX t1i1 ON t1(x);
43    CREATE TABLE t2 AS SELECT * FROM t1;
44    DELETE FROM t2 WHERE rowid%5!=0;
45    COMMIT;
46  }
47} {}
48integrity_check corrupt-1.2
49
50# Copy file $from into $to
51#
52proc copy_file {from to} {
53  set f [open $from]
54  fconfigure $f -translation binary
55  set t [open $to w]
56  fconfigure $t -translation binary
57  puts -nonewline $t [read $f [file size $from]]
58  close $t
59  close $f
60}
61
62# Setup for the tests.  Make a backup copy of the good database in test.bu.
63# Create a string of garbage data that is 256 bytes long.
64#
65copy_file test.db test.bu
66set fsize [file size test.db]
67set junk "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
68while {[string length $junk]<256} {append junk $junk}
69set junk [string range $junk 0 255]
70
71# Go through the database and write garbage data into each 256 segment
72# of the file.  Then do various operations on the file to make sure that
73# the database engine can recover gracefully from the corruption.
74#
75for {set i [expr {1*256}]} {$i<$fsize-256} {incr i 256} {
76  set tn [expr {$i/256}]
77  db close
78  copy_file test.bu test.db
79  set fd [open test.db r+]
80  fconfigure $fd -translation binary
81  seek $fd $i
82  puts -nonewline $fd $junk
83  close $fd
84  do_test corrupt-2.$tn.1 {
85    sqlite3 db test.db
86    catchsql {SELECT count(*) FROM sqlite_master}
87    set x {}
88  } {}
89  do_test corrupt-2.$tn.2 {
90    catchsql {SELECT count(*) FROM t1}
91    set x {}
92  } {}
93  do_test corrupt-2.$tn.3 {
94    catchsql {SELECT count(*) FROM t1 WHERE x>'abcdef'}
95    set x {}
96  } {}
97  do_test corrupt-2.$tn.4 {
98    catchsql {SELECT count(*) FROM t2}
99    set x {}
100  } {}
101  do_test corrupt-2.$tn.5 {
102    catchsql {CREATE TABLE t3 AS SELECT * FROM t1}
103    set x {}
104  } {}
105  do_test corrupt-2.$tn.6 {
106    catchsql {DROP TABLE t1}
107    set x {}
108  } {}
109  do_test corrupt-2.$tn.7 {
110    catchsql {PRAGMA integrity_check}
111    set x {}
112  } {}
113}
114
115finish_test
116