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