xref: /sqlite-3.40.0/test/thread002.test (revision cd7274ce)
1# 2007 September 10
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#
12#   This test attempts to deadlock SQLite in shared-cache mode.
13#
14#
15# $Id: thread002.test,v 1.2 2007/10/09 08:29:33 danielk1977 Exp $
16
17set testdir [file dirname $argv0]
18
19source $testdir/tester.tcl
20source $testdir/thread_common.tcl
21if {[info commands sqlthread] eq ""} {
22  finish_test
23  return
24}
25ifcapable !attach {
26  finish_test
27  return
28}
29
30db close
31sqlite3_enable_shared_cache 1
32
33set ::NTHREAD 10
34
35do_test thread002.1 {
36  # Create 3 databases with identical schemas:
37  for {set ii 0} {$ii < 3} {incr ii} {
38    file delete -force test${ii}.db
39    sqlite3 db test${ii}.db
40    execsql {
41      CREATE TABLE t1(k, v);
42      CREATE INDEX t1_i ON t1(v);
43      INSERT INTO t1(v) VALUES(1.0);
44    }
45    db close
46  }
47} {}
48
49set thread_program {
50  set ::DB [sqlite3_open test.db]
51  for {set ii 1} {$ii <= 3} {incr ii} {
52    set T [lindex $order [expr $ii-1]]
53    execsql "ATTACH 'test${T}.db' AS aux${ii}"
54  }
55
56  for {set ii 0} {$ii < 100} {incr ii} {
57    execsql { SELECT * FROM aux1.t1 }
58    execsql { INSERT INTO aux1.t1(v) SELECT sum(v) FROM aux2.t1 }
59
60    execsql { SELECT * FROM aux2.t1 }
61    execsql { INSERT INTO aux2.t1(v) SELECT sum(v) FROM aux3.t1 }
62
63    execsql { SELECT * FROM aux3.t1 }
64    execsql { INSERT INTO aux3.t1(v) SELECT sum(v) FROM aux1.t1 }
65
66    execsql { CREATE TABLE aux1.t2(a,b) }
67    execsql { DROP TABLE aux1.t2 }
68
69    # if {($ii%10)==0} {puts -nonewline . ; flush stdout}
70    puts -nonewline . ; flush stdout
71  }
72
73  sqlite3_close $::DB
74  list OK
75}
76
77set order_list [list {0 1 2} {0 2 1} {1 0 2} {1 2 0} {2 0 1} {2 1 0}]
78
79array unset finished
80for {set ii 0} {$ii < $::NTHREAD} {incr ii} {
81  set order [lindex $order_list [expr $ii%6]]
82  thread_spawn finished($ii) $thread_procs "set order {$order}" $thread_program
83}
84
85# Wait for all threads to finish,  then check they all returned "OK".
86#
87for {set i 0} {$i < $::NTHREAD} {incr i} {
88  if {![info exists finished($i)]} {
89    vwait finished($i)
90  }
91  do_test thread001.2.$i {
92    set ::finished($i)
93  } OK
94}
95
96# Check all three databases are Ok.
97for {set ii 0} {$ii < 3} {incr ii} {
98  do_test thread002.3.$ii {
99    sqlite3 db test${ii}.db
100    set res [list                         \
101      [execsql {SELECT count(*) FROM t1}] \
102      [execsql {PRAGMA integrity_check}]  \
103    ]
104    db close
105    set res
106  } [list [expr 1 + $::NTHREAD*100] ok]
107}
108
109finish_test
110
111