Upgrade thread001.test to test with multiple database handles. (CVS 4417)
FossilOrigin-Name: 6ee2b8ffc4310c8e329f634f3ade058b33c53a2a
This commit is contained in:
parent
667a6c98e9
commit
d9b5b1177d
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\san\sundeclared\sidentifier\sin\san\sIOTRACE\s(debugging)\sblock.\s(CVS\s4416)
|
||||
D 2007-09-10T06:12:04
|
||||
C Upgrade\sthread001.test\sto\stest\swith\smultiple\sdatabase\shandles.\s(CVS\s4417)
|
||||
D 2007-09-10T06:23:54
|
||||
F Makefile.in cbfb898945536a8f9ea8b897e1586dd1fdbcc5db
|
||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -156,7 +156,7 @@ F src/test_md5.c 34599caee5b1c73dcf86ca31f55846fab8c19ef7
|
||||
F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
|
||||
F src/test_server.c 1020673fc02ba5bbfa5dc96ded9f54f0f3744d38
|
||||
F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
||||
F src/test_thread.c 35d2b6c83b18cc32961e868a7e784e9eed6c94e9
|
||||
F src/test_thread.c cbd7ba2cb295df9c9a8e848a8886c8d0f318de27
|
||||
F src/tokenize.c 67e42600ab34f976f2b1288c499ad6c98d652f0e
|
||||
F src/trigger.c 724a77d54609a33bde90618934fbeddfcc729a10
|
||||
F src/update.c e89b980b443d44b68bfc0b1746cdb6308e049ac9
|
||||
@ -425,7 +425,7 @@ F test/tableapi.test 036575a98dcce7c92e9f39056839bbad8a715412
|
||||
F test/tclsqlite.test a868898e3350246be7ea132621dc25f9835b3030
|
||||
F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821
|
||||
F test/tester.tcl 913a808f05b0aed2fbb16481a423b1a5a118bdf0
|
||||
F test/thread001.test 52ea6333672d4b6d11a637be45582a0154a838b5
|
||||
F test/thread001.test 956b80909cbec7cf2f2540bf1c8bb573052f0868
|
||||
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
||||
F test/thread2.test 6d7b30102d600f51b4055ee3a5a19228799049fb
|
||||
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
||||
@ -573,7 +573,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P 9b7bab7fc28201b62159e959651acb980095ad06
|
||||
R 90d4db77fefa25d20916043e00059852
|
||||
P 48e59c747f2be08102f16290fa57dfffc2ae920d
|
||||
R e7956c3743bdd54859507fb25353105c
|
||||
U danielk1977
|
||||
Z 01c5bb4b8b727cf6a26f0f3b84249e3e
|
||||
Z 0ed31afa9b04e141d583b88b37a43f9c
|
||||
|
@ -1 +1 @@
|
||||
48e59c747f2be08102f16290fa57dfffc2ae920d
|
||||
6ee2b8ffc4310c8e329f634f3ade058b33c53a2a
|
@ -14,7 +14,7 @@
|
||||
** test that sqlite3 database handles may be concurrently accessed by
|
||||
** multiple threads. Right now this only works on unix.
|
||||
**
|
||||
** $Id: test_thread.c,v 1.2 2007/09/07 18:40:38 danielk1977 Exp $
|
||||
** $Id: test_thread.c,v 1.3 2007/09/10 06:23:54 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
@ -108,14 +108,17 @@ static Tcl_ThreadCreateType tclScriptThread(ClientData pSqlThread){
|
||||
Tcl_IncrRefCount(pList);
|
||||
Tcl_IncrRefCount(pRes);
|
||||
|
||||
if( rc==TCL_OK ){
|
||||
Tcl_ListObjAppendElement(interp, pList, Tcl_NewStringObj("set", -1));
|
||||
Tcl_ListObjAppendElement(interp, pList, Tcl_NewStringObj(p->zVarname, -1));
|
||||
}else{
|
||||
if( rc!=TCL_OK ){
|
||||
Tcl_ListObjAppendElement(interp, pList, Tcl_NewStringObj("error", -1));
|
||||
Tcl_ListObjAppendElement(interp, pList, pRes);
|
||||
postToParent(p, pList);
|
||||
Tcl_DecrRefCount(pList);
|
||||
pList = Tcl_NewObj();
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, pList, pRes);
|
||||
|
||||
Tcl_ListObjAppendElement(interp, pList, Tcl_NewStringObj("set", -1));
|
||||
Tcl_ListObjAppendElement(interp, pList, Tcl_NewStringObj(p->zVarname, -1));
|
||||
Tcl_ListObjAppendElement(interp, pList, pRes);
|
||||
postToParent(p, pList);
|
||||
|
||||
ckfree((void *)p);
|
||||
@ -216,6 +219,37 @@ static int sqlthread_parent(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int xBusy(void *pArg, int nBusy){
|
||||
sqlite3_sleep(50);
|
||||
return 1; /* Try again... */
|
||||
}
|
||||
|
||||
static int sqlthread_open(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int sqlite3TestMakePointerStr(Tcl_Interp *interp, char *zPtr, void *p);
|
||||
|
||||
const char *zFilename;
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
char zBuf[100];
|
||||
extern void Md5_Register(sqlite3*);
|
||||
|
||||
zFilename = Tcl_GetString(objv[2]);
|
||||
rc = sqlite3_open(zFilename, &db);
|
||||
Md5_Register(db);
|
||||
sqlite3_busy_handler(db, xBusy, 0);
|
||||
|
||||
if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Dispatch routine for the sub-commands of [sqlthread].
|
||||
*/
|
||||
@ -233,6 +267,7 @@ static int sqlthread_proc(
|
||||
} aSub[] = {
|
||||
{"parent", sqlthread_parent, 1, "SCRIPT"},
|
||||
{"spawn", sqlthread_spawn, 2, "VARNAME SCRIPT"},
|
||||
{"open", sqlthread_open, 1, "DBNAME"},
|
||||
{0, 0, 0}
|
||||
};
|
||||
struct SubCommand *pSub;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# $Id: thread001.test,v 1.2 2007/09/07 18:40:38 danielk1977 Exp $
|
||||
# $Id: thread001.test,v 1.3 2007/09/10 06:23:54 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -23,32 +23,11 @@ if {[info commands sqlthread] eq ""} {
|
||||
return
|
||||
}
|
||||
|
||||
# Set up a database and a schema. The database contains a single
|
||||
# table with two columns. The first column ("a") is an INTEGER PRIMARY
|
||||
# KEY. The second contains the md5sum of all rows in the table with
|
||||
# a smaller value stored in column "a".
|
||||
#
|
||||
do_test thread001.1 {
|
||||
execsql {
|
||||
CREATE TABLE ab(a INTEGER PRIMARY KEY, b);
|
||||
CREATE INDEX ab_i ON ab(b);
|
||||
INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab;
|
||||
SELECT count(*) FROM ab;
|
||||
}
|
||||
} {1}
|
||||
do_test thread001.2 {
|
||||
execsql {
|
||||
SELECT
|
||||
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
|
||||
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
|
||||
}
|
||||
} {1}
|
||||
do_test thread001.3 {
|
||||
execsql { PRAGMA integrity_check }
|
||||
} {ok}
|
||||
set ::NTHREAD 10
|
||||
|
||||
set thread_program [format {
|
||||
set ::DB %s
|
||||
# The following script is sourced by every thread spawned using
|
||||
# [sqlthread spawn]:
|
||||
set thread_procs {
|
||||
|
||||
# Execute the supplied SQL using database handle $::DB.
|
||||
#
|
||||
@ -73,60 +52,112 @@ set thread_program [format {
|
||||
error "$name failed: expected \"$result\" got \"$res\""
|
||||
}
|
||||
}
|
||||
|
||||
for {set i 0} {$i < 100} {incr i} {
|
||||
# Test that the invariant is true.
|
||||
do_test t1 {
|
||||
execsql {
|
||||
SELECT
|
||||
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
|
||||
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
|
||||
}
|
||||
} {1}
|
||||
|
||||
# Add another row to the database.
|
||||
execsql { INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab }
|
||||
}
|
||||
|
||||
list OK
|
||||
} [sqlite3_connection_pointer db]]
|
||||
|
||||
# Kick off 10 threads:
|
||||
#
|
||||
array unset finished
|
||||
for {set i 0} {$i < 10} {incr i} {
|
||||
sqlthread spawn finished($i) $thread_program
|
||||
}
|
||||
|
||||
for {set i 0} {$i < 10} {incr i} {
|
||||
if {![info exists finished($i)]} {
|
||||
vwait finished($i)
|
||||
}
|
||||
do_test thread001.4.$i {
|
||||
set ::finished($i)
|
||||
} OK
|
||||
proc thread_spawn {varname args} {
|
||||
sqlthread spawn $varname [join $args ;]
|
||||
}
|
||||
|
||||
do_test thread001.5 {
|
||||
execsql { SELECT count(*) FROM ab; }
|
||||
} {1001}
|
||||
do_test thread001.6 {
|
||||
execsql {
|
||||
SELECT
|
||||
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
|
||||
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
|
||||
}
|
||||
} {1}
|
||||
do_test thread001.7 {
|
||||
execsql { PRAGMA integrity_check }
|
||||
} {ok}
|
||||
#########################################################################
|
||||
# End of infrastruture. Start of test cases.
|
||||
#########################################################################
|
||||
|
||||
# Give the event-handlers a chance to close any open parent-child pipes.
|
||||
# Otherwise, the test is reported as leaking memory (it has not - it's
|
||||
# just that the memory is freed asynchronously).
|
||||
|
||||
# Run this test twice: Once with all threads using the same database
|
||||
# connection, and once with each using it's own connection.
|
||||
#
|
||||
after 250 {set abit 0}
|
||||
vwait abit
|
||||
foreach {dbconfig tn} [list "set ::DB $::DB" 1 "" 2] {
|
||||
|
||||
# Empty the database.
|
||||
#
|
||||
catchsql { DROP TABLE ab; }
|
||||
|
||||
# Set up a database and a schema. The database contains a single
|
||||
# table with two columns. The first column ("a") is an INTEGER PRIMARY
|
||||
# KEY. The second contains the md5sum of all rows in the table with
|
||||
# a smaller value stored in column "a".
|
||||
#
|
||||
do_test thread001.$tn.1 {
|
||||
execsql {
|
||||
CREATE TABLE ab(a INTEGER PRIMARY KEY, b);
|
||||
CREATE INDEX ab_i ON ab(b);
|
||||
INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab;
|
||||
SELECT count(*) FROM ab;
|
||||
}
|
||||
} {1}
|
||||
do_test thread001.$tn.2 {
|
||||
execsql {
|
||||
SELECT
|
||||
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
|
||||
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
|
||||
}
|
||||
} {1}
|
||||
do_test thread001.$tn.3 {
|
||||
execsql { PRAGMA integrity_check }
|
||||
} {ok}
|
||||
|
||||
set thread_program {
|
||||
set needToClose 0
|
||||
if {![info exists ::DB]} {
|
||||
set ::DB [sqlthread open test.db]
|
||||
set needToClose 1
|
||||
}
|
||||
|
||||
for {set i 0} {$i < 100} {incr i} {
|
||||
# Test that the invariant is true.
|
||||
do_test t1 {
|
||||
execsql {
|
||||
SELECT
|
||||
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
|
||||
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
|
||||
}
|
||||
} {1}
|
||||
|
||||
# Add another row to the database.
|
||||
execsql { INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab }
|
||||
}
|
||||
|
||||
if {$needToClose} {
|
||||
sqlite3_close $::DB
|
||||
}
|
||||
|
||||
list OK
|
||||
}
|
||||
|
||||
# Kick off $::NTHREAD threads:
|
||||
#
|
||||
array unset finished
|
||||
for {set i 0} {$i < $::NTHREAD} {incr i} {
|
||||
thread_spawn finished($i) $dbconfig $thread_procs $thread_program
|
||||
}
|
||||
|
||||
# Wait for all threads to finish, then check they all returned "OK".
|
||||
#
|
||||
for {set i 0} {$i < $::NTHREAD} {incr i} {
|
||||
if {![info exists finished($i)]} {
|
||||
vwait finished($i)
|
||||
}
|
||||
do_test thread001.$tn.4.$i {
|
||||
set ::finished($i)
|
||||
} OK
|
||||
}
|
||||
|
||||
# Check the database still looks Ok.
|
||||
#
|
||||
do_test thread001.$tn.5 {
|
||||
execsql { SELECT count(*) FROM ab; }
|
||||
} [expr {1 + $::NTHREAD*100}]
|
||||
do_test thread001.$tn.6 {
|
||||
execsql {
|
||||
SELECT
|
||||
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
|
||||
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
|
||||
}
|
||||
} {1}
|
||||
do_test thread001.$tn.7 {
|
||||
execsql { PRAGMA integrity_check }
|
||||
} {ok}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user