1# 2011 May 09 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# 12# This file contains tests for using WAL databases in read-only mode. 13# 14 15set testdir [file dirname $argv0] 16source $testdir/tester.tcl 17source $testdir/lock_common.tcl 18set ::testprefix walro 19 20# These tests are only going to work on unix. 21# 22if {$::tcl_platform(platform) != "unix"} { 23 finish_test 24 return 25} 26 27# And only if the build is WAL-capable. 28# 29ifcapable !wal { 30 finish_test 31 return 32} 33 34do_multiclient_test tn { 35 # Do not run tests with the connections in the same process. 36 # 37 if {$tn==2} continue 38 39 # Close all connections and delete the database. 40 # 41 code1 { db close } 42 code2 { db2 close } 43 code3 { db3 close } 44 forcedelete test.db 45 forcedelete walro 46 47 foreach c {code1 code2 code3} { 48 $c { 49 sqlite3_shutdown 50 sqlite3_config_uri 1 51 } 52 } 53 54 file mkdir walro 55 56 do_test 1.1.1 { 57 code2 { sqlite3 db2 test.db } 58 sql2 { 59 PRAGMA journal_mode = WAL; 60 CREATE TABLE t1(x, y); 61 INSERT INTO t1 VALUES('a', 'b'); 62 } 63 file exists test.db-shm 64 } {1} 65 66 do_test 1.1.2 { 67 file attributes test.db-shm -permissions r--r--r-- 68 code1 { sqlite3 db file:test.db?readonly_shm=1 } 69 } {} 70 71 do_test 1.1.3 { sql1 "SELECT * FROM t1" } {a b} 72 do_test 1.1.4 { sql2 "INSERT INTO t1 VALUES('c', 'd')" } {} 73 do_test 1.1.5 { sql1 "SELECT * FROM t1" } {a b c d} 74 75 # Check that the read-only connection cannot write or checkpoint the db. 76 # 77 do_test 1.1.6 { 78 csql1 "INSERT INTO t1 VALUES('e', 'f')" 79 } {1 {attempt to write a readonly database}} 80 do_test 1.1.7 { 81 csql1 "PRAGMA wal_checkpoint" 82 } {1 {attempt to write a readonly database}} 83 84 do_test 1.1.9 { sql2 "INSERT INTO t1 VALUES('e', 'f')" } {} 85 do_test 1.1.10 { sql1 "SELECT * FROM t1" } {a b c d e f} 86 87 do_test 1.1.11 { 88 sql2 { 89 INSERT INTO t1 VALUES('g', 'h'); 90 PRAGMA wal_checkpoint; 91 } 92 set {} {} 93 } {} 94 do_test 1.1.12 { sql1 "SELECT * FROM t1" } {a b c d e f g h} 95 do_test 1.1.13 { sql2 "INSERT INTO t1 VALUES('i', 'j')" } {} 96 97 do_test 1.2.1 { 98 code2 { db2 close } 99 code1 { db close } 100 list [file exists test.db-wal] [file exists test.db-shm] 101 } {1 1} 102 do_test 1.2.2 { 103 code1 { sqlite3 db file:test.db?readonly_shm=1 } 104 sql1 { SELECT * FROM t1 } 105 } {a b c d e f g h i j} 106 107 do_test 1.2.3 { 108 code1 { db close } 109 file attributes test.db-shm -permissions rw-r--r-- 110 hexio_write test.db-shm 0 01020304 111 file attributes test.db-shm -permissions r--r--r-- 112 code1 { sqlite3 db file:test.db?readonly_shm=1 } 113 csql1 { SELECT * FROM t1 } 114 } {1 {attempt to write a readonly database}} 115 do_test 1.2.4 { 116 code1 { sqlite3_extended_errcode db } 117 } {SQLITE_READONLY_RECOVERY} 118 119 do_test 1.2.5 { 120 file attributes test.db-shm -permissions rw-r--r-- 121 code2 { sqlite3 db2 test.db } 122 sql2 "SELECT * FROM t1" 123 } {a b c d e f g h i j} 124 file attributes test.db-shm -permissions r--r--r-- 125 do_test 1.2.6 { sql1 "SELECT * FROM t1" } {a b c d e f g h i j} 126 127 do_test 1.2.7 { 128 sql2 { 129 PRAGMA wal_checkpoint; 130 INSERT INTO t1 VALUES('k', 'l'); 131 } 132 set {} {} 133 } {} 134 do_test 1.2.8 { sql1 "SELECT * FROM t1" } {a b c d e f g h i j k l} 135 136 # Now check that if the readonly_shm option is not supplied, or if it 137 # is set to zero, it is not possible to connect to the database without 138 # read-write access to the shm. 139 do_test 1.3.1 { 140 code1 { db close } 141 code1 { sqlite3 db test.db } 142 csql1 { SELECT * FROM t1 } 143 } {1 {unable to open database file}} 144 145 # Also test that if the -shm file can be opened for read/write access, 146 # it is not if readonly_shm=1 is present in the URI. 147 do_test 1.3.2.1 { 148 code1 { db close } 149 code2 { db2 close } 150 file exists test.db-shm 151 } {0} 152 do_test 1.3.2.2 { 153 code1 { sqlite3 db file:test.db?readonly_shm=1 } 154 csql1 { SELECT * FROM sqlite_master } 155 } {1 {unable to open database file}} 156 do_test 1.3.2.3 { 157 code1 { db close } 158 close [open test.db-shm w] 159 file attributes test.db-shm -permissions r--r--r-- 160 code1 { sqlite3 db file:test.db?readonly_shm=1 } 161 csql1 { SELECT * FROM t1 } 162 } {1 {attempt to write a readonly database}} 163 do_test 1.3.2.4 { 164 code1 { sqlite3_extended_errcode db } 165 } {SQLITE_READONLY_RECOVERY} 166} 167 168finish_test 169