diff options
Diffstat (limited to 'test/symlink.test')
-rw-r--r-- | test/symlink.test | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/test/symlink.test b/test/symlink.test new file mode 100644 index 0000000..98b2a32 --- /dev/null +++ b/test/symlink.test @@ -0,0 +1,210 @@ +# 2015 October 31 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing that SQLite can follow symbolic links. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix symlink + +# This only runs on unix. +if {$::tcl_platform(platform)!="unix"} { + finish_test + return +} + +# Ensure that test.db has been created. +# +do_execsql_test 1.0 { + CREATE TABLE t1(x, y); +} + +# Test that SQLite follows symlinks when opening files. +# +forcedelete test.db2 +do_test 1.1 { + file link test.db2 test.db + sqlite3 db2 test.db2 + sqlite3_db_filename db2 main +} [file join [pwd] test.db] + +# But not with the -nofollow flag +# +do_test 1.1.2 { + db2 close + set rc [catch {sqlite3 db2 test.db2 -nofollow 1} msg] + lappend rc $msg +} {1 {unable to open database file}} + +# If the main database is successfully opened with -nofollow, then -nofollow +# is also used for ATTACH. +# +do_test 1.1.3 { + catch {db2 close} + sqlite3 db2 test.db -nofollow 1 +} {} +do_test 1.1.4 { + catchsql {ATTACH 'test.db2' AS aux1;} db2 +} {1 {unable to open database: test.db2}} + +# Test that if the symlink points to a file that does not exists, it is +# created when it is opened. +# +do_test 1.2.1 { + catch {db2 close} + db close + forcedelete test.db + file exists test.db +} 0 +do_test 1.2.2 { + sqlite3 db2 test.db2 + file exists test.db +} 1 +do_test 1.2.3 { + sqlite3_db_filename db2 main +} [file join [pwd] test.db] +db2 close + +# Test that a loop of symlinks cannot be opened. +# +do_test 1.3 { + forcedelete test.db + # Note: Tcl [file link] command is too smart to create loops of symlinks. + exec ln -s test.db2 test.db + list [catch { sqlite3 db test.db } msg] $msg +} {1 {unable to open database file}} + +# Test that overly large paths cannot be opened. +# +do_test 1.4 { + set name "test.db[string repeat x 502]" + list [catch { sqlite3 db $name } msg] $msg +} {1 {unable to open database file}} +do_test 1.5 { + set r [expr 510 - [string length test.db] - [string length [pwd]]] + set name "test.db[string repeat x $r]" + list [catch { sqlite3 db $name } msg] $msg +} {1 {unable to open database file}} + +#------------------------------------------------------------------------- +# Test that journal and wal files are created next to the real file, +# not the symlink. +# +do_test 2.0 { + catch { db close } + catch { db2 close } + forcedelete test.db test.db2 test.db3 + sqlite3 db test.db + execsql { CREATE TABLE t1(x) } + file link test.db2 test.db + file link test.db3 test.db2 + set {} {} +} {} + +foreach {tn f} {1 test.db2 2 test.db3} { + do_test 2.$tn.1 { + sqlite3 db2 $f + file exists test.db-journal + } 0 + do_test 2.$tn.2 { + execsql { + BEGIN; + INSERT INTO t1 VALUES(1); + } db2 + file exists test.db-journal + } [expr [atomic_batch_write test.db]==0] + do_test 2.$tn.3 { + list [file exists test2.db-journal] [file exists test3.db-journal] + } {0 0} + do_test 2.$tn.4 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(2); + } db2 + file exists test.db-wal + } 1 + do_test 2.$tn.5 { + list [file exists test2.db-wal] [file exists test3.db-wal] + } {0 0} + do_execsql_test 2.$tn.6 { + SELECT * FROM t1; + } {1 2} + db2 close + do_execsql_test 2.$tn.7 { + DELETE FROM t1; + PRAGMA journal_mode = delete; + } delete +} + +# Try to open a ridiculously long pathname. Bug found by +# Kostya Serebryany using libFuzzer on 2015-11-30. +# +do_test 3.1 { + db close + catch {sqlite3 db [string repeat [string repeat x 100]/ 6]} res + set res +} {unable to open database file} + +#------------------------------------------------------------------------- +# Test that relative symlinks that are not located in the cwd work. +# +do_test 4.1 { + forcedelete x y z + file mkdir x + file mkdir y + file mkdir z + sqlite3 db x/test.db + file link y/test.db ../x/test.db + file link z/test.db ../y/test.db + execsql { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES('hello', 'world'); + } +} {wal} + +do_test 4.2.1 { + db close + sqlite3 db y/test.db + db eval { SELECT * FROM t1 } +} {hello world} +do_test 4.2.2 { + list [file exists x/test.db-wal] [file exists y/test.db-wal] +} {1 0} + +do_test 4.3.1 { + db close + sqlite3 db z/test.db + db eval { SELECT * FROM t1 } +} {hello world} +do_test 4.3.2 { + list [file exists x/test.db-wal] [file exists y/test.db-wal] \ + [file exists z/test.db-wal] +} {1 0 0} + +do_test 4.4.0 { + forcedelete w + file mkdir w + file link w/test.db [file join [pwd] x/test.db] + set {} {} +} {} +do_test 4.4.1 { + db close + sqlite3 db w/test.db + db eval { SELECT * FROM t1 } +} {hello world} +do_test 4.4.2 { + list [file exists x/test.db-wal] [file exists w/test.db-wal] +} {1 0} + +finish_test |