summaryrefslogtreecommitdiff
path: root/tool/omittest.tcl
blob: 7f13a4cbe3536235b4d1510d946d5e2674f0511f (plain)
1
2
3
4
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

set rcsid {$Id: omittest.tcl,v 1.8 2008/10/13 15:35:09 drh Exp $}

# Documentation for this script. This may be output to stderr
# if the script is invoked incorrectly.
set ::USAGE_MESSAGE {
This Tcl script is used to test the various compile time options 
available for omitting code (the SQLITE_OMIT_xxx options). It
should be invoked as follows:

    <script> ?test-symbol? ?-makefile PATH-TO-MAKEFILE? ?-skip_run?

The default value for ::MAKEFILE is "../Makefile.linux.gcc".

If -skip_run option is given then only the compile part is attempted.

This script builds the testfixture program and runs the SQLite test suite
once with each SQLITE_OMIT_ option defined and then once with all options
defined together. Each run is performed in a seperate directory created
as a sub-directory of the current directory by the script. The output
of the build is saved in <sub-directory>/build.log. The output of the
test-suite is saved in <sub-directory>/test.log.

Almost any SQLite makefile (except those generated by configure - see below)
should work. The following properties are required:

  * The makefile should support the "testfixture" target.
  * The makefile should support the "test" target.
  * The makefile should support the variable "OPTS" as a way to pass
    options from the make command line to lemon and the C compiler.

More precisely, the following two invocations must be supported:

  $::MAKEBIN -f $::MAKEFILE testfixture OPTS="-DSQLITE_OMIT_ALTERTABLE=1"
  $::MAKEBIN -f $::MAKEFILE test

Makefiles generated by the sqlite configure program cannot be used as
they do not respect the OPTS variable.
}


# Build a testfixture executable and run quick.test using it. The first
# parameter is the name of the directory to create and use to run the
# test in. The second parameter is a list of OMIT symbols to define
# when doing so. For example:
#
#     run_quick_test /tmp/testdir {SQLITE_OMIT_TRIGGER SQLITE_OMIT_VIEW}
#
#
proc run_quick_test {dir omit_symbol_list} {
  # Compile the value of the OPTS Makefile variable.
  set opts ""
  if {$::tcl_platform(platform)=="windows"} {
    append opts "OPTS += -DSQLITE_OS_WIN=1\n"
    set target "testfixture.exe"
  } elseif {$::tcl_platform(platform)=="os2"} {
    append opts "OPTS += -DSQLITE_OS_OS2=1\n"
  } else {
    append opts "OPTS += -DSQLITE_OS_UNIX=1\n"
  }
  foreach sym $omit_symbol_list {
    append opts "OPTS += -D${sym}=1\n"
  }

  # Create the directory and do the build. If an error occurs return
  # early without attempting to run the test suite.
  file mkdir $dir
  puts -nonewline "Building $dir..."
  flush stdout
  catch {
    file copy -force ./config.h $dir
    file copy -force ./libtool $dir
  }
  set fd [open $::MAKEFILE]
  set mkfile [read $fd]
  close $fd
  regsub {\ninclude} $mkfile "\n$opts\ninclude" mkfile
  set fd [open $dir/makefile w]
  puts $fd $mkfile
  close $fd
  
  set rc [catch {
    exec $::MAKEBIN -C $dir -f makefile clean $::TARGET >& $dir/build.log
  }]
  if {$rc} {
    puts "No good. See $dir/build.log."
    return
  } else {
    puts "Ok"
  }
  
  # Create an empty file "$dir/sqlite3". This is to trick the makefile out 
  # of trying to build the sqlite shell. The sqlite shell won't build 
  # with some of the OMIT options (i.e OMIT_COMPLETE).
  set sqlite3_dummy $dir/sqlite3
  if {$::tcl_platform(platform)=="windows" || $::tcl_platform(platform)=="os2"} {
    append sqlite3_dummy ".exe"
  }
  if {![file exists $sqlite3_dummy]} {
    set wr [open $sqlite3_dummy w]
    puts $wr "dummy"
    close $wr
  }

  if {$::SKIP_RUN} {
      puts "Skip testing $dir."
  } else {
    # Run the test suite.
    puts -nonewline "Testing $dir..."
    flush stdout
    set rc [catch {
      exec $::MAKEBIN -C $dir -f makefile test >& $dir/test.log
    }]
    if {$rc} {
      puts "No good. See $dir/test.log."
    } else {
      puts "Ok"
    }
  }
}


