/ Check-in [b076e165]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Update the rest of the malloc failure test scripts to use the new interface. (CVS 4296)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b076e1655d6bae5ae10e6ceee646f502435da66a
User & Date: danielk1977 2007-08-25 13:37:49
Context
2007-08-25
14:39
Use recursive mutexes in pthreads. If the pthreads implementation does not support recursive mutexes, then you cannot compile SQLite with SQLITE_THREADSAFE=1. Ticket #2588. (CVS 4297) check-in: 1668284d user: drh tags: trunk
13:37
Update the rest of the malloc failure test scripts to use the new interface. (CVS 4296) check-in: b076e165 user: danielk1977 tags: trunk
13:09
Fix bugs in the altermalloc.test and incrblob_err.test scripts. (CVS 4295) check-in: e5ec1707 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/test8.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
299
300
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
...
780
781
782
783
784
785
786



787
788
789
790
791
792
793
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.53 2007/08/23 02:47:53 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  echo_vtab *pVtab, 
  sqlite3 *db 
){
  int rc = SQLITE_OK;

  if( pVtab->zTableName ){
    sqlite3_stmt *pStmt = 0;
    sqlite3_prepare(db, 
        "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?",
        -1, &pStmt, 0);

    sqlite3_bind_text(pStmt, 1, pVtab->zTableName, -1, 0);
    if( sqlite3_step(pStmt)==SQLITE_ROW ){
      int rc2;
      const char *zCreateTable = (const char *)sqlite3_column_text(pStmt, 0);
      rc = sqlite3_declare_vtab(db, zCreateTable);
      rc2 = sqlite3_finalize(pStmt);
      if( rc==SQLITE_OK ){
        rc = rc2;
      }
    } else {
      rc = sqlite3_finalize(pStmt);
      if( rc==SQLITE_OK ){ 
        rc = SQLITE_ERROR;
      }
    }
    if( rc==SQLITE_OK ){
      rc = getColumnNames(db, pVtab->zTableName, &pVtab->aCol, &pVtab->nCol);
    }
    if( rc==SQLITE_OK ){
      rc = getIndexArray(db, pVtab->zTableName, pVtab->nCol, &pVtab->aIndex);

    }
  }

  return rc;
}

/*
................................................................................
    string_concat(&zQuery, zNew, 1);
    pIdxInfo->orderByConsumed = 1;
  }

  appendToEchoModule(pVtab->interp, "xBestIndex");;
  appendToEchoModule(pVtab->interp, zQuery);




  pIdxInfo->idxNum = hashString(zQuery);
  pIdxInfo->idxStr = zQuery;
  pIdxInfo->needToFreeIdxStr = 1;
  if (useCost) {
    pIdxInfo->estimatedCost = cost;
  } else if( useIdx ){
    /* Approximation of log2(nRow). */







|







 







|


>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







 







>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
...
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.54 2007/08/25 13:37:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  echo_vtab *pVtab, 
  sqlite3 *db 
){
  int rc = SQLITE_OK;

  if( pVtab->zTableName ){
    sqlite3_stmt *pStmt = 0;
    rc = sqlite3_prepare(db, 
        "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?",
        -1, &pStmt, 0);
    if( rc==SQLITE_OK ){
      sqlite3_bind_text(pStmt, 1, pVtab->zTableName, -1, 0);
      if( sqlite3_step(pStmt)==SQLITE_ROW ){
        int rc2;
        const char *zCreateTable = (const char *)sqlite3_column_text(pStmt, 0);
        rc = sqlite3_declare_vtab(db, zCreateTable);
        rc2 = sqlite3_finalize(pStmt);
        if( rc==SQLITE_OK ){
          rc = rc2;
        }
      } else {
        rc = sqlite3_finalize(pStmt);
        if( rc==SQLITE_OK ){ 
          rc = SQLITE_ERROR;
        }
      }
      if( rc==SQLITE_OK ){
        rc = getColumnNames(db, pVtab->zTableName, &pVtab->aCol, &pVtab->nCol);
      }
      if( rc==SQLITE_OK ){
        rc = getIndexArray(db, pVtab->zTableName, pVtab->nCol, &pVtab->aIndex);
      }
    }
  }

  return rc;
}

