<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Model-Based API Testing for SMT Solvers</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Aina Niemetz</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Mathias Preiner</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Armin Biere</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Institute for Formal Models and Verification Johannes Kepler University</institution>
          ,
          <addr-line>Linz</addr-line>
          ,
          <country country="AT">Austria</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>Verification back ends such as SMT solvers are typically highly complex pieces of software with performance, correctness and robustness as key requirements. Full verification of SMT solvers, however, is difficult due to their complex nature and still an open question. Grammar-based black-box input fuzzing proved to be effective to uncover bugs in SMT solvers but is entirely input-based and restricted to a certain input language. State-of-theart SMT solvers, however, usually provide a rich API, which often introduces additional functionality not supported by the input language. Previous work showed that applying model-based API fuzzing to SAT solvers is more effective than input fuzzing. In this paper, we introduce a model-based API testing framework for our SMT solver Boolector. Our experimental results show that model-based API fuzzing in combination with delta debugging techniques is effective for testing SMT solvers.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Introduction</title>
      <p>
        of the error in a time efficient manner. Applying this approach to the SAT solver Lingeling [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ]
yields convincing results, and is in particular promising for other solver back-ends.
      </p>
      <p>
        In this paper, based on the results in [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] we introduce a model-based API testing framework
for our SMT solver Boolector [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ], consisting of the model-based API tester BtorMBT, the trace
execution tool BtorUntrace, and the delta debugger ddMBT. It is an integral part of the testing
workflow in the development process of Boolector, complemented by basic unit testing, a
regression test suite and parser testing tools (e.g., FuzzSMT [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ] in combination with ddSMT [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ] to
test valid input, and the ddsexpr tool set [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ] to test for robustness and correct error handling).
Since version 1.6, our model-based tester BtorMBT and our trace execution tool BtorUntrace
are shipped together with Boolector, and in particular BtorMBT can be considered as continued
work in progress while Boolector is under active development. Our model-based testing
workflow improved considerably since version 1.6 and our practical experience is extremely positive.
Our experimental results confirm the claim in [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] that model-based API testing in particular in
combination with delta debugging is effective for testing verification back-ends.
2
      </p>
    </sec>
    <sec id="sec-2">
      <title>Workflow</title>
      <p>
        The core test case generation engine in our model-based testing framework is our model-based
API testing tool BtorMBT, which implements a model of Boolector’s API and generates valid
sequences of API calls. In case that one of these sequences causes an error, Boolector
generates an API error trace, which allows to replay and reproduce faulty behaviour with our trace
execution tool BtorUntrace. Our delta debugging tool ddMBT then minimizes such an API
error trace while preserving its fault-inducing characteristics when replayed with BtorUntrace.
Figure 1 describes the general workflow of our framework and its components as follows.
Data Model Boolector, our system under test, is an SMT solver for the quantifier-free
theory of fixed-size bit-vectors, arrays, and uninterpreted functions as defined in the SMT-LIB
v2 [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ], and natively supports the use of non-recursive first-order lambda terms.
Option Model Boolector provides multiple solver engines, which are configurable via more
than 70 options in total. All options and their default values and value ranges can be queried
via its API. BtorMBT identifies valid option values based on these queries and defines invalid
option combinations. Else, any random combination of options is allowed.
      </p>
      <p>API Model Boolector provides a rich public API with full access to the complete feature
set of the solver. It is available in C and Python, but since both BtorMBT and BtorUntrace,
which tightly integrate Boolector via its API, are written in C, we will in the following focus on
Option Model</p>
      <p>Data Model
API Model</p>
      <p>API</p>
      <p>Error Trace
BtorMBT</p>
      <p>API</p>
      <p>Boolector</p>
      <p>API</p>
      <p>BtorUntrace
ddMBT</p>
      <p>Minimized API</p>
      <p>Error Trace
its C API, which consists of more than 150 API functions. Figure 2 illustrates the API model
of Boolector as implemented in BtorMBT. It incorporates Boolector’s option model and the
data model as above, and will be described in more detail in Section 3.</p>
      <p>BtorMBT Our model-based API testing tool BtorMBT generates test cases as valid
