1# 2011 March 28 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 13set testdir [file dirname $argv0] 14source $testdir/tester.tcl 15source $testdir/lock_common.tcl 16source $testdir/malloc_common.tcl 17 18if {[llength [info commands test_syscall]]==0} { 19 finish_test 20 return 21} 22 23set testprefix sysfault 24 25set FAULTSIM(vfsfault-transient) [list \ 26 -injectinstall vfsfault_install \ 27 -injectstart vfsfault_injectstart_t \ 28 -injectstop vfsfault_injectstop \ 29 -injecterrlist {} \ 30 -injectuninstall {test_syscall uninstall} \ 31] 32set FAULTSIM(vfsfault-persistent) [list \ 33 -injectinstall vfsfault_install \ 34 -injectstart vfsfault_injectstart_p \ 35 -injectstop vfsfault_injectstop \ 36 -injecterrlist {} \ 37 -injectuninstall {test_syscall uninstall} \ 38] 39 40proc vfsfault_injectstart_t {iFail} { test_syscall fault $iFail 0 } 41proc vfsfault_injectstart_p {iFail} { test_syscall fault $iFail 1 } 42proc vfsfault_injectstop {} { test_syscall fault } 43 44faultsim_save_and_close 45 46 47set open_and_write_body { 48 sqlite3 db test.db 49 db eval { 50 CREATE TABLE t1(a, b); 51 INSERT INTO t1 VALUES(1, 2); 52 PRAGMA journal_mode = WAL; 53 INSERT INTO t1 VALUES(3, 4); 54 SELECT * FROM t1; 55 CREATE TEMP TABLE t2(x); 56 INSERT INTO t2 VALUES('y'); 57 } 58} 59 60proc vfsfault_install {} { test_syscall install {open getcwd} } 61do_faultsim_test 1 -faults vfsfault-* -prep { 62 faultsim_restore 63} -body $open_and_write_body -test { 64 faultsim_test_result {0 {wal 1 2 3 4}} \ 65 {1 {unable to open database file}} \ 66 {1 {attempt to write a readonly database}} 67} 68 69# Errors in the fstat() function when opening and writing a file. 70# 71foreach {tn errno errlist} { 72 1 ENOMEM {{disk I/O error}} 73 2 EOVERFLOW {{disk I/O error} {large file support is disabled}} 74} { 75 proc vfsfault_install {} { test_syscall install fstat } 76 set errs [list] 77 foreach e $errlist { lappend errs [list 1 $e] } 78 do_faultsim_test 1.2.$tn -faults vfsfault-* -prep { 79 faultsim_restore 80 } -body " 81 test_syscall errno fstat $errno 82 $open_and_write_body 83 " -test " 84 faultsim_test_result {0 {wal 1 2 3 4}} $errs 85 " 86} 87 88#------------------------------------------------------------------------- 89# Check that a single EINTR error does not affect processing. 90# 91proc vfsfault_install {} { 92 test_syscall reset 93 test_syscall install {open ftruncate close} 94} 95 96forcedelete test.db test.db2 97sqlite3 db test.db 98do_test 2.setup { 99 execsql { 100 CREATE TABLE t1(a, b, c, PRIMARY KEY(a)); 101 INSERT INTO t1 VALUES('abc', 'def', 'ghi'); 102 ATTACH 'test.db2' AS 'aux'; 103 CREATE TABLE aux.t2(x); 104 INSERT INTO t2 VALUES(1); 105 } 106 faultsim_save_and_close 107} {} 108 109do_faultsim_test 2.1 -faults vfsfault-transient -prep { 110 catch { db close } 111 faultsim_restore 112} -body { 113 test_syscall errno open EINTR 114 test_syscall errno ftruncate EINTR 115 test_syscall errno close EINTR 116 117 sqlite3 db test.db 118 set res [db eval { 119 ATTACH 'test.db2' AS 'aux'; 120 SELECT * FROM t1; 121 PRAGMA journal_mode = truncate; 122 BEGIN; 123 INSERT INTO t1 VALUES('jkl', 'mno', 'pqr'); 124 UPDATE t2 SET x = 2; 125 COMMIT; 126 SELECT * FROM t1; 127 SELECT * FROM t2; 128 }] 129 db close 130 set res 131} -test { 132 faultsim_test_result {0 {abc def ghi truncate abc def ghi jkl mno pqr 2}} 133} 134 135do_faultsim_test 2.2 -faults vfsfault-* -prep { 136 catch { db close } 137 faultsim_restore 138} -body { 139 sqlite3 db test.db 140 set res [db eval { 141 ATTACH 'test.db2' AS 'aux'; 142 SELECT * FROM t1; 143 PRAGMA journal_mode = truncate; 144 BEGIN; 145 INSERT INTO t1 VALUES('jkl', 'mno', 'pqr'); 146 UPDATE t2 SET x = 2; 147 COMMIT; 148 SELECT * FROM t1; 149 SELECT * FROM t2; 150 }] 151 db close 152 set res 153} -test { 154 faultsim_test_result {0 {abc def ghi truncate abc def ghi jkl mno pqr 2}} \ 155 {1 {unable to open database file}} \ 156 {1 {unable to open database: test.db2}} \ 157 {1 {attempt to write a readonly database}} \ 158 {1 {disk I/O error}} 159} 160 161#------------------------------------------------------------------------- 162# 163 164 165finish_test 166 167