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