sequences of calls to Boolector’s API and implements the API model illustrated in Fig. 2. It
aims to exploit the full feature set of Boolector as available via its API. In case of an error,
Boolector generates an API error trace, which can then be replayed with our trace execution
tool BtorUntrace. Note that delegating API tracing to the solver assumes that it traces API
sequences correctly. Within our model-based API testing workflow it would therefore be more
reliable to let BtorMBT do the tracing, which we leave to future work. However, API tracing
as provided by the solver itself is still a valuable feature since it allows to reproduce erroneous
behavior outside of our test framework without the need for the original setup of the tool chain
that triggered the error. We will describe BtorMBT in more detail in Section 3.
API Error Trace Boolector provides the possibility to trace all API calls with their
arguments into a dedicated trace file. Given such an API trace, the trace execution tool BtorUntrace
then replays the sequence of API calls listed in the trace file and reproduces undesired behavior
in case of an error. An example of an API trace generated by Boolector is given in Fig. 3. We
will describe API tracing and the trace in Fig. 3 in Section 4 in more detail.
BtorUntrace The trace execution tool BtorUntrace allows to replay a sequence of API calls
given an API trace file as above. We will describe BtorUntrace in Section 4 in more detail.
ddMBT Given an API Error trace file which logs a sequence of API calls leading to undesired
behavior of Boolector, the delta debugger ddMBT minimizes the API trace while preserving
this behavior reproduced via BtorUntrace. We will describe ddMBT in more detail in Section 5.
3</p>
    </sec>
    <sec id="sec-3">
      <title>Test Case Generation with BtorMBT</title>
      <p>
        Our model-based API tester BtorMBT is a dedicated tool for testing random configurations
of Boolector. It is explicitly tailored to Boolector and supports the quantifier-free theories of
fixed-size bit-vectors, arrays and uninterpreted functions, extended with non-recursive
firstorder lambda terms. BtorMBT serves as the test case generation engine in our model-based
testing workflow and fully supports all functionality provided by Boolector via its API. In
contrast to input fuzzers such as FuzzSMT [
        <xref ref-type="bibr" rid="ref10 ref9">9, 10</xref>
        ], which generate a random but valid input
file to be handed to the system under test, BtorMBT tightly integrates Boolector via its C
API and generates test cases in the form of valid sequences of API calls. In case that an API
sequence triggers an error, Boolector produces an API error trace, which can then be replayed
with BtorUntrace for debugging purposes. BtorMBT further allows to test Boolector’s cloning
feature [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ], which generates a disjunct copy of a Boolector instance, in a test setting we refer
to as shadow clone testing. We will describe shadow clone testing in more detail in Section 3.2.
      </p>
      <p>
        Note that Boolector makes heavy use of runtime assertions and provides means to internally
check key features of the solver. This includes model validation for satisfiable instances, checking
the inconsistency of the set of inconsistent assumptions (also called failed assumptions [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ]) for
unsatisfiable instances when incremental solving is enabled, and checks for Boolector’s cloning
feature. Errors triggered by BtorMBT therefore include failed internal checks, assertion failures,
segmentation faults, and any other kind of abort.
3.1
      </p>
      <sec id="sec-3-1">
        <title>Architecture</title>
        <p>The general architecture of BtorMBT is defined by a state machine implementing the data,
options and API Model of Boolector as illustrated in Fig. 2. Test case generation with BtorMBT
is performed in rounds, each with a different configuration of Boolector. One round corresponds
to a sequence of states from state New to state Delete and the states are defined as follows.
New In each round, a fresh instance of Boolector is generated. Further, all parameters that
influence formula size and structure such as probability distributions and maximum numbers
for generating and releasing expressions are (re)initialized with random values (within certain
ranges).</p>
        <p>
          Set Options Boolector provides multiple solver engines, with some of them relying on an
underlying SAT solver. As back-end SAT solver, Boolector supports the solvers Lingeling [
          <xref ref-type="bibr" rid="ref8">8</xref>
          ],
PicoSAT [
          <xref ref-type="bibr" rid="ref5">5</xref>
          ] and MiniSat [
          <xref ref-type="bibr" rid="ref12">12</xref>
          ]. BtorMBT randomly chooses a solver engine and, if required,
a SAT solver to use. The solver engine is then configured by randomly choosing and setting
configuration options and their values within their predefined ranges. Note that option
combinations identified as invalid according to the option model of Boolector are explicitly excluded.
Further note that some options, e.g., incremental solving, are chosen with higher probability
than others, depending on their relevance.
        </p>
        <p>Generate Initial Expressions After a new Boolector configuration and all parameters
that influence the formula size and structure have been set up, an initial set of inputs and
non-input expressions is generated. The set of inputs is divided into randomly sized shares of
uninterpreted functions, array variables, and Boolean and bit-vector constants and variables.
Non-input expressions are randomly generated by combining inputs and already existing
noninput expressions until the maximum number of non-input expressions is reached. Note that
in case that the chosen solver engine only supports the quantifier-free theory of fixed-size
bitvectors, only bit-vector expressions are generated.</p>
        <p>Main After generating an initial set of expressions, in state Main a random number of
