| OLD | NEW | 
 | (Empty) | 
|    1 # 2006 January 14 |  | 
|    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 # This file implements regression tests for SQLite library.  The |  | 
|   12 # focus of this script is multithreading behavior |  | 
|   13 # |  | 
|   14 # $Id: thread2.test,v 1.3 2008/10/07 15:25:49 drh Exp $ |  | 
|   15  |  | 
|   16  |  | 
|   17 set testdir [file dirname $argv0] |  | 
|   18 source $testdir/tester.tcl |  | 
|   19  |  | 
|   20 ifcapable !mutex { |  | 
|   21   finish_test |  | 
|   22   return |  | 
|   23 } |  | 
|   24  |  | 
|   25  |  | 
|   26 # Skip this whole file if the thread testing code is not enabled |  | 
|   27 # |  | 
|   28 if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} { |  | 
|   29   finish_test |  | 
|   30   return |  | 
|   31 } |  | 
|   32 if {![info exists threadsOverrideEachOthersLocks]} { |  | 
|   33   finish_test |  | 
|   34   return |  | 
|   35 } |  | 
|   36  |  | 
|   37 # Create some data to work with |  | 
|   38 # |  | 
|   39 do_test thread1-1.1 { |  | 
|   40   execsql { |  | 
|   41     CREATE TABLE t1(a,b); |  | 
|   42     INSERT INTO t1 VALUES(1,'abcdefgh'); |  | 
|   43     INSERT INTO t1 SELECT a+1, b||b FROM t1; |  | 
|   44     INSERT INTO t1 SELECT a+2, b||b FROM t1; |  | 
|   45     INSERT INTO t1 SELECT a+4, b||b FROM t1; |  | 
|   46     SELECT count(*), max(length(b)) FROM t1; |  | 
|   47   } |  | 
|   48 } {8 64} |  | 
|   49  |  | 
|   50 # Use the thread_swap command to move the database connections between |  | 
|   51 # threads, then verify that they still work. |  | 
|   52 # |  | 
|   53 do_test thread2-1.2 { |  | 
|   54   db close |  | 
|   55   thread_create A test.db |  | 
|   56   thread_create B test.db |  | 
|   57   thread_swap A B |  | 
|   58   thread_compile A {SELECT a FROM t1 LIMIT 1} |  | 
|   59   thread_result A |  | 
|   60 } {SQLITE_OK} |  | 
|   61 do_test thread2-1.3 { |  | 
|   62   thread_step A |  | 
|   63   thread_result A |  | 
|   64 } {SQLITE_ROW} |  | 
|   65 do_test thread2-1.4 { |  | 
|   66   thread_argv A 0 |  | 
|   67 } {1} |  | 
|   68 do_test thread2-1.5 { |  | 
|   69   thread_finalize A |  | 
|   70   thread_result A |  | 
|   71 } {SQLITE_OK} |  | 
|   72 do_test thread2-1.6 { |  | 
|   73   thread_compile B {SELECT a FROM t1 LIMIT 1} |  | 
|   74   thread_result B |  | 
|   75 } {SQLITE_OK} |  | 
|   76 do_test thread2-1.7 { |  | 
|   77   thread_step B |  | 
|   78   thread_result B |  | 
|   79 } {SQLITE_ROW} |  | 
|   80 do_test thread2-1.8 { |  | 
|   81   thread_argv B 0 |  | 
|   82 } {1} |  | 
|   83 do_test thread2-1.9 { |  | 
|   84   thread_finalize B |  | 
|   85   thread_result B |  | 
|   86 } {SQLITE_OK} |  | 
|   87  |  | 
|   88 # Swap them again. |  | 
|   89 # |  | 
|   90 do_test thread2-2.2 { |  | 
|   91   thread_swap A B |  | 
|   92   thread_compile A {SELECT a FROM t1 LIMIT 1} |  | 
|   93   thread_result A |  | 
|   94 } {SQLITE_OK} |  | 
|   95 do_test thread2-2.3 { |  | 
|   96   thread_step A |  | 
|   97   thread_result A |  | 
|   98 } {SQLITE_ROW} |  | 
|   99 do_test thread2-2.4 { |  | 
|  100   thread_argv A 0 |  | 
|  101 } {1} |  | 
|  102 do_test thread2-2.5 { |  | 
|  103   thread_finalize A |  | 
|  104   thread_result A |  | 
|  105 } {SQLITE_OK} |  | 
|  106 do_test thread2-2.6 { |  | 
|  107   thread_compile B {SELECT a FROM t1 LIMIT 1} |  | 
|  108   thread_result B |  | 
|  109 } {SQLITE_OK} |  | 
|  110 do_test thread2-2.7 { |  | 
|  111   thread_step B |  | 
|  112   thread_result B |  | 
|  113 } {SQLITE_ROW} |  | 
|  114 do_test thread2-2.8 { |  | 
|  115   thread_argv B 0 |  | 
|  116 } {1} |  | 
|  117 do_test thread2-2.9 { |  | 
|  118   thread_finalize B |  | 
|  119   thread_result B |  | 
|  120 } {SQLITE_OK} |  | 
|  121 thread_halt A |  | 
|  122 thread_halt B |  | 
|  123  |  | 
|  124 # Save the original (correct) value of threadsOverrideEachOthersLocks |  | 
|  125 # so that it can be restored.  If this value is left set incorrectly, lots |  | 
|  126 # of things will go wrong in future tests. |  | 
|  127 # |  | 
|  128 set orig_threadOverride $threadsOverrideEachOthersLocks |  | 
|  129  |  | 
|  130 # Pretend we are on a system (like RedHat9) were threads do not |  | 
|  131 # override each others locks. |  | 
|  132 # |  | 
|  133 set threadsOverrideEachOthersLocks 0 |  | 
|  134  |  | 
|  135 # Verify that we can move database connections between threads as |  | 
|  136 # long as no locks are held. |  | 
|  137 # |  | 
|  138 do_test thread2-3.1 { |  | 
|  139   thread_create A test.db |  | 
|  140   set DB [thread_db_get A] |  | 
|  141   thread_halt A |  | 
|  142 } {} |  | 
|  143 do_test thread2-3.2 { |  | 
|  144   set STMT [sqlite3_prepare $DB {SELECT a FROM t1 LIMIT 1} -1 TAIL] |  | 
|  145   sqlite3_step $STMT |  | 
|  146 } SQLITE_ROW |  | 
|  147 do_test thread2-3.3 { |  | 
|  148   sqlite3_column_int $STMT 0 |  | 
|  149 } 1 |  | 
|  150 do_test thread2-3.4 { |  | 
|  151   sqlite3_finalize $STMT |  | 
|  152 } SQLITE_OK |  | 
|  153 do_test thread2-3.5 { |  | 
|  154   set STMT [sqlite3_prepare $DB {SELECT max(a) FROM t1} -1 TAIL] |  | 
|  155   sqlite3_step $STMT |  | 
|  156 } SQLITE_ROW |  | 
|  157 do_test thread2-3.6 { |  | 
|  158   sqlite3_column_int $STMT 0 |  | 
|  159 } 8 |  | 
|  160 do_test thread2-3.7 { |  | 
|  161   sqlite3_finalize $STMT |  | 
|  162 } SQLITE_OK |  | 
|  163 do_test thread2-3.8 { |  | 
|  164   sqlite3_close $DB |  | 
|  165 } {SQLITE_OK} |  | 
|  166  |  | 
|  167 do_test thread2-3.10 { |  | 
|  168   thread_create A test.db |  | 
|  169   thread_compile A {SELECT a FROM t1 LIMIT 1} |  | 
|  170   thread_step A |  | 
|  171   thread_finalize A |  | 
|  172   set DB [thread_db_get A] |  | 
|  173   thread_halt A |  | 
|  174 } {} |  | 
|  175 do_test thread2-3.11 { |  | 
|  176   set STMT [sqlite3_prepare $DB {SELECT a FROM t1 LIMIT 1} -1 TAIL] |  | 
|  177   sqlite3_step $STMT |  | 
|  178 } SQLITE_ROW |  | 
|  179 do_test thread2-3.12 { |  | 
|  180   sqlite3_column_int $STMT 0 |  | 
|  181 } 1 |  | 
|  182 do_test thread2-3.13 { |  | 
|  183   sqlite3_finalize $STMT |  | 
|  184 } SQLITE_OK |  | 
|  185 do_test thread2-3.14 { |  | 
|  186   sqlite3_close $DB |  | 
|  187 } SQLITE_OK |  | 
|  188  |  | 
|  189 do_test thread2-3.20 { |  | 
|  190   thread_create A test.db |  | 
|  191   thread_compile A {SELECT a FROM t1 LIMIT 3} |  | 
|  192   thread_step A |  | 
|  193   set STMT [thread_stmt_get A] |  | 
|  194   set DB [thread_db_get A] |  | 
|  195   sqlite3_step $STMT |  | 
|  196 } SQLITE_ROW |  | 
|  197 do_test thread2-3.22 { |  | 
|  198   sqlite3_column_int $STMT 0 |  | 
|  199 } 2 |  | 
|  200 do_test thread2-3.23 { |  | 
|  201   # The unlock fails here.  But because we never check the return |  | 
|  202   # code from sqlite3OsUnlock (because we cannot do anything about it |  | 
|  203   # if it fails) we do not realize that an error has occurred. |  | 
|  204   breakpoint |  | 
|  205   sqlite3_finalize $STMT |  | 
|  206 } SQLITE_OK |  | 
|  207 do_test thread2-3.25 { |  | 
|  208   thread_db_put A $DB |  | 
|  209   thread_halt A |  | 
|  210 } {} |  | 
|  211  |  | 
|  212 do_test thread2-3.30 { |  | 
|  213   thread_create A test.db |  | 
|  214   thread_compile A {BEGIN} |  | 
|  215   thread_step A |  | 
|  216   thread_finalize A |  | 
|  217   thread_compile A {SELECT a FROM t1 LIMIT 1} |  | 
|  218   thread_step A |  | 
|  219   thread_finalize A |  | 
|  220   set DB [thread_db_get A] |  | 
|  221   set STMT [sqlite3_prepare $DB {INSERT INTO t1 VALUES(99,'error')} -1 TAIL] |  | 
|  222   sqlite3_step $STMT |  | 
|  223 } SQLITE_ERROR |  | 
|  224 do_test thread2-3.32 { |  | 
|  225   sqlite3_finalize $STMT |  | 
|  226 } SQLITE_MISUSE |  | 
|  227 do_test thread2-3.33 { |  | 
|  228   thread_db_put A $DB |  | 
|  229   thread_halt A |  | 
|  230 } {} |  | 
|  231  |  | 
|  232 # VERY important to set the override flag back to its true value. |  | 
|  233 # |  | 
|  234 set threadsOverrideEachOthersLocks $orig_threadOverride |  | 
|  235  |  | 
|  236 # Also important to halt the worker threads, which are using spin |  | 
|  237 # locks and eating away CPU cycles. |  | 
|  238 # |  | 
|  239 thread_halt *    |  | 
|  240 finish_test |  | 
| OLD | NEW |