# 2017 April 25 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the server mode of SQLite. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix serverlimit source $testdir/server_common.tcl source $testdir/lock_common.tcl return_if_no_server #------------------------------------------------------------------------- # Test plan: # # 1.* The concurrent connections limit in multi-process mode. With all # connections in the local process. # # 2.* The concurrent connections limit in multi-process mode. Using # multiple processes. # # 3.* The concurrent transactions limit in single-process mode. # server_set_vfs multi server_reset_db set MLIMIT 16 ;# maximum number of allowed connections do_test 1.0 { server_sqlite3 db test.db db eval { CREATE TABLE t1(x); INSERT INTO t1 VALUES('hello'), ('world'); } db close for {set i 0} {$i < $MLIMIT} {incr i} { server_sqlite3 db.$i test.db db.$i eval { SELECT * FROM t1 } } set {} {} } {} # Connection [db] cannot connect - all client slots are occupied. # do_test 1.1 { server_sqlite3 db test.db list [catch { db eval { SELECT * FROM t1 } } msg] $msg } {1 {database is locked}} # But, if one connection disconnects, [db] can then connect and # query the db. # do_test 1.2 { db.0 close list [catch { db eval { SELECT * FROM t1 } } msg] $msg } {0 {hello world}} do_test 1.3 { for {set i 0} {$i < $MLIMIT} {incr i} { catch { db.$i close } } set {} {} } {} #------------------------------------------------------------------------- # Connections in different processes. do_multiclient_test tn { code1 { db close } code2 { db2 close } code3 { db3 close } set N1 [expr $MLIMIT / 2] set N2 [expr $MLIMIT - $N1] do_test 2.$tn.0 { file mkdir test.db-journal code1 { sqlite3 db test.db db eval { CREATE TABLE t11(a, b); INSERT INTO t11 VALUES(1, 2), (3, 4); } db close for {set i 0} {$i < $N1} {incr i} { sqlite3 db.$i test.db db.$i eval { SELECT * FROM t11 } } } code2 [string map [list %N2% $N2] { for {set i 0} {$i < %N2%} {incr i} { sqlite3 db2.$i test.db db2.$i eval { SELECT * FROM t11 } } }] code2 { db2.0 eval {SELECT * FROM t11} } } {1 2 3 4} do_test 2.$tn.1 { code3 { sqlite3 db3 test.db } csql3 { SELECT * FROM t11 } } {1 {database is locked}} do_test 2.$tn.2 { code2 { db2.0 close } csql3 { SELECT * FROM t11 } } {0 {1 2 3 4}} do_test 2.$tn.3 { code1 { sqlite3 db test.db } csql1 { SELECT * FROM t11 } } {1 {database is locked}} do_test 2.$tn.4 { code2 { db2.1 close } csql1 { SELECT * FROM t11 } } {0 {1 2 3 4}} do_test 2.$tn.X { code1 { for {set i 0} {$i < 50} {incr i} { catch {db.$i close} } } code2 { for {set i 0} {$i < 50} {incr i} { catch {db2.$i close} } } } {} } server_set_vfs single server_reset_db set TLIMIT 16 do_test 3.0 { execsql "CREATE TABLE t1 (o PRIMARY KEY) WITHOUT ROWID" for {set i 0} {$i < $TLIMIT} {incr i} { execsql "CREATE TABLE x$i (o PRIMARY KEY) WITHOUT ROWID" } set "" "" } {} do_test 3.1 { for {set i 0} {$i < $TLIMIT} {incr i} { sqlite3 db.$i test.db db.$i eval " BEGIN; INSERT INTO x$i VALUES ('one'); " } } {} do_catchsql_test 3.2 { INSERT INTO t1 VALUES('two'); } {1 {database is locked}} do_test 3.3 { db.0 eval COMMIT execsql { INSERT INTO t1 VALUES('two'); } } {} do_catchsql_test 3.4 { SELECT * FROM x1 } {1 {database is locked}} do_catchsql_test 3.5 { SELECT * FROM x0 } {0 one} do_test 3.6 { for {set i 1} {$i < $TLIMIT} {incr i} { db.$i eval COMMIT } } {} finish_test