xref: /sqlite-3.40.0/test/syscall.test (revision 5ef47bf0)
1# 2011 March 29
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
13set testdir [file dirname $argv0]
14source $testdir/tester.tcl
15source $testdir/lock_common.tcl
16source $testdir/malloc_common.tcl
17
18if {[llength [info commands test_syscall]]==0} {
19  finish_test
20  return
21}
22set testprefix syscall
23
24
25#-------------------------------------------------------------------------
26# Tests for the xSetSystemCall method.
27#
28do_test 1.1.1 {
29  list [catch { test_syscall reset open } msg] $msg
30} {0 {}}
31do_test 1.1.2 {
32  list [catch { test_syscall reset nosuchcall } msg] $msg
33} {1 SQLITE_NOTFOUND}
34do_test 1.1.3 {
35  list [catch { test_syscall reset open } msg] $msg
36} {0 {}}
37do_test 1.1.4 {
38  list [catch { test_syscall reset ""} msg] $msg
39} {1 SQLITE_NOTFOUND}
40
41do_test 1.2 { test_syscall reset } {}
42
43do_test 1.3.1 { test_syscall install {open getcwd access} } {}
44do_test 1.3.2 { test_syscall reset } {}
45
46#-------------------------------------------------------------------------
47# Tests for the xGetSystemCall method.
48#
49do_test 2.1.1 { test_syscall exists open } 1
50do_test 2.1.2 { test_syscall exists nosuchcall } 0
51
52#-------------------------------------------------------------------------
53# Tests for the xNextSystemCall method.
54#
55set syscall_list [list                                \
56    open close access getcwd stat fstat ftruncate     \
57    fcntl read pread write pwrite fchmod              \
58]
59if {[test_syscall exists fallocate]} {lappend syscall_list fallocate}
60do_test 3.1 { test_syscall list } $syscall_list
61
62#-------------------------------------------------------------------------
63# This test verifies that if a call to open() fails and errno is set to
64# EINTR, the call is retried. If it succeeds, execution continues as if
65# nothing happened.
66#
67test_syscall reset
68forcedelete test.db2
69do_execsql_test 4.1 {
70  CREATE TABLE t1(x, y);
71  INSERT INTO t1 VALUES(1, 2);
72  ATTACH 'test.db2' AS aux;
73  CREATE TABLE aux.t2(x, y);
74  INSERT INTO t2 VALUES(3, 4);
75}
76
77db_save_and_close
78test_syscall install open
79foreach jrnl [list wal delete] {
80  for {set i 1} {$i < 20} {incr i} {
81    db_restore_and_reopen
82    test_syscall fault $i 0
83    test_syscall errno open EINTR
84
85    do_test 4.2.$jrnl.$i {
86      sqlite3 db test.db
87      execsql { ATTACH 'test.db2' AS aux }
88      execsql "PRAGMA main.journal_mode = $jrnl"
89      execsql "PRAGMA aux.journal_mode = $jrnl"
90      execsql {
91        BEGIN;
92          INSERT INTO t1 VALUES(5, 6);
93          INSERT INTO t2 VALUES(7, 8);
94        COMMIT;
95      }
96
97      db close
98      sqlite3 db test.db
99      execsql { ATTACH 'test.db2' AS aux }
100      execsql {
101        SELECT * FROM t1;
102        SELECT * FROM t2;
103      }
104    } {1 2 5 6 3 4 7 8}
105  }
106}
107
108#-------------------------------------------------------------------------
109# This test verifies that closing database handles does not drop locks
110# held by other database handles in the same process on the same file.
111#
112# The os_unix.c module has to take precautions to prevent this as the
113# close() system call drops locks held by other file-descriptors on the
114# same file. From the Linux man page:
115#
116#   close() closes a file descriptor, so that it no longer refers to any file
117#   and may be reused. Any record locks (see fcntl(2)) held on the file it
118#   was associated with, and owned by the process, are removed (regardless
119#   of the file descriptor that was used to obtain the lock).
120#
121catch { db close }
122forcedelete test.db test.db2
123
124do_multiclient_test tn {
125  code1 {
126    sqlite3 dbX1 test.db
127    sqlite3 dbX2 test.db
128  }
129
130  do_test syscall-5.$tn.1 {
131    sql1 {
132      CREATE TABLE t1(a, b);
133      INSERT INTO t1 VALUES(1, 2);
134      BEGIN;
135        INSERT INTO t1 VALUES(3, 4);
136    }
137  } {}
138
139  do_test syscall-5.$tn.2 { sql2 { SELECT * FROM t1 } } {1 2}
140  do_test syscall-5.$tn.3 {
141    csql2 { INSERT INTO t1 VALUES(5, 6) }
142  } {1 {database is locked}}
143
144  do_test syscall-5.$tn.4 {
145    code1 {
146      dbX1 close
147      dbX2 close
148    }
149  } {}
150
151  do_test syscall-5.$tn.5 {
152    csql2 { INSERT INTO t1 VALUES(5, 6) }
153  } {1 {database is locked}}
154
155  do_test syscall-5.$tn.6 { sql1 { COMMIT } } {}
156
157  do_test syscall-5.$tn.7 {
158    csql2 { INSERT INTO t1 VALUES(5, 6) }
159  } {0 {}}
160}
161
162catch {db close}
163do_test 6.1 {
164  sqlite3 db1 test.db1
165  sqlite3 db2 test.db2
166  sqlite3 db3 test.db3
167  sqlite3 dbM ""
168
169  db2 close
170  db3 close
171  dbM close
172  db1 close
173} {}
174
175do_test 6.2 {
176  sqlite3 db test.db
177  execsql {
178    PRAGMA temp_store = file;
179
180    PRAGMA main.cache_size = 10;
181    PRAGMA temp.cache_size = 10;
182    CREATE TABLE temp.tt(a, b);
183    INSERT INTO tt VALUES(randomblob(500), randomblob(600));
184    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
185    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
186    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
187    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
188    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
189    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
190    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
191    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
192  }
193
194  db close
195} {}
196
197
198
199finish_test
200