[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#528603: [michael@elehack.net: Bug#528603: Patch to add support for backtraces to oUnit]



Hello,

You will find attached to this mail a patch to add extra information
(from Michael Ekstrand).

It uses pa_macro to keep compatibility with < 3.11 ocaml version.

Regards
Sylvain Le Gall

ps: if you want to discuss further this patch with Mr Ekstrand and I,
keep the bug number in CC.

----- Forwarded message from Michael Ekstrand <michael@elehack.net> -----

From: Michael Ekstrand <michael@elehack.net>
Date: Sat, 16 May 2009 11:45:20 -0500

Sylvain Le Gall <gildor@debian.org> writes:
> On Fri, May 15, 2009 at 04:02:11PM -0500, Michael Ekstrand wrote:
>> Attached is a patch for oUnit which does the following:
>> 
>>  - Augments RError and RFailure with an additional string option element
>>    to store a backtrace.
>>  - Adds code to test runner to store the backtrace in the result if
>>    backtraces are enabled.
>>  - Adds code to reporting to print backtraces with the error/failure
>>    report.
>
> Is the backtrace functions not 3.11 specific ? If this is the case, it
> should be better to allow some kind of macro to enable/disable it to
> compile oUnit with at least OCaml 3.10.

It is 3.11-specific.  I have attached a new patch which uses pa_macro to
provide compatibility with OCaml 3.10.  The method for detecting whether
to enable backtrace support works on Debian; I have not tested it in
other OCaml environments, but I expect it should work (it uses ocamlc
-where to locate printexc.mli, and then greps it for get_backtrace).
Further, this patch does not have the additional string option parameter
in failure and error results, preferring instead to include the
backtrace in the failure message itself.  This change is to avoid
breaking compatibility with client code which uses the test result types
directly.

I have also attached a debdiff patch which builds the Debian package
with the backtrace patch.

>>  - Modifies the Makefile to compile everything with -g (so stack traces
>>    don't get lost in oUnit).
>> 
>
> If you use -g in oUnit, you will get the backtrace from oUnit function ?
> or if you don't use -g you will loose all backtrace ?
>
> If you only lost oUnit backtrace, I think you should not enable -g for
> oUnit, since oUnit function is not very interesting for debugging.

You only lose oUnit backtraces, but some of the interesting exceptions
are thrown via oUnit functions (e.g. assert_equal).  I think that the
backtrace will contain stack elements on both sides of an oUnit call if
oUnit does not have debugging information, but I have not specifically
tested this.  If this is the case, I think it becomes a matter of
preference; I tend to prefer seeing my backtraces as complete as
possible (I don't like seeing "unknown location" in the trace if it can
be avoided).

- Michael


Content-Description: Second version of backtrace patch
Print backtraces for errors and failures.
---
 Makefile |   13 ++++++++++---
 oUnit.ml |   20 +++++++++++++-------
 2 files changed, 23 insertions(+), 10 deletions(-)

Index: ounit-dev/oUnit.ml
===================================================================
--- ounit-dev.orig/oUnit.ml	2009-05-15 15:59:37.000000000 -0500
+++ ounit-dev/oUnit.ml	2009-05-16 10:34:22.000000000 -0500
@@ -259,15 +259,15 @@
 
 let result_path = function
     RSuccess path 
-  | RError (path, _) 
-  | RFailure (path, _) 
+  | RError (path, _)
+  | RFailure (path, _)
   | RSkip (path, _)
   | RTodo (path, _) -> path
 
 let result_msg = function
     RSuccess _ -> "Success"
-  | RError (_, msg) 
-  | RFailure (_, msg) 
+  | RError (_, msg)
+  | RFailure (_, msg)
   | RSkip (_, msg)
   | RTodo (_, msg) -> msg
 
@@ -287,6 +287,12 @@
   | EEnd of path
   | EResult of test_result
 
+DEFINE MAYBE_BACKTRACE = IFDEF BACKTRACE THEN
+    (if Printexc.backtrace_status () then
+       "\n" ^ Printexc.get_backtrace ()
+     else "")
+    ELSE "" ENDIF
+
 (* Run all tests, report starts, errors, failures, and return the results *)
 let perform_test report test =
   let run_test_case f path =
@@ -294,10 +300,10 @@
       f ();
       RSuccess path
     with
-	Failure s -> RFailure (path, s)
+	Failure s -> RFailure (path, s ^ MAYBE_BACKTRACE)
       | Skip s -> RSkip (path, s)
       | Todo s -> RTodo (path, s)
-      | s -> RError (path, (Printexc.to_string s))
+      | s -> RError (path, (Printexc.to_string s) ^ MAYBE_BACKTRACE)
   in
   let rec run_test path results test = 
     match test with 
@@ -334,7 +340,7 @@
 	if verbose then "ok\n" else "."
     | RFailure (_, _) ->
 	if verbose then "FAIL\n" else "F"
-    | RError (_, _) -> 
+    | RError (_, _) ->
 	if verbose then "ERROR\n" else "E"
     | RSkip (_, _) ->
 	if verbose then "SKIP\n" else "S"
Index: ounit-dev/Makefile
===================================================================
--- ounit-dev.orig/Makefile	2009-05-15 15:59:37.000000000 -0500
+++ ounit-dev/Makefile	2009-05-16 10:50:55.000000000 -0500
@@ -9,10 +9,14 @@
 ARCHIVE=oUnit.cma
 XARCHIVE=$(ARCHIVE:.cma=.cmxa)
 
+PRINTEXC_MLI=$(shell ocamlc -where)/printexc.mli
+
+OCAMLPP_DEFINES=$(shell grep get_backtrace $(PRINTEXC_MLI) >/dev/null && echo -DBACKTRACE)
+OCAMLPP=-pp "camlp4o pa_macro.cmo $(OCAMLPP_DEFINES)"
 OCAMLRUN=ocamlrun
-OCAMLC=ocamlc
-OCAMLOPT=ocamlopt
-OCAMLDEP=ocamldep
+OCAMLC=ocamlc $(OCAMLPP) -g
+OCAMLOPT=ocamlopt $(OCAMLPP)
+OCAMLDEP=ocamldep $(OCAMLPP)
 MKLIB=ocamlmklib
 OCAMLDOC=ocamldoc
 OCAMLFIND=ocamlfind
@@ -24,6 +28,9 @@
 all: $(ARCHIVE)
 allopt: $(XARCHIVE)
 
+debug:
+	@echo Printexc: $(PRINTEXC_MLI)
+	@echo Macros: $(OCAMLPP_DEFINES)
 $(ARCHIVE): $(OBJECTS)
 	$(OCAMLC) -a -o $(ARCHIVE) $(OBJECTS)
 $(XARCHIVE): $(XOBJECTS)

Attachment: signature.asc
Description: Digital signature


Reply to: