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