The Virtuoso ini file contains a parameter in [Parameters] section called TestCoverage whose value is the name of an XML file that will accumulate test coverage data.

The PLDebug switch controls the type of debugging enabled:

PLDebug = 0 - default debugging information and test coverage disabled.
PLDebug = 1 - debugging information enabled.
PLDebug = 2 - debugging information enabled, test coverage data will be written to file specified in TestCoverage Virtuoso ini file parameter.

If the test coverage file is specified the initial state of the accumulation is read from the coverage file if one exists. If the file does not exist then coverage starts from scratch.

The format of the file for store/restore of coverage data is:

<pl_stats>
  <proc name="xxx" calls="nn" file="ff" >
    <line no="xx" ctr="nn" /> ..
    <caller name="nnn" ct="nn" /> ..
  </proc>
  ...
</pl_stats>

An example of file:

<pl_stats>
  <proc name="DB.DBA.pop_get_command" calls="00000133" file="pop3_svr.sql" >
    <line no="000152" ctr="000133" />
    <line no="000153" ctr="000133" />
    <line no="000156" ctr="000133" />
    <caller name="DB.DBA.POP_IF_COMMAND" ct="000070" />
    <caller name="WS.WS.NN_SRV" ct="000063" />
  </proc>
</pl_stats>

For the purpose of making a Coverage report the format is extended. The lct attribute of the <proc> element contains a total number of lines for the procedure. The CDATA sections of the <line> element contain the excerpt of the line in question up to a maximum of 50 characters.

An example of the extended file format (made with cov_store ('ccc.xml', 1)) is:

<proc name="DB.DBA.pop_is_ok_" calls="00000034" file="pop3_svr.sql" lct="22" >
 <line no="000239" ctr="000034"><![CDATA[6    _idx := pop_atoi (num); ]]></line>
 <line no="000240" ctr="000034"><![CDATA[7    _all := length (_stat); ]]></line>
 <line no="000242" ctr="000034"><![CDATA[9    if ((_idx < 1) or (_idx > _all - 1)) ]]></line>
 <line no="000247" ctr="000034"><![CDATA[14    if (pop_is_deleted (_idx, _stat)) ]]></line>
 <line no="000253" ctr="000034"><![CDATA[20    return 1; ]]></line>
 <caller name="DB.DBA.POP_DELE" ct="000011" />
 <caller name="DB.DBA.POP_RETR" ct="000023" />
</proc>

The comment --src xxxx:yyy indicates the file xxx and line yyy. This comment will be added at the end line of each procedure when loading a file via isql or when generating SQL procedure constants for C code from sql files. These files and lines will be used for annotating the coverage report.

The function cov_load() is used to cumulatively load a test coverage file into a running system. Repeatedly calling this allows making a union of multiple separately obtained coverage files which will all show in the ultimate report.

The function cov_store (in out_file varchar, in add_comments integer := 0) is used to make an XML file for further XSL-T processing with cov_report() (see below) or to make a snapshot of current coverage statistics. The add_comments parameter is used to add a line info and count, usually it takes 1 for making the report, so internally it is used with add_comments equal to 0 to store the cumulative report in the TestCoverage file.

The function cov_report (in file varchar, in outdir varchar) makes the full coverage report based on the current state and writes it out.

The report consists of a summary file called profile.prof, containing execution counts and times for individual functions, sorted by self time as well as by time including called functions. For each distinct file mentioned in loaded procedures there is a file called <outdir>/<orgname>.sql.cov under the server's working directory. This file contains listings of all procedures from the file, annotated with line numbers at the start of each line. Each line with executable code will have an execution count. The line number field has six leading characters, the exec count is the next six characters, the line follows. The lines that are not executed are denoted with ## on place of exec count number.

Procedures that do not have source info associated are listed in name order in the file unnamed.sql.cov in the same directory.

An example of files generated by cov_report ('ccc.xml', 'cov/') are:

---->

>> begin <<<----
Lines: 806
TotalLines: 2741
Coverage: 29 %

[times called] [proc name]
    6250 : WS.WS.FINDPARAM
    --- code info
    [line in file] : [how many times executed] : [offset from beginning] [line excerpt]
       664 :   6250 : 5    if (pkey is null)
       665 :     ## : 6      pkey := '';
       666 :  12500 : 7    i := 0; l := length (params);
       667 :   6250 : 8    pkey := rtrim (pkey,': ');
       668 :   6250 : 9    while (i < l)
       670 :  35966 : 11        ret := http_request_header (vector (para
       671 :  35966 : 12        if (ret is not null)
       672 :   3014 : 13          return ret;
       673 :  32952 : 14        i := i + 1;
       675 :   3236 : 16    return '';

    -- caller information
    [time called] [from proc]
         6 : WS.WS.MOVE
         9 : WS.WS.COPY
       267 : WS.WS.UNLOCK
       269 : WS.WS.GET
       982 : WS.WS.PUT
      1028 : WS.WS.LOCK
      3689 : WS.WS.ISLOCKED
..... more sections follow .....