From: dan Date: Wed, 18 Feb 2015 20:16:15 +0000 (+0000) Subject: Add ota tests to increase code coverage. Fix some minor issues in error handling... X-Git-Tag: version-3.8.11~252^2~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3e031ce85c51ac141522ca23672b4a975f540cb;p=thirdparty%2Fsqlite.git Add ota tests to increase code coverage. Fix some minor issues in error handling within the ota code. FossilOrigin-Name: 2b10c5d2b8b8b535d3dec0c68a777db16268e1e5 --- diff --git a/ext/ota/ota1.test b/ext/ota/ota1.test index 0184875f49..d0e7890ed2 100644 --- a/ext/ota/ota1.test +++ b/ext/ota/ota1.test @@ -527,6 +527,24 @@ foreach {tn3 create_vfs destroy_vfs} { CREATE TABLE ota.data_t1(a, b, ota_control); INSERT INTO ota.data_t1 VALUES(1, 2, 'x.x'); } {SQLITE_ERROR - invalid ota_control value} + + 7 { + CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID; + CREATE TABLE ota.data_t1(a, b, ota_control); + INSERT INTO ota.data_t1 VALUES(1, 2, NULL); + } {SQLITE_ERROR - invalid ota_control value} + + 8 { + CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID; + CREATE TABLE ota.data_t1(a, b, ota_control); + INSERT INTO ota.data_t1 VALUES(1, 2, 4); + } {SQLITE_ERROR - invalid ota_control value} + + 9 { + CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID; + CREATE TABLE ota.data_t1(a, b, ota_control); + INSERT INTO ota.data_t1 VALUES(1, 2, 2); + } {SQLITE_ERROR - invalid ota_control value} } { reset_db diff --git a/ext/ota/ota11.test b/ext/ota/ota11.test index 19f9671cd2..6bd233c0c0 100644 --- a/ext/ota/ota11.test +++ b/ext/ota/ota11.test @@ -148,18 +148,51 @@ do_test 4.4 { ota close } {SQLITE_DONE} +do_test 4.5.1 { + sqlite3 dbo ota.db + dbo eval { INSERT INTO ota_state VALUES(100, 100) } + dbo close + sqlite3ota ota test.db ota.db + ota step +} {SQLITE_CORRUPT} +do_test 4.5.2 { + list [catch {ota close} msg] $msg +} {1 SQLITE_CORRUPT} +do_test 4.5.3 { + sqlite3 dbo ota.db + dbo eval { DELETE FROM ota_state WHERE k = 100 } + dbo close +} {} + # Also, check that an invalid state value in the ota_state table is # detected and reported as corruption. -do_test 4.5 { +do_test 4.6.1 { sqlite3 dbo ota.db - dbo eval { UPDATE ota_state SET v = -1 WHERE k = 1 } + dbo eval { UPDATE ota_state SET v = v*-1 WHERE k = 1 } dbo close sqlite3ota ota test.db ota.db ota step } {SQLITE_CORRUPT} -do_test 4.6 { +do_test 4.6.2 { list [catch {ota close} msg] $msg } {1 SQLITE_CORRUPT} +do_test 4.6.3 { + sqlite3 dbo ota.db + dbo eval { UPDATE ota_state SET v = v*-1 WHERE k = 1 } + dbo close +} {} + +do_test 4.7.1 { + sqlite3 dbo ota.db + dbo eval { UPDATE ota_state SET v = 1 WHERE k = 1 } + dbo eval { UPDATE ota_state SET v = 'nosuchtable' WHERE k = 2 } + dbo close + sqlite3ota ota test.db ota.db + ota step +} {SQLITE_ERROR} +do_test 4.7.2 { + list [catch {ota close} msg] $msg +} {1 {SQLITE_ERROR - ota_state mismatch error}} finish_test diff --git a/ext/ota/ota3.test b/ext/ota/ota3.test index 6e1645edda..0dae31c190 100644 --- a/ext/ota/ota3.test +++ b/ext/ota/ota3.test @@ -170,6 +170,36 @@ do_test 4.2 { } {1 {SQLITE_ERROR - ota vfs not found}} tvfs delete +#------------------------------------------------------------------------- +# Test a large ota update to ensure that wal_autocheckpoint does not get +# in the way. +# +forcedelete ota.db +reset_db +do_execsql_test 5.1 { + CREATE TABLE x1(a, b, c, PRIMARY KEY(a)) WITHOUT ROWID; + CREATE INDEX i1 ON x1(a); + + ATTACH 'ota.db' AS ota; + CREATE TABLE ota.data_x1(a, b, c, ota_control); + WITH s(a, b, c) AS ( + SELECT randomblob(300), randomblob(300), 1 + UNION ALL + SELECT randomblob(300), randomblob(300), c+1 FROM s WHERE c<2000 + ) + INSERT INTO data_x1 SELECT a, b, c, 0 FROM s; +} + +do_test 5.2 { + sqlite3ota ota test.db ota.db + while {[ota step]=="SQLITE_OK" && [file exists test.db-wal]==0} {} + ota close +} {SQLITE_OK} + +do_test 5.3 { + expr {[file size test.db-wal] > (1024 * 1200)} +} 1 + finish_test diff --git a/ext/ota/otafault.test b/ext/ota/otafault.test index d49f9d58f3..de6939a556 100644 --- a/ext/ota/otafault.test +++ b/ext/ota/otafault.test @@ -84,6 +84,17 @@ foreach {tn2 setup sql expect} { SELECT * FROM t1 ORDER BY a; } {A Z C G H I} + 5 { + CREATE TABLE t1(a, b, c); + CREATE INDEX t1c ON t1(c, b); + + CREATE TABLE ota.data_t1(a, b, c, ota_rowid, ota_control); + INSERT INTO data_t1 VALUES('a', 'b', 'c', 1, 0); + INSERT INTO data_t1 VALUES('d', 'e', 'f', '2', 0); + } { + SELECT * FROM t1 ORDER BY a; + } {a b c d e f} + } { catch {db close} forcedelete ota.db test.db @@ -118,6 +129,12 @@ foreach {tn2 setup sql expect} { {1 {SQLITE_ERROR - unable to open database: ota.db}} {1 {SQLITE_IOERR - unable to open database: ota.db}} } + + 3 shmerr-* { + {0 SQLITE_DONE} + {1 {SQLITE_IOERR - disk I/O error}} + {1 SQLITE_IOERR} + } } { catch {db close} diff --git a/ext/ota/sqlite3ota.c b/ext/ota/sqlite3ota.c index 0ef1954811..3f67535548 100644 --- a/ext/ota/sqlite3ota.c +++ b/ext/ota/sqlite3ota.c @@ -1640,7 +1640,8 @@ static int otaCaptureWalRead(sqlite3ota *pOta, i64 iOff, int iAmt){ u32 iFrame; if( pOta->mLock!=mReq ){ - return SQLITE_BUSY; + pOta->rc = SQLITE_BUSY; + return SQLITE_INTERNAL; } pOta->pgsz = iAmt; @@ -1667,18 +1668,17 @@ static int otaCaptureDbWrite(sqlite3ota *pOta, i64 iOff){ } static void otaCheckpointFrame(sqlite3ota *p, OtaFrame *pFrame){ - if( p->rc==SQLITE_OK ){ - sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; - sqlite3_file *pDb = p->pTargetFd->pReal; - i64 iOff; + sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; + sqlite3_file *pDb = p->pTargetFd->pReal; + i64 iOff; - iOff = (i64)(pFrame->iWalFrame-1) * (p->pgsz + 24) + 32 + 24; - p->rc = pWal->pMethods->xRead(pWal, p->aBuf, p->pgsz, iOff); - if( p->rc ) return; + assert( p->rc==SQLITE_OK ); + iOff = (i64)(pFrame->iWalFrame-1) * (p->pgsz + 24) + 32 + 24; + p->rc = pWal->pMethods->xRead(pWal, p->aBuf, p->pgsz, iOff); + if( p->rc ) return; - iOff = (i64)(pFrame->iDbPage-1) * p->pgsz; - p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff); - } + iOff = (i64)(pFrame->iDbPage-1) * p->pgsz; + p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff); } @@ -1686,12 +1686,11 @@ static void otaCheckpointFrame(sqlite3ota *p, OtaFrame *pFrame){ ** Take an EXCLUSIVE lock on the database file. */ static void otaLockDatabase(sqlite3ota *p){ + sqlite3_file *pReal = p->pTargetFd->pReal; + assert( p->rc==SQLITE_OK ); + p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED); if( p->rc==SQLITE_OK ){ - sqlite3_file *pReal = p->pTargetFd->pReal; - p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED); - if( p->rc==SQLITE_OK ){ - p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE); - } + p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE); } } @@ -1860,13 +1859,12 @@ static int otaStep(sqlite3ota *p){ goto step_out; } - if( eType==SQLITE_DELETE && pIter->zIdx==0 && pIter->abTblPk[i]==0 ){ + if( eType==OTA_DELETE && pIter->abTblPk[i]==0 ){ continue; } pVal = sqlite3_column_value(pIter->pSelect, i); p->rc = sqlite3_bind_value(pWriter, i+1, pVal); - if( p->rc==SQLITE_RANGE ) p->rc = SQLITE_OK; if( p->rc ) goto step_out; } if( pIter->zIdx==0 @@ -1887,9 +1885,10 @@ static int otaStep(sqlite3ota *p){ sqlite3_step(pWriter); p->rc = resetAndCollectError(pWriter, &p->zErrmsg); } - }else if( eType==OTA_UPDATE ){ + }else{ sqlite3_value *pVal; sqlite3_stmt *pUpdate = 0; + assert( eType==OTA_UPDATE ); otaGetUpdateStmt(p, pIter, zMask, &pUpdate); if( pUpdate ){ for(i=0; p->rc==SQLITE_OK && inCol; i++){ @@ -1912,9 +1911,6 @@ static int otaStep(sqlite3ota *p){ p->rc = resetAndCollectError(pUpdate, &p->zErrmsg); } } - }else{ - /* no-op */ - assert( eType==OTA_DELETE && pIter->zIdx ); } } @@ -1994,7 +1990,7 @@ int sqlite3ota_step(sqlite3ota *p){ switch( p->eStage ){ case OTA_STAGE_OAL: { OtaObjIter *pIter = &p->objiter; - while( p && p->rc==SQLITE_OK && pIter->zTbl ){ + while( p->rc==SQLITE_OK && pIter->zTbl ){ if( pIter->bCleanup ){ /* Clean up the ota_tmp_xxx table for the previous table. It @@ -2022,7 +2018,8 @@ int sqlite3ota_step(sqlite3ota *p){ otaObjIterNext(p, pIter); } - if( p->rc==SQLITE_OK && pIter->zTbl==0 ){ + if( p->rc==SQLITE_OK ){ + assert( pIter->zTbl==0 ); otaSaveState(p, OTA_STAGE_MOVE); otaIncrSchemaCookie(p); if( p->rc==SQLITE_OK ){ @@ -2042,32 +2039,33 @@ int sqlite3ota_step(sqlite3ota *p){ } case OTA_STAGE_CKPT: { - if( p->nStep>=p->nFrame ){ - sqlite3_file *pDb = p->pTargetFd->pReal; - - /* Sync the db file */ - p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL); - - /* Update nBackfill */ - if( p->rc==SQLITE_OK ){ - void volatile *ptr; - p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, &ptr); + if( p->rc==SQLITE_OK ){ + if( p->nStep>=p->nFrame ){ + sqlite3_file *pDb = p->pTargetFd->pReal; + + /* Sync the db file */ + p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL); + + /* Update nBackfill */ if( p->rc==SQLITE_OK ){ - ((u32*)ptr)[12] = p->iMaxFrame; + void volatile *ptr; + p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, &ptr); + if( p->rc==SQLITE_OK ){ + ((u32*)ptr)[12] = p->iMaxFrame; + } } + + if( p->rc==SQLITE_OK ){ + p->eStage = OTA_STAGE_DONE; + p->rc = SQLITE_DONE; + } + }else{ + OtaFrame *pFrame = &p->aFrame[p->nStep]; + otaCheckpointFrame(p, pFrame); + p->nStep++; } - - if( p->rc==SQLITE_OK ){ - p->eStage = OTA_STAGE_DONE; - p->rc = SQLITE_DONE; - } - }else{ - OtaFrame *pFrame = &p->aFrame[p->nStep]; - otaCheckpointFrame(p, pFrame); - p->nStep++; + p->nProgress++; } - - p->nProgress++; break; } @@ -2169,13 +2167,13 @@ static void otaLoadTransactionState(sqlite3ota *p, OtaState *pState){ int rc = SQLITE_OK; while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup - || otaStrCompare(pIter->zTbl, pState->zTbl) || otaStrCompare(pIter->zIdx, pState->zIdx) + || otaStrCompare(pIter->zTbl, pState->zTbl) )){ - rc = otaObjIterNext(p, &p->objiter); + rc = otaObjIterNext(p, pIter); } - if( rc==SQLITE_OK && !p->objiter.zTbl ){ + if( rc==SQLITE_OK && !pIter->zTbl ){ rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("ota_state mismatch error"); } @@ -2293,9 +2291,7 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){ if( p->eStage==OTA_STAGE_OAL ){ /* Open the transaction */ - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(p->db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); - } + p->rc = sqlite3_exec(p->db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); /* Point the object iterator at the first object */ if( p->rc==SQLITE_OK ){ diff --git a/manifest b/manifest index 48056fe9f6..e5db2328cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sOTA\supdates\sin\sthe\spresence\sof\sdatabase\sreaders. -D 2015-02-18T17:40:05.856 +C Add\sota\stests\sto\sincrease\scode\scoverage.\sFix\ssome\sminor\sissues\sin\serror\shandling\swithin\sthe\sota\scode. +D 2015-02-18T20:16:15.838 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,18 +125,18 @@ F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/ota/README.txt 2ce4ffbb0aaa6731b041c27a7359f9a5f1c69152 F ext/ota/ota.c c11a85af71dccc45976622fe7a51169a481caa91 -F ext/ota/ota1.test 88a47987dc12780c23d9efbeb0e9416c838eb1f6 +F ext/ota/ota1.test ba408c5e777c320ef72f328e20cd2ae2a8888cda F ext/ota/ota10.test 85e0f6e7964db5007590c1b299e75211ed4240d4 -F ext/ota/ota11.test 0a0c56b9474f82097018a8f399172417737c64c9 -F ext/ota/ota3.test 59fc88cf9749156c8a0b3ed9210b72a6af3f29d0 +F ext/ota/ota11.test 2f606cd2b4af260a86b549e91b9f395450fc75cb +F ext/ota/ota3.test 1f12eba0b69ef12a45e5c17bb1bebd13211663e7 F ext/ota/ota5.test ad0799daf8923ddebffe75ae8c5504ca90b7fadb F ext/ota/ota6.test 3bde7f69a894748b27206b6753462ec3b75b6bb6 F ext/ota/ota7.test 1fe2c5761705374530e29f70c39693076028221a F ext/ota/ota8.test cd70e63a0c29c45c0906692827deafa34638feda F ext/ota/ota9.test d3eee95dd836824d07a22e5efcdb7bf6e869358b F ext/ota/otaA.test ef4bfa8cfd4ed814ae86f7457b64aa2f18c90171 -F ext/ota/otafault.test c17e0297b4d2b83115fa733b614cf4883cd826f2 -F ext/ota/sqlite3ota.c f04e79519f275ae932ad3573a089e2ef08552a78 +F ext/ota/otafault.test 8c43586c2b96ca16bbce00b5d7e7d67316126db8 +F ext/ota/sqlite3ota.c 981bbfae01063fa176a2851e4564f89cc53efe96 F ext/ota/sqlite3ota.h 1cc7201086fe65a36957740381485a24738c4077 F ext/ota/test_ota.c 5dd58e4e6eb3ae7b471566616d44b701971bce88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1256,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 a438fa6c9ad2fb1d78ac747172d07455d6381387 -R 4b928e3e4481330de038aee8bbb8f63e +P 144bb29ffcbfe96dc10c0224113e73a80e89314b +R 651c92e3909a9521816fc3a304b913d3 U dan -Z 71e8a5928d01f269472bf7adff7d46be +Z 24ae6a68f15f30a6afab37fb8335827c diff --git a/manifest.uuid b/manifest.uuid index 4a97b0bd4d..e13ec507eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -144bb29ffcbfe96dc10c0224113e73a80e89314b \ No newline at end of file +2b10c5d2b8b8b535d3dec0c68a777db16268e1e5 \ No newline at end of file