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