# This proc processes the command line options passed to this script.
# Currently the only option supported is "-makefile", default
# "../Makefile.linux-gcc". Set the ::MAKEFILE variable to the value of this
# option.
#
proc process_options {argv} {
  set ::MAKEBIN make                        ;# Default value
  if {$::tcl_platform(platform)=="windows" || $::tcl_platform(platform)=="os2"} {
    set ::MAKEFILE ./Makefile               ;# Default value on Windows and OS2
  } else {
    set ::MAKEFILE ./Makefile.linux-gcc     ;# Default value
  }
  set ::SKIP_RUN 0                          ;# Default to attempt test
  set ::TARGET testfixture                  ;# Default thing to build

  for {set i 0} {$i < [llength $argv]} {incr i} {
    switch -- [lindex $argv $i] {
      -makefile {
        incr i
        set ::MAKEFILE [lindex $argv $i]
      }
  
      -nmake {
        set ::MAKEBIN nmake
        set ::MAKEFILE ./Makefile.msc
      }

      -target {
        incr i
        set ::TARGET [lindex $argv $i]
      }

      -skip_run {
        set ::SKIP_RUN 1
      }

      default {
        if {[info exists ::SYMBOL]} {
          puts stderr [string trim $::USAGE_MESSAGE]
          exit -1
        }
        set ::SYMBOL [lindex $argv $i]
      }
    }
    set ::MAKEFILE [file normalize $::MAKEFILE]
  }
}

# Main routine.
#