/*
................................................................................
    string_concat(&zQuery, zNew, 1);
    pIdxInfo->orderByConsumed = 1;
  }

  appendToEchoModule(pVtab->interp, "xBestIndex");;
  appendToEchoModule(pVtab->interp, zQuery);

  if( !zQuery ){
    return SQLITE_NOMEM;
  }
  pIdxInfo->idxNum = hashString(zQuery);
  pIdxInfo->idxStr = zQuery;
  pIdxInfo->needToFreeIdxStr = 1;
  if (useCost) {
    pIdxInfo->estimatedCost = cost;
  } else if( useIdx ){
    /* Approximation of log2(nRow). */

Changes to test/attachmalloc.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#    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 ATTACH statement and
# specifically out-of-memory conditions within that command.
#
# $Id: attachmalloc.test,v 1.3 2006/09/04 18:54:14 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {
  puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG=1"
  finish_test
  return
}


# Usage: do_malloc_test <test name> <options...>
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
#     -tclprep          TCL script to run to prepare test.
#     -sqlprep          SQL script to run to prepare test.
#     -tclbody          TCL script to run with malloc failure simulation.
#     -sqlbody          TCL script to run with malloc failure simulation.
#     -cleanup          TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
  array set ::mallocopts $args

  set ::go 1
  for {set ::n 1} {$::go} {incr ::n} {

    do_test $tn.$::n {

      sqlite_malloc_fail 0
      catch {db close}
      catch {file delete -force test.db}
      catch {file delete -force test.db-journal}
      catch {file delete -force test2.db}
      catch {file delete -force test2.db-journal}
      set ::DB [sqlite3 db test.db]

      if {[info exists ::mallocopts(-tclprep)]} {
        eval $::mallocopts(-tclprep)
      }
      if {[info exists ::mallocopts(-sqlprep)]} {
        execsql $::mallocopts(-sqlprep)
      }

      sqlite_malloc_fail $::n
      set ::mallocbody {}
      if {[info exists ::mallocopts(-tclbody)]} {
        append ::mallocbody "$::mallocopts(-tclbody)\n"
      }
      if {[info exists ::mallocopts(-sqlbody)]} {
        append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
      }

      set v [catch $::mallocbody msg]

      set leftover [lindex [sqlite_malloc_stat] 2]
      if {$leftover>0} {
        if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
        set ::go 0
        set v {1 1}
      } else {
        set v2 [expr {$msg=="" || $msg=="out of memory"}]
        if {!$v2} {puts "\nError message returned: $msg"}
        lappend v $v2
      }
    } {1 1}
    sqlite_malloc_fail 0

    if {[info exists ::mallocopts(-cleanup)]} {
      catch $::mallocopts(-cleanup)
    }
  }
  unset ::mallocopts
}

