From: dan Date: Mon, 16 Feb 2015 11:48:34 +0000 (+0000) Subject: Add further tests and fixes for ota. X-Git-Tag: version-3.8.11~252^2~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5902352fca48cc51c5c7845688eb0242ff938cf5;p=thirdparty%2Fsqlite.git Add further tests and fixes for ota. FossilOrigin-Name: 62dc1fffc38cb157c15105098749b6dd0198eb84 --- diff --git a/ext/ota/ota11.test b/ext/ota/ota11.test new file mode 100644 index 0000000000..8e832495db --- /dev/null +++ b/ext/ota/ota11.test @@ -0,0 +1,85 @@ +# 2015 February 16 +# +# 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. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +set ::testprefix ota11 + + +#-------------------------------------------------------------------- +# Test that the xAccess() method of an ota vfs handles queries other +# than SQLITE_ACCESS_EXISTS correctly. The test code below causes +# SQLite to call xAccess(SQLITE_ACCESS_READWRITE) on the directory +# path argument passed to "PRAGMA temp_store_directory". +# +do_test 1.1 { + sqlite3ota_create_vfs -default ota "" + reset_db + catchsql { PRAGMA temp_store_directory = '/no/such/directory' } +} {1 {not a writable directory}} + +do_test 1.2 { + catchsql " PRAGMA temp_store_directory = '[pwd]' " +} {0 {}} + +do_test 1.3 { + catchsql " PRAGMA temp_store_directory = '' " +} {0 {}} + +do_test 1.4 { + db close + sqlite3ota_destroy_vfs ota +} {} + +#-------------------------------------------------------------------- +# Try to trick ota into operating on a database opened in wal mode. +# +reset_db +do_execsql_test 2.1 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + PRAGMA journal_mode = 'wal'; + CREATE TABLE t2(d PRIMARY KEY, e, f); +} {wal} + +do_test 2.2 { + db_save + db close + + forcedelete ota.db + sqlite3 dbo ota.db + dbo eval { + CREATE TABLE data_t1(a, b, c, ota_control); + INSERT INTO data_t1 VALUES(4, 5, 6, 0); + INSERT INTO data_t1 VALUES(7, 8, 9, 0); + } + dbo close + + db_restore + hexio_write test.db 18 0101 + file exists test.db-wal +} {1} + +breakpoint +do_test 2.3 { + sqlite3ota ota test.db ota.db + ota step +} {SQLITE_ERROR} + +do_test 2.4 { + list [catch {ota close} msg] $msg +} {1 {SQLITE_ERROR - cannot update wal mode database}} + +finish_test + diff --git a/ext/ota/ota3.test b/ext/ota/ota3.test index 74dba1f166..da29454b9a 100644 --- a/ext/ota/ota3.test +++ b/ext/ota/ota3.test @@ -135,5 +135,23 @@ do_execsql_test 2.5 { PRAGMA integrity_check; } {ok} + +#------------------------------------------------------------------------- +# Test that sqlite3ota_create_vfs() returns an error if the requested +# parent VFS is unknown. +# +# And that nothing disasterous happens if a VFS name passed to +# sqlite3ota_destroy_vfs() is unknown or not an OTA vfs. +# +do_test 3.1 { + list [catch {sqlite3ota_create_vfs xyz nosuchparent} msg] $msg +} {1 SQLITE_NOTFOUND} + +do_test 3.2 { + sqlite3ota_destroy_vfs nosuchvfs + sqlite3ota_destroy_vfs unix + sqlite3ota_destroy_vfs win32 +} {} + finish_test diff --git a/ext/ota/otaA.test b/ext/ota/otaA.test index 9ba9606e30..c76609035a 100644 --- a/ext/ota/otaA.test +++ b/ext/ota/otaA.test @@ -69,6 +69,7 @@ do_test 2.1 { sqlite3 db test.db db eval {PRAGMA journal_mode = wal} db close + breakpoint sqlite3ota ota test.db ota.db ota step } {SQLITE_ERROR} diff --git a/ext/ota/sqlite3ota.c b/ext/ota/sqlite3ota.c index 01607f1f15..eea04b0510 100644 --- a/ext/ota/sqlite3ota.c +++ b/ext/ota/sqlite3ota.c @@ -113,6 +113,7 @@ struct OtaState { i64 iWalCksum; int nRow; i64 nProgress; + u32 iCookie; }; /* @@ -235,9 +236,6 @@ struct ota_file { }; -static void otaCreateVfs(sqlite3ota*, const char*); -static void otaDeleteVfs(sqlite3ota*); - /* ** Prepare the SQL statement in buffer zSql against database handle db. ** If successful, set *ppStmt to point to the new statement and return @@ -2069,16 +2067,7 @@ static OtaState *otaLoadState(sqlite3ota *p){ break; case OTA_STATE_COOKIE: - /* At this point (p->iCookie) contains the value of the change-counter - ** cookie (the thing that gets incremented when a transaction is - ** committed in rollback mode) currently stored on page 1 of the - ** database file. */ - if( pRet->eStage==OTA_STAGE_OAL - && p->pTargetFd->iCookie!=(u32)sqlite3_column_int64(pStmt, 1) - ){ - rc = SQLITE_BUSY; - p->zErrmsg = sqlite3_mprintf("database modified during ota update"); - } + pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1); break; default: @@ -2138,6 +2127,28 @@ static void otaDeleteOalFile(sqlite3ota *p){ sqlite3_free(zOal); } +static void otaCreateVfs(sqlite3ota *p){ + int rnd; + char zRnd[64]; + + assert( p->rc==SQLITE_OK ); + sqlite3_randomness(sizeof(int), (void*)&rnd); + sprintf(zRnd, "ota_vfs_%d", rnd); + p->rc = sqlite3ota_create_vfs(zRnd, 0); + if( p->rc==SQLITE_OK ){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd); + assert( pVfs ); + p->zVfsName = pVfs->zName; + } +} + +static void otaDeleteVfs(sqlite3ota *p){ + if( p->zVfsName ){ + sqlite3ota_destroy_vfs(p->zVfsName); + p->zVfsName = 0; + } +} + /* ** Open and return a new OTA handle. */ @@ -2152,7 +2163,7 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){ /* Create the custom VFS. */ memset(p, 0, sizeof(sqlite3ota)); - otaCreateVfs(p, 0); + otaCreateVfs(p); /* Open the target database */ if( p->rc==SQLITE_OK ){ @@ -2173,15 +2184,18 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){ ** function, on the off chance that the target is a wal database for ** which the first page of the db file has been overwritten by garbage ** during an earlier failed checkpoint. */ +#if 0 if( p->rc==SQLITE_OK && p->pTargetFd->iWriteVer>1 ){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("cannot update wal mode database"); } +#endif if( p->rc==SQLITE_OK ){ pState = otaLoadState(p); assert( pState || p->rc!=SQLITE_OK ); if( p->rc==SQLITE_OK ){ + if( pState->eStage==0 ){ otaDeleteOalFile(p); p->eStage = OTA_STAGE_OAL; @@ -2195,6 +2209,21 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){ if( p->rc==SQLITE_OK ){ if( p->eStage==OTA_STAGE_OAL ){ + if( p->pTargetFd->pWalFd ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("cannot update wal mode database"); + } + + /* At this point (pTargetFd->iCookie) contains the value of the + ** change-counter cookie (the thing that gets incremented when a + ** transaction is committed in rollback mode) currently stored on + ** page 1 of the database file. */ + else if( pState->eStage==OTA_STAGE_OAL + && p->pTargetFd->iCookie!=pState->iCookie + ){ + p->rc = SQLITE_BUSY; + p->zErrmsg = sqlite3_mprintf("database modified during ota update"); + } /* Open the transaction */ if( p->rc==SQLITE_OK ){ @@ -2357,6 +2386,7 @@ static int otaVfsClose(sqlite3_file *pFile){ for(pp=&p->pOtaVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext)); *pp = p->pMainNext; sqlite3_mutex_leave(p->pOtaVfs->mutex); + p->pReal->pMethods->xShmUnmap(p->pReal, 0); } /* Close the underlying file handle */ @@ -2911,7 +2941,7 @@ static int otaVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ void sqlite3ota_destroy_vfs(const char *zName){ sqlite3_vfs *pVfs = sqlite3_vfs_find(zName); - if( pVfs ){ + if( pVfs && pVfs->xOpen==otaVfsOpen ){ sqlite3_vfs_unregister(pVfs); sqlite3_free(pVfs); } @@ -2945,67 +2975,41 @@ int sqlite3ota_create_vfs(const char *zName, const char *zParent){ 0, 0, 0 /* Unimplemented version 3 methods */ }; - sqlite3_vfs *pParent; /* Parent VFS */ ota_vfs *pNew = 0; /* Newly allocated VFS */ int nName; int rc = SQLITE_OK; + int nByte; nName = strlen(zName); - pParent = sqlite3_vfs_find(zParent); - if( pParent==0 ){ - rc = SQLITE_NOTFOUND; + nByte = sizeof(ota_vfs) + nName + 1; + pNew = (ota_vfs*)sqlite3_malloc(nByte); + if( pNew==0 ){ + rc = SQLITE_NOMEM; }else{ - int nByte = sizeof(ota_vfs) + nName + 1; - pNew = (ota_vfs*)sqlite3_malloc(nByte); - if( pNew==0 ){ - rc = SQLITE_NOMEM; + sqlite3_vfs *pParent; /* Parent VFS */ + memset(pNew, 0, nByte); + pParent = sqlite3_vfs_find(zParent); + if( pParent==0 ){ + rc = SQLITE_NOTFOUND; }else{ - memset(pNew, 0, nByte); - } - } - - if( rc==SQLITE_OK ){ - char *zSpace; - memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs)); - pNew->base.mxPathname = pParent->mxPathname; - pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile; - pNew->pRealVfs = pParent; + char *zSpace; + memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs)); + pNew->base.mxPathname = pParent->mxPathname; + pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile; + pNew->pRealVfs = pParent; - pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]); - memcpy(zSpace, zName, nName); + pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]); + memcpy(zSpace, zName, nName); - /* Register the new VFS (not as the default) */ - rc = sqlite3_vfs_register(&pNew->base, 0); - if( rc ){ - sqlite3_free(pNew); + /* Register the new VFS (not as the default) */ + rc = sqlite3_vfs_register(&pNew->base, 0); } } - return rc; -} - -static void otaCreateVfs(sqlite3ota *p, const char *zParent){ - int rnd; - char zRnd[64]; - - assert( p->rc==SQLITE_OK ); - sqlite3_randomness(sizeof(int), (void*)&rnd); - sprintf(zRnd, "ota_vfs_%d", rnd); - p->rc = sqlite3ota_create_vfs(zRnd, zParent); - if( p->rc==SQLITE_NOTFOUND ){ - p->zErrmsg = sqlite3_mprintf("no such vfs: %s", zParent); - }else if( p->rc==SQLITE_OK ){ - sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd); - assert( pVfs ); - p->zVfsName = pVfs->zName; - } -} - -static void otaDeleteVfs(sqlite3ota *p){ - if( p->zVfsName ){ - sqlite3ota_destroy_vfs(p->zVfsName); - p->zVfsName = 0; + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew); } + return rc; } diff --git a/manifest b/manifest index e8f6d9d11e..facf00eb48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\stcl\stest\scode\sfrom\ssqlite3ota.c\sto\snew\sfile\sext/ota/test_ota.c. -D 2015-02-16T06:27:37.241 +C Add\sfurther\stests\sand\sfixes\sfor\sota. +D 2015-02-16T11:48:34.819 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -127,15 +127,16 @@ F ext/ota/README.txt 2ce4ffbb0aaa6731b041c27a7359f9a5f1c69152 F ext/ota/ota.c c11a85af71dccc45976622fe7a51169a481caa91 F ext/ota/ota1.test dee5b852353642a243e0bf414d332b1bccd5324f F ext/ota/ota10.test 85e0f6e7964db5007590c1b299e75211ed4240d4 -F ext/ota/ota3.test a77efbce7723332eb688d2b28bf18204fc9614d7 +F ext/ota/ota11.test 44e9ebdc1d9c23214c739f122f2b36e169e515aa +F ext/ota/ota3.test cd654ef16fc6b3d3596894ee3f3b8fd821b969f5 F ext/ota/ota5.test ad0799daf8923ddebffe75ae8c5504ca90b7fadb F ext/ota/ota6.test 40996b7716dee72a6c5d28c3bee436717a438d3d F ext/ota/ota7.test 1fe2c5761705374530e29f70c39693076028221a F ext/ota/ota8.test cd70e63a0c29c45c0906692827deafa34638feda F ext/ota/ota9.test d3eee95dd836824d07a22e5efcdb7bf6e869358b -F ext/ota/otaA.test 95566a8d193113867b960eadf85b310937f2fe03 +F ext/ota/otaA.test ef4bfa8cfd4ed814ae86f7457b64aa2f18c90171 F ext/ota/otafault.test 508ba87c83d632670ac0f94371a465d4bb4d49dd -F ext/ota/sqlite3ota.c 79874bc6f31a514aebd17ab24d31e7c567e6225e +F ext/ota/sqlite3ota.c f2ea3fe9d7fceec5efc1ad62b8bf07ec607f99c5 F ext/ota/sqlite3ota.h 1cc7201086fe65a36957740381485a24738c4077 F ext/ota/test_ota.c 5dd58e4e6eb3ae7b471566616d44b701971bce88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1255,7 +1256,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b64a11a754dc56f3406d3b703531ebe9e4af4908 -R 8813c4f37af98778b18f1d2e1e748912 +P f20779a6e890ba73bfaa904cefcf3a029b01fed4 +R d9098c0831f1564055344cfb128a3e0f U dan -Z ac67e9a36714c8c694cc168f5b99c0ce +Z f0ac85428b81638540d3d3b58c8f458b diff --git a/manifest.uuid b/manifest.uuid index 1b07b3af8e..a394a31cbd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f20779a6e890ba73bfaa904cefcf3a029b01fed4 \ No newline at end of file +62dc1fffc38cb157c15105098749b6dd0198eb84 \ No newline at end of file