]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add a completely new testing system for the Bitvec object. The new
authordrh <drh@noemail.net>
Fri, 21 Mar 2008 16:45:47 +0000 (16:45 +0000)
committerdrh <drh@noemail.net>
Fri, 21 Mar 2008 16:45:47 +0000 (16:45 +0000)
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

12 files changed:
manifest
manifest.uuid
src/bitvec.c
src/fault.c
src/main.c
src/random.c
src/sqlite.h.in
src/sqliteInt.h
src/test2.c
src/test_config.c
test/bitvec.test
test/malloc_common.tcl

index acd7e9960da357c2189d5fb5aa347afcf64aac69..0200997f2532e6befa28e9ef89edeab78cdaecbe 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index ff6b6c40351aad80a33319a5543e6716a68df175..03a6987c53246d5c387d459b466006f552033f72 100644 (file)
@@ -1 +1 @@
-79738f582fbac87f2d335e0c6b7f53e3054b41ba
\ No newline at end of file
+2498d3ea36ecab6d9c0f04ef1c49d76a7a215a4f
\ No newline at end of file
index 7fa8a8aec7891e7a8f43630aeee0496f7f8320d5..be8f4d6d16092ea5094df351fe843664d2b92b8a 100644 (file)
 ** 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 */
index af7702ec9b06d03676e98652d9ba8652d3ffb834..7e183ed43babd1e6590b98f2617bcf6be21dde55 100644 (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 */
index 140e64a62deba623a4d92af68feac226098c823f..41b84c0948d823c2ec35676e648d664f4e7e8602 100644 (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;
 }
index 0c65918669b9ac45ff5d721f3b54ea854302c21b..4b977f2b46410a04e734051cfc0eb59897185b0c 100644 (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 */
index 158c6e1e3349cb89368b1e7f9e071089f6924266..18d44d26315feb01d085ee5a51e752ca66c0dbea 100644 (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
 
 
 /*
index 8c7173b2f3fc4b6ddd57e80e40bccd97ca5cbdd5..8f6b5bdd622059617d1ae9c6d1340448e4137fef 100644 (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);
index a8457efb331a24545be59b10c751fded18378880..68e9c65c0b71781bcb42b26b830af4e8e7abcab8 100644 (file)
 ** 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
+** sqlite3BitvecBuiltinTest SIZE PROGRAM
+**
+** Invoke the SQLITE_TESTCTRL_BITVEC_TEST operator on test_control.
+** See comments on sqlite3BitvecBuiltinTest() for additional information.
 */
-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(
+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 N;
-  Bitvec *p;
+  int sz, rc;
+  int nProg = 0;
+  int aProg[100];
+  const char *z;
   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);
+    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++){
index adf6805e811567fca20d4af973a01d5dabc5b685..c396763d4dda67498cd0c74a163777a14058f7dd 100644 (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);
index 415724210ef6601ebe1b0661f9560577ad160451..aff2bf7fcaa58f6708d6af1cf270c9106f366050 100644 (file)
 #
 # 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}
-
-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
-    }
-    for {set j $i} {$j<=$i+50} {incr j} {
-      sqlite3BitvecClear $PTR $i
-    }
-  }
-  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
+  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
+
+# 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
     }
-  }
-  set r {}
-  for {set i 1} {$i<=2000} {incr i} {
-    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
-  }
-  sqlite3BitvecDestroy $PTR
-  set r
-} {}
+    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 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
index 570186ef960c1920c05c07a60825784d64c51599..4909634dacd4df0900ae685ecbf6a04e021995d0 100644 (file)
 # 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