operations that influence the structure of the input formula is performed in random order: (1)
new expressions are generated, (2) existing expressions are released, (3) and existing Boolean
expressions are added to the input formula as assertions and, in the incremental case,
assumptions. Note that when selecting expressions to generate new non-input expressions, in order
New</p>
        <p>Set Options
Delete</p>
        <p>Dump Formula
Query Model sat
Assignments
incremental</p>
        <p>Generate Initial</p>
        <p>Expressions</p>
        <p>Main
Sat
incremental
Reset for
Incremental Usage
to increase expression depth, expressions from the initial set are chosen with lower probability.
After finalizing the current input formula, BtorMBT randomly performs various operations that
operate on the current state of the input formula and possibly manipulate the current state
of the Boolector instance e.g., simplifying the input formula by means of rewriting and other
techniques, or generating a clone of the current Boolector instance. Next, BtorMBT randomly
picks between dumping the input formula (state Dump Formula) or determining its
satisfiability (state Sat). Note that the latter is chosen with higher probability.</p>
        <p>
          Dump Formula Boolector allows to dump the current state of the input formula (without
assumptions) anytime during the solving process and supports BTOR [
          <xref ref-type="bibr" rid="ref11">11</xref>
          ], SMT-LIB v2 [
          <xref ref-type="bibr" rid="ref3">3</xref>
          ] and
AIGER [
          <xref ref-type="bibr" rid="ref4">4</xref>
          ] as output format. Depending on the structure of the formula, either of these formats
is chosen randomly. Note that AIGER is a bit-blasted and-inverter-graph (AIG) representation
of the input formula and can therefore only be produced if it is a bit-vector formula without
uninterpreted functions, arrays and lambda terms. If the output format is BTOR or
SMTLIB v2, the formula is dumped to a temporary file. This file is then parsed into a temporary
Boolector instance in order to check the dump for errors. If the output format is AIGER, the
formula is dumped to stdout without checking for correctness since Boolector does not provide
support for parsing input files in AIGER format. Checking the correctness of AIGER dumps
is left to future work. Next, BtorMBT randomly picks between concluding the current round
(state Delete) and continuing (state Main) with equal probability.
        </p>
        <p>
          Sat After setting up the current input, a call to determine its satisfiability is issued.
Boolector supports incremental solving under assumptions and, in case of unsatisfiability, allows to
determine the set of failed assumptions [
          <xref ref-type="bibr" rid="ref12">12</xref>
          ], i.e., those assumptions that are inconsistent with
the input formula. If failed assumptions checking is enabled, the set of failed assumptions is
internally checked for inconsistency with the current input. In case of satisfiability, Boolector
provides a model of the input formula, and if model checking is enabled, this model is internally
checked for validity. Next, if the input formula is satisfiable and model generation is enabled,
BtorMBT continues with printing and querying model assignments (state Query Model
Assignments). If incremental solving is enabled, BtorMBT may randomly choose to continue with an
incremental step (state Reset for Incremental Usage). Else, it proceeds to conclude the current
round (state Delete).
        </p>
        <p>
          Query Model Assignments If the input formula is satisfiable and model generation is
enabled, calls to query the model assignments of all generated expressions are issued. Further,
if model printing is enabled, the model of the input formula is printed to stdout. Boolector
supports model output formats based on BTOR [
          <xref ref-type="bibr" rid="ref11">11</xref>
          ] and SMT-LIB v2 [
          <xref ref-type="bibr" rid="ref3">3</xref>
          ], and BtorMBT may
pick either of them randomly. Note that as of version 2.5, model output in SMT-LIB format is
not yet fully standardized.
        </p>
        <p>Reset for Incremental Usage Prior to performing an incremental step, parameters such
as maximum numbers and probability distributions are reinitialized with random values (within
certain ranges). Note that the value ranges for these parameters may differ from the ranges
employed in state New.</p>
        <p>
          Delete State Delete concludes one round (one test case) with releasing all generated
expressions and deleting the current Boolector instance.
28 return true
29 sat b1
30 return 10
31 release b1 e2@b1
32 release b1 e3@b1
33 release b1 e4@b1
34 release b1 e6@b1
35 release b1 e8@b1
36 release b1 e9@b1
37 release b1 e-10@b1
38 release_sort b1 s1@b1
39 release_sort b1 s3@b1
40 delete b1
As of version 2.0, Boolector provides a cloning feature which allows to generate a disjunct
copy of a Boolector instance [
          <xref ref-type="bibr" rid="ref16">16</xref>
          ]. A clone captures the current state of the solver and can be
either a deep copy (full clone) or a term layer copy (term layer clone) of the original instance.
As a deep copy, a full clone includes the underlying SAT solver and the (bit-blasted) AIG
layer (if present) and requires corresponding cloning support of the SAT solver back-end (e.g.,
Lingeling [
          <xref ref-type="bibr" rid="ref7 ref8">7, 8</xref>
          ]). A full clone is required to behave exactly the same as the instance it has been
