1# 2008 January 30 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# This file implements regression tests for SQLite library. The 12# focus of this file is testing the sqlite3_backup_XXX API. 13# 14# $Id: backup.test,v 1.2 2009/02/04 17:40:58 drh Exp $ 15 16set testdir [file dirname $argv0] 17source $testdir/tester.tcl 18 19#--------------------------------------------------------------------- 20# Test organization: 21# 22# backup-1.*: Warm-body tests. 23# 24# backup-2.*: Test backup under various conditions. To and from in-memory 25# databases. To and from empty/populated databases. etc. 26# 27# backup-3.*: Verify that the locking-page (pending byte page) is handled. 28# 29# backup-4.*: Test various error conditions. 30# 31# backup-5.*: Test the source database being modified during a backup. 32# 33# backup-6.*: Test the backup_remaining() and backup_pagecount() APIs. 34# 35# backup-7.*: Test SQLITE_BUSY and SQLITE_LOCKED errors. 36# 37# backup-8.*: Test multiple simultaneous backup operations. 38# 39 40proc data_checksum {db file} { $db one "SELECT md5sum(a, b) FROM ${file}.t1" } 41proc test_contents {name db1 file1 db2 file2} { 42 $db2 eval {select * from sqlite_master} 43 $db1 eval {select * from sqlite_master} 44 set checksum [data_checksum $db2 $file2] 45 uplevel [list do_test $name [list data_checksum $db1 $file1] $checksum] 46} 47 48do_test backup-1.1 { 49 execsql { 50 BEGIN; 51 CREATE TABLE t1(a, b); 52 CREATE INDEX i1 ON t1(a, b); 53 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 54 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 55 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 56 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 57 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 58 COMMIT; 59 } 60} {} 61 62# Sanity check to verify that the [test_contents] proc works. 63# 64test_contents backup-1.2 db main db main 65 66# Check that it is possible to create and finish backup operations. 67# 68do_test backup-1.3.1 { 69 file delete test2.db 70 sqlite3 db2 test2.db 71 sqlite3_backup B db2 main db main 72} {B} 73do_test backup-1.3.2 { 74 B finish 75} {SQLITE_OK} 76do_test backup-1.3.3 { 77 info commands B 78} {} 79 80# Simplest backup operation. Backup test.db to test2.db. test2.db is 81# initially empty. test.db uses the default page size. 82# 83do_test backup-1.4.1 { 84 sqlite3_backup B db2 main db main 85} {B} 86do_test backup-1.4.2 { 87 B step 200 88} {SQLITE_DONE} 89do_test backup-1.4.3 { 90 B finish 91} {SQLITE_OK} 92do_test backup-1.4.4 { 93 info commands B 94} {} 95test_contents backup-1.4.5 db2 main db main 96db close 97db2 close 98# 99# End of backup-1.* tests. 100#--------------------------------------------------------------------- 101 102 103#--------------------------------------------------------------------- 104# The following tests, backup-2.*, are based on the following procedure: 105# 106# 1) Populate the source database. 107# 2) Populate the destination database. 108# 3) Run the backup to completion. (backup-2.*.1) 109# 4) Integrity check the destination db. (backup-2.*.2) 110# 5) Check that the contents of the destination db is the same as that 111# of the source db. (backup-2.*.3) 112# 113# The test is run with all possible combinations of the following 114# input parameters, except that if the destination is an in-memory 115# database, the only page size tested is 1024 bytes (the same as the 116# source page-size). 117# 118# * Source database is an in-memory database, OR 119# * Source database is a file-backed database. 120# 121# * Target database is an in-memory database, OR 122# * Target database is a file-backed database. 123# 124# * Destination database is a main file, OR 125# * Destination database is an attached file, OR 126# * Destination database is a temp database. 127# 128# * Target database is empty (zero bytes), OR 129# * Target database is larger than the source, OR 130# * Target database is smaller than the source. 131# 132# * Target database page-size is the same as the source, OR 133# * Target database page-size is larger than the source, OR 134# * Target database page-size is smaller than the source. 135# 136# * Each call to step copies a single page, OR 137# * A single call to step copies the entire source database. 138# 139set iTest 1 140foreach zSrcFile {test.db :memory:} { 141foreach zDestFile {test2.db :memory:} { 142foreach zOpenScript [list { 143 sqlite3 db $zSrcFile 144 sqlite3 db2 $zSrcFile 145 db2 eval "ATTACH '$zDestFile' AS bak" 146 set db_dest db2 147 set file_dest bak 148} { 149 sqlite3 db $zSrcFile 150 sqlite3 db2 $zDestFile 151 set db_dest db2 152 set file_dest main 153} { 154 sqlite3 db $zSrcFile 155 sqlite3 db2 $zDestFile 156 set db_dest db2 157 set file_dest temp 158}] { 159foreach rows_dest {0 3 10} { 160foreach pgsz_dest {512 1024 2048} { 161foreach nPagePerStep {1 200} { 162 163 # Open the databases. 164 catch { file delete test.db } 165 catch { file delete test2.db } 166 eval $zOpenScript 167 168 if {$zDestFile ne ":memory:" || $pgsz_dest == 1024 } { 169 170 if 0 { 171 puts -nonewline "Test $iTest: src=$zSrcFile dest=$zDestFile" 172 puts -nonewline " (as $db_dest.$file_dest)" 173 puts -nonewline " rows_dest=$rows_dest pgsz_dest=$pgsz_dest" 174 puts "" 175 } 176 177 # Set up the content of the source database. 178 execsql { 179 BEGIN; 180 CREATE TABLE t1(a, b); 181 CREATE INDEX i1 ON t1(a, b); 182 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 183 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 184 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 185 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 186 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 187 COMMIT; 188 } 189 190 191 192 # Set up the content of the target database. 193 execsql "PRAGMA ${file_dest}.page_size = ${pgsz_dest}" $db_dest 194 if {$rows_dest != 0} { 195 execsql " 196 BEGIN; 197 CREATE TABLE ${file_dest}.t1(a, b); 198 CREATE INDEX ${file_dest}.i1 ON t1(a, b); 199 " $db_dest 200 for {set ii 0} {$ii < $rows_dest} {incr ii} { 201 execsql " 202 INSERT INTO ${file_dest}.t1 VALUES(1, randstr(1000,1000)) 203 " $db_dest 204 } 205 } 206 207 # Backup the source database. 208 do_test backup-2.$iTest.1 { 209 sqlite3_backup B $db_dest $file_dest db main 210 while {[B step $nPagePerStep]=="SQLITE_OK"} {} 211 B finish 212 } {SQLITE_OK} 213 214 # Run integrity check on the backup. 215 do_test backup-2.$iTest.2 { 216 execsql "PRAGMA ${file_dest}.integrity_check" $db_dest 217 } {ok} 218 219 test_contents backup-2.$iTest.3 db main $db_dest $file_dest 220 221 } 222 223 db close 224 catch {db2 close} 225 incr iTest 226 227} } } } } } 228# 229# End of backup-2.* tests. 230#--------------------------------------------------------------------- 231 232#--------------------------------------------------------------------- 233# These tests, backup-3.*, ensure that nothing goes wrong if either 234# the source or destination database are large enough to include the 235# the locking-page (the page that contains the range of bytes that 236# the locks are applied to). These tests assume that the pending 237# byte is at offset 0x00010000 (64KB offset), as set by tester.tcl, 238# not at the 1GB offset as it usually is. 239# 240# The test procedure is as follows (same procedure as used for 241# the backup-2.* tests): 242# 243# 1) Populate the source database. 244# 2) Populate the destination database. 245# 3) Run the backup to completion. (backup-3.*.1) 246# 4) Integrity check the destination db. (backup-3.*.2) 247# 5) Check that the contents of the destination db is the same as that 248# of the source db. (backup-3.*.3) 249# 250# The test procedure is run with the following parameters varied: 251# 252# * Source database includes pending-byte page. 253# * Source database does not include pending-byte page. 254# 255# * Target database includes pending-byte page. 256# * Target database does not include pending-byte page. 257# 258# * Target database page-size is the same as the source, OR 259# * Target database page-size is larger than the source, OR 260# * Target database page-size is smaller than the source. 261# 262set iTest 1 263foreach nSrcRow {10 100} { 264foreach nDestRow {10 100} { 265foreach nDestPgsz {512 1024 2048 4096} { 266 267 catch { file delete test.db } 268 catch { file delete test2.db } 269 sqlite3 db test.db 270 sqlite3 db2 test2.db 271 272 # Set up the content of the two databases. 273 # 274 foreach {db nRow} [list db $nSrcRow db2 $nDestRow] { 275 execsql { 276 BEGIN; 277 CREATE TABLE t1(a, b); 278 CREATE INDEX i1 ON t1(a, b); 279 } $db 280 for {set ii 0} {$ii < $nSrcRow} {incr ii} { 281 execsql { INSERT INTO t1 VALUES($ii, randstr(1000,1000)) } $db 282 } 283 execsql COMMIT $db 284 } 285 286 # Backup the source database. 287 do_test backup-3.$iTest.1 { 288 sqlite3_backup B db main db2 main 289 while {[B step 10]=="SQLITE_OK"} {} 290 B finish 291 } {SQLITE_OK} 292 293 # Run integrity check on the backup. 294 do_test backup-3.$iTest.2 { 295 execsql "PRAGMA integrity_check" db2 296 } {ok} 297 298 test_contents backup-3.$iTest.3 db main db2 main 299 300 db close 301 db2 close 302 incr iTest 303} 304} 305} 306# 307# End of backup-3.* tests. 308#--------------------------------------------------------------------- 309 310 311#--------------------------------------------------------------------- 312# The following tests, backup-4.*, test various error conditions: 313# 314# backup-4.1.*: Test invalid database names. 315# 316# backup-4.2.*: Test that the source database cannot be detached while 317# a backup is in progress. 318# 319# backup-4.3.*: Test that the source database handle cannot be closed 320# while a backup is in progress. 321# 322# backup-4.4.*: Test an attempt to specify the same handle for the 323# source and destination databases. 324# 325# backup-4.5.*: Test that an in-memory destination with a different 326# page-size to the source database is an error. 327# 328sqlite3 db test.db 329sqlite3 db2 test2.db 330 331do_test backup-4.1.1 { 332 catch { sqlite3_backup B db aux db2 main } 333} {1} 334do_test backup-4.1.2 { 335 sqlite3_errmsg db 336} {unknown database aux} 337do_test backup-4.1.3 { 338 catch { sqlite3_backup B db main db2 aux } 339} {1} 340do_test backup-4.1.4 { 341 sqlite3_errmsg db 342} {unknown database aux} 343 344do_test backup-4.2.1 { 345 execsql { ATTACH 'test3.db' AS aux1 } 346 execsql { ATTACH 'test4.db' AS aux2 } db2 347 sqlite3_backup B db aux1 db2 aux2 348} {B} 349do_test backup-4.2.2 { 350 catchsql { DETACH aux2 } db2 351} {1 {database aux2 is locked}} 352do_test backup-4.2.3 { 353 B step 50 354} {SQLITE_DONE} 355do_test backup-4.2.4 { 356 B finish 357} {SQLITE_OK} 358 359do_test backup-4.3.1 { 360 sqlite3_backup B db aux1 db2 aux2 361} {B} 362do_test backup-4.3.2 { 363 db2 cache flush 364 sqlite3_close db2 365} {SQLITE_BUSY} 366do_test backup-4.3.3 { 367 sqlite3_errmsg db2 368} {unable to close due to unfinished backup operation} 369do_test backup-4.3.4 { 370 B step 50 371} {SQLITE_DONE} 372do_test backup-4.3.5 { 373 B finish 374} {SQLITE_OK} 375 376do_test backup-4.4.1 { 377 set rc [catch {sqlite3_backup B db main db aux1}] 378 list $rc [sqlite3_errcode db] [sqlite3_errmsg db] 379} {1 SQLITE_ERROR {source and destination must be distinct}} 380db close 381db2 close 382 383do_test backup-4.5.1 { 384 catch { file delete -force test.db } 385 sqlite3 db test.db 386 sqlite3 db2 :memory: 387 execsql { 388 CREATE TABLE t1(a, b); 389 INSERT INTO t1 VALUES(1, 2); 390 } 391 execsql { 392 PRAGMA page_size = 4096; 393 CREATE TABLE t2(a, b); 394 INSERT INTO t2 VALUES(3, 4); 395 } db2 396 sqlite3_backup B db2 main db main 397} {B} 398do_test backup-4.5.2 { 399 B step 5000 400} {SQLITE_READONLY} 401do_test backup-4.5.3 { 402 B finish 403} {SQLITE_READONLY} 404 405db close 406db2 close 407# 408# End of backup-5.* tests. 409#--------------------------------------------------------------------- 410 411#--------------------------------------------------------------------- 412# The following tests, backup-5.*, test that the backup works properly 413# when the source database is modified during the backup. Test cases 414# are organized as follows: 415# 416# backup-5.x.1.*: Nothing special. Modify the database mid-backup. 417# 418# backup-5.x.2.*: Modify the database mid-backup so that one or more 419# pages are written out due to cache stress. Then 420# rollback the transaction. 421# 422# backup-5.x.3.*: Database is vacuumed. 423# 424# backup-5.x.4.*: Database is vacuumed and the page-size modified. 425# 426# backup-5.x.5.*: Database is shrunk via incr-vacuum. 427# 428# Each test is run three times, in the following configurations: 429# 430# 1) Backing up file-to-file. The writer writes via an external pager. 431# 2) Backing up file-to-file. The writer writes via the same pager as 432# is used by the backup operation. 433# 3) Backing up memory-to-file. 434# 435set iTest 0 436foreach {writer file} {db test.db db3 test.db db :memory:} { 437 incr iTest 438 catch { file delete bak.db } 439 sqlite3 db2 bak.db 440 catch { file delete $file } 441 sqlite3 db $file 442 sqlite3 db3 $file 443 444 do_test backup-5.$iTest.1.1 { 445 execsql { 446 BEGIN; 447 CREATE TABLE t1(a, b); 448 CREATE INDEX i1 ON t1(a, b); 449 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 450 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 451 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 452 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 453 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 454 COMMIT; 455 } 456 expr {[execsql {PRAGMA page_count}] > 10} 457 } {1} 458 do_test backup-5.$iTest.1.2 { 459 sqlite3_backup B db2 main db main 460 B step 5 461 } {SQLITE_OK} 462 do_test backup-5.$iTest.1.3 { 463 execsql { UPDATE t1 SET a = a + 1 } $writer 464 B step 50 465 } {SQLITE_DONE} 466 do_test backup-5.$iTest.1.4 { 467 B finish 468 } {SQLITE_OK} 469 integrity_check backup-5.$iTest.1.5 db2 470 test_contents backup-5.$iTest.1.6 db main db2 main 471 472 do_test backup-5.$iTest.2.1 { 473 execsql { 474 PRAGMA cache_size = 10; 475 BEGIN; 476 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 477 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 478 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 479 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 480 COMMIT; 481 } 482 } {} 483 do_test backup-5.$iTest.2.2 { 484 sqlite3_backup B db2 main db main 485 B step 50 486 } {SQLITE_OK} 487 do_test backup-5.$iTest.2.3 { 488 execsql { 489 BEGIN; 490 UPDATE t1 SET a = a + 1; 491 ROLLBACK; 492 } $writer 493 B step 5000 494 } {SQLITE_DONE} 495 do_test backup-5.$iTest.2.4 { 496 B finish 497 } {SQLITE_OK} 498 integrity_check backup-5.$iTest.2.5 db2 499 test_contents backup-5.$iTest.2.6 db main db2 main 500 501 do_test backup-5.$iTest.3.1 { 502 execsql { UPDATE t1 SET b = randstr(1000,1000) } 503 } {} 504 do_test backup-5.$iTest.3.2 { 505 sqlite3_backup B db2 main db main 506 B step 50 507 } {SQLITE_OK} 508 do_test backup-5.$iTest.3.3 { 509 execsql { VACUUM } $writer 510 B step 5000 511 } {SQLITE_DONE} 512 do_test backup-5.$iTest.3.4 { 513 B finish 514 } {SQLITE_OK} 515 integrity_check backup-5.$iTest.3.5 db2 516 test_contents backup-5.$iTest.3.6 db main db2 main 517 518 do_test backup-5.$iTest.4.1 { 519 execsql { UPDATE t1 SET b = randstr(1000,1000) } 520 } {} 521 do_test backup-5.$iTest.4.2 { 522 sqlite3_backup B db2 main db main 523 B step 50 524 } {SQLITE_OK} 525 do_test backup-5.$iTest.4.3 { 526 execsql { 527 PRAGMA page_size = 2048; 528 VACUUM; 529 } $writer 530 B step 5000 531 } {SQLITE_DONE} 532 do_test backup-5.$iTest.4.4 { 533 B finish 534 } {SQLITE_OK} 535 integrity_check backup-5.$iTest.4.5 db2 536 test_contents backup-5.$iTest.4.6 db main db2 main 537 538 catch { file delete bak.db } 539 sqlite3 db2 bak.db 540 catch { file delete $file } 541 sqlite3 db $file 542 sqlite3 db3 $file 543 do_test backup-5.$iTest.5.1 { 544 execsql { 545 PRAGMA auto_vacuum = incremental; 546 BEGIN; 547 CREATE TABLE t1(a, b); 548 CREATE INDEX i1 ON t1(a, b); 549 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 550 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 551 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 552 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 553 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 554 COMMIT; 555 } 556 } {} 557 do_test backup-5.$iTest.5.2 { 558 sqlite3_backup B db2 main db main 559 B step 8 560 } {SQLITE_OK} 561 do_test backup-5.$iTest.5.3 { 562 execsql { 563 DELETE FROM t1; 564 PRAGMA incremental_vacuum; 565 } $writer 566 B step 50 567 } {SQLITE_DONE} 568 do_test backup-5.$iTest.5.4 { 569 B finish 570 } {SQLITE_OK} 571 integrity_check backup-5.$iTest.5.5 db2 572 test_contents backup-5.$iTest.5.6 db main db2 main 573} 574catch {db close} 575catch {db2 close} 576catch {db3 close} 577# 578# End of backup-5.* tests. 579#--------------------------------------------------------------------- 580 581#--------------------------------------------------------------------- 582# Test the sqlite3_backup_remaining() and backup_pagecount() APIs. 583# 584do_test backup-6.1 { 585 catch { file delete -force test.db } 586 catch { file delete -force test2.db } 587 sqlite3 db test.db 588 sqlite3 db2 test2.db 589 execsql { 590 BEGIN; 591 CREATE TABLE t1(a, b); 592 CREATE INDEX i1 ON t1(a, b); 593 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 594 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 595 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 596 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 597 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 598 COMMIT; 599 } 600} {} 601do_test backup-6.2 { 602 set nTotal [expr {[file size test.db]/1024}] 603 sqlite3_backup B db2 main db main 604 B step 1 605} {SQLITE_OK} 606do_test backup-6.3 { 607 B pagecount 608} $nTotal 609do_test backup-6.4 { 610 B remaining 611} [expr $nTotal-1] 612do_test backup-6.5 { 613 B step 5 614 list [B remaining] [B pagecount] 615} [list [expr $nTotal-6] $nTotal] 616do_test backup-6.6 { 617 execsql { CREATE TABLE t2(a PRIMARY KEY, b) } 618 B step 1 619 list [B remaining] [B pagecount] 620} [list [expr $nTotal-5] [expr $nTotal+2]] 621 622do_test backup-6.X { 623 B finish 624} {SQLITE_OK} 625 626 627 628#--------------------------------------------------------------------- 629# Test cases backup-7.* test that SQLITE_BUSY and SQLITE_LOCKED errors 630# are returned correctly: 631# 632# backup-7.1.*: Source database is externally locked (return SQLITE_BUSY). 633# 634# backup-7.2.*: Attempt to step the backup process while a 635# write-transaction is underway on the source pager (return 636# SQLITE_LOCKED). 637# 638# backup-7.3.*: Destination database is externally locked (return SQLITE_BUSY). 639# 640do_test backup-7.0 { 641 catch { file delete -force test.db } 642 catch { file delete -force test2.db } 643 sqlite3 db2 test2.db 644 sqlite3 db test.db 645 execsql { 646 CREATE TABLE t1(a, b); 647 CREATE INDEX i1 ON t1(a, b); 648 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 649 INSERT INTO t1 SELECT a+ 1, randstr(1000,1000) FROM t1; 650 INSERT INTO t1 SELECT a+ 2, randstr(1000,1000) FROM t1; 651 INSERT INTO t1 SELECT a+ 4, randstr(1000,1000) FROM t1; 652 INSERT INTO t1 SELECT a+ 8, randstr(1000,1000) FROM t1; 653 INSERT INTO t1 SELECT a+16, randstr(1000,1000) FROM t1; 654 INSERT INTO t1 SELECT a+32, randstr(1000,1000) FROM t1; 655 INSERT INTO t1 SELECT a+64, randstr(1000,1000) FROM t1; 656 } 657} {} 658 659do_test backup-7.1.1 { 660 sqlite3_backup B db2 main db main 661 B step 5 662} {SQLITE_OK} 663do_test backup-7.1.2 { 664 sqlite3 db3 test.db 665 execsql { BEGIN EXCLUSIVE } db3 666 B step 5 667} {SQLITE_BUSY} 668do_test backup-7.1.3 { 669 execsql { ROLLBACK } db3 670 B step 5 671} {SQLITE_OK} 672do_test backup-7.2.1 { 673 execsql { 674 BEGIN; 675 INSERT INTO t1 VALUES(1, 4); 676 } 677} {} 678do_test backup-7.2.2 { 679 B step 5000 680} {SQLITE_LOCKED} 681do_test backup-7.2.3 { 682 execsql { ROLLBACK } 683 B step 5000 684} {SQLITE_DONE} 685do_test backup-7.2.4 { 686 B finish 687} {SQLITE_OK} 688test_contents backup-7.2.5 db main db2 main 689integrity_check backup-7.3.6 db2 690 691do_test backup-7.3.1 { 692 db2 close 693 db3 close 694 file delete -force test2.db 695 sqlite3 db2 test2.db 696 sqlite3 db3 test2.db 697 698 sqlite3_backup B db2 main db main 699 execsql { BEGIN ; CREATE TABLE t2(a, b); } db3 700 701 B step 5 702} {SQLITE_BUSY} 703do_test backup-7.3.2 { 704 execsql { COMMIT } db3 705 B step 5000 706} {SQLITE_DONE} 707do_test backup-7.3.3 { 708 B finish 709} {SQLITE_OK} 710test_contents backup-7.3.4 db main db2 main 711integrity_check backup-7.3.5 db2 712catch { db2 close } 713catch { db3 close } 714 715#----------------------------------------------------------------------- 716# The following tests, backup-8.*, test attaching multiple backup 717# processes to the same source database. Also, reading from the source 718# database while a read transaction is active. 719# 720# These tests reuse the database "test.db" left over from backup-7.*. 721# 722do_test backup-8.1 { 723 catch { file delete -force test2.db } 724 catch { file delete -force test3.db } 725 sqlite3 db2 test2.db 726 sqlite3 db3 test3.db 727 728 sqlite3_backup B2 db2 main db main 729 sqlite3_backup B3 db3 main db main 730 list [B2 finish] [B3 finish] 731} {SQLITE_OK SQLITE_OK} 732do_test backup-8.2 { 733 sqlite3_backup B3 db3 main db main 734 sqlite3_backup B2 db2 main db main 735 list [B2 finish] [B3 finish] 736} {SQLITE_OK SQLITE_OK} 737do_test backup-8.3 { 738 sqlite3_backup B2 db2 main db main 739 sqlite3_backup B3 db3 main db main 740 B2 step 5 741} {SQLITE_OK} 742do_test backup-8.4 { 743 execsql { 744 BEGIN; 745 SELECT * FROM sqlite_master; 746 } 747 B3 step 5 748} {SQLITE_OK} 749do_test backup-8.5 { 750 list [B3 step 5000] [B3 finish] 751} {SQLITE_DONE SQLITE_OK} 752do_test backup-8.6 { 753 list [B2 step 5000] [B2 finish] 754} {SQLITE_DONE SQLITE_OK} 755test_contents backup-8.7 db main db2 main 756test_contents backup-8.8 db main db3 main 757do_test backup-8.9 { 758 execsql { PRAGMA lock_status } 759} {main shared temp closed} 760do_test backup-8.10 { 761 execsql COMMIT 762} {} 763catch { db2 close } 764catch { db3 close } 765 766 767finish_test 768