Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Test cases to improve coverage of pager.c. (CVS 2205) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0428a1480126f7e73dc1e24b6fbfa185 |
User & Date: | danielk1977 2005-01-13 11:07:53.000 |
Context
2005-01-13
| ||
11:10 | Fix typo in shell .help. Ticket #1071. (CVS 2206) (check-in: 2c7a1a1698 user: danielk1977 tags: trunk) | |
11:07 | Test cases to improve coverage of pager.c. (CVS 2205) (check-in: 0428a14801 user: danielk1977 tags: trunk) | |
02:14 | Fixes to 'configure' build system. Also extra coverage for main.c. (CVS 2204) (check-in: 8378455f32 user: danielk1977 tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.182 2005/01/13 11:07:53 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
354 355 356 357 358 359 360 | */ /* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */ #define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1) /* ** Enable reference count tracking (for debugging) here: */ | | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | */ /* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */ #define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1) /* ** Enable reference count tracking (for debugging) here: */ #ifdef SQLITE_DEBUG int pager3_refinfo_enable = 0; static void pager_refinfo(PgHdr *p){ static int cnt = 0; if( !pager3_refinfo_enable ) return; sqlite3DebugPrintf( "REFCNT: %4d addr=%p nRef=%d\n", p->pgno, PGHDR_TO_DATA(p), p->nRef |
︙ | ︙ | |||
502 503 504 505 506 507 508 | /* If the checksum doesn't add up, then one or more of the disk sectors ** containing the master journal filename is corrupted. This means ** definitely roll back, so just return SQLITE_OK and report a (nul) ** master-journal filename. */ sqliteFree(*pzMaster); *pzMaster = 0; | | | > | 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | /* If the checksum doesn't add up, then one or more of the disk sectors ** containing the master journal filename is corrupted. This means ** definitely roll back, so just return SQLITE_OK and report a (nul) ** master-journal filename. */ sqliteFree(*pzMaster); *pzMaster = 0; }else{ (*pzMaster)[len] = '\0'; } return SQLITE_OK; } /* ** Seek the journal file descriptor to the next sector boundary where a ** journal header may be read or written. Pager.journalOff is updated with |
︙ | ︙ | |||
1825 1826 1827 1828 1829 1830 1831 | sqlite3OsClose(&pPager->fd); assert( pPager->journalOpen==0 ); /* Temp files are automatically deleted by the OS ** if( pPager->tempFile ){ ** sqlite3OsDelete(pPager->zFilename); ** } */ | < < < < < | | 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 | sqlite3OsClose(&pPager->fd); assert( pPager->journalOpen==0 ); /* Temp files are automatically deleted by the OS ** if( pPager->tempFile ){ ** sqlite3OsDelete(pPager->zFilename); ** } */ sqliteFree(pPager); return SQLITE_OK; } /* ** Return the page number for the given page data. */ |
︙ | ︙ | |||
1875 1876 1877 1878 1879 1880 1881 | pPg->pPager->pLast = pPg->pPrevFree; } pPg->pPager->nRef++; } pPg->nRef++; REFINFO(pPg); } | | | 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 | pPg->pPager->pLast = pPg->pPrevFree; } pPg->pPager->nRef++; } pPg->nRef++; REFINFO(pPg); } #ifdef SQLITE_DEBUG static void page_ref(PgHdr *pPg){ if( pPg->nRef==0 ){ _page_ref(pPg); }else{ pPg->nRef++; REFINFO(pPg); } |
︙ | ︙ |
Changes to src/test2.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the pager.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the pager.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test2.c,v 1.28 2005/01/13 11:07:54 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include "pager.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
371 372 373 374 375 376 377 378 379 380 381 382 383 384 | pPage = sqlite3pager_lookup(pPager, pgno); if( pPage ){ sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage); Tcl_AppendResult(interp, zBuf, 0); } return TCL_OK; } /* ** Usage: page_unref PAGE ** ** Drop a pointer to a page. */ static int page_unref( | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | pPage = sqlite3pager_lookup(pPager, pgno); if( pPage ){ sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage); Tcl_AppendResult(interp, zBuf, 0); } return TCL_OK; } /* ** Usage: pager_truncate ID PGNO */ static int pager_truncate( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Pager *pPager; int rc; int pgno; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID PGNO\"", 0); return TCL_ERROR; } pPager = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; rc = sqlite3pager_truncate(pPager, pgno); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; } /* ** Usage: page_unref PAGE ** ** Drop a pointer to a page. */ static int page_unref( |
︙ | ︙ | |||
549 550 551 552 553 554 555 556 557 558 559 560 561 562 | { "pager_pagecount", (Tcl_CmdProc*)pager_pagecount }, { "page_get", (Tcl_CmdProc*)page_get }, { "page_lookup", (Tcl_CmdProc*)page_lookup }, { "page_unref", (Tcl_CmdProc*)page_unref }, { "page_read", (Tcl_CmdProc*)page_read }, { "page_write", (Tcl_CmdProc*)page_write }, { "page_number", (Tcl_CmdProc*)page_number }, { "fake_big_file", (Tcl_CmdProc*)fake_big_file }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } Tcl_LinkVar(interp, "sqlite_io_error_pending", | > | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | { "pager_pagecount", (Tcl_CmdProc*)pager_pagecount }, { "page_get", (Tcl_CmdProc*)page_get }, { "page_lookup", (Tcl_CmdProc*)page_lookup }, { "page_unref", (Tcl_CmdProc*)page_unref }, { "page_read", (Tcl_CmdProc*)page_read }, { "page_write", (Tcl_CmdProc*)page_write }, { "page_number", (Tcl_CmdProc*)page_number }, { "pager_truncate", (Tcl_CmdProc*)pager_truncate }, { "fake_big_file", (Tcl_CmdProc*)fake_big_file }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } Tcl_LinkVar(interp, "sqlite_io_error_pending", |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1030 1031 1032 1033 1034 1035 1036 | return rc; } /* Write the name of each database file in the transaction into the new ** master journal file. If an error occurs at this point close ** and delete the master journal file. All the individual journal files ** still have 'null' as the master journal pointer, so they will roll | | | 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 | return rc; } /* Write the name of each database file in the transaction into the new ** master journal file. If an error occurs at this point close ** and delete the master journal file. All the individual journal files ** still have 'null' as the master journal pointer, so they will roll ** back independently if a failure occurs. */ for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( i==1 ) continue; /* Ignore the TEMP database */ if( pBt && sqlite3BtreeIsInTrans(pBt) ){ char const *zFile = sqlite3BtreeGetJournalname(pBt); if( zFile[0]==0 ) continue; /* Ignore :memory: databases */ |
︙ | ︙ |
Changes to test/all.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2001 September 15 # # 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. # #*********************************************************************** # This file runs all tests. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 2001 September 15 # # 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. # #*********************************************************************** # This file runs all tests. # # $Id: all.test,v 1.27 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl rename finish_test really_finish_test proc finish_test {} {memleak_check} if {[file exists ./sqlite_test_count]} { |
︙ | ︙ | |||
111 112 113 114 115 116 117 | } puts " Ok" } # Run the crashtest only on unix and only once. If the library does not # always create auto-vacuum databases, also run autovacuum_crash.test. # | | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | } puts " Ok" } # Run the crashtest only on unix and only once. If the library does not # always create auto-vacuum databases, also run autovacuum_crash.test. # if {$::tcl_platform(platform)=="unix"} { source $testdir/crash.test ifcapable !default_autovacuum { source $testdir/autovacuum_crash.test } } # Run the malloc tests and the misuse test after memory leak detection. |
︙ | ︙ |
Changes to test/crash.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 | # module "crashtest" compiled with the special "os_test.c" backend is used. # The os_test.c simulates the kind of file corruption that can occur # when writes are happening at the moment of power loss. # # The special crash-test module with its os_test.c backend only works # on Unix. # | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # module "crashtest" compiled with the special "os_test.c" backend is used. # The os_test.c simulates the kind of file corruption that can occur # when writes are happening at the moment of power loss. # # The special crash-test module with its os_test.c backend only works # on Unix. # # $Id: crash.test,v 1.14 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # set repeats 100 set repeats 10 |
︙ | ︙ | |||
402 403 404 405 406 407 408 409 410 411 412 413 414 415 | crashsql 1 test.db { DROP TABLE abc; } } {1 {child process exited abnormally}} do_test crash-6.2 { signature } $sig # The AUTOVACUUM was changed above. We have to reset it for # other scripts that run as part of "fulltest" # set AUTOVACUUM $sqlite_options(default_autovacuum) finish_test | > > > > > > > > > > > > > > > > > > > > > > > > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | crashsql 1 test.db { DROP TABLE abc; } } {1 {child process exited abnormally}} do_test crash-6.2 { signature } $sig #-------------------------------------------------------------------------- # These test cases test the case where the master journal file name is # corrupted slightly so that the corruption has to be detected by the # checksum. do_test crash-7.1 { crashsql 1 test.db { ATTACH 'test2.db' AS aux; BEGIN; INSERT INTO abc VALUES(randstr(1500,1500), 0, 0); INSERT INTO abc2 VALUES(randstr(1500,1500), 0, 0); COMMIT; } # Change the checksum value for the master journal name. set f [open test.db-journal a] fconfigure $f -encoding binary seek $f [expr [file size test.db-journal] - 12] puts -nonewline $f "\00\00\00\00" close $f } {} do_test crash-7.2 { signature } $sig # The AUTOVACUUM was changed above. We have to reset it for # other scripts that run as part of "fulltest" # set AUTOVACUUM $sqlite_options(default_autovacuum) finish_test |
Changes to test/ioerr.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # This file implements regression tests for SQLite library. The # focus of this file is testing for correct handling of I/O errors # such as writes failing because the disk is full. # # The tests in this file use special facilities that are only # available in the SQLite test fixture. # | | > > > > | | | 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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | # This file implements regression tests for SQLite library. The # focus of this file is testing for correct handling of I/O errors # such as writes failing because the disk is full. # # The tests in this file use special facilities that are only # available in the SQLite test fixture. # # $Id: ioerr.test,v 1.12 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::AV [execsql {pragma auto_vacuum}] # Usage: do_ioerr_test <test number> <options...> # # The first argument, <test number>, is an integer used to name the # tests executed by this proc. Options are as follows: # # -tclprep TCL script to run to prepare test. # -sqlprep SQL script to run to prepare test. # -tclbody TCL script to run with IO error simulation. # -sqlbody TCL script to run with IO error simulation. # -exclude List of 'N' values not to test. # -start Value of 'N' to begin with (default 1) # proc do_ioerr_test {tn args} { array set ::ioerropts $args set ::go 1 if {![info exists ::ioerropts(-start)]} { set ::ioerropts(-start) 1 } for {set n $::ioerropts(-start)} {$::go} {incr n} { if {[info exists ::ioerropts(-exclude)]} { if {[lsearch $::ioerropts(-exclude) $n]!=-1} continue } do_test ioerr-$tn.$n.1 { set ::sqlite_io_error_pending 0 catch {db close} catch {file delete -force test.db} catch {file delete -force test.db-journal} catch {file delete -force test2.db} catch {file delete -force test2.db-journal} set ::DB [sqlite3 db test.db] |
︙ | ︙ | |||
76 77 78 79 80 81 82 83 84 85 86 87 88 89 | do_test ioerr-$tn.$n.3 { set r [catch $::ioerrorbody msg] set ::go [expr {$::sqlite_io_error_pending<=0}] expr {$::sqlite_io_error_pending>0 || $r!=0} } {1} } set ::sqlite_io_error_pending 0 } # If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error # on the 8th IO operation in the SQL script below doesn't report an error. # # This is because the 8th IO call attempts to read page 2 of the database # file when the file on disk is only 1 page. The pager layer detects that | > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | do_test ioerr-$tn.$n.3 { set r [catch $::ioerrorbody msg] set ::go [expr {$::sqlite_io_error_pending<=0}] expr {$::sqlite_io_error_pending>0 || $r!=0} } {1} } set ::sqlite_io_error_pending 0 unset ::ioerropts } # If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error # on the 8th IO operation in the SQL script below doesn't report an error. # # This is because the 8th IO call attempts to read page 2 of the database # file when the file on disk is only 1 page. The pager layer detects that |
︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 219 220 221 222 | execsql $sql execsql {INSERT INTO abc (a1) VALUES(NULL)} } -sqlbody { SELECT * FROM abc; } # Test IO errors that may occur during a multi-file commit. do_ioerr_test 5 -sqlprep { ATTACH 'test2.db' AS test2; } -sqlbody { BEGIN; CREATE TABLE t1(a,b,c); CREATE TABLE test2.t2(a,b,c); COMMIT; | > > > > | > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | execsql $sql execsql {INSERT INTO abc (a1) VALUES(NULL)} } -sqlbody { SELECT * FROM abc; } # Test IO errors that may occur during a multi-file commit. # # Test 8 is excluded when auto-vacuum is enabled for the same reason # as in test cases ioerr-1.XXX do_ioerr_test 5 -sqlprep { ATTACH 'test2.db' AS test2; } -sqlbody { BEGIN; CREATE TABLE t1(a,b,c); CREATE TABLE test2.t2(a,b,c); COMMIT; } -exclude [expr [execsql {pragma auto_vacuum}] ? 8 : 0] # Test IO errors when replaying two hot journals from a 2-file # transaction. This test only runs on UNIX. if {$tcl_platform(platform)=="unix"} { do_ioerr_test 6 -tclprep { set rc [crashsql 2 test2.db-journal { ATTACH 'test2.db' as aux; PRAGMA cache_size = 10; BEGIN; CREATE TABLE aux.t2(a, b, c); CREATE TABLE t1(a, b, c); COMMIT; }] if {$rc!="1 {child process exited abnormally}"} { error "Wrong error message: $rc" } } -sqlbody { ATTACH 'test2.db' as aux; SELECT * FROM t1; SELECT * FROM t2; } } # Test handling of IO errors that occur while rolling back hot journal # files. do_ioerr_test 14 -tclprep { db close sqlite3 db2 test2.db db2 eval { PRAGMA synchronous = 0; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); BEGIN; INSERT INTO t1 VALUES(3, 4); } file copy -force test2.db test.db file copy -force test2.db-journal test.db-journal db2 close } -tclbody { sqlite3 db test.db db eval { SELECT * FROM t1; } } -exclude 1 # do_ioerr_test 15 -sqlprep { # CREATE TABLE abc(a UNIQUE, b, c); # INSERT INTO abc VALUES(1, 2, 3); # } -sqlbody { # BEGIN; # INSERT INTO abc VALUES(1, 2, 3); # COMMIT; # } finish_test |
Changes to test/malloc.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 | #*********************************************************************** # This file attempts to check the library in an out-of-memory situation. # When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special # command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This # special feature is used to see what happens in the library if a malloc # were to really fail due to an out-of-memory situation. # | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #*********************************************************************** # This file attempts to check the library in an out-of-memory situation. # When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special # command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This # special feature is used to see what happens in the library if a malloc # were to really fail due to an out-of-memory situation. # # $Id: malloc.test,v 1.19 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # if {[info command sqlite_malloc_stat]==""} { |
︙ | ︙ | |||
92 93 94 95 96 97 98 99 100 101 102 103 104 105 | } else { set v2 [expr {$msg=="" || $msg=="out of memory"}] if {!$v2} {puts "\nError message returned: $msg"} lappend v $v2 } } {1 1} } } for {set go 1; set i 1} {$go} {incr i} { do_test malloc-1.$i { sqlite_malloc_fail 0 catch {db close} catch {file delete -force test.db} | > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | } else { set v2 [expr {$msg=="" || $msg=="out of memory"}] if {!$v2} {puts "\nError message returned: $msg"} lappend v $v2 } } {1 1} } unset ::mallocopts } for {set go 1; set i 1} {$go} {incr i} { do_test malloc-1.$i { sqlite_malloc_fail 0 catch {db close} catch {file delete -force test.db} |
︙ | ︙ | |||
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 | do_malloc_test 12 -tclbody { set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] append sql16 "\00\00" set ::STMT [sqlite3_prepare16 $::DB $sql16 -1 DUMMY] sqlite3_finalize $::STMT } # Ensure that no file descriptors were leaked. do_test malloc-99.X { catch {db close} set sqlite_open_file_count } {0} sqlite_malloc_fail 0 finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | do_malloc_test 12 -tclbody { set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] append sql16 "\00\00" set ::STMT [sqlite3_prepare16 $::DB $sql16 -1 DUMMY] sqlite3_finalize $::STMT } # Test malloc errors when replaying two hot journals from a 2-file # transaction. This test only runs on UNIX. if {$tcl_platform(platform)=="unix"} { do_malloc_test 13 -tclprep { set rc [crashsql 1 test2.db { ATTACH 'test2.db' as aux; PRAGMA cache_size = 10; BEGIN; CREATE TABLE aux.t2(a, b, c); CREATE TABLE t1(a, b, c); COMMIT; }] if {$rc!="1 {child process exited abnormally}"} { error "Wrong error message: $rc" } } -sqlbody { ATTACH 'test2.db' as aux; SELECT * FROM t1; SELECT * FROM t2; } } do_malloc_test 14 -tclprep { catch {db close} sqlite3 db2 test2.db db2 eval { PRAGMA synchronous = 0; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); BEGIN; INSERT INTO t1 VALUES(3, 4); } file copy -force test2.db test.db file copy -force test2.db-journal test.db-journal db2 close } -tclbody { sqlite3 db test.db db eval { SELECT * FROM t1; } } # Ensure that no file descriptors were leaked. do_test malloc-99.X { catch {db close} set sqlite_open_file_count } {0} sqlite_malloc_fail 0 finish_test |
Changes to test/pager.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is page cache subsystem. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is page cache subsystem. # # $Id: pager.test,v 1.19 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl if {[info commands pager_open]!=""} { db close |
︙ | ︙ | |||
391 392 393 394 395 396 397 398 399 400 401 402 403 404 | set res } {} do_test pager-4.5.$i.10 { pager_commit $p1 lrange [pager_stats $p1] 8 9 } {state 1} } do_test pager-4.99 { pager_close $::p1 } {} | > > > > > > > > > > > > > > > > > > > > | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | set res } {} do_test pager-4.5.$i.10 { pager_commit $p1 lrange [pager_stats $p1] 8 9 } {state 1} } # Test that nothing bad happens when sqlite3pager_set_cachesize() is # called with a negative argument. do_test pager-4.6.1 { pager_close [pager_open ptf2.db -15] } {} # Test truncate on an in-memory database is Ok. do_test pager-4.6.2 { set ::p2 [pager_open :memory: 10] pager_truncate $::p2 5 } {} do_test pager-4.6.3 { for {set i 1} {$i<5} {incr i} { set p [page_get $::p2 $i] page_write $p "Page $i" pager_commit $::p2 } pager_truncate $::p2 3 } {} do_test pager-4.99 { pager_close $::p1 } {} |
︙ | ︙ | |||
417 418 419 420 421 422 423 424 | CREATE TABLE t1(x); PRAGMA synchronous=off; COMMIT; } } {} } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | CREATE TABLE t1(x); PRAGMA synchronous=off; COMMIT; } } {} } do_test pager-6.1 { file delete -force test2.db file delete -force test2.db-journal sqlite3 db2 test2.db execsql { PRAGMA synchronous = 0; CREATE TABLE abc(a, b, c); INSERT INTO abc VALUES(1, 2, randstr(200,200)); INSERT INTO abc VALUES(1, 2, randstr(200,200)); INSERT INTO abc VALUES(1, 2, randstr(200,200)); INSERT INTO abc VALUES(1, 2, randstr(200,200)); INSERT INTO abc VALUES(1, 2, randstr(200,200)); INSERT INTO abc VALUES(1, 2, randstr(200,200)); INSERT INTO abc VALUES(1, 2, randstr(200,200)); INSERT INTO abc VALUES(1, 2, randstr(200,200)); INSERT INTO abc VALUES(1, 2, randstr(200,200)); BEGIN; UPDATE abc SET c = randstr(200,200); } db2 file copy -force test2.db test.db file copy -force test2.db-journal test.db-journal set f [open test.db-journal a] fconfigure $f -encoding binary seek $f [expr [file size test.db-journal] - 1032] start puts -nonewline $f "\00\00\00\00" close $f sqlite3 db test.db execsql { SELECT sql FROM sqlite_master } } {{CREATE TABLE abc(a, b, c)}} do_test pager-6.2 { file copy -force test2.db test.db file copy -force test2.db-journal test.db-journal set f [open test.db-journal a] fconfigure $f -encoding binary seek $f [expr [file size test.db-journal] - 1032] start puts -nonewline $f "\00\00\00\FF" close $f sqlite3 db test.db execsql { SELECT sql FROM sqlite_master } } {{CREATE TABLE abc(a, b, c)}} do_test pager-6.3 { file copy -force test2.db test.db file copy -force test2.db-journal test.db-journal set f [open test.db-journal a] fconfigure $f -encoding binary seek $f [expr [file size test.db-journal] - 4] start puts -nonewline $f "\00\00\00\00" close $f sqlite3 db test.db execsql { SELECT sql FROM sqlite_master } } {{CREATE TABLE abc(a, b, c)}} do_test pager-6.4 { db2 close } {} finish_test |
Changes to test/tester.tcl.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # 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. # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # 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. # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # # $Id: tester.tcl,v 1.44 2005/01/13 11:07:54 danielk1977 Exp $ # Make sure tclsqlite3 was compiled correctly. Abort now with an # error message if not. # if {[sqlite3 -tcl-uses-utf]} { if {"\u1234"=="u1234"} { puts stderr "***** BUILD PROBLEM *****" |
︙ | ︙ | |||
241 242 243 244 245 246 247 248 249 250 251 | # code. Omit the code if false. # proc ifcapable {expr code} { regsub -all {[a-z_0-9]+} $expr {$::sqlite_options(&)} e2 if !($e2) return return -code [catch {uplevel 1 $code}] } # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | # code. Omit the code if false. # proc ifcapable {expr code} { regsub -all {[a-z_0-9]+} $expr {$::sqlite_options(&)} e2 if !($e2) return return -code [catch {uplevel 1 $code}] } # This proc execs a seperate process that crashes midway through executing # the SQL script $sql on database test.db. # # The crash occurs during a sync() of file $crashfile. When the crash # occurs a random subset of all unsynced writes made by the process are # written into the files on disk. Argument $crashdelay indicates the # number of file syncs to wait before crashing. # # The return value is a list of two elements. The first element is a # boolean, indicating whether or not the process actually crashed or # reported some other error. The second element in the returned list is the # error message. This is "child process exited abnormally" if the crash # occured. # proc crashsql {crashdelay crashfile sql} { if {$::tcl_platform(platform)!="unix"} { error "crashsql should only be used on unix" } set cfile [file join [pwd] $crashfile] set f [open crash.tcl w] puts $f "sqlite3_crashparams $crashdelay $cfile" puts $f "sqlite3 db test.db" puts $f "db eval {pragma cache_size = 10}" puts $f "db eval {" puts $f "$sql" puts $f "}" close $f set r [catch { exec [file join . crashtest] crash.tcl >@stdout } msg] lappend r $msg } # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum) |