Snapshot of upstream SQLite 3.45.3
[sqlcipher.git] / ext / lsm1 / lsm-test / lsmtest4.c
bloba47241db929504e918b3310927249401132e4261
2 /*
3 ** This file contains test cases involving multiple database clients.
4 */
6 #include "lsmtest.h"
8 /*
9 ** The following code implements test cases "mc1.*".
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.
15 ** The test consists of $nStep steps. Each step the following is performed:
17 ** 1. The writer inserts $nWriteStep records into the db.
19 ** 2. The writer checks that the contents of the db are as expected.
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).
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.
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 */
39 static void do_mc_test(
40 const char *zSystem, /* Database system to test */
41 Mctest *pTest,
42 int *pRc /* IN/OUT: return code */
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 */
51 /* Array of reader connections */
52 struct Reader {
53 TestDb *pDb; /* Connection handle */
54 int iLast; /* Current snapshot contains keys 0..iLast */
55 } *aReader;
57 /* Create a data source */
58 pData = testDatasourceNew(&pTest->defn);
60 /* Open the writer connection */
61 pDb = testOpen(zSystem, 1, pRc);
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);
69 for(iStep=0; iStep<pTest->nStep; iStep++){
70 int iLast;
71 int iBegin; /* Start read trans using aReader[iBegin] */
73 /* Insert nWriteStep more records into the database */
74 int iFirst = iStep*pTest->nWriteStep;
75 testWriteDatasourceRange(pDb, pData, iFirst, pTest->nWriteStep, pRc);
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);
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;
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
95 /* Report progress */
96 testCaseProgress(iStep, pTest->nStep, testCaseNDot(), &iDot);
99 /* Close all readers */
100 for(iReader=0; iReader<pTest->nReader; iReader++){
101 testClose(&aReader[iReader].pDb);
103 testFree(aReader);
105 /* Close the writer-connection and free the datasource */
106 testClose(&pDb);
107 testDatasourceFree(pData);
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 */
116 int i;
117 Mctest aTest[] = {
118 { { TEST_DATASOURCE_RANDOM, 10,10, 100,100 }, 100, 10, 5 },
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);