xref: /sqlite-3.40.0/test/win32lock.test (revision c59b7b1f)
1# 2011 July 11
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# This file implements regression tests for SQLite library.  The
12# focus of this script is recovery from transient manditory locks
13# that sometimes appear on database files due to anti-virus software.
14#
15
16if {$tcl_platform(platform)!="windows"} return
17
18set testdir [file dirname $argv0]
19source $testdir/tester.tcl
20
21set testprefix win32lock
22
23db close
24sqlite3_shutdown
25test_sqlite3_log xLog
26proc xLog {error_code msg} {
27  lappend ::log $msg
28}
29sqlite3 db test.db
30db eval {PRAGMA mmap_size=0}
31
32do_test win32lock-1.1 {
33  db eval {
34    PRAGMA cache_size=10;
35    CREATE TABLE t1(x,y);
36    INSERT INTO t1 VALUES(1,randomblob(100000));
37    INSERT INTO t1 VALUES(2,randomblob(50000));
38    INSERT INTO t1 VALUES(3,randomblob(25000));
39    INSERT INTO t1 VALUES(4,randomblob(12500));
40    SELECT x, length(y) FROM t1 ORDER BY rowid;
41  }
42} {1 100000 2 50000 3 25000 4 12500}
43
44unset -nocomplain delay1 rc msg
45set old_pending_byte [sqlite3_test_control_pending_byte 0x40000000]
46
47set win32_lock_ok [list]
48set win32_lock_error [list]
49set delay1 25
50while {1} {
51  lock_win32_file test.db 0 $::delay1
52  set ::log {}
53  set rc [catch {db eval {SELECT x, length(y) FROM t1 ORDER BY rowid}} msg]
54  if {$rc} {
55    lappend win32_lock_error $::delay1
56    do_test win32lock-1.2-$delay1-error {
57       set ::msg
58    } {disk I/O error}
59  } else {
60    lappend win32_lock_ok $::delay1
61    do_test win32lock-1.2-$delay1-ok {
62       set ::msg
63    } {1 100000 2 50000 3 25000 4 12500}
64    if {[info exists ::log] && $::log!=""} {
65      do_test win32lock-1.2-$delay1-log1 {
66        regsub {\d+} $::log # x
67        regsub { at line \d+} $x "" x
68        set x
69      } {{delayed #ms for lock/sharing conflict}}
70    }
71  }
72  if {[llength $win32_lock_ok] && [llength $win32_lock_error]} break
73  incr delay1 25
74  if {$delay1 > 12500} {
75    puts "Timed out waiting for \"ok\" and \"error\" results."
76    break
77  }
78  sqlite3_sleep 10
79}
80
81do_test win32lock-2.0 {
82  file_control_win32_av_retry db -1 -1
83} {0 10 25}
84do_test win32lock-2.1 {
85  file_control_win32_av_retry db 1 1
86} {0 1 1}
87
88#
89# NOTE: It is known that the win32lock-2.2-* tests may fail if the system is
90#       experiencing heavy load (i.e. they are very timing sensitive).  This is
91#       primarily due to the AV retry delay being set to 1 millisecond in the
92#       win32lock-2.1 test (above).  While it is important to test this corner
93#       case for the AV retry logic, a failure of this test should probably not
94#       be interpreted as a bug in SQLite or these test cases.
95#
96set win32_lock_ok [list]
97set win32_lock_error [list]
98set delay1 1
99while {1} {
100  lock_win32_file test.db 0 $::delay1
101  set ::log {}
102  set rc [catch {db eval {SELECT x, length(y) FROM t1 ORDER BY rowid}} msg]
103  if {$rc} {
104    lappend win32_lock_error $::delay1
105    do_test win32lock-2.2-$delay1-error {
106       set ::msg
107    } {disk I/O error}
108  } else {
109    lappend win32_lock_ok $::delay1
110    do_test win32lock-2.2-$delay1-ok {
111       set ::msg
112    } {1 100000 2 50000 3 25000 4 12500}
113    if {[info exists ::log] && $::log!=""} {
114      do_test win32lock-2.2-$delay1-log1 {
115        regsub {\d+} $::log # x
116        regsub { at line \d+} $x "" x
117        set x
118      } {{delayed #ms for lock/sharing conflict}}
119    }
120  }
121  if {[llength $win32_lock_ok] && [llength $win32_lock_error]} break
122  incr delay1 1
123  if {$delay1 > 500} {
124    puts "Timed out waiting for \"ok\" and \"error\" results."
125    break
126  }
127  sqlite3_sleep 10
128}
129
130file_control_win32_av_retry db 10 25
131sqlite3_test_control_pending_byte $old_pending_byte
132db close
133forcedelete test.db
134
135sqlite3 db test.db
136sqlite3 db2 test.db
137
138do_test win32lock-3.0 {
139  db eval {
140    CREATE TABLE t1(x);
141    INSERT INTO t1 VALUES(1);
142    INSERT INTO t1 VALUES(2);
143    INSERT INTO t1 VALUES(3);
144  }
145} {}
146
147do_test win32lock-3.1 {
148  db eval {
149    BEGIN EXCLUSIVE;
150    INSERT INTO t1 VALUES(4);
151  }
152} {}
153
154do_test win32lock-3.2 {
155  catchsql {
156    BEGIN EXCLUSIVE;
157    INSERT INTO t1 VALUES(5);
158    COMMIT;
159  } db2
160} {1 {database is locked}}
161
162do_test win32lock-3.3 {
163  db eval {
164    COMMIT;
165  }
166} {}
167
168do_test win32lock-3.4 {
169  set handle [lindex [file_control_win32_set_handle db 0] end]
170  list [catchsql {
171    BEGIN EXCLUSIVE;
172    INSERT INTO t1 VALUES(6);
173    COMMIT;
174  }] [file_control_win32_set_handle db $handle] [sqlite3_extended_errcode db]
175} {{1 {disk I/O error}} {0 0} SQLITE_IOERR_LOCK}
176
177db2 close
178db close
179sqlite3_shutdown
180test_sqlite3_log
181sqlite3_initialize
182finish_test
183