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