Home | History | Annotate | Download | only in test
      1 # 2010 April 19
      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 operation of the library in
     13 # "PRAGMA journal_mode=WAL" mode.
     14 #
     15 
     16 set testdir [file dirname $argv0]
     17 source $testdir/tester.tcl
     18 source $testdir/malloc_common.tcl
     19 
     20 # If the library was compiled without WAL support, check that the 
     21 # "PRAGMA journal_mode=WAL" treats "WAL" as an unrecognized mode.
     22 #
     23 ifcapable !wal {
     24 
     25   do_test walmode-0.1 {
     26     execsql { PRAGMA journal_mode = wal }
     27   } {delete}
     28   do_test walmode-0.2 {
     29     execsql { PRAGMA main.journal_mode = wal }
     30   } {delete}
     31   do_test walmode-0.3 {
     32     execsql { PRAGMA main.journal_mode }
     33   } {delete}
     34 
     35   finish_test
     36   return
     37 }
     38 
     39 do_test walmode-1.1 {
     40   set sqlite_sync_count 0
     41   execsql { PRAGMA page_size = 1024 }
     42   execsql { PRAGMA journal_mode = wal }
     43 } {wal}
     44 do_test walmode-1.2 {
     45   file size test.db
     46 } {1024}
     47 
     48 set expected_sync_count 3
     49 if {$::tcl_platform(platform)!="windows"} {
     50   ifcapable dirsync {
     51     incr expected_sync_count
     52   }
     53 }
     54 do_test walmode-1.3 {
     55   set sqlite_sync_count
     56 } $expected_sync_count
     57 
     58 do_test walmode-1.4 {
     59   file exists test.db-wal
     60 } {0}
     61 do_test walmode-1.5 {
     62   execsql { CREATE TABLE t1(a, b) }
     63   file size test.db
     64 } {1024}
     65 do_test walmode-1.6 {
     66   file exists test.db-wal
     67 } {1}
     68 do_test walmode-1.7 {
     69   db close
     70   file exists test.db-wal
     71 } {0}
     72 
     73 # There is now a database file with the read and write versions set to 2
     74 # in the file system. This file should default to WAL mode.
     75 #
     76 do_test walmode-2.1 {
     77   sqlite3 db test.db
     78   file exists test.db-wal
     79 } {0}
     80 do_test walmode-2.2 {
     81   execsql { SELECT * FROM sqlite_master }
     82   file exists test.db-wal
     83 } {1}
     84 do_test walmode-2.3 {
     85   db close
     86   file exists test.db-wal
     87 } {0}
     88 
     89 # If the first statement executed is "PRAGMA journal_mode = wal", and
     90 # the file is already configured for WAL (read and write versions set
     91 # to 2), then there should be no need to write the database. The 
     92 # statement should cause the client to connect to the log file.
     93 #
     94 set sqlite_sync_count 0
     95 do_test walmode-3.1 {
     96   sqlite3 db test.db
     97   execsql { PRAGMA journal_mode = wal }
     98 } {wal}
     99 do_test walmode-3.2 {
    100   list $sqlite_sync_count [file exists test.db-wal] [file size test.db-wal]
    101 } {0 1 0}
    102 
    103 # Test that changing back to journal_mode=persist works.
    104 #
    105 do_test walmode-4.1 {
    106   execsql { INSERT INTO t1 VALUES(1, 2) }
    107   execsql { PRAGMA journal_mode = persist }
    108 } {persist}
    109 do_test walmode-4.2 {
    110   list [file exists test.db-journal] [file exists test.db-wal]
    111 } {1 0}
    112 do_test walmode-4.3 {
    113   execsql { SELECT * FROM t1 }
    114 } {1 2}
    115 do_test walmode-4.4 {
    116   db close
    117   sqlite3 db test.db
    118   execsql { SELECT * FROM t1 }
    119 } {1 2}
    120 do_test walmode-4.5 {
    121   list [file exists test.db-journal] [file exists test.db-wal]
    122 } {1 0}
    123 
    124 # Test that nothing goes wrong if a connection is prevented from changing
    125 # from WAL to rollback mode because a second connection has the database
    126 # open. Or from rollback to WAL.
    127 #
    128 do_test walmode-4.6 {
    129   sqlite3 db2 test.db
    130   execsql { PRAGMA main.journal_mode } db2
    131 } {delete}
    132 do_test walmode-4.7 {
    133   execsql { PRAGMA main.journal_mode = wal } db
    134 } {wal}
    135 do_test walmode-4.8 {
    136   execsql { SELECT * FROM t1 } db2
    137 } {1 2}
    138 do_test walmode-4.9 {
    139   catchsql { PRAGMA journal_mode = delete } db
    140 } {1 {database is locked}}
    141 do_test walmode-4.10 {
    142   execsql { PRAGMA main.journal_mode } db
    143 } {wal}
    144 
    145 do_test walmode-4.11 {
    146   db2 close
    147   execsql { PRAGMA journal_mode = delete } db
    148 } {delete}
    149 do_test walmode-4.12 {
    150   execsql { PRAGMA main.journal_mode } db
    151 } {delete}
    152 do_test walmode-4.13 {
    153   list [file exists test.db-journal] [file exists test.db-wal]
    154 } {0 0}
    155 do_test walmode-4.14 {
    156   sqlite3 db2 test.db
    157   execsql {
    158     BEGIN;
    159       SELECT * FROM t1;
    160   } db2
    161 } {1 2}
    162 
    163 do_test walmode-4.16 { execsql { PRAGMA main.journal_mode } db  } {delete}
    164 do_test walmode-4.17 { execsql { PRAGMA main.journal_mode } db2 } {delete}
    165 
    166 do_test walmode-4.17 {
    167   catchsql { PRAGMA main.journal_mode = wal } db
    168 } {1 {database is locked}}
    169 do_test walmode-4.18 {
    170   execsql { PRAGMA main.journal_mode } db
    171 } {delete}
    172 catch { db close }
    173 catch { db2 close }
    174 
    175 # Test that it is not possible to change a temporary or in-memory database
    176 # to WAL mode. WAL mode is for persistent file-backed databases only.
    177 #
    178 #   walmode-5.1.*: Try to set journal_mode=WAL on [sqlite3 db :memory:] database.
    179 #   walmode-5.2.*: Try to set journal_mode=WAL on [sqlite3 db ""] database.
    180 #   walmode-5.3.*: Try to set temp.journal_mode=WAL.
    181 #
    182 do_test walmode-5.1.1 {
    183   sqlite3 db :memory:
    184   execsql { PRAGMA main.journal_mode }
    185 } {memory}
    186 do_test walmode-5.1.2 {
    187   execsql { PRAGMA main.journal_mode = wal }
    188 } {memory}
    189 do_test walmode-5.1.3 {
    190   execsql {
    191     BEGIN;
    192       CREATE TABLE t1(a, b);
    193       INSERT INTO t1 VALUES(1, 2);
    194     COMMIT;
    195     SELECT * FROM t1;
    196     PRAGMA main.journal_mode;
    197   }
    198 } {1 2 memory}
    199 do_test walmode-5.1.4 {
    200   execsql { PRAGMA main.journal_mode = wal }
    201 } {memory}
    202 do_test walmode-5.1.5 {
    203   execsql { 
    204     INSERT INTO t1 VALUES(3, 4);
    205     SELECT * FROM t1;
    206     PRAGMA main.journal_mode;
    207   }
    208 } {1 2 3 4 memory}
    209 
    210 if {$TEMP_STORE>=2} {
    211   set tempJrnlMode memory
    212 } else {
    213   set tempJrnlMode delete
    214 }
    215 do_test walmode-5.2.1 {
    216   sqlite3 db ""
    217   execsql { PRAGMA main.journal_mode }
    218 } $tempJrnlMode
    219 do_test walmode-5.2.2 {
    220   execsql { PRAGMA main.journal_mode = wal }
    221 } $tempJrnlMode
    222 do_test walmode-5.2.3 {
    223   execsql {
    224     BEGIN;
    225       CREATE TABLE t1(a, b);
    226       INSERT INTO t1 VALUES(1, 2);
    227     COMMIT;
    228     SELECT * FROM t1;
    229     PRAGMA main.journal_mode;
    230   }
    231 } [list 1 2 $tempJrnlMode]
    232 do_test walmode-5.2.4 {
    233   execsql { PRAGMA main.journal_mode = wal }
    234 } $tempJrnlMode
    235 do_test walmode-5.2.5 {
    236   execsql { 
    237     INSERT INTO t1 VALUES(3, 4);
    238     SELECT * FROM t1;
    239     PRAGMA main.journal_mode;
    240   }
    241 } [list 1 2 3 4 $tempJrnlMode]
    242 
    243 do_test walmode-5.3.1 {
    244   sqlite3 db test.db
    245   execsql { PRAGMA temp.journal_mode }
    246 } $tempJrnlMode
    247 do_test walmode-5.3.2 {
    248   execsql { PRAGMA temp.journal_mode = wal }
    249 } $tempJrnlMode
    250 do_test walmode-5.3.3 {
    251   execsql {
    252     BEGIN;
    253       CREATE TEMP TABLE t1(a, b);
    254       INSERT INTO t1 VALUES(1, 2);
    255     COMMIT;
    256     SELECT * FROM t1;
    257     PRAGMA temp.journal_mode;
    258   }
    259 } [list 1 2 $tempJrnlMode]
    260 do_test walmode-5.3.4 {
    261   execsql { PRAGMA temp.journal_mode = wal }
    262 } $tempJrnlMode
    263 do_test walmode-5.3.5 {
    264   execsql { 
    265     INSERT INTO t1 VALUES(3, 4);
    266     SELECT * FROM t1;
    267     PRAGMA temp.journal_mode;
    268   }
    269 } [list 1 2 3 4 $tempJrnlMode]
    270 
    271 
    272 #-------------------------------------------------------------------------
    273 # Test changing to WAL mode from journal_mode=off or journal_mode=memory
    274 #
    275 foreach {tn mode} {
    276   1 off
    277   2 memory
    278   3 persist
    279   4 delete
    280   5 truncate
    281 } {
    282   do_test walmode-6.$tn {
    283     faultsim_delete_and_reopen
    284     execsql "
    285       PRAGMA journal_mode = $mode;
    286       PRAGMA journal_mode = wal;
    287     "
    288   } [list $mode wal]
    289 }
    290 db close
    291 
    292 #-------------------------------------------------------------------------
    293 # Test the effect of a "PRAGMA journal_mode" command being the first 
    294 # thing executed by a new connection. This means that the schema is not
    295 # loaded when sqlite3_prepare_v2() is called to compile the statement.
    296 #
    297 do_test walmode-7.0 {
    298   file delete -force test.db
    299   sqlite3 db test.db
    300   execsql {
    301     PRAGMA journal_mode = WAL;
    302     CREATE TABLE t1(a, b);
    303   }
    304 } {wal}
    305 foreach {tn sql result} {
    306   1  "PRAGMA journal_mode"                wal
    307   2  "PRAGMA main.journal_mode"           wal
    308   3  "PRAGMA journal_mode = delete"       delete
    309   4  "PRAGMA journal_mode"                delete
    310   5  "PRAGMA main.journal_mode"           delete
    311   6  "PRAGMA journal_mode = wal"          wal
    312   7  "PRAGMA journal_mode"                wal
    313   8  "PRAGMA main.journal_mode"           wal
    314 
    315   9  "PRAGMA journal_mode"                wal
    316  10  "PRAGMA main.journal_mode"           wal
    317  11  "PRAGMA main.journal_mode = delete"  delete
    318  12  "PRAGMA journal_mode"                delete
    319  13  "PRAGMA main.journal_mode"           delete
    320  14  "PRAGMA main.journal_mode = wal"     wal
    321  15  "PRAGMA journal_mode"                wal
    322  16  "PRAGMA main.journal_mode"           wal
    323 } {
    324   do_test walmode-7.$tn { 
    325     db close
    326     sqlite3 db test.db
    327     execsql $sql
    328   } $result
    329 }
    330 db close
    331 
    332 #-------------------------------------------------------------------------
    333 # Test the effect of a "PRAGMA journal_mode" command on an attached 
    334 # database.
    335 #
    336 faultsim_delete_and_reopen
    337 do_execsql_test walmode-8.1 {
    338   CREATE TABLE t1(a, b);
    339   PRAGMA journal_mode = WAL;
    340   ATTACH 'test.db2' AS two;
    341   CREATE TABLE two.t2(a, b);
    342 } {wal}
    343 do_execsql_test walmode-8.2 { PRAGMA main.journal_mode }         {wal}
    344 do_execsql_test walmode-8.3 { PRAGMA two.journal_mode  }         {delete}
    345 do_execsql_test walmode-8.4 { PRAGMA two.journal_mode = DELETE } {delete}
    346 
    347 db close
    348 sqlite3 db test.db
    349 do_execsql_test walmode-8.5  { ATTACH 'test.db2' AS two }          {}
    350 do_execsql_test walmode-8.6  { PRAGMA main.journal_mode }          {wal}
    351 do_execsql_test walmode-8.7  { PRAGMA two.journal_mode  }          {delete}
    352 do_execsql_test walmode-8.8  { INSERT INTO two.t2 DEFAULT VALUES } {}
    353 do_execsql_test walmode-8.9  { PRAGMA two.journal_mode  }          {delete}
    354 do_execsql_test walmode-8.10 { INSERT INTO t1 DEFAULT VALUES } {}
    355 do_execsql_test walmode-8.11 { PRAGMA main.journal_mode  }         {wal}
    356 do_execsql_test walmode-8.12 { PRAGMA journal_mode  }              {wal}
    357 
    358 # Change to WAL mode on test2.db and make sure (in the tests that follow)
    359 # that this mode change persists. 
    360 do_test walmode-8.x1 {
    361   execsql {
    362      PRAGMA two.journal_mode=WAL;
    363      PRAGMA two.journal_mode;
    364   }
    365 } {wal wal}
    366 
    367 db close
    368 sqlite3 db test.db
    369 do_execsql_test walmode-8.13 { PRAGMA journal_mode = WAL }         {wal}
    370 do_execsql_test walmode-8.14 { ATTACH 'test.db2' AS two  }         {}
    371 do_execsql_test walmode-8.15 { PRAGMA main.journal_mode  }         {wal}
    372 do_execsql_test walmode-8.16 { PRAGMA two.journal_mode   }         {wal}
    373 do_execsql_test walmode-8.17 { INSERT INTO two.t2 DEFAULT VALUES } {}
    374 do_execsql_test walmode-8.18 { PRAGMA two.journal_mode   }         {wal}
    375  
    376 sqlite3 db2 test.db2
    377 do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 }  {wal}
    378 db2 close
    379 
    380 do_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete}
    381 do_execsql_test walmode-8.21 { PRAGMA main.journal_mode }     {delete}
    382 do_execsql_test walmode-8.22 { PRAGMA two.journal_mode }      {delete}
    383 do_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL }    {wal}
    384 do_execsql_test walmode-8.21 { PRAGMA main.journal_mode }     {wal}
    385 do_execsql_test walmode-8.22 { PRAGMA two.journal_mode }      {wal}
    386 
    387 finish_test
    388