Documentation Source Text

Check-in [0d69a8d268]
Login

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

Overview
Comment:Updates to the testing document.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | branch-3.29
Files: files | file ages | folders
SHA3-256: 0d69a8d268a36ff11fb2de14df8110f46429a51d06e37b0734136be1fb29bc53
User & Date: drh 2019-07-16 13:44:52.459
Context
2019-08-05
12:55
Update the documentation on the affinity of the columns of VIEWs and subqueries that are generated from expressions to match the actual implementation of 10 years standing - namely such columns have BLOB affinity, not no affinity. Ticket https://www.sqlite.org/src/info/d52a29a9e6bc55c5 (check-in: 16a418966a user: drh tags: branch-3.29)
2019-07-16
13:44
Updates to the testing document. (check-in: 0d69a8d268 user: drh tags: branch-3.29)
2019-07-15
17:48
Minor typos fixes in the lemon documentation. (check-in: bd1181fb39 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to pages/testing.in.
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
# facilitate that, all the size values are defined by variables here
# which are then used as needed through the document.
#
# NOTE:  Also update the version number in the text!!!
#

# sloc sqlite3.c
set stat(coreSLOC)   128906  ;# Non-comment lines of amalgamation code 
# sloc test*.c
set stat(tclcSLOC)    26088  ;# Non-comment lines of test C code
# ls test*.c tclsqlite.c | wc
set stat(tclcNfile)      48  ;# Number of files of TCL C testcode + tclsqlite.c
# ls -l test*.c tclsqlite.c | awk '{sum+=$5}END{print sum}'
set stat(tclcNByte) 1212234  ;# Number of bytes of TCL C testcode + tclsqlite.c
# sloc `find . -name '*.test' -print` test/*.tcl
set stat(tclsSLOC)   462686  ;# Non-comment lines of TCL test script
# ls `find . -name '*.test' -print` test/*.tcl | wc
set stat(tclsNFile)    1307  ;# Number of files of TCL test script
# wc `find . -name '*.test' -print` test/*.tcl
set stat(tclsNByte) 16214472 ;# Number of bytes of TCL test script
# cat `find . -name '*.test' -print` | egrep 'do[_a-z]*_test' | wc
set stat(tclNTest)    40870  ;# Number of test cases in the TCL test suite
set stat(tclNEval)  2514125  ;# Number of test case evaluations (fulltest)
# grep fuzz device_one/test-out.txt | wc
set stat(nSqlFuzz)   111268  ;# Number of SQL fuzz tests
set stat(vqNEval)    142597  ;# Number of test evaluations for veryquick.test
#  set stat(vqStmtCov)   97.23  ;# veryquick statement coverage
#  set stat(vqBrCov)     92.57  ;# veryquick branch coverage
#  set stat(allStmtCov)  99.50  ;# all.test statement coverage
#  set stat(allBrCov)    97.41  ;# all.test condition/decision coverage
# tclsh mkth3.tcl cfg/*.cfg */*.test >th3.c; sloc th3.c
set stat(th3SLOC)    792338  ;# Non-comment lines in full th3.c
# ls -l th3.c
set stat(th3NByte) 57927541  ;# Number of bytes in full th3.c
# grep th3testCheck */*.test |wc
# grep '^--result' */*.test | wc
# grep '^--glob' */*.test | wc
# grep '^--notglob' */*.test | wc
# grep '^--eqp' */*.test | wc




set stat(th3NTest)      43049  ;# Number of test cases
# from output of a min.rc test run.
set stat(th3NECov)    1614390  ;# Number of test case evals for coverage
#set stat(th3NETest)  7247055  ;# Number of test case evaluations
#set stat(th3NEExt) 589175483  ;# Number of test case evals extended
#set stat(th3NERel) 2500000000 ;# Number of test case evals release
set stat(th3StmtCov) 100.00  ;# TH3 statement coverage
set stat(th3BrCov)   100.00  ;# TH3 branch coverage
# wc `find . -name '*.test'` | awk '{x+=$1}END{print x}'
set stat(sltsSLOC)  90489494 ;# Non-comment lines of SLT test script
# ls -l `find . -name '*.test'` | awk '{sum+=$5}END{print sum}'
set stat(sltsNByte) 1116800308 ;# Bytes of SLT test script
# find . -name '*.test' | wc
set stat(sltsNFile)        622 ;# Files of SLT test script
# sloc md5.c slt_*.c sqllogictest.c
set stat(sltcSLOC)        1404 ;# Non-comment lines of SLT C code
# grep '^query' `fossil ls | awk '/\.test$/{print $2}'` | wc
set stat(sltNTest)     7195342 ;# Number of test cases in SLT
# grep 'errors out of' all-out.txt | awk '{x+=$5}END{print x}'
set stat(sltNRun)     11879758 ;# Number of tests run in SLT
# grep 'assert(' sqlite3.c | wc
set stat(nAssert)         5415 ;# Number of assert statements
# grep 'testcase(' sqlite3.c | grep -v define | wc
set stat(nTestcase)        878 ;# Number of testcase statements

set stat(totalSLOC) [expr {$stat(tclcSLOC)+$stat(tclsSLOC)+
                           $stat(th3SLOC)+$stat(sltcSLOC)+$stat(sltsSLOC)}]

proc GB {expr} {
  set n [uplevel #0 expr $expr]
  hd_puts [format %.2f [expr {$n/(1000.0*1000.0*1000.0)}]]







|

|

|

|

|

|

|

|
|


|





|

|





>
>
>
>
|

|


















|

|







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
# facilitate that, all the size values are defined by variables here
# which are then used as needed through the document.
#
# NOTE:  Also update the version number in the text!!!
#

# sloc sqlite3.c
set stat(coreSLOC)   138858  ;# Non-comment lines of amalgamation code 
# sloc test*.c
set stat(tclcSLOC)    26873  ;# Non-comment lines of test C code
# ls test*.c tclsqlite.c | wc
set stat(tclcNfile)      50  ;# Number of files of TCL C testcode + tclsqlite.c
# ls -l test*.c tclsqlite.c | awk '{sum+=$5}END{print sum}'
set stat(tclcNByte) 1245032  ;# Number of bytes of TCL C testcode + tclsqlite.c
# sloc `find . -name '*.test' -print` test/*.tcl
set stat(tclsSLOC)   480305  ;# Non-comment lines of TCL test script
# ls `find . -name '*.test' -print` test/*.tcl | wc
set stat(tclsNFile)    1264  ;# Number of files of TCL test script
# wc `find . -name '*.test' -print` test/*.tcl
set stat(tclsNByte) 21545154 ;# Number of bytes of TCL test script
# cat `find . -name '*.test' -print` | egrep 'do[_a-z]*_test' | wc
set stat(tclNTest)    44792  ;# Number of test cases in the TCL test suite
set stat(tclNEval) 11291041  ;# Number of test case evaluations (releasetest)
# grep fuzz device_one/test-out.txt | wc
set stat(nSqlFuzz)   111268  ;# Number of SQL fuzz tests
set stat(vqNEval)    248537  ;# Number of test evaluations for veryquick.test
#  set stat(vqStmtCov)   97.23  ;# veryquick statement coverage
#  set stat(vqBrCov)     92.57  ;# veryquick branch coverage
#  set stat(allStmtCov)  99.50  ;# all.test statement coverage
#  set stat(allBrCov)    97.41  ;# all.test condition/decision coverage
# tclsh mkth3.tcl cfg/*.cfg */*.test >th3.c; sloc th3.c
set stat(th3SLOC)    948149  ;# Non-comment lines in full th3.c
# ls -l th3.c
set stat(th3NByte) 69393976  ;# Number of bytes in full th3.c
# grep th3testCheck */*.test |wc
# grep '^--result' */*.test | wc
# grep '^--glob' */*.test | wc
# grep '^--notglob' */*.test | wc
# grep '^--eqp' */*.test | wc
# grep '^--tableresult' */*.test | wc
# grep '^--anyglob' */*.test | wc
# grep '^--sort-check' */*.test | wc
# grep '^--cklog' */*.test | wc
set stat(th3NTest)      44753  ;# Number of test cases
# from output of a min.rc test run.
set stat(th3NECov)    1683889  ;# Number of test case evals for coverage
#set stat(th3NETest)  7247055  ;# Number of test case evaluations
#set stat(th3NEExt) 589175483  ;# Number of test case evals extended
#set stat(th3NERel) 2500000000 ;# Number of test case evals release
set stat(th3StmtCov) 100.00  ;# TH3 statement coverage
set stat(th3BrCov)   100.00  ;# TH3 branch coverage
# wc `find . -name '*.test'` | awk '{x+=$1}END{print x}'
set stat(sltsSLOC)  90489494 ;# Non-comment lines of SLT test script
# ls -l `find . -name '*.test'` | awk '{sum+=$5}END{print sum}'
set stat(sltsNByte) 1116800308 ;# Bytes of SLT test script
# find . -name '*.test' | wc
set stat(sltsNFile)        622 ;# Files of SLT test script
# sloc md5.c slt_*.c sqllogictest.c
set stat(sltcSLOC)        1404 ;# Non-comment lines of SLT C code
# grep '^query' `fossil ls | awk '/\.test$/{print $2}'` | wc
set stat(sltNTest)     7195342 ;# Number of test cases in SLT
# grep 'errors out of' all-out.txt | awk '{x+=$5}END{print x}'
set stat(sltNRun)     11879758 ;# Number of tests run in SLT
# grep 'assert(' sqlite3.c | wc
set stat(nAssert)         5665 ;# Number of assert statements
# grep 'testcase(' sqlite3.c | grep -v define | wc
set stat(nTestcase)        992 ;# Number of testcase statements

set stat(totalSLOC) [expr {$stat(tclcSLOC)+$stat(tclsSLOC)+
                           $stat(th3SLOC)+$stat(sltcSLOC)+$stat(sltsSLOC)}]

proc GB {expr} {
  set n [uplevel #0 expr $expr]
  hd_puts [format %.2f [expr {$n/(1000.0*1000.0*1000.0)}]]
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
</tcl>

<h1>Introduction</h1>

<p>The reliability and robustness of SQLite is achieved in part
by thorough and careful testing.</p>

<p>As of [version 3.23.0] ([dateof:3.23.0]),
the SQLite library consists of approximately
<tcl>KB {$stat(coreSLOC)}</tcl> KSLOC of C code.
(KSLOC means thousands of "Source Lines Of Code" or, in other words,
lines of code excluding blank lines and comments.)
By comparison, the project has
<tcl>
hd_puts "[expr {int($stat(totalSLOC)/$stat(coreSLOC))}] times as much"







|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
</tcl>

<h1>Introduction</h1>

<p>The reliability and robustness of SQLite is achieved in part
by thorough and careful testing.</p>

<p>As of [version 3.29.0] ([dateof:3.29.0]),
the SQLite library consists of approximately
<tcl>KB {$stat(coreSLOC)}</tcl> KSLOC of C code.
(KSLOC means thousands of "Source Lines Of Code" or, in other words,
lines of code excluding blank lines and comments.)
By comparison, the project has
<tcl>
hd_puts "[expr {int($stat(totalSLOC)/$stat(coreSLOC))}] times as much"
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
result.</p>

<p>The SQL fuzz generator tests are part of the TCL test suite.
During a full test run, about <tcl>KB {$stat(nSqlFuzz)}</tcl> 
thousand fuzz SQL statements are
generated and tested.</p>

<tcl>hd_fragment aflfuzz {American Fuzzy Lop fuzzer}</tcl>
<h3>SQL Fuzz Using The American Fuzzy Lop Fuzzer</h3>

<p>The <a href="http://lcamtuf.coredump.cx/afl/">American Fuzzy Lop</a>
or "AFL" fuzzer is a recent (circa 2014) innovation from Michal Zalewski.
Unlike most other fuzzers that blindly generate random inputs, the AFL
fuzzer instruments the program being tested (by modifying the assembly-language
output from the C compiler) and uses that instrumentation to detect when







|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
result.</p>

<p>The SQL fuzz generator tests are part of the TCL test suite.
During a full test run, about <tcl>KB {$stat(nSqlFuzz)}</tcl> 
thousand fuzz SQL statements are
generated and tested.</p>

<tcl>hd_fragment aflfuzz {American Fuzzy Lop fuzzer} {AFL}</tcl>
<h3>SQL Fuzz Using The American Fuzzy Lop Fuzzer</h3>

<p>The <a href="http://lcamtuf.coredump.cx/afl/">American Fuzzy Lop</a>
or "AFL" fuzzer is a recent (circa 2014) innovation from Michal Zalewski.
Unlike most other fuzzers that blindly generate random inputs, the AFL
fuzzer instruments the program being tested (by modifying the assembly-language
output from the C compiler) and uses that instrumentation to detect when
398
399
400
401
402
403
404



405
406
407
408
409
410
411
412
413
414
415
416
417
418




































419
420
421
422
423
424
425
Both SQL statements and database files are fuzzed.
Billions and billions of mutations have been tried, but AFL's 
instrumentation has narrowed them down to less than 50,000 test cases that
cover all distinct behaviors.  Newly discovered test cases are periodically
captured and added to the [TCL test suite] where they can be rerun using
the "make fuzztest" or "make valgrindfuzz" commands.




<tcl>hd_fragment ossfuzz {OSS Fuzz}</tcl>
<h3>Google OSS Fuzz</h3>

<p>Beginning in 2016, a team of engineers at Google started the
[https://github.com/google/oss-fuzz|OSS Fuzz] project.  
OSS Fuzz uses a AFL-style guided fuzzer running on Google's infrastructure.
The Fuzzer automatically downloads the latest check-ins for participating
projects, fuzzes them, and sends email to the developers reporting any
problems.  When a fix is checked in, the fuzzer automatically detects this
and emails a confirmation to the developers.

<p>SQLite is one of many open-source projects that OSS Fuzz tests. The
[https://www.sqlite.org/src/file/test/ossfuzz.c|test/ossfuzz.c] source file
in the SQLite repository is SQLite's interface to OSS fuzz.





































<h2>Malformed Database Files</h2>

<p>There are numerous test cases that verify that SQLite is able to
deal with malformed database files.
These tests first build a well-formed database file, then add
corruption by changing one or more bytes in the file by some means







>
>
>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
Both SQL statements and database files are fuzzed.
Billions and billions of mutations have been tried, but AFL's 
instrumentation has narrowed them down to less than 50,000 test cases that
cover all distinct behaviors.  Newly discovered test cases are periodically
captured and added to the [TCL test suite] where they can be rerun using
the "make fuzztest" or "make valgrindfuzz" commands.

<p>Update:  As of SQLite [version 3.29.0] ([dateof:3.29.0]) the use of
AFL has been superceded by the new [dbsqlfuzz] fuzzer described below.

<tcl>hd_fragment ossfuzz {OSS Fuzz}</tcl>
<h3>Google OSS Fuzz</h3>

<p>Beginning in 2016, a team of engineers at Google started the
[https://github.com/google/oss-fuzz|OSS Fuzz] project.  
OSS Fuzz uses a AFL-style guided fuzzer running on Google's infrastructure.
The Fuzzer automatically downloads the latest check-ins for participating
projects, fuzzes them, and sends email to the developers reporting any
problems.  When a fix is checked in, the fuzzer automatically detects this
and emails a confirmation to the developers.

<p>SQLite is one of many open-source projects that OSS Fuzz tests. The
[https://www.sqlite.org/src/file/test/ossfuzz.c|test/ossfuzz.c] source file
in the SQLite repository is SQLite's interface to OSS fuzz.

<tcl>hd_fragment dbsqlfuzz {dbsqlfuzz}</tcl>
<h3>The dbsqlfuzz fuzzer</h3>

<p>Beginning in late 2018, SQLite has been fuzzed using a new proprietary
fuzzer called "dbsqlfuzz".  Dbsqlfuzz is built using the 
[http://llvm.org/docs/LibFuzzer.html|libFuzzer] framework of LLVM.

<p>The dbsqlfuzz fuzzer mutates both the SQL input and the database file
at the same time.  Dbsqlfuzz uses a custom
[https://github.com/google/fuzzer-test-suite/blob/master/tutorial/structure-aware-fuzzing.md|Structure-Aware Mutator]
on a specialized input file that defines both an input database and SQL
text to be run against that database. Because it mutates both the input
database and the input SQL at the same time, dbsqlfuzz has been able to
find some obscure faults in SQLite that were missed by prior fuzzers that
mutated only SQL inputs or only the database file.

<p>As of this writing (2019-07-16), the SQLite developers have stopped
using AFL for routine testing and instead are focused on running
dbsqlfuzz.  At least one instance of dbsqlfuzz is running on the latest
SQLite source code at all times, in order to catch any new problems that 
might be introduced into the source tree as features are added and routine
maintenance is performed.

<tcl>hd_fragment fuzzcheck fuzzcheck</tcl>
<h3>The fuzzcheck test harness</h3>

<p>Historical test cases from [AFL], [OSS Fuzz], and [dbsqlfuzz] are
collected in a set of database files in the main SQLite source tree
and then rerun by the "fuzzcheck" utility program whenever one runs
"make test".  Fuzzcheck only runs a few thousand "interesting" cases
out of the hundreds of millions of cases that the various fuzzers have
examined over the years.  "Interesting" cases are cases that exhibit
previously unseen behavior.  Actual bugs found by fuzzers are always
included among the interesting test cases, but most of the cases run
by fuzzcheck were never actual bugs. 

<h2>Malformed Database Files</h2>

<p>There are numerous test cases that verify that SQLite is able to
deal with malformed database files.
These tests first build a well-formed database file, then add
corruption by changing one or more bytes in the file by some means
814
815
816
817
818
819
820



821
822
823
824
825
826
827
<p>Assert() macros are disabled by compiling with the NDEBUG macro defined.
In most systems, asserts are enabled by default.  But in SQLite, the
asserts are so numerous and are in such performance critical places, that
the database engine runs about three times slower when asserts are enabled.
Hence, the default (production) build of SQLite disables asserts.  
Assert statements are only enabled when SQLite is compiled with the
SQLITE_DEBUG preprocessor macro defined.</p>




<tcl>hd_fragment valgrind</tcl>
<h2>Valgrind</h2>

<p>[http://valgrind.org/ | Valgrind] is perhaps the most amazing
and useful developer tool in the world.  Valgrind is a simulator - it simulates
an x86 running a Linux binary.  (Ports of Valgrind for platforms other







>
>
>







857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
<p>Assert() macros are disabled by compiling with the NDEBUG macro defined.
In most systems, asserts are enabled by default.  But in SQLite, the
asserts are so numerous and are in such performance critical places, that
the database engine runs about three times slower when asserts are enabled.
Hence, the default (production) build of SQLite disables asserts.  
Assert statements are only enabled when SQLite is compiled with the
SQLITE_DEBUG preprocessor macro defined.</p>

<p>See the [The Use Of assert In SQLite|Use Of assert in SQLite] document
for additional information about how SQLite uses assert().</p>b

<tcl>hd_fragment valgrind</tcl>
<h2>Valgrind</h2>

<p>[http://valgrind.org/ | Valgrind] is perhaps the most amazing
and useful developer tool in the world.  Valgrind is a simulator - it simulates
an x86 running a Linux binary.  (Ports of Valgrind for platforms other