xref: /sqlite-3.40.0/test/win32lock.test (revision ff9fcd5a)
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        set x
68      } {{delayed #ms for lock/sharing conflict}}
69    }
70  }
71  if {[llength $win32_lock_ok] && [llength $win32_lock_error]} break
72  incr delay1 25
73  if {$delay1 > 12500} {
74    puts "Timed out waiting for \"ok\" and \"error\" results."
75    break
76  }
77  sqlite3_sleep 10
78}
79
80do_test win32lock-2.0 {
81  file_control_win32_av_retry db -1 -1
82} {0 10 25}
83do_test win32lock-2.1 {
84  file_control_win32_av_retry db 1 1
85} {0 1 1}
86
87#
88# NOTE: It is known that the win32lock-2.2-* tests may fail if the system is
89#       experiencing heavy load (i.e. they are very timing sensitive).  This is
90#       primarily due to the AV retry delay being set to 1 millisecond in the
91#       win32lock-2.1 test (above).  While it is important to test this corner
92#       case for the AV retry logic, a failure of this test should probably not
93#       be interpreted as a bug in SQLite or these test cases.
94#
95set win32_lock_ok [list]
96set win32_lock_error [list]
97set delay1 1
98while {1} {
99  lock_win32_file test.db 0 $::delay1
100  set ::log {}
101  set rc [catch {db eval {SELECT x, length(y) FROM t1 ORDER BY rowid}} msg]
102  if {$rc} {
103    lappend win32_lock_error $::delay1
104    do_test win32lock-2.2-$delay1-error {
105       set ::msg
106    } {disk I/O error}
107  } else {
108    lappend win32_lock_ok $::delay1
109    do_test win32lock-2.2-$delay1-ok {
110       set ::msg
111    } {1 100000 2 50000 3 25000 4 12500}
112    if {[info exists ::log] && $::log!=""} {
113      do_test win32lock-2.2-$delay1-log1 {
114        regsub {\d+} $::log # x
115        set x
116      } {{delayed #ms for lock/sharing conflict}}
117    }
118  }
119  if {[llength $win32_lock_ok] && [llength $win32_lock_error]} break
120  incr delay1 1
121  if {$delay1 > 500} {
122    puts "Timed out waiting for \"ok\" and \"error\" results."
123    break
124  }
125  sqlite3_sleep 10
126}
127
128file_control_win32_av_retry db 10 25
129sqlite3_test_control_pending_byte $old_pending_byte
130db close
131forcedelete test.db
132
133sqlite3 db test.db
134sqlite3 db2 test.db
135
136do_test win32lock-3.0 {
137  db eval {
138    CREATE TABLE t1(x);
139    INSERT INTO t1 VALUES(1);
140    INSERT INTO t1 VALUES(2);
141    INSERT INTO t1 VALUES(3);
142  }
143} {}
144
145do_test win32lock-3.1 {
146  db eval {
147    BEGIN EXCLUSIVE;
148    INSERT INTO t1 VALUES(4);
149  }
150} {}
151
152do_test win32lock-3.2 {
153  catchsql {
154    BEGIN EXCLUSIVE;
155    INSERT INTO t1 VALUES(5);
156    COMMIT;
157  } db2
158} {1 {database is locked}}
159
160do_test win32lock-3.3 {
161  db eval {
162    COMMIT;
163  }
164} {}
165
166do_test win32lock-3.4 {
167  set handle [lindex [file_control_win32_set_handle db 0] end]
168  list [catchsql {
169    BEGIN EXCLUSIVE;
170    INSERT INTO t1 VALUES(6);
171    COMMIT;
172  }] [file_control_win32_set_handle db $handle] [sqlite3_extended_errcode db]
173} {{1 {disk I/O error}} {0 0} SQLITE_IOERR_LOCK}
174
175db2 close
176db close
177sqlite3_shutdown
178test_sqlite3_log
179sqlite3_initialize
180finish_test
181