From 89ccf4481b894c7ca5c8a8cd0e02616f43219a7d Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 1 Jul 2010 15:09:47 +0000 Subject: [PATCH] Add pager test cases. Change a condition in pager.c to NEVER(). FossilOrigin-Name: a8f6341d3b12d64ef56ed05226e3b4f183b8957d --- manifest | 20 ++--- manifest.uuid | 2 +- src/pager.c | 2 +- src/test1.c | 1 + src/test_vfs.c | 26 ++++-- test/pager1.test | 195 +++++++++++++++++++++++++++++++++++++++++- test/pagerfault.test | 198 ++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 424 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 603e350f8f..803f9d3b3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfurther\stest\scases.\sFix\san\sassert()\sin\spager.c. -D 2010-06-30T10:36:19 +C Add\spager\stest\scases.\sChange\sa\scondition\sin\spager.c\sto\sNEVER(). +D 2010-07-01T15:09:48 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -156,7 +156,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19 F src/os_unix.c ec7c7f7ca224ce2ff58736eebf804b48a75f9946 F src/os_win.c 48f67798969ba983487fed5691059ade7fff2ef7 -F src/pager.c 778df1ad25b679e836e480e62767c625448fb6af +F src/pager.c 19975354882e9ac8d361bb3c1c434fd3aa9b0928 F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 @@ -177,7 +177,7 @@ F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3 F src/status.c 4df6fe7dce2d256130b905847c6c60055882bdbe F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c b898ab058f51ee57e6b54aa8de902526a5376959 -F src/test1.c 1ddb761b09342fbf3e81c7027332f2522673a6fc +F src/test1.c 5f813ce9d9e9070379ed910d7ea2af0863056be5 F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94 F src/test4.c ad03bb987ddedce928f4258c1e7fa4109a73497d @@ -209,7 +209,7 @@ F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c aa9919c885a1fe53eafc73492f0898ee6c0a0726 -F src/test_vfs.c 2291fd22726e499830e9958563e760effaf9e9af +F src/test_vfs.c 88ca1326c124cc81396dd3ad752018c0e68711df F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb F src/trigger.c 67e95c76d625b92d43409ace771c8e0d02a09ac2 @@ -535,9 +535,9 @@ F test/notify3.test b923ff67728f363378698fb27b5f41a5a1b4d9e0 F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec -F test/pager1.test a87a7dffe28d2940fdea2bac3b3354317f358d3f +F test/pager1.test f00c701b29a37a08f084a0183b4901a3a57e6673 F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef -F test/pagerfault.test 03160cec962526ee46f57e8fb984065fe7748b69 +F test/pagerfault.test 6d5bf244d171e808e3b642ab830f5cd159af8f7b F test/pagerfault2.test 1287f123bd5d20452113739ed7755fd254e502f1 F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb @@ -829,7 +829,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P cdf2c5c2dd2e4404ffb85a680d31307afea266eb -R aeea8d6e6bedd1415172495b05353710 +P 8e65c0e3dac400f6a0ec3b7494fba62c14ed6182 +R ce36b405629391c76b6369dbfd427fc7 U dan -Z 2bc1bd3da71e890911d4e52601f27027 +Z 6dd5024e4de43ce2f67cf29dfaba34f2 diff --git a/manifest.uuid b/manifest.uuid index b32333bd4d..7e0c2ecb7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e65c0e3dac400f6a0ec3b7494fba62c14ed6182 \ No newline at end of file +a8f6341d3b12d64ef56ed05226e3b4f183b8957d \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 2d084e54c0..b2e1487126 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5963,7 +5963,7 @@ int sqlite3PagerGetJournalMode(Pager *pPager){ */ int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ if( pPager->dbModified ) return 0; - if( isOpen(pPager->jfd) && pPager->journalOff>0 ) return 0; + if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; return 1; } diff --git a/src/test1.c b/src/test1.c index e5059eb652..3f46dc1a6d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1902,6 +1902,7 @@ static int sqlite_abort( char **argv /* Text of each argument */ ){ assert( interp==0 ); /* This will always fail */ + abort(); return TCL_OK; } diff --git a/src/test_vfs.c b/src/test_vfs.c index ce0642e2c8..cd4636230f 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -190,7 +190,7 @@ static void tvfsShmBarrier(sqlite3_file*); static int tvfsShmClose(sqlite3_file*, int); static sqlite3_io_methods tvfs_io_methods = { - 2, /* iVersion */ + 2, /* iVersion */ tvfsClose, /* xClose */ tvfsRead, /* xRead */ tvfsWrite, /* xWrite */ @@ -575,9 +575,18 @@ static int tvfsOpen( rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, pFd->pReal, flags, pOutFlags); if( pFd->pReal->pMethods ){ sqlite3_io_methods *pMethods; - pMethods = (sqlite3_io_methods *)ckalloc(sizeof(sqlite3_io_methods)); - memcpy(pMethods, &tvfs_io_methods, sizeof(sqlite3_io_methods)); - if( ((Testvfs *)pVfs->pAppData)->isNoshm ){ + int nByte; + + if( pVfs->iVersion>1 ){ + nByte = sizeof(sqlite3_io_methods); + }else{ + nByte = offsetof(sqlite3_io_methods, xShmOpen); + } + + pMethods = (sqlite3_io_methods *)ckalloc(nByte); + memcpy(pMethods, &tvfs_io_methods, nByte); + pMethods->iVersion = pVfs->iVersion; + if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){ pMethods->xShmOpen = 0; pMethods->xShmClose = 0; pMethods->xShmLock = 0; @@ -1300,6 +1309,7 @@ static int testvfs_cmd( int isDefault = 0; /* True if -default is passed */ int szOsFile = 0; /* Value passed to -szosfile */ int mxPathname = -1; /* Value passed to -mxpathname */ + int iVersion = 2; /* Value passed to -iversion */ if( objc<2 || 0!=(objc%2) ) goto bad_args; for(i=2; i2 && 0==strncmp("-iversion", zSwitch, nSwitch) ){ + if( Tcl_GetIntFromObj(interp, objv[i+1], &iVersion) ){ + return TCL_ERROR; + } + } else{ goto bad_args; } @@ -1359,6 +1374,7 @@ static int testvfs_cmd( pVfs = (sqlite3_vfs *)ckalloc(sizeof(sqlite3_vfs)); memcpy(pVfs, &tvfs_vfs, sizeof(sqlite3_vfs)); pVfs->pAppData = (void *)p; + pVfs->iVersion = iVersion; pVfs->zName = p->zName; pVfs->mxPathname = p->pParent->mxPathname; if( mxPathname>=0 && mxPathnamemxPathname ){ @@ -1374,7 +1390,7 @@ static int testvfs_cmd( return TCL_OK; bad_args: - Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT?"); + Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?"); return TCL_ERROR; } diff --git a/test/pager1.test b/test/pager1.test index 897b034fe6..5175ba4d66 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -1093,6 +1093,28 @@ ifcapable wal { } } +do_test pager1-7.2.1 { + faultsim_delete_and_reopen + execsql { + PRAGMA locking_mode = EXCLUSIVE; + CREATE TABLE t1(a, b); + BEGIN; + PRAGMA journal_mode = delete; + PRAGMA journal_mode = truncate; + } +} {exclusive delete truncate} +do_test pager1-7.2.2 { + execsql { INSERT INTO t1 VALUES(1, 2) } + execsql { PRAGMA journal_mode = persist } +} {truncate} +do_test pager1-7.2.3 { + execsql { COMMIT } + execsql { + PRAGMA journal_mode = persist; + PRAGMA journal_size_limit; + } +} {persist -1} + #------------------------------------------------------------------------- # The following tests, pager1-8.*, test that the special filenames # ":memory:" and "" open temporary databases. @@ -1756,7 +1778,178 @@ do_test pager1-20.3.2 { execsql COMMIT } {} - +#------------------------------------------------------------------------- +# Test that a WAL database may not be opened if: +# +# pager1-21.1.*: The VFS has an iVersion less than 2, or +# pager1-21.2.*: The VFS does not provide xShmXXX() methods. +# +do_test pager1-21.0 { + faultsim_delete_and_reopen + execsql { + PRAGMA journal_mode = WAL; + CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def'); + INSERT INTO ko DEFAULT VALUES; + } +} {wal} +do_test pager1-21.1 { + testvfs tv -noshm 1 + sqlite3 db2 test.db -vfs tv + catchsql { SELECT * FROM ko } db2 +} {1 {unable to open database file}} +db2 close +tv delete +do_test pager1-21.2 { +breakpoint + testvfs tv -iversion 1 + sqlite3 db2 test.db -vfs tv + catchsql { SELECT * FROM ko } db2 +} {1 {unable to open database file}} +db2 close +tv delete + +#------------------------------------------------------------------------- +# Test that a "PRAGMA wal_checkpoint": +# +# pager1-22.1.*: is a no-op on a non-WAL db, and +# pager1-22.2.*: does not cause xSync calls with a synchronous=off db. +# +do_test pager1-22.1.1 { + faultsim_delete_and_reopen + execsql { + CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def'); + INSERT INTO ko DEFAULT VALUES; + } + execsql { PRAGMA wal_checkpoint } +} {} +do_test pager1-22.2.1 { + testvfs tv -default 1 + tv filter xSync + tv script xSyncCb + proc xSyncCb {args} {incr ::synccount} + set ::synccount 0 + sqlite3 db test.db + execsql { + PRAGMA synchronous = off; + PRAGMA journal_mode = WAL; + INSERT INTO ko DEFAULT VALUES; + } + execsql { PRAGMA wal_checkpoint } + set synccount +} {0} +db close +tv delete + +#------------------------------------------------------------------------- +# Tests for changing journal mode. +# +# pager1-23.1.*: Test that when changing from PERSIST to DELETE mode, +# the journal file is deleted. +# +# pager1-23.2.*: Same test as above, but while a shared lock is held +# on the database file. +# +# pager1-23.3.*: Same test as above, but while a reserved lock is held +# on the database file. +# +# pager1-23.4.*: And, for fun, while holding an exclusive lock. +# +# pager1-23.5.*: Try to set various different journal modes with an +# in-memory database (only MEMORY and OFF should work). +# +do_test pager1-23.1.1 { + faultsim_delete_and_reopen + execsql { + PRAGMA journal_mode = PERSIST; + CREATE TABLE t1(a, b); + } + file exists test.db-journal +} {1} +do_test pager1-23.1.2 { + execsql { PRAGMA journal_mode = DELETE } + file exists test.db-journal +} {0} + +do_test pager1-23.2.1 { + execsql { + PRAGMA journal_mode = PERSIST; + INSERT INTO t1 VALUES('Canberra', 'ACT'); + } + db eval { SELECT * FROM t1 } { + db eval { PRAGMA journal_mode = DELETE } + } + execsql { PRAGMA journal_mode } +} {delete} +do_test pager1-23.2.2 { + file exists test.db-journal +} {0} + +do_test pager1-23.3.1 { + execsql { + PRAGMA journal_mode = PERSIST; + INSERT INTO t1 VALUES('Darwin', 'NT'); + BEGIN IMMEDIATE; + } + db eval { PRAGMA journal_mode = DELETE } + execsql { PRAGMA journal_mode } +} {delete} +do_test pager1-23.3.2 { + file exists test.db-journal +} {0} +do_test pager1-23.3.3 { + execsql COMMIT +} {} + +do_test pager1-23.4.1 { + execsql { + PRAGMA journal_mode = PERSIST; + INSERT INTO t1 VALUES('Adelaide', 'SA'); + BEGIN EXCLUSIVE; + } + db eval { PRAGMA journal_mode = DELETE } + execsql { PRAGMA journal_mode } +} {delete} +do_test pager1-23.4.2 { + file exists test.db-journal +} {0} +do_test pager1-23.4.3 { + execsql COMMIT +} {} + +do_test pager1-23.5.1 { + faultsim_delete_and_reopen + sqlite3 db :memory: +} {} +foreach {tn mode possible} { + 2 off 1 + 3 memory 1 + 4 persist 0 + 5 delete 0 + 6 wal 0 + 7 truncate 0 +} { + do_test pager1-23.5.$tn.1 { + execsql "PRAGMA journal_mode = off" + execsql "PRAGMA journal_mode = $mode" + } [if $possible {list $mode} {list off}] + do_test pager1-23.5.$tn.2 { + execsql "PRAGMA journal_mode = memory" + execsql "PRAGMA journal_mode = $mode" + } [if $possible {list $mode} {list memory}] +} +do_test pager1-23.8.1 { + execsql {PRAGMA locking_mode = normal} +} {exclusive} +do_test pager1-23.8.2 { + execsql {PRAGMA locking_mode = exclusive} +} {exclusive} +do_test pager1-23.8.3 { + execsql {PRAGMA locking_mode} +} {exclusive} +do_test pager1-23.8.4 { + execsql {PRAGMA main.locking_mode} +} {exclusive} + finish_test diff --git a/test/pagerfault.test b/test/pagerfault.test index 7e470bebfc..ae1867c4bb 100644 --- a/test/pagerfault.test +++ b/test/pagerfault.test @@ -614,8 +614,6 @@ do_faultsim_test pagerfault-13 -prep { faultsim_test_result {0 {}} } -} - #--------------------------------------------------------------------------- # Test fault injection into a small backup operation. @@ -712,5 +710,201 @@ do_faultsim_test pagerfault-16 -prep { } +#------------------------------------------------------------------------- +# Test fault injection while changing into and out of WAL mode. +# +do_test pagerfault-17-pre1 { + faultsim_delete_and_reopen + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(1862, 'Botha'); + INSERT INTO t1 VALUES(1870, 'Smuts'); + INSERT INTO t1 VALUES(1866, 'Hertzog'); + } + faultsim_save_and_close +} {} +do_faultsim_test pagerfault-17a -prep { + faultsim_restore_and_reopen +} -body { + execsql { + PRAGMA journal_mode = wal; + PRAGMA journal_mode = delete; + } +} -test { + faultsim_test_result {0 {wal delete}} + faultsim_integrity_check +} +do_faultsim_test pagerfault-17b -prep { + faultsim_restore_and_reopen + execsql { PRAGMA synchronous = OFF } +} -body { + execsql { + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(22, 'Clarke'); + PRAGMA journal_mode = delete; + } +} -test { + faultsim_test_result {0 {wal delete}} + faultsim_integrity_check +} +do_faultsim_test pagerfault-17c -prep { + faultsim_restore_and_reopen + execsql { + PRAGMA locking_mode = exclusive; + PRAGMA journal_mode = wal; + } +} -body { + execsql { PRAGMA journal_mode = delete } +} -test { + faultsim_test_result {0 delete} + faultsim_integrity_check +} +do_faultsim_test pagerfault-17d -prep { + faultsim_restore_and_reopen + sqlite3 db2 test.db + execsql { PRAGMA journal_mode = delete } + execsql { PRAGMA journal_mode = wal } + execsql { INSERT INTO t1 VALUES(99, 'Bradman') } db2 +} -body { + execsql { PRAGMA journal_mode = delete } +} -test { + faultsim_test_result {1 {database is locked}} + faultsim_integrity_check +} +do_faultsim_test pagerfault-17e -prep { + faultsim_restore_and_reopen + sqlite3 db2 test.db + execsql { PRAGMA journal_mode = delete } + execsql { PRAGMA journal_mode = wal } + set ::chan [launch_testfixture] + testfixture $::chan { + sqlite3 db test.db + db eval { INSERT INTO t1 VALUES(101, 'Latham') } + } + catch { testfixture $::chan sqlite_abort } + catch { close $::chan } +} -body { + execsql { PRAGMA journal_mode = delete } +} -test { + faultsim_test_result {0 delete} + faultsim_integrity_check +} + +#------------------------------------------------------------------------- +# Test fault-injection when changing from journal_mode=persist to +# journal_mode=delete (this involves deleting the journal file). +# +do_test pagerfault-18-pre1 { + faultsim_delete_and_reopen + execsql { + CREATE TABLE qq(x); + INSERT INTO qq VALUES('Herbert'); + INSERT INTO qq VALUES('Macalister'); + INSERT INTO qq VALUES('Mackenzie'); + INSERT INTO qq VALUES('Lilley'); + INSERT INTO qq VALUES('Palmer'); + } + faultsim_save_and_close +} {} +do_faultsim_test pagerfault-18 -prep { + faultsim_restore_and_reopen + execsql { + PRAGMA journal_mode = PERSIST; + INSERT INTO qq VALUES('Beatty'); + } +} -body { + execsql { PRAGMA journal_mode = delete } +} -test { + faultsim_test_result {0 delete} + faultsim_integrity_check +} + +} + +do_faultsim_test pagerfault-19a -prep { + sqlite3 db :memory: + db func a_string a_string + execsql { + PRAGMA auto_vacuum = FULL; + BEGIN; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(a_string(5000), a_string(6000)); + COMMIT; + } +} -body { + execsql { + CREATE TABLE t2(a, b); + INSERT INTO t2 SELECT * FROM t1; + DELETE FROM t1; + } +} -test { + faultsim_test_result {0 {}} +} + +do_test pagerfault-19-pre1 { + faultsim_delete_and_reopen + execsql { + PRAGMA auto_vacuum = FULL; + CREATE TABLE t1(x); INSERT INTO t1 VALUES(1); + CREATE TABLE t2(x); INSERT INTO t2 VALUES(2); + CREATE TABLE t3(x); INSERT INTO t3 VALUES(3); + CREATE TABLE t4(x); INSERT INTO t4 VALUES(4); + CREATE TABLE t5(x); INSERT INTO t5 VALUES(5); + CREATE TABLE t6(x); INSERT INTO t6 VALUES(6); + } + faultsim_save_and_close +} {} +do_faultsim_test pagerfault-19b -prep { + faultsim_restore_and_reopen +} -body { + execsql { + BEGIN; + UPDATE t4 SET x = x+1; + UPDATE t6 SET x = x+1; + SAVEPOINT one; + UPDATE t3 SET x = x+1; + SAVEPOINT two; + DROP TABLE t2; + ROLLBACK TO one; + COMMIT; + SELECT * FROM t3; + SELECT * FROM t4; + SELECT * FROM t6; + } +} -test { + faultsim_test_result {0 {3 5 7}} +} + +do_test pagerfault-20-pre1 { + faultsim_delete_and_reopen + db func a_string a_string + execsql { + CREATE TABLE x1(x, y, z, PRIMARY KEY(y, z)); + INSERT INTO x1 VALUES(a_string(400), a_string(500), a_string(600)); + INSERT INTO x1 SELECT a_string(600), a_string(400), a_string(500) FROM x1; + INSERT INTO x1 SELECT a_string(500), a_string(600), a_string(400) FROM x1; + INSERT INTO x1 SELECT a_string(400), a_string(500), a_string(600) FROM x1; + INSERT INTO x1 SELECT a_string(600), a_string(400), a_string(500) FROM x1; + INSERT INTO x1 SELECT a_string(500), a_string(600), a_string(400) FROM x1; + INSERT INTO x1 SELECT a_string(400), a_string(500), a_string(600) FROM x1; + } + faultsim_save_and_close +} {} +do_faultsim_test pagerfault-20 -prep { + faultsim_restore_and_reopen + db func a_string a_string +} -body { + execsql { + BEGIN; + UPDATE x1 SET z = a_string(300); + DELETE FROM x1 WHERE rowid<32; + COMMIT; + } +} -test { + faultsim_test_result {0 {}} + faultsim_integrity_check + set nRow [db one {SELECT count(*) FROM x1}] + if {$nRow!=33 && $nRow!=64} {error "Wrong number of rows $nRow"} +} finish_test