xref: /sqlite-3.40.0/test/thread1.test (revision fe98f9b2)
1a6064dcfSdrh# 2003 December 18
2a6064dcfSdrh#
3a6064dcfSdrh# The author disclaims copyright to this source code.  In place of
4a6064dcfSdrh# a legal notice, here is a blessing:
5a6064dcfSdrh#
6a6064dcfSdrh#    May you do good and not evil.
7a6064dcfSdrh#    May you find forgiveness for yourself and forgive others.
8a6064dcfSdrh#    May you share freely, never taking more than you give.
9a6064dcfSdrh#
10a6064dcfSdrh#***********************************************************************
11a6064dcfSdrh# This file implements regression tests for SQLite library.  The
12a6064dcfSdrh# focus of this script is multithreading behavior
13a6064dcfSdrh#
1418472fa7Sdrh# $Id: thread1.test,v 1.8 2008/10/07 15:25:49 drh Exp $
15a6064dcfSdrh
16a6064dcfSdrh
17a6064dcfSdrhset testdir [file dirname $argv0]
18a6064dcfSdrhsource $testdir/tester.tcl
19a6064dcfSdrh
20a6064dcfSdrh# Skip this whole file if the thread testing code is not enabled
21a6064dcfSdrh#
22*fe98f9b2Sdanif {[run_thread_tests]==0} { finish_test ; return }
23ef4ac8f9Sdrhif {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
24a6064dcfSdrh  finish_test
25a6064dcfSdrh  return
26a6064dcfSdrh}
27a6064dcfSdrh
28a6064dcfSdrh# Create some data to work with
29a6064dcfSdrh#
30a6064dcfSdrhdo_test thread1-1.1 {
31a6064dcfSdrh  execsql {
32a6064dcfSdrh    CREATE TABLE t1(a,b);
33a6064dcfSdrh    INSERT INTO t1 VALUES(1,'abcdefgh');
34a6064dcfSdrh    INSERT INTO t1 SELECT a+1, b||b FROM t1;
35a6064dcfSdrh    INSERT INTO t1 SELECT a+2, b||b FROM t1;
36a6064dcfSdrh    INSERT INTO t1 SELECT a+4, b||b FROM t1;
37a6064dcfSdrh    SELECT count(*), max(length(b)) FROM t1;
38a6064dcfSdrh  }
39a6064dcfSdrh} {8 64}
40a6064dcfSdrh
41a6064dcfSdrh# Interleave two threads on read access.  Then make sure a third
42acf01e7dSdrh# thread can write the database.  In other words:
43acf01e7dSdrh#
44acf01e7dSdrh#    read-lock A
45acf01e7dSdrh#    read-lock B
46acf01e7dSdrh#    unlock A
47acf01e7dSdrh#    unlock B
48acf01e7dSdrh#    write-lock C
49acf01e7dSdrh#
50acf01e7dSdrh# At one point, the write-lock of C would fail on Linux.
51a6064dcfSdrh#
52a6064dcfSdrhdo_test thread1-1.2 {
53a6064dcfSdrh  thread_create A test.db
54a6064dcfSdrh  thread_create B test.db
55a6064dcfSdrh  thread_create C test.db
56a6064dcfSdrh  thread_compile A {SELECT a FROM t1}
57a6064dcfSdrh  thread_step A
58a6064dcfSdrh  thread_result A
59a6064dcfSdrh} SQLITE_ROW
60a6064dcfSdrhdo_test thread1-1.3 {
61a6064dcfSdrh  thread_argc A
62a6064dcfSdrh} 1
63a6064dcfSdrhdo_test thread1-1.4 {
64a6064dcfSdrh  thread_argv A 0
65a6064dcfSdrh} 1
66a6064dcfSdrhdo_test thread1-1.5 {
67a6064dcfSdrh  thread_compile B {SELECT b FROM t1}
68a6064dcfSdrh  thread_step B
69a6064dcfSdrh  thread_result B
70a6064dcfSdrh} SQLITE_ROW
71a6064dcfSdrhdo_test thread1-1.6 {
72a6064dcfSdrh  thread_argc B
73a6064dcfSdrh} 1
74a6064dcfSdrhdo_test thread1-1.7 {
75a6064dcfSdrh  thread_argv B 0
76a6064dcfSdrh} abcdefgh
77a6064dcfSdrhdo_test thread1-1.8 {
78a6064dcfSdrh  thread_finalize A
79a6064dcfSdrh  thread_result A
80a6064dcfSdrh} SQLITE_OK
81a6064dcfSdrhdo_test thread1-1.9 {
82a6064dcfSdrh  thread_finalize B
83a6064dcfSdrh  thread_result B
84a6064dcfSdrh} SQLITE_OK
85a6064dcfSdrhdo_test thread1-1.10 {
86a6064dcfSdrh  thread_compile C {CREATE TABLE t2(x,y)}
87a6064dcfSdrh  thread_step C
88a6064dcfSdrh  thread_result C
89a6064dcfSdrh} SQLITE_DONE
90a6064dcfSdrhdo_test thread1-1.11 {
91a6064dcfSdrh  thread_finalize C
92a6064dcfSdrh  thread_result C
93a6064dcfSdrh} SQLITE_OK
94acf01e7dSdrhdo_test thread1-1.12 {
95acf01e7dSdrh  catchsql {SELECT name FROM sqlite_master}
96acf01e7dSdrh  execsql {SELECT name FROM sqlite_master}
97acf01e7dSdrh} {t1 t2}
98a6064dcfSdrh
99a6064dcfSdrh
100acf01e7dSdrh#
101f9d19a6bSdanielk1977# The following tests - thread1-2.* - test the following scenario:
102acf01e7dSdrh#
103f9d19a6bSdanielk1977# 1:  Read-lock thread A
104f9d19a6bSdanielk1977# 2:  Read-lock thread B
105f9d19a6bSdanielk1977# 3:  Attempt to write in thread C -> SQLITE_BUSY
106f9d19a6bSdanielk1977# 4:  Check db write failed from main thread.
107f9d19a6bSdanielk1977# 5:  Unlock from thread A.
108f9d19a6bSdanielk1977# 6:  Attempt to write in thread C -> SQLITE_BUSY
109f9d19a6bSdanielk1977# 7:  Check db write failed from main thread.
110f9d19a6bSdanielk1977# 8:  Unlock from thread B.
111f9d19a6bSdanielk1977# 9:  Attempt to write in thread C -> SQLITE_DONE
112f9d19a6bSdanielk1977# 10: Finalize the write from thread C
113f9d19a6bSdanielk1977# 11: Check db write succeeded from main thread.
114acf01e7dSdrh#
115acf01e7dSdrhdo_test thread1-2.1 {
116acf01e7dSdrh  thread_halt *
117acf01e7dSdrh  thread_create A test.db
118acf01e7dSdrh  thread_compile A {SELECT a FROM t1}
119acf01e7dSdrh  thread_step A
120acf01e7dSdrh  thread_result A
121acf01e7dSdrh} SQLITE_ROW
122acf01e7dSdrhdo_test thread1-2.2 {
123acf01e7dSdrh  thread_create B test.db
124acf01e7dSdrh  thread_compile B {SELECT b FROM t1}
125acf01e7dSdrh  thread_step B
126acf01e7dSdrh  thread_result B
127acf01e7dSdrh} SQLITE_ROW
128acf01e7dSdrhdo_test thread1-2.3 {
129acf01e7dSdrh  thread_create C test.db
130acf01e7dSdrh  thread_compile C {INSERT INTO t2 VALUES(98,99)}
131acf01e7dSdrh  thread_step C
132acf01e7dSdrh  thread_result C
1330de0bb33Sdanielk1977  thread_finalize C
1340de0bb33Sdanielk1977  thread_result C
135acf01e7dSdrh} SQLITE_BUSY
1360de0bb33Sdanielk1977
137acf01e7dSdrhdo_test thread1-2.4 {
138acf01e7dSdrh  execsql {SELECT * FROM t2}
139acf01e7dSdrh} {}
1400de0bb33Sdanielk1977
141acf01e7dSdrhdo_test thread1-2.5 {
142acf01e7dSdrh  thread_finalize A
143acf01e7dSdrh  thread_result A
144acf01e7dSdrh} SQLITE_OK
145acf01e7dSdrhdo_test thread1-2.6 {
1460de0bb33Sdanielk1977  thread_compile C {INSERT INTO t2 VALUES(98,99)}
147acf01e7dSdrh  thread_step C
148acf01e7dSdrh  thread_result C
1490de0bb33Sdanielk1977  thread_finalize C
1500de0bb33Sdanielk1977  thread_result C
151acf01e7dSdrh} SQLITE_BUSY
152acf01e7dSdrhdo_test thread1-2.7 {
153acf01e7dSdrh  execsql {SELECT * FROM t2}
154acf01e7dSdrh} {}
155acf01e7dSdrhdo_test thread1-2.8 {
156acf01e7dSdrh  thread_finalize B
157acf01e7dSdrh  thread_result B
158acf01e7dSdrh} SQLITE_OK
159acf01e7dSdrhdo_test thread1-2.9 {
1600de0bb33Sdanielk1977  thread_compile C {INSERT INTO t2 VALUES(98,99)}
161acf01e7dSdrh  thread_step C
162acf01e7dSdrh  thread_result C
163acf01e7dSdrh} SQLITE_DONE
164acf01e7dSdrhdo_test thread1-2.10 {
165acf01e7dSdrh  thread_finalize C
166acf01e7dSdrh  thread_result C
167acf01e7dSdrh} SQLITE_OK
168ecb2a964Sdanielk1977do_test thread1-2.11 {
169ecb2a964Sdanielk1977  execsql {SELECT * FROM t2}
170ecb2a964Sdanielk1977} {98 99}
171acf01e7dSdrh
172a6064dcfSdrhthread_halt *
173a6064dcfSdrhfinish_test
174