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