1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Add a completely new testing system for the Bitvec object. The new

testing system uses sqlite3_test_control() instead of unpublished
APIs.  Now provides 100% condition/decision coverage.  Obscure bugs
in Bitvec found and fixed as a result of the enhanced coverage. (CVS 4902)

FossilOrigin-Name: 2498d3ea36ecab6d9c0f04ef1c49d76a7a215a4f
This commit is contained in:
drh
2008-03-21 16:45:47 +00:00
parent 6f332c18d9
commit 3088d59e06
12 changed files with 357 additions and 309 deletions

View File

@ -1,5 +1,5 @@
C Add\ssome\smore\slogging\sto\sthe\smalloc\ssystem\sused\swhen\sSQLITE_MEMDEBUG\sis\sdefined.\s(CVS\s4901)
D 2008-03-21T14:22:44
C Add\sa\scompletely\snew\stesting\ssystem\sfor\sthe\sBitvec\sobject.\s\sThe\snew\ntesting\ssystem\suses\ssqlite3_test_control()\sinstead\sof\sunpublished\nAPIs.\s\sNow\sprovides\s100%\scondition/decision\scoverage.\s\sObscure\sbugs\nin\sBitvec\sfound\sand\sfixed\sas\sa\sresult\sof\sthe\senhanced\scoverage.\s(CVS\s4902)
D 2008-03-21T16:45:47
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in cf434ce8ca902e69126ae0f94fc9f7dc7428a5fa
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -84,7 +84,7 @@ F src/alter.c b42d782906fc3b92c331efbe06e9389617b47ce7
F src/analyze.c a78ac494668581fe7f54ee63700815bb0ea34261
F src/attach.c bdc75e759ca25a16f4dc7fbdbc6d37ad2561bb24
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
F src/bitvec.c fac68429a9916a50229c4ab88abb69c00c438f7f
F src/bitvec.c 49817d442e51e4123585f3cf3c2afc293a3c91e2
F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2
F src/btree.c 77304a2086a9089fe5e5ee8861248b72d6cca5d6
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
@ -96,7 +96,7 @@ F src/date.c e41ce4513fb0e359dc678d6bddb4ace135fe365d
F src/delete.c 217cd5559e00bb135dc626d4ea4ac713604729e8
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
F src/expr.c 8758d120f03f5856b594724732e42497efe00731
F src/fault.c 039abb45c9dbcbdf575ec2a23ae38db01bc2f7b2
F src/fault.c c28478c7190daef16be09d261c5461638b4d686c
F src/func.c c9e8c7ff4c45027edee89bde7adbf86a3a3b2afe
F src/hash.c 53655c312280211444bfe23af6490a460aec2980
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
@ -104,7 +104,7 @@ F src/insert.c 358c80592c20a61a8d5b4a127215b5e25de652f4
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
F src/legacy.c cb1939fdeb91ea88fb44fbd2768a10e14bc44650
F src/loadext.c f26b22f7c84153c9d5dbd7c240848823c6e6b6dc
F src/main.c f9c9a666f0cc5f5a4b768e48d12c1d1e65bf9b36
F src/main.c 7d22155e35094bc5d368202c3db8a3fc429548af
F src/malloc.c 60e392a4c12c839517f9b0db7b995f825444fb35
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
F src/mem1.c fc716ff521b6dd3e43eaa211967383308800e70a
@ -134,18 +134,18 @@ F src/parse.y b0ee84d94218046ea88c2a6561005710d127ca7d
F src/pragma.c f64eed914518c28d1863356163dea1e6f58e28f2
F src/prepare.c 1b71b5d43ba3d88f2d3c2a6d084f28ac209df956
F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d
F src/random.c 8b6ab5418cf0f4dde551730825d67da1457c2b3c
F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
F src/select.c 2a0f383a16c780b8ee8108e994c2f6c4f82233a9
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c 22297fffa6f00a6c6d44020fa13b1184a1bb372d
F src/sqlite.h.in b18c4cb006f16237aa044200ddd6a16cf4b7457c
F src/sqlite.h.in da2ab729b5c590c7dfa5418477ed181d52ab9c82
F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
F src/sqliteInt.h c96aca7c69ba463ee09eac19b1ac9974752b467e
F src/sqliteInt.h 07b472437b2d7297c300f8b7cea5205984fa64d1
F src/sqliteLimit.h eecbc288b410ae5565e71aaa4a439aae57bb0707
F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a
F src/tclsqlite.c d42912617d4734b8f9195416badf5b27e512ded2
F src/test1.c aab521bef2a038dfdf1bcafb4f3372285be7d91b
F src/test2.c da3c4016fc1e08fa1a133ca81591ee8ca99ce8e7
F src/test2.c f0808cc643528b9620e4059ca9bda8346f526121
F src/test3.c 5c7452038ab27aa698070799b10132f26cdd2a80
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
@ -156,7 +156,7 @@ F src/test9.c 4615ef08750245a2d96aaa7cbe2fb4aff2b57acc
F src/test_async.c 3147c64c34721f088d5ab20f85dabd5d7732c007
F src/test_autoext.c 5e892ab84aece3f0428920bf46923f16ac83962a
F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c
F src/test_config.c a0c779e589df63a9de36d4fe3971bc04975e2675
F src/test_config.c 100a3381cedd5435ce6928f1c21ec6887a16b71e
F src/test_devsym.c cee1aecaa90c895030399ca4ae38f84a08038f8a
F src/test_func.c 9e9b33ff083b65da91c389cece903bc32de06f01
F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d
@ -213,7 +213,7 @@ F test/bigfile.test 9a6a8346e4042d9c781ed6cb6553ac871ae30618
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bind.test 261fd1603613e7f877a516d29f281c9d8c2ecf52
F test/bindxfer.test 995d2cf8df61204d748cde6960443121c4ccd2e1
F test/bitvec.test 52a1caf5b4f037982f0e7720ffff6296f20940a6
F test/bitvec.test 62a512c3f7041d1df12558eb25990e5a19820571
F test/blob.test f2dbdbf1159674283645c2636436839313ee7131
F test/btree.test d22b1b2cc9becc36f6b1f2f91b9fca1e48060979
F test/btree2.test 4b56a2a4a4f84d68c77aef271223a713bf5ebafc
@ -390,7 +390,7 @@ F test/mallocD.test f78c295e8e18ea3029e65ca08278690e00c22100
F test/mallocE.test db1ed69d7eded1b080952e2a7c37f364ad241b08
F test/mallocF.test 2d5c590ebc2fc7f0dcebdf5aa8498b9aed69107e
F test/mallocG.test b295dc03b6d8d705ce425ff4d1ce6bbeb1c5ab33
F test/malloc_common.tcl ed56c8cdb9a435c5fd1b209b3ad3c5093a8ecc10
F test/malloc_common.tcl fd7040bbb0bbbe84187c7f80049fdf6b2a4d699b
F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893
F test/memleak.test d2d2a1ff7105d32dc3fdf691458cf6cba58c7217
@ -624,7 +624,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P d6be1f495ec57158f7bcca3e32145a9a8fde723a
R 28cbaee3047482f301b44be906e76f05
U danielk1977
Z a16e4b15bf7acabffb6c1a202fc0f688
P 79738f582fbac87f2d335e0c6b7f53e3054b41ba
R 344a09e57d57d3bd52a8653f304b056c
U drh
Z 248ddc23a8b5ab000e802a066f25ef83

