/ Check-in [4941e437]
Login

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

Overview
Comment:Add test cases to pager1.test and pagerfault.test.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4941e437d2638f36ac8510d4a5b4c780afc798bb
User & Date: dan 2010-06-24 19:16:06
Context
2010-06-25
11:35
Modify the merge-sort in wal.c so that it does not use recursion. check-in: daea6c05 user: dan tags: trunk
2010-06-24
19:16
Add test cases to pager1.test and pagerfault.test. check-in: 4941e437 user: dan tags: trunk
18:36
Revert to allowing a cache spill during writes of multiple pages within a single sector as long as the spill does not require a journal sync and a new journal header. check-in: 7d83fbae user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to test/pager1.test.

    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     41   # pager1-9.*: Tests related to the backup API.
    42     42   #
           43  +# pager1-10.*: Test that the assumed file-system sector-size is limited to
           44  +#              64KB.
           45  +#              
           46  +#
    43     47   
    44     48   set a_string_counter 1
    45     49   proc a_string {n} {
    46     50     global a_string_counter
    47     51     incr a_string_counter
    48     52     string range [string repeat "${a_string_counter}." $n] 1 $n
    49     53   }
................................................................................
   275    279   #
   276    280   # pager1.4.4.*: Test hot-journal rollback of journal file with a master
   277    281   #               journal pointer generated in various "PRAGMA synchronous"
   278    282   #               modes.
   279    283   #
   280    284   # pager1.4.5.*: Test that hot-journal rollback stops if it encounters a
   281    285   #               journal-record for which the checksum fails.
          286  +#
          287  +# pager1.4.6.*: Test that when rolling back a hot-journal that contains a
          288  +#               master journal pointer, the master journal file is deleted
          289  +#               after all the hot-journals that refer to it are deleted.
   282    290   # 
   283    291   do_test pager1.4.1.1 {
   284    292     faultsim_delete_and_reopen
   285    293     execsql { 
   286    294       CREATE TABLE x(y, z);
   287    295       INSERT INTO x VALUES(1, 2);
   288    296     }
................................................................................
   578    586   # Check the transaction was committed:
   579    587   #
   580    588   do_execsql_test pager1.4.5.2 {
   581    589     SELECT * FROM t1;
   582    590     SELECT * FROM t2;
   583    591   } {I II 1 2 III IV 3 4}
   584    592   
   585         -# Now try three tests:
          593  +# Now try four tests:
   586    594   #
   587    595   #  pager1-4.5.3: Restore the file-system. Check that the whole transaction 
   588    596   #                is rolled back.
   589    597   #
   590    598   #  pager1-4.5.4: Restore the file-system. Corrupt the first record in the
   591    599   #                journal. Check the transaction is not rolled back.
   592    600   #
................................................................................
   619    627   faultsim_restore_and_reopen
   620    628   db close
   621    629   sqlite3 db test.db -readonly 1
   622    630   do_catchsql_test pager1.4.5.6 {
   623    631     SELECT * FROM t1;
   624    632     SELECT * FROM t2;
   625    633   } {1 {disk I/O error}}
          634  +db close
          635  +
          636  +# Snapshot the file-system just before multi-file commit. Save the name
          637  +# of the master journal file in $::mj_filename.
          638  +#
          639  +tv script copy_on_mj_delete
          640  +tv filter xDelete
          641  +proc copy_on_mj_delete {method filename args} {
          642  +  if {[string match *mj* [file tail $filename]]} { 
          643  +    set ::mj_filename $filename
          644  +    faultsim_save 
          645  +  }
          646  +  return SQLITE_OK
          647  +}
          648  +do_test pager1.4.6.1 {
          649  +  faultsim_delete_and_reopen
          650  +  execsql {
          651  +    ATTACH 'test.db2' AS two;
          652  +    CREATE TABLE t1(a, b);
          653  +    CREATE TABLE two.t2(a, b);
          654  +    INSERT INTO t1 VALUES(1, 't1.1');
          655  +    INSERT INTO t2 VALUES(1, 't2.1');
          656  +    BEGIN;
          657  +      UPDATE t1 SET b = 't1.2';
          658  +      UPDATE t2 SET b = 't2.2';
          659  +    COMMIT;
          660  +  }
          661  +  tv filter {}
          662  +  db close
          663  +} {}
          664  +
          665  +faultsim_restore_and_reopen
          666  +do_execsql_test pager1.4.6.2 { SELECT * FROM t1 }           {1 t1.1}
          667  +do_test         pager1.4.6.3 { file exists $::mj_filename } {1}
          668  +do_execsql_test pager1.4.6.4 {
          669  +  ATTACH 'test.db2' AS two;
          670  +  SELECT * FROM t2;
          671  +} {1 t2.1}
          672  +do_test pager1.4.6.5 { file exists $::mj_filename } {0}
          673  +
          674  +faultsim_restore_and_reopen
          675  +db close
          676  +do_test pager1.4.6.8 {
          677  +  set ::mj_filename1 $::mj_filename
          678  +  tv filter xDelete
          679  +  sqlite3 db test.db2
          680  +  execsql {
          681  +    ATTACH 'test.db3' AS three;
          682  +    CREATE TABLE three.t3(a, b);
          683  +    INSERT INTO t3 VALUES(1, 't3.1');
          684  +    BEGIN;
          685  +      UPDATE t2 SET b = 't2.3';
          686  +      UPDATE t3 SET b = 't3.3';
          687  +    COMMIT;
          688  +  }
          689  +  expr {$::mj_filename1 != $::mj_filename}
          690  +} {1}
          691  +faultsim_restore_and_reopen
          692  +tv filter {}
          693  +
          694  +# The file-system now contains:
          695  +#
          696  +#   * three databases
          697  +#   * three hot-journal files
          698  +#   * two master-journal files.
          699  +#
          700  +# The hot-journals associated with test.db2 and test.db3 point to
          701  +# master journal $::mj_filename. The hot-journal file associated with
          702  +# test.db points to master journal $::mj_filename1. So reading from
          703  +# test.db should delete $::mj_filename1.
          704  +#
          705  +do_test pager1.4.6.9 {
          706  +  lsort [glob test.db*]
          707  +} [lsort [list                                           \
          708  +  test.db test.db2 test.db3                              \
          709  +  test.db-journal test.db2-journal test.db3-journal      \
          710  +  [file tail $::mj_filename] [file tail $::mj_filename1]
          711  +]]
          712  +
          713  +# The master-journal $::mj_filename1 contains pointers to test.db and 
          714  +# test.db2. However the hot-journal associated with test.db2 points to
          715  +# a different master-journal. Therefore, reading from test.db only should
          716  +# be enough to cause SQLite to delete $::mj_filename1.
          717  +#
          718  +do_test         pager1.4.6.10 { file exists $::mj_filename  } {1}
          719  +do_test         pager1.4.6.11 { file exists $::mj_filename1 } {1}
          720  +do_execsql_test pager1.4.6.12 { SELECT * FROM t1 } {1 t1.1}
          721  +do_test         pager1.4.6.13 { file exists $::mj_filename  } {1}
          722  +do_test         pager1.4.6.14 { file exists $::mj_filename1 } {0}
          723  +
          724  +do_execsql_test pager1.4.6.12 {
          725  +  ATTACH 'test.db2' AS two;
          726  +  SELECT * FROM t2;
          727  +} {1 t2.1}
          728  +do_test         pager1.4.6.13 { file exists $::mj_filename }  {1}
          729  +do_execsql_test pager1.4.6.14 {
          730  +  ATTACH 'test.db3' AS three;
          731  +  SELECT * FROM t3;
          732  +} {1 t3.1}
          733  +do_test         pager1.4.6.15 { file exists $::mj_filename }  {0}
   626    734   
   627    735   db close
   628    736   tv delete
   629    737   
   630    738   #-------------------------------------------------------------------------
   631    739   # The following tests deal with multi-file commits.
   632    740   #
................................................................................
   946   1054     }
   947   1055     list [B step 10000] [B finish]
   948   1056   } {SQLITE_DONE SQLITE_OK}
   949   1057   do_test pager1-9.2.3 {
   950   1058    db one {SELECT md5sum(a, b) FROM ab}
   951   1059   } [db2 one {SELECT md5sum(a, b) FROM ab}]
   952   1060   do_test pager1-9.2.4 { execsql { SELECT count(*) FROM ab } } {128}
         1061  +db close
         1062  +db2 close
         1063  +
         1064  +#-------------------------------------------------------------------------
         1065  +# Test that regardless of the value returned by xSectorSize(), the
         1066  +# minimum effective sector-size is 512 and the maximum 65536 bytes.
         1067  +#
         1068  +testvfs tv -default 1
         1069  +foreach sectorsize {
         1070  +    32   64   128   256   512   1024   2048 
         1071  +    4096 8192 16384 32768 65536 131072 262144
         1072  +} {
         1073  +  tv sectorsize $sectorsize
         1074  +  set eff $sectorsize
         1075  +  if {$sectorsize < 512}   { set eff 512 }
         1076  +  if {$sectorsize > 65536} { set eff 65536 }
         1077  +
         1078  +  do_test pager1-10.$sectorsize {
         1079  +    faultsim_delete_and_reopen
         1080  +    execsql {
         1081  +      PRAGMA journal_mode = PERSIST;
         1082  +      PRAGMA page_size = 1024;
         1083  +      CREATE TABLE t1(a, b);
         1084  +    }
         1085  +    file size test.db-journal
         1086  +  } [expr $sectorsize > 65536 ? 65536 : $sectorsize]
         1087  +}
         1088  +db close
         1089  +tv delete
         1090  +
         1091  +testvfs tv -default 1
         1092  +faultsim_delete_and_reopen
         1093  +db func a_string a_string
         1094  +do_execsql_test pager1-11.1 {
         1095  +  PRAGMA cache_size = 10;
         1096  +  BEGIN;
         1097  +    CREATE TABLE zz(top PRIMARY KEY);
         1098  +    INSERT INTO zz VALUES(a_string(222));
         1099  +    INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
         1100  +    INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
         1101  +    INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
         1102  +    INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
         1103  +    INSERT INTO zz SELECT a_string((SELECT 222+max(rowid) FROM zz)) FROM zz;
         1104  +  COMMIT;
         1105  +  BEGIN;
         1106  +    UPDATE zz SET top = a_string(345);
         1107  +} {}
         1108  +
         1109  +proc lockout {method args} { return SQLITE_IOERR }
         1110  +tv script lockout
         1111  +tv filter {xWrite xTruncate xSync}
         1112  +do_catchsql_test pager1-11.2 { COMMIT } {1 {disk I/O error}}
         1113  +
         1114  +tv script {}
         1115  +do_test pager1-11.3 {
         1116  +  sqlite3 db2 test.db
         1117  +  execsql {
         1118  +    PRAGMA journal_mode = TRUNCATE;
         1119  +    PRAGMA integrity_check;
         1120  +  } db2
         1121  +} {truncate ok}
         1122  +do_test pager1-11.4 {
         1123  +  db2 close
         1124  +  file size test.db-journal
         1125  +} {0}
         1126  +breakpoint
         1127  +do_execsql_test pager1-11.5 { SELECT count(*) FROM zz } {32}
         1128  +  
   953   1129   
   954   1130   finish_test
   955   1131   