cloned from. Generating full clones for producing independent subproblems is, e.g., one of the
key requirements for the work splitting approach implemented in PBoolector [
          <xref ref-type="bibr" rid="ref18">18</xref>
          ], a parallel
prototype implementation of Boolector. A term layer clone, on the other hand, only copies
the term layer of the original instance, which does not guarantee exact same behavior but is
sufficient for many applications (e.g., generating a dual solver instance for the
dual-propagationbased optimization of the lemmas on demand approach described in [
          <xref ref-type="bibr" rid="ref15">15</xref>
          ]).
        </p>
        <p>In order to test and guarantee that a full clone behaves exactly the same as the instance
it has been cloned from, BtorMBT provides a dedicated shadow clone test setting similar to
shadow clone testing as implemented for Lingeling. Shadow clone testing is randomly enabled
and when enabled, BtorMBT initially generates a full clone (the shadow clone) of the current
Boolector instance, which then mirrors every API call to the original instance and cross-checks
return values for equivalence. Additionally, Boolector implements extensive checks for freshly
generated clones and internally checks the state of the shadow clone after each API call. A
shadow clone may be initialized anytime prior to the first SAT call and is usually randomly
released and regenerated multiple times after being initialized, at different stages during one
test round, to prevent that clones are only generated and checked prior to (incremental) API
calls.
4</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>API Trace Execution with BtorUntrace</title>
      <p>Our SMT solver Boolector allows to record all API calls with their arguments to a trace file,
which then serves as input for our trace execution tool BtorUntrace. An example of an API
trace generated by Boolector is given in Fig. 3, with each line of the trace either listing an
API call or the return value of an API call in chronological order. A line representing an API
call consists of an identifier, the Boolector instance to issue the call to, and the arguments to
the call. A line representing the return value of an API call must immediately follow the line
of the call and consists of the keyword return and the return value, which can either be an
identifier or a numerical value. As an example, consider the API call in line 7 and its return
value in line 8. Identifier array_sort in line 7 refers to the API call to create an array sort
with bit-vector sort s1 as its first (index sort) and second (element sort) argument, issued to
Boolector instance b1. Line 8 identifies the return value of this call as array sort s3.</p>
      <p>BtorUntrace is a dedicated tool for replaying traces generated by Boolector and tightly
integrates Boolector via its C API. In our model-based API testing workflow, BtorUntrace is
used in combination with BtorMBT to reproduce faulty behavior when a test case generated
by BtorMBT fails. However, BtorUntrace is also useful outside of our testing workflow when
debugging undesired behavior triggered by any (real world) application of Boolector. Since
BtorUntrace only requires the API trace to replay a faulty run of Boolector, it is, e.g., not
necessary to have the original (possibly complex) setup of the tool chain available for debugging
purposes. Further, some errors triggered via the API may not be triggered with a dump of the
corresponding input formula since some (sequences of) Boolector API calls can not be expressed
in the input file formats it supports.
5</p>
    </sec>
    <sec id="sec-5">
      <title>API Error Trace Minimization with ddMBT</title>
      <p>
        Our delta debugger ddMBT minimizes a given API error trace while preserving its
failureinducing characteristics based on the exit code and error message produced by Boolector when
replaying the (minimized) trace with BtorUntrace. Trace minimization with ddMBT works in
rounds until fixpoint, with each round divided into three phases. In the first phase, lines of the
trace file are eliminated in a divide-and-conquer manner similar to the original delta debugging
algorithm proposed in [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ]. In the second and third phase, children of terms are substituted
with fresh variables and already existing expressions of the same sort. These three substitution
strategies are in practice usually sufficient to obtain a trace file small enough to allow efficient
debugging. In some cases, however, modifying numeric parameters such as bit-widths, shift
widths, or indices for slicing might be beneficial. We leave these enhancements to future work.
6
      </p>
    </sec>
    <sec id="sec-6">
      <title>Experimental Evaluation</title>
      <p>
        In the following, similarly as in [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ], we evaluate the effectiveness of our model-based API tester
BtorMBT in terms of code coverage, throughput and the success rate when inserting defects
into the code of Boolector. We further compare the performance of BtorMBT to
grammarbased input fuzz testing, in particular to FuzzSMT [
        <xref ref-type="bibr" rid="ref10 ref9">9, 10</xref>
        ], the only currently available input
fuzzer for SMT. Note that since FuzzSMT originally is an input fuzzer for the SMT-LIB v1 [
        <xref ref-type="bibr" rid="ref17">17</xref>
        ]
