]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Infrastructure for a new test program named "iotester" that strives to verify
authordrh <>
Tue, 13 Aug 2024 19:30:03 +0000 (19:30 +0000)
committerdrh <>
Tue, 13 Aug 2024 19:30:03 +0000 (19:30 +0000)
the operation of a VFS object.

FossilOrigin-Name: b46d86c22bd486789affa9c5e41b8f6ee47bae23eee5efe0640db3d3860e8a7a

Makefile.in
Makefile.msc
manifest
manifest.uuid
test/iotester.c [new file with mode: 0644]

index 7ff6e901e49ecdc9209b7ebbd3e6234d3fa18559..cb74e35443b29909fca7b4f8111008dbb731c9d6 100644 (file)
@@ -1537,6 +1537,9 @@ threadtest: threadtest3$(TEXE)
 threadtest5: sqlite3.c $(TOP)/test/threadtest5.c
        $(LTLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS)
 
+iotester:      sqlite3.lo $(TOP)/test/iotester.c
+       $(LTLINK) $(TOP)/test/iotester.c sqlite3.lo -o $@ $(TLIBS)
+
 # Standard install and cleanup targets
 #
 lib_install:   libsqlite3.la
index e31aee08998ca5bef41ac38c313f7b13eb3e6c86..844e33b771caa60ce1b8f3249d29dfbdafefef54 100644 (file)
@@ -1301,7 +1301,7 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
 
 # Object files for the amalgamation.
 #
-LIBOBJS1 = sqlite3.lo
+LIBOBJS1 = sqlite3.obj
 
 # Determine the real value of LIBOBJ based on the 'configure' script
 #
@@ -1944,7 +1944,7 @@ sqlite3-all.c:    sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
 
 # Rule to build the amalgamation
 #
-sqlite3.lo:    $(SQLITE3C)
+sqlite3.obj:   $(SQLITE3C)
        $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
 
 # <<mark>>
@@ -2700,6 +2700,9 @@ THREADTEST3_SRC = \
 threadtest3.exe: $(THREADTEST3_SRC) $(TOP)\src\test_multiplex.c $(SQLITE3C) $(SQLITE3H)
        $(LTLINK) $(NO_WARN) $(TOP)\test\threadtest3.c $(TOP)\src\test_multiplex.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
 
+iotester.exe:  sqlite3.obj $(TOP)\test\iotester.c
+       $(LTLINK) $(TOP)\test\iotester.c sqlite3.obj /link $(LDFLAGS) $(LTLINKOPTS)
+
 LSMDIR=$(TOP)\ext\lsm1
 !INCLUDE $(LSMDIR)\Makefile.msc
 
index 159330c456b3431e9485636ff34b2697751dd5b0..fe9be1b9300a2c1a9154d36f2ea60ea4703f961e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,11 +1,11 @@
-C Resolve\sparameters\sBind\s$int_N\sand\s$test_T\sin\sfuzzcheck\sinputs.
-D 2024-08-12T09:49:02.212
+C Infrastructure\sfor\sa\snew\stest\sprogram\snamed\s"iotester"\sthat\sstrives\sto\sverify\nthe\soperation\sof\sa\sVFS\sobject.
+D 2024-08-13T19:30:03.469
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
-F Makefile.in cf96aa7d2682650dec56dc2f03cfe463feb101a1be594e4929bcd38662bc2ea8
+F Makefile.in b3af743d2ce5be536a2643143847feca680a745e309a8884a9b45220f56228ab
 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
-F Makefile.msc 6c3fe8b6ce60e73f34a148c957d78b4648745c8d30e792423aa1a8d8bf12d065
+F Makefile.msc 744d25d85ceb0080b147cfc188740fbdba1a45a53f08a421f530fb80b60eadba
 F README.md 6358805260a03ebead84e168bbf3740ddf3f683b477e478567186aa7afb490d3
 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -1337,6 +1337,7 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
 F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
 F test/ioerr5.test 5984da7bf74b6540aa356f2ab0c6ae68a6d12039a3d798a9ac6a100abc17d520
 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
+F test/iotester.c 4df6dff77a78162808854dd6d3810ed4fe2a8fe4ba5e95a74575548f23480026
 F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9
 F test/join.test f7abfef3faeaf2800308872e33a57e5b6e4a2b44fb8c6b90c6068412e71a6cf4
 F test/join2.test 8561fe82ce434ac96de91544072e578dc2cadddf2d9bc9cd802f866a9b92502e
