Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improve the os_test.c module. (CVS 1657) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ecdb93d3c92e34f7d85aa2fd70388066 |
User & Date: | danielk1977 2004-06-22 12:18:32.000 |
Context
2004-06-22
| ||
12:30 | Add os_tst.c to the TESTSRC macro in main.mk. (CVS 1658) (check-in: d0def160e5 user: drh tags: trunk) | |
12:18 | Improve the os_test.c module. (CVS 1657) (check-in: ecdb93d3c9 user: danielk1977 tags: trunk) | |
12:13 | Patch around compilers that do not support "long long int". (CVS 1656) (check-in: d98b1502e2 user: drh tags: trunk) | |
Changes
Changes to main.mk.
︙ | ︙ | |||
355 356 357 358 359 360 361 | testfixture$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -DSQLITE_TEST=1 -o testfixture$(EXE) \ $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) testfixturex: $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) | | | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | testfixture$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -DSQLITE_TEST=1 -o testfixture$(EXE) \ $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) testfixturex: $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 -o testfixturex \ $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) fulltest: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/all.test test: testfixture$(EXE) sqlite3$(EXE) |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.231 2004/06/22 12:18:32 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
961 962 963 964 965 966 967 | /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the database text encoding of name zName, length nName. ** If the collation sequence */ static void callCollNeeded(sqlite *db, const char *zName, int nName){ | < | > | 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 | /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the database text encoding of name zName, length nName. ** If the collation sequence */ static void callCollNeeded(sqlite *db, const char *zName, int nName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); if( nName<0 ) nName = strlen(zName); if( db->xCollNeeded ){ char *zExternal = sqliteStrNDup(zName, nName); if( !zExternal ) return; db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); sqliteFree(zExternal); } if( db->xCollNeeded16 ){ char const *zExternal; sqlite3_value *pTmp = sqlite3GetTransientValue(db); sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); if( !zExternal ) return; db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); } } |
︙ | ︙ |
Changes to src/os_test.c.
︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 100 | int i; sqlite3OsEnterMutex(); i = crashseed_var; sqlite3OsLeaveMutex(); return i; } /* ** Initialise the os_test.c specific fields of pFile. */ | > > | > > > > > > > > > > > > > > > > > > > > > > > | | | 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 | int i; sqlite3OsEnterMutex(); i = crashseed_var; sqlite3OsLeaveMutex(); return i; } static OsTestFile *pAllFiles = 0; /* ** Initialise the os_test.c specific fields of pFile. */ static void initFile(OsFile *id){ OsTestFile *pFile = (OsTestFile *)sqliteMalloc(sizeof(OsTestFile)); pFile->nMaxWrite = 0; pFile->nBlk = 0; pFile->apBlk = 0; *id = pFile; pFile->pNext = pAllFiles; pAllFiles = pFile; } /* ** Undo the work done by initFile. Delete the OsTestFile structure ** and unlink the structure from the pAllFiles list. */ static void closeFile(OsFile *id){ OsTestFile *pFile = *id; if( pFile==pAllFiles ){ pAllFiles = pFile->pNext; }else{ OsTestFile *p; for(p=pAllFiles; p->pNext!=pFile; p=p->pNext ){ assert( p ); } p->pNext = pFile->pNext; } sqliteFree(pFile); *id = 0; } /* ** Return the current seek offset from the start of the file. This ** is unix-only code. */ static off_t osTell(OsTestFile *pFile){ return lseek(pFile->fd.h, 0, SEEK_CUR); } /* ** Load block 'blk' into the cache of pFile. */ static int cacheBlock(OsTestFile *pFile, int blk){ if( blk>=pFile->nBlk ){ int n = ((pFile->nBlk * 2) + 100 + blk); pFile->apBlk = (u8 **)sqliteRealloc(pFile->apBlk, n * sizeof(u8*)); if( !pFile->apBlk ) return SQLITE_NOMEM; pFile->nBlk = n; } |
︙ | ︙ | |||
149 150 151 152 153 154 155 | return SQLITE_OK; } /* ** Write the cache of pFile to disk. If crash is non-zero, randomly ** skip blocks when writing. The cache is deleted before returning. */ | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | return SQLITE_OK; } /* ** Write the cache of pFile to disk. If crash is non-zero, randomly ** skip blocks when writing. The cache is deleted before returning. */ static int writeCache2(OsTestFile *pFile, int crash){ int i; int nMax = pFile->nMaxWrite; off_t offset; int rc = SQLITE_OK; offset = osTell(pFile); for(i=0; i<pFile->nBlk; i++){ |
︙ | ︙ | |||
193 194 195 196 197 198 199 | } return rc; } /* ** Write the cache to disk. */ | | | > | | > | > > | > | | > > > | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 | } return rc; } /* ** Write the cache to disk. */ static int writeCache(OsTestFile *pFile){ int cs = crashseed(); if( cs==1 ){ /* FIX ME: writeCache2() should be called on all open files here. */ OsTestFile *pFile; for(pFile=pAllFiles; pFile; pFile=pFile->pNext){ writeCache2(pFile, 1); } exit(-1); }else{ if( cs>0 ) sqlite3SetCrashseed(cs-1); return writeCache2(pFile, 0); } } /* ** Close the file. */ int sqlite3OsClose(OsFile *id){ if( !(*id) ) return SQLITE_OK; if( (*id)->fd.isOpen ){ writeCache(*id); sqlite3RealClose(&(*id)->fd); } closeFile(id); return SQLITE_OK; } int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ off_t offset; /* The current offset from the start of the file */ off_t end; /* The byte just past the last byte read */ int blk; /* Block number the read starts on */ int i; u8 *zCsr; int rc = SQLITE_OK; OsTestFile *pFile = *id; offset = osTell(pFile); end = offset+amt; blk = (offset/BLOCKSIZE); zCsr = (u8 *)pBuf; for(i=blk; i*BLOCKSIZE<end; i++){ int off = 0; int len = 0; if( BLOCK_OFFSET(i) < offset ){ off = offset-BLOCK_OFFSET(i); } len = BLOCKSIZE - off; if( BLOCK_OFFSET(i+1) > end ){ len = len - (BLOCK_OFFSET(i+1)-end); } if( i<pFile->nBlk && pFile->apBlk[i]){ u8 *pBlk = pFile->apBlk[i]; memcpy(zCsr, &pBlk[off], len); }else{ rc = sqlite3RealSeek(&pFile->fd, BLOCK_OFFSET(i) + off); if( rc!=SQLITE_OK ) return rc; rc = sqlite3RealRead(&pFile->fd, zCsr, len); if( rc!=SQLITE_OK ) return rc; } zCsr += len; } assert( zCsr==&((u8 *)pBuf)[amt] ); rc = sqlite3RealSeek(&pFile->fd, end); return rc; } int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ off_t offset; /* The current offset from the start of the file */ off_t end; /* The byte just past the last byte written */ int blk; /* Block number the write starts on */ int i; const u8 *zCsr; int rc = SQLITE_OK; OsTestFile *pFile = *id; offset = osTell(pFile); end = offset+amt; blk = (offset/BLOCKSIZE); zCsr = (u8 *)pBuf; for(i=blk; i*BLOCKSIZE<end; i++){ u8 *pBlk; int off = 0; int len = 0; /* Make sure the block is in the cache */ rc = cacheBlock(pFile, i); if( rc!=SQLITE_OK ) return rc; /* Write into the cache */ pBlk = pFile->apBlk[i]; assert( pBlk ); if( BLOCK_OFFSET(i) < offset ){ off = offset-BLOCK_OFFSET(i); } len = BLOCKSIZE - off; if( BLOCK_OFFSET(i+1) > end ){ len = len - (BLOCK_OFFSET(i+1)-end); } memcpy(&pBlk[off], zCsr, len); zCsr += len; } if( pFile->nMaxWrite<end ){ pFile->nMaxWrite = end; } assert( zCsr==&((u8 *)pBuf)[amt] ); rc = sqlite3RealSeek(&pFile->fd, end); return rc; } /* ** Sync the file. First flush the write-cache to disk, then call the ** real sync() function. */ int sqlite3OsSync(OsFile *id){ int rc = writeCache(*id); if( rc!=SQLITE_OK ) return rc; rc = sqlite3RealSync(&(*id)->fd); return rc; } /* ** Truncate the file. Set the internal OsFile.nMaxWrite variable to the new ** file size to ensure that nothing in the write-cache past this point ** is written to disk. */ int sqlite3OsTruncate(OsFile *id, off_t nByte){ (*id)->nMaxWrite = nByte; return sqlite3RealTruncate(&(*id)->fd, nByte); } /* ** Return the size of the file. If the cache contains a write that extended ** the file, then return this size instead of the on-disk size. */ int sqlite3OsFileSize(OsFile *id, off_t *pSize){ int rc = sqlite3RealFileSize(&(*id)->fd, pSize); if( rc==SQLITE_OK && pSize && *pSize<(*id)->nMaxWrite ){ *pSize = (*id)->nMaxWrite; } return rc; } /* ** The three functions used to open files. All that is required is to ** initialise the os_test.c specific fields and then call the corresponding ** os_unix.c function to really open the file. */ int sqlite3OsOpenReadWrite(const char *zFilename, OsFile *id, int *pReadonly){ initFile(id); return sqlite3RealOpenReadWrite(zFilename, &(*id)->fd, pReadonly); } int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ initFile(id); return sqlite3RealOpenExclusive(zFilename, &(*id)->fd, delFlag); } int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){ initFile(id); return sqlite3RealOpenReadOnly(zFilename, &(*id)->fd); } /* ** These six function calls are passed straight through to the os_unix.c ** backend. */ int sqlite3OsSeek(OsFile *id, off_t offset){ return sqlite3RealSeek(&(*id)->fd, offset); } int sqlite3OsCheckReservedLock(OsFile *id){ return sqlite3RealCheckReservedLock(&(*id)->fd); } int sqlite3OsLock(OsFile *id, int locktype){ return sqlite3RealLock(&(*id)->fd, locktype); } int sqlite3OsUnlock(OsFile *id, int locktype){ return sqlite3RealUnlock(&(*id)->fd, locktype); } int sqlite3OsFileModTime(OsFile *id, double *prNow){ return sqlite3RealFileModTime(&(*id)->fd, prNow); } int sqlite3OsOpenDirectory(const char *zDirname, OsFile *id){ return sqlite3RealOpenDirectory(zDirname, &(*id)->fd); } #endif /* OS_TEST */ |
Changes to src/os_test.h.
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include "os_unix.h" #undef OS_UNIX #undef OsFile /* Include sqliteInt.h now to get the type u8. */ #include "sqliteInt.h" | | > | > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include "os_unix.h" #undef OS_UNIX #undef OsFile /* Include sqliteInt.h now to get the type u8. */ #include "sqliteInt.h" typedef struct OsTestFile* OsFile; typedef struct OsTestFile OsTestFile; struct OsTestFile { u8 **apBlk; /* Array of blocks that have been written to. */ int nBlk; /* Size of apBlock. */ int nMaxWrite; /* Largest offset written to. */ OsRealFile fd; OsTestFile *pNext; }; void sqlite3SetCrashseed(int seed); #endif /* _SQLITE_OS_UNIX_H_ */ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.135 2004/06/22 12:18:32 danielk1977 Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
2782 2783 2784 2785 2786 2787 2788 | /* ** Return the current state of the file lock for the given pager. ** The return value is one of NO_LOCK, SHARED_LOCK, RESERVED_LOCK, ** PENDING_LOCK, or EXCLUSIVE_LOCK. */ int sqlite3pager_lockstate(Pager *pPager){ #ifdef OS_TEST | | | 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 | /* ** Return the current state of the file lock for the given pager. ** The return value is one of NO_LOCK, SHARED_LOCK, RESERVED_LOCK, ** PENDING_LOCK, or EXCLUSIVE_LOCK. */ int sqlite3pager_lockstate(Pager *pPager){ #ifdef OS_TEST return pPager->fd->fd.locktype; #else return pPager->fd.locktype; #endif } #endif #ifdef SQLITE_TEST |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.81 2004/06/22 12:18:32 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
979 980 981 982 983 984 985 986 987 988 989 990 991 992 | return TCL_OK; bad_args: Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); return TCL_ERROR; } /* ** Usage: breakpoint ** ** This routine exists for one purpose - to provide a place to put a ** breakpoint with GDB that can be triggered using TCL code. The use ** for this is when a particular test fails on (say) the 1485th iteration. | > > > > > > > > > > > > > > > > > > > > > | 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | return TCL_OK; bad_args: Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); return TCL_ERROR; } static int sqlite3_crashseed( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #ifdef OS_TEST int seed; if( objc!=2 ) goto bad_args; if( Tcl_GetIntFromObj(interp, objv[2], &seed) ) return TCL_ERROR; sqlite3SetCrashseed(seed); #endif return TCL_OK; bad_args: Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), "<seed>", 0); return TCL_ERROR; } /* ** Usage: breakpoint ** ** This routine exists for one purpose - to provide a place to put a ** breakpoint with GDB that can be triggered using TCL code. The use ** for this is when a particular test fails on (say) the 1485th iteration. |
︙ | ︙ | |||
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 | /* Functions from os.h */ { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, { "sqlite3OsClose", test_sqlite3OsClose, 0 }, { "sqlite3OsLock", test_sqlite3OsLock, 0 }, { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, { "add_test_collate", test_collate, 0 }, }; int i; extern int sqlite3_os_trace; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); | > | 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 | /* Functions from os.h */ { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, { "sqlite3OsClose", test_sqlite3OsClose, 0 }, { "sqlite3OsLock", test_sqlite3OsLock, 0 }, { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, { "add_test_collate", test_collate, 0 }, { "sqlite3_crashseed", sqlite3_crashseed, 0 }, }; int i; extern int sqlite3_os_trace; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); |
︙ | ︙ |