Skip to content

Commit e3dcc7a

Browse files
committed
Merge branch 'leo/102-tagada_doc' into 'master'
Doc: Document basic integration between gnattest and gnatfuzz See merge request eng/cov/gnatcoverage!253 Although the features are not mature, document them so as not to confuse users when seeing new command line options with no matching documentation in the users' guide.
2 parents 499b3a3 + 9796cb5 commit e3dcc7a

File tree

3 files changed

+140
-9
lines changed

3 files changed

+140
-9
lines changed

Diff for: doc/gnattest/gnattest_part.rst

+71-9
Original file line numberDiff line numberDiff line change
@@ -926,10 +926,54 @@ The tool currently has the following limitations:
926926

927927
.. _Automatic_testcase_generation:
928928

929-
Automatically generating test cases (alpha)
930-
-------------------------------------------
929+
Automatically generating test cases (experimental)
930+
--------------------------------------------------
931931

932-
``gnattest`` provides a switch ``--gen-test-vectors`` that can be used to
932+
Please note that all the features described bellow are experimental, and the
933+
interface is subject to change.
934+
935+
GNATtest has the capability to generate test inputs for subprograms under test.
936+
937+
.. _Tgen_Env:
938+
939+
Setting up the test generation runtime
940+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
941+
942+
Generation of values for Ada cannot be fully done statically, as the bounds of
943+
some types may only be defined at runtime. As such, the test generation feature
944+
requires the compilation and installation of a runtime project.
945+
946+
The sources for that project are located at
947+
``<GNATdas_install_dir/share/tgen/tgen_rts``.
948+
949+
To build the runtime, simply copy the above directory to a location of you
950+
choice, build the project using ``gprbuild``, install it using ``gprinstall``
951+
and make it available to the tools by referencing it in the ``GPR_PROJECT_PATH``
952+
environment variable:
953+
954+
.. code-block:: sh
955+
956+
# Clean previous source if present
957+
rm -rf /tmp/tgen_rts_src
958+
959+
# Copy the sources
960+
cp -r <GNATdas_install_dir>/share/tgen/tgen_rts /tmp/tgen_rts_src
961+
962+
# Build the project
963+
cd /tmp/tgen_rts_src
964+
gprbuild -P tgen_rts.gpr
965+
966+
# Install the project (removing the previous one if needed)
967+
gprinstall --uninstall -P tgen_rts.gpr --prefix=/tmp/tgen_rts_install
968+
gprinstall -p -P tgen_rts.gpr --prefix=/tmp/tgen_rts_install
969+
970+
# Make it available to other tools
971+
export GPR_PROJECT_PATH=/tmp/tgen_rts_install/share/gpr:$GPR_PROJECT_PATH
972+
973+
Generating test inputs
974+
^^^^^^^^^^^^^^^^^^^^^^
975+
976+
``gnattest`` provides a ``--gen-test-vectors`` switch that can be used to
933977
automatically generate test cases for all of the supported subprogram profiles.
934978
The number of generated test cases can be configured through the
935979
``--gen-test-num`` switch.
@@ -946,21 +990,39 @@ are true:
946990
5. Any of the subprogram's "in" or "out" mode parameters is a private type of
947991
a nested package.
948992

949-
..
950-
TODO: document a bit the value generation (mostly random, except for
951-
unconstrained arrays and discriminated record).
993+
Input value generation currently follows a simple strategy for each input
994+
parameter of the subprogram under test. Parameters of scalar types, and scalar
995+
components of composite types have their values uniformly generated. For
996+
unconstrained array types, a length is randomly chosen between 0 and 10
997+
elements, then the low bound is randomly chosen and the high bound computed
998+
accordingly to those two first points.
999+
1000+
For record discriminants, different strategies are chosen depending on the use
1001+
of the discriminant within the record: If the discriminant constraints a array
1002+
component, then the array strategy described above is used. If the discriminant
1003+
is used in a variant part, generation will be biased in order to generated all
1004+
possible shapes of the record (i.e. explore all variants). Otherwise, these are
1005+
generated as any other scalar component.
1006+
9521007

9531008
The generated test cases are then stored in a ad-hoc (and yet to be specified)
954-
JSON format, in files under the <obj_dir>/gnattest/tests/JSON_Tests directory.
1009+
JSON format, in files under the ``<obj_dir>/gnattest/tests/JSON_Tests`` directory.
9551010
The generated JSON files are preserved through a ``gnattest`` rerun. The user is
9561011
thus free to modify them, to e.g. fill in expected return values, though
9571012
backward compatibility of the format is not guaranteed at this stage.
9581013

