/ Check-in [7aac9ad6]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add coverage tests. Remove a NEVER macro from pager.c, as the condition can now be true in wal mode.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7aac9ad6dd14b1c56eb8e4750ac769c6197c30bd
User & Date: dan 2010-06-24 10:50:18
Context
2010-06-24
13:24
Add a coverage test to pagerfault.test. check-in: b58db67e user: dan tags: trunk
10:50
Add coverage tests. Remove a NEVER macro from pager.c, as the condition can now be true in wal mode. check-in: 7aac9ad6 user: dan tags: trunk
02:46
Make sure the wal-index reader detects an incorrect version number even if it had to hold a lock in order to read the wal-index. Also, expand and enhance various comments in wal.c. check-in: 2e6a462c user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

  5088   5088   ){
  5089   5089     int rc = SQLITE_OK;             /* Return code */
  5090   5090   
  5091   5091     /* The dbOrigSize is never set if journal_mode=OFF */
  5092   5092     assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 );
  5093   5093   
  5094   5094     /* If a prior error occurred, report that error again. */
  5095         -  if( NEVER(pPager->errCode) ) return pPager->errCode;
         5095  +  if( pPager->errCode ) return pPager->errCode;
  5096   5096   
  5097   5097     PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
  5098   5098         pPager->zFilename, zMaster, pPager->dbSize));
  5099   5099   
  5100   5100     if( MEMDB && pPager->dbModified ){
  5101   5101       /* If this is an in-memory db, or no pages have been written to, or this
  5102   5102       ** function has already been called, it is mostly a no-op.  However, any

Changes to test/malloc_common.tcl.

   183    183     set ::sqlite_io_error_pending 0
   184    184     set ::sqlite_io_error_hardhit 0
   185    185     set ::sqlite_io_error_hit     0
   186    186     set ::sqlite_io_error_pending 0
   187    187     return $sv
   188    188   }
   189    189   
   190         -
   191    190   # The following procs are used as [do_one_faultsim_test] callbacks when 
   192    191   # injecting shared-memory related error faults into test cases.
   193    192   #
   194    193   proc shmerr_injectinstall {} {
   195    194     testvfs shmfault -default true
   196    195     shmfault filter {xShmOpen xShmMap xShmLock}
   197    196   }
................................................................................
   203    202   proc shmerr_injectstart {persist iFail} {
   204    203     shmfault ioerr $iFail $persist
   205    204   }
   206    205   proc shmerr_injectstop {} {
   207    206     shmfault ioerr 0 0
   208    207   }
   209    208   
          209  +# The following procs are used as [do_one_faultsim_test] callbacks when 
          210  +# injecting SQLITE_FULL error faults into test cases.
          211  +#
   210    212   proc fullerr_injectinstall {} {
   211    213     testvfs shmfault -default true
   212    214   }
   213    215   proc fullerr_injectuninstall {} {
   214    216     catch {db  close}
   215    217     catch {db2 close}
   216    218     shmfault delete

Changes to test/pager1.test.

    34     34   #
    35     35   # pager1-6.*: Cases related to "PRAGMA max_page_count"
    36     36   #
    37     37   # pager1-7.*: Cases specific to "PRAGMA journal_mode=TRUNCATE"
    38     38   #
    39     39   # pager1-8.*: Cases using temporary and in-memory databases.
    40     40   #
           41  +# pager1-9.*: Tests related to the backup API.
           42  +#
    41     43   
    42     44   set a_string_counter 1
    43     45   proc a_string {n} {
    44     46     global a_string_counter
    45     47     incr a_string_counter
    46     48     string range [string repeat "${a_string_counter}." $n] 1 $n
    47     49   }
................................................................................
   181    183     do_test pager1-$tn.27 { sql1 { SELECT * FROM t1 } } {21 one 22 two 23 three}
   182    184     do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {21 one 22 two 23 three}
   183    185     do_test pager1-$tn.28 { sql3 { SELECT * FROM t1 } } {21 one 22 two 23 three}
   184    186   }
   185    187   
   186    188   #-------------------------------------------------------------------------
   187    189   # Savepoint related test cases.
          190  +#
          191  +# pager1-3.1.2.*: Force a savepoint rollback to cause the database file
          192  +#                 to grow.
   188    193   # 
   189    194   do_test pager1-3.1.1 {
   190    195     faultsim_delete_and_reopen
   191    196     execsql {
   192    197       CREATE TABLE t1(a PRIMARY KEY, b);
   193    198       CREATE TABLE counter(
   194    199         i CHECK (i<5), 
................................................................................
   214    219   } {3 0}
   215    220   do_catchsql_test pager1-3.1.3 {
   216    221       INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1
   217    222   } {1 {constraint failed}}
   218    223   do_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0}
   219    224   do_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3}
   220    225   do_execsql_test pager1-3.6 { COMMIT } {}
          226  +
          227  +do_test pager1-3.2.1 {
          228  +  faultsim_delete_and_reopen
          229  +  db func a_string a_string
          230  +  execsql {
          231  +    PRAGMA auto_vacuum = 2;
          232  +    PRAGMA cache_size = 10;
          233  +    CREATE TABLE z(x INTEGER PRIMARY KEY, y);
          234  +    BEGIN;
          235  +      INSERT INTO z VALUES(NULL, a_string(800));
          236  +      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   2
          237  +      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   4
          238  +      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   8
          239  +      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  16
          240  +      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  32
          241  +      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  64
          242  +      INSERT INTO z SELECT NULL, a_string(800) FROM z;     -- 128
          243  +      INSERT INTO z SELECT NULL, a_string(800) FROM z;     -- 256
          244  +    COMMIT;
          245  +  }
          246  +  execsql { PRAGMA auto_vacuum }
          247  +} {2}
          248  +do_execsql_test pager1-3.2.2 {
          249  +  BEGIN;
          250  +    INSERT INTO z VALUES(NULL, a_string(800));
          251  +    INSERT INTO z VALUES(NULL, a_string(800));
          252  +    SAVEPOINT one;
          253  +      DELETE FROM z WHERE x>256;
          254  +      PRAGMA incremental_vacuum;
          255  +      SELECT count(*) FROM z WHERE x < 100;
          256  +    ROLLBACK TO one;
          257  +  COMMIT;
          258  +} {99}
   221    259   
   222    260   #-------------------------------------------------------------------------
   223    261   # Hot journal rollback related test cases.
   224    262   #
   225    263   # pager1.4.1.*: Test that the pager module deletes very small invalid
   226    264   #               journal files.
   227    265   #
................................................................................
   837    875     do_execsql_test pager1-8.$tn.3 {
   838    876       BEGIN;
   839    877         INSERT INTO x1 VALUES('William');
   840    878         INSERT INTO x1 VALUES('Anne');
   841    879       ROLLBACK;
   842    880     } {}
   843    881   }
          882  +
          883  +#-------------------------------------------------------------------------
          884  +# The next block of tests - pager1-9.* - deal with interactions between
          885  +# the pager and the backup API. Test cases:
          886  +#
          887  +#   pager1-9.1.*: Test that a backup completes successfully even if the
          888  +#                 source db is written to during the backup op.
          889  +#
          890  +#   pager1-9.2.*: Test that a backup completes successfully even if the
          891  +#                 source db is written to and then rolled back during a 
          892  +#                 backup operation.
          893  +#
          894  +do_test pager1-9.0.1 {
          895  +  faultsim_delete_and_reopen
          896  +  db func a_string a_string
          897  +  execsql {
          898  +    PRAGMA cache_size = 10;
          899  +    BEGIN;
          900  +      CREATE TABLE ab(a, b, UNIQUE(a, b));
          901  +      INSERT INTO ab VALUES( a_string(200), a_string(300) );
          902  +      INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
          903  +      INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
          904  +      INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
          905  +      INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
          906  +      INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
          907  +      INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
          908  +      INSERT INTO ab SELECT a_string(200), a_string(300) FROM ab;
          909  +    COMMIT;
          910  +  }
          911  +} {}
          912  +do_test pager1-9.0.2 {
          913  +  sqlite3 db2 test.db2
          914  +  db2 eval { PRAGMA cache_size = 10 }
          915  +  sqlite3_backup B db2 main db main
          916  +  list [B step 10000] [B finish]
          917  +} {SQLITE_DONE SQLITE_OK}
          918  +do_test pager1-9.0.3 {
          919  + db one {SELECT md5sum(a, b) FROM ab}
          920  +} [db2 one {SELECT md5sum(a, b) FROM ab}]
          921  +
          922  +do_test pager1-9.1.1 {
          923  +  execsql { UPDATE ab SET a = a_string(201) }
          924  +  sqlite3_backup B db2 main db main
          925  +  B step 30
          926  +} {SQLITE_OK}
          927  +do_test pager1-9.1.2 {
          928  +  execsql { UPDATE ab SET b = a_string(301) }
          929  +  list [B step 10000] [B finish]
          930  +} {SQLITE_DONE SQLITE_OK}
          931  +do_test pager1-9.1.3 {
          932  + db one {SELECT md5sum(a, b) FROM ab}
          933  +} [db2 one {SELECT md5sum(a, b) FROM ab}]
          934  +do_test pager1-9.1.4 { execsql { SELECT count(*) FROM ab } } {128}
          935  +
          936  +do_test pager1-9.2.1 {
          937  +  execsql { UPDATE ab SET a = a_string(202) }
          938  +  sqlite3_backup B db2 main db main
          939  +  B step 30
          940  +} {SQLITE_OK}
          941  +do_test pager1-9.2.2 {
          942  +  execsql { 
          943  +    BEGIN;
          944  +      UPDATE ab SET b = a_string(301);
          945  +    ROLLBACK;
          946  +  }
          947  +  list [B step 10000] [B finish]
          948  +} {SQLITE_DONE SQLITE_OK}
          949  +do_test pager1-9.2.3 {
          950  + db one {SELECT md5sum(a, b) FROM ab}
          951  +} [db2 one {SELECT md5sum(a, b) FROM ab}]
          952  +do_test pager1-9.2.4 { execsql { SELECT count(*) FROM ab } } {128}
   844    953   
   845    954   finish_test
   846    955   

Changes to test/pagerfault.test.

   303    303   #     SELECT DISTINCT x FROM t1;
   304    304   #   }
   305    305   # } -test {
   306    306   #   faultsim_test_result {0 {5 6 7 8}}
   307    307   #   faultsim_integrity_check
   308    308   # }
   309    309   #
          310  +
          311  +# This is designed to provoke a special case in the pager code:
          312  +#
          313  +# If an error (specifically, a FULL or IOERR error) occurs while writing a
          314  +# dirty page to the file-system in order to free up memory, the pager enters
          315  +# the "error state". An IO error causes SQLite to roll back the current
          316  +# transaction (exiting the error state). A FULL error, however, may only
          317  +# rollback the current statement.
          318  +#
          319  +# This block tests that nothing goes wrong if a FULL error occurs while
          320  +# writing a dirty page out to free memory from within a statement that has
          321  +# opened a statement transaction.
          322  +#
   310    323   do_test pagerfault-7-pre1 {
   311    324     faultsim_delete_and_reopen
   312    325     execsql {
   313    326       CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
   314    327       BEGIN;
   315    328         INSERT INTO t2 VALUES(NULL, randomblob(1500));
   316    329         INSERT INTO t2 VALUES(NULL, randomblob(1500));
................................................................................
   331    344     execsql { 
   332    345       PRAGMA cache_size = 10;
   333    346       BEGIN;
   334    347         UPDATE t1 SET b = randomblob(1500);
   335    348     }
   336    349   } -body {
   337    350     execsql { UPDATE t1 SET a = 65, b = randomblob(1500) WHERE (a+1)>200 }
          351  +  execsql COMMIT
          352  +} -test {
          353  +  faultsim_test_result {0 {}}
          354  +  faultsim_integrity_check
          355  +}
          356  +
          357  +do_test pagerfault-8-pre1 {
          358  +  faultsim_delete_and_reopen
          359  +  execsql {
          360  +    PRAGMA auto_vacuum = 1;
          361  +    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
          362  +    BEGIN;
          363  +      INSERT INTO t1 VALUES(NULL, randomblob(1500));
          364  +      INSERT INTO t1 VALUES(NULL, randomblob(1500));
          365  +      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    --  4
          366  +      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    --  8
          367  +      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    -- 16
          368  +      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    -- 32
          369  +      INSERT INTO t1 SELECT NULL, randomblob(1500) FROM t1;    -- 64
          370  +    COMMIT;
          371  +  }
          372  +  faultsim_save_and_close
          373  +  set filesize [file size test.db]
          374  +  set {} {}
          375  +} {}
          376  +do_test pagerfault-8-pre2 {
          377  +  faultsim_restore_and_reopen
          378  +  execsql { DELETE FROM t1 WHERE a>32 }
          379  +  expr {[file size test.db] < $filesize}
          380  +} {1}
          381  +breakpoint
          382  +do_faultsim_test pagerfault-8 -prep {
          383  +  faultsim_restore_and_reopen
          384  +  execsql { 
          385  +    BEGIN;
          386  +    DELETE FROM t1 WHERE a>32;
          387  +  }
          388  +} -body {
   338    389     execsql COMMIT
   339    390   } -test {
   340    391     faultsim_test_result {0 {}}
   341    392     faultsim_integrity_check
   342    393   }
   343    394   
   344    395   finish_test