/ Hex Artifact Content
Login

Artifact 7ffb45accf6ee91c736df9bafe0806a44358f035:


0000: 23 20 32 30 31 30 20 41 70 72 69 6c 20 31 34 0a  # 2010 April 14.
0010: 23 0a 23 20 54 68 65 20 61 75 74 68 6f 72 20 64  #.# The author d
0020: 69 73 63 6c 61 69 6d 73 20 63 6f 70 79 72 69 67  isclaims copyrig
0030: 68 74 20 74 6f 20 74 68 69 73 20 73 6f 75 72 63  ht to this sourc
0040: 65 20 63 6f 64 65 2e 20 20 49 6e 20 70 6c 61 63  e code.  In plac
0050: 65 20 6f 66 0a 23 20 61 20 6c 65 67 61 6c 20 6e  e of.# a legal n
0060: 6f 74 69 63 65 2c 20 68 65 72 65 20 69 73 20 61  otice, here is a
0070: 20 62 6c 65 73 73 69 6e 67 3a 0a 23 0a 23 20 20   blessing:.#.#  
0080: 20 20 4d 61 79 20 79 6f 75 20 64 6f 20 67 6f 6f    May you do goo
0090: 64 20 61 6e 64 20 6e 6f 74 20 65 76 69 6c 2e 0a  d and not evil..
00a0: 23 20 20 20 20 4d 61 79 20 79 6f 75 20 66 69 6e  #    May you fin
00b0: 64 20 66 6f 72 67 69 76 65 6e 65 73 73 20 66 6f  d forgiveness fo
00c0: 72 20 79 6f 75 72 73 65 6c 66 20 61 6e 64 20 66  r yourself and f
00d0: 6f 72 67 69 76 65 20 6f 74 68 65 72 73 2e 0a 23  orgive others..#
00e0: 20 20 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72      May you shar
00f0: 65 20 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20  e freely, never 
0100: 74 61 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e  taking more than
0110: 20 79 6f 75 20 67 69 76 65 2e 0a 23 0a 23 2a 2a   you give..#.#**
0120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 0a 23 20 54 68 69 73 20 66 69 6c  *****.# This fil
0170: 65 20 63 6f 6e 74 61 69 6e 73 20 63 6f 64 65 20  e contains code 
0180: 75 73 65 64 20 62 79 20 73 65 76 65 72 61 6c 20  used by several 
0190: 64 69 66 66 65 72 65 6e 74 20 74 65 73 74 20 73  different test s
01a0: 63 72 69 70 74 73 2e 20 54 68 65 0a 23 20 63 6f  cripts. The.# co
01b0: 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20  de in this file 
01c0: 61 6c 6c 6f 77 73 20 74 65 73 74 66 69 78 74 75  allows testfixtu
01d0: 72 65 20 74 6f 20 63 6f 6e 74 72 6f 6c 20 61 6e  re to control an
01e0: 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20 28 6f  other process (o
01f0: 72 0a 23 20 70 72 6f 63 65 73 73 65 73 29 20 74  r.# processes) t
0200: 6f 20 74 65 73 74 20 6c 6f 63 6b 69 6e 67 2e 0a  o test locking..
0210: 23 0a 0a 70 72 6f 63 20 64 6f 5f 6d 75 6c 74 69  #..proc do_multi
0220: 63 6c 69 65 6e 74 5f 74 65 73 74 20 7b 76 61 72  client_test {var
0230: 6e 61 6d 65 20 73 63 72 69 70 74 7d 20 7b 0a 0a  name script} {..
0240: 20 20 66 6f 72 65 61 63 68 20 63 6f 64 65 20 5b    foreach code [
0250: 6c 69 73 74 20 7b 0a 20 20 20 20 69 66 20 7b 5b  list {.    if {[
0260: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
0270: 76 61 6c 67 72 69 6e 64 29 5d 7d 20 7b 20 64 62  valgrind)]} { db
0280: 20 63 6c 6f 73 65 20 3b 20 63 6f 6e 74 69 6e 75   close ; continu
0290: 65 20 7d 0a 20 20 20 20 73 65 74 20 3a 3a 63 6f  e }.    set ::co
02a0: 64 65 32 5f 63 68 61 6e 20 5b 6c 61 75 6e 63 68  de2_chan [launch
02b0: 5f 74 65 73 74 66 69 78 74 75 72 65 5d 0a 20 20  _testfixture].  
02c0: 20 20 73 65 74 20 3a 3a 63 6f 64 65 33 5f 63 68    set ::code3_ch
02d0: 61 6e 20 5b 6c 61 75 6e 63 68 5f 74 65 73 74 66  an [launch_testf
02e0: 69 78 74 75 72 65 5d 0a 20 20 20 20 70 72 6f 63  ixture].    proc
02f0: 20 63 6f 64 65 32 20 7b 74 63 6c 7d 20 7b 20 74   code2 {tcl} { t
0300: 65 73 74 66 69 78 74 75 72 65 20 24 3a 3a 63 6f  estfixture $::co
0310: 64 65 32 5f 63 68 61 6e 20 24 74 63 6c 20 7d 0a  de2_chan $tcl }.
0320: 20 20 20 20 70 72 6f 63 20 63 6f 64 65 33 20 7b      proc code3 {
0330: 74 63 6c 7d 20 7b 20 74 65 73 74 66 69 78 74 75  tcl} { testfixtu
0340: 72 65 20 24 3a 3a 63 6f 64 65 33 5f 63 68 61 6e  re $::code3_chan
0350: 20 24 74 63 6c 20 7d 0a 20 20 20 20 73 65 74 20   $tcl }.    set 
0360: 74 6e 20 31 0a 20 20 7d 20 7b 0a 20 20 20 20 70  tn 1.  } {.    p
0370: 72 6f 63 20 63 6f 64 65 32 20 7b 74 63 6c 7d 20  roc code2 {tcl} 
0380: 7b 20 75 70 6c 65 76 65 6c 20 23 30 20 24 74 63  { uplevel #0 $tc
0390: 6c 20 7d 0a 20 20 20 20 70 72 6f 63 20 63 6f 64  l }.    proc cod
03a0: 65 33 20 7b 74 63 6c 7d 20 7b 20 75 70 6c 65 76  e3 {tcl} { uplev
03b0: 65 6c 20 23 30 20 24 74 63 6c 20 7d 0a 20 20 20  el #0 $tcl }.   
03c0: 20 73 65 74 20 74 6e 20 32 0a 20 20 7d 5d 20 7b   set tn 2.  }] {
03d0: 0a 20 20 20 20 66 61 75 6c 74 73 69 6d 5f 64 65  .    faultsim_de
03e0: 6c 65 74 65 5f 61 6e 64 5f 72 65 6f 70 65 6e 0a  lete_and_reopen.
03f0: 0a 20 20 20 20 70 72 6f 63 20 63 6f 64 65 31 20  .    proc code1 
0400: 7b 74 63 6c 7d 20 7b 20 75 70 6c 65 76 65 6c 20  {tcl} { uplevel 
0410: 23 30 20 24 74 63 6c 20 7d 0a 20 20 0a 20 20 20  #0 $tcl }.  .   
0420: 20 23 20 4f 70 65 6e 20 63 6f 6e 6e 65 63 74 69   # Open connecti
0430: 6f 6e 73 20 5b 64 62 32 5d 20 61 6e 64 20 5b 64  ons [db2] and [d
0440: 62 33 5d 2e 20 44 65 70 65 6e 64 69 6e 67 20 6f  b3]. Depending o
0450: 6e 20 77 68 69 63 68 20 69 74 65 72 61 74 69 6f  n which iteratio
0460: 6e 20 74 68 69 73 0a 20 20 20 20 23 20 69 73 2c  n this.    # is,
0470: 20 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73   the connections
0480: 20 6d 61 79 20 62 65 20 63 72 65 61 74 65 64 20   may be created 
0490: 69 6e 20 74 68 69 73 20 69 6e 74 65 72 70 72 65  in this interpre
04a0: 74 65 72 2c 20 6f 72 20 69 6e 20 0a 20 20 20 20  ter, or in .    
04b0: 23 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 72  # interpreters r
04c0: 75 6e 6e 69 6e 67 20 69 6e 20 6f 74 68 65 72 20  unning in other 
04d0: 4f 53 20 70 72 6f 63 65 73 73 65 73 2e 20 41 73  OS processes. As
04e0: 20 73 75 63 68 2c 20 74 68 65 20 5b 64 62 32 5d   such, the [db2]
04f0: 20 61 6e 64 20 5b 64 62 33 5d 0a 20 20 20 20 23   and [db3].    #
0500: 20 63 6f 6d 6d 61 6e 64 73 20 73 68 6f 75 6c 64   commands should
0510: 20 6f 6e 6c 79 20 62 65 20 61 63 63 65 73 73 65   only be accesse
0520: 64 20 77 69 74 68 69 6e 20 5b 63 6f 64 65 32 5d  d within [code2]
0530: 20 61 6e 64 20 5b 63 6f 64 65 33 5d 20 62 6c 6f   and [code3] blo
0540: 63 6b 73 2c 0a 20 20 20 20 23 20 72 65 73 70 65  cks,.    # respe
0550: 63 74 69 76 65 6c 79 2e 0a 20 20 20 20 23 0a 20  ctively..    #. 
0560: 20 20 20 65 76 61 6c 20 24 63 6f 64 65 0a 20 20     eval $code.  
0570: 20 20 63 6f 64 65 32 20 7b 20 73 71 6c 69 74 65    code2 { sqlite
0580: 33 20 64 62 32 20 74 65 73 74 2e 64 62 20 7d 0a  3 db2 test.db }.
0590: 20 20 20 20 63 6f 64 65 33 20 7b 20 73 71 6c 69      code3 { sqli
05a0: 74 65 33 20 64 62 33 20 74 65 73 74 2e 64 62 20  te3 db3 test.db 
05b0: 7d 0a 20 20 20 20 0a 20 20 20 20 23 20 53 68 6f  }.    .    # Sho
05c0: 72 74 68 61 6e 64 20 63 6f 6d 6d 61 6e 64 73 2e  rthand commands.
05d0: 20 45 78 65 63 75 74 65 20 53 51 4c 20 75 73 69   Execute SQL usi
05e0: 6e 67 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  ng database conn
05f0: 65 63 74 69 6f 6e 20 5b 64 62 32 5d 20 6f 72 20  ection [db2] or 
0600: 0a 20 20 20 20 23 20 5b 64 62 33 5d 2e 20 52 65  .    # [db3]. Re
0610: 74 75 72 6e 20 74 68 65 20 72 65 73 75 6c 74 73  turn the results
0620: 2e 0a 20 20 20 20 23 0a 20 20 20 20 70 72 6f 63  ..    #.    proc
0630: 20 73 71 6c 31 20 7b 73 71 6c 7d 20 7b 20 64 62   sql1 {sql} { db
0640: 20 65 76 61 6c 20 24 73 71 6c 20 7d 0a 20 20 20   eval $sql }.   
0650: 20 70 72 6f 63 20 73 71 6c 32 20 7b 73 71 6c 7d   proc sql2 {sql}
0660: 20 7b 20 63 6f 64 65 32 20 5b 6c 69 73 74 20 64   { code2 [list d
0670: 62 32 20 65 76 61 6c 20 24 73 71 6c 5d 20 7d 0a  b2 eval $sql] }.
0680: 20 20 20 20 70 72 6f 63 20 73 71 6c 33 20 7b 73      proc sql3 {s
0690: 71 6c 7d 20 7b 20 63 6f 64 65 33 20 5b 6c 69 73  ql} { code3 [lis
06a0: 74 20 64 62 33 20 65 76 61 6c 20 24 73 71 6c 5d  t db3 eval $sql]
06b0: 20 7d 0a 20 20 0a 20 20 20 20 70 72 6f 63 20 63   }.  .    proc c
06c0: 73 71 6c 31 20 7b 73 71 6c 7d 20 7b 20 6c 69 73  sql1 {sql} { lis
06d0: 74 20 5b 63 61 74 63 68 20 7b 20 73 71 6c 31 20  t [catch { sql1 
06e0: 24 73 71 6c 20 7d 20 6d 73 67 5d 20 24 6d 73 67  $sql } msg] $msg
06f0: 20 7d 0a 20 20 20 20 70 72 6f 63 20 63 73 71 6c   }.    proc csql
0700: 32 20 7b 73 71 6c 7d 20 7b 20 6c 69 73 74 20 5b  2 {sql} { list [
0710: 63 61 74 63 68 20 7b 20 73 71 6c 32 20 24 73 71  catch { sql2 $sq
0720: 6c 20 7d 20 6d 73 67 5d 20 24 6d 73 67 20 7d 0a  l } msg] $msg }.
0730: 20 20 20 20 70 72 6f 63 20 63 73 71 6c 33 20 7b      proc csql3 {
0740: 73 71 6c 7d 20 7b 20 6c 69 73 74 20 5b 63 61 74  sql} { list [cat
0750: 63 68 20 7b 20 73 71 6c 33 20 24 73 71 6c 20 7d  ch { sql3 $sql }
0760: 20 6d 73 67 5d 20 24 6d 73 67 20 7d 0a 0a 20 20   msg] $msg }..  
0770: 20 20 75 70 6c 65 76 65 6c 20 73 65 74 20 24 76    uplevel set $v
0780: 61 72 6e 61 6d 65 20 24 74 6e 0a 20 20 20 20 75  arname $tn.    u
0790: 70 6c 65 76 65 6c 20 24 73 63 72 69 70 74 0a 0a  plevel $script..
07a0: 20 20 20 20 63 61 74 63 68 20 7b 20 63 6f 64 65      catch { code
07b0: 32 20 7b 20 64 62 32 20 63 6c 6f 73 65 20 7d 20  2 { db2 close } 
07c0: 7d 0a 20 20 20 20 63 61 74 63 68 20 7b 20 63 6f  }.    catch { co
07d0: 64 65 33 20 7b 20 64 62 33 20 63 6c 6f 73 65 20  de3 { db3 close 
07e0: 7d 20 7d 0a 20 20 20 20 63 61 74 63 68 20 7b 20  } }.    catch { 
07f0: 63 6c 6f 73 65 20 24 3a 3a 63 6f 64 65 32 5f 63  close $::code2_c
0800: 68 61 6e 20 7d 0a 20 20 20 20 63 61 74 63 68 20  han }.    catch 
0810: 7b 20 63 6c 6f 73 65 20 24 3a 3a 63 6f 64 65 33  { close $::code3
0820: 5f 63 68 61 6e 20 7d 0a 20 20 20 20 63 61 74 63  _chan }.    catc
0830: 68 20 7b 20 64 62 20 63 6c 6f 73 65 20 7d 0a 20  h { db close }. 
0840: 20 7d 0a 7d 0a 0a 23 20 4c 61 75 6e 63 68 20 61   }.}..# Launch a
0850: 6e 6f 74 68 65 72 20 74 65 73 74 66 69 78 74 75  nother testfixtu
0860: 72 65 20 70 72 6f 63 65 73 73 20 74 6f 20 62 65  re process to be
0870: 20 63 6f 6e 74 72 6f 6c 6c 65 64 20 62 79 20 74   controlled by t
0880: 68 69 73 20 6f 6e 65 2e 20 41 0a 23 20 63 68 61  his one. A.# cha
0890: 6e 6e 65 6c 20 6e 61 6d 65 20 69 73 20 72 65 74  nnel name is ret
08a0: 75 72 6e 65 64 20 74 68 61 74 20 6d 61 79 20 62  urned that may b
08b0: 65 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  e passed as the 
08c0: 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74  first argument t
08d0: 6f 20 70 72 6f 63 0a 23 20 27 74 65 73 74 66 69  o proc.# 'testfi
08e0: 78 74 75 72 65 27 20 74 6f 20 65 78 65 63 75 74  xture' to execut
08f0: 65 20 61 20 63 6f 6d 6d 61 6e 64 2e 20 54 68 65  e a command. The
0900: 20 63 68 69 6c 64 20 74 65 73 74 66 69 78 74 75   child testfixtu
0910: 72 65 20 70 72 6f 63 65 73 73 20 69 73 20 73 68  re process is sh
0920: 75 74 0a 23 20 64 6f 77 6e 20 62 79 20 63 6c 6f  ut.# down by clo
0930: 73 69 6e 67 20 74 68 65 20 63 68 61 6e 6e 65 6c  sing the channel
0940: 2e 0a 70 72 6f 63 20 6c 61 75 6e 63 68 5f 74 65  ..proc launch_te
0950: 73 74 66 69 78 74 75 72 65 20 7b 7b 70 72 67 20  stfixture {{prg 
0960: 22 22 7d 7d 20 7b 0a 20 20 77 72 69 74 65 5f 6d  ""}} {.  write_m
0970: 61 69 6e 5f 6c 6f 6f 70 0a 20 20 69 66 20 7b 24  ain_loop.  if {$
0980: 70 72 67 20 65 71 20 22 22 7d 20 7b 20 73 65 74  prg eq ""} { set
0990: 20 70 72 67 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f   prg [info nameo
09a0: 66 65 78 65 63 5d 20 7d 0a 20 20 69 66 20 7b 24  fexec] }.  if {$
09b0: 70 72 67 20 65 71 20 22 22 7d 20 7b 20 73 65 74  prg eq ""} { set
09c0: 20 70 72 67 20 74 65 73 74 66 69 78 74 75 72 65   prg testfixture
09d0: 20 7d 0a 20 20 69 66 20 7b 5b 66 69 6c 65 20 74   }.  if {[file t
09e0: 61 69 6c 20 24 70 72 67 5d 3d 3d 24 70 72 67 7d  ail $prg]==$prg}
09f0: 20 7b 20 73 65 74 20 70 72 67 20 5b 66 69 6c 65   { set prg [file
0a00: 20 6a 6f 69 6e 20 2e 20 24 70 72 67 5d 20 7d 0a   join . $prg] }.
0a10: 20 20 73 65 74 20 63 68 61 6e 20 5b 6f 70 65 6e    set chan [open
0a20: 20 22 7c 24 70 72 67 20 74 66 5f 6d 61 69 6e 2e   "|$prg tf_main.
0a30: 74 63 6c 22 20 72 2b 5d 0a 20 20 66 63 6f 6e 66  tcl" r+].  fconf
0a40: 69 67 75 72 65 20 24 63 68 61 6e 20 2d 62 75 66  igure $chan -buf
0a50: 66 65 72 69 6e 67 20 6c 69 6e 65 0a 20 20 73 65  fering line.  se
0a60: 74 20 72 63 20 5b 63 61 74 63 68 20 7b 20 0a 20  t rc [catch { . 
0a70: 20 20 20 74 65 73 74 66 69 78 74 75 72 65 20 24     testfixture $
0a80: 63 68 61 6e 20 22 73 71 6c 69 74 65 33 5f 74 65  chan "sqlite3_te
0a90: 73 74 5f 63 6f 6e 74 72 6f 6c 5f 70 65 6e 64 69  st_control_pendi
0aa0: 6e 67 5f 62 79 74 65 20 24 3a 3a 73 71 6c 69 74  ng_byte $::sqlit
0ab0: 65 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 22 0a  e_pending_byte".
0ac0: 20 20 7d 5d 0a 20 20 69 66 20 7b 24 72 63 7d 20    }].  if {$rc} 
0ad0: 7b 0a 20 20 20 20 74 65 73 74 66 69 78 74 75 72  {.    testfixtur
0ae0: 65 20 24 63 68 61 6e 20 22 73 65 74 20 3a 3a 73  e $chan "set ::s
0af0: 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f 62 79  qlite_pending_by
0b00: 74 65 20 24 3a 3a 73 71 6c 69 74 65 5f 70 65 6e  te $::sqlite_pen
0b10: 64 69 6e 67 5f 62 79 74 65 22 0a 20 20 7d 0a 20  ding_byte".  }. 
0b20: 20 72 65 74 75 72 6e 20 24 63 68 61 6e 0a 7d 0a   return $chan.}.
0b30: 0a 23 20 45 78 65 63 75 74 65 20 61 20 63 6f 6d  .# Execute a com
0b40: 6d 61 6e 64 20 69 6e 20 61 20 63 68 69 6c 64 20  mand in a child 
0b50: 74 65 73 74 66 69 78 74 75 72 65 20 70 72 6f 63  testfixture proc
0b60: 65 73 73 2c 20 63 6f 6e 6e 65 63 74 65 64 20 62  ess, connected b
0b70: 79 20 74 77 6f 2d 77 61 79 0a 23 20 63 68 61 6e  y two-way.# chan
0b80: 6e 65 6c 20 24 63 68 61 6e 2e 20 52 65 74 75 72  nel $chan. Retur
0b90: 6e 20 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20  n the result of 
0ba0: 74 68 65 20 63 6f 6d 6d 61 6e 64 2c 20 6f 72 20  the command, or 
0bb0: 61 6e 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  an error message
0bc0: 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74 66 69 78  ..#.proc testfix
0bd0: 74 75 72 65 20 7b 63 68 61 6e 20 63 6d 64 20 61  ture {chan cmd a
0be0: 72 67 73 7d 20 7b 0a 0a 20 20 69 66 20 7b 5b 6c  rgs} {..  if {[l
0bf0: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 20 3d 3d  length $args] ==
0c00: 20 30 7d 20 7b 0a 20 20 20 20 66 63 6f 6e 66 69   0} {.    fconfi
0c10: 67 75 72 65 20 24 63 68 61 6e 20 2d 62 6c 6f 63  gure $chan -bloc
0c20: 6b 69 6e 67 20 31 0a 20 20 20 20 70 75 74 73 20  king 1.    puts 
0c30: 24 63 68 61 6e 20 24 63 6d 64 0a 20 20 20 20 70  $chan $cmd.    p
0c40: 75 74 73 20 24 63 68 61 6e 20 4f 56 45 52 0a 0a  uts $chan OVER..
0c50: 20 20 20 20 73 65 74 20 72 20 22 22 0a 20 20 20      set r "".   
0c60: 20 77 68 69 6c 65 20 7b 20 31 20 7d 20 7b 0a 20   while { 1 } {. 
0c70: 20 20 20 20 20 73 65 74 20 6c 69 6e 65 20 5b 67       set line [g
0c80: 65 74 73 20 24 63 68 61 6e 5d 0a 20 20 20 20 20  ets $chan].     
0c90: 20 69 66 20 7b 20 24 6c 69 6e 65 20 3d 3d 20 22   if { $line == "
0ca0: 4f 56 45 52 22 20 7d 20 7b 20 0a 20 20 20 20 20  OVER" } { .     
0cb0: 20 20 20 73 65 74 20 72 65 73 20 5b 6c 69 6e 64     set res [lind
0cc0: 65 78 20 24 72 20 31 5d 0a 20 20 20 20 20 20 20  ex $r 1].       
0cd0: 20 69 66 20 7b 20 5b 6c 69 6e 64 65 78 20 24 72   if { [lindex $r
0ce0: 20 30 5d 20 7d 20 7b 20 65 72 72 6f 72 20 24 72   0] } { error $r
0cf0: 65 73 20 7d 0a 20 20 20 20 20 20 20 20 72 65 74  es }.        ret
0d00: 75 72 6e 20 24 72 65 73 0a 20 20 20 20 20 20 7d  urn $res.      }
0d10: 0a 20 20 20 20 20 20 69 66 20 7b 5b 65 6f 66 20  .      if {[eof 
0d20: 24 63 68 61 6e 5d 7d 20 7b 0a 20 20 20 20 20 20  $chan]} {.      
0d30: 20 20 72 65 74 75 72 6e 20 22 45 52 52 4f 52 3a    return "ERROR:
0d40: 20 43 68 69 6c 64 20 70 72 6f 63 65 73 73 20 68   Child process h
0d50: 75 6e 67 20 75 70 22 0a 20 20 20 20 20 20 7d 0a  ung up".      }.
0d60: 20 20 20 20 20 20 61 70 70 65 6e 64 20 72 20 24        append r $
0d70: 6c 69 6e 65 0a 20 20 20 20 7d 0a 20 20 20 20 72  line.    }.    r
0d80: 65 74 75 72 6e 20 24 72 0a 20 20 7d 20 65 6c 73  eturn $r.  } els
0d90: 65 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a 74 66  e {.    set ::tf
0da0: 6e 62 28 24 63 68 61 6e 29 20 22 22 0a 20 20 20  nb($chan) "".   
0db0: 20 66 63 6f 6e 66 69 67 75 72 65 20 24 63 68 61   fconfigure $cha
0dc0: 6e 20 2d 62 6c 6f 63 6b 69 6e 67 20 30 20 2d 62  n -blocking 0 -b
0dd0: 75 66 66 65 72 69 6e 67 20 6e 6f 6e 65 0a 20 20  uffering none.  
0de0: 20 20 70 75 74 73 20 24 63 68 61 6e 20 24 63 6d    puts $chan $cm
0df0: 64 0a 20 20 20 20 70 75 74 73 20 24 63 68 61 6e  d.    puts $chan
0e00: 20 4f 56 45 52 0a 20 20 20 20 66 69 6c 65 65 76   OVER.    fileev
0e10: 65 6e 74 20 24 63 68 61 6e 20 72 65 61 64 61 62  ent $chan readab
0e20: 6c 65 20 5b 6c 69 73 74 20 74 65 73 74 66 69 78  le [list testfix
0e30: 74 75 72 65 5f 73 63 72 69 70 74 5f 63 62 20 24  ture_script_cb $
0e40: 63 68 61 6e 20 5b 6c 69 6e 64 65 78 20 24 61 72  chan [lindex $ar
0e50: 67 73 20 30 5d 5d 0a 20 20 20 20 72 65 74 75 72  gs 0]].    retur
0e60: 6e 20 22 22 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63  n "".  }.}..proc
0e70: 20 74 65 73 74 66 69 78 74 75 72 65 5f 73 63 72   testfixture_scr
0e80: 69 70 74 5f 63 62 20 7b 63 68 61 6e 20 73 63 72  ipt_cb {chan scr
0e90: 69 70 74 7d 20 7b 0a 20 20 69 66 20 7b 5b 65 6f  ipt} {.  if {[eo
0ea0: 66 20 24 63 68 61 6e 5d 7d 20 7b 0a 20 20 20 20  f $chan]} {.    
0eb0: 61 70 70 65 6e 64 20 3a 3a 74 66 6e 62 28 24 63  append ::tfnb($c
0ec0: 68 61 6e 29 20 22 45 52 52 4f 52 3a 20 43 68 69  han) "ERROR: Chi
0ed0: 6c 64 20 70 72 6f 63 65 73 73 20 68 75 6e 67 20  ld process hung 
0ee0: 75 70 22 0a 20 20 20 20 73 65 74 20 6c 69 6e 65  up".    set line
0ef0: 20 22 4f 56 45 52 22 0a 20 20 7d 20 65 6c 73 65   "OVER".  } else
0f00: 20 7b 0a 20 20 20 20 73 65 74 20 6c 69 6e 65 20   {.    set line 
0f10: 5b 67 65 74 73 20 24 63 68 61 6e 5d 0a 20 20 7d  [gets $chan].  }
0f20: 0a 0a 20 20 69 66 20 7b 20 24 6c 69 6e 65 20 3d  ..  if { $line =
0f30: 3d 20 22 4f 56 45 52 22 20 7d 20 7b 0a 20 20 20  = "OVER" } {.   
0f40: 20 75 70 6c 65 76 65 6c 20 23 30 20 24 73 63 72   uplevel #0 $scr
0f50: 69 70 74 20 5b 6c 69 73 74 20 5b 6c 69 6e 64 65  ipt [list [linde
0f60: 78 20 24 3a 3a 74 66 6e 62 28 24 63 68 61 6e 29  x $::tfnb($chan)
0f70: 20 31 5d 5d 0a 20 20 20 20 75 6e 73 65 74 20 3a   1]].    unset :
0f80: 3a 74 66 6e 62 28 24 63 68 61 6e 29 0a 20 20 20  :tfnb($chan).   
0f90: 20 66 69 6c 65 65 76 65 6e 74 20 24 63 68 61 6e   fileevent $chan
0fa0: 20 72 65 61 64 61 62 6c 65 20 22 22 0a 20 20 7d   readable "".  }
0fb0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 61 70 70 65   else {.    appe
0fc0: 6e 64 20 3a 3a 74 66 6e 62 28 24 63 68 61 6e 29  nd ::tfnb($chan)
0fd0: 20 24 6c 69 6e 65 0a 20 20 7d 0a 7d 0a 0a 70 72   $line.  }.}..pr
0fe0: 6f 63 20 74 65 73 74 66 69 78 74 75 72 65 5f 6e  oc testfixture_n
0ff0: 62 5f 63 62 20 7b 76 61 72 6e 61 6d 65 20 63 68  b_cb {varname ch
1000: 61 6e 7d 20 7b 0a 20 20 69 66 20 7b 5b 65 6f 66  an} {.  if {[eof
1010: 20 24 63 68 61 6e 5d 7d 20 7b 0a 20 20 20 20 61   $chan]} {.    a
1020: 70 70 65 6e 64 20 3a 3a 74 66 6e 62 28 24 63 68  ppend ::tfnb($ch
1030: 61 6e 29 20 22 45 52 52 4f 52 3a 20 43 68 69 6c  an) "ERROR: Chil
1040: 64 20 70 72 6f 63 65 73 73 20 68 75 6e 67 20 75  d process hung u
1050: 70 22 0a 20 20 20 20 73 65 74 20 6c 69 6e 65 20  p".    set line 
1060: 22 4f 56 45 52 22 0a 20 20 7d 20 65 6c 73 65 20  "OVER".  } else 
1070: 7b 0a 20 20 20 20 73 65 74 20 6c 69 6e 65 20 5b  {.    set line [
1080: 67 65 74 73 20 24 63 68 61 6e 5d 0a 20 20 7d 0a  gets $chan].  }.
1090: 0a 20 20 69 66 20 7b 20 24 6c 69 6e 65 20 3d 3d  .  if { $line ==
10a0: 20 22 4f 56 45 52 22 20 7d 20 7b 0a 20 20 20 20   "OVER" } {.    
10b0: 73 65 74 20 24 76 61 72 6e 61 6d 65 20 5b 6c 69  set $varname [li
10c0: 6e 64 65 78 20 24 3a 3a 74 66 6e 62 28 24 63 68  ndex $::tfnb($ch
10d0: 61 6e 29 20 31 5d 0a 20 20 20 20 75 6e 73 65 74  an) 1].    unset
10e0: 20 3a 3a 74 66 6e 62 28 24 63 68 61 6e 29 0a 20   ::tfnb($chan). 
10f0: 20 20 20 63 6c 6f 73 65 20 24 63 68 61 6e 0a 20     close $chan. 
1100: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 61 70   } else {.    ap
1110: 70 65 6e 64 20 3a 3a 74 66 6e 62 28 24 63 68 61  pend ::tfnb($cha
1120: 6e 29 20 24 6c 69 6e 65 0a 20 20 7d 0a 7d 0a 0a  n) $line.  }.}..
1130: 70 72 6f 63 20 74 65 73 74 66 69 78 74 75 72 65  proc testfixture
1140: 5f 6e 62 20 7b 76 61 72 6e 61 6d 65 20 63 6d 64  _nb {varname cmd
1150: 7d 20 7b 0a 20 20 73 65 74 20 63 68 61 6e 20 5b  } {.  set chan [
1160: 6c 61 75 6e 63 68 5f 74 65 73 74 66 69 78 74 75  launch_testfixtu
1170: 72 65 5d 0a 20 20 73 65 74 20 3a 3a 74 66 6e 62  re].  set ::tfnb
1180: 28 24 63 68 61 6e 29 20 22 22 0a 20 20 66 63 6f  ($chan) "".  fco
1190: 6e 66 69 67 75 72 65 20 24 63 68 61 6e 20 2d 62  nfigure $chan -b
11a0: 6c 6f 63 6b 69 6e 67 20 30 20 2d 62 75 66 66 65  locking 0 -buffe
11b0: 72 69 6e 67 20 6e 6f 6e 65 0a 20 20 70 75 74 73  ring none.  puts
11c0: 20 24 63 68 61 6e 20 24 63 6d 64 0a 20 20 70 75   $chan $cmd.  pu
11d0: 74 73 20 24 63 68 61 6e 20 4f 56 45 52 0a 20 20  ts $chan OVER.  
11e0: 66 69 6c 65 65 76 65 6e 74 20 24 63 68 61 6e 20  fileevent $chan 
11f0: 72 65 61 64 61 62 6c 65 20 5b 6c 69 73 74 20 74  readable [list t
1200: 65 73 74 66 69 78 74 75 72 65 5f 6e 62 5f 63 62  estfixture_nb_cb
1210: 20 24 76 61 72 6e 61 6d 65 20 24 63 68 61 6e 5d   $varname $chan]
1220: 0a 20 20 72 65 74 75 72 6e 20 22 22 0a 7d 0a 0a  .  return "".}..
1230: 23 20 57 72 69 74 65 20 74 68 65 20 6d 61 69 6e  # Write the main
1240: 20 6c 6f 6f 70 20 66 6f 72 20 74 68 65 20 63 68   loop for the ch
1250: 69 6c 64 20 74 65 73 74 66 69 78 74 75 72 65 20  ild testfixture 
1260: 70 72 6f 63 65 73 73 65 73 20 69 6e 74 6f 20 66  processes into f
1270: 69 6c 65 0a 23 20 74 66 5f 6d 61 69 6e 2e 74 63  ile.# tf_main.tc
1280: 6c 2e 20 54 68 65 20 70 61 72 65 6e 74 20 28 74  l. The parent (t
1290: 68 69 73 20 73 63 72 69 70 74 29 20 69 6e 74 65  his script) inte
12a0: 72 61 63 74 73 20 77 69 74 68 20 74 68 65 20 63  racts with the c
12b0: 68 69 6c 64 20 70 72 6f 63 65 73 73 65 73 0a 23  hild processes.#
12c0: 20 76 69 61 20 61 20 74 77 6f 20 77 61 79 20 70   via a two way p
12d0: 69 70 65 2e 20 54 68 65 20 70 61 72 65 6e 74 20  ipe. The parent 
12e0: 77 72 69 74 65 73 20 61 20 73 63 72 69 70 74 20  writes a script 
12f0: 74 6f 20 74 68 65 20 73 74 64 69 6e 20 6f 66 20  to the stdin of 
1300: 74 68 65 20 63 68 69 6c 64 0a 23 20 70 72 6f 63  the child.# proc
1310: 65 73 73 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79  ess, followed by
1320: 20 74 68 65 20 77 6f 72 64 20 22 4f 56 45 52 22   the word "OVER"
1330: 20 6f 6e 20 61 20 6c 69 6e 65 20 6f 66 20 69 74   on a line of it
1340: 73 20 6f 77 6e 2e 20 54 68 65 20 63 68 69 6c 64  s own. The child
1350: 0a 23 20 70 72 6f 63 65 73 73 20 65 76 61 6c 75  .# process evalu
1360: 61 74 65 73 20 74 68 65 20 73 63 72 69 70 74 20  ates the script 
1370: 61 6e 64 20 77 72 69 74 65 73 20 74 68 65 20 72  and writes the r
1380: 65 73 75 6c 74 73 20 74 6f 20 73 74 64 6f 75 74  esults to stdout
1390: 2c 20 66 6f 6c 6c 6f 77 65 64 0a 23 20 62 79 20  , followed.# by 
13a0: 61 6e 20 22 4f 56 45 52 22 20 6f 66 20 69 74 73  an "OVER" of its
13b0: 20 6f 77 6e 2e 0a 23 0a 73 65 74 20 6d 61 69 6e   own..#.set main
13c0: 5f 6c 6f 6f 70 5f 77 72 69 74 74 65 6e 20 30 0a  _loop_written 0.
13d0: 70 72 6f 63 20 77 72 69 74 65 5f 6d 61 69 6e 5f  proc write_main_
13e0: 6c 6f 6f 70 20 7b 7d 20 7b 0a 20 20 69 66 20 7b  loop {} {.  if {
13f0: 24 3a 3a 6d 61 69 6e 5f 6c 6f 6f 70 5f 77 72 69  $::main_loop_wri
1400: 74 74 65 6e 7d 20 72 65 74 75 72 6e 0a 20 20 73  tten} return.  s
1410: 65 74 20 77 72 61 70 70 65 72 20 22 22 0a 20 20  et wrapper "".  
1420: 69 66 20 7b 5b 73 71 6c 69 74 65 33 20 2d 68 61  if {[sqlite3 -ha
1430: 73 2d 63 6f 64 65 63 5d 20 26 26 20 5b 69 6e 66  s-codec] && [inf
1440: 6f 20 65 78 69 73 74 73 20 3a 3a 64 6f 5f 6e 6f  o exists ::do_no
1450: 74 5f 75 73 65 5f 63 6f 64 65 63 5d 3d 3d 30 7d  t_use_codec]==0}
1460: 20 7b 0a 20 20 20 20 73 65 74 20 77 72 61 70 70   {.    set wrapp
1470: 65 72 20 22 0a 20 20 20 20 20 20 72 65 6e 61 6d  er ".      renam
1480: 65 20 73 71 6c 69 74 65 33 20 73 71 6c 69 74 65  e sqlite3 sqlite
1490: 5f 6f 72 69 67 0a 20 20 20 20 20 20 70 72 6f 63  _orig.      proc
14a0: 20 73 71 6c 69 74 65 33 20 7b 61 72 67 73 7d 20   sqlite3 {args} 
14b0: 7b 5b 69 6e 66 6f 20 62 6f 64 79 20 73 71 6c 69  {[info body sqli
14c0: 74 65 33 5d 7d 0a 20 20 20 20 22 0a 20 20 7d 0a  te3]}.    ".  }.
14d0: 0a 20 20 73 65 74 20 66 64 20 5b 6f 70 65 6e 20  .  set fd [open 
14e0: 74 66 5f 6d 61 69 6e 2e 74 63 6c 20 77 5d 0a 20  tf_main.tcl w]. 
14f0: 20 70 75 74 73 20 24 66 64 20 5b 73 74 72 69 6e   puts $fd [strin
1500: 67 20 6d 61 70 20 5b 6c 69 73 74 20 25 57 52 41  g map [list %WRA
1510: 50 50 45 52 25 20 24 77 72 61 70 70 65 72 5d 20  PPER% $wrapper] 
1520: 7b 0a 20 20 20 20 25 57 52 41 50 50 45 52 25 0a  {.    %WRAPPER%.
1530: 20 20 20 20 73 65 74 20 73 63 72 69 70 74 20 22      set script "
1540: 22 0a 20 20 20 20 77 68 69 6c 65 20 7b 21 5b 65  ".    while {![e
1550: 6f 66 20 73 74 64 69 6e 5d 7d 20 7b 0a 20 20 20  of stdin]} {.   
1560: 20 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a     flush stdout.
1570: 20 20 20 20 20 20 73 65 74 20 6c 69 6e 65 20 5b        set line [
1580: 67 65 74 73 20 73 74 64 69 6e 5d 0a 20 20 20 20  gets stdin].    
1590: 20 20 69 66 20 7b 20 24 6c 69 6e 65 20 3d 3d 20    if { $line == 
15a0: 22 4f 56 45 52 22 20 7d 20 7b 0a 20 20 20 20 20  "OVER" } {.     
15b0: 20 20 20 73 65 74 20 72 63 20 5b 63 61 74 63 68     set rc [catch
15c0: 20 7b 65 76 61 6c 20 24 73 63 72 69 70 74 7d 20   {eval $script} 
15d0: 72 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20  result].        
15e0: 70 75 74 73 20 5b 6c 69 73 74 20 24 72 63 20 24  puts [list $rc $
15f0: 72 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20  result].        
1600: 70 75 74 73 20 4f 56 45 52 0a 20 20 20 20 20 20  puts OVER.      
1610: 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20    flush stdout. 
1620: 20 20 20 20 20 20 20 73 65 74 20 73 63 72 69 70         set scrip
1630: 74 20 22 22 0a 20 20 20 20 20 20 7d 20 65 6c 73  t "".      } els
1640: 65 20 7b 0a 20 20 20 20 20 20 20 20 61 70 70 65  e {.        appe
1650: 6e 64 20 73 63 72 69 70 74 20 24 6c 69 6e 65 0a  nd script $line.
1660: 20 20 20 20 20 20 20 20 61 70 70 65 6e 64 20 73          append s
1670: 63 72 69 70 74 20 22 5c 6e 22 0a 20 20 20 20 20  cript "\n".     
1680: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 5d 0a 20 20   }.    }.  }].  
1690: 63 6c 6f 73 65 20 24 66 64 0a 20 20 73 65 74 20  close $fd.  set 
16a0: 6d 61 69 6e 5f 6c 6f 6f 70 5f 77 72 69 74 74 65  main_loop_writte
16b0: 6e 20 31 0a 7d 0a 0a                             n 1.}..