Changes to test/pagerfault.test.

    93     93     execsql { SELECT * FROM abc }
    94     94   } -test {
    95     95     set answer [split [string repeat "ottffs" 128] ""]
    96     96     faultsim_test_result [list 0 $answer]
    97     97     faultsim_integrity_check
    98     98     set res [db eval { SELECT * FROM abc }]
    99     99     if {$res != $answer} { error "Database content appears incorrect ($res)" }
   100         -} -faults oom-transient
          100  +} 
   101    101   
   102    102   #-------------------------------------------------------------------------
   103    103   # Test fault-injection while rolling back hot-journals that were created
   104    104   # as part of a multi-file transaction.
   105    105   #
   106    106   do_test pagerfault-3-pre1 {
   107    107     testvfs tstvfs -default 1
................................................................................
   137    137         REPLACE INTO t2 SELECT * FROM t1;
   138    138       COMMIT;
   139    139     }
   140    140   
   141    141     db close
   142    142     tstvfs delete
   143    143   } {}
   144         -do_faultsim_test pagerfault-3 -faults ioerr-persistent -prep {
          144  +do_faultsim_test pagerfault-3 -prep {
   145    145     faultsim_restore_and_reopen
   146    146   } -body {
   147    147     execsql { 
   148    148       ATTACH 'test.db2' AS aux;
   149    149       SELECT count(*) FROM t2;
   150    150       SELECT count(*) FROM t1;
   151    151     }
................................................................................
   216    216     }
   217    217   } -body {
   218    218     execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }
   219    219   } -test {
   220    220     faultsim_test_result {0 {}}
   221    221     faultsim_integrity_check
   222    222   }
   223         -do_faultsim_test pagerfault-5.3 -prep {
          223  +do_faultsim_test pagerfault-5.3 -faults oom-transient -prep {
   224    224     faultsim_restore_and_reopen
   225    225     db func a_string a_string
   226    226     file delete -force test2.db test2.db-journal test2.db-wal
   227    227     execsql { 
   228    228       PRAGMA journal_mode = PERSIST;
   229    229       ATTACH 'test2.db' AS aux;
   230    230       PRAGMA aux.journal_mode = PERSIST;
................................................................................
   235    235       BEGIN;
   236    236         INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
   237    237         CREATE TABLE aux.t2 AS SELECT * FROM t1;
   238    238       COMMIT;
   239    239     }
   240    240   } -test {
   241    241     faultsim_test_result {0 {}}
          242  +  faultsim_integrity_check
          243  +
          244  +  set res ""
          245  +  set rc [catch { set res [db one { PRAGMA aux.integrity_check }] }]
          246  +  if {$rc!=0 || $res != "ok"} {error "integrity-check problem:$rc $res"}
   242    247   }
          248  +
   243    249   
   244    250   #-------------------------------------------------------------------------
   245    251   # Test fault-injection as part of a commit when using 
   246    252   # journal_mode=TRUNCATE.
   247    253   #
   248    254   do_test pagerfault-6-pre1 {
   249    255     faultsim_delete_and_reopen
................................................................................
   335    341       COMMIT;
   336    342       CREATE TABLE t1(a PRIMARY KEY, b);
   337    343       INSERT INTO t1 SELECT * FROM t2;
   338    344       DROP TABLE t2;
   339    345     }
   340    346     faultsim_save_and_close
   341    347   } {}
   342         -do_faultsim_test pagerfault-7 -faults full -prep {
          348  +do_faultsim_test pagerfault-7 -prep {
   343    349     faultsim_restore_and_reopen
   344    350     execsql { 
   345    351       PRAGMA cache_size = 10;
   346    352       BEGIN;
   347    353         UPDATE t1 SET b = randomblob(1500);
   348    354     }
   349    355   } -body {
................................................................................
   402    408       INSERT INTO t1 VALUES(randomblob(900));
   403    409       INSERT INTO t1 VALUES(randomblob(900));
   404    410       DELETE FROM t1;
   405    411     }
   406    412     faultsim_save_and_close
   407    413   } {}
   408    414   
   409         -do_faultsim_test pagerfault-9 -faults oom-transient -prep {
          415  +do_faultsim_test pagerfault-9 -prep {
   410    416     faultsim_restore_and_reopen
   411    417     execsql { 
   412    418       BEGIN;
   413    419         INSERT INTO t1 VALUES(randomblob(900));
   414    420         INSERT INTO t1 VALUES(randomblob(900));
   415    421         DROP TABLE t3;
   416    422         DROP TABLE t2;