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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
# 2011 December 13
#
# 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 tests for error (IO, OOM etc.) handling when using
# the multiplexor extension with 8.3 filenames.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set ::testprefix multiplex3
ifcapable !8_3_names {
puts -nonewline "SQLite compiled without SQLITE_ENABLE_8_3_NAMES. "
puts "Skipping tests multiplex3-*."
finish_test
return
}
db close
sqlite3_shutdown
sqlite3_config_uri 1
autoinstall_test_functions
sqlite3_multiplex_initialize "" 1
proc destroy_vfs_stack {} {
generic_unregister stack
sqlite3_multiplex_shutdown
}
proc multiplex_delete_db {} {
forcedelete test.db
for {set i 1} {$i <= 1000} {incr i} {
forcedelete test.[format %03d $i]
}
}
# Procs to save and restore the current muliplexed database.
#
proc multiplex_save_db {} {
foreach f [glob -nocomplain sv_test.*] { forcedelete $f }
foreach f [glob -nocomplain test.*] { forcecopy $f "sv_$f" }
}
proc multiplex_restore_db {} {
foreach f [glob -nocomplain test.*] {forcedelete $f}
foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} }
proc setup_and_save_db {} {
multiplex_delete_db
sqlite3 db file:test.db?8_3_names=1
sqlite3_multiplex_control db main chunk_size [expr 256*1024]
execsql {
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(randomblob(15), randomblob(2000));
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 2
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 4
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 8
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 16
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 32
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 64
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 128
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 256
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 512
}
set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
db close
multiplex_save_db
}
do_test 1.0 { setup_and_save_db } {}
do_faultsim_test 1 -prep {
multiplex_restore_db
sqlite3 db file:test.db?8_3_names=1
sqlite3_multiplex_control db main chunk_size [expr 256*1024]
execsql { PRAGMA journal_mode = truncate }
execsql { PRAGMA synchronous = off }
} -body {
execsql {
UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0
}
} -test {
faultsim_test_result {0 {}}
if {$testrc!=0} {
set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
if {$cksum2 != $::cksum1} { error "data mismatch" }
}
}
#-------------------------------------------------------------------------
# The following tests verify that hot-journal rollback works. As follows:
#
# 1. Create a large database.
# 2. Set the pager cache to be very small.
# 3. Open a transaction.
# 4. Run the following 100 times:
# a. Update a row.
# b. Copy all files on disk to a new db location, including the journal.
# c. Verify that the new db can be opened and that the content matches
# the database created in step 1 (proving the journal was rolled
# back).
do_test 2.0 {
setup_and_save_db
multiplex_restore_db
sqlite3 db file:test.db?8_3_names=1
execsql { PRAGMA cache_size = 10 }
execsql { BEGIN }
} {}
for {set iTest 1} {$iTest<=100} {incr iTest} {
do_test 2.$iTest {
execsql {
UPDATE t1 SET a=randomblob(12), b=randomblob(1400) WHERE rowid=5*$iTest
}
foreach f [glob -nocomplain test.*] {forcecopy $f "xx_$f"}
sqlite3 db2 file:xx_test.db?8_3_names=1
execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a} db2
} $::cksum1
db2 close
}
catch { db close }
do_test 3.0 { setup_and_save_db } {}
do_faultsim_test 3 -faults ioerr-trans* -prep {
forcedelete test2.db
set fd [open test2.wal w]
seek $fd 4095
puts -nonewline $fd x
close $fd
multiplex_restore_db
sqlite3 db file:test.db?8_3_names=1
sqlite3 db2 file:test2.db?8_3_names=1
sqlite3_multiplex_control db main chunk_size [expr 256*1024]
sqlite3_multiplex_control db2 main chunk_size [expr 256*1024]
} -body {
sqlite3_backup B db2 main db main
B step 100000
set rc [B finish]
if { [string match SQLITE_IOERR_* $rc] } {error "disk I/O error"}
set rc
} -test {
faultsim_test_result {0 SQLITE_OK}
if {$testrc==0} {
set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a} db2]
if {$cksum2 != $::cksum1} { error "data mismatch" }
}
catch { B finish }
catch { db close }
catch { db2 close }
}
catch { db close }
sqlite3_multiplex_shutdown
finish_test
|