View File

@ -1 +1 @@
79738f582fbac87f2d335e0c6b7f53e3054b41ba
2498d3ea36ecab6d9c0f04ef1c49d76a7a215a4f

View File

@ -32,14 +32,14 @@
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
** @(#) $Id: bitvec.c,v 1.2 2008/03/14 13:02:08 mlcreech Exp $
** @(#) $Id: bitvec.c,v 1.3 2008/03/21 16:45:47 drh Exp $
*/
#include "sqliteInt.h"
#define BITVEC_SZ 512
/* Round the union size down to the nearest pointer boundary, since that's how
** it will be aligned within the Bitvec struct. */
#define BITVEC_USIZE (((BITVEC_SZ-12)/sizeof(Bitvec *))*sizeof(Bitvec *))
#define BITVEC_USIZE (((BITVEC_SZ-12)/sizeof(Bitvec*))*sizeof(Bitvec*))
#define BITVEC_NCHAR BITVEC_USIZE
#define BITVEC_NBIT (BITVEC_NCHAR*8)
#define BITVEC_NINT (BITVEC_USIZE/4)
@ -101,9 +101,8 @@ Bitvec *sqlite3BitvecCreate(u32 iSize){
** i is out of range, then return false.
*/
int sqlite3BitvecTest(Bitvec *p, u32 i){
assert( i>0 );
if( p==0 ) return 0;
if( i>p->iSize ) return 0;
if( i>p->iSize || i==0 ) return 0;
if( p->iSize<=BITVEC_NBIT ){
i--;
return (p->u.aBitmap[i/8] & (1<<(i&7)))!=0;
@ -130,6 +129,7 @@ int sqlite3BitvecTest(Bitvec *p, u32 i){
int sqlite3BitvecSet(Bitvec *p, u32 i){
u32 h;
assert( p!=0 );
assert( i>0 );
if( p->iSize<=BITVEC_NBIT ){
i--;
p->u.aBitmap[i/8] |= 1 << (i&7);
@ -159,8 +159,8 @@ int sqlite3BitvecSet(Bitvec *p, u32 i){
memcpy(aiValues, p->u.aHash, sizeof(aiValues));
memset(p->u.apSub, 0, sizeof(p->u.apSub[0])*BITVEC_NPTR);
p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
sqlite3BitvecSet(p, i);
for(rc=j=0; j<BITVEC_NINT; j++){
rc = sqlite3BitvecSet(p, i);
for(j=0; j<BITVEC_NINT; j++){
if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
}
return rc;
@ -175,6 +175,7 @@ int sqlite3BitvecSet(Bitvec *p, u32 i){
*/
void sqlite3BitvecClear(Bitvec *p, u32 i){
assert( p!=0 );
assert( i>0 );
if( p->iSize<=BITVEC_NBIT ){
i--;
p->u.aBitmap[i/8] &= ~(1 << (i&7));
@ -191,7 +192,9 @@ void sqlite3BitvecClear(Bitvec *p, u32 i){
memset(p->u.aHash, 0, sizeof(p->u.aHash[0])*BITVEC_NINT);
p->nSet = 0;
for(j=0; j<BITVEC_NINT; j++){
if( aiValues[j] && aiValues[j]!=i ) sqlite3BitvecSet(p, aiValues[j]);
if( aiValues[j] && aiValues[j]!=i ){
sqlite3BitvecSet(p, aiValues[j]);
}
}
}
}
@ -209,3 +212,113 @@ void sqlite3BitvecDestroy(Bitvec *p){
}
sqlite3_free(p);
}
#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** Let V[] be an array of unsigned characters sufficient to hold
** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
** Then the following macros can be used to set, clear, or test
** individual bits within V.
*/
#define SETBIT(V,I) V[I>>3] |= (1<<(I&7))
#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7))
#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0
/*
** This routine runs an extensive test of the Bitvec code.
**
** The input is an array of integers that acts as a program
** to test the Bitvec. The integers are opcodes followed
** by 0, 1, or 3 operands, depending on the opcode. Another
** opcode follows immediately after the last operand.
**
** There are 6 opcodes numbered from 0 through 5. 0 is the
** "halt" opcode and causes the test to end.
**
** 0 Halt and return the number of errors
** 1 N S X Set N bits beginning with S and incrementing by X
** 2 N S X Clear N bits beginning with S and incrementing by X
** 3 N Set N randomly chosen bits
** 4 N Clear N randomly chosen bits
** 5 N S X Set N bits from S increment X in array only, not in bitvec
**
** The opcodes 1 through 4 perform set and clear operations are performed
** on both a Bitvec object and on a linear array of bits obtained from malloc.
** Opcode 5 works on the linear array only, not on the Bitvec.
** Opcode 5 is used to deliberately induce a fault in order to
** confirm that error detection works.
**
** At the conclusion of the test the linear array is compared
** against the Bitvec object. If there are any differences,
** an error is returned. If they are the same, zero is returned.
**
** If a memory allocation error occurs, return -1.
*/
int sqlite3BitvecBuiltinTest(int sz, int *aOp){
Bitvec *pBitvec = 0;
unsigned char *pV = 0;
int rc = -1;
int i, nx, pc, op;
/* Allocate the Bitvec to be tested and a linear array of
** bits to act as the reference */
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3_malloc( (sz+7)/8 + 1 );
if( pBitvec==0 || pV==0 ) goto bitvec_end;
memset(pV, 0, (sz+7)/8 + 1);
/* Run the program */
pc = 0;
while( (op = aOp[pc])!=0 ){
switch( op ){
case 1:
case 2:
case 5: {
nx = 4;
i = aOp[pc+2] - 1;
aOp[pc+2] += aOp[pc+3];
break;
}
case 3:
case 4:
default: {
nx = 2;
sqlite3_randomness(sizeof(i), &i);
break;
}
}
if( (--aOp[pc+1]) > 0 ) nx = 0;
pc += nx;
i = (i & 0x7fffffff)%sz;
if( (op & 1)!=0 ){
SETBIT(pV, (i+1));
if( op!=5 ){
if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
}
}else{
CLEARBIT(pV, (i+1));
sqlite3BitvecClear(pBitvec, i+1);
}
}
/* Test to make sure the linear array exactly matches the
** Bitvec object. Start with the assumption that they do
** match (rc==0). Change rc to non-zero if a discrepancy
** is found.
*/
rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
+ sqlite3BitvecTest(pBitvec, 0);
for(i=1; i<=sz; i++){
if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
rc = i;
break;
}
}
/* Free allocated structure */
bitvec_end:
sqlite3_free(pV);
sqlite3BitvecDestroy(pBitvec);
return rc;
}
#endif /* SQLITE_OMIT_BUILTIN_TEST */

View File

@ -19,7 +19,7 @@
** allocation failures or I/O errors.
**
** The fault injector is omitted from the code if SQLite is
** compiled with -DSQLITE_OMIT_TESTLOGIC=1. There is a very
** compiled with -DSQLITE_OMIT_BUILTIN_TEST=1. There is a very
** small performance hit for leaving the fault injector in the code.
** Commerical products will probably want to omit the fault injector
** from production builds. But safety-critical systems who work
@ -28,7 +28,7 @@
*/
#include "sqliteInt.h"
#ifndef SQLITE_OMIT_TESTLOGIC
#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** There can be various kinds of faults. For example, there can be
@ -144,4 +144,4 @@ int sqlite3FaultStep(int id){
return 1;
}
#endif /* SQLITE_OMIT_TESTLOGIC */
#endif /* SQLITE_OMIT_BUILTIN_TEST */

View File

@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.428 2008/03/20 18:00:49 drh Exp $
** $Id: main.c,v 1.429 2008/03/21 16:45:47 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -1574,7 +1574,7 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
*/
int sqlite3_test_control(int op, ...){
int rc = 0;
#ifndef SQLITE_OMIT_TESTLOGIC
#ifndef SQLITE_OMIT_BUILTIN_TEST
va_list ap;
va_start(ap, op);
switch( op ){
@ -1658,8 +1658,23 @@ int sqlite3_test_control(int op, ...){
sqlite3PrngResetState();
break;
}
/*
** sqlite3_test_control(BITVEC_TEST, size, program)
**
** Run a test against a Bitvec object of size. The program argument
** is an array of integers that defines the test. Return -1 on a
** memory allocation error, 0 on success, or non-zero for an error.
** See the sqlite3BitvecBuiltinTest() for additional information.
*/
case SQLITE_TESTCTRL_BITVEC_TEST: {
int sz = va_arg(ap, int);
int *aProg = va_arg(ap, int*);
rc = sqlite3BitvecBuiltinTest(sz, aProg);
break;
}
}
va_end(ap);
#endif /* SQLITE_OMIT_TESTLOGIC */
#endif /* SQLITE_OMIT_BUILTIN_TEST */
return rc;
}

View File

@ -15,7 +15,7 @@
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.22 2008/03/19 14:15:35 drh Exp $
** $Id: random.c,v 1.23 2008/03/21 16:45:47 drh Exp $
*/
#include "sqliteInt.h"
@ -103,7 +103,7 @@ void sqlite3_randomness(int N, void *pBuf){
sqlite3_mutex_leave(mutex);
}
#ifndef SQLITE_OMIT_TESTLOGIC
#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** For testing purposes, we sometimes want to preserve the state of
** PRNG and restore the PRNG to its saved state at a later time.
@ -120,4 +120,4 @@ void sqlite3PrngRestoreState(void){
void sqlite3PrngResetState(void){
sqlite3Prng.isInit = 0;
}
#endif /* SQLITE_OMIT_TESTLOGIC */
#endif /* SQLITE_OMIT_BUILTIN_TEST */

View File

@ -30,7 +30,7 @@
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.298 2008/03/20 18:00:49 drh Exp $
** @(#) $Id: sqlite.h.in,v 1.299 2008/03/21 16:45:47 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@ -5610,6 +5610,7 @@ int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_PRNG_SAVE 5
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
#define SQLITE_TESTCTRL_PRNG_RESET 7
#define SQLITE_TESTCTRL_BITVEC_TEST 8
/*

View File

@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.678 2008/03/20 16:30:18 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.679 2008/03/21 16:45:47 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@ -1790,6 +1790,7 @@ int sqlite3BitvecTest(Bitvec*, u32);
int sqlite3BitvecSet(Bitvec*, u32);
void sqlite3BitvecClear(Bitvec*, u32);
void sqlite3BitvecDestroy(Bitvec*);
int sqlite3BitvecBuiltinTest(int,int*);
void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
@ -2084,7 +2085,7 @@ CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
** mechanism is disabled at compile-time then set up macros so that no
** unnecessary code is generated.
*/
#ifndef SQLITE_OMIT_TESTLOGIC
#ifndef SQLITE_OMIT_BUILTIN_TEST
void sqlite3FaultConfig(int,int,int);
int sqlite3FaultFailures(int);
int sqlite3FaultBenignFailures(int);

View File

@ -13,12 +13,13 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.56 2008/03/20 11:04:21 danielk1977 Exp $
** $Id: test2.c,v 1.57 2008/03/21 16:45:48 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/*
** Interpret an SQLite error number
@ -561,103 +562,40 @@ static int fake_big_file(
}
#endif
/*
** sqlite3BitvecCreate SIZE
** sqlite3BitvecTest POINTER N
** sqlite3BitvecSet POINTER N
** sqlite3BitvecClear POINTER N
** sqlite3BitvecDestroy POINTER
*/
static int testBitvecCreate(
void *NotUsed,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
const char **argv /* Text of each argument */
){
int size;
Bitvec *p;
char zBuf[100];
if( argc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"",
(void*)0);
}
if( Tcl_GetInt(interp, argv[1], &size) ) return TCL_ERROR;
p = sqlite3BitvecCreate(size);
sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",p);
Tcl_AppendResult(interp, zBuf, 0);
return TCL_OK;
}
static int testBitvecTest(
void *NotUsed,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
const char **argv /* Text of each argument */
){
int N;
Bitvec *p;
char zBuf[100];
if( argc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PTR N\"",
(void*)0);
}
p = (Bitvec*)sqlite3TextToPtr(argv[1]);
if( Tcl_GetInt(interp, argv[2], &N) ) return TCL_ERROR;
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",sqlite3BitvecTest(p,N));
Tcl_AppendResult(interp, zBuf, 0);
return TCL_OK;
}
static int testBitvecSet(
void *NotUsed,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
const char **argv /* Text of each argument */
){
int N;
Bitvec *p;
char zBuf[100];
if( argc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PTR N\"",
(void*)0);
}
p = (Bitvec*)sqlite3TextToPtr(argv[1]);
if( Tcl_GetInt(interp, argv[2], &N) ) return TCL_ERROR;
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",sqlite3BitvecSet(p,N));
Tcl_AppendResult(interp, zBuf, 0);
return TCL_OK;
}
static int testBitvecClear(
void *NotUsed,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
const char **argv /* Text of each argument */
){
int N;
Bitvec *p;
if( argc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PTR N\"",
(void*)0);
}
p = (Bitvec*)sqlite3TextToPtr(argv[1]);
if( Tcl_GetInt(interp, argv[2], &N) ) return TCL_ERROR;
sqlite3BitvecClear(p,N);
return TCL_OK;
}
static int testBitvecDestroy(
void *NotUsed,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
const char **argv /* Text of each argument */
){
Bitvec *p;
if( argc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PTR\"",
(void*)0);
}
p = (Bitvec*)sqlite3TextToPtr(argv[1]);
sqlite3BitvecDestroy(p);
return TCL_OK;
}
/*
** sqlite3BitvecBuiltinTest SIZE PROGRAM
**
** Invoke the SQLITE_TESTCTRL_BITVEC_TEST operator on test_control.
** See comments on sqlite3BitvecBuiltinTest() for additional information.
*/
static int testBitvecBuiltinTest(
void *NotUsed,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
const char **argv /* Text of each argument */
){
int sz, rc;
int nProg = 0;
int aProg[100];
const char *z;
if( argc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" SIZE PROGRAM\"", (void*)0);
}
if( Tcl_GetInt(interp, argv[1], &sz) ) return TCL_ERROR;
z = argv[2];
while( nProg<99 && *z ){
while( *z && !isdigit(*z) ){ z++; }
if( *z==0 ) break;
aProg[nProg++] = atoi(z);
while( isdigit(*z) ){ z++; }
}
aProg[nProg] = 0;
rc = sqlite3_test_control(SQLITE_TESTCTRL_BITVEC_TEST, sz, aProg);
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
return TCL_OK;
}
/*
** Register commands with the TCL interpreter.
@ -693,11 +631,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
#ifndef SQLITE_OMIT_DISKIO
{ "fake_big_file", (Tcl_CmdProc*)fake_big_file },
#endif
{ "sqlite3BitvecCreate", (Tcl_CmdProc*)testBitvecCreate },
{ "sqlite3BitvecTest", (Tcl_CmdProc*)testBitvecTest },
{ "sqlite3BitvecSet", (Tcl_CmdProc*)testBitvecSet },
{ "sqlite3BitvecClear", (Tcl_CmdProc*)testBitvecClear },
{ "sqlite3BitvecDestroy", (Tcl_CmdProc*)testBitvecDestroy },
{ "sqlite3BitvecBuiltinTest",(Tcl_CmdProc*)testBitvecBuiltinTest},
};
int i;
for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){

View File

@ -16,7 +16,7 @@
** The focus of this file is providing the TCL testing layer
** access to compile-time constants.
**
** $Id: test_config.c,v 1.22 2008/03/20 14:03:29 drh Exp $
** $Id: test_config.c,v 1.23 2008/03/21 16:45:48 drh Exp $
*/
#include "sqliteLimit.h"
@ -135,6 +135,12 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_BUILTIN_TEST
Tcl_SetVar2(interp, "sqlite_options", "builtin_test", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "builtin_test", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_BLOB_LITERAL
Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY);
#else
@ -356,12 +362,6 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_TESTLOGIC
Tcl_SetVar2(interp, "sqlite_options", "testlogic", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "testlogic", "1", TCL_GLOBAL_ONLY);
#endif
rc = sqlite3_threadsafe();
#if SQLITE_THREADSAFE
Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY);

View File

@ -11,197 +11,181 @@
#
# Unit testing of the Bitvec object.
#
# $Id: bitvec.test,v 1.1 2008/02/18 14:47:34 drh Exp $
# $Id: bitvec.test,v 1.2 2008/03/21 16:45:48 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
#ifcapable !subquery {
# finish_test
# return
#}
# The built-in test logic must be operational in order for
# this test to work.
ifcapable !builtin_test {
finish_test
return
}
# Test that sqlite3BitvecBuiltinTest correctly reports errors
# that are deliberately introduced.
#
do_test bitvec-1.0.1 {
sqlite3BitvecBuiltinTest 400 {5 1 1 1 0}
} 1
do_test bitvec-1.0.2 {
sqlite3BitvecBuiltinTest 400 {5 1 234 1 0}
} 234
# Run test cases that set every bit in vectors of various sizes.
# for larger cases, this should cycle the bit vector representation
# from hashing into subbitmaps. The subbitmaps should start as
# hashes then change to either subbitmaps or linear maps, depending
# on their size.
#
do_test bitvec-1.1 {
set PTR [sqlite3BitvecCreate 4000]
for {set i 1} {$i<=4000} {incr i} {
if {$i%1000==999} continue
sqlite3BitvecSet $PTR $i
}
set r {}
for {set i 1} {$i<=4000} {incr i} {
if {![sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {999 1999 2999 3999}
sqlite3BitvecBuiltinTest 400 {1 400 1 1 0}
} 0
do_test bitvec-1.2 {
set PTR [sqlite3BitvecCreate 4001]
for {set i 1} {$i<=4001} {incr i} {
if {$i%1000==999} continue
sqlite3BitvecSet $PTR $i
}
set r {}
for {set i 1} {$i<=4001} {incr i} {
if {![sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {999 1999 2999 3999}
sqlite3BitvecBuiltinTest 4000 {1 4000 1 1 0}
} 0
do_test bitvec-1.3 {
set PTR [sqlite3BitvecCreate 40000]
for {set i 1} {$i<=40000} {incr i} {
if {$i%10000==9999} continue
sqlite3BitvecSet $PTR $i
}
set r {}
for {set i 1} {$i<=40000} {incr i} {
if {![sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {9999 19999 29999 39999}
sqlite3BitvecBuiltinTest 40000 {1 40000 1 1 0}
} 0
do_test bitvec-1.4 {
set PTR [sqlite3BitvecCreate 2000000000]
for {set i 1000000} {$i<=1001000} {incr i} {
if {$i%1000==789} continue
sqlite3BitvecSet $PTR $i
}
set r {}
for {set i 1000000} {$i<=1001000} {incr i} {
if {![sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {1000789}
sqlite3BitvecBuiltinTest 400000 {1 400000 1 1 0}
} 0
# By specifying a larger increments, we spread the load around.
#
do_test bitvec-1.5 {
sqlite3BitvecBuiltinTest 400 {1 400 1 7 0}
} 0
do_test bitvec-1.6 {
sqlite3BitvecBuiltinTest 4000 {1 4000 1 7 0}
} 0
do_test bitvec-1.7 {
sqlite3BitvecBuiltinTest 40000 {1 40000 1 7 0}
} 0
do_test bitvec-1.8 {
sqlite3BitvecBuiltinTest 400000 {1 400000 1 7 0}
} 0
# First fill up the bitmap with ones, then go through and
# clear all the bits. This will stress the clearing mechanism.
#
do_test bitvec-1.9 {
sqlite3BitvecBuiltinTest 400 {1 400 1 1 2 400 1 1 0}
} 0
do_test bitvec-1.10 {
sqlite3BitvecBuiltinTest 4000 {1 4000 1 1 2 4000 1 1 0}
} 0
do_test bitvec-1.11 {
sqlite3BitvecBuiltinTest 40000 {1 40000 1 1 2 40000 1 1 0}
} 0
do_test bitvec-1.12 {
sqlite3BitvecBuiltinTest 400000 {1 400000 1 1 2 400000 1 1 0}
} 0
do_test bitvec-1.13 {
sqlite3BitvecBuiltinTest 400 {1 400 1 1 2 400 1 7 0}
} 0
do_test bitvec-1.15 {
sqlite3BitvecBuiltinTest 4000 {1 4000 1 1 2 4000 1 7 0}
} 0
do_test bitvec-1.16 {
sqlite3BitvecBuiltinTest 40000 {1 40000 1 1 2 40000 1 77 0}
} 0
do_test bitvec-1.17 {
sqlite3BitvecBuiltinTest 400000 {1 400000 1 1 2 400000 1 777 0}
} 0
do_test bitvec-1.18 {
sqlite3BitvecBuiltinTest 400000 {1 5000 100000 1 2 400000 1 37 0}
} 0
# Attempt to induce hash collisions.
#
unset -nocomplain start
unset -nocomplain incr
foreach start {1 2 3 4 5 6 7 8} {
foreach incr {124 125} {
do_test bitvec-1.20.$start.$incr {
set prog [list 1 60 $::start $::incr 2 5000 1 1 0]
sqlite3BitvecBuiltinTest 5000 $prog
} 0
}
}
do_test bitvec-1.30.big_and_slow {
sqlite3BitvecBuiltinTest 17000000 {1 17000000 1 1 2 17000000 1 1 0}
} 0
# Test setting and clearing a random subset of bits.
#
do_test bitvec-2.1 {
set PTR [sqlite3BitvecCreate 4000]
for {set i 1} {$i<=4000} {incr i 2} {
sqlite3BitvecSet $PTR $i
}
for {set i 1} {$i<=4000} {incr i} {
sqlite3BitvecClear $PTR $i
}
set r {}
for {set i 1} {$i<=4000} {incr i} {
if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {}
sqlite3BitvecBuiltinTest 4000 {3 2000 4 2000 0}
} 0
do_test bitvec-2.2 {
set PTR [sqlite3BitvecCreate 4001]
for {set i 1} {$i<=101} {incr i 2} {
sqlite3BitvecSet $PTR $i
}
for {set i 1} {$i<=99} {incr i} {
sqlite3BitvecClear $PTR $i
}
set r {}
for {set i 1} {$i<=4000} {incr i} {
if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {101}
sqlite3BitvecBuiltinTest 4000 {3 1000 4 1000 3 1000 4 1000 3 1000 4 1000
3 1000 4 1000 3 1000 4 1000 3 1000 4 1000 0}
} 0
do_test bitvec-2.3 {
set PTR [sqlite3BitvecCreate 4001]
for {set i 1} {$i<=101} {incr i} {
sqlite3BitvecSet $PTR $i
}
for {set i 1} {$i<=99} {incr i} {
sqlite3BitvecClear $PTR $i
}
set r {}
for {set i 1} {$i<=4000} {incr i} {
if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {100 101}
sqlite3BitvecBuiltinTest 400000 {3 10 0}
} 0
do_test bitvec-2.4 {
set PTR [sqlite3BitvecCreate 5000]
for {set i 1} {$i<=5000} {incr i} {
sqlite3BitvecSet $PTR $i
if {$i%1000!=456} {sqlite3BitvecClear $PTR $i}
}
set r {}
for {set i 1} {$i<=5000} {incr i} {
if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {456 1456 2456 3456 4456}
sqlite3BitvecBuiltinTest 4000 {3 10 2 4000 1 1 0}
} 0
do_test bitvec-2.5 {
sqlite3BitvecBuiltinTest 5000 {3 20 2 5000 1 1 0}
} 0
do_test bitvec-2.6 {
sqlite3BitvecBuiltinTest 50000 {3 60 2 50000 1 1 0}
} 0
do_test bitvec-3.1 {
set PTR [sqlite3BitvecCreate 2000000000]
for {set i 2000000} {$i<=3000000} {incr i 100000} {
for {set j $i} {$j<=$i+50} {incr j} {
sqlite3BitvecSet $PTR $i
# This procedure runs sqlite3BitvecBuiltinTest with argments "n" and
# "program". But it also causes a malloc error to occur after the
# "failcnt"-th malloc. The result should be "0" if no malloc failure
# occurs or "-1" if there is a malloc failure.
#
proc bitvec_malloc_test {label failcnt n program} {
do_test $label [subst {
sqlite3_memdebug_fail $failcnt
set x \[sqlite3BitvecBuiltinTest $n [list $program]\]
set nFail \[sqlite3_memdebug_fail -1\]
if {\$nFail==0} {
set ::go 0
set x -1
}
for {set j $i} {$j<=$i+50} {incr j} {
sqlite3BitvecClear $PTR $i
set x
}] -1
}
# Make sure malloc failures are handled sanily.
#
unset -nocomplain n
unset -nocomplain go
set go 1
save_prng_state
for {set n 0} {$go} {incr n} {
restore_prng_state
bitvec_malloc_test bitvec-3.1.$n $n 5000 {
3 60 2 5000 1 1 3 60 2 5000 1 1 3 60 2 5000 1 1 0
}
}
set go 1
for {set n 0} {$go} {incr n} {
restore_prng_state
bitvec_malloc_test bitvec-3.2.$n $n 5000 {
3 600 2 5000 1 1 3 600 2 5000 1 1 3 600 2 5000 1 1 0
}
set r {}
for {set i 2000000} {$i<=3000000} {incr i} {
if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {}
do_test bitvec-3.2 {
set PTR [sqlite3BitvecCreate 200000]
for {set i 1000} {$i<=190000} {incr i 10000} {
for {set j $i} {$j<=$i+50} {incr j} {
sqlite3BitvecSet $PTR $i
}
for {set j $i} {$j<=$i+50} {incr j} {
sqlite3BitvecClear $PTR $i
}
}
set r {}
for {set i 1} {$i<=200000} {incr i} {
if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {}
do_test bitvec-3.3 {
set PTR [sqlite3BitvecCreate 200000]
for {set i 1000} {$i<=190000} {incr i 10000} {
for {set j $i} {$j<=$i+500} {incr j} {
sqlite3BitvecSet $PTR $i
}
for {set j $i} {$j<=$i+500} {incr j} {
sqlite3BitvecClear $PTR $i
}
}
set r {}
for {set i 1} {$i<=200000} {incr i} {
if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {}
do_test bitvec-3.4 {
set PTR [sqlite3BitvecCreate 2000]
for {set i 10} {$i<=1900} {incr i 100} {
for {set j $i} {$j<=$i+50} {incr j} {
sqlite3BitvecSet $PTR $i
}
for {set j $i} {$j<=$i+50} {incr j} {
sqlite3BitvecClear $PTR $i
}
}
set r {}
for {set i 1} {$i<=2000} {incr i} {
if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
}
sqlite3BitvecDestroy $PTR
set r
} {}
}
set go 1
for {set n 1} {$go} {incr n} {
bitvec_malloc_test bitvec-3.3.$n $n 50000 {1 50000 1 1 0}
}
finish_test
return
finish_test

View File

@ -12,11 +12,11 @@
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.15 2008/03/19 14:15:35 drh Exp $
# $Id: malloc_common.tcl,v 1.16 2008/03/21 16:45:48 drh Exp $
# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable testlogic {
ifcapable builtin_test {
set MEMDEBUG 1
} else {
set MEMDEBUG 0