/ Check-in [f0ed7146]
Login

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

Overview
Comment:If the library is built with SQLITE_VDBE_COVERAGE defined, have the Tcl tests generate a vdbe coverage report in file testdir/vdbe_coverage.txt.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f0ed714637bf30443d0551d9b6fececa00fc9dfe9669fe720c4598ef71c61e2c
User & Date: dan 2019-04-01 17:24:20
Context
2019-04-01
18:43
Add a test case to cover a missed VDBE branch generated by window.c. check-in: b36813d6 user: dan tags: trunk
17:24
If the library is built with SQLITE_VDBE_COVERAGE defined, have the Tcl tests generate a vdbe coverage report in file testdir/vdbe_coverage.txt. check-in: f0ed7146 user: dan tags: trunk
16:23
Frame range comparisons can never be NULL because the values will have been checked for NULL prior to the test. check-in: fa37cf9a user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   418    418     $(TOP)/src/test_schema.c \
   419    419     $(TOP)/src/test_server.c \
   420    420     $(TOP)/src/test_superlock.c \
   421    421     $(TOP)/src/test_syscall.c \
   422    422     $(TOP)/src/test_tclsh.c \
   423    423     $(TOP)/src/test_tclvar.c \
   424    424     $(TOP)/src/test_thread.c \
          425  +  $(TOP)/src/test_vdbecov.c \
   425    426     $(TOP)/src/test_vfs.c \
   426    427     $(TOP)/src/test_windirent.c \
   427    428     $(TOP)/src/test_window.c \
   428    429     $(TOP)/src/test_wsd.c       \
   429    430     $(TOP)/ext/fts3/fts3_term.c \
   430    431     $(TOP)/ext/fts3/fts3_test.c  \
   431    432     $(TOP)/ext/session/test_session.c \

Changes to Makefile.msc.

  1513   1513     $(TOP)\src\test_schema.c \
  1514   1514     $(TOP)\src\test_server.c \
  1515   1515     $(TOP)\src\test_superlock.c \
  1516   1516     $(TOP)\src\test_syscall.c \
  1517   1517     $(TOP)\src\test_tclsh.c \
  1518   1518     $(TOP)\src\test_tclvar.c \
  1519   1519     $(TOP)\src\test_thread.c \
         1520  +  $(TOP)\src\test_vdbecov.c \
  1520   1521     $(TOP)\src\test_vfs.c \
  1521   1522     $(TOP)\src\test_windirent.c \
  1522   1523     $(TOP)\src\test_window.c \
  1523   1524     $(TOP)\src\test_wsd.c \
  1524   1525     $(TOP)\ext\fts3\fts3_term.c \
  1525   1526     $(TOP)\ext\fts3\fts3_test.c \
  1526   1527     $(TOP)\ext\rbu\test_rbu.c \

Changes to main.mk.

   344    344     $(TOP)/src/test_server.c \
   345    345     $(TOP)/src/test_sqllog.c \
   346    346     $(TOP)/src/test_superlock.c \
   347    347     $(TOP)/src/test_syscall.c \
   348    348     $(TOP)/src/test_tclsh.c \
   349    349     $(TOP)/src/test_tclvar.c \
   350    350     $(TOP)/src/test_thread.c \
          351  +  $(TOP)/src/test_vdbecov.c \
   351    352     $(TOP)/src/test_vfs.c \
   352    353     $(TOP)/src/test_windirent.c \
   353    354     $(TOP)/src/test_window.c \
   354    355     $(TOP)/src/test_wsd.c
   355    356   
   356    357   # Extensions to be statically loaded.
   357    358   #

Changes to src/test_tclsh.c.

   102    102     extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
   103    103   #endif
   104    104   #ifdef SQLITE_ENABLE_ZIPVFS
   105    105     extern int Zipvfs_Init(Tcl_Interp*);
   106    106   #endif
   107    107     extern int TestExpert_Init(Tcl_Interp*);
   108    108     extern int Sqlitetest_window_Init(Tcl_Interp *);
          109  +  extern int Sqlitetestvdbecov_Init(Tcl_Interp *);
   109    110   
   110    111     Tcl_CmdInfo cmdInfo;
   111    112   
   112    113     /* Since the primary use case for this binary is testing of SQLite,
   113    114     ** be sure to generate core files if we crash */
   114    115   #if defined(unix)
   115    116     { struct rlimit x;
................................................................................
   167    168     Sqlitetesttcl_Init(interp);
   168    169   
   169    170   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
   170    171     Sqlitetestfts3_Init(interp);
   171    172   #endif
   172    173     TestExpert_Init(interp);
   173    174     Sqlitetest_window_Init(interp);
          175  +  Sqlitetestvdbecov_Init(interp);
   174    176   
   175    177     Tcl_CreateObjCommand(
   176    178         interp, "load_testfixture_extensions", load_testfixture_extensions,0,0
   177    179     );
   178    180     return 0;
   179    181   }
   180    182   