@@ -2204,8 +2205,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P d4014c87ba9b011a6a04c2bf85879b668dc762ebcbbfb50a2f8a417ce594ef88
-R 33ab7e360692d6ed2c1cd4d18565e8ac
+P 9c10664416274df6f8da53ddd86f6356c9704ad798fd4034d2784ae433c1c056
+R d53719958cd6e7f4f987278bf19c1278
 U drh
-Z 32b23835ef00f951c0107d2a77ff843c
+Z 4d2d6900391d50d204c15f38c15fadf7
 # Remove this line to create a well-formed Fossil manifest.
index ef73d7fbbd58cdc6b95b664df3258b9e8e748b96..6e9d3c73387318b5eeb11121a18d8a56e4b341b8 100644 (file)
@@ -1 +1 @@
-9c10664416274df6f8da53ddd86f6356c9704ad798fd4034d2784ae433c1c056
+b46d86c22bd486789affa9c5e41b8f6ee47bae23eee5efe0640db3d3860e8a7a
diff --git a/test/iotester.c b/test/iotester.c
new file mode 100644 (file)
index 0000000..56bb287
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+** 2024-08-13
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** A program to test I/O through a VFS implementations.
+**
+** This program is intended as a template for custom test module used
+** to verify ports of SQLite to non-standard platforms.  Typically
+** porting SQLite to a new platform requires writing a new VFS object
+** to implement the I/O methods required by SQLite.  This file contains
+** code that attempts exercise such a VFS object and verify that it is
+** operating correctly.
+*/
+#include "sqlite3.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* Number of elements in static array X */
+#define COUNT(X)  (sizeof(X)/sizeof(X[0]))
+
+/*
+** State of the tester.
+*/
+typedef struct IOTester IOTester;
+struct IOTester {
+  int pgsz;                    /* Databases should use this page size */
+  const char *zJMode;          /* Databases should use this journal mode */
+  int isExclusive;             /* True for exclusive locking mode */
+  sqlite3_int64 szMMap;        /* Memory-map size */
+  const char *zTestModule;     /* Test module currently running */
+  int iTestNum;                /* Test number currently running */
+  int nTest;                   /* Total number of tests run */
+  int nFault;                  /* Number of test failures */
+  int nOOM;                    /* Out of memory faults */
+  int eVerbosity;              /* How much output */
+  sqlite3_str *errTxt;         /* Error text written here */
+};
+
+
+/* Forward declarations of subroutines and functions. */
+void iotestError(IOTester*,const char *zFormat, ...);
+sqlite3 *iotestOpenDb(IOTester*,const char *zDbName);
+void iotestUnlink(IOTester *p, const char *zFilename);
+void iotestBeginTest(IOTester *p, int iTestnum);
+
+
+void iotestBasic1(IOTester*);
+
+
+/********************************** Utilities *******************************
+**
+** Functions intended for common use by all test modules.
+*/
+
+/*
+** Record a test failure.
+*/
+void iotestError(IOTester *p, const char *zFormat, ...){
+  va_list ap;
+  p->nFault++;
+  if( p->errTxt==0 ){
+    p->errTxt = sqlite3_str_new(0);
+    if( p==0 ){
+      p->nOOM++;
+      return;
+    }
+  }
+  sqlite3_str_appendf(p->errTxt,
+     "FAULT: %s-%d pgsz=%d journal-mode=%s mmap-size=%lld",
+     p->zTestModule, p->iTestNum,
+     p->pgsz, p->zJMode, p->szMMap);
+  if( p->isExclusive ){
+     sqlite3_str_appendf(p->errTxt, " exclusive-locking-mode");
+  }
+  sqlite3_str_appendf(p->errTxt, "\n");
+  if( zFormat ){
+    va_start(ap, zFormat);
+    sqlite3_str_vappendf(p->errTxt, zFormat, ap);
+    va_end(ap);
+  }
+}
+
+/*
+** Create a new prepared statement based on SQL text.
+*/
+sqlite3_stmt *iotestVPrepare(
+  IOTester *p,
+  sqlite3 *db,
+  const char *zFormat,
+  va_list ap
+){
+  char *zSql = 0;
+  int rc;
+  sqlite3_stmt *pStmt = 0;
+  if( db==0 ) return 0;
+  zSql = sqlite3_vmprintf(zFormat, ap);
+  if( zSql==0 ){
+    p->nOOM++;
+    return 0;
+  }
+  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+  if( rc!=SQLITE_OK || pStmt==0 ){
+    iotestError(p, "unable to prepare statement: \"%s\"\n", zSql);
+    sqlite3_free(zSql);
+    sqlite3_finalize(pStmt);
+  }
+  return pStmt;
+}
+
+
+/*
+** Run a statement against a database.  Expect no results.
+*/
+void iotestRun(
+  IOTester *p,
+  sqlite3 *db,
+  const char *zSql,
+  ...
+){
+  va_list ap;
+  sqlite3_stmt *pStmt = 0;
+  if( db==0 ) return;
+  va_start(ap, zSql);
+  pStmt = iotestVPrepare(p, db, zSql, ap);
+  va_end(ap);
+  if( pStmt ){
+    int rc;
+    while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){}
+    if( rc==SQLITE_ERROR ){
+      iotestError(p, "error running SQL statement %s: %s\n",
+                   sqlite3_sql(pStmt), sqlite3_errmsg(db));
+    }
+  }
+  sqlite3_finalize(pStmt);
+}
+
+/*
+** Run a query against a database that returns a single integer.
+*/
+sqlite3_int64 iotestQueryInt(
+  IOTester *p,
+  sqlite3 *db,
+  sqlite3_int64 iDflt,
+  const char *zSql,
+  ...
+){
+  va_list ap;
+  sqlite3_stmt *pStmt = 0;
+  sqlite3_int64 res = iDflt;
+  int rc;
+  if( db==0 ) return iDflt;
+  va_start(ap, zSql);
+  pStmt = iotestVPrepare(p, db, zSql, ap);
+  va_end(ap);
+  if( pStmt==0 ){
+    return iDflt;
+  }
+  rc = sqlite3_step(pStmt);
+  if( rc==SQLITE_ROW ){
+    res = sqlite3_column_int64(pStmt, 0);
+  }else if( rc==SQLITE_ERROR ){
+    iotestError(p, "error while running \"%s\": %s\n",
+                 sqlite3_sql(pStmt), sqlite3_errmsg(db));
+    res = iDflt;
+  }
+  sqlite3_finalize(pStmt);
+  return res;
+}
+
+/*
+** Open a database.  Return a pointer to that database connection,
+** or if something goes wrong, return a NULL pointer.
+**
+** If the database does not previously exist, then do all the necessary
+** setup as proscribed by the IOTester configuration.
+*/
+sqlite3 *iotestOpen(IOTester *p, const char *zDbFilename){
+  sqlite3 *db;
+  int rc;
+
+  rc = sqlite3_open(zDbFilename, &db);
+  if( rc!=SQLITE_OK ){
+    iotestError(p, "cannot open database \"%s\"\n", zDbFilename);
+    sqlite3_close(db);
+    return 0;
+  }
+  if( iotestQueryInt(p, db, -1, "PRAGMA page_count")==0 ){
+    iotestRun(p, db, "PRAGMA page_size=%d", p->pgsz);
+    iotestRun(p, db, "PRAGMA journal_mode=%s", p->zJMode);
+    iotestRun(p, db, "PRAGMA mmap_size=%lld", p->szMMap);
+    if( p->isExclusive ){
+      iotestRun(p, db, "PRAGMA locking_mode=EXCLUSIVE;");
+    }
+    iotestRun(p, db, "PRAGMA cache_size=2;");
+  }
+  return db;
+}
+
+
+/*********************************** Test Modules ****************************
+*/
+void iotestBasic1(IOTester *p){
+  sqlite3 *db = 0;
+  p->zTestModule = "basic1";
+  iotestBeginTest(p, 1);
+  iotestUnlink(p, "basic1.db");
+  if( p->nFault ) return;
+  iotestBeginTest(p, 2);
+  db = iotestOpen(p, "basic1.db");
+  if( p->nFault ) goto basic1_exit;
+  iotestBeginTest(p, 3);
+  iotestRun(p, db, "CREATE TABLE t1(a,b,c);");
+  if( p->nFault ) goto basic1_exit;
+  iotestBeginTest(p, 4);
+  iotestRun(p, db, "DROP TABLE t1;");
+
+basic1_exit:
+  sqlite3_close(db);
+  iotestUnlink(p, "basic1.db");
+}
+
+/********************** Out-Of-Band System Interactions **********************
+**
+** Any customizations that need to be made to port this test program to
+** new platforms are made below this point.
+**
+** These functions access the filesystem directly or make other system
+** interactions that are non-portable.  Modify these routines as necessary
+** to work on alternative operating systems.
+*/
+#include <stdio.h>
+#ifdef _WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <errno.h>
+#endif
+
+/* Remove the named file from disk, if it exists.
+**
+** If the file does not exist, this routine is a no-op.
+** If the file does exists but could not be removed, this routine raises
+** and error in the IOTester module.
+*/
+void iotestUnlink(IOTester *p, const char *zFilename){
+  int rc;
+#ifdef _WIN32
+  rc = remove(zFilename);
+#else
+  rc = unlink(zFilename);
+#endif
+  if( rc!=0 && errno!=ENOENT ){
+    iotestError(p, "cannot delete file \"%s\"\n", zFilename);
+  }
+}
+
+/*
+** Start a new test case.  (This is under the "Out-of-band" section because
+** of its optional use of printf().)
+*/
+void iotestBeginTest(IOTester *p, int iTN){
+  p->iTestNum = iTN;
+  p->nTest++;
+  if( p->eVerbosity>=2 ) printf("%s-%d\n", p->zTestModule, iTN);
+}
+
+/*********************************** Main ************************************
+**
+** The main test driver.
+*/
+int main(int argc, char **argv){
+  IOTester x;
+  int i;
+  static const int aPgsz[] = {
+     512, 1024, 2048, 4096, 8192, 16384, 32768, 65536
+  };
+  static const char *azJMode[] = {
+     "delete", "truncate", "persist", "wal"
+  };
+  static const sqlite3_int64 aszMMap[] = {
+     0, 2097152, 2147483648
+  };
+  memset(&x, 0, sizeof(x));
+  for(i=1; i<argc; i++){
+    const char *z = argv[i];
+    if( z[0]=='-' && z[1]=='-' && z[2]!=0 ) z++;
+    if( strcmp(z,"-v")==0 ){
+      x.eVerbosity++;
+    }else if( strcmp(z, "-vv")==0 ){
+      x.eVerbosity += 2;
+    }else if (strcmp(z, "-vfs")==0 && i<argc-1 ){
+      int rc;
+      sqlite3_vfs *pNew = sqlite3_vfs_find(argv[++i]);
+      if( pNew==0 ){
+        iotestError(&x, "No such VFS: \"%s\"\n", argv[i]);
+        break;
+      }
+      rc = sqlite3_vfs_register(pNew, 1);
+      if( rc!=SQLITE_OK ){
+        iotestError(&x, "Unable to register VFS \"%s\" - result code %d\n",
+                     argv[i], rc);
+        break;
+      }
+    }else{
+      iotestError(&x, "unknown option: \"%s\"\n", argv[i]);
+      break;
+    }
+  }
+  for(i=0; x.nFault==0 && i<COUNT(aPgsz)*COUNT(azJMode)*COUNT(aszMMap)*2; i++){
+    int j,k;
+    j = i;
+    k = j % COUNT(aPgsz);
+    x.pgsz = aPgsz[k];
+    j /= COUNT(aPgsz);
+    k = j % COUNT(azJMode);
+    x.zJMode = azJMode[k];
+    j /= COUNT(azJMode);
+    k = j % COUNT(aszMMap);
+    x.szMMap = aszMMap[k];
+    j /= COUNT(aszMMap);
+    k = j % 2;
+    x.isExclusive = k;
+    j /= 2;
+
+    if( x.eVerbosity>=1 ){
+      printf("pgsz=%d journal_mode=%s mmap_size=%lld exclusive=%d\n",
+             x.pgsz, x.zJMode, x.szMMap, x.isExclusive);
+    }
+
+    iotestBasic1(&x);
+    if( x.nFault ) break;
+  }
+
+  /* Report results */
+  printf("%d tests and %d errors\n", x.nTest, x.nFault);
+  if( x.nOOM ) printf("%d out-of-memory faults\n", x.nOOM);
+  if( x.errTxt ){
+    char *zMsg = sqlite3_str_finish(x.errTxt);
+    if( zMsg ){
+      printf("%s", zMsg);
+      sqlite3_free(zMsg);
+    }
+  }
+  return x.nFault>0; 
+}