language, we applied an available patch [
        <xref ref-type="bibr" rid="ref19">19</xref>
        ] for SMT-LIB v2 [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ] support. However, this patch
only provides SMT-LIB v2 compliant output of SMT-LIB v1 test cases. As a consequence,
extensions of the language introduced in SMT-LIB v2, e.g., support for incremental solving, are
not included, which may have a considerable impact on the performance of the tool. Measuring
this impact without extending the tool to support the full feature set of the SMT-LIB v2
language, however, is difficult. We still include a comparison with FuzzSMT since up until now
it was the de facto state-of-the-art for generating random test cases in SMT, and leave the
extension of the tool to fully support SMT-LIB v2 to future work.
6.1
      </p>
      <sec id="sec-6-1">
        <title>Configuration</title>
        <p>Since we aim to evaluate BtorMBT and FuzzSMT on as even terms as possible, we provide a
script for FuzzSMT that simulates option fuzzing and the round-based behavior as implemented
in BtorMBT. In the following, we refer to this script as FuzzSMT, and compare against the
version of BtorMBT released together with the current version 2.4 of Boolector.</p>
        <p>
          We optionally switch off option fuzzing (while still randomly choosing solver engines and SAT
solvers) and refer to BtorMBT and FuzzSMT without option fuzzing as BtorMBTno and
FuzzSMTno. Note that we compiled Boolector with all three supported SAT solvers Lingeling [
          <xref ref-type="bibr" rid="ref8">8</xref>
          ],
PicoSAT [
          <xref ref-type="bibr" rid="ref5">5</xref>
          ] and MiniSat [
          <xref ref-type="bibr" rid="ref12">12</xref>
          ].
        </p>
        <p>We evaluated BtorMBT and FuzzSMT on runs of 100k rounds and chose a time limit of 2
seconds per round. Note that since increasing this time limit did not increase code coverage
for 100k rounds for configuration BtorMBT, we chose this limit as a good compromise between
throughput and test coverage.</p>
        <p>In order to be able to determine if either of the tools is able to identify faulty mutations of
Boolector (see Section 6.4), we thoroughly tested our base version 2.4 of Boolector prior to our
experimental evaluation and run 10M rounds with each BtorMBT and FuzzSMT, all of which
did not result in a single error.</p>
        <p>We performed all our experiments on a cluster with 30 nodes of 2.83 GHz Intel Core 2 Quad
machines running Ubuntu 14.04.5 LTS.
6.2</p>
      </sec>
      <sec id="sec-6-2">
        <title>Code Coverage</title>
        <p>We used the tool gcov of the GNU Compiler Collection (GCC) suite to determine the code
coverage over 100k non-faulty rounds of BtorMBT and FuzzMBT with and without option
fuzzing. The evolution of line coverage for configurations BtorMBT, BtorMBTno, FuzzSMT
and FuzzSMTno as measured by gcov over 100k rounds is illustrated in Fig. 4.</p>
        <p>After 10k runs, BtorMBT already
