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 }