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.11 2009/06/05 17:09:12 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# 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 { 407 B step 50 408} {SQLITE_DONE} 409do_test backup-4.2.4 { 410 B finish 411} {SQLITE_OK} 412 413do_test backup-4.3.1 { 414 sqlite3_backup B db aux1 db2 aux2 415} {B} 416do_test backup-4.3.2 { 417 db2 cache flush 418 sqlite3_close db2 419} {SQLITE_BUSY} 420do_test backup-4.3.3 { 421 sqlite3_errmsg db2 422} {unable to close due to unfinished backup operation} 423do_test backup-4.3.4 { 424 B step 50 425} {SQLITE_DONE} 426do_test backup-4.3.5 { 427 B finish 428} {SQLITE_OK} 429 430do_test backup-4.4.1 { 431 set rc [catch {sqlite3_backup B db main db aux1}] 432 list $rc [sqlite3_errcode db] [sqlite3_errmsg db] 433} {1 SQLITE_ERROR {source and destination must be distinct}} 434db close 435db2 close 436 437do_test backup-4.5.1 { 438 catch { file delete -force test.db } 439 sqlite3 db test.db 440 sqlite3 db2 :memory: 441 execsql { 442 CREATE TABLE t1(a, b); 443 INSERT INTO t1 VALUES(1, 2); 444 } 445 execsql { 446 PRAGMA page_size = 4096; 447 CREATE TABLE t2(a, b); 448 INSERT INTO t2 VALUES(3, 4); 449 } db2 450 sqlite3_backup B db2 main db main 451} {B} 452do_test backup-4.5.2 { 453 B step 5000 454} {SQLITE_READONLY} 455do_test backup-4.5.3 { 456 B finish 457} {SQLITE_READONLY} 458 459db close 460db2 close 461# 462# End of backup-5.* tests. 463#--------------------------------------------------------------------- 464 465#--------------------------------------------------------------------- 466# The following tests, backup-5.*, test that the backup works properly 467# when the source database is modified during the backup. Test cases 468# are organized as follows: 469# 470# backup-5.x.1.*: Nothing special. Modify the database mid-backup. 471# 472# backup-5.x.2.*: Modify the database mid-backup so that one or more 473# pages are written out due to cache stress. Then 474# rollback the transaction. 475# 476# backup-5.x.3.*: Database is vacuumed. 477# 478# backup-5.x.4.*: Database is vacuumed and the page-size modified. 479# 480# backup-5.x.5.*: Database is shrunk via incr-vacuum. 481# 482# Each test is run three times, in the following configurations: 483# 484# 1) Backing up file-to-file. The writer writes via an external pager. 485# 2) Backing up file-to-file. The writer writes via the same pager as 486# is used by the backup operation. 487# 3) Backing up memory-to-file. 488# 489set iTest 0 490foreach {writer file} {db test.db db3 test.db db :memory:} { 491 incr iTest 492 catch { file delete bak.db } 493 sqlite3 db2 bak.db 494 catch { file delete $file } 495 sqlite3 db $file 496 sqlite3 db3 $file 497 498 do_test backup-5.$iTest.1.1 { 499 execsql { 500 BEGIN; 501 CREATE TABLE t1(a, b); 502 CREATE INDEX i1 ON t1(a, b); 503 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 504 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 505 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 506 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 507 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 508 COMMIT; 509 } 510 expr {[execsql {PRAGMA page_count}] > 10} 511 } {1} 512 do_test backup-5.$iTest.1.2 { 513 sqlite3_backup B db2 main db main 514 B step 5 515 } {SQLITE_OK} 516 do_test backup-5.$iTest.1.3 { 517 execsql { UPDATE t1 SET a = a + 1 } $writer 518 B step 50 519 } {SQLITE_DONE} 520 do_test backup-5.$iTest.1.4 { 521 B finish 522 } {SQLITE_OK} 523 integrity_check backup-5.$iTest.1.5 db2 524 test_contents backup-5.$iTest.1.6 db main db2 main 525 526 do_test backup-5.$iTest.2.1 { 527 execsql { 528 PRAGMA cache_size = 10; 529 BEGIN; 530 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 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 COMMIT; 535 } 536 } {} 537 do_test backup-5.$iTest.2.2 { 538 sqlite3_backup B db2 main db main 539 B step 50 540 } {SQLITE_OK} 541 do_test backup-5.$iTest.2.3 { 542 execsql { 543 BEGIN; 544 UPDATE t1 SET a = a + 1; 545 ROLLBACK; 546 } $writer 547 B step 5000 548 } {SQLITE_DONE} 549 do_test backup-5.$iTest.2.4 { 550 B finish 551 } {SQLITE_OK} 552 integrity_check backup-5.$iTest.2.5 db2 553 test_contents backup-5.$iTest.2.6 db main db2 main 554 555 do_test backup-5.$iTest.3.1 { 556 execsql { UPDATE t1 SET b = randstr(1000,1000) } 557 } {} 558 do_test backup-5.$iTest.3.2 { 559 sqlite3_backup B db2 main db main 560 B step 50 561 } {SQLITE_OK} 562 do_test backup-5.$iTest.3.3 { 563 execsql { VACUUM } $writer 564 B step 5000 565 } {SQLITE_DONE} 566 do_test backup-5.$iTest.3.4 { 567 B finish 568 } {SQLITE_OK} 569 integrity_check backup-5.$iTest.3.5 db2 570 test_contents backup-5.$iTest.3.6 db main db2 main 571 572 do_test backup-5.$iTest.4.1 { 573 execsql { UPDATE t1 SET b = randstr(1000,1000) } 574 } {} 575 do_test backup-5.$iTest.4.2 { 576 sqlite3_backup B db2 main db main 577 B step 50 578 } {SQLITE_OK} 579 do_test backup-5.$iTest.4.3 { 580 execsql { 581 PRAGMA page_size = 2048; 582 VACUUM; 583 } $writer 584 B step 5000 585 } {SQLITE_DONE} 586 do_test backup-5.$iTest.4.4 { 587 B finish 588 } {SQLITE_OK} 589 integrity_check backup-5.$iTest.4.5 db2 590 test_contents backup-5.$iTest.4.6 db main db2 main 591 592 catch {db close} 593 catch {db2 close} 594 catch {db3 close} 595 catch { file delete bak.db } 596 sqlite3 db2 bak.db 597 catch { file delete $file } 598 sqlite3 db $file 599 sqlite3 db3 $file 600 do_test backup-5.$iTest.5.1 { 601 execsql { 602 PRAGMA auto_vacuum = incremental; 603 BEGIN; 604 CREATE TABLE t1(a, b); 605 CREATE INDEX i1 ON t1(a, b); 606 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 607 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 608 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 609 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 610 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 611 COMMIT; 612 } 613 } {} 614 do_test backup-5.$iTest.5.2 { 615 sqlite3_backup B db2 main db main 616 B step 8 617 } {SQLITE_OK} 618 do_test backup-5.$iTest.5.3 { 619 execsql { 620 DELETE FROM t1; 621 PRAGMA incremental_vacuum; 622 } $writer 623 B step 50 624 } {SQLITE_DONE} 625 do_test backup-5.$iTest.5.4 { 626 B finish 627 } {SQLITE_OK} 628 integrity_check backup-5.$iTest.5.5 db2 629 test_contents backup-5.$iTest.5.6 db main db2 main 630 catch {db close} 631 catch {db2 close} 632 catch {db3 close} 633} 634# 635# End of backup-5.* tests. 636#--------------------------------------------------------------------- 637 638#--------------------------------------------------------------------- 639# Test the sqlite3_backup_remaining() and backup_pagecount() APIs. 640# 641do_test backup-6.1 { 642 catch { file delete -force test.db } 643 catch { file delete -force test2.db } 644 sqlite3 db test.db 645 sqlite3 db2 test2.db 646 execsql { 647 BEGIN; 648 CREATE TABLE t1(a, b); 649 CREATE INDEX i1 ON t1(a, b); 650 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 651 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 652 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 653 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 654 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 655 COMMIT; 656 } 657} {} 658do_test backup-6.2 { 659 set nTotal [expr {[file size test.db]/1024}] 660 sqlite3_backup B db2 main db main 661 B step 1 662} {SQLITE_OK} 663do_test backup-6.3 { 664 B pagecount 665} $nTotal 666do_test backup-6.4 { 667 B remaining 668} [expr $nTotal-1] 669do_test backup-6.5 { 670 B step 5 671 list [B remaining] [B pagecount] 672} [list [expr $nTotal-6] $nTotal] 673do_test backup-6.6 { 674 execsql { CREATE TABLE t2(a PRIMARY KEY, b) } 675 B step 1 676 list [B remaining] [B pagecount] 677} [list [expr $nTotal-5] [expr $nTotal+2]] 678 679do_test backup-6.X { 680 B finish 681} {SQLITE_OK} 682 683catch {db close} 684catch {db2 close} 685 686#--------------------------------------------------------------------- 687# Test cases backup-7.* test that SQLITE_BUSY and SQLITE_LOCKED errors 688# are returned correctly: 689# 690# backup-7.1.*: Source database is externally locked (return SQLITE_BUSY). 691# 692# backup-7.2.*: Attempt to step the backup process while a 693# write-transaction is underway on the source pager (return 694# SQLITE_LOCKED). 695# 696# backup-7.3.*: Destination database is externally locked (return SQLITE_BUSY). 697# 698do_test backup-7.0 { 699 catch { file delete -force test.db } 700 catch { file delete -force test2.db } 701 sqlite3 db2 test2.db 702 sqlite3 db test.db 703 execsql { 704 CREATE TABLE t1(a, b); 705 CREATE INDEX i1 ON t1(a, b); 706 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 707 INSERT INTO t1 SELECT a+ 1, randstr(1000,1000) FROM t1; 708 INSERT INTO t1 SELECT a+ 2, randstr(1000,1000) FROM t1; 709 INSERT INTO t1 SELECT a+ 4, randstr(1000,1000) FROM t1; 710 INSERT INTO t1 SELECT a+ 8, randstr(1000,1000) FROM t1; 711 INSERT INTO t1 SELECT a+16, randstr(1000,1000) FROM t1; 712 INSERT INTO t1 SELECT a+32, randstr(1000,1000) FROM t1; 713 INSERT INTO t1 SELECT a+64, randstr(1000,1000) FROM t1; 714 } 715} {} 716 717do_test backup-7.1.1 { 718 sqlite3_backup B db2 main db main 719 B step 5 720} {SQLITE_OK} 721do_test backup-7.1.2 { 722 sqlite3 db3 test.db 723 execsql { BEGIN EXCLUSIVE } db3 724 B step 5 725} {SQLITE_BUSY} 726do_test backup-7.1.3 { 727 execsql { ROLLBACK } db3 728 B step 5 729} {SQLITE_OK} 730do_test backup-7.2.1 { 731 execsql { 732 BEGIN; 733 INSERT INTO t1 VALUES(1, 4); 734 } 735} {} 736do_test backup-7.2.2 { 737 B step 5000 738} {SQLITE_BUSY} 739do_test backup-7.2.3 { 740 execsql { ROLLBACK } 741 B step 5000 742} {SQLITE_DONE} 743do_test backup-7.2.4 { 744 B finish 745} {SQLITE_OK} 746test_contents backup-7.2.5 db main db2 main 747integrity_check backup-7.3.6 db2 748 749do_test backup-7.3.1 { 750 db2 close 751 db3 close 752 file delete -force test2.db 753 sqlite3 db2 test2.db 754 sqlite3 db3 test2.db 755 756 sqlite3_backup B db2 main db main 757 execsql { BEGIN ; CREATE TABLE t2(a, b); } db3 758 759 B step 5 760} {SQLITE_BUSY} 761do_test backup-7.3.2 { 762 execsql { COMMIT } db3 763 B step 5000 764} {SQLITE_DONE} 765do_test backup-7.3.3 { 766 B finish 767} {SQLITE_OK} 768test_contents backup-7.3.4 db main db2 main 769integrity_check backup-7.3.5 db2 770catch { db2 close } 771catch { db3 close } 772 773#----------------------------------------------------------------------- 774# The following tests, backup-8.*, test attaching multiple backup 775# processes to the same source database. Also, reading from the source 776# database while a read transaction is active. 777# 778# These tests reuse the database "test.db" left over from backup-7.*. 779# 780do_test backup-8.1 { 781 catch { file delete -force test2.db } 782 catch { file delete -force test3.db } 783 sqlite3 db2 test2.db 784 sqlite3 db3 test3.db 785 786 sqlite3_backup B2 db2 main db main 787 sqlite3_backup B3 db3 main db main 788 list [B2 finish] [B3 finish] 789} {SQLITE_OK SQLITE_OK} 790do_test backup-8.2 { 791 sqlite3_backup B3 db3 main db main 792 sqlite3_backup B2 db2 main db main 793 list [B2 finish] [B3 finish] 794} {SQLITE_OK SQLITE_OK} 795do_test backup-8.3 { 796 sqlite3_backup B2 db2 main db main 797 sqlite3_backup B3 db3 main db main 798 B2 step 5 799} {SQLITE_OK} 800do_test backup-8.4 { 801 execsql { 802 BEGIN; 803 SELECT * FROM sqlite_master; 804 } 805 B3 step 5 806} {SQLITE_OK} 807do_test backup-8.5 { 808 list [B3 step 5000] [B3 finish] 809} {SQLITE_DONE SQLITE_OK} 810do_test backup-8.6 { 811 list [B2 step 5000] [B2 finish] 812} {SQLITE_DONE SQLITE_OK} 813test_contents backup-8.7 db main db2 main 814test_contents backup-8.8 db main db3 main 815do_test backup-8.9 { 816 execsql { PRAGMA lock_status } 817} {main shared temp closed} 818do_test backup-8.10 { 819 execsql COMMIT 820} {} 821catch { db2 close } 822catch { db3 close } 823 824#----------------------------------------------------------------------- 825# The following tests, backup-9.*, test that: 826# 827# * Passing 0 as an argument to sqlite3_backup_step() means no pages 828# are backed up (backup-9.1.*), and 829# * Passing a negative value as an argument to sqlite3_backup_step() means 830# all pages are backed up (backup-9.2.*). 831# 832# These tests reuse the database "test.db" left over from backup-7.*. 833# 834do_test backup-9.1.1 { 835 sqlite3 db2 test2.db 836 sqlite3_backup B db2 main db main 837 B step 1 838} {SQLITE_OK} 839do_test backup-9.1.2 { 840 set nRemaining [B remaining] 841 expr {$nRemaining>100} 842} {1} 843do_test backup-9.1.3 { 844 B step 0 845} {SQLITE_OK} 846do_test backup-9.1.4 { 847 B remaining 848} $nRemaining 849 850do_test backup-9.2.1 { 851 B step -1 852} {SQLITE_DONE} 853do_test backup-9.2.2 { 854 B remaining 855} {0} 856do_test backup-9.2.3 { 857 B finish 858} {SQLITE_OK} 859catch {db2 close} 860 861ifcapable memorymanage { 862 db close 863 file delete -force test.db 864 file delete -force bak.db 865 866 sqlite3 db test.db 867 sqlite3 db2 test.db 868 sqlite3 db3 bak.db 869 870 do_test backup-10.1.1 { 871 execsql { 872 BEGIN; 873 CREATE TABLE t1(a, b); 874 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 875 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 876 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 877 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 878 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 879 CREATE INDEX i1 ON t1(a, b); 880 COMMIT; 881 } 882 } {} 883 do_test backup-10.1.2 { 884 sqlite3_backup B db3 main db2 main 885 B step 5 886 } {SQLITE_OK} 887 do_test backup-10.1.3 { 888 execsql { 889 UPDATE t1 SET b = randstr(500,500); 890 } 891 } {} 892 sqlite3_release_memory [expr 1024*1024] 893 do_test backup-10.1.3 { 894 B step 50 895 } {SQLITE_DONE} 896 do_test backup-10.1.4 { 897 B finish 898 } {SQLITE_OK} 899 do_test backup-10.1.5 { 900 execsql { PRAGMA integrity_check } db3 901 } {ok} 902 903 db2 close 904 db3 close 905} 906 907finish_test 908