aocphtiioevnesfu7z5zi%ng,linaendco8v7er%agewhweinthooupt- 100.0 BBttoorrMMBBTTno
toinonthfeuzoztinhger ishaennda,blreeda.chesFuazzcSoMveTr-, 90.0 FFuuzzzzSSMMTTno 90.0
]
age of 64% and 72%. After 100k [%
trFouunz7sz8,S%MBt(To+r3Ma%cBh)iTeavniedms9pa0ro%cvoev(s+erc1ao2gv%eer)oa,fgwe6h5ui%lpe rveoageC 80.0 7783..14
(+1%) and 73% (+1%). ieLn 766076...046</p>
        <p>Unsurprisingly, BtorMBT covers 65.0
more than 98% of Boolector’s API, 6601..08
with error handling code as the un- 57.5
covered rest that is not triggered due 0 20000 40000 60000 80000 100000
to the fact that all test cases were
error free. FuzzSMT, on the other hand, Figure 4: Code coverage evolution over 100k rounds.
only achieves a coverage of 52%, which
is likely to be improved by introducing full SMT-LIB v2 support, however, not up to the
coverage rate BtorMBT achieved. Note that for both tools, a coverage rate of 100% for error free test
cases is in general impossible due to the fact that error handling code is not triggered. Further,
since FuzzSMT only generates input in SMT-LIB v2 format, all code related to parsing BTOR
format (3%) remains unused.
6.3</p>
      </sec>
      <sec id="sec-6-3">
        <title>Throughput</title>
        <p>When fuzz testing an SMT solver, no matter if it is input fuzzing or API fuzzing, the number
of tests completed within a certain time frame (the throughput) is an important measure of
efficiency and effectiveness of the test method. A high number may indicate that the generated
test cases are too trivial and therefore less likely to trigger errors. A low number, on the other
hand, may be caused by too difficult and therefore too time consuming test cases, which may
considerably slow down progress when testing. We aim to perform as many good test cases,
i.e., test cases with a high code coverage rate, in as little time as possible, which is a balancing
act between the two extremes above.</p>
        <p>For 100k rounds, BtorMBT achieves a throughput of on average 45 rounds per second, which
increases by 20% when shadow clone testing is disabled. FuzzSMT, on the other hand, achieves
a far lower throughput of 7 test cases per second since it first generates an input file that is
then handed to the SMT solver. Further, FuzzSMT is written in Java, and (re)starting the
Java VM in each round introduces additional overhead which further decreases throughput.</p>
        <p>Note that in 100k rounds with BtorMBT, 20% of all calls to determine satisfiability are
incremental. Further, one in four solved instances is satisfiable, which corresponds to a rather
unbalanced ratio of 1:3 of satisfiable to unsatisfiable instances. We leave improving this ratio
to future work.
6.4</p>
      </sec>
      <sec id="sec-6-4">
        <title>Defect Injection</title>
        <p>In our final experiment, we evaluated the success rate of BtorMBT and FuzzSMT in identifying
faulty configurations of Boolector. We compiled a set of test configurations TC (4626 in total),
which consists of two subsets TCA and TCD and contains configurations where we introduced
artificial defects into the source code of Boolector. Set TCA contains 2305 configurations with
a randomly inserted abort statement, and set TCD consists of 2321 configurations where we
deleted a random statement from the code. All 4626 configurations in set TC are faulty
configurations. However, some defects, e.g., modifications of heuristics due to a missing statement,
may result in performance bugs rather than producing incorrect results or any other erroneous
behavior and are therefore impossible to detect with either test method.</p>
        <p>For each faulty test configuration, we set a limit of 100k rounds for BtorMBT. However,
since the low throughput of FuzzSMT (7 rounds per second) would require too much runtime
for our experiment with 100k rounds even on a cluster with 30 nodes (26 days in the worst
case), we limited the number of rounds for FuzzSMT to 10k and compare its results to the
number of faulty configurations identified by BtorMBT within 10k rounds.</p>
        <p>Table 1 shows the number of faulty configurations identified by BtorMBT and FuzzSMT with
and without option fuzzing within 100k and 10k rounds. Overall, within 10k rounds BtorMBT
has a 11% higher success rate than FuzzSMT, which is increased by 14% to 80.4% when the
limit is extended to 100k rounds. Disabling option fuzzing, on the other hand, decreases the
number of configurations identified as faulty for both tools by 12%.</p>
        <p>Not surprisingly, for both tools the success rates for configuration set TCA correspond to
their code coverage as determined in Section 6.2. The number of successfully identified faulty
configurations in set TCD, on the other hand, is significantly lower due to the fact that set TCD
contains test cases with defects that concern error handling code or decrease performance rather
than introducing erroneous behavior. Further, in case of BtorMBT, since dumps in AIGER
format are not tested for correctness it is not possible to detect configurations that produce
incorrect AIGER output. The same applies in case of FuzzSMT for configurations that produce
incorrect dump output in any format since it is not checked for correctness.
100k
10k</p>
        <p>TCA (2305)
TCD (2321)
TC (4626)
TCA (2305)
TCD (2321)
TC (4626)
In this paper, we presented a model-based API testing tool set for our SMT solver Boolector.
It consists of several dedicated tools, the model-based API tester BtorMBT, the API trace
exection tool BtorUntrace and the API trace minimizing tool ddMBT.</p>
        <p>Our API fuzzer BtorMBT generates random but valid sequences of calls to Boolector’s
API and allows to test random configurations of Boolector on random input formulas. With a
success rate of 80% on our artificial set of faulty configurations of Boolector and a line coverage
of 90% over 100k rounds, our experiments suggest that BtorMBT is an effective method for
testing Boolector. Our extremely positive practical experience confirms this claim. Based on
our results, we believe that applying our techniques to other SMT solvers is effective in general.
An interesting direction for future work would be introducing symbolic execution techniques
into BtorMBT in order to be able to direct trace generation towards maximal code coverage.</p>
        <p>
          Our model-based API testing framework is the core component of the testing workflow in
the development process of Boolector. However, it still needs to be complemented by several
other tools to cover cases that can not be tested with BtorMBT alone. The solver front end, for
example, can only be tested by using the solver as standalone tool with files in BTOR or
SMTLIB format as input. For that purpose, we use a suite of regression tests and FuzzSMT, even
though its support for the SMT-LIB v2 format is incomplete. Another example is parser testing,
which is incomplete with BtorMBT since Boolector is currently not able to dump incremental
input and in general does not use the full feature set of the SMT-LIB language when dumping.
Further, dumping with Boolector only produces valid input files. However, a parser must be
tested for correct parse error handling on invalid input, too. We test Boolector’s parsers by
means of the tool fzsexpr of the ddsexpr tool set [
          <xref ref-type="bibr" rid="ref6">6</xref>
          ], which generates (mostly) invalid input by
mutating existing files based on lines, S-expressions and characters.
        </p>
        <p>Currently, BtorMBT produces a rather unbalanced ratio of 1:3 of satisfiable to unsatisfiable
instances. Further, AIGER dump output is not checked for correctness since Boolector does not
allow to parse AIGER input files. We leave improving the ratio of satisfiable to unsatisfiable
instances and checking the correctness of AIGER dumps to future work.</p>
      </sec>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>Cyrille</given-names>
            <surname>Artho</surname>
          </string-name>
          , Armin Biere, and
          <string-name>
            <given-names>Martina</given-names>
            <surname>Seidl</surname>
          </string-name>
          .
          <article-title>Model-based testing for verification back-ends</article-title>
          .
          <source>In Margus Veanes and Luca Viganò</source>
          , editors,
          <source>Tests and Proofs - 7th International Conference, TAP 2013</source>
          , Budapest, Hungary, June 16-20,
          <year>2013</year>
          . Proceedings, volume
          <volume>7942</volume>
          of Lecture Notes in Computer Science, pages
          <fpage>39</fpage>
          -
          <lpage>55</lpage>
          . Springer,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>Clark</given-names>
            <surname>Barrett</surname>
          </string-name>
          , Pascal Fontaine, and
          <string-name>
            <given-names>Cesare</given-names>
            <surname>Tinelli</surname>
          </string-name>
          .
          <source>The SMT-LIB Standard: Version 2.5. Technical report</source>
          , Department of Computer Science, The University of Iowa,
          <year>2015</year>
          . Available at www.
          <source>SMT-LIB.org.</source>
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>Clark</given-names>
            <surname>Barrett</surname>
          </string-name>
          , Aaron Stump, and
          <string-name>
            <given-names>Cesare</given-names>
            <surname>Tinelli</surname>
          </string-name>
          .
          <source>The SMT-LIB Standard: Version 2.0. Technical report</source>
          , Department of Computer Science, The University of Iowa,
          <year>2010</year>
          . Available at www.
          <source>SMT-LIB.org.</source>
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          .
          <source>AIGER Format and Toolbox</source>
          . http://fmv.jku.at/aiger.
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          .
          <article-title>Picosat essentials</article-title>
          .
          <source>JSAT</source>
          ,
          <volume>4</volume>
          (
          <issue>2</issue>
          -4):
          <fpage>75</fpage>
          -
          <lpage>97</lpage>
          ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          . ddsexpr. http://fmv.jku.at/ddsexpr,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          .
          <article-title>Yet another Local Search Solver and Lingeling and Friends Entering the SAT Competition 2014</article-title>
          . In Adrian Balingt, Anton Belov, Marijn Heule, and Matti Järvisalo, editors,
          <source>SAT Competition</source>
          <year>2014</year>
          , volume
          <string-name>
            <surname>B-</surname>
          </string-name>
          <year>2014</year>
          -2 of Department of Computer Science Series of Publications B, pages
          <fpage>39</fpage>
          -
          <lpage>40</lpage>
          . University of Helsinki,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          . Splatz, Lingeling, Plingeling, Treengeling,
          <source>YalSAT Entering the SAT Competition</source>
          <year>2016</year>
          . In Tomáš Balyo, Marijn Heule, and Matti Järvisalo, editors,
          <source>SAT Competition 2016 - Solver and Benchmark Descriptions</source>
          , volume
          <string-name>
            <surname>B-</surname>
          </string-name>
          <year>2016</year>
          -1 of Department of Computer Science Series of Publications B, pages
          <fpage>44</fpage>
          -
          <lpage>45</lpage>
          . University of Helsinki,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>Robert</given-names>
            <surname>Brummayer</surname>
          </string-name>
          . FuzzSMT. http://fmv.jku.at/fuzzsmt,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>Robert</given-names>
            <surname>Brummayer</surname>
          </string-name>
          and
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          .
          <article-title>Fuzzing and Delta-Debugging SMT Solvers</article-title>
          .
          <source>In Proceedings of the 7th International Workshop on Satisfiability Modulo Theories (SMT'09)</source>
          <article-title>, page 5</article-title>
          . ACM,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <surname>Robert</surname>
            <given-names>Brummayer</given-names>
          </string-name>
          , Armin Biere, and
          <string-name>
            <given-names>Florian</given-names>
            <surname>Lonsing</surname>
          </string-name>
          . BTOR:
          <article-title>Bit-Precise Modelling of WordLevel Problems for Model Checking</article-title>
          .
          <source>In Proceedings of the 1st International Workshop on BitPrecise Reasoning</source>
          , BPR 2008,
          <article-title>affiliated with the 20th International Conference on Computer Aided Verification</article-title>
          ,
          <string-name>
            <surname>CAV</surname>
          </string-name>
          <year>2008</year>
          , Princeton, NJ, USA, July
          <volume>14</volume>
          ,
          <year>2008</year>
          ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>Niklas</given-names>
            <surname>Eén</surname>
          </string-name>
          and
          <string-name>
            <given-names>Niklas</given-names>
            <surname>Sörensson</surname>
          </string-name>
          .
          <article-title>An extensible sat-solver</article-title>
          .
          <source>In Enrico Giunchiglia and Armando Tacchella</source>
          , editors,
          <source>Theory and Applications of Satisfiability Testing</source>
          , 6th International Conference,
          <string-name>
            <surname>SAT</surname>
          </string-name>
          <year>2003</year>
          .
          <article-title>Santa Margherita Ligure</article-title>
          , Italy, May 5-
          <issue>8</issue>
          , 2003 Selected Revised Papers, volume
          <volume>2919</volume>
          of Lecture Notes in Computer Science, pages
          <fpage>502</fpage>
          -
          <lpage>518</lpage>
          . Springer,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <given-names>Ralf</given-names>
            <surname>Hildebrandt</surname>
          </string-name>
          and
          <string-name>
            <given-names>Andreas</given-names>
            <surname>Zeller</surname>
          </string-name>
          .
          <article-title>Simplifying failure-inducing input</article-title>
          .
          <source>In ISSTA</source>
          , pages
          <fpage>135</fpage>
          -
          <lpage>145</lpage>
          ,
          <year>2000</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>Aina</given-names>
            <surname>Niemetz</surname>
          </string-name>
          and
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          .
          <article-title>ddSMT: A Delta Debugger for the SMT-LIB v2 Format</article-title>
          .
          <source>In Proceedings of the 11th International Workshop on Satisfiability Modulo Theories (SMT'13)</source>
          , affiliated to SAT'
          <volume>13</volume>
          , Helsinki, Finland, pages
          <fpage>36</fpage>
          -
          <lpage>45</lpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <surname>Aina</surname>
            <given-names>Niemetz</given-names>
          </string-name>
          , Mathias Preiner, and
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          .
          <article-title>Turbo-charging lemmas on demand with don't care reasoning</article-title>
          . In Formal Methods in Computer-Aided Design,
          <string-name>
            <surname>FMCAD</surname>
          </string-name>
          <year>2014</year>
          , Lausanne, Switzerland,
          <source>October 21-24</source>
          ,
          <year>2014</year>
          , pages
          <fpage>179</fpage>
          -
          <lpage>186</lpage>
          . IEEE,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <surname>Aina</surname>
            <given-names>Niemetz</given-names>
          </string-name>
          ,
          <source>Mathias Preiner, and Armin Biere. Boolector 2.0. Journal on Satisfiability, Boolean Modeling and Computation JSAT</source>
          ,
          <volume>9</volume>
          :
          <fpage>53</fpage>
          -
          <lpage>58</lpage>
          ,
          <year>2015</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          [17]
          <string-name>
            <given-names>Silvio</given-names>
            <surname>Ranise</surname>
          </string-name>
          and
          <string-name>
            <given-names>Cesare</given-names>
            <surname>Tinelli</surname>
          </string-name>
          .
          <source>The SMT-LIB Standard: Version 1.2. Technical report</source>
          , Department of Computer Science, The University of Iowa,
          <year>2006</year>
          . Available at www.
          <source>SMT-LIB.org.</source>
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          [18]
          <string-name>
            <given-names>Christian</given-names>
            <surname>Reisenberger. PBoolector: A Parallel SMT</surname>
          </string-name>
          <article-title>Solver for QF_BV by Combining BitBlasting with Look-Ahead. Master's thesis</article-title>
          , Johannes Kepler University Linz,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          [19]
          <string-name>
            <given-names>Christoph</given-names>
            <surname>Wintersteiger</surname>
          </string-name>
          .
          <article-title>Patch for FuzzSMT to produce SMT-LIB v2 output</article-title>
          . http://fmv.jku.at/fuzzsmt/fuzzsmt-smt2.
          <source>patch.gz</source>
          ,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>