Added src/test_vdbecov.c.

            1  +/*
            2  +** 2019 April 02
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +*/
           14  +#if SQLITE_TEST          /* This file is used for testing only */
           15  +
           16  +#include "sqlite3.h"
           17  +#include "sqliteInt.h"
           18  +#if defined(INCLUDE_SQLITE_TCL_H)
           19  +#  include "sqlite_tcl.h"
           20  +#else
           21  +#  include "tcl.h"
           22  +#endif
           23  +
           24  +#ifdef SQLITE_VDBE_COVERAGE
           25  +
           26  +static u8 aBranchArray[200000];
           27  +
           28  +static void test_vdbe_branch(
           29  +  void *pCtx, 
           30  +  unsigned int iSrc, 
           31  +  unsigned char iBranch, 
           32  +  unsigned char iType
           33  +){
           34  +  if( iSrc<sizeof(aBranchArray) ){
           35  +    aBranchArray[iSrc] |= iBranch;
           36  +  }
           37  +}
           38  +
           39  +static void appendToList(Tcl_Obj *pList, int iLine, int iPath){
           40  +  Tcl_Obj *pNew = Tcl_NewObj();
           41  +  Tcl_IncrRefCount(pNew);
           42  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iLine));
           43  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iPath));
           44  +  Tcl_ListObjAppendElement(0, pList, pNew);
           45  +  Tcl_DecrRefCount(pNew);
           46  +}
           47  +
           48  +
           49  +static int SQLITE_TCLAPI test_vdbe_coverage(
           50  +  ClientData cd,
           51  +  Tcl_Interp *interp,
           52  +  int objc,
           53  +  Tcl_Obj *CONST objv[]
           54  +){
           55  +  const char *aSub[] = { "start", "report", "stop", 0 };
           56  +  int iSub = -1;
           57  +  if( objc!=2 ){
           58  +    Tcl_WrongNumArgs(interp, 1, objv, "sub-command");
           59  +    return TCL_ERROR;
           60  +  }
           61  +
           62  +  if( Tcl_GetIndexFromObj(interp, objv[1], aSub, "sub-command", 0, &iSub) ){
           63  +    return TCL_ERROR;
           64  +  }
           65  +
           66  +  Tcl_ResetResult(interp);
           67  +  assert( iSub==0 || iSub==1 || iSub==2 );
           68  +  switch( iSub ){
           69  +    case 0:       /* start */
           70  +      memset(aBranchArray, 0, sizeof(aBranchArray));
           71  +      sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, test_vdbe_branch, 0);
           72  +      break;
           73  +    case 1: {     /* report */
           74  +      int i;
           75  +      Tcl_Obj *pRes = Tcl_NewObj();
           76  +      Tcl_IncrRefCount(pRes);
           77  +      for(i=0; i<sizeof(aBranchArray); i++){
           78  +        u8 b = aBranchArray[i];
           79  +        if( b ){
           80  +          if( (b & 0x01)==0 ) appendToList(pRes, i, 0);
           81  +          if( (b & 0x02)==0 ) appendToList(pRes, i, 1);
           82  +          if( (b & 0x04)==0 ) appendToList(pRes, i, 2);
           83  +        }
           84  +      }
           85  +      Tcl_SetObjResult(interp, pRes);
           86  +      Tcl_DecrRefCount(pRes);
           87  +      break;
           88  +    };
           89  +      
           90  +    default:      /* stop */         
           91  +      sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, 0, 0);
           92  +      break;
           93  +  }
           94  +
           95  +  return TCL_OK;
           96  +}
           97  +
           98  +#endif  /* SQLITE_VDBE_COVERAGE */
           99  +
          100  +int Sqlitetestvdbecov_Init(Tcl_Interp *interp){
          101  +#ifdef SQLITE_VDBE_COVERAGE
          102  +  Tcl_CreateObjCommand(interp, "vdbe_coverage", test_vdbe_coverage, 0, 0);
          103  +#endif
          104  +  return TCL_OK;
          105  +}
          106  +
          107  +#endif

Changes to test/tester.tcl.

   572    572       set ::G(output_fd) [open $cmdlinearg(output) w]
   573    573       fconfigure $::G(output_fd) -buffering line
   574    574     }
   575    575   
   576    576     if {$cmdlinearg(verbose)==""} {
   577    577       set cmdlinearg(verbose) 1
   578    578     }
          579  +
          580  +  if {[info commands vdbe_coverage]!=""} {
          581  +    vdbe_coverage start
          582  +  }
   579    583   }
   580    584   
   581    585   # Update the soft-heap-limit each time this script is run. In that
   582    586   # way if an individual test file changes the soft-heap-limit, it
   583    587   # will be reset at the start of the next test file.
   584    588   #
   585    589   sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
