CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
indexfault.test353 linesDownload Raw Back to test
1# 2011 August 082#3# The author disclaims copyright to this source code.  In place of4# 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.tcl15source $testdir/lock_common.tcl16source $testdir/malloc_common.tcl17 18ifcapable !mergesort {19  finish_test20  return21}22 23set testprefix indexfault24 25# Set up the custom fault-injector. This is further configured by using26# different values for $::custom_filter and different implementations27# of Tcl proc [xCustom] for each test case.28#29proc install_custom_faultsim {} {30  set ::FAULTSIM(custom)            [list      \31    -injectinstall   custom_injectinstall    \32    -injectstart     custom_injectstart      \33    -injectstop      custom_injectstop       \34    -injecterrlist   {{1 {disk I/O error}}}  \35    -injectuninstall custom_injectuninstall  \36  ]37  proc custom_injectinstall {} {38    testvfs shmfault -default true39    shmfault filter $::custom_filter40    shmfault script xCustom41  }42  proc custom_injectuninstall {} {43    catch {db  close}44    catch {db2 close}45    shmfault delete46  }47  set ::custom_ifail -148  set ::custom_nfail -149  proc custom_injectstart {iFail} {50    set ::custom_ifail $iFail51    set ::custom_nfail 052  }53  proc custom_injectstop {} {54    set ::custom_ifail -155    return $::custom_nfail56  }57}58proc uninstall_custom_faultsim {} {59  unset -nocomplain ::FAULTSIM(custom)60}61 62 63#-------------------------------------------------------------------------64# These tests - indexfault-1.* - Build an index on a smallish table with65# all different kinds of fault-injection. The CREATE INDEX is run once66# with default options and once with a 50KB soft-heap-limit.67#68do_execsql_test 1.0 {69  BEGIN;70    CREATE TABLE t1(x);71    INSERT INTO t1 VALUES(randomblob(202));72    INSERT INTO t1 SELECT randomblob(202) FROM t1;     --     273    INSERT INTO t1 SELECT randomblob(202) FROM t1;     --     474    INSERT INTO t1 SELECT randomblob(202) FROM t1;     --     875    INSERT INTO t1 SELECT randomblob(202) FROM t1;     --    1676    INSERT INTO t1 SELECT randomblob(202) FROM t1;     --    3277    INSERT INTO t1 SELECT randomblob(202) FROM t1;     --    6478    INSERT INTO t1 SELECT randomblob(202) FROM t1;     --   12879    INSERT INTO t1 SELECT randomblob(202) FROM t1;     --   25680  COMMIT;81}82faultsim_save_and_close83 84do_faultsim_test 1.1 -prep {85  faultsim_restore_and_reopen86} -body {87  execsql { CREATE INDEX i1 ON t1(x) }88  faultsim_test_result {0 {}} 89  faultsim_integrity_check90}91ifcapable memorymanage {92  set soft_limit [sqlite3_soft_heap_limit 50000]93  do_faultsim_test 2.1 -prep {94    faultsim_restore_and_reopen95  } -body {96    execsql { CREATE INDEX i1 ON t1(x) }97    faultsim_test_result {0 {}} 98  }99  sqlite3_soft_heap_limit $soft_limit100}101 102#-------------------------------------------------------------------------103# These are similar to the indexfault-1.* tests, except they create an104# index with more than one column.105#106sqlite3 db test.db107do_execsql_test 2.0 {108  BEGIN;109    DROP TABLE IF EXISTS t1;110    CREATE TABLE t1(t,u,v,w,x,y,z);111    INSERT INTO t1 VALUES(112      randomblob(30), randomblob(30), randomblob(30), randomblob(30),113      randomblob(30), randomblob(30), randomblob(30)114    );115    INSERT INTO t1 SELECT 116      randomblob(30), randomblob(30), randomblob(30), randomblob(30),117      randomblob(30), randomblob(30), randomblob(30) FROM t1;         -- 2118    INSERT INTO t1 SELECT 119      randomblob(30), randomblob(30), randomblob(30), randomblob(30),120      randomblob(30), randomblob(30), randomblob(30) FROM t1;         -- 4121    INSERT INTO t1 SELECT 122      randomblob(30), randomblob(30), randomblob(30), randomblob(30),123      randomblob(30), randomblob(30), randomblob(30) FROM t1;         -- 8124    INSERT INTO t1 SELECT 125      randomblob(30), randomblob(30), randomblob(30), randomblob(30),126      randomblob(30), randomblob(30), randomblob(30) FROM t1;         -- 16127    INSERT INTO t1 SELECT 128      randomblob(30), randomblob(30), randomblob(30), randomblob(30),129      randomblob(30), randomblob(30), randomblob(30) FROM t1;         -- 32130    INSERT INTO t1 SELECT 131      randomblob(30), randomblob(30), randomblob(30), randomblob(30),132      randomblob(30), randomblob(30), randomblob(30) FROM t1;         -- 64133    INSERT INTO t1 SELECT 134      randomblob(30), randomblob(30), randomblob(30), randomblob(30),135      randomblob(30), randomblob(30), randomblob(30) FROM t1;         -- 128136  COMMIT;137}138faultsim_save_and_close139 140do_faultsim_test 2.1 -prep {141  faultsim_restore_and_reopen142} -body {143  execsql { CREATE INDEX i1 ON t1(t,u,v,w,x,y,z) }144  faultsim_test_result {0 {}} 145  faultsim_integrity_check146}147ifcapable memorymanage {148  set soft_limit [sqlite3_soft_heap_limit 50000]149  do_faultsim_test 2.2 -prep {150    faultsim_restore_and_reopen151  } -body {152    execsql { CREATE INDEX i1 ON t1(t,u,v,w,x,y,z) }153    faultsim_test_result {0 {}} 154  }155  sqlite3_soft_heap_limit $soft_limit156}157 158#-------------------------------------------------------------------------159# The following tests - indexfault-2.* - all attempt to build a index160# on table t1 in the main database with injected IO errors. Individual161# test cases work as follows:162#163#   3.1: IO errors injected into xOpen() calls.164#   3.2: As 7.1, but with a low (50KB) soft-heap-limit.165#166#   3.3: IO errors injected into the first 200 write() calls made on the167#        second temporary file.168#   3.4: As 7.3, but with a low (50KB) soft-heap-limit.169#170#   3.5: After a certain amount of data has been read from the main database171#        file (and written into the temporary b-tree), sqlite3_release_memory()172#        is called to free as much memory as possible. This causes the temp173#        b-tree to be flushed to disk. So that before its contents can be 174#        transfered to a PMA they must be read back from disk - creating extra175#        opportunities for IO errors.176#177install_custom_faultsim178 179# Set up a table to build indexes on. Save the setup using the 180# [faultsim_save_and_close] mechanism.181# 182sqlite3 db test.db183do_execsql_test 3.0 {184  BEGIN;185    DROP TABLE IF EXISTS t1;186    CREATE TABLE t1(x);187    INSERT INTO t1 VALUES(randomblob(11000));188    INSERT INTO t1 SELECT randomblob(11001) FROM t1;     --     2189    INSERT INTO t1 SELECT randomblob(11002) FROM t1;     --     4190    INSERT INTO t1 SELECT randomblob(11003) FROM t1;     --     8191    INSERT INTO t1 SELECT randomblob(11004) FROM t1;     --    16192    INSERT INTO t1 SELECT randomblob(11005) FROM t1;     --    32193    INSERT INTO t1 SELECT randomblob(11006) FROM t1;     --    64194    INSERT INTO t1 SELECT randomblob(11007) FROM t1;     --   128195    INSERT INTO t1 SELECT randomblob(11008) FROM t1;     --   256196    INSERT INTO t1 SELECT randomblob(11009) FROM t1;     --   512197  COMMIT;198}199faultsim_save_and_close200 201set ::custom_filter xOpen202proc xCustom {args} {203  incr ::custom_ifail -1204  if {$::custom_ifail==0} {205    incr ::custom_nfail206    return "SQLITE_IOERR"207  }208  return "SQLITE_OK"209}210do_faultsim_test 3.1 -faults custom -prep {211  faultsim_restore_and_reopen212} -body {213  execsql { CREATE INDEX i1 ON t1(x) }214  faultsim_test_result {0 {}} 215}216ifcapable memorymanage {217  set soft_limit [sqlite3_soft_heap_limit 50000]218  do_faultsim_test 3.2 -faults custom -prep {219    faultsim_restore_and_reopen220  } -body {221    execsql { CREATE INDEX i1 ON t1(x) }222    faultsim_test_result {0 {}} 223  }224  sqlite3_soft_heap_limit $soft_limit225}226 227set ::custom_filter {xOpen xWrite}228proc xCustom {method args} {229  if {$method == "xOpen"} {230    if {[lindex $args 0] == ""} {231      incr ::nTmpOpen 1232      if {$::nTmpOpen == 3} { return "failme" }233    }234    return "SQLITE_OK"235  }236  if {$::custom_ifail<200 && [lindex $args 1] == "failme"} {237    incr ::custom_ifail -1238    if {$::custom_ifail==0} {239      incr ::custom_nfail240      return "SQLITE_IOERR"241    }242  }243  return "SQLITE_OK"244}245 246do_faultsim_test 3.3 -faults custom -prep {247  faultsim_restore_and_reopen248  set ::nTmpOpen 0249} -body {250  execsql { CREATE INDEX i1 ON t1(x) }251  faultsim_test_result {0 {}} 252}253 254ifcapable memorymanage {255  set soft_limit [sqlite3_soft_heap_limit 50000]256  do_faultsim_test 3.4 -faults custom -prep {257    faultsim_restore_and_reopen258    set ::nTmpOpen 0259  } -body {260    execsql { CREATE INDEX i1 ON t1(x) }261    faultsim_test_result {0 {}} 262  }263  sqlite3_soft_heap_limit $soft_limit264}265 266uninstall_custom_faultsim267 268#-------------------------------------------------------------------------269# Test 4: After a certain amount of data has been read from the main database270# file (and written into the temporary b-tree), sqlite3_release_memory() is271# called to free as much memory as possible. This causes the temp b-tree to be272# flushed to disk. So that before its contents can be transfered to a PMA they273# must be read back from disk - creating extra opportunities for IO errors.274# 275install_custom_faultsim276 277catch { db close }278forcedelete test.db279sqlite3 db test.db280 281do_execsql_test 4.0 {282  BEGIN;283    DROP TABLE IF EXISTS t1;284    CREATE TABLE t1(x);285    INSERT INTO t1 VALUES(randomblob(11000));286    INSERT INTO t1 SELECT randomblob(11001) FROM t1;     --     2287    INSERT INTO t1 SELECT randomblob(11002) FROM t1;     --     4288    INSERT INTO t1 SELECT randomblob(11003) FROM t1;     --     8289    INSERT INTO t1 SELECT randomblob(11004) FROM t1;     --    16290    INSERT INTO t1 SELECT randomblob(11005) FROM t1;     --    32291    INSERT INTO t1 SELECT randomblob(11005) FROM t1;     --    64292  COMMIT;293}294faultsim_save_and_close295 296testvfs tvfs 297tvfs script xRead298tvfs filter xRead299set ::nRead 0300proc xRead {method file args} {301  if {[file tail $file] == "test.db"} { incr ::nRead }302}303 304do_test 4.1 {305  sqlite3 db test.db -vfs tvfs306  execsql { CREATE INDEX i1 ON t1(x) }307} {}308 309db close310tvfs delete311 312set ::custom_filter xRead313proc xCustom {method file args} {314  incr ::nReadCall315  if {$::nReadCall >= ($::nRead/5)} {316    if {$::nReadCall == ($::nRead/5)} {317      set nByte [sqlite3_release_memory [expr 64*1024*1024]]318      sqlite3_soft_heap_limit 20000319    }320    if {$file == ""} {321      incr ::custom_ifail -1322      if {$::custom_ifail==0} {323        incr ::custom_nfail324        return "SQLITE_IOERR"325      }326    }327  }328  return "SQLITE_OK"329}330 331do_faultsim_test 4.2 -faults custom -prep {332  faultsim_restore_and_reopen333  set ::nReadCall 0334  sqlite3_soft_heap_limit 0335} -body {336  execsql { CREATE INDEX i1 ON t1(x) }337  faultsim_test_result {0 {}} 338}339 340do_faultsim_test 5 -prep {341  reset_db342} -body {343  execsql { 344 CREATE TABLE reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongname(a PRIMARY KEY) WITHOUT ROWID;345  }346} -test {347  faultsim_test_result {0 {}} 348}349 350uninstall_custom_faultsim351 352finish_test353