do_malloc_test attachmalloc-1 -tclprep {
  db close
  for {set i 2} {$i<=4} {incr i} {
    file delete -force test$i.db
    file delete -force test$i.db-journal
  }







|





|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21





















































































22
23
24
25
26
27
28
#    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 ATTACH statement and
# specifically out-of-memory conditions within that command.
#
# $Id: attachmalloc.test,v 1.4 2007/08/25 13:37:49 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

source $testdir/malloc_common.tcl






















































































do_malloc_test attachmalloc-1 -tclprep {
  db close
  for {set i 2} {$i<=4} {incr i} {
    file delete -force test$i.db
    file delete -force test$i.db-journal
  }

Changes to test/capi3.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
746
747
748
749
750
751
752
753
754
755
756
757
758

759
760
761
762
763
764
765
766
767
768
769
770
771
772

773
774
775
776
777
778
779
#    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 testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.52 2007/08/22 02:56:44 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
set test_number 1
foreach {code english} $code2english {
  do_test capi3-9.$test_number "sqlite3_test_errstr $code" $english
  incr test_number
}

# Test the error message when a "real" out of memory occurs.
if {[info command sqlite_malloc_stat]!=""} {
set sqlite_malloc_fail 1
do_test capi3-10-1 {
  sqlite3 db test.db
  set DB [sqlite3_connection_pointer db]
  sqlite_malloc_fail 1

  catchsql {
    select * from sqlite_master;
  }
} {1 {out of memory}}
do_test capi3-10-2 {
  sqlite3_errmsg $::DB
} {out of memory}
ifcapable {utf16} {
  do_test capi3-10-3 {
    utf8 [sqlite3_errmsg16 $::DB]
  } {out of memory}
}
db close
sqlite_malloc_fail 0

}

# The following tests - capi3-11.* - test that a COMMIT or ROLLBACK
# statement issued while there are still outstanding VMs that are part of
# the transaction fails.
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]







|







 







|
<
|
|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
746
747
748
749
750
751
752
753

754
755
756

757
758
759
760
761
762
763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
778
#    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 testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.53 2007/08/25 13:37:49 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
set test_number 1
foreach {code english} $code2english {
  do_test capi3-9.$test_number "sqlite3_test_errstr $code" $english
  incr test_number
}

# Test the error message when a "real" out of memory occurs.
if {[info command sqlite3_memdebug_fail]!=""} {

  do_test capi3-10-1 {
    sqlite3 db test.db
    set DB [sqlite3_connection_pointer db]

    sqlite3_memdebug_fail 0 0
    catchsql {
      select * from sqlite_master;
    }
  } {1 {out of memory}}
  do_test capi3-10-2 {
    sqlite3_errmsg $::DB
  } {out of memory}
  ifcapable {utf16} {
    do_test capi3-10-3 {
      utf8 [sqlite3_errmsg16 $::DB]
    } {out of memory}
  }
  db close

  sqlite3_memdebug_fail -1 0
}

# The following tests - capi3-11.* - test that a COMMIT or ROLLBACK
# statement issued while there are still outstanding VMs that are part of
# the transaction fails.
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]

Changes to test/capi3c.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
741
742
743
744
745
746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763
764
765
766
767

768
769
770
771
772
773
774
#
#***********************************************************************
# This file implements regression tests for SQLite library.  
#
# This is a copy of the capi3.test file that has been adapted to
# test the new sqlite3_prepare_v2 interface.
#
# $Id: capi3c.test,v 1.9 2007/07/19 22:30:19 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
set test_number 1
foreach {code english} $code2english {
  do_test capi3c-9.$test_number "sqlite3_test_errstr $code" $english
  incr test_number
}

# Test the error message when a "real" out of memory occurs.
if {[info command sqlite_malloc_stat]!=""} {
set sqlite_malloc_fail 1
do_test capi3c-10-1 {
  sqlite3 db test.db
  set DB [sqlite3_connection_pointer db]
  sqlite_malloc_fail 1

  catchsql {
    select * from sqlite_master;
  }
} {1 {out of memory}}
do_test capi3c-10-2 {
  sqlite3_errmsg $::DB
} {out of memory}
ifcapable {utf16} {
  do_test capi3c-10-3 {
    utf8 [sqlite3_errmsg16 $::DB]
  } {out of memory}
}
db close
sqlite_malloc_fail 0

}

# The following tests - capi3c-11.* - test that a COMMIT or ROLLBACK
# statement issued while there are still outstanding VMs that are part of
# the transaction fails.
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]







|







 







|
<
|
|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
741
742
743
744
745
746
747
748

749
750
751

752
753
754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773
#
#***********************************************************************
# This file implements regression tests for SQLite library.  
#
# This is a copy of the capi3.test file that has been adapted to
# test the new sqlite3_prepare_v2 interface.
#
# $Id: capi3c.test,v 1.10 2007/08/25 13:37:49 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
set test_number 1
foreach {code english} $code2english {
  do_test capi3c-9.$test_number "sqlite3_test_errstr $code" $english
  incr test_number
}

