1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
-
+
+
+
-
-
-
+
+
-
-
-
+
-
-
+
-
-
+
-
-
-
-
+
+
-
-
-
-
-
-
+
|
/*
** 2010-07-22
**
** 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.
**
*************************************************************************
**
** The code in this file runs a few multi-threaded test cases using the
** SQLite library. It can be compiled to an executable on unix using the
** following command:
**
** gcc -O2 threadtest3.c sqlite3.c -ldl -lpthread -lm
**
** Even though threadtest3.c is the only C source code file mentioned on
** Then run the compiled program. The exit status is non-zero if any tests
** the compiler command-line, #include macros are used to pull in additional
** failed (hopefully there is also some output to stdout to clarify what went
** wrong).
** C code files named "tt3_*.c".
**
** There are three parts to the code in this file, in the following order:
** After compiling, run this program with an optional argument telling
** which test to run. All tests are run if no argument is given. The
** argument can be a glob pattern to match multiple tests. Examples:
**
** 1. Code for the SQL aggregate function md5sum() copied from
** tclsqlite.c in the SQLite distribution. The names of all the
** types and functions in this section begin with "MD5" or "md5".
** ./a.out -- Run all tests
** ./a.out walthread3 -- Run the "walthread3" test
**
** 2. A set of utility functions that may be used to implement
** multi-threaded test cases. These are all called by test code
** ./a.out 'wal*' -- Run all of the wal* tests
** via macros that help with error reporting. The macros are defined
** immediately below this comment.
** ./a.out --help -- List all available tests
**
** 3. The test code itself. And a main() routine to drive the test
** code.
** The exit status is non-zero if any test fails.
*/
/*************************************************************************
** Start of test code/infrastructure interface macros.
**
** The following macros constitute the interface between the test
/*
** The "Set Error Line" macro.
** programs and the test infrastructure. Test infrastructure code
** does not itself use any of these macros. Test code should not
** call any of the macroname_x() functions directly.
**
** See the header comments above the corresponding macroname_x()
** function for a description of each interface.
*/
#define SEL(e) ((e)->iLine = ((e)->rc ? (e)->iLine : __LINE__))
/* Database functions */
#define opendb(w,x,y,z) (SEL(w), opendb_x(w,x,y,z))
#define closedb(y,z) (SEL(y), closedb_x(y,z))
/* Functions to execute SQL */
#define sql_script(x,y,z) (SEL(x), sql_script_x(x,y,z))
|
︙ | | |
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
|
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
|
-
+
-
+
|
char zBuf[33];
p = sqlite3_aggregate_context(context, sizeof(*p));
MD5Final(digest,p);
MD5DigestToBase16(digest, zBuf);
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
/*************************************************************************
/*
** End of copied md5sum() code.
*/
**************************************************************************/
typedef sqlite3_int64 i64;
typedef struct Error Error;
typedef struct Sqlite Sqlite;
typedef struct Statement Statement;
|
︙ | | |
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
|
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
|
-
+
+
|
p->zErr = 0;
p->rc = 0;
}
static void print_err(Error *p){
if( p->rc!=SQLITE_OK ){
printf("Error: (%d) \"%s\" at line %d\n", p->rc, p->zErr, p->iLine);
nGlobalErr++;
if( sqlite3_strglob("* - no such table: *",p->zErr)!=0 ) nGlobalErr++;
fflush(stdout);
}
}
static void print_and_free_err(Error *p){
print_err(p);
free_err(p);
}
|
︙ | | |
781
782
783
784
785
786
787
788
789
790
791
792
793
794
|
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
|
+
|
pNext = p->pNext;
int rc;
rc = pthread_join(p->tid, &ret);
if( rc!=0 ){
if( pErr->rc==SQLITE_OK ) system_error(pErr, rc);
}else{
printf("Thread %d says: %s\n", p->iTid, (ret==0 ? "..." : (char *)ret));
fflush(stdout);
}
sqlite3_free(p);
}
pThreads->pThread = 0;
}
static i64 filesize_x(
|
︙ | | |
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
|
896
897
898
899
900
901
902
903
904
905
906
907
908
909
|
-
-
-
-
-
|
}else{
ret = (t >= timelimit);
}
}
return ret;
}
/*
** The "Set Error Line" macro.
*/
#define SEL(e) ((e)->iLine = ((e)->rc ? (e)->iLine : __LINE__))
/*************************************************************************
**************************************************************************
**************************************************************************
** End infrastructure. Begin tests.
*/
|
︙ | | |
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
|
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
|
-
-
-
+
+
+
|
#include "tt3_index.c"
#include "tt3_lookaside1.c"
#include "tt3_vacuum.c"
#include "tt3_stress.c"
int main(int argc, char **argv){
struct ThreadTest {
void (*xTest)(int);
const char *zTest;
int nMs;
void (*xTest)(int); /* Routine for running this test */
const char *zTest; /* Name of this test */
int nMs; /* How long to run this test, in milliseconds */
} aTest[] = {
{ walthread1, "walthread1", 20000 },
{ walthread2, "walthread2", 20000 },
{ walthread3, "walthread3", 20000 },
{ walthread4, "walthread4", 20000 },
{ walthread5, "walthread5", 1000 },
{ walthread5, "walthread5", 1000 },
|
︙ | | |
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
|
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
|
-
+
+
-
+
-
+
-
+
-
-
|
{ lookaside1, "lookaside1", 10000 },
{ vacuum1, "vacuum1", 10000 },
{ stress1, "stress1", 10000 },
{ stress2, "stress2", 60000 },
};
int i;
int bTestfound = 0;
int nTestfound = 0;
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
for(i=0; i<sizeof(aTest)/sizeof(aTest[0]); i++){
char const *z = aTest[i].zTest;
if( argc>1 ){
int iArg;
for(iArg=1; iArg<argc; iArg++){
if( 0==sqlite3_strglob(argv[iArg], z) ) break;
}
if( iArg==argc ) continue;
}
printf("Running %s for %d seconds...\n", z, aTest[i].nMs/1000);
fflush(stdout);
aTest[i].xTest(aTest[i].nMs);
bTestfound++;
nTestfound++;
}
if( bTestfound==0 ) goto usage;
if( nTestfound==0 ) goto usage;
printf("Total of %d errors across all tests\n", nGlobalErr);
printf("%d errors out of %d tests\n", nGlobalErr, nTestfound);
return (nGlobalErr>0 ? 255 : 0);
usage:
printf("Usage: %s [testname|testprefix*]...\n", argv[0]);
printf("Available tests are:\n");
for(i=0; i<sizeof(aTest)/sizeof(aTest[0]); i++){
printf(" %s\n", aTest[i].zTest);
}
return 254;
}
|