Through the combination of indexing requiments specification documents (especially IETF RFCs) and the use of attributes in OCaml source code referring to specific requirements, this tool can produce an annotated requirements specification that includes references to the code that implements and/or tests each requirement. This also allows unimplemented or untested requirements to be identified automatically.
References from OCaml source code to requirements specifications is done using attribute syntax: http://caml.inria.fr/pub/docs/manual-ocaml/extn.html#attr-id
The most common case is to add an attribute after an expression:
let _ =
hello (something 1) [@ref (rfc 9999) "s18"]
The above attribute is intended to express that the adjacent code implements the requirement defined in section 18 of fictional RFC 9999. Currently the hyperlink generated for such references links to the line of code, and is intended for human readers, so the precise placement of the attribute is not important.
To make it easier to remember the meaning of RFC numbers, and to enable less verbose references, it is possible to express the same reference as follows:
[@@@specdoc let foo = rfc 9999]
let _ =
hello (something 1) [@ref foo "s18"]
The name foo
can be any OCaml identifier that has meaning to you.
Documents other than IETF RFCs can be referenced using URIs:
[@@@specdoc let reqif = uri "http://www.omg.org/spec/ReqIF/1.1/"]
When verifying traceability the goal is typically to ensure that all requirements have been implemented, and also that all requirements have been tested.
To express the difference between implementation code and test code, use the following near the top of the source file:
[@@@reftype Impl]
or:
[@@@reftype Test]
The format of annotated specification documents is yet to be documented. An example can be found at:
https://github.com/infidel/ocaml-mdns/blob/master/doc/rfc6762_notes.xml
To generate the necessary metadata required by the reqtrace
tool,
pass the -bin-annot
option to the ocamlc
compiler command.
This will generate a .cmt
file for each OCaml source file.
After compiling the code, invoke the reqtrace extract
command and pass the path to the root directory containing
the .cmt
files:
reqtrace extract --strip=_build/ _build
This will generate a set of .req
XML files in the same directory
structure. The combine the specification XML with the references
to generate an annotated specification in HTML format:
reqtrace html example_spec.xml --ref=_build --base=https://github.com/foo/bar/blob/master/ --out=example_spec.html
If your OCaml code requires preprocessing using camlp4 then only a subset of attribute syntax can be used, because of: camlp4/camlp4#55
The recommended usage is:
let _ =
hello (something 1) [@ref foo "s18"]
One reason for this is that camlp4 does not support
block attributes ([@@attr...]
) or floating attributes ([@@@attr...]
).
While it is possible to use expression attributes for
@specdoc
and @reftype
, this is not so convenient.
Since no @specdoc
attribute defines the name foo
, it is necessary
to use the reqtrace
command line option --rfc foo=9999
instead.
Unfortunately an attribute such as [@ref (rfc 1234) "s3_p2"]
is corrupted by camlp4, causing it to be interpreted as [@ref rfc 1234 "s3_p2"]
,
so named specifications are required.
The annotated RFC 6762 specification mentioned above was initially generated by running:
parseietf.py rfc6762.txt --xml rfc6762_notes.xml
However, this script only been tested on very few IETF RFCs, so it is unlikely to work on a significant percentage of RFCs (because they were not really intended to be machine-readable).