modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/lsm1/lsm-test/lsmtest4.c (about)

     1  
     2  /*
     3  ** This file contains test cases involving multiple database clients.
     4  */
     5  
     6  #include "lsmtest.h"
     7  
     8  /*
     9  ** The following code implements test cases "mc1.*".
    10  **
    11  ** This test case uses one writer and $nReader readers. All connections
    12  ** are driven by a single thread. All connections are opened at the start
    13  ** of the test and remain open until the test is finished.
    14  **
    15  ** The test consists of $nStep steps. Each step the following is performed:
    16  **
    17  **   1. The writer inserts $nWriteStep records into the db.
    18  **
    19  **   2. The writer checks that the contents of the db are as expected.
    20  **
    21  **   3. Each reader that currently has an open read transaction also checks
    22  **      that the contents of the db are as expected (according to the snapshot
    23  **      the read transaction is reading - see below).
    24  **
    25  ** After step 1, reader 1 opens a read transaction. After step 2, reader
    26  ** 2 opens a read transaction, and so on. At step ($nReader+1), reader 1
    27  ** closes the current read transaction and opens a new one. And so on.
    28  ** The result is that at step N (for N > $nReader), there exists a reader
    29  ** with an open read transaction reading the snapshot committed following
    30  ** steps (N-$nReader-1) to N. 
    31  */
    32  typedef struct Mctest Mctest;
    33  struct Mctest {
    34    DatasourceDefn defn;            /* Datasource to use */
    35    int nStep;                      /* Total number of steps in test */
    36    int nWriteStep;                 /* Number of rows to insert each step */
    37    int nReader;                    /* Number of read connections */
    38  };
    39  static void do_mc_test(
    40    const char *zSystem,            /* Database system to test */
    41    Mctest *pTest,
    42    int *pRc                        /* IN/OUT: return code */
    43  ){
    44    const int nDomain = pTest->nStep * pTest->nWriteStep;
    45    Datasource *pData;              /* Source of data */
    46    TestDb *pDb;                    /* First database connection (writer) */
    47    int iReader;                    /* Used to iterate through aReader */
    48    int iStep;                      /* Current step in test */
    49    int iDot = 0;                   /* Current step in test */
    50  
    51    /* Array of reader connections */
    52    struct Reader {
    53      TestDb *pDb;                  /* Connection handle */
    54      int iLast;                    /* Current snapshot contains keys 0..iLast */
    55    } *aReader;
    56  
    57    /* Create a data source */
    58    pData = testDatasourceNew(&pTest->defn);
    59  
    60    /* Open the writer connection */
    61    pDb = testOpen(zSystem, 1, pRc);
    62  
    63    /* Allocate aReader */
    64    aReader = (struct Reader *)testMalloc(sizeof(aReader[0]) * pTest->nReader);
    65    for(iReader=0; iReader<pTest->nReader; iReader++){
    66      aReader[iReader].pDb = testOpen(zSystem, 0, pRc);
    67    }
    68  
    69    for(iStep=0; iStep<pTest->nStep; iStep++){
    70      int iLast;
    71      int iBegin;                   /* Start read trans using aReader[iBegin] */
    72  
    73      /* Insert nWriteStep more records into the database */
    74      int iFirst = iStep*pTest->nWriteStep;
    75      testWriteDatasourceRange(pDb, pData, iFirst, pTest->nWriteStep, pRc);
    76  
    77      /* Check that the db is Ok according to the writer */
    78      iLast = (iStep+1) * pTest->nWriteStep - 1;
    79      testDbContents(pDb, pData, nDomain, 0, iLast, iLast, 1, pRc);
    80  
    81      /* Have reader (iStep % nReader) open a read transaction here. */
    82      iBegin = (iStep % pTest->nReader);
    83      if( iBegin<iStep ) tdb_commit(aReader[iBegin].pDb, 0);
    84      tdb_begin(aReader[iBegin].pDb, 1);
    85      aReader[iBegin].iLast = iLast;
    86  
    87      /* Check that the db is Ok for each open reader */
    88      for(iReader=0; iReader<pTest->nReader && aReader[iReader].iLast; iReader++){
    89        iLast = aReader[iReader].iLast;
    90        testDbContents(
    91            aReader[iReader].pDb, pData, nDomain, 0, iLast, iLast, 1, pRc
    92        );
    93      }
    94  
    95      /* Report progress */
    96      testCaseProgress(iStep, pTest->nStep, testCaseNDot(), &iDot);
    97    }
    98  
    99    /* Close all readers */
   100    for(iReader=0; iReader<pTest->nReader; iReader++){
   101      testClose(&aReader[iReader].pDb);
   102    }
   103    testFree(aReader);
   104  
   105    /* Close the writer-connection and free the datasource */
   106    testClose(&pDb);
   107    testDatasourceFree(pData);
   108  }
   109  
   110  
   111  void test_mc(
   112    const char *zSystem,            /* Database system name */
   113    const char *zPattern,           /* Run test cases that match this pattern */
   114    int *pRc                        /* IN/OUT: Error code */
   115  ){
   116    int i;
   117    Mctest aTest[] = {
   118      { { TEST_DATASOURCE_RANDOM, 10,10, 100,100 }, 100, 10, 5 },
   119    };
   120  
   121    for(i=0; i<ArraySize(aTest); i++){
   122      if( testCaseBegin(pRc, zPattern, "mc1.%s.%d", zSystem, i) ){
   123        do_mc_test(zSystem, &aTest[i], pRc);
   124        testCaseFinish(*pRc);
   125      }
   126    }
   127  }