xref: /sqlite-3.40.0/test/oserror.test (revision 3af1b60e)
1e18d4953Sdan# 2011 February 19
2e18d4953Sdan#
3e18d4953Sdan# The author disclaims copyright to this source code.  In place of
4e18d4953Sdan# a legal notice, here is a blessing:
5e18d4953Sdan#
6e18d4953Sdan#    May you do good and not evil.
7e18d4953Sdan#    May you find forgiveness for yourself and forgive others.
8e18d4953Sdan#    May you share freely, never taking more than you give.
9e18d4953Sdan#
10e18d4953Sdan#***********************************************************************
11e18d4953Sdan# This file implements regression tests for SQLite library.  The
12e18d4953Sdan# focus of this file is testing that error messages are logged via the
13e18d4953Sdan# sqlite3_log() mechanism when certain errors are encountered in the
14e18d4953Sdan# default unix or windows VFS modules.
15e18d4953Sdan#
16e18d4953Sdan
17e18d4953Sdanset testdir [file dirname $argv0]
18e18d4953Sdansource $testdir/tester.tcl
19e18d4953Sdanif {$::tcl_platform(platform)!="unix"} { finish_test ; return }
20e18d4953Sdanset ::testprefix oserror
21e18d4953Sdan
22e18d4953Sdandb close
23e18d4953Sdansqlite3_shutdown
24e18d4953Sdantest_sqlite3_log xLog
25e18d4953Sdanproc xLog {error_code msg} {
26e18d4953Sdan  if {[string match os_* $msg]} {
27e18d4953Sdan    lappend ::log $msg
28e18d4953Sdan  }
29e18d4953Sdan}
30e18d4953Sdan
31e18d4953Sdanproc do_re_test {tn script expression} {
32e18d4953Sdan  uplevel do_test $tn [list [subst -nocommands {
33e18d4953Sdan    set res [eval { $script }]
34e18d4953Sdan    if {[regexp {$expression} [set res]]} {
35e18d4953Sdan      set {} {$expression}
36e18d4953Sdan    } else {
37e18d4953Sdan      set res
38e18d4953Sdan    }
39e18d4953Sdan  }]] [list $expression]
40e18d4953Sdan
41e18d4953Sdan}
42e18d4953Sdan
43e18d4953Sdan#--------------------------------------------------------------------------
44e18d4953Sdan# Tests oserror-1.* test failures in the open() system call.
45e18d4953Sdan#
46e18d4953Sdan
47e18d4953Sdan# Test a failure in open() due to too many files.
48e18d4953Sdan#
49211fb084Sdan# The xOpen() method of the unix VFS calls getcwd() as well as open().
50211fb084Sdan# Although this does not appear to be documented in the man page, on OSX
51211fb084Sdan# a call to getcwd() may fail if there are no free file descriptors. So
52211fb084Sdan# an error may be reported for either open() or getcwd() here.
53211fb084Sdan#
5432e1f279Sdrhif {![clang_sanitize_address]} {
55*3af1b60eSdrh  unset -nocomplain rc
56*3af1b60eSdrh  unset -nocomplain nOpen
57*3af1b60eSdrh  set nOpen 20000
58e18d4953Sdan  do_test 1.1.1 {
59e18d4953Sdan    set ::log [list]
60*3af1b60eSdrh    set ::rc [catch {
61*3af1b60eSdrh      for {set i 0} {$i < $::nOpen} {incr i} { sqlite3 dbh_$i test.db -readonly 1 }
62*3af1b60eSdrh    } msg]
63*3af1b60eSdrh    if {$::rc==0} {
64*3af1b60eSdrh      # Some system (ex: Debian) are able to create 20000+ file descriptiors
65*3af1b60eSdrh      # such systems will not fail here
66*3af1b60eSdrh      set x ok
67*3af1b60eSdrh    } elseif {$::rc==1 && $msg=="unable to open database file"} {
68*3af1b60eSdrh      set x ok
69*3af1b60eSdrh    } else {
70*3af1b60eSdrh      set x [list $::rc $msg]
71*3af1b60eSdrh    }
72*3af1b60eSdrh  } {ok}
73e18d4953Sdan  do_test 1.1.2 {
74*3af1b60eSdrh    catch { for {set i 0} {$i < $::nOpen} {incr i} { dbh_$i close } }
75*3af1b60eSdrh  } $::rc
76*3af1b60eSdrh  if {$rc} {
77211fb084Sdan    do_re_test 1.1.3 {
78211fb084Sdan      lindex $::log 0
79211fb084Sdan    } {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - }
8032e1f279Sdrh  }
81*3af1b60eSdrh}
82e18d4953Sdan
83e18d4953Sdan
84e18d4953Sdan# Test a failure in open() due to the path being a directory.
85e18d4953Sdan#
86e18d4953Sdando_test 1.2.1 {
87e18d4953Sdan  file mkdir dir.db
88e18d4953Sdan  set ::log [list]
89e18d4953Sdan  list [catch { sqlite3 dbh dir.db } msg] $msg
90e18d4953Sdan} {1 {unable to open database file}}
91e18d4953Sdan
9266d655b4Sdrhdo_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) open\(.*dir.db\) - }
93e18d4953Sdan
94e18d4953Sdan# Test a failure in open() due to the path not existing.
95e18d4953Sdan#
96e18d4953Sdando_test 1.3.1 {
97e18d4953Sdan  set ::log [list]
98e18d4953Sdan  list [catch { sqlite3 dbh /x/y/z/test.db } msg] $msg
99e18d4953Sdan} {1 {unable to open database file}}
100e18d4953Sdan
10166d655b4Sdrhdo_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c:\d+: \(\d+\) open\(.*test.db\) - }
102e18d4953Sdan
103e18d4953Sdan# Test a failure in open() due to the path not existing.
104e18d4953Sdan#
105e18d4953Sdando_test 1.4.1 {
106e18d4953Sdan  set ::log [list]
107e18d4953Sdan  list [catch { sqlite3 dbh /root/test.db } msg] $msg
108e18d4953Sdan} {1 {unable to open database file}}
109e18d4953Sdan
110245fdc60Sdando_re_test 1.4.2 {
111245fdc60Sdan  lindex $::log 0
112af1b36b1Sdan} {^os_unix.c:\d*: \(\d+\) (open|readlink|lstat)\(.*test.db\) - }
113e18d4953Sdan
114e18d4953Sdan#--------------------------------------------------------------------------
115e18d4953Sdan# Tests oserror-1.* test failures in the unlink() system call.
116e18d4953Sdan#
1175209132aSdanifcapable wal {
118e18d4953Sdan  do_test 2.1.1 {
119e18d4953Sdan    set ::log [list]
120e18d4953Sdan    file mkdir test.db-wal
121e18d4953Sdan    forcedelete test.db
12226ec621aSdan    list [catch {
123e18d4953Sdan      sqlite3 dbh test.db
12426ec621aSdan      execsql { SELECT * FROM sqlite_master } dbh
12526ec621aSdan    } msg] $msg
126e18d4953Sdan  } {1 {disk I/O error}}
127e18d4953Sdan
12826ec621aSdan  do_re_test 2.1.2 {
12926ec621aSdan    lindex $::log 0
13026ec621aSdan  } {^os_unix.c:\d+: \(\d+\) unlink\(.*test.db-wal\) - }
131e18d4953Sdan  do_test 2.1.3 {
13226ec621aSdan    catch { dbh close }
133e18d4953Sdan    forcedelete test.db-wal
134e18d4953Sdan  } {}
1355209132aSdan}
136e18d4953Sdan
137e18d4953Sdan
13851438a79Sdantest_syscall reset
139e18d4953Sdansqlite3_shutdown
140e18d4953Sdantest_sqlite3_log
141e18d4953Sdansqlite3_initialize
142e18d4953Sdanfinish_test
143