# Test the error message when a "real" out of memory occurs.
if {[info command sqlite3_memdebug_fail]!=""} {

  do_test capi3c-10-1 {
    sqlite3 db test.db
    set DB [sqlite3_connection_pointer db]

    sqlite3_memdebug_fail 0 0
    catchsql {
      select * from sqlite_master;
    }
  } {1 {out of memory}}
  do_test capi3c-10-2 {
    sqlite3_errmsg $::DB
  } {out of memory}
  ifcapable {utf16} {
    do_test capi3c-10-3 {
      utf8 [sqlite3_errmsg16 $::DB]
    } {out of memory}
  }
  db close

  sqlite3_memdebug_fail -1 0
}

# The following tests - capi3c-11.* - test that a COMMIT or ROLLBACK
# statement issued while there are still outstanding VMs that are part of
# the transaction fails.
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]

Changes to test/fuzz_malloc.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
..
89
90
91
92
93
94
95
96
97
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file tests malloc failures in concert with fuzzy SQL generation.
#
# $Id: fuzz_malloc.test,v 1.5 2007/06/18 12:22:43 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {
  puts "Skipping fuzz_malloc tests: not compiled with -DSQLITE_MEMDEBUG=1"
  finish_test
  return
}

source $testdir/fuzz_common.tcl
source $testdir/malloc_common.tcl

