Commit 533fac24 authored by Erwan Jahier's avatar Erwan Jahier
Browse files

Enhance ocaml support in lurette (cf 74f93d6c)

The oracle is not necessary anymore to run a test.

Moreover, the sut no more needs to (and must not) be named 'sut.ml'
(resp.  'oracle.ml' for the oracle).

Moreover, rename the env var EXTRA_CFILES into EXTRA_SOURCE_FILES, so that users
use it for ocaml programs.
parent 3d7485e8
...@@ -35,10 +35,10 @@ in your current directory. It might confuse Lurette. ...@@ -35,10 +35,10 @@ in your current directory. It might confuse Lurette.
or constants. For example, the scade compiler generates files such or constants. For example, the scade compiler generates files such
as "foo_const.dc" or "foo_fctext.dc" that needs to be completed as "foo_const.dc" or "foo_fctext.dc" that needs to be completed
and renamed "foo_const.c" resp "foo_fctext.c". One then need to and renamed "foo_const.c" resp "foo_fctext.c". One then need to
say Lurette to use it by filling the EXTRA_CFILES entry of the say Lurette to use it by filling the EXTRA_SOURCE_FILES entry of the
"Extra Environment Variables" window. Note that this is not a "Extra Environment Variables" window. Note that this is not a
Lurette issue, but an issue with the code generator you use (the Lurette issue, but an issue with the code generator you use (the
EXTRA_CFILES entry filling excepted). EXTRA_SOURCE_FILES entry filling excepted).
* It does not work. * It does not work.
......
...@@ -44,5 +44,7 @@ diff: ...@@ -44,5 +44,7 @@ diff:
echo "il y a $(shell grep "+" diff.diff | wc -l) + et $(shell grep "-" diff.diff | wc -l) -" echo "il y a $(shell grep "+" diff.diff | wc -l) + et $(shell grep "-" diff.diff | wc -l) -"
# in order to tag a version, 'git tag 1.52'
# XXX automate that tag numbering and via a make rule
#tag:
# git tag ``xxx
...@@ -2,7 +2,7 @@ VERSION:=$(shell E=`git log --oneline | wc -l` ; echo "$$E-166" | bc ) ...@@ -2,7 +2,7 @@ VERSION:=$(shell E=`git log --oneline | wc -l` ; echo "$$E-166" | bc )
VERSION:="1.$(VERSION)" VERSION:="1.$(VERSION)"
# well, finally, set it manually... # well, finally, set it manually...
VERSION:=1.51 VERSION:=1.52
# the sha is still automatic tough! # the sha is still automatic tough!
SHA:=`git log -1 --pretty=format:"%h"` SHA:=`git log -1 --pretty=format:"%h"`
......
V1.52 (18/08/2010)
* Add support for testing ocaml programs via lurette.
V1.51 (8/07/2010) V1.51 (8/07/2010)
* New feature: when some SUT or environement inputs are missing, use * New feature: when some SUT or environement inputs are missing, use
......
...@@ -11,16 +11,20 @@ $(objdir)/lurette-start.ps $(objdir)/lurette-try.ps \ ...@@ -11,16 +11,20 @@ $(objdir)/lurette-start.ps $(objdir)/lurette-try.ps \
$(objdir)/obj-code-gen.ps $(objdir)/components-diagram.ps \ $(objdir)/obj-code-gen.ps $(objdir)/components-diagram.ps \
$(objdir)/heater_sensors.ps $(objdir)/heater_sensors.ps
ALLTEX=sensors.tex wearing_sensors.tex heater_control.tex heater_control_env.tex ALLTEX=sensors.tex wearing_sensors.tex heater_control.tex heater_control_env.tex touch.tex
all : $(objdir) pdf all : $(objdir) pdf
make re make re
make re make re
re : .PHONY:touch.tex
touch $(MAIN).tex; make pdf touch.tex:
touch touch.tex
pdf:$(MAIN).pdf re : touch.tex
make pdf
pdf:touch.tex $(MAIN).pdf
cp $(objdir)/$(MAIN).pdf . cp $(objdir)/$(MAIN).pdf .
bib : bib :
...@@ -44,7 +48,7 @@ $(objdir): ...@@ -44,7 +48,7 @@ $(objdir):
$(MAIN).ps : $(objdir)/$(MAIN).dvi $(MAIN).ps : $(objdir)/$(MAIN).dvi
cd $(objdir); dvips $(MAIN).dvi -o ../$(MAIN).ps ; cp $(MAIN).dvi .. cd $(objdir); dvips $(MAIN).dvi -o ../$(MAIN).ps ; cp $(MAIN).dvi ..
$(MAIN).pdf : $(objdir)/$(MAIN).tex $(FIGS) $(MAIN).pdf : touch.tex $(objdir)/$(MAIN).tex $(FIGS)
cd $(objdir); pdflatex $(MAIN).tex -o ../$(MAIN).pdf cd $(objdir); pdflatex $(MAIN).tex -o ../$(MAIN).pdf
$(objdir)/$(MAIN).dvi : $(objdir)/$(MAIN).tex $(FIGS) $(objdir)/$(MAIN).dvi : $(objdir)/$(MAIN).tex $(FIGS)
......
...@@ -212,7 +212,7 @@ for more information. ...@@ -212,7 +212,7 @@ for more information.
\newpage \newpage
\section{Lurette principles } \section{The principles }
\label{lurette-func} \label{lurette-func}
...@@ -412,6 +412,9 @@ elected at the previous step (instead of {\tt boot~i}). ...@@ -412,6 +412,9 @@ elected at the previous step (instead of {\tt boot~i}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newpage \newpage
\section{The tool}
\subsection{The XLurette Main window parameters} \subsection{The XLurette Main window parameters}
\label{test-parameters} \label{test-parameters}
...@@ -496,59 +499,36 @@ is selected in a directory that is not the same as the current one. ...@@ -496,59 +499,36 @@ is selected in a directory that is not the same as the current one.
\subsubsection{The compiling modes} \subsubsection{The compiling modes}
\label{compiling-mode} \label{compiling-mode}
The SUT and the oracle can be either {\tt .saofdm}, {\tt .lus} or The SUT and the oracle can be either {\tt .saofdm}, {\tt .lus}, {\tt
{\tt .c} files. When the SUT is a {\tt .saofdm}, there is no .c}, or {\tt .ml} files. When the SUT is a {\tt .saofdm}, there is
ambiguity: the scade compiler should be used. no ambiguity: the scade compiler should be used. However, for {\tt
.lus} files, lurette needs to know whether to use the Verimag V4,
the Verimag V6, or the Scade compiler (The same holds for C files).
However, for {\tt .lus} files, lurette needs to know whether to use Users can specify the compiler mode using the combo boxes at the
the Verimag V4, the Verimag V6, or the Scade compiler. Furthermore, for {\tt .c} files, rigth-hand-side of the node names (cf,
lurette needs to know whether they follow the Verimag and the Scade Figure~\ref{main-window-part}). They can choose between:
conventions.
Users can specify the compiler mode using the
combo boxes at the rigth-hand-side of the node names (cf,
Figure~\ref{main-window-part}). They can choose between:
\begin{itemize} \begin{itemize}
\item {\tt lv4} \item {\tt lv4}
\item {\tt lv6} \item {\tt lv6}
\item {\tt scade} \item {\tt scade}
\item {\tt ocaml}
\item {\tt stdin/stdout} \item {\tt stdin/stdout}
\end{itemize} \end{itemize}
The first 3 items correspond to the verimag and the scade
conventions that we have been just talking about.
%
The third item correspond to an (experimental) completely different
execution mode. In this mode, users do not specify a SUT/oracle file
and node name, but a system call that launches a program that
reads/writes its input/output on the standard input/output
(stdin/stdout). The inputs must follow the RIF convention
(cf~Appendix\ref{rif}), and the outputs will.
%
For example, one can enter the string {\tt "ecexe heater\_control.ec"},
because the{\tt ecexe} ec files interpreter reads and writes data
on stdin/stdout following the RIF conventions.
\paragraph{Watch out:} in the {\tt verimag} and {\tt scade} modes,
the link between the SUT, the environment and the oracle is done via
{\bf variable names}, whereas in the {\tt stdin/stdout} mode, it is done
via the {\bf variable positions} of their declaration in the
interface.
More details on the different compiling modes can be found in
Sections~\ref{lustre-mode}, ~\ref{c-mode}, ~\ref{ocaml-mode},
and~\ref{stdin-mode}.
%
Note also that the test thickness parameters (cf
\ref{test-thickness}) are (currently) ignored in the {\tt
stdin/stdout} mode.
\subsubsection{The Extra Environment variables window} \subsubsection{The Extra Environment variables window}
\label{extra-var-window}
One can launch the ``Extra Environment Parameters'' window by One can launch the ``Extra Environment Parameters'' window by
clicking on the button just below the oracle line. A snapshot of clicking on the button just below the oracle line. A snapshot of
...@@ -573,10 +553,10 @@ are used in the Makefile that builds the final test executable. ...@@ -573,10 +553,10 @@ are used in the Makefile that builds the final test executable.
\begin{itemize} \begin{itemize}
\item {\tt EXTRA\_CFILES} lets one add C files. For example, the \item {\tt EXTRA\_SOURCE\_FILES} lets one add C files. For example, the
scade compiler sometimes generates a file named {\tt scade compiler sometimes generates a file named {\tt
<sut>\_const.c} that contains the definitions of the some of the <sut>\_const.c} that contains the definitions of the some of the
SUT constants. C files appearing in {\tt EXTRA\_CFILES} are SUT constants. C files appearing in {\tt EXTRA\_SOURCE\_FILES} are
compiled and linked with the SUT by lurette. compiled and linked with the SUT by lurette.
\item {\tt EXTRA\_LIBS} lets one add libraries ({\tt <file>.a}). \item {\tt EXTRA\_LIBS} lets one add libraries ({\tt <file>.a}).
\item {\tt EXTRA\_LIBDIRS} lets one add paths to directories containing librairies. \item {\tt EXTRA\_LIBDIRS} lets one add paths to directories containing librairies.
...@@ -593,7 +573,7 @@ For all those environment variables, one can put several items ...@@ -593,7 +573,7 @@ For all those environment variables, one can put several items
\subsection{The Test Parameters window} \subsection{The XLurette Test parameters window}
The ``Test Parameters window'' lets one set additional parameters; The ``Test Parameters window'' lets one set additional parameters;
one can launch it by clicking on the one can launch it by clicking on the
...@@ -742,46 +722,160 @@ It is the first part of the RIF (see~\ref{rif}) file name used to ...@@ -742,46 +722,160 @@ It is the first part of the RIF (see~\ref{rif}) file name used to
test length. test length.
%-------------------------------------------------------------------- %--------------------------------------------------------------------
%-------------------------------------------------------------------- %--------------------------------------------------------------------
\newpage \newpage
\section{Supported Architectures and languages} \subsection{Testing Lustre or Scade Programs}
\label{supported-arch} \label{lustre-mode}
Lurette has been tested with the following architectures: In order to test lustre programs, one needs to specify which compiler
should be used (cf Section~\ref{compiling-mode}). For the time being,
3 lustre compilers are supported: the Verimag Lustre V4 compiler
(lv4); the the Verimag Lustre V6 compiler (lv6); the
Esterel-Technologies Lustre compiler (scade). In the scade mode, one
can also test Scade (.saofdm) programs.
Note that a different compiling mode might be used for the oracle;
but not all the combinations are supported. More precisely,
\begin{itemize} \begin{itemize}
\item Ultra-sparc machine running Solaris 2.8; \item lv4 and lv6 modes can be mixed arbitrarily
\item i686 running Linux; \item In the the scade mode for the SUT, the oracle can be lv4, lv6,
\item i686 running WindowsNt and Cygwin. or scade
\item Otherwise, the SUT and the oracle compiling modes should be the same.
\end{itemize} \end{itemize}
\subsection{Testing C Programs}
\label{c-mode}
The System Under Test can either be: Since all lustre (and scade) compilers generates C code, any C code
that follows one of the lustre compilers convention can be used.
One's need to be very familiar with those conventions though.
\begin{itemize}
\item an academic Lustre program ({\tt .lus});
\item a Scade\footnote{only tested with the 4.2 version} program
({\tt .saofdm});
\item a C file, provided that it follows the Verimag~\cite{poc-man}
or the Scade code generators conventions.
\end{itemize}
\subsection{Testing OCaml Programs}
\label{ocaml-mode}
Is is also possible (since August 2010) to test ocaml programs using
Lurette. We suppose that readers are familiar with ocaml in this
section.
\paragraph{The SUT.}
If your SUT is in Ocaml, it must implement the following interface:
\begin{small}
\begin{example}
val init : unit -> unit
type var_type = string (* Should be "bool", "int", or "float" *)
val get_input_var_name_and_type : unit -> (string * var_type) list
val get_output_var_name_and_type : unit -> (string * var_type) list
val step : (string * Value.t) list -> (string, Value.t) Hashtbl.t
val step_try : (string * Value.t) list -> (string, Value.t) Hashtbl.t
\end{example}
\end{small}
Of course, the outputs of {\tt get\_input\_var\_name\_and\_type} and
{\tt get\_output\_var\_name\_and\_type} should be consistent with
{\tt step} and {\tt step\_try}, i.e. , the arity, and the variable
names and types should match.
{\tt step\_try} is supposed to save the current state of the SUT,
perform a {\tt step}, and restore the saved state. Hence {\tt step\_try}
is the same as {\tt step} for stateless programs.
\paragraph{The oracle.}
Similarly, oracles written in Ocaml must implement the following
interface:
\begin{small}
\begin{example}
val init : unit -> unit
type var_type = string
val get_input_var_name_and_type : unit -> (string * var_type) list
val get_output_var_name_and_type: unit -> (string * var_type) list
val step: (string * Value.t) list -> (string, Value.t) Hashtbl.t -> bool * Var.subst list
val step_try: (string * Value.t) list -> (string, Value.t) Hashtbl.t -> bool * Var.subst list
\end{example}
\end{small}
{\tt step} (and {\tt step\_try}) should return a pair made of the result
of the oracle (success or failure) and the list of oracle outputs.
Note that the oracle step takes as input the SUT inputs, and then the
SUT outputs. Hence you should make sure that the oracle inputs is
made of the SUT inputs and the SUT outputs. In other words, you
should satisfy the following assertion:
\begin{small}
\begin{example}
assert(
List.sort (compare)
(TheSut.get_input_var_name_and_type())@(TheSut.get_output_var_name_and_type())
=
List.sort (compare) (TheOracle.get_input_var_name_and_type ())
)
\end{example}
\end{small}
\paragraph{nb.}
Like in other modes, if our ocaml programs is splited into several
files, or if its uses libraries, one need to set appropriately the
parameters in the \emph{Extra Environment variables window} (cf
Section~\ref{extra-var-window}).
\subsection{Testing any Programs (using stdin/stdout and RIF conventions)}
\label{stdin-mode}
There exists a versatile (and rather experimental) mode, that is
language-agnostic. It can test any (executable) programs that reads
and writes its IO on its standard inputs and outputs using the RIF
conventions (cf Appendix~\ref{rif}). In this mode, lurette will
launch a system call using the string written in the SUT (and the
oracle) box. It can be a command with parameters.
Note that the SUT and the oracle can be in C (provided that they
follow the poc or the scade conventions), but the SUT environment For example, one can write {\tt "ecexe heater\_control.ec"} in the
descriptions needs to be in Lutin, Lustre, or Lucky. Indeed, in SUT box. Indeed, the {\tt ecexe} ec files interpreter (present in the
the Lurette testing process, the SUT and the oracle just need to be Lustre V4 distribution) reads and writes data on stdin/stdout
compiled and executed, whereas the environment description needs to following the RIF conventions.
be parsed and interpreted. %
If you have a data file that follows the RIF convention, something
like {\tt "cat my\_data\_file.rif"} ougth to work also.
\paragraph{Watch out:} the {\tt stdin/stdout} mode,
the link between the SUT, the environment and the oracle is done by
{\bf variable positions}, whereas it is done by {\bf variable names}
in all the other modes.
Note also that the test thickness parameters (cf
\ref{test-thickness}) are (currently) ignored in this mode.
%-------------------------------------------------------------------- %--------------------------------------------------------------------
%-------------------------------------------------------------------- %--------------------------------------------------------------------
\newpage \newpage
\section{Installation and configuration issues} \subsection{Installation and configuration issues}
\label{install} \label{install}
\label{supported-arch}
Lurette has been tested with the following architectures:
\begin{itemize}
\item Solaris/Sparc.
\item Linux/PC.
\item Windows/PC.
\item Mac os/PC and powermac.
\end{itemize}
In order to use Lurette, you need In order to use Lurette, you need
\begin{itemize} \begin{itemize}
...@@ -878,6 +972,7 @@ explicitely specify the full path of tools that are used by Lurette. ...@@ -878,6 +972,7 @@ explicitely specify the full path of tools that are used by Lurette.
%-------------------------------------------------------------------- %--------------------------------------------------------------------
%-------------------------------------------------------------------- %--------------------------------------------------------------------
\newpage
\input{fault-tolerant-tut} \input{fault-tolerant-tut}
......
LUTINSRC=../../source/Lutin LUTINSRC=../../source/Lutin
SRCS=./src/commands.tex \ SRCS=./commands.tex \
./src/language.tex \ ./language.tex \
./src/lutsyntax.tex \ ./lutsyntax.tex \
./src/semantics.tex \ ./semantics.tex \
./objs/lutyacc.tex \ ./objs/lutyacc.tex \
./objs/version.tex \ ./objs/version.tex \
./src/main.tex \ ./main.tex \
all: lutin-man.pdf all: lutin-man.pdf
...@@ -34,5 +34,5 @@ clean: ...@@ -34,5 +34,5 @@ clean:
rm -f ./objs/* rm -f ./objs/*
re: re:
touch $(LUTINSRC)/lutParser.mly touch $(LUTINSRC)/lutParser.mly
touch src/* touch *.tex
make make
LTOP=../../../$(HOST_TYPE)/bin/lurettetop LTOP=../../../$(HOST_TYPE)/bin/lurettetop
LURETTETOP=$(LTOP) --precision 2 --sut sut.ml \ LURETTETOP=$(LTOP) --precision 2 --sut heat_ctrl.ml \
--sut-compiler ocaml \ --sut-compiler ocaml \
--oracle-compiler ocaml --oracle oracle.ml \ --oracle-compiler ocaml --oracle not_a_sauna.ml \
--test-length 500 --thick-draw 1 \ --test-length 500 --thick-draw 1 \
--draw-inside 0 --draw-edges 0 --draw-vertices 0 --draw-all-vertices \ --draw-inside 0 --draw-edges 0 --draw-vertices 0 --draw-all-vertices \
--step-mode Inside --local-var --no-sim2chro --seed 3 \ --step-mode Inside --local-var --no-sim2chro --seed 3 \
...@@ -27,7 +27,7 @@ utest: ...@@ -27,7 +27,7 @@ utest:
clean: clean:
rm -rf *.ec *.log *~ .*~ *.o *rif0 *rif Data *.pp_luc *.plot *.gp rm -rf *.ec *.cm* *.log *~ .*~ *.o *rif0 *rif Data *.pp_luc *.plot *.gp
......
(* Time-stamp: <modified the 13/07/2010 (at 15:47) by Erwan Jahier> *) (* Time-stamp: <modified the 18/08/2010 (at 11:02) by Erwan Jahier> *)
...@@ -6,14 +6,14 @@ let init _ = () ...@@ -6,14 +6,14 @@ let init _ = ()
let pre_res = ref false let pre_res = ref false
type str_type = string type var_type = string
(* An str_type can be "bool", "int", or "float" *) (* An var_type can be "bool", "int", or "float" *)
let (get_input_var_name_and_type : unit -> (string * str_type) list) = let (get_input_var_name_and_type : unit -> (string * var_type) list) =
fun () -> ["T", "float"; "T1", "float"; "T2", "float"; "T3", "float"] fun () -> ["T", "float"; "T1", "float"; "T2", "float"; "T3", "float"]
let (get_output_var_name_and_type : unit -> (string * str_type) list) = let (get_output_var_name_and_type : unit -> (string * var_type) list) =
fun () -> ["Heat_on", "bool"] fun () -> ["Heat_on", "bool"]
...@@ -34,22 +34,13 @@ let (step : (string * Value.t) list -> (string, Value.t) Hashtbl.t) = ...@@ -34,22 +34,13 @@ let (step : (string * Value.t) list -> (string, Value.t) Hashtbl.t) =
Hashtbl.replace tbl "Heat_on" (B(res)); Hashtbl.replace tbl "Heat_on" (B(res));
tbl tbl
(* Trie save the current state of the SUT, perfoms a step, and restore the saved state let (step_try : (string * Value.t) list -> (string, Value.t) Hashtbl.t)=
nb : i cannot call it try, it is an ocaml kwd ... *)
let (trie : (string * Value.t) list -> (string, Value.t) Hashtbl.t)=
fun l -> fun l ->
step l step l
(** Where module Value defines the following types:
(** Where module Value is defined as follows:
type num = I of int | F of float type num = I of int | F of float
type t = B of bool | N of num type t = B of bool | N of num
......
(* Time-stamp: <modified the 13/07/2010 (at 15:49) by Erwan Jahier> *) (* Time-stamp: <modified the 18/08/2010 (at 11:02) by Erwan Jahier> *)
let init _ = () let init _ = ()
type str_type = string type var_type = string
(* An str_type can be "bool", "int", or "float" *) (* An var_type can be "bool", "int", or "float" *)
let (get_input_var_name_and_type : unit -> (string * str_type) list) = let (get_input_var_name_and_type : unit -> (string * var_type) list) =
fun () -> ["T", "float"; "T1", "float"; "T2", "float"; "T3", "float";"Heat_on", "bool"] fun () -> ["T", "float"; "T1", "float"; "T2", "float"; "T3", "float";"Heat_on", "bool"]
let (get_output_var_name_and_type : unit -> (string * str_type) list) = let (get_output_var_name_and_type : unit -> (string * var_type) list) =
fun () -> ["ok", "bool"] fun () -> ["ok", "bool"]
...@@ -36,9 +36,6 @@ let (step : (string * Value.t) list -> (string, Value.t) Hashtbl.t -> bool* Va ...@@ -36,9 +36,6 @@ let (step : (string * Value.t) list -> (string, Value.t) Hashtbl.t -> bool* Va
in in
ok, ["ok", (B(ok))] ok, ["ok", (B(ok))]