xref: /sqlite-3.40.0/test/sysfault.test (revision c18ed977)
1213ca0a8Sdan# 2011 March 28
2213ca0a8Sdan#
3213ca0a8Sdan# The author disclaims copyright to this source code.  In place of
4213ca0a8Sdan# a legal notice, here is a blessing:
5213ca0a8Sdan#
6213ca0a8Sdan#    May you do good and not evil.
7213ca0a8Sdan#    May you find forgiveness for yourself and forgive others.
8213ca0a8Sdan#    May you share freely, never taking more than you give.
9213ca0a8Sdan#
10213ca0a8Sdan#***********************************************************************
11213ca0a8Sdan#
12213ca0a8Sdan
13213ca0a8Sdanset testdir [file dirname $argv0]
14213ca0a8Sdansource $testdir/tester.tcl
15213ca0a8Sdansource $testdir/lock_common.tcl
16213ca0a8Sdansource $testdir/malloc_common.tcl
17213ca0a8Sdan
18213ca0a8Sdanif {[llength [info commands test_syscall]]==0} {
19213ca0a8Sdan  finish_test
20213ca0a8Sdan  return
21213ca0a8Sdan}
22213ca0a8Sdan
23213ca0a8Sdanset testprefix sysfault
24213ca0a8Sdan
25213ca0a8Sdanset FAULTSIM(vfsfault-transient) [list             \
26213ca0a8Sdan  -injectinstall   vfsfault_install                \
27213ca0a8Sdan  -injectstart     vfsfault_injectstart_t          \
28213ca0a8Sdan  -injectstop      vfsfault_injectstop             \
29213ca0a8Sdan  -injecterrlist   {}                              \
30213ca0a8Sdan  -injectuninstall {test_syscall uninstall}        \
31213ca0a8Sdan]
32213ca0a8Sdanset FAULTSIM(vfsfault-persistent) [list            \
33213ca0a8Sdan  -injectinstall   vfsfault_install                \
34213ca0a8Sdan  -injectstart     vfsfault_injectstart_p          \
35213ca0a8Sdan  -injectstop      vfsfault_injectstop             \
36213ca0a8Sdan  -injecterrlist   {}                              \
37213ca0a8Sdan  -injectuninstall {test_syscall uninstall}        \
38213ca0a8Sdan]
39213ca0a8Sdan
40213ca0a8Sdanproc vfsfault_injectstart_t {iFail} { test_syscall fault $iFail 0 }
41213ca0a8Sdanproc vfsfault_injectstart_p {iFail} { test_syscall fault $iFail 1 }
42213ca0a8Sdanproc vfsfault_injectstop    {}      { test_syscall fault }
43213ca0a8Sdan
44213ca0a8Sdanfaultsim_save_and_close
45213ca0a8Sdan
46213ca0a8Sdan
475ef47bf0Sdanset open_and_write_body {
48213ca0a8Sdan  sqlite3 db test.db
49213ca0a8Sdan  db eval {
50213ca0a8Sdan    CREATE TABLE t1(a, b);
51213ca0a8Sdan    INSERT INTO t1 VALUES(1, 2);
52213ca0a8Sdan    PRAGMA journal_mode = WAL;
53213ca0a8Sdan    INSERT INTO t1 VALUES(3, 4);
54213ca0a8Sdan    SELECT * FROM t1;
55213ca0a8Sdan    CREATE TEMP TABLE t2(x);
56213ca0a8Sdan    INSERT INTO t2 VALUES('y');
57213ca0a8Sdan  }
585ef47bf0Sdan}
595ef47bf0Sdan
605ef47bf0Sdanproc vfsfault_install {} { test_syscall install {open getcwd} }
615ef47bf0Sdando_faultsim_test 1 -faults vfsfault-* -prep {
625ef47bf0Sdan  faultsim_restore
635ef47bf0Sdan} -body $open_and_write_body -test {
64213ca0a8Sdan  faultsim_test_result {0 {wal 1 2 3 4}}       \
65213ca0a8Sdan    {1 {unable to open database file}}         \
66213ca0a8Sdan    {1 {attempt to write a readonly database}}
67213ca0a8Sdan}
68213ca0a8Sdan
69661d71afSdan#-------------------------------------------------------------------------
70661d71afSdan# Errors in the fstat() function when opening and writing a file. Cases
71661d71afSdan# where fstat() fails and sets errno to ENOMEM and EOVERFLOW are both
72661d71afSdan# tested. EOVERFLOW is interpreted as meaning that a file on disk is
73661d71afSdan# too large to be opened by the OS.
745ef47bf0Sdan#
755ef47bf0Sdanforeach {tn errno errlist} {
765ef47bf0Sdan  1 ENOMEM       {{disk I/O error}}
775ef47bf0Sdan  2 EOVERFLOW    {{disk I/O error} {large file support is disabled}}
785ef47bf0Sdan} {
795ef47bf0Sdan  proc vfsfault_install {} { test_syscall install fstat }
805ef47bf0Sdan  set errs [list]
815ef47bf0Sdan  foreach e $errlist { lappend errs [list 1 $e] }
825ef47bf0Sdan  do_faultsim_test 1.2.$tn -faults vfsfault-* -prep {
835ef47bf0Sdan    faultsim_restore
845ef47bf0Sdan  } -body "
855ef47bf0Sdan    test_syscall errno fstat $errno
865ef47bf0Sdan    $open_and_write_body
875ef47bf0Sdan  " -test "
885ef47bf0Sdan    faultsim_test_result {0 {wal 1 2 3 4}} $errs
895ef47bf0Sdan  "
905ef47bf0Sdan}
915ef47bf0Sdan
9260939d0aSdan#-------------------------------------------------------------------------
93661d71afSdan# Various errors in locking functions.
94661d71afSdan#
95661d71afSdanforeach vfs {unix unix-excl} {
96661d71afSdan  foreach {tn errno errlist} {
97ea83bc61Sdan    1 EAGAIN       {{database is locked} {disk I/O error}}
98ea83bc61Sdan    2 ETIMEDOUT    {{database is locked} {disk I/O error}}
99ea83bc61Sdan    3 EBUSY        {{database is locked} {disk I/O error}}
100ea83bc61Sdan    4 EINTR        {{database is locked} {disk I/O error}}
101ea83bc61Sdan    5 ENOLCK       {{database is locked} {disk I/O error}}
102ea83bc61Sdan    6 EACCES       {{database is locked} {disk I/O error}}
103ea83bc61Sdan    7 EPERM        {{access permission denied} {disk I/O error}}
104661d71afSdan    8 EDEADLK      {{disk I/O error}}
105661d71afSdan    9 ENOMEM       {{disk I/O error}}
106661d71afSdan  } {
107661d71afSdan    proc vfsfault_install {} { test_syscall install fcntl }
108661d71afSdan    set errs [list]
109661d71afSdan    foreach e $errlist { lappend errs [list 1 $e] }
110661d71afSdan
111661d71afSdan    set body [string map [list %VFS% $vfs] {
112661d71afSdan      sqlite3 db test.db
113661d71afSdan      db eval {
114661d71afSdan        CREATE TABLE t1(a, b);
115661d71afSdan        INSERT INTO t1 VALUES(1, 2);
116661d71afSdan      }
117661d71afSdan      set fd [open test.db-journal w]
118661d71afSdan      puts $fd "hello world"
119661d71afSdan      close $fd
120661d71afSdan      sqlite3 db test.db -vfs %VFS%
121661d71afSdan      db eval {
122661d71afSdan        SELECT * FROM t1;
123661d71afSdan      }
124661d71afSdan    }]
125661d71afSdan
126661d71afSdan    do_faultsim_test 1.3.$vfs.$tn -faults vfsfault-* -prep {
127661d71afSdan      faultsim_restore
128661d71afSdan    } -body "
129661d71afSdan      test_syscall errno fcntl $errno
130661d71afSdan      $body
131661d71afSdan    " -test "
132661d71afSdan      faultsim_test_result {0 {1 2}} $errs
133661d71afSdan    "
134661d71afSdan  }
135661d71afSdan}
136661d71afSdan
137661d71afSdan#-------------------------------------------------------------------------
13860939d0aSdan# Check that a single EINTR error does not affect processing.
13960939d0aSdan#
14060939d0aSdanproc vfsfault_install {} {
14160939d0aSdan  test_syscall reset
142661d71afSdan  test_syscall install {open ftruncate close read pread pread64 write fallocate}
14360939d0aSdan}
14460939d0aSdan
14560939d0aSdanforcedelete test.db test.db2
14660939d0aSdansqlite3 db test.db
14760939d0aSdando_test 2.setup {
14860939d0aSdan  execsql {
14960939d0aSdan    CREATE TABLE t1(a, b, c, PRIMARY KEY(a));
15060939d0aSdan    INSERT INTO t1 VALUES('abc', 'def', 'ghi');
15160939d0aSdan    ATTACH 'test.db2' AS 'aux';
15260939d0aSdan    CREATE TABLE aux.t2(x);
15360939d0aSdan    INSERT INTO t2 VALUES(1);
15460939d0aSdan  }
15560939d0aSdan  faultsim_save_and_close
15660939d0aSdan} {}
15760939d0aSdan
15860939d0aSdando_faultsim_test 2.1 -faults vfsfault-transient -prep {
15960939d0aSdan  catch { db close }
16060939d0aSdan  faultsim_restore
16160939d0aSdan} -body {
16260939d0aSdan  test_syscall errno open      EINTR
16360939d0aSdan  test_syscall errno ftruncate EINTR
16460939d0aSdan  test_syscall errno close     EINTR
165661d71afSdan  test_syscall errno read      EINTR
166661d71afSdan  test_syscall errno pread     EINTR
167661d71afSdan  test_syscall errno pread64   EINTR
168661d71afSdan  test_syscall errno write     EINTR
169661d71afSdan  test_syscall errno fallocate EINTR
17060939d0aSdan
17160939d0aSdan  sqlite3 db test.db
172661d71afSdan  file_control_chunksize_test db main 8192
173661d71afSdan
17460939d0aSdan  set res [db eval {
17560939d0aSdan    ATTACH 'test.db2' AS 'aux';
17660939d0aSdan    SELECT * FROM t1;
17760939d0aSdan    PRAGMA journal_mode = truncate;
17860939d0aSdan    BEGIN;
17960939d0aSdan      INSERT INTO t1 VALUES('jkl', 'mno', 'pqr');
180661d71afSdan      INSERT INTO t1 VALUES(randomblob(10000), 0, 0);
18160939d0aSdan      UPDATE t2 SET x = 2;
18260939d0aSdan    COMMIT;
183661d71afSdan    DELETE FROM t1 WHERE length(a)>3;
18460939d0aSdan    SELECT * FROM t1;
18560939d0aSdan    SELECT * FROM t2;
18660939d0aSdan  }]
18760939d0aSdan  db close
18860939d0aSdan  set res
18960939d0aSdan} -test {
19060939d0aSdan  faultsim_test_result {0 {abc def ghi truncate abc def ghi jkl mno pqr 2}}
19160939d0aSdan}
19260939d0aSdan
19360939d0aSdando_faultsim_test 2.2 -faults vfsfault-* -prep {
19460939d0aSdan  catch { db close }
19560939d0aSdan  faultsim_restore
19660939d0aSdan} -body {
19760939d0aSdan  sqlite3 db test.db
19860939d0aSdan  set res [db eval {
19960939d0aSdan    ATTACH 'test.db2' AS 'aux';
20060939d0aSdan    SELECT * FROM t1;
20160939d0aSdan    PRAGMA journal_mode = truncate;
20260939d0aSdan    BEGIN;
20360939d0aSdan      INSERT INTO t1 VALUES('jkl', 'mno', 'pqr');
20460939d0aSdan      UPDATE t2 SET x = 2;
20560939d0aSdan    COMMIT;
20660939d0aSdan    SELECT * FROM t1;
20760939d0aSdan    SELECT * FROM t2;
20860939d0aSdan  }]
20960939d0aSdan  db close
21060939d0aSdan  set res
21160939d0aSdan} -test {
21260939d0aSdan  faultsim_test_result {0 {abc def ghi truncate abc def ghi jkl mno pqr 2}} \
21360939d0aSdan    {1 {unable to open database file}}                                      \
21460939d0aSdan    {1 {unable to open database: test.db2}}                                 \
21560939d0aSdan    {1 {attempt to write a readonly database}}                              \
21660939d0aSdan    {1 {disk I/O error}}
21760939d0aSdan}
21860939d0aSdan
2195ef47bf0Sdan#-------------------------------------------------------------------------
2205ef47bf0Sdan
221661d71afSdanproc vfsfault_install {} {
222661d71afSdan  test_syscall reset
223661d71afSdan  test_syscall install {fstat fallocate}
224661d71afSdan}
225661d71afSdando_faultsim_test 3 -faults vfsfault-* -prep {
226661d71afSdan  faultsim_delete_and_reopen
227661d71afSdan  file_control_chunksize_test db main 8192
228661d71afSdan  execsql {
229*c18ed977Sdrh    PRAGMA synchronous=OFF;
230661d71afSdan    CREATE TABLE t1(a, b);
231661d71afSdan    BEGIN;
232661d71afSdan      SELECT * FROM t1;
233661d71afSdan  }
234661d71afSdan} -body {
235661d71afSdan  test_syscall errno fstat     EIO
236661d71afSdan  test_syscall errno fallocate EIO
237661d71afSdan
238661d71afSdan  execsql {
239661d71afSdan    INSERT INTO t1 VALUES(randomblob(10000), randomblob(10000));
240661d71afSdan    SELECT length(a) + length(b) FROM t1;
241661d71afSdan    COMMIT;
242661d71afSdan  }
243661d71afSdan} -test {
244661d71afSdan  faultsim_test_result {0 20000}
245661d71afSdan}
24660939d0aSdan
247893c0ffcSdan#-------------------------------------------------------------------------
248893c0ffcSdan# Test errors in mmap().
249893c0ffcSdan#
250893c0ffcSdanproc vfsfault_install {} {
251893c0ffcSdan  test_syscall reset
252893c0ffcSdan  test_syscall install {mmap}
253893c0ffcSdan}
254893c0ffcSdan
255893c0ffcSdanfaultsim_delete_and_reopen
256893c0ffcSdanexecsql {
257893c0ffcSdan  CREATE TABLE t1(a, b);
258893c0ffcSdan  INSERT INTO t1 VALUES(1, 2);
259893c0ffcSdan}
260893c0ffcSdanfaultsim_save_and_close
261893c0ffcSdan
262893c0ffcSdando_faultsim_test 4 -faults vfsfault-* -prep {
263893c0ffcSdan  faultsim_restore_and_reopen
264893c0ffcSdan  file_control_chunksize_test db main 8192
265893c0ffcSdan  execsql {
2669b4c59faSdrh    PRAGMA mmap_size = 1000000;
267893c0ffcSdan  }
268893c0ffcSdan} -body {
269893c0ffcSdan  test_syscall errno mmap     EACCES
270893c0ffcSdan
271893c0ffcSdan  execsql {
272893c0ffcSdan    SELECT * FROM t1;
273893c0ffcSdan  }
274893c0ffcSdan} -test {
275893c0ffcSdan  faultsim_test_result {0 {1 2}} {1 {disk I/O error}}
276893c0ffcSdan}
277893c0ffcSdan
278213ca0a8Sdanfinish_test
279