| # 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 |
| |