gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/thread1.test (about)

     1  # 2003 December 18
     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: thread1.test,v 1.8 2008/10/07 15:25:49 drh Exp $
    15  
    16  
    17  set testdir [file dirname $argv0]
    18  source $testdir/tester.tcl
    19  
    20  # Skip this whole file if the thread testing code is not enabled
    21  #
    22  if {[run_thread_tests]==0} { finish_test ; return }
    23  if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
    24    finish_test
    25    return
    26  }
    27  
    28  # Create some data to work with
    29  #
    30  do_test thread1-1.1 {
    31    execsql {
    32      CREATE TABLE t1(a,b);
    33      INSERT INTO t1 VALUES(1,'abcdefgh');
    34      INSERT INTO t1 SELECT a+1, b||b FROM t1;
    35      INSERT INTO t1 SELECT a+2, b||b FROM t1;
    36      INSERT INTO t1 SELECT a+4, b||b FROM t1;
    37      SELECT count(*), max(length(b)) FROM t1;
    38    }
    39  } {8 64}
    40  
    41  # Interleave two threads on read access.  Then make sure a third
    42  # thread can write the database.  In other words:
    43  #
    44  #    read-lock A
    45  #    read-lock B
    46  #    unlock A
    47  #    unlock B
    48  #    write-lock C
    49  #
    50  # At one point, the write-lock of C would fail on Linux. 
    51  #
    52  do_test thread1-1.2 {
    53    thread_create A test.db
    54    thread_create B test.db
    55    thread_create C test.db
    56    thread_compile A {SELECT a FROM t1}
    57    thread_step A
    58    thread_result A
    59  } SQLITE_ROW
    60  do_test thread1-1.3 {
    61    thread_argc A
    62  } 1
    63  do_test thread1-1.4 {
    64    thread_argv A 0
    65  } 1
    66  do_test thread1-1.5 {
    67    thread_compile B {SELECT b FROM t1}
    68    thread_step B
    69    thread_result B
    70  } SQLITE_ROW
    71  do_test thread1-1.6 {
    72    thread_argc B
    73  } 1
    74  do_test thread1-1.7 {
    75    thread_argv B 0
    76  } abcdefgh
    77  do_test thread1-1.8 {
    78    thread_finalize A
    79    thread_result A
    80  } SQLITE_OK
    81  do_test thread1-1.9 {
    82    thread_finalize B
    83    thread_result B
    84  } SQLITE_OK
    85  do_test thread1-1.10 {
    86    thread_compile C {CREATE TABLE t2(x,y)}
    87    thread_step C
    88    thread_result C
    89  } SQLITE_DONE
    90  do_test thread1-1.11 {
    91    thread_finalize C
    92    thread_result C
    93  } SQLITE_OK
    94  do_test thread1-1.12 {
    95    catchsql {SELECT name FROM sqlite_master}
    96    execsql {SELECT name FROM sqlite_master}
    97  } {t1 t2}
    98  
    99  
   100  #
   101  # The following tests - thread1-2.* - test the following scenario:
   102  #
   103  # 1:  Read-lock thread A
   104  # 2:  Read-lock thread B
   105  # 3:  Attempt to write in thread C -> SQLITE_BUSY
   106  # 4:  Check db write failed from main thread.
   107  # 5:  Unlock from thread A.
   108  # 6:  Attempt to write in thread C -> SQLITE_BUSY
   109  # 7:  Check db write failed from main thread.
   110  # 8:  Unlock from thread B.
   111  # 9:  Attempt to write in thread C -> SQLITE_DONE
   112  # 10: Finalize the write from thread C
   113  # 11: Check db write succeeded from main thread.
   114  #
   115  do_test thread1-2.1 {
   116    thread_halt *
   117    thread_create A test.db
   118    thread_compile A {SELECT a FROM t1}
   119    thread_step A
   120    thread_result A
   121  } SQLITE_ROW
   122  do_test thread1-2.2 {
   123    thread_create B test.db
   124    thread_compile B {SELECT b FROM t1}
   125    thread_step B
   126    thread_result B
   127  } SQLITE_ROW
   128  do_test thread1-2.3 {
   129    thread_create C test.db
   130    thread_compile C {INSERT INTO t2 VALUES(98,99)}
   131    thread_step C
   132    thread_result C
   133    thread_finalize C
   134    thread_result C
   135  } SQLITE_BUSY
   136  
   137  do_test thread1-2.4 {
   138    execsql {SELECT * FROM t2}
   139  } {}
   140  
   141  do_test thread1-2.5 {
   142    thread_finalize A
   143    thread_result A
   144  } SQLITE_OK
   145  do_test thread1-2.6 {
   146    thread_compile C {INSERT INTO t2 VALUES(98,99)}
   147    thread_step C
   148    thread_result C
   149    thread_finalize C
   150    thread_result C
   151  } SQLITE_BUSY
   152  do_test thread1-2.7 {
   153    execsql {SELECT * FROM t2}
   154  } {}
   155  do_test thread1-2.8 {
   156    thread_finalize B
   157    thread_result B
   158  } SQLITE_OK
   159  do_test thread1-2.9 {
   160    thread_compile C {INSERT INTO t2 VALUES(98,99)}
   161    thread_step C
   162    thread_result C
   163  } SQLITE_DONE
   164  do_test thread1-2.10 {
   165    thread_finalize C
   166    thread_result C
   167  } SQLITE_OK
   168  do_test thread1-2.11 {
   169    execsql {SELECT * FROM t2}
   170  } {98 99}
   171  
   172  thread_halt *   
   173  finish_test