10fd7d860Sdan# 2011 March 29 20fd7d860Sdan# 30fd7d860Sdan# The author disclaims copyright to this source code. In place of 40fd7d860Sdan# a legal notice, here is a blessing: 50fd7d860Sdan# 60fd7d860Sdan# May you do good and not evil. 70fd7d860Sdan# May you find forgiveness for yourself and forgive others. 80fd7d860Sdan# May you share freely, never taking more than you give. 90fd7d860Sdan# 100fd7d860Sdan#*********************************************************************** 110fd7d860Sdan# 120fd7d860Sdan 130fd7d860Sdanset testdir [file dirname $argv0] 140fd7d860Sdansource $testdir/tester.tcl 150fd7d860Sdansource $testdir/lock_common.tcl 160fd7d860Sdansource $testdir/malloc_common.tcl 170fd7d860Sdan 180fd7d860Sdanif {[llength [info commands test_syscall]]==0} { 190fd7d860Sdan finish_test 200fd7d860Sdan return 210fd7d860Sdan} 220fd7d860Sdan 2351438a79Sdanif {[test_syscall defaultvfs] != "unix"} { 2451438a79Sdan finish_test 2551438a79Sdan return 2651438a79Sdan} 2751438a79Sdanset testprefix syscall 280fd7d860Sdan 290fd7d860Sdan#------------------------------------------------------------------------- 300fd7d860Sdan# Tests for the xSetSystemCall method. 310fd7d860Sdan# 320fd7d860Sdando_test 1.1.1 { 330fd7d860Sdan list [catch { test_syscall reset open } msg] $msg 340fd7d860Sdan} {0 {}} 350fd7d860Sdando_test 1.1.2 { 360fd7d860Sdan list [catch { test_syscall reset nosuchcall } msg] $msg 370fd7d860Sdan} {1 SQLITE_NOTFOUND} 380fd7d860Sdando_test 1.1.3 { 390fd7d860Sdan list [catch { test_syscall reset open } msg] $msg 400fd7d860Sdan} {0 {}} 410fd7d860Sdando_test 1.1.4 { 420fd7d860Sdan list [catch { test_syscall reset ""} msg] $msg 430fd7d860Sdan} {1 SQLITE_NOTFOUND} 440fd7d860Sdan 450fd7d860Sdando_test 1.2 { test_syscall reset } {} 460fd7d860Sdan 470fd7d860Sdando_test 1.3.1 { test_syscall install {open getcwd access} } {} 480fd7d860Sdando_test 1.3.2 { test_syscall reset } {} 490fd7d860Sdan 500fd7d860Sdan#------------------------------------------------------------------------- 510fd7d860Sdan# Tests for the xGetSystemCall method. 520fd7d860Sdan# 530fd7d860Sdando_test 2.1.1 { test_syscall exists open } 1 540fd7d860Sdando_test 2.1.2 { test_syscall exists nosuchcall } 0 550fd7d860Sdan 560fd7d860Sdan#------------------------------------------------------------------------- 570fd7d860Sdan# Tests for the xNextSystemCall method. 580fd7d860Sdan# 5951438a79Sdanforeach s { 6051438a79Sdan open close access getcwd stat fstat ftruncate 6151438a79Sdan fcntl read pread write pwrite fchmod fallocate 629ef6bc42Sdrh pread64 pwrite64 unlink openDirectory mkdir rmdir 636226ca2aSdrh statvfs fchown geteuid umask mmap munmap mremap 64*efe16971Sdan getpagesize readlink lstat ioctl 6551438a79Sdan} { 6651438a79Sdan if {[test_syscall exists $s]} {lappend syscall_list $s} 6751438a79Sdan} 6851438a79Sdando_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list] 690fd7d860Sdan 7060939d0aSdan#------------------------------------------------------------------------- 7160939d0aSdan# This test verifies that if a call to open() fails and errno is set to 7260939d0aSdan# EINTR, the call is retried. If it succeeds, execution continues as if 7360939d0aSdan# nothing happened. 7460939d0aSdan# 7560939d0aSdantest_syscall reset 7660939d0aSdanforcedelete test.db2 7760939d0aSdando_execsql_test 4.1 { 7860939d0aSdan CREATE TABLE t1(x, y); 7960939d0aSdan INSERT INTO t1 VALUES(1, 2); 8060939d0aSdan ATTACH 'test.db2' AS aux; 8160939d0aSdan CREATE TABLE aux.t2(x, y); 8260939d0aSdan INSERT INTO t2 VALUES(3, 4); 8360939d0aSdan} 8460939d0aSdan 8560939d0aSdandb_save_and_close 8660939d0aSdantest_syscall install open 8760939d0aSdanforeach jrnl [list wal delete] { 8860939d0aSdan for {set i 1} {$i < 20} {incr i} { 8960939d0aSdan db_restore_and_reopen 9060939d0aSdan test_syscall fault $i 0 9160939d0aSdan test_syscall errno open EINTR 9260939d0aSdan 9360939d0aSdan do_test 4.2.$jrnl.$i { 9460939d0aSdan sqlite3 db test.db 9560939d0aSdan execsql { ATTACH 'test.db2' AS aux } 9660939d0aSdan execsql "PRAGMA main.journal_mode = $jrnl" 9760939d0aSdan execsql "PRAGMA aux.journal_mode = $jrnl" 9860939d0aSdan execsql { 9960939d0aSdan BEGIN; 10060939d0aSdan INSERT INTO t1 VALUES(5, 6); 10160939d0aSdan INSERT INTO t2 VALUES(7, 8); 10260939d0aSdan COMMIT; 10360939d0aSdan } 10460939d0aSdan 10560939d0aSdan db close 10660939d0aSdan sqlite3 db test.db 10760939d0aSdan execsql { ATTACH 'test.db2' AS aux } 10860939d0aSdan execsql { 10960939d0aSdan SELECT * FROM t1; 11060939d0aSdan SELECT * FROM t2; 11160939d0aSdan } 11260939d0aSdan } {1 2 5 6 3 4 7 8} 11360939d0aSdan } 11460939d0aSdan} 11560939d0aSdan 1165ef47bf0Sdan#------------------------------------------------------------------------- 1175ef47bf0Sdan# This test verifies that closing database handles does not drop locks 1185ef47bf0Sdan# held by other database handles in the same process on the same file. 1195ef47bf0Sdan# 1205ef47bf0Sdan# The os_unix.c module has to take precautions to prevent this as the 1215ef47bf0Sdan# close() system call drops locks held by other file-descriptors on the 1225ef47bf0Sdan# same file. From the Linux man page: 1235ef47bf0Sdan# 1245ef47bf0Sdan# close() closes a file descriptor, so that it no longer refers to any file 1255ef47bf0Sdan# and may be reused. Any record locks (see fcntl(2)) held on the file it 1265ef47bf0Sdan# was associated with, and owned by the process, are removed (regardless 1275ef47bf0Sdan# of the file descriptor that was used to obtain the lock). 1285ef47bf0Sdan# 1295ef47bf0Sdancatch { db close } 1305ef47bf0Sdanforcedelete test.db test.db2 1315ef47bf0Sdan 1325ef47bf0Sdando_multiclient_test tn { 1335ef47bf0Sdan code1 { 1345ef47bf0Sdan sqlite3 dbX1 test.db 1355ef47bf0Sdan sqlite3 dbX2 test.db 1365ef47bf0Sdan } 1375ef47bf0Sdan 1385ef47bf0Sdan do_test syscall-5.$tn.1 { 1395ef47bf0Sdan sql1 { 1405ef47bf0Sdan CREATE TABLE t1(a, b); 1415ef47bf0Sdan INSERT INTO t1 VALUES(1, 2); 1425ef47bf0Sdan BEGIN; 1435ef47bf0Sdan INSERT INTO t1 VALUES(3, 4); 1445ef47bf0Sdan } 1455ef47bf0Sdan } {} 1465ef47bf0Sdan 1475ef47bf0Sdan do_test syscall-5.$tn.2 { sql2 { SELECT * FROM t1 } } {1 2} 1485ef47bf0Sdan do_test syscall-5.$tn.3 { 1495ef47bf0Sdan csql2 { INSERT INTO t1 VALUES(5, 6) } 1505ef47bf0Sdan } {1 {database is locked}} 1515ef47bf0Sdan 1525ef47bf0Sdan do_test syscall-5.$tn.4 { 1535ef47bf0Sdan code1 { 1545ef47bf0Sdan dbX1 close 1555ef47bf0Sdan dbX2 close 1565ef47bf0Sdan } 1575ef47bf0Sdan } {} 1585ef47bf0Sdan 1595ef47bf0Sdan do_test syscall-5.$tn.5 { 1605ef47bf0Sdan csql2 { INSERT INTO t1 VALUES(5, 6) } 1615ef47bf0Sdan } {1 {database is locked}} 1625ef47bf0Sdan 1635ef47bf0Sdan do_test syscall-5.$tn.6 { sql1 { COMMIT } } {} 1645ef47bf0Sdan 1655ef47bf0Sdan do_test syscall-5.$tn.7 { 1665ef47bf0Sdan csql2 { INSERT INTO t1 VALUES(5, 6) } 1675ef47bf0Sdan } {0 {}} 1685ef47bf0Sdan} 1695ef47bf0Sdan 1705ef47bf0Sdancatch {db close} 1715ef47bf0Sdando_test 6.1 { 1725ef47bf0Sdan sqlite3 db1 test.db1 1735ef47bf0Sdan sqlite3 db2 test.db2 1745ef47bf0Sdan sqlite3 db3 test.db3 1755ef47bf0Sdan sqlite3 dbM "" 1765ef47bf0Sdan 1775ef47bf0Sdan db2 close 1785ef47bf0Sdan db3 close 1795ef47bf0Sdan dbM close 1805ef47bf0Sdan db1 close 1815ef47bf0Sdan} {} 1825ef47bf0Sdan 1835ef47bf0Sdando_test 6.2 { 1845ef47bf0Sdan sqlite3 db test.db 1855ef47bf0Sdan execsql { 1865ef47bf0Sdan PRAGMA temp_store = file; 1875ef47bf0Sdan 1885ef47bf0Sdan PRAGMA main.cache_size = 10; 1895ef47bf0Sdan PRAGMA temp.cache_size = 10; 1905ef47bf0Sdan CREATE TABLE temp.tt(a, b); 1915ef47bf0Sdan INSERT INTO tt VALUES(randomblob(500), randomblob(600)); 1925ef47bf0Sdan INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 1935ef47bf0Sdan INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 1945ef47bf0Sdan INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 1955ef47bf0Sdan INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 1965ef47bf0Sdan INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 1975ef47bf0Sdan INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 1985ef47bf0Sdan INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 1995ef47bf0Sdan INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt; 2005ef47bf0Sdan } 2015ef47bf0Sdan 2025ef47bf0Sdan db close 2035ef47bf0Sdan} {} 2045ef47bf0Sdan 205661d71afSdan#------------------------------------------------------------------------- 206661d71afSdan# Test that a database file a single byte in size is treated as an empty 207661d71afSdan# file. Whereas a file 2 bytes or larger might be considered corrupt. 208661d71afSdan# 209661d71afSdancatch { db close } 210661d71afSdanforcedelete test.db test.db2 211661d71afSdan 212661d71afSdanproc create_db_file {nByte} { 213661d71afSdan set fd [open test.db w] 214661d71afSdan fconfigure $fd -translation binary -encoding binary 215661d71afSdan puts -nonewline $fd [string range "xSQLite" 1 $nByte] 216661d71afSdan close $fd 217661d71afSdan} 218661d71afSdan 219661d71afSdanforeach {nByte res} { 220661d71afSdan 1 {0 {}} 221ff4fa772Sdrh 2 {1 {file is not a database}} 222ff4fa772Sdrh 3 {1 {file is not a database}} 223661d71afSdan} { 224661d71afSdan do_test 7.$nByte { 225661d71afSdan create_db_file $nByte 22626ec621aSdan list [catch { 227661d71afSdan sqlite3 db test.db 22826ec621aSdan execsql { CREATE TABLE t1(a, b) } 22926ec621aSdan } msg] $msg 230661d71afSdan } $res 231661d71afSdan catch { db close } 232661d71afSdan} 233661d71afSdan 234661d71afSdan#------------------------------------------------------------------------- 235661d71afSdan# 236661d71afSdancatch { db close } 237661d71afSdanforcedelete test.db test.db2 238661d71afSdan 239661d71afSdando_test 8.1 { 240661d71afSdan sqlite3 db test.db 241661d71afSdan file_control_chunksize_test db main 4096 242661d71afSdan file size test.db 243661d71afSdan} {0} 244661d71afSdanforeach {tn hint size} { 245661d71afSdan 1 1000 4096 246661d71afSdan 2 1000 4096 247661d71afSdan 3 3000 4096 248661d71afSdan 4 4096 4096 249661d71afSdan 5 4197 8192 250661d71afSdan} { 251661d71afSdan do_test 8.2.$tn { 252661d71afSdan file_control_sizehint_test db main $hint 253661d71afSdan file size test.db 254661d71afSdan } $size 255661d71afSdan} 256661d71afSdan 257dc5df0f8Sdando_test 8.3 { 258dc5df0f8Sdan db close 259dc5df0f8Sdan forcedelete test.db test.db2 260dc5df0f8Sdan sqlite3 db test.db 261dc5df0f8Sdan file_control_chunksize_test db main 16 262dc5df0f8Sdan file size test.db 263dc5df0f8Sdan} {0} 264dc5df0f8Sdanforeach {tn hint size} { 265dc5df0f8Sdan 1 5 16 266dc5df0f8Sdan 2 13 16 267dc5df0f8Sdan 3 45 48 268dc5df0f8Sdan 4 48 48 269dc5df0f8Sdan 5 49 64 270dc5df0f8Sdan} { 271dc5df0f8Sdan do_test 8.4.$tn { 272dc5df0f8Sdan file_control_sizehint_test db main $hint 273dc5df0f8Sdan file size test.db 274dc5df0f8Sdan } $size 275dc5df0f8Sdan} 276dc5df0f8Sdan 27751438a79Sdantest_syscall reset 2780fd7d860Sdanfinish_test 279