if {[info exists ISQUICK]} {
  set ::REPEATS 20
} elseif {[info exists SOAKTEST]} {
  set ::REPEATS 100
} else {
  set ::REPEATS 40
................................................................................
#     -repeats
#     
proc do_fuzzy_malloc_test {testname args} {
  set ::fuzzyopts(-repeats) $::REPEATS
  set ::fuzzyopts(-sqlprep) {}
  array set ::fuzzyopts $args

  sqlite_malloc_fail 0
  db close
  file delete test.db test.db-journal
  sqlite3 db test.db
  set ::prep $::fuzzyopts(-sqlprep)
  execsql $::prep
  set jj 0
  for {set ii 0} {$ii < $::fuzzyopts(-repeats)} {incr ii} {
................................................................................
set ::TableList  [list abc def ghi]
set ::ColumnList [list a b c]

do_fuzzy_malloc_test fuzzy_malloc-3 \
  -template {[Select]}              \
  -sqlprep $::SQLPREP

sqlite_malloc_fail 0
finish_test







|




|
<
<
<
<
<
<
<

<







 







|







 







|

8
9
10
11
12
13
14
15
16
17
18
19
20







21

22
23
24
25
26
27
28
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
81
82
83
84
85
86
87
88
89
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file tests malloc failures in concert with fuzzy SQL generation.
#
# $Id: fuzz_malloc.test,v 1.6 2007/08/25 13:37:49 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

source $testdir/malloc_common.tcl







source $testdir/fuzz_common.tcl


if {[info exists ISQUICK]} {
  set ::REPEATS 20
} elseif {[info exists SOAKTEST]} {
  set ::REPEATS 100
} else {
  set ::REPEATS 40
................................................................................
#     -repeats
#     
proc do_fuzzy_malloc_test {testname args} {
  set ::fuzzyopts(-repeats) $::REPEATS
  set ::fuzzyopts(-sqlprep) {}
  array set ::fuzzyopts $args

  sqlite3_memdebug_fail -1 0
  db close
  file delete test.db test.db-journal
  sqlite3 db test.db
  set ::prep $::fuzzyopts(-sqlprep)
  execsql $::prep
  set jj 0
  for {set ii 0} {$ii < $::fuzzyopts(-repeats)} {incr ii} {
................................................................................
set ::TableList  [list abc def ghi]
set ::ColumnList [list a b c]

do_fuzzy_malloc_test fuzzy_malloc-3 \
  -template {[Select]}              \
  -sqlprep $::SQLPREP

sqlite3_memdebug_fail -1 0
finish_test

Changes to test/shared_err.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.11 2007/04/06 01:04:40 drh Exp $

proc skip {args} {}


set testdir [file dirname $argv0]
source $testdir/tester.tcl

db close

ifcapable !shared_cache||!subquery {
  finish_test
  return
}
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]

# Todo: This is a copy of the [do_malloc_test] proc in malloc.test
# It would be better if these were consolidated.

# Usage: do_malloc_test <test number> <options...>
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
#     -tclprep          TCL script to run to prepare test.
#     -sqlprep          SQL script to run to prepare test.
#     -tclbody          TCL script to run with malloc failure simulation.
#     -sqlbody          TCL script to run with malloc failure simulation.
#     -cleanup          TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
  array unset ::mallocopts 
  array set ::mallocopts $args

  set ::go 1
  for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
    do_test shared_malloc-$tn.$::n {

      # Remove all traces of database files test.db and test2.db from the files
      # system. Then open (empty database) "test.db" with the handle [db].
      # 
      sqlite_malloc_fail 0
      catch {db close} 
      catch {file delete -force test.db}
      catch {file delete -force test.db-journal}
      catch {file delete -force test2.db}
      catch {file delete -force test2.db-journal}
      catch {sqlite3 db test.db} 
      set ::DB [sqlite3_connection_pointer db]

      # Execute any -tclprep and -sqlprep scripts.
      #
      if {[info exists ::mallocopts(-tclprep)]} {
        eval $::mallocopts(-tclprep)
      }
      if {[info exists ::mallocopts(-sqlprep)]} {
        execsql $::mallocopts(-sqlprep)
      }

      # Now set the ${::n}th malloc() to fail and execute the -tclbody and
      # -sqlbody scripts.
      #
      sqlite_malloc_fail $::n
      set ::mallocbody {}
      if {[info exists ::mallocopts(-tclbody)]} {
        append ::mallocbody "$::mallocopts(-tclbody)\n"
      }
      if {[info exists ::mallocopts(-sqlbody)]} {
        append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
      }
      set v [catch $::mallocbody msg]

      set leftover [lindex [sqlite_malloc_stat] 2]
      if {$leftover>0} {
        if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
        set ::go 0
        if {$v} {
          puts "\nError message returned: $msg"
        } else {
          set v {1 1}
        }
      } else {
        set v2 [expr {$msg=="" || $msg=="out of memory"}]
        if {!$v2} {puts "\nError message returned: $msg"}
        lappend v $v2
      }
    } {1 1}

    sqlite_malloc_fail 0
    if {[info exists ::mallocopts(-cleanup)]} {
      catch [list uplevel #0 $::mallocopts(-cleanup)] msg
    }
  }
  unset ::mallocopts
}



do_ioerr_test shared_ioerr-1 -tclprep {
  sqlite3 db2 test.db
  execsql {
    PRAGMA read_uncommitted = 1;
    CREATE TABLE t1(a,b,c);
    BEGIN;







|






>






<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30





























































































31
32
33
34
35
36
37
38
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.12 2007/08/25 13:37:49 danielk1977 Exp $

proc skip {args} {}


set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
db close

ifcapable !shared_cache||!subquery {
  finish_test
  return
}































































































set ::enable_shared_cache [sqlite3_enable_shared_cache 1]

do_ioerr_test shared_ioerr-1 -tclprep {
  sqlite3 db2 test.db
  execsql {
    PRAGMA read_uncommitted = 1;
    CREATE TABLE t1(a,b,c);
    BEGIN;

Changes to test/vtab_err.test.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
160
161
162
163
164
165
166
167

168
#
#    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.
#
#***********************************************************************
#
# $Id: vtab_err.test,v 1.5 2007/04/19 11:09:02 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {
  puts "Skipping vtab_err tests: not compiled with -DSQLITE_MEMDEBUG=1"
  finish_test
  return
}

ifcapable !vtab {
  finish_test
  return
}

# Usage: do_malloc_test <test number> <options...>
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
#     -tclprep          TCL script to run to prepare test.
#     -sqlprep          SQL script to run to prepare test.
#     -tclbody          TCL script to run with malloc failure simulation.
#     -sqlbody          TCL script to run with malloc failure simulation.
#     -cleanup          TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
  array unset ::mallocopts 
  array set ::mallocopts $args

  set ::go 1
  for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
    do_test $tn.$::n {

      # Remove all traces of database files test.db and test2.db from the files
      # system. Then open (empty database) "test.db" with the handle [db].
      # 
      sqlite_malloc_fail 0
      catch {db close} 
      catch {file delete -force test.db}
      catch {file delete -force test.db-journal}
      catch {file delete -force test2.db}
      catch {file delete -force test2.db-journal}
      catch {sqlite3 db test.db} 
      set ::DB [sqlite3_connection_pointer db]

      # Execute any -tclprep and -sqlprep scripts.
      #
      if {[info exists ::mallocopts(-tclprep)]} {
        eval $::mallocopts(-tclprep)
      }
      if {[info exists ::mallocopts(-sqlprep)]} {
        execsql $::mallocopts(-sqlprep)
      }

      # Now set the ${::n}th malloc() to fail and execute the -tclbody and
      # -sqlbody scripts.
      #
      sqlite_malloc_fail $::n
      set ::mallocbody {}
      if {[info exists ::mallocopts(-tclbody)]} {
        append ::mallocbody "$::mallocopts(-tclbody)\n"
      }
      if {[info exists ::mallocopts(-sqlbody)]} {
        append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
      }
      set v [catch $::mallocbody msg]

      # If the test fails (if $v!=0) and the database connection actually
      # exists, make sure the failure code is SQLITE_NOMEM.
      if {$v&&[info command db]=="db"&&[info exists ::mallocopts(-sqlbody)]} {
        if {[db errorcode]!=7 && $msg!="vtable constructor failed: e"} {
          set v 999
        }
      }

      set leftover [lindex [sqlite_malloc_stat] 2]
      if {$leftover>0} {
        if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
        set ::go 0
        if {$v} {
          puts "\nError message returned: $msg"
        } else {
          set v {1 1}
        }
      } else {
        set v2 [expr {
          $msg == "" || $msg == "out of memory" || 
          $msg == "vtable constructor failed: e"
        }]
        if {!$v2} {puts "\nError message returned: $msg"}
        lappend v $v2
      }
    } {1 1}

    if {[info exists ::mallocopts(-cleanup)]} {
      catch [list uplevel #0 $::mallocopts(-cleanup)] msg
    }
  }
  unset ::mallocopts
}

unset -nocomplain echo_module_begin_fail
do_ioerr_test vtab_err-1 -tclprep {
  register_echo_module [sqlite3_connection_pointer db]
} -sqlbody {
  BEGIN;
  CREATE TABLE r(a PRIMARY KEY, b, c);
  CREATE VIRTUAL TABLE e USING echo(r);
................................................................................
  BEGIN;
    CREATE TABLE r2(a, b, c);
    INSERT INTO r2 SELECT * FROM e;
    INSERT INTO e SELECT a||'x', b, c FROM r2;
  COMMIT;
} 

sqlite_malloc_fail 0

finish_test







|




|
|
<
<
<
<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
>

5
6
7
8
9
10
11
12
13
14
15
16
17
18






19
20
21
22
23




































































































24
25
26
27
28
29
30
..
54
55
56
57
58
59
60
61
62
63
#
#    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.
#
#***********************************************************************
#
# $Id: vtab_err.test,v 1.6 2007/08/25 13:37:49 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

source $testdir/malloc_common.tcl







ifcapable !vtab {
  finish_test
  return
}





































































































unset -nocomplain echo_module_begin_fail
do_ioerr_test vtab_err-1 -tclprep {
  register_echo_module [sqlite3_connection_pointer db]
} -sqlbody {
  BEGIN;
  CREATE TABLE r(a PRIMARY KEY, b, c);
  CREATE VIRTUAL TABLE e USING echo(r);
................................................................................
  BEGIN;
    CREATE TABLE r2(a, b, c);
    INSERT INTO r2 SELECT * FROM e;
    INSERT INTO e SELECT a||'x', b, c FROM r2;
  COMMIT;
} 

sqlite3_memdebug_fail -1 0

finish_test