9591014
``gnattest`` also generates Ada files to actually execute the test cases. Each test vector
9601015
has its own AUnit test case, and all test cases for a specific subprogram are all
9611016
stored in a dedicated file, namely
962-
<unit_name>-test_data-test_<subp_name>_<subp_hash>.ad[bs]. The content of these
963-
files is not preserved through a ``gnattest`` rerun.
1017+
``<unit_name>-test_data-test_<subp_name>_<subp_hash>.ad[bs]``, where
1018+
``<unit_name>`` is the name of the unit in which the subprogram is declared,
1019+
``<subp_name>`` is the name of the subprogram, and <subp_hash> is a hash based
1020+
on the profile of the subprogram, in order to differentiate overloads.
1021+
1022+
The content of these files are re-generated each time ``gnattest`` is invoked,
1023+
independently of the presence of the ``--gen-test-vectors`` switch on the
1024+
command line. It is thus not necessary to re-invoke ``gnattest`` with that
1025+
switch more than once, unless the goal is to generate additional test inputs.
9641026

9651027
..
9661028
TODO: document the --unparse switch

Diff for: doc/integration/gs_menu.png

128 KB
Loading

Diff for: doc/integration/integration_part.rst

+69
Original file line numberDiff line numberDiff line change
@@ -461,3 +461,72 @@ created in the same directory as each ``test_driver.gpr`` file. This file
461461
contains the name of the unit tested by the driver, and can be used to specify
462462
to |gcv| to only process the unit under test, by adding the switch
463463
:cmd-option:`[email protected]`.
464+
465+
###########################################
466+
Using GNATtest with GNATfuzz (experimental)
467+
###########################################
468+
469+
This section presents how a pre-existing GNATtest test harness can be used as
470+
a starting corpus for a GNATfuzz fuzzing campaign, and how inputs of interest
471+
found by GNATfuzz can be imported back into a GNATtest harness. These features
472+
are still experimental; the workflow and command line interface may change in
473+
the future.
474+
475+
**************************
476+
Setting up the environment
477+
**************************
478+
479+
To ensure the entire workflow functions properly, it's crucial to configure
480+
the various tools by setting specific environment variables.
481+
482+
The first step is to setup the value generation runtime library. For detailed
483+
instructions on how to do so, see :ref:`Tgen_Env`.
484+
485+
Then in order to activate the import and export of tests between GNATfuzz
486+
and GNATtest, the ``GNATFUZZ_TGEN`` environment variable must be set:
487+
488+
.. code-block::bash
489+
export GNATFUZZ_TGEN=1
490+
491+
*******************************************
492+
Using GNATStudio to perform the integration
493+
*******************************************
494+
495+
The simplest way to sequence the invocations of the two tools is to use the
496+
GNATstudio integration plugin.
497+
498+
First, create a GNATtest harness project if it doesn't already exist, using the
499+
``Analyze -> GNATtest -> Generate harness project`` entries in the menu bar.
500+
Note that in the dialog box opening there is an option to generate tests inputs
501+
if needed.
502+
503+
Then, exporting tests inputs from GNATtest to GNATfuzz and running a fuzzing
504+
campaign on a specific subprogram can be done by right-clicking on the
505+
declaration of the target subprogram, then selecting
506+
``GNATtest -> Start/Stop fuzzing subprogram``, as illustrated bellow.
507+
508+
.. Image:: gs_menu.png
509+
510+
This will first instrument sources and re-generate the GNATtest harness in order
511+
to be able to intercept the inputs passed to the subprogram, then run the test
512+
harness, dumping the inputs in a binary format that can be used by GNATfuzz.
513+
GNATstudio will then setup a fuzzing session on the subprogram, for which the
514+
parameters can be controlled through the various pop-up windows that will be
515+
displayed during the process.
516+
517+
``gnatfuzz`` will periodically export newly found inputs in a human readable
518+
JSON format under ``<obj>/gnattest/test/JSON_Tests``, where ``<obj>`` designates
519+
the object directory of the project.
520+
521+
The fuzzing session will stop once all the stopping criteria have been met. The
522+
fuzzing session can also be stopped early by right clicking on the subprogram
523+
declaration, then selecting ``GNATtest => Start/Stop fuzzing subprogram``.
524+
525+
After the fuzzing sessions has ended, a new GNATtest harness will be
526+
regenerated, including the tests exported by the GNATfuzz session. These will
527+
appear in
528+
``<obj>/gnattest/tests/<unit_name>-test_data-test_<subp_name>_<subp_hash>.adb``,
529+
where ``<unit_name>`` is the name of the unit in which the subprogram is
530+
declared, ``<subp_name>`` is the name of the subprogram, and <subp_hash> is a
531+
hash based on the profile of the subprogram, in order to differentiate
532+
overloads.

0 commit comments

Comments
 (0)