Annotation of embedaddon/sqlite3/test/backup.test, revision 1.1.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>