Change things so that journal2.test works with ENABLE_ATOMIC_WRITE.
FossilOrigin-Name: a64d96db09ef2b7651fa4e98d3c7bf3ae5d3fe96
This commit is contained in:
+151
-1
@@ -227,6 +227,13 @@ do_execsql_test pager1-3.6 { COMMIT } {}
|
||||
# pager1.4.3.*: Test that the contents of a hot-journal are ignored if the
|
||||
# page-size or sector-size in the journal header appear to
|
||||
# be invalid (too large, too small or not a power of 2).
|
||||
#
|
||||
# pager1.4.4.*: Test hot-journal rollback of journal file with a master
|
||||
# journal pointer generated in various "PRAGMA synchronous"
|
||||
# modes.
|
||||
#
|
||||
# pager1.4.5.*: Test that hot-journal rollback stops if it encounters a
|
||||
# journal-record for which the checksum fails.
|
||||
#
|
||||
do_test pager1.4.1.1 {
|
||||
faultsim_delete_and_reopen
|
||||
@@ -354,6 +361,146 @@ foreach {tn ofst value result} {
|
||||
}
|
||||
db close
|
||||
|
||||
# Set up a VFS that snapshots the file-system just before a master journal
|
||||
# file is deleted to commit a multi-file transaction. Specifically, the
|
||||
# file-system is saved just before the xDelete() call to remove the
|
||||
# master journal file from the file-system.
|
||||
#
|
||||
testvfs tv -default 1
|
||||
tv script copy_on_mj_delete
|
||||
set ::mj_filename_length 0
|
||||
proc copy_on_mj_delete {method filename args} {
|
||||
if {[string match *mj* [file tail $filename]]} {
|
||||
set ::mj_filename_length [string length $filename]
|
||||
faultsim_save
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
set pwd [pwd]
|
||||
foreach {tn1 tcl} {
|
||||
1 { set prefix "test.db" }
|
||||
2 {
|
||||
# This test depends on the underlying VFS being able to open paths
|
||||
# 512 bytes in length. The idea is to create a hot-journal file that
|
||||
# contains a master-journal pointer so large that it could contain
|
||||
# a valid page record (if the file page-size is 512 bytes). So as to
|
||||
# make sure SQLite doesn't get confused by this.
|
||||
#
|
||||
set nPadding [expr 511 - $::mj_filename_length]
|
||||
|
||||
# We cannot just create a really long database file name to open, as
|
||||
# Linux limits a single component of a path to 255 bytes by default
|
||||
# (and presumably other systems have limits too). So create a directory
|
||||
# hierarchy to work in.
|
||||
#
|
||||
set dirname "d123456789012345678901234567890/"
|
||||
set nDir [expr $nPadding / 32]
|
||||
if { $nDir } {
|
||||
set p [string repeat $dirname $nDir]
|
||||
file mkdir $p
|
||||
cd $p
|
||||
}
|
||||
|
||||
set padding [string repeat x [expr $nPadding %32]]
|
||||
set prefix "test.db${padding}"
|
||||
}
|
||||
} {
|
||||
eval $tcl
|
||||
foreach {tn2 sql} {
|
||||
o {
|
||||
PRAGMA main.synchronous=OFF;
|
||||
PRAGMA aux.synchronous=OFF;
|
||||
}
|
||||
o512 {
|
||||
PRAGMA main.synchronous=OFF;
|
||||
PRAGMA aux.synchronous=OFF;
|
||||
PRAGMA main.page_size = 512;
|
||||
PRAGMA aux.page_size = 512;
|
||||
}
|
||||
n {
|
||||
PRAGMA main.synchronous=NORMAL;
|
||||
PRAGMA aux.synchronous=NORMAL;
|
||||
}
|
||||
f {
|
||||
PRAGMA main.synchronous=FULL;
|
||||
PRAGMA aux.synchronous=FULL;
|
||||
}
|
||||
} {
|
||||
|
||||
set tn "${tn1}.${tn2}"
|
||||
|
||||
# Set up a connection to have two databases, test.db (main) and
|
||||
# test.db2 (aux). Then run a multi-file transaction on them. The
|
||||
# VFS will snapshot the file-system just before the master-journal
|
||||
# file is deleted to commit the transaction.
|
||||
#
|
||||
tv filter xDelete
|
||||
do_test pager1-4.4.$tn.1 {
|
||||
faultsim_delete_and_reopen $prefix
|
||||
execsql "
|
||||
ATTACH '${prefix}2' AS aux;
|
||||
$sql
|
||||
CREATE TABLE a(x);
|
||||
CREATE TABLE aux.b(x);
|
||||
INSERT INTO a VALUES('double-you');
|
||||
INSERT INTO a VALUES('why');
|
||||
INSERT INTO a VALUES('zed');
|
||||
INSERT INTO b VALUES('won');
|
||||
INSERT INTO b VALUES('too');
|
||||
INSERT INTO b VALUES('free');
|
||||
"
|
||||
execsql {
|
||||
BEGIN;
|
||||
INSERT INTO a SELECT * FROM b WHERE rowid<=3;
|
||||
INSERT INTO b SELECT * FROM a WHERE rowid<=3;
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
tv filter {}
|
||||
|
||||
# Check that the transaction was committed successfully.
|
||||
#
|
||||
do_execsql_test pager1-4.4.$tn.2 {
|
||||
SELECT * FROM a
|
||||
} {double-you why zed won too free}
|
||||
do_execsql_test pager1-4.4.$tn.3 {
|
||||
SELECT * FROM b
|
||||
} {won too free double-you why zed}
|
||||
|
||||
# Restore the file-system and reopen the databases. Check that it now
|
||||
# appears that the transaction was not committed (because the file-system
|
||||
# was restored to the state where it had not been).
|
||||
#
|
||||
do_test pager1-4.4.$tn.4 {
|
||||
faultsim_restore_and_reopen $prefix
|
||||
execsql "ATTACH '${prefix}2' AS aux"
|
||||
} {}
|
||||
do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed}
|
||||
do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free}
|
||||
|
||||
# Restore the file-system again. This time, before reopening the databases,
|
||||
# delete the master-journal file from the file-system. It now appears that
|
||||
# the transaction was committed (no master-journal file == no rollback).
|
||||
#
|
||||
do_test pager1-4.4.$tn.7 {
|
||||
faultsim_restore_and_reopen $prefix
|
||||
foreach f [glob ${prefix}-mj*] { file delete -force $f }
|
||||
execsql "ATTACH '${prefix}2' AS aux"
|
||||
} {}
|
||||
do_execsql_test pager1-4.4.$tn.8 {
|
||||
SELECT * FROM a
|
||||
} {double-you why zed won too free}
|
||||
do_execsql_test pager1-4.4.$tn.9 {
|
||||
SELECT * FROM b
|
||||
} {won too free double-you why zed}
|
||||
}
|
||||
|
||||
cd $pwd
|
||||
}
|
||||
db close
|
||||
tv delete
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests deal with multi-file commits.
|
||||
#
|
||||
@@ -373,7 +520,10 @@ db close
|
||||
# name does not lie on the same sector as the last journal file
|
||||
# record.
|
||||
#
|
||||
# pager1-5.5.*:
|
||||
# pager1-5.5.*: Check that in journal_mode=PERSIST mode, a journal file is
|
||||
# truncated to zero bytes when a multi-file transaction is
|
||||
# committed (instead of the first couple of bytes being zeroed).
|
||||
#
|
||||
#
|
||||
do_test pager1-5.1.1 {
|
||||
faultsim_delete_and_reopen
|
||||
|
||||
Reference in New Issue
Block a user