proc main {argv} {
  # List of SQLITE_OMIT_XXX symbols supported by SQLite.
  set ::OMIT_SYMBOLS [list \
    SQLITE_OMIT_ALTERTABLE \
    SQLITE_OMIT_ANALYZE \
    SQLITE_OMIT_ATTACH \
    SQLITE_OMIT_AUTHORIZATION \
    SQLITE_OMIT_AUTOINCREMENT \
    SQLITE_OMIT_AUTOINIT \
    SQLITE_OMIT_AUTOMATIC_INDEX \
    SQLITE_OMIT_AUTORESET \
    SQLITE_OMIT_AUTOVACUUM \
    SQLITE_OMIT_BETWEEN_OPTIMIZATION \
    SQLITE_OMIT_BLOB_LITERAL \
    SQLITE_OMIT_BTREECOUNT \
    SQLITE_OMIT_BUILTIN_TEST \
    SQLITE_OMIT_CAST \
    SQLITE_OMIT_CHECK \
    SQLITE_OMIT_COMPILEOPTION_DIAGS \
    SQLITE_OMIT_COMPLETE \
    SQLITE_OMIT_COMPOUND_SELECT \
    SQLITE_OMIT_DATETIME_FUNCS \
    SQLITE_OMIT_DECLTYPE \
    SQLITE_OMIT_DEPRECATED \
    SQLITE_OMIT_EXPLAIN \
    SQLITE_OMIT_FLAG_PRAGMAS \
    SQLITE_OMIT_FLOATING_POINT \
    SQLITE_OMIT_FOREIGN_KEY \
    SQLITE_OMIT_GET_TABLE \
    SQLITE_OMIT_INCRBLOB \
    SQLITE_OMIT_INTEGRITY_CHECK \
    SQLITE_OMIT_LIKE_OPTIMIZATION \
    SQLITE_OMIT_LOAD_EXTENSION \
    SQLITE_OMIT_LOCALTIME \
    SQLITE_OMIT_LOOKASIDE \
    SQLITE_OMIT_MEMORYDB \
    SQLITE_OMIT_OR_OPTIMIZATION \
    SQLITE_OMIT_PAGER_PRAGMAS \
    SQLITE_OMIT_PRAGMA \
    SQLITE_OMIT_PROGRESS_CALLBACK \
    SQLITE_OMIT_QUICKBALANCE \
    SQLITE_OMIT_REINDEX \
    SQLITE_OMIT_SCHEMA_PRAGMAS \
    SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS \
    SQLITE_OMIT_SHARED_CACHE \
    SQLITE_OMIT_SUBQUERY \
    SQLITE_OMIT_TCL_VARIABLE \
    SQLITE_OMIT_TEMPDB \
    SQLITE_OMIT_TRACE \
    SQLITE_OMIT_TRIGGER \
    SQLITE_OMIT_TRUNCATE_OPTIMIZATION \
    SQLITE_OMIT_UNIQUE_ENFORCEMENT \
    SQLITE_OMIT_UTF16 \
    SQLITE_OMIT_VACUUM \
    SQLITE_OMIT_VIEW \
    SQLITE_OMIT_VIRTUALTABLE \
    SQLITE_OMIT_WAL \
    SQLITE_OMIT_WSD \
    SQLITE_OMIT_XFER_OPT \
  ]

  set ::ENABLE_SYMBOLS [list \
    SQLITE_DISABLE_DIRSYNC \
    SQLITE_DISABLE_LFS \
    SQLITE_ENABLE_ATOMIC_WRITE \
    SQLITE_ENABLE_COLUMN_METADATA \
    SQLITE_ENABLE_EXPENSIVE_ASSERT \
    SQLITE_ENABLE_FTS3 \
    SQLITE_ENABLE_FTS3_PARENTHESIS \
    SQLITE_ENABLE_FTS4 \
    SQLITE_ENABLE_IOTRACE \
    SQLITE_ENABLE_LOAD_EXTENSION \
    SQLITE_ENABLE_LOCKING_STYLE \
    SQLITE_ENABLE_MEMORY_MANAGEMENT \
    SQLITE_ENABLE_MEMSYS3 \
    SQLITE_ENABLE_MEMSYS5 \
    SQLITE_ENABLE_OVERSIZE_CELL_CHECK \
    SQLITE_ENABLE_RTREE \
    SQLITE_ENABLE_STAT3 \
    SQLITE_ENABLE_UNLOCK_NOTIFY \
    SQLITE_ENABLE_UPDATE_DELETE_LIMIT \
  ]

  # Process any command line options.
  process_options $argv

  if {[info exists ::SYMBOL] } {
    set sym $::SYMBOL

    if {[lsearch $::OMIT_SYMBOLS $sym]<0 && [lsearch $::ENABLE_SYMBOLS $sym]<0} {
      puts stderr "No such symbol: $sym"
      exit -1
    }

    set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
    run_quick_test $dirname $sym
  } else {
    # First try a test with all OMIT symbols except SQLITE_OMIT_FLOATING_POINT 
    # and SQLITE_OMIT_PRAGMA defined. The former doesn't work (causes segfaults)
    # and the latter is currently incompatible with the test suite (this should
    # be fixed, but it will be a lot of work).
    set allsyms [list]
    foreach s $::OMIT_SYMBOLS {
      if {$s!="SQLITE_OMIT_FLOATING_POINT" && $s!="SQLITE_OMIT_PRAGMA"} {
        lappend allsyms $s
      }
    }
    run_quick_test test_OMIT_EVERYTHING $allsyms
  
    # Now try one quick.test with each of the OMIT symbols defined. Included
    # are the OMIT_FLOATING_POINT and OMIT_PRAGMA symbols, even though we
    # know they will fail. It's good to be reminded of this from time to time.
    foreach sym $::OMIT_SYMBOLS {
      set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
      run_quick_test $dirname $sym
    }
  
    # Try the ENABLE/DISABLE symbols one at a time.  
    # We don't do them all at once since some are conflicting.
    foreach sym $::ENABLE_SYMBOLS {
      set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
      run_quick_test $dirname $sym
    }
  }
}

main $argv