................................................................................
  1291   1295       sqlite3_memdebug_log stop
  1292   1296       sqlite3_memdebug_log clear
  1293   1297       if {[sqlite3_memory_used]>0} {
  1294   1298         output2 "Writing leaks.tcl..."
  1295   1299         sqlite3_memdebug_log sync
  1296   1300         memdebug_log_sql leaks.tcl
  1297   1301       }
         1302  +  }
         1303  +  if {[info commands vdbe_coverage]!=""} {
         1304  +    vdbe_coverage_report
  1298   1305     }
  1299   1306     foreach f [glob -nocomplain test.db-*-journal] {
  1300   1307       forcedelete $f
  1301   1308     }
  1302   1309     foreach f [glob -nocomplain test.db-mj*] {
  1303   1310       forcedelete $f
  1304   1311     }
  1305   1312     exit [expr {$nErr>0}]
  1306   1313   }
         1314  +
         1315  +proc vdbe_coverage_report {} {
         1316  +  puts "Writing vdbe coverage report to vdbe_coverage.txt"
         1317  +  set lSrc [list]
         1318  +  set iLine 0
         1319  +  if {[file exists ../sqlite3.c]} {
         1320  +    set fd [open ../sqlite3.c]
         1321  +    set iLine
         1322  +    while { ![eof $fd] } {
         1323  +      set line [gets $fd]
         1324  +      incr iLine
         1325  +      if {[regexp {^/\** Begin file (.*\.c) \**/} $line -> file]} {
         1326  +        lappend lSrc [list $iLine $file]
         1327  +      }
         1328  +    }
         1329  +    close $fd
         1330  +  }
         1331  +  set fd [open vdbe_coverage.txt w]
         1332  +  foreach miss [vdbe_coverage report] {
         1333  +    foreach {line branch} $miss {}
         1334  +    set nextfile ""
         1335  +    while {[llength $lSrc]>0 && [lindex $lSrc 0 0] < $line} {
         1336  +      set nextfile [lindex $lSrc 0 1]
         1337  +      set lSrc [lrange $lSrc 1 end]
         1338  +    }
         1339  +    if {$nextfile != ""} {
         1340  +      puts $fd ""
         1341  +      puts $fd "### $nextfile ###"
         1342  +    }
         1343  +    puts $fd "Vdbe branch $line: path $branch never taken"
         1344  +  }
         1345  +  close $fd
         1346  +}
  1307   1347   
  1308   1348   # Display memory statistics for analysis and debugging purposes.
  1309   1349   #
  1310   1350   proc show_memstats {} {
  1311   1351     set x [sqlite3_status SQLITE_STATUS_MEMORY_USED 0]
  1312   1352     set y [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
  1313   1353     set val [format {now %10d  max %10d  max-size %10d} \

Changes to test/windowerr.tcl.

    50     50   errorsql_test 2.1 {
    51     51     SELECT sum( sum(a) OVER () ) FROM t1;
    52     52   }
    53     53   
    54     54   errorsql_test 2.2 {
    55     55     SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz);
    56     56   }
           57  +
           58  +errorsql_test 3.0 {
           59  +  SELECT sum(a) OVER win FROM t1
           60  +  WINDOW win AS (ROWS BETWEEN 'hello' PRECEDING AND 10 FOLLOWING)
           61  +}
           62  +errorsql_test 3.2 {
           63  +  SELECT sum(a) OVER win FROM t1
           64  +  WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING)
           65  +}
    57     66   
    58     67   
    59     68   finish_test
    60     69   

Changes to test/windowerr.test.

    91     91     SELECT sum( sum(a) OVER () ) FROM t1;
    92     92   } } } 1
    93     93   
    94     94   # PG says ERROR:  column "xyz" does not exist
    95     95   do_test 2.2 { catch { execsql {
    96     96     SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz);
    97     97   } } } 1
           98  +
           99  +# PG says ERROR:  invalid input syntax for integer: "hello"
          100  +do_test 3.0 { catch { execsql {
          101  +  SELECT sum(a) OVER win FROM t1
          102  +  WINDOW win AS (ROWS BETWEEN 'hello' PRECEDING AND 10 FOLLOWING)
          103  +} } } 1
          104  +
          105  +# PG says ERROR:  argument of ROWS must be type bigint, not type bit
          106  +do_test 3.2 { catch { execsql {
          107  +  SELECT sum(a) OVER win FROM t1
          108  +  WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING)
          109  +} } } 1
    98    110   
    99    111   finish_test