dan | f5da7db | 2017-03-16 18:14:39 +0000 | [diff] [blame] | 1 | # 2017 March 16 |
| 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. |
| 12 | # |
| 13 | # Specificly, it tests that "PRAGMA synchronous" appears to work. |
| 14 | # |
| 15 | |
| 16 | set testdir [file dirname $argv0] |
| 17 | source $testdir/tester.tcl |
| 18 | set testprefix sync2 |
| 19 | |
| 20 | # |
| 21 | # These tests are only applicable when pager pragma are |
| 22 | # enabled. Also, since every test uses an ATTACHed database, they |
| 23 | # are only run when ATTACH is enabled. |
| 24 | # |
dan | cfb3235 | 2017-04-03 13:59:22 +0000 | [diff] [blame] | 25 | ifcapable !pager_pragmas||!attach||!dirsync { |
dan | f5da7db | 2017-03-16 18:14:39 +0000 | [diff] [blame] | 26 | finish_test |
| 27 | return |
| 28 | } |
dan | a14b7e0 | 2017-03-21 10:45:38 +0000 | [diff] [blame] | 29 | if {$::tcl_platform(platform)!="unix" |
| 30 | || [permutation] == "journaltest" |
| 31 | || [permutation] == "inmemory_journal" |
dan | 69aedc8 | 2018-01-13 13:07:49 +0000 | [diff] [blame] | 32 | || [atomic_batch_write test.db] |
dan | a14b7e0 | 2017-03-21 10:45:38 +0000 | [diff] [blame] | 33 | } { |
dan | 154cc74 | 2017-03-20 15:11:40 +0000 | [diff] [blame] | 34 | finish_test |
| 35 | return |
| 36 | } |
dan | f5da7db | 2017-03-16 18:14:39 +0000 | [diff] [blame] | 37 | |
| 38 | proc execsql_sync {sql} { |
| 39 | set s $::sqlite_sync_count |
| 40 | set res [execsql $sql] |
| 41 | concat [expr $::sqlite_sync_count-$s] $res |
| 42 | } |
| 43 | |
| 44 | proc do_execsql_sync_test {tn sql res} { |
| 45 | uplevel [list do_test $tn [list execsql_sync $sql] [list {*}$res]] |
| 46 | } |
| 47 | |
| 48 | #----------------------------------------------------------------------- |
| 49 | # Tests for journal mode. |
| 50 | # |
| 51 | sqlite3 db test.db |
| 52 | do_execsql_test 1.0 { |
| 53 | CREATE TABLE t1(a, b); |
| 54 | INSERT INTO t1 VALUES(1, 2); |
| 55 | } |
| 56 | |
| 57 | do_execsql_sync_test 1.1 { INSERT INTO t1 VALUES(3, 4) } 4 |
| 58 | |
| 59 | # synchronous=normal. So, 1 sync on the directory, 1 on the journal, 1 |
| 60 | # on the db file. 3 in total. |
| 61 | do_execsql_test 1.2.1 { PRAGMA main.synchronous = NORMAL } |
| 62 | do_execsql_test 1.2.2 { PRAGMA main.synchronous } 1 |
| 63 | do_execsql_sync_test 1.2.3 { INSERT INTO t1 VALUES(5, 6) } 3 |
| 64 | |
| 65 | # synchronous=off. No syncs. |
| 66 | do_execsql_test 1.3.1 { PRAGMA main.synchronous = OFF } |
| 67 | do_execsql_test 1.3.2 { PRAGMA main.synchronous } 0 |
| 68 | do_execsql_sync_test 1.3.3 { INSERT INTO t1 VALUES(7, 8) } 0 |
| 69 | |
| 70 | # synchronous=full, journal_mode=delete. So, 1 sync on the directory, |
| 71 | # 2 on the journal, 1 on the db file. 4 in total. |
| 72 | do_execsql_test 1.4.1 { PRAGMA main.synchronous = FULL } |
| 73 | do_execsql_test 1.4.2 { PRAGMA main.synchronous } 2 |
| 74 | do_execsql_sync_test 1.4.3 { INSERT INTO t1 VALUES(9, 10) } 4 |
| 75 | |
| 76 | #----------------------------------------------------------------------- |
| 77 | # Tests for wal mode. |
| 78 | # |
| 79 | do_execsql_test 1.5 { PRAGMA journal_mode = wal } {wal} |
| 80 | |
| 81 | # sync=full, journal_mode=wal. One sync on the directory, two on the |
| 82 | # wal file. |
| 83 | do_execsql_sync_test 1.6 { INSERT INTO t1 VALUES(11, 12) } 3 |
| 84 | |
| 85 | # One sync on the wal file. |
| 86 | do_execsql_sync_test 1.7 { INSERT INTO t1 VALUES(13, 14) } 1 |
| 87 | |
| 88 | # No syncs. |
| 89 | do_execsql_test 1.8.1 { PRAGMA main.synchronous = NORMAL } |
| 90 | do_execsql_test 1.8.2 { PRAGMA main.synchronous } 1 |
| 91 | do_execsql_sync_test 1.8.3 { INSERT INTO t1 VALUES(15, 16) } 0 |
| 92 | |
| 93 | # One sync on wal file, one on the db file. |
| 94 | do_execsql_sync_test 1.9 { PRAGMA wal_checkpoint } {2 0 3 3} |
| 95 | |
| 96 | # No syncs. |
| 97 | do_execsql_test 1.10.1 { PRAGMA main.synchronous = OFF } |
| 98 | do_execsql_test 1.10.2 { PRAGMA main.synchronous } 0 |
| 99 | do_execsql_sync_test 1.10.3 { INSERT INTO t1 VALUES(17, 18) } 0 |
| 100 | |
| 101 | #----------------------------------------------------------------------- |
| 102 | # Tests for the compile time settings SQLITE_DEFAULT_SYNCHRONOUS and |
| 103 | # SQLITE_DEFAULT_WAL_SYNCHRONOUS. These tests only run if the former |
| 104 | # is set to "2" and the latter to "1". This is not the default, but |
| 105 | # it is currently the recommended configuration. |
| 106 | # |
| 107 | # https://sqlite.org/compile.html#recommended_compile_time_options |
| 108 | # |
| 109 | if {$SQLITE_DEFAULT_SYNCHRONOUS==2 && $SQLITE_DEFAULT_WAL_SYNCHRONOUS==1} { |
| 110 | |
| 111 | db close |
| 112 | sqlite3 db test.db |
| 113 | |
| 114 | # Wal mode, sync=normal. The first transaction does one sync on directory, |
| 115 | # one on the wal file. The second does no syncs. |
| 116 | do_execsql_sync_test 1.11.1 { INSERT INTO t1 VALUES(19, 20) } 2 |
| 117 | do_execsql_sync_test 1.11.2 { INSERT INTO t1 VALUES(21, 22) } 0 |
| 118 | do_execsql_test 1.11.3 { PRAGMA main.synchronous } 1 |
| 119 | |
| 120 | # One sync on wal file, one on the db file. |
| 121 | do_execsql_sync_test 1.12 { PRAGMA wal_checkpoint } {2 0 2 2} |
| 122 | |
| 123 | # First transaction syncs the wal file once, the second not at all. |
| 124 | # one on the wal file. The second does no syncs. |
| 125 | do_execsql_sync_test 1.13.1 { INSERT INTO t1 VALUES(22, 23) } 1 |
| 126 | do_execsql_sync_test 1.13.2 { INSERT INTO t1 VALUES(24, 25) } 0 |
| 127 | |
| 128 | do_execsql_test 1.14 { PRAGMA journal_mode = delete } {delete} |
| 129 | |
| 130 | # Delete mode, sync=full. The first transaction does one sync on |
| 131 | # directory, two on the journal file, one on the db. The second does |
| 132 | # the same. |
| 133 | do_execsql_sync_test 1.15.1 { INSERT INTO t1 VALUES(26, 27) } 4 |
| 134 | do_execsql_sync_test 1.15.2 { INSERT INTO t1 VALUES(28, 29) } 4 |
| 135 | do_execsql_test 1.15.3 { PRAGMA main.synchronous } 2 |
| 136 | |
| 137 | # Switch back to wal mode. |
| 138 | do_execsql_test 1.16 { PRAGMA journal_mode = wal } {wal} |
| 139 | |
| 140 | do_execsql_sync_test 1.17.1 { INSERT INTO t1 VALUES(30, 31) } 2 |
| 141 | do_execsql_sync_test 1.17.2 { INSERT INTO t1 VALUES(32, 33) } 0 |
| 142 | do_execsql_test 1.17.3 { PRAGMA main.synchronous } 1 |
| 143 | |
| 144 | # Now set synchronous=off, then switch back to delete mode. Check |
| 145 | # that the db handle is still using synchronous=off. |
| 146 | do_execsql_test 1.18.3 { PRAGMA main.synchronous=off } |
| 147 | do_execsql_test 1.18 { PRAGMA journal_mode = delete } {delete} |
| 148 | |
| 149 | do_execsql_sync_test 1.19.1 { INSERT INTO t1 VALUES(34, 35) } 0 |
| 150 | do_execsql_sync_test 1.19.2 { INSERT INTO t1 VALUES(36, 37) } 0 |
| 151 | do_execsql_test 1.19.3 { PRAGMA main.synchronous } 0 |
| 152 | |
| 153 | # Close and reopen the db. Back to synchronous=normal. |
| 154 | db close |
| 155 | sqlite3 db test.db |
| 156 | do_execsql_sync_test 1.20.1 { INSERT INTO t1 VALUES(38, 39) } 4 |
| 157 | do_execsql_sync_test 1.20.2 { INSERT INTO t1 VALUES(40, 41) } 4 |
| 158 | do_execsql_test 1.20.3 { PRAGMA main.synchronous } 2 |
| 159 | } |
| 160 | |
| 161 | finish_test |