xref: /sqlite-3.40.0/test/syscall.test (revision efe16971)
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