~ubuntu-branches/ubuntu/hardy/sqlite3/hardy

« back to all changes in this revision

Viewing changes to test/vtab_err.test

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2006-10-12 21:55:37 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20061012215537-mgvrxoq8ee4nqxzh
Tags: 3.3.8-1
* New upstream version.
* Create lang_* files for documentation (closes: #310603).
* Enable column metadata functions (closes: #375352).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# 2006 June 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
# $Id: vtab_err.test,v 1.3 2006/08/15 14:21:16 drh Exp $
 
13
 
 
14
set testdir [file dirname $argv0]
 
15
source $testdir/tester.tcl
 
16
 
 
17
ifcapable !vtab {
 
18
  finish_test
 
19
  return
 
20
}
 
21
 
 
22
# Usage: do_malloc_test <test number> <options...>
 
23
#
 
24
# The first argument, <test number>, is an integer used to name the
 
25
# tests executed by this proc. Options are as follows:
 
26
#
 
27
#     -tclprep          TCL script to run to prepare test.
 
28
#     -sqlprep          SQL script to run to prepare test.
 
29
#     -tclbody          TCL script to run with malloc failure simulation.
 
30
#     -sqlbody          TCL script to run with malloc failure simulation.
 
31
#     -cleanup          TCL script to run after the test.
 
32
#
 
33
# This command runs a series of tests to verify SQLite's ability
 
34
# to handle an out-of-memory condition gracefully. It is assumed
 
35
# that if this condition occurs a malloc() call will return a
 
36
# NULL pointer. Linux, for example, doesn't do that by default. See
 
37
# the "BUGS" section of malloc(3).
 
38
#
 
39
# Each iteration of a loop, the TCL commands in any argument passed
 
40
# to the -tclbody switch, followed by the SQL commands in any argument
 
41
# passed to the -sqlbody switch are executed. Each iteration the
 
42
# Nth call to sqliteMalloc() is made to fail, where N is increased
 
43
# each time the loop runs starting from 1. When all commands execute
 
44
# successfully, the loop ends.
 
45
#
 
46
proc do_malloc_test {tn args} {
 
47
  array unset ::mallocopts 
 
48
  array set ::mallocopts $args
 
49
 
 
50
  set ::go 1
 
51
  for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
 
52
    do_test $tn.$::n {
 
53
 
 
54
      # Remove all traces of database files test.db and test2.db from the files
 
55
      # system. Then open (empty database) "test.db" with the handle [db].
 
56
      # 
 
57
      sqlite_malloc_fail 0
 
58
      catch {db close} 
 
59
      catch {file delete -force test.db}
 
60
      catch {file delete -force test.db-journal}
 
61
      catch {file delete -force test2.db}
 
62
      catch {file delete -force test2.db-journal}
 
63
      catch {sqlite3 db test.db} 
 
64
      set ::DB [sqlite3_connection_pointer db]
 
65
 
 
66
      # Execute any -tclprep and -sqlprep scripts.
 
67
      #
 
68
      if {[info exists ::mallocopts(-tclprep)]} {
 
69
        eval $::mallocopts(-tclprep)
 
70
      }
 
71
      if {[info exists ::mallocopts(-sqlprep)]} {
 
72
        execsql $::mallocopts(-sqlprep)
 
73
      }
 
74
 
 
75
      # Now set the ${::n}th malloc() to fail and execute the -tclbody and
 
76
      # -sqlbody scripts.
 
77
      #
 
78
      sqlite_malloc_fail $::n
 
79
      set ::mallocbody {}
 
80
      if {[info exists ::mallocopts(-tclbody)]} {
 
81
        append ::mallocbody "$::mallocopts(-tclbody)\n"
 
82
      }
 
83
      if {[info exists ::mallocopts(-sqlbody)]} {
 
84
        append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
 
85
      }
 
86
      set v [catch $::mallocbody msg]
 
87
 
 
88
      # If the test fails (if $v!=0) and the database connection actually
 
89
      # exists, make sure the failure code is SQLITE_NOMEM.
 
90
      if {$v&&[info command db]=="db"&&[info exists ::mallocopts(-sqlbody)]} {
 
91
        if {[db errorcode]!=7 && $msg!="vtable constructor failed: e"} {
 
92
          set v 999
 
93
        }
 
94
      }
 
95
 
 
96
      set leftover [lindex [sqlite_malloc_stat] 2]
 
97
      if {$leftover>0} {
 
98
        if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
 
99
        set ::go 0
 
100
        if {$v} {
 
101
          puts "\nError message returned: $msg"
 
102
        } else {
 
103
          set v {1 1}
 
104
        }
 
105
      } else {
 
106
        set v2 [expr {
 
107
          $msg == "" || $msg == "out of memory" || 
 
108
          $msg == "vtable constructor failed: e"
 
109
        }]
 
110
        if {!$v2} {puts "\nError message returned: $msg"}
 
111
        lappend v $v2
 
112
      }
 
113
    } {1 1}
 
114
 
 
115
    if {[info exists ::mallocopts(-cleanup)]} {
 
116
      catch [list uplevel #0 $::mallocopts(-cleanup)] msg
 
117
    }
 
118
  }
 
119
  unset ::mallocopts
 
120
}
 
121
 
 
122
unset -nocomplain echo_module_begin_fail
 
123
do_ioerr_test vtab_err-1 -tclprep {
 
124
  register_echo_module [sqlite3_connection_pointer db]
 
125
} -sqlbody {
 
126
  BEGIN;
 
127
  CREATE TABLE r(a PRIMARY KEY, b, c);
 
128
  CREATE VIRTUAL TABLE e USING echo(r);
 
129
  INSERT INTO e VALUES(1, 2, 3);
 
130
  INSERT INTO e VALUES('a', 'b', 'c');
 
131
  UPDATE e SET c = 10;
 
132
  DELETE FROM e WHERE a = 'a';
 
133
  COMMIT;
 
134
  BEGIN;
 
135
    CREATE TABLE r2(a, b, c);
 
136
    INSERT INTO r2 SELECT * FROM e;
 
137
    INSERT INTO e SELECT a||'x', b, c FROM r2;
 
138
  COMMIT;
 
139
}
 
140
 
 
141
 
 
142
do_malloc_test vtab_err-2 -tclprep {
 
143
  register_echo_module [sqlite3_connection_pointer db]
 
144
} -sqlbody {
 
145
  BEGIN;
 
146
  CREATE TABLE r(a PRIMARY KEY, b, c);
 
147
  CREATE VIRTUAL TABLE e USING echo(r);
 
148
  INSERT INTO e VALUES(1, 2, 3);
 
149
  INSERT INTO e VALUES('a', 'b', 'c');
 
150
  UPDATE e SET c = 10;
 
151
  DELETE FROM e WHERE a = 'a';
 
152
  COMMIT;
 
153
  BEGIN;
 
154
    CREATE TABLE r2(a, b, c);
 
155
    INSERT INTO r2 SELECT * FROM e;
 
156
    INSERT INTO e SELECT a||'x', b, c FROM r2;
 
157
  COMMIT;
 
158
 
159
 
 
160
sqlite_malloc_fail 0
 
161
finish_test