Add a case to permutations.test to run tests with the test_journal.c backend installed. Also many fixes to test_journal.c and one quite obscure fix to pager.c. (CVS 6052)
FossilOrigin-Name: bb177e3072ab61d0af7af91660ebe4dafa487b42
This commit is contained in:
parent
852e232922
commit
f3107512f7
@ -371,6 +371,7 @@ TESTSRC = \
|
||||
$(TOP)/src/test_devsym.c \
|
||||
$(TOP)/src/test_func.c \
|
||||
$(TOP)/src/test_hexio.c \
|
||||
$(TOP)/src/test_journal.c \
|
||||
$(TOP)/src/test_malloc.c \
|
||||
$(TOP)/src/test_md5.c \
|
||||
$(TOP)/src/test_mutex.c \
|
||||
|
22
manifest
22
manifest
@ -1,7 +1,7 @@
|
||||
C Fix\sa\svariable\stype\sto\sprevent\sa\swarning\sin\sthe\sproxy-locking\scode.\s(CVS\s6051)
|
||||
D 2008-12-22T03:37:00
|
||||
C Add\sa\scase\sto\spermutations.test\sto\srun\stests\swith\sthe\stest_journal.c\sbackend\sinstalled.\sAlso\smany\sfixes\sto\stest_journal.c\sand\sone\squite\sobscure\sfix\sto\spager.c.\s(CVS\s6052)
|
||||
D 2008-12-22T10:58:46
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in f7e4c81c347b04f7b0f1c1b081a168645d7b8af7
|
||||
F Makefile.in 77635d0909c2067cee03889a1e04ce910d8fb809
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
F Makefile.vxwSH4 d53b4be86491060d498b22148951b6d765884cab
|
||||
F README b974cdc3f9f12b87e851b04e75996d720ebf81ac
|
||||
@ -142,7 +142,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
||||
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
|
||||
F src/os_unix.c e6eacc7ec735ded605fefcbaf250058baa8feb12
|
||||
F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
|
||||
F src/pager.c 5c2b49c37db966bc312ff28d296767961fb894c3
|
||||
F src/pager.c 4fc24d29d699c00169a129fa6835a1ea31598873
|
||||
F src/pager.h 7191294438881eb4d13eedade97891e8dc993905
|
||||
F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057
|
||||
F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6
|
||||
@ -179,7 +179,7 @@ F src/test_config.c 4f85387a52f3c7966c3ffab913e988a3830fe1af
|
||||
F src/test_devsym.c 9f4bc2551e267ce7aeda195f3897d0f30c5228f4
|
||||
F src/test_func.c a55c4d5479ff2eb5c0a22d4d88e9528ab59c953b
|
||||
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
|
||||
F src/test_journal.c 74b97d631841b0ebd55e54ba059f61299f537667
|
||||
F src/test_journal.c aec37656038150fa60f0418d54b1c535b5b33430
|
||||
F src/test_loadext.c 97dc8800e46a46ed002c2968572656f37e9c0dd9
|
||||
F src/test_malloc.c 5127337c9fb4c851a7f604c0170e0e5ca1fbfe33
|
||||
F src/test_md5.c 28209a4e2068711b5443c33104fe41f21d160071
|
||||
@ -476,7 +476,7 @@ F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a
|
||||
F test/pagesize.test 0d9ff3fedfce6e5ffe8fa7aca9b6d3433a2e843b
|
||||
F test/pcache.test 515b4c26e9f57660357dfff5b6b697acac1abc5f
|
||||
F test/pcache2.test 46efd980a89f737847b99327bda19e08fe11e402
|
||||
F test/permutations.test 5308a94878efc81a8e8ce133926dfb2c53d19133
|
||||
F test/permutations.test 4fd4c7944c42201799c0e2855261f54e1bfda6d2
|
||||
F test/pragma.test 0f299601c3b15e8941eb48d2f7a43e6678e3f735
|
||||
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
||||
F test/printf.test 262a5acd3158f788e9bdf7f18d718f3af32ff6ef
|
||||
@ -493,7 +493,7 @@ F test/rowid.test 1c8fc43c60d273e6ea44dfb992db587f3164312c
|
||||
F test/rtree.test b85fd4f0861a40ca366ac195e363be2528dcfadf
|
||||
F test/safety.test b69e2b2dd5d52a3f78e216967086884bbc1a09c6
|
||||
F test/savepoint.test 24b7d67971c0b7a8d22ba1cabbfd846e72f21594
|
||||
F test/savepoint2.test e1c29bd8341a0214903455971833603852254279
|
||||
F test/savepoint2.test 18f6c75d5c133b93838019df8988b8cdf379d3de
|
||||
F test/savepoint3.test b3c9aa5af3f777ccb8b9e15597c75c93eb5bc369
|
||||
F test/savepoint4.test fd8850063e3c40565545f5c291e7f79a30591670
|
||||
F test/schema.test a8b000723375fd42c68d310091bdbd744fde647c
|
||||
@ -607,7 +607,7 @@ F test/tkt3541.test 5dc257bde9bc833ab9cc6844bf170b998dbb950a
|
||||
F test/tkt35xx.test 53bca895091e968126a858ee7da186f59f328994
|
||||
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||
F test/trace.test 951cd0f5f571e7f36bf7bfe04be70f90fb16fb00
|
||||
F test/trans.test 2fd24cd7aa0b879d49a224cbd647d698f1e7ac5c
|
||||
F test/trans.test b3f0c696ddf8c3f113fd2edf49318b2bf431c99a
|
||||
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
|
||||
F test/trans3.test d728abaa318ca364dc370e06576aa7e5fbed7e97
|
||||
F test/trigger1.test 53342dfd582155a599518f1918fdc997e9413177
|
||||
@ -684,7 +684,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
P 778e91ddb834f6084ecdf3909692b54bb7da8f6d
|
||||
R 24c69e7f21063e09d372b85b48a9e328
|
||||
P d9595b961800a13c141bebdb8c0a67377f30efad
|
||||
R b5374e09d172c2ab41305c978396d82d
|
||||
U danielk1977
|
||||
Z a57801844c740a64a631ffb37d80b4cc
|
||||
Z 98d2c97eeee17c8939e3e7380b43abd8
|
||||
|
@ -1 +1 @@
|
||||
d9595b961800a13c141bebdb8c0a67377f30efad
|
||||
bb177e3072ab61d0af7af91660ebe4dafa487b42
|
20
src/pager.c
20
src/pager.c
@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.519 2008/12/20 08:39:57 danielk1977 Exp $
|
||||
** @(#) $Id: pager.c,v 1.520 2008/12/22 10:58:46 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
@ -3280,6 +3280,17 @@ static int pager_write(PgHdr *pPg){
|
||||
PAGERID(pPager), pPg->pgno,
|
||||
((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg));
|
||||
|
||||
/* Even if an IO or diskfull error occurred while journalling the
|
||||
** page in the block above, set the need-sync flag for the page.
|
||||
** Otherwise, when the transaction is rolled back, the logic in
|
||||
** playback_one_page() will think that the page needs to be restored
|
||||
** in the database file. And if an IO error occurs while doing so,
|
||||
** then corruption may follow.
|
||||
*/
|
||||
if( !pPager->noSync ){
|
||||
pPg->flags |= PGHDR_NEED_SYNC;
|
||||
}
|
||||
|
||||
/* An error has occured writing to the journal file. The
|
||||
** transaction will be rolled back by the layer above.
|
||||
*/
|
||||
@ -3290,9 +3301,6 @@ static int pager_write(PgHdr *pPg){
|
||||
pPager->nRec++;
|
||||
assert( pPager->pInJournal!=0 );
|
||||
sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
|
||||
if( !pPager->noSync ){
|
||||
pPg->flags |= PGHDR_NEED_SYNC;
|
||||
}
|
||||
addToSavepointBitvecs(pPager, pPg->pgno);
|
||||
}else{
|
||||
if( !pPager->journalStarted && !pPager->noSync ){
|
||||
@ -4001,11 +4009,11 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
|
||||
pPager->nSavepoint = nNew;
|
||||
|
||||
if( op==SAVEPOINT_ROLLBACK ){
|
||||
PagerSavepoint *pSavepoint = (nNew==0) ? 0 : &pPager->aSavepoint[nNew-1];
|
||||
PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
|
||||
rc = pagerPlaybackSavepoint(pPager, pSavepoint);
|
||||
assert(rc!=SQLITE_DONE);
|
||||
}
|
||||
|
||||
|
||||
/* If this is a release of the outermost savepoint, truncate
|
||||
** the sub-journal. */
|
||||
if( nNew==0 && op==SAVEPOINT_RELEASE && pPager->sjfd->pMethods ){
|
||||
|
@ -19,7 +19,7 @@
|
||||
** b) the page was not a free-list leaf page when the transaction was
|
||||
** first opened.
|
||||
**
|
||||
** $Id: test_journal.c,v 1.1 2008/12/20 18:33:59 danielk1977 Exp $
|
||||
** $Id: test_journal.c,v 1.2 2008/12/22 10:58:46 danielk1977 Exp $
|
||||
*/
|
||||
#if SQLITE_TEST /* This file is used for testing only */
|
||||
|
||||
@ -134,6 +134,11 @@ struct JtGlobal {
|
||||
};
|
||||
static struct JtGlobal g = {0, 0};
|
||||
|
||||
static void closeTransaction(jt_file *p){
|
||||
sqlite3BitvecDestroy(p->pWritable);
|
||||
p->pWritable = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close an jt-file.
|
||||
*/
|
||||
@ -142,7 +147,7 @@ static int jtClose(sqlite3_file *pFile){
|
||||
jt_file *p = (jt_file *)pFile;
|
||||
|
||||
if( p->zName ){
|
||||
for(pp=&g.pList; *pp!=p; *pp=(*pp)->pNext);
|
||||
for(pp=&g.pList; *pp!=p; pp=&(*pp)->pNext);
|
||||
*pp = p->pNext;
|
||||
}
|
||||
|
||||
@ -183,23 +188,25 @@ static u32 decodeUint32(const unsigned char *z){
|
||||
return (z[0]<<24) + (z[1]<<16) + (z[2]<<8) + z[3];
|
||||
}
|
||||
|
||||
static void readFreelist(jt_file *pMain){
|
||||
static int readFreelist(jt_file *pMain){
|
||||
int rc;
|
||||
sqlite3_file *p = pMain->pReal;
|
||||
sqlite3_int64 iSize;
|
||||
|
||||
sqlite3OsFileSize(p, &iSize);
|
||||
if( iSize>=pMain->nPagesize ){
|
||||
rc = sqlite3OsFileSize(p, &iSize);
|
||||
if( rc==SQLITE_OK && iSize>=pMain->nPagesize ){
|
||||
unsigned char *zBuf = (unsigned char *)malloc(pMain->nPagesize);
|
||||
u32 iTrunk;
|
||||
|
||||
sqlite3OsRead(p, zBuf, pMain->nPagesize, 0);
|
||||
rc = sqlite3OsRead(p, zBuf, pMain->nPagesize, 0);
|
||||
iTrunk = decodeUint32(&zBuf[32]);
|
||||
while( iTrunk>0 ){
|
||||
while( rc==SQLITE_OK && iTrunk>0 ){
|
||||
u32 nLeaf;
|
||||
u32 iLeaf;
|
||||
sqlite3OsRead(p, zBuf, pMain->nPagesize, (iTrunk-1)*pMain->nPagesize);
|
||||
sqlite3_int64 iOff = (iTrunk-1)*pMain->nPagesize;
|
||||
rc = sqlite3OsRead(p, zBuf, pMain->nPagesize, iOff);
|
||||
nLeaf = decodeUint32(&zBuf[4]);
|
||||
for(iLeaf=0; iLeaf<nLeaf; iLeaf++){
|
||||
for(iLeaf=0; rc==SQLITE_OK && iLeaf<nLeaf; iLeaf++){
|
||||
u32 pgno = decodeUint32(&zBuf[8+4*iLeaf]);
|
||||
sqlite3BitvecSet(pMain->pWritable, pgno);
|
||||
}
|
||||
@ -208,6 +215,8 @@ static void readFreelist(jt_file *pMain){
|
||||
|
||||
free(zBuf);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -249,20 +258,24 @@ static int jtWrite(
|
||||
if( decodeJournalHdr(zBuf, 0, &pMain->nPage, 0, &pMain->nPagesize) ){
|
||||
/* Zeroing the first journal-file header. This is the end of a
|
||||
** transaction. */
|
||||
sqlite3BitvecDestroy(pMain->pWritable);
|
||||
pMain->pWritable = 0;
|
||||
closeTransaction(pMain);
|
||||
}else{
|
||||
/* Writing the first journal header to a journal file. This happens
|
||||
** when a transaction is first started. */
|
||||
int rc;
|
||||
pMain->pWritable = sqlite3BitvecCreate(pMain->nPage);
|
||||
readFreelist(pMain);
|
||||
if( !pMain->pWritable ){
|
||||
return SQLITE_IOERR_NOMEM;
|
||||
}
|
||||
rc = readFreelist(pMain);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
|
||||
u32 pgno;
|
||||
assert( iAmt==p->nPagesize );
|
||||
pgno = iOfst/p->nPagesize + 1;
|
||||
if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable && iAmt==p->nPagesize ){
|
||||
u32 pgno = iOfst/p->nPagesize + 1;
|
||||
assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) );
|
||||
}
|
||||
|
||||
@ -277,8 +290,7 @@ static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){
|
||||
/* Truncating a journal file. This is the end of a transaction. */
|
||||
jt_file *pMain = locateDatabaseHandle(p->zName);
|
||||
sqlite3BitvecDestroy(pMain->pWritable);
|
||||
pMain->pWritable = 0;
|
||||
closeTransaction(pMain);
|
||||
}
|
||||
return sqlite3OsTruncate(p->pReal, size);
|
||||
}
|
||||
@ -288,31 +300,41 @@ static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||
** This function reads the journal file and adds the page number for each
|
||||
** page in the journal to the Bitvec object passed as the second argument.
|
||||
*/
|
||||
static void readJournalFile(jt_file *p, jt_file *pMain){
|
||||
static int readJournalFile(jt_file *p, jt_file *pMain){
|
||||
int rc;
|
||||
unsigned char zBuf[28];
|
||||
sqlite3_file *pReal = p->pReal;
|
||||
sqlite3_int64 iOff = 0;
|
||||
sqlite3_int64 iSize = 0;
|
||||
|
||||
sqlite3OsFileSize(p->pReal, &iSize);
|
||||
while( iOff<iSize ){
|
||||
rc = sqlite3OsFileSize(p->pReal, &iSize);
|
||||
while( rc==SQLITE_OK && iOff<iSize ){
|
||||
u32 nRec, nPage, nSector, nPagesize;
|
||||
u32 ii;
|
||||
sqlite3OsRead(pReal, zBuf, 28, iOff);
|
||||
if( decodeJournalHdr(zBuf, &nRec, &nPage, &nSector, &nPagesize) ){
|
||||
return;
|
||||
rc = sqlite3OsRead(pReal, zBuf, 28, iOff);
|
||||
if( rc!=SQLITE_OK
|
||||
|| decodeJournalHdr(zBuf, &nRec, &nPage, &nSector, &nPagesize)
|
||||
){
|
||||
return rc;
|
||||
}
|
||||
iOff += nSector;
|
||||
for(ii=0; ii<nRec && iOff<iSize; ii++){
|
||||
if( nRec==0 ){
|
||||
nRec = (iSize - iOff)/(pMain->nPagesize + 8);
|
||||
}
|
||||
for(ii=0; rc==SQLITE_OK && ii<nRec && iOff<iSize; ii++){
|
||||
u32 pgno;
|
||||
sqlite3OsRead(pReal, zBuf, 4, iOff);
|
||||
pgno = decodeUint32(zBuf);
|
||||
iOff += (8 + pMain->nPagesize);
|
||||
sqlite3BitvecSet(pMain->pWritable, pgno);
|
||||
rc = sqlite3OsRead(pReal, zBuf, 4, iOff);
|
||||
if( rc==SQLITE_OK ){
|
||||
pgno = decodeUint32(zBuf);
|
||||
iOff += (8 + pMain->nPagesize);
|
||||
sqlite3BitvecSet(pMain->pWritable, pgno);
|
||||
}
|
||||
}
|
||||
|
||||
iOff = ((iOff + (nSector-1)) / nSector) * nSector;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -322,6 +344,7 @@ static int jtSync(sqlite3_file *pFile, int flags){
|
||||
jt_file *p = (jt_file *)pFile;
|
||||
|
||||
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){
|
||||
int rc;
|
||||
jt_file *pMain; /* The associated database file */
|
||||
|
||||
/* The journal file is being synced. At this point, we inspect the
|
||||
@ -331,10 +354,14 @@ static int jtSync(sqlite3_file *pFile, int flags){
|
||||
*/
|
||||
pMain = locateDatabaseHandle(p->zName);
|
||||
assert(pMain);
|
||||
assert(pMain->pWritable);
|
||||
|
||||
/* Set the bitvec values */
|
||||
readJournalFile(p, pMain);
|
||||
if( pMain->pWritable ){
|
||||
rc = readJournalFile(p, pMain);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sqlite3OsSync(p->pReal, flags);
|
||||
@ -426,6 +453,7 @@ static int jtOpen(
|
||||
p->zName = zName;
|
||||
p->flags = flags;
|
||||
p->pNext = 0;
|
||||
p->pWritable = 0;
|
||||
if( zName ){
|
||||
p->pNext = g.pList;
|
||||
g.pList = p;
|
||||
@ -444,8 +472,9 @@ static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
||||
if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){
|
||||
/* Deleting a journal file. The end of a transaction. */
|
||||
jt_file *pMain = locateDatabaseHandle(zPath);
|
||||
sqlite3BitvecDestroy(pMain->pWritable);
|
||||
pMain->pWritable = 0;
|
||||
if( pMain ){
|
||||
closeTransaction(pMain);
|
||||
}
|
||||
}
|
||||
|
||||
return sqlite3OsDelete(g.pVfs, zPath, dirSync);
|
||||
|
@ -9,7 +9,7 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# $Id: permutations.test,v 1.39 2008/11/19 01:20:26 drh Exp $
|
||||
# $Id: permutations.test,v 1.40 2008/12/22 10:58:46 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -39,7 +39,7 @@ if {$::perm::testmode eq "all" || $::perm::testmode eq ""} {
|
||||
set ::perm::testmode {
|
||||
memsubsys1 memsubsys2 singlethread multithread onefile utf16 exclusive
|
||||
persistent_journal persistent_journal_error no_journal no_journal_error
|
||||
autovacuum_ioerr no_mutex_try fullmutex
|
||||
autovacuum_ioerr no_mutex_try fullmutex journaltest
|
||||
}
|
||||
}
|
||||
if {$::perm::testmode eq "targets"} {
|
||||
@ -705,6 +705,21 @@ run_tests "pcache100" -description {
|
||||
sqlite3_initialize
|
||||
} -include ${perm-alt-pcache-testset}
|
||||
|
||||
run_tests "journaltest" -description {
|
||||
Check that pages are synced before being written (test_journal.c).
|
||||
} -initialize {
|
||||
set ISQUICK 1
|
||||
catch {db close}
|
||||
register_jt_vfs -default ""
|
||||
} -shutdown {
|
||||
unregister_jt_vfs
|
||||
} -exclude [concat $EXCLUDE {
|
||||
incrvacuum.test
|
||||
ioerr.test
|
||||
corrupt4.test
|
||||
io.test
|
||||
}]
|
||||
|
||||
# End of tests
|
||||
#############################################################################
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# $Id: savepoint2.test,v 1.3 2008/12/20 18:33:59 danielk1977 Exp $
|
||||
# $Id: savepoint2.test,v 1.4 2008/12/22 10:58:46 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -18,10 +18,6 @@ source $testdir/tester.tcl
|
||||
# avtrans.test.
|
||||
#
|
||||
|
||||
db close
|
||||
register_jt_vfs -default ""
|
||||
sqlite3 db test.db -vfs jt
|
||||
|
||||
proc signature {} {
|
||||
return [db eval {SELECT count(*), md5sum(x) FROM t3}]
|
||||
}
|
||||
@ -149,7 +145,5 @@ for {set ii 2} {$ii < ($iterations+2)} {incr ii} {
|
||||
unset -nocomplain ::sig
|
||||
unset -nocomplain SQL
|
||||
|
||||
unregister_jt_vfs
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -11,13 +11,12 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is database locks.
|
||||
#
|
||||
# $Id: trans.test,v 1.38 2008/04/19 20:34:19 drh Exp $
|
||||
# $Id: trans.test,v 1.39 2008/12/22 10:58:46 danielk1977 Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
|
||||
# Create several tables to work with.
|
||||
#
|
||||
do_test trans-1.0 {
|
||||
|
Loading…
Reference in New Issue
Block a user