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

Bug#528603: Patch to add support for backtraces to oUnit



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

-- 
mouse, n: A device for pointing at the xterm in which you want to type.
Confused by the strange files?  I cryptographically sign my messages.
For more information see <http://www.elehack.net/resources/gpg>.

Attachment: pgpI53HG4NXAZ.pgp
Description: PGP signature

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)
diff -u ounit-1.0.3/debian/changelog ounit-1.0.3/debian/changelog
--- ounit-1.0.3/debian/changelog
+++ ounit-1.0.3/debian/changelog
@@ -1,3 +1,10 @@
+ounit (1.0.3-2elehack1) unstable; urgency=low
+
+  * Added support for backtraces (01_backtrace.dpatch)
+  * Added dependency on camlp4 for backtrace patch
+
+ -- Michael Ekstrand <michael@elehack.net>  Sat, 16 May 2009 11:06:13 -0500
+
 ounit (1.0.3-2) unstable; urgency=low
 
   * Update Standards-Version to 3.8.0:
diff -u ounit-1.0.3/debian/control ounit-1.0.3/debian/control
--- ounit-1.0.3/debian/control
+++ ounit-1.0.3/debian/control
@@ -6,7 +6,7 @@
 Build-Depends: cdbs (>= 0.4), 
  debhelper (>= 7), 
  dpatch, 
- ocaml-nox (>= 3.11), 
+ ocaml-nox (>= 3.11), camlp4 (>= 3.11),
  ocaml-findlib (>= 1.2.4), 
  docbook-utils, 
  dh-ocaml (>= 0.4.1)
diff -u ounit-1.0.3/debian/patches/00list ounit-1.0.3/debian/patches/00list
--- ounit-1.0.3/debian/patches/00list
+++ ounit-1.0.3/debian/patches/00list
@@ -1 +1 @@
-
+01_backtrace
only in patch2:
unchanged:
--- ounit-1.0.3.orig/debian/patches/01_backtrace.dpatch
+++ ounit-1.0.3/debian/patches/01_backtrace.dpatch
@@ -0,0 +1,105 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 01_backtrace.dpatch by  <michael@elehack.net>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Add backtrace tracking
+
+@DPATCH@
+
+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)

Reply to: