[prev in list] [next in list] [prev in thread] [next in thread] 

List:       grub-devel
Subject:    Re: Unittests
From:       BVK Chaitanya <bvk.groups () gmail ! com>
Date:       2009-12-17 6:36:38
Message-ID: d019d53c0912162224t2b85b497lb49f29b8da152ddc () mail ! gmail ! com
[Download RAW message or body]

Hi,

On Thu, Dec 17, 2009 at 5:15 AM, Carles Pina i Estany <carles@pina.cat> wrote:
>
> when I said "it's very easy" I was thinking more like "you explain to me
> how the unittest infrastructure works and I write the test" more than
> the other way. But no problem at all if you want to write it!
>

For scripted tests, unit test framework simply executes the script and
reports PASS/FAIL based on its exit status.  Attached patch has an
example_scripted_test.in

Basically, add a testcase.in (.in would make it run through autoconf
stuff, so you can use @builddir@, @srcdir@, etc. stuff in your
testcase) file into tests/ subdir and modify conf/tests.rmk file to
include your testcase, as

check_SCRIPTS += testcase
testcase_SOURCES = tests/testcase.in

and run configure and "make check".  Let me know if you face any problems.

> This is not what I wanted to test using the unittest, but I can show a
> shell script that I did last june testing for these things.
>
> carles@pinux:~/grub2/oldgrub/grubprova$ cat test.sh
> #!/bin/bash
>
> export TEXTDOMAIN="testscript"
> export TEXTDOMAINDIR="./locale"
> echo $(gettext "hello world")
>
> And then:
> carles@pinux:~/grub2/oldgrub/grubprova$ find
> .
> ./locale
> ./locale/ca
> ./locale/ca/LC_MESSAGES
> ./locale/ca/LC_MESSAGES/testscript.mo
> ./locale/ca_ES@euro.po
> ./locale/test.pot
> ./test.sh
> carles@pinux:~/grub2/oldgrub/grubprova$
>


Currently, GRUB-2 build system doesn't provide this directory
structure, we need to fix it :-(


> But what I was thinking to test with the unittest is the gettext.mod,
> not outside. I could do semi-manually doing:
> a) Different .mo files with some strings (inside /boot/grub/locale/[.mo
> files])
> b) A Grub2 disk image with the script to check the gettext module.
> Mainly would do (I'll write in pseudo-Bash, would be in Grub script):
> -------
> set lang=ca
> TESTFAILED=false
> if [ $(gettext "hello world") -ne "hola món" ]
> then
>        echo "Test failed 01!"
>        TESTFAILED=true
> fi
>
> if [ ... ]
> then
>        echo "Test failed 02!"
>        TESTFAILED=true
> fi
>
> set lang=es
>
> if [ ... ]
> then
>
> fi
>
> if [ $TESTFAILED -eq "true" ]
> then
>        echo "TESTS FAILEDS"
> fi
> -------
>
> So when I do changes in gettext module (like optimizse something, add
> support for plurals, etc. etc.) I would be sure that everything is all
> right.
>
> Was you thinking something like this?
>

Well, not exactly!  Since $(gettext "hello world") output must be same
in grub-shell environment and regular bash-shell, we can automate most
of the test case failures.  For example, for below script, we expect
the output to be same both on grub-shell and bash-shell

#! grub-tester
gettext "hello world"
LANG="zh_CN" gettext "helloworld"

so *if* we can write an interpreter (like, grub-tester above) that
executes given script in both shells and compares the output
automatically, our unit tests would be a lot easier.  A testcase
failure should be raised by grub-tester if it finds that grub-shell
output is different than bash-shell output for that script :-)  Of
course, testcase should use only those commands that are valid in both
grub and bash.

For this to work we need a script to start grub image inside qemu with
user specified script and capture its output.

   Earlier I thought we could use grub-qemu port, but i am now
convinced that grub-mkrescue tool is sufficient.  I am half way in
doing this already.  I hit these below problems, but i have
workarounds in mind:

  a.  Option for not to display grub prompt (add PS1 environment variable ???)
  b.  Option to set noecho flag to tty.
  c.  Option to disable NCURSES escape sequences for serial terminal
(add TERM=dumb support ???)

Currently I am trying to cleanup escape sequences, grub> prompt and
echoed characters from serial port output captured from grub;
hopefully it should do for some time.



regards,
-- 
bvk.chaitanya

["unit-testing-framework-on-exp-1432.patch.txt" (text/plain)]

=== modified file 'Makefile.in'
--- old/Makefile.in	2009-12-13 20:25:49 +0000
+++ new/Makefile.in	2009-12-17 06:13:08 +0000
@@ -138,6 +138,7 @@
 SCRIPTS = $(bin_SCRIPTS) $(sbin_SCRIPTS) $(grub-mkconfig_SCRIPTS) \
 	$(lib_SCRIPTS)
 INFOS = $(info_INFOS)
+TESTS = $(check_TESTS) $(check_SCRIPTS) $(check_MODULES)
 
 CLEANFILES =
 MOSTLYCLEANFILES =
@@ -168,6 +169,9 @@
 -include $(wildcard $(GRUB_CONTRIB)/*/conf/common.mk)
 endif
 
+# For tests.
+include $(srcdir)/conf/tests.mk
+
 ### General targets.
 
 CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo
@@ -452,7 +456,15 @@
 	@echo "$(distdir).tar.gz is ready for distribution" | \
 	  sed 'h;s/./=/g;p;x;p;x'
 
-check:
+check: all $(TESTS)
+	@list="$(check_TESTS) $(check_SCRIPTS)"; \
+	for file in $$list; do \
+	  if $(builddir)/$$file; then \
+	    echo "$$file: PASS"; \
+	  else \
+	    echo "$$file: FAIL"; \
+	  fi; \
+	done
 
 .SUFFIX:
 .SUFFIX: .c .o .S .d

=== added file 'conf/tests.rmk'
--- old/conf/tests.rmk	1970-01-01 00:00:00 +0000
+++ new/conf/tests.rmk	2009-12-17 06:14:48 +0000
@@ -0,0 +1,30 @@
+# -*- makefile -*-
+
+check_MODULES += functional_test.mod
+functional_test_mod_SOURCES = tests/functional_test.c tests/test.c
+functional_test_mod_CFLAGS  = $(COMMON_CFLAGS)
+functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Unit tests
+
+check_TESTS += example_unit_test
+example_unit_test_SOURCES = tests/example_unit_test.c kern/list.c kern/misc.c \
tests/test.c tests/unit_test.c +example_unit_test_CFLAGS  = -Wno-format
+
+check_TESTS += grub_sprintf
+grub_sprintf_SOURCES = tests/grub_sprintf.c kern/misc.c kern/list.c tests/test.c \
tests/unit_test.c +grub_sprintf_CFLAGS  = -Wno-error -Wno-format
+
+# Functional tests
+
+check_MODULES += example_functional_test.mod
+example_functional_test_mod_SOURCES = tests/example_functional_test.c
+example_functional_test_mod_CFLAGS  = -Wno-format $(COMMON_CFLAGS)
+example_functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Scripted tests
+
+check_SCRIPTS += example_scripted_test
+example_scripted_test_SOURCES = tests/example_scripted_test.in
+
+

=== modified file 'genmk.rb'
--- old/genmk.rb	2009-12-13 20:25:49 +0000
+++ new/genmk.rb	2009-12-17 06:11:05 +0000
@@ -413,7 +413,7 @@
 	    PModule.new(prefix, pmod)
 	  end
 
-	when 'UTILITIES'
+	when 'UTILITIES', 'TESTS'
 	  utils += args.split(/\s+/).collect do |util|
 	    Utility.new(prefix, util)
 	  end

=== added file 'include/grub/test.h'
--- old/include/grub/test.h	1970-01-01 00:00:00 +0000
+++ new/include/grub/test.h	2009-12-17 06:11:05 +0000
@@ -0,0 +1,84 @@
+#ifndef GRUB_TEST_HEADER
+#define GRUB_TEST_HEADER
+
+#include <grub/dl.h>
+#include <grub/list.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+struct grub_test
+{
+  /* The next test.  */
+  struct grub_test *next;
+
+  /* The test name.  */
+  char *name;
+
+  /* The test main function.  */
+  void (*main) (void);
+};
+typedef struct grub_test *grub_test_t;
+
+extern grub_test_t EXPORT_VAR (grub_test_list);
+
+void EXPORT_FUNC (grub_test_register) (const char *name, void (*test) (void));
+
+void EXPORT_FUNC (grub_test_unregister) (const char *name);
+
+/* Execute a test and print results.  */
+int grub_test_run (const char *name);
+
+/* Test `cond' for nonzero; log failure otherwise.  */
+void grub_test_nonzero (int cond, const char *file,
+			const char *func, grub_uint32_t line,
+			const char *fmt, ...)
+  __attribute__ ((format (printf, 5, 6)));
+
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+#  define __func__ __FUNCTION__
+# else
+#  define __func__ "<unknown>"
+# endif
+#endif
+
+/* Macro to fill in location details and an optional error message.  */
+#define grub_test_assert(cond, ...)			\
+  grub_test_nonzero(cond, __FILE__, __func__, __LINE__, \
+		    ## __VA_ARGS__,			\
+		    "assert failed: %s", #cond)
+
+/* Macro to define a unit test.  */
+#define GRUB_UNIT_TEST(name, funp)		\
+  void grub_unit_test_init (void)		\
+  {						\
+    grub_test_register (name, funp);		\
+  }						\
+						\
+  void grub_unit_test_fini (void)		\
+  {						\
+    grub_test_unregister (name);		\
+  }
+
+/* Macro to define a functional test.  */
+#define GRUB_FUNCTIONAL_TEST(name, funp)	\
+  GRUB_MOD_INIT(functional_test_##funp)		\
+  {						\
+    grub_test_register (name, funp);		\
+  }						\
+						\
+  GRUB_MOD_FINI(functional_test_##funp)		\
+  {						\
+    grub_test_unregister (name);		\
+  }
+
+/* Functions that are defined differently for unit and functional tests.  */
+void *grub_test_malloc (grub_size_t size);
+void grub_test_free (void *ptr);
+char *grub_test_strdup (const char *str);
+int grub_test_vsprintf (char *str, const char *fmt, va_list args);
+int grub_test_printf (const char *fmt, ...)
+  __attribute__ ((format (printf, 1, 2)));
+
+#endif /* ! GRUB_TEST_HEADER */

=== added directory 'tests'
=== added file 'tests/example_functional_test.c'
--- old/tests/example_functional_test.c	1970-01-01 00:00:00 +0000
+++ new/tests/example_functional_test.c	2009-12-17 06:11:05 +0000
@@ -0,0 +1,17 @@
+/* All tests need to include test.h for GRUB testing framework.  */
+#include <grub/test.h>
+
+/* Functional test main method.  */
+static void
+example_test (void)
+{
+  /* Check if 1st argument is true and report with default error message.  */
+  grub_test_assert (1 == 1);
+
+  /* Check if 1st argument is true and report with custom error message.  */
+  grub_test_assert (2 == 2, "2 equal 2 expected");
+  grub_test_assert (2 == 3, "2 is not equal to %d", 3);
+}
+
+/* Register example_test method as a functional test.  */
+GRUB_FUNCTIONAL_TEST ("example_functional_test", example_test);

=== added file 'tests/example_scripted_test.in'
--- old/tests/example_scripted_test.in	1970-01-01 00:00:00 +0000
+++ new/tests/example_scripted_test.in	2009-12-17 06:11:05 +0000
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+
+true

=== added file 'tests/example_unit_test.c'
--- old/tests/example_unit_test.c	1970-01-01 00:00:00 +0000
+++ new/tests/example_unit_test.c	2009-12-17 06:11:05 +0000
@@ -0,0 +1,20 @@
+/* Unit tests are normal programs, so they can include C library.  */
+#include <string.h>
+
+/* All tests need to include test.h for GRUB testing framework.  */
+#include <grub/test.h>
+
+/* Unit test main method.  */
+static void
+example_test (void)
+{
+  /* Check if 1st argument is true and report with default error message.  */
+  grub_test_assert (1 == 1);
+
+  /* Check if 1st argument is true and report with custom error message.  */
+  grub_test_assert (2 == 2, "2 equal 2 expected");
+  grub_test_assert (2 == 3, "2 is not equal to %d", 3);
+}
+
+/* Register example_test method as a unit test.  */
+GRUB_UNIT_TEST ("example_unit_test", example_test);

=== added file 'tests/functional_test.c'
--- old/tests/functional_test.c	1970-01-01 00:00:00 +0000
+++ new/tests/functional_test.c	2009-12-17 06:11:05 +0000
@@ -0,0 +1,89 @@
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/test.h>
+
+void *
+grub_test_malloc (grub_size_t size)
+{
+  return grub_malloc (size);
+}
+
+void
+grub_test_free (void *ptr)
+{
+  grub_free (ptr);
+}
+
+int
+grub_test_vsprintf (char *str, const char *fmt, va_list args)
+{
+  return grub_vsprintf (str, fmt, args);
+}
+
+char *
+grub_test_strdup (const char *str)
+{
+  return grub_strdup (str);
+}
+
+int
+grub_test_printf (const char *fmt, ...)
+{
+  int r;
+  va_list ap;
+
+  va_start (ap, fmt);
+  r = grub_vprintf (fmt, ap);
+  va_end (ap);
+
+  return r;
+}
+
+static grub_err_t
+grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)),
+		      int argc, char **args __attribute__ ((unused)))
+{
+  int i;
+  int status;
+  grub_test_t test;
+
+  auto int print_name (grub_test_t test);
+  int print_name (grub_test_t test)
+  {
+    grub_printf ("%s\n", test->name);
+    return 0;
+  }
+
+  if (!argc)
+    {
+      grub_list_iterate (GRUB_AS_LIST (grub_test_list),
+			 (grub_list_hook_t) print_name);
+      return GRUB_ERR_NONE;
+    }
+
+  status = 0;
+  for (i = 0; i < argc; i++)
+    {
+      test = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_test_list),
+				   args[i]);
+      status = grub_test_run (test->name) ? : status;
+    }
+
+  return status;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT (functional_test)
+{
+  cmd = grub_register_extcmd ("functional_test", grub_functional_test,
+			      GRUB_COMMAND_FLAG_CMDLINE,
+			      "functional_test [name ...]",
+			      "Run or list functional tests.", 0);
+}
+
+GRUB_MOD_FINI (functional_test)
+{
+  grub_unregister_extcmd (cmd);
+}

=== added file 'tests/grub_sprintf.c'
--- old/tests/grub_sprintf.c	1970-01-01 00:00:00 +0000
+++ new/tests/grub_sprintf.c	2009-12-17 06:11:05 +0000
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <grub/test.h>
+#include <grub/misc.h>
+
+#define TEST(type,fmt,val)				\
+  do {							\
+    int r1, r2;						\
+    char b1[1024];					\
+    char b2[1024];					\
+							\
+    b1[0] = b2[0] = '\0';				\
+    r1 = sprintf (b1, fmt, val);			\
+    r2 = grub_sprintf (b2, fmt, val);			\
+							\
+    grub_test_assert (strcmp (b1, b2) == 0,		\
+		      "for (\"%s\","type") "		\
+		      "result should be (\"%s\",%d) "	\
+		      "but got (\"%s\",%d)",		\
+		      fmt, val, b1, r1, b2, r2);	\
+							\
+    grub_test_assert (r1 == r2,				\
+		      "for (\"%s\","type") "		\
+		      "result should be (\"%s\",%d) "	\
+		      "but got (\"%s\",%d)",		\
+		      fmt, val, b1, r1, b2, r2);	\
+  } while (0)
+
+#define D(fmt,v) TEST("%d",fmt,v)
+#define U(fmt,v) TEST("%u",fmt,v)
+#define x(fmt,v) TEST("%x",fmt,v)
+#define X(fmt,v) TEST("%X",fmt,v)
+#define P(fmt,v) TEST("%p",fmt,v)
+#define S(fmt,s) TEST("%s",fmt,s)
+
+static void
+sprintf_checks (void)
+{
+  D ("%d", -1);
+  D ("%d", 0);
+  D ("%d", 1);
+  D ("%5d", -1);
+  D ("%5d", 0);
+  D ("%5d", 1);
+  D ("%-5d", -1);
+  D ("%-5d", 0);
+  D ("%-5d", 1);
+  D ("%.5d", -1);
+  D ("%.5d", 0);
+  D ("%.5d", 1);
+  D ("%5.0d", -1);
+  D ("%5.0d", 0);
+  D ("%5.0d", 1);
+  D ("%-5.0d", -1);
+  D ("%-5.0d", 0);
+  D ("%-5.0d", 1);
+
+  U ("%d", -1);
+  U ("%d", 0);
+  U ("%d", 1);
+  U ("%5d", -1);
+  U ("%5d", 0);
+  U ("%5d", 1);
+  U ("%-5d", -1);
+  U ("%-5d", 0);
+  U ("%-5d", 1);
+  U ("%.5d", -1);
+  U ("%.5d", 0);
+  U ("%.5d", 1);
+  U ("%5.0d", -1);
+  U ("%5.0d", 0);
+  U ("%5.0d", 1);
+  U ("%-5.0d", -1);
+  U ("%-5.0d", 0);
+  U ("%-5.0d", 1);
+
+  x ("%d", -1);
+  x ("%d", 0);
+  x ("%d", 1);
+  x ("%5d", -1);
+  x ("%5d", 0);
+  x ("%5d", 1);
+  x ("%-5d", -1);
+  x ("%-5d", 0);
+  x ("%-5d", 1);
+  x ("%.5d", -1);
+  x ("%.5d", 0);
+  x ("%.5d", 1);
+  x ("%5.0d", -1);
+  x ("%5.0d", 0);
+  x ("%5.0d", 1);
+  x ("%-5.0d", -1);
+  x ("%-5.0d", 0);
+  x ("%-5.0d", 1);
+
+  X ("%d", -1);
+  X ("%d", 0);
+  X ("%d", 1);
+  X ("%5d", -1);
+  X ("%5d", 0);
+  X ("%5d", 1);
+  X ("%-5d", -1);
+  X ("%-5d", 0);
+  X ("%-5d", 1);
+  X ("%.5d", -1);
+  X ("%.5d", 0);
+  X ("%.5d", 1);
+  X ("%5.0d", -1);
+  X ("%5.0d", 0);
+  X ("%5.0d", 1);
+  X ("%-5.0d", -1);
+  X ("%-5.0d", 0);
+  X ("%-5.0d", 1);
+
+  P ("%p", NULL);
+  P ("%p", sprintf_checks);
+
+  S ("%s", (char *) NULL);
+  S ("%s", "abcd");
+  S ("%10s", "abcd");
+  S ("%10.5s", "abcdefgh");
+  S ("%10.5s", "ab");
+  S ("%2.5s", "a");
+  S ("%2.5s", "abcdefgh");
+
+  D ("%4.2d", 1);
+  D ("%4.2d", 12);
+  D ("%4.2d", 123);
+  D ("%4.2d", 1234);
+  D ("%4.2d", 12345);
+  D ("%3.3d", 12);
+  D ("%3.3d", 123);
+  D ("%3.3d", 1234);
+  D ("%2.4d", 12345);
+  D ("%2.4d", 1234);
+  D ("%2.4d", 123);
+  D ("%2.4d", 12);
+  D ("%2.4d", 1);
+  D ("%.0d", 0);
+  D ("%.0d", 1);
+
+  S ("%4.2s", "1");
+  S ("%4.2s", "12");
+  S ("%4.2s", "123");
+  S ("%4.2s", "1234");
+  S ("%4.2s", "12345");
+  S ("%3.3s", "12");
+  S ("%3.3s", "123");
+  S ("%3.3s", "1234");
+  S ("%2.4s", "12345");
+  S ("%2.4s", "1234");
+  S ("%2.4s", "123");
+  S ("%2.4s", "12");
+  S ("%2.4s", "1");
+
+  /* add few more here, if necessary  */
+}
+
+GRUB_UNIT_TEST ("grub_sprintf", sprintf_checks);

=== added file 'tests/test.c'
--- old/tests/test.c	1970-01-01 00:00:00 +0000
+++ new/tests/test.c	2009-12-17 06:11:05 +0000
@@ -0,0 +1,150 @@
+#include <grub/misc.h>
+#include <grub/test.h>
+
+struct grub_test_failure
+{
+  /* The next failure.  */
+  struct grub_test_failure *next;
+
+  /* The test source file name.  */
+  char *file;
+
+  /* The test function name.  */
+  char *funp;
+
+  /* The test call line number.  */
+  grub_uint32_t line;
+
+  /* The test failure message.  */
+  char *message;
+};
+typedef struct grub_test_failure *grub_test_failure_t;
+
+grub_test_t grub_test_list;
+static grub_test_failure_t failure_list;
+
+static void
+add_failure (const char *file,
+	     const char *funp,
+	     grub_uint32_t line, const char *fmt, va_list args)
+{
+  char buf[1024];
+  grub_test_failure_t failure;
+
+  failure = (grub_test_failure_t) grub_test_malloc (sizeof (*failure));
+  if (!failure)
+    return;
+
+  grub_test_vsprintf (buf, fmt, args);
+
+  failure->file = grub_test_strdup (file ? : "<unknown_file>");
+  failure->funp = grub_test_strdup (funp ? : "<unknown_function>");
+  failure->line = line;
+  failure->message = grub_test_strdup (buf);
+
+  grub_list_push (GRUB_AS_LIST_P (&failure_list), GRUB_AS_LIST (failure));
+}
+
+void
+free_failures (void)
+{
+  grub_test_failure_t item;
+
+  while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0)
+    {
+      if (item->message)
+	grub_test_free (item->message);
+
+      if (item->funp)
+	grub_test_free (item->funp);
+
+      if (item->file)
+	grub_test_free (item->file);
+
+      grub_test_free (item);
+    }
+  failure_list = 0;
+}
+
+void
+grub_test_nonzero (int cond,
+		   const char *file,
+		   const char *funp, grub_uint32_t line, const char *fmt, ...)
+{
+  va_list ap;
+
+  if (cond)
+    return;
+
+  va_start (ap, fmt);
+  add_failure (file, funp, line, fmt, ap);
+  va_end (ap);
+}
+
+void
+grub_test_register (const char *name, void (*test_main) (void))
+{
+  grub_test_t test;
+
+  test = (grub_test_t) grub_test_malloc (sizeof (*test));
+  if (!test)
+    return;
+
+  test->name = grub_test_strdup (name);
+  test->main = test_main;
+
+  grub_list_push (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test));
+}
+
+void
+grub_test_unregister (const char *name)
+{
+  grub_test_t test;
+
+  test = (grub_test_t) grub_named_list_find
+    (GRUB_AS_NAMED_LIST (grub_test_list), name);
+
+  if (test)
+    {
+      grub_list_remove (GRUB_AS_LIST_P (&grub_test_list),
+			GRUB_AS_LIST (test));
+
+      if (test->name)
+	grub_test_free (test->name);
+
+      grub_test_free (test);
+    }
+}
+
+int
+grub_test_run (const char *name)
+{
+  grub_test_t test;
+
+  auto int print_failure (grub_test_failure_t item);
+  int print_failure (grub_test_failure_t item)
+  {
+    grub_test_failure_t failure = (grub_test_failure_t) item;
+
+    grub_test_printf (" %s:%s:%u: %s\n",
+		      (failure->file ? : "<unknown_file>"),
+		      (failure->funp ? : "<unknown_function>"),
+		      failure->line, (failure->message ? : "<no message>"));
+    return 0;
+  }
+
+  test = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_test_list), name);
+  if (!test)
+    return GRUB_ERR_FILE_NOT_FOUND;
+
+  test->main ();
+
+  if (!failure_list)
+    return GRUB_ERR_NONE;
+
+  grub_test_printf ("%s:\n", test->name);
+  grub_list_iterate (GRUB_AS_LIST (failure_list),
+		     (grub_list_hook_t) print_failure);
+  free_failures ();
+  return GRUB_ERR_TEST_FAILURE;
+}

=== added file 'tests/unit_test.c'
--- old/tests/unit_test.c	1970-01-01 00:00:00 +0000
+++ new/tests/unit_test.c	2009-12-17 06:11:05 +0000
@@ -0,0 +1,122 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <grub/list.h>
+#include <grub/test.h>
+#include <grub/handler.h>
+
+void *
+grub_test_malloc (grub_size_t size)
+{
+  return malloc (size);
+}
+
+void
+grub_test_free (void *ptr)
+{
+  free (ptr);
+}
+
+int
+grub_test_vsprintf (char *str, const char *fmt, va_list args)
+{
+  return vsprintf (str, fmt, args);
+}
+
+char *
+grub_test_strdup (const char *str)
+{
+  return strdup (str);
+}
+
+int
+grub_test_printf (const char *fmt, ...)
+{
+  int r;
+  va_list ap;
+
+  va_start (ap, fmt);
+  r = vprintf (fmt, ap);
+  va_end (ap);
+
+  return r;
+}
+
+int
+main (int argc __attribute__ ((unused)),
+      char *argv[] __attribute__ ((unused)))
+{
+  int status = 0;
+
+  extern void grub_unit_test_init (void);
+  extern void grub_unit_test_fini (void);
+
+  auto int run_test (grub_test_t test);
+  int run_test (grub_test_t test)
+  {
+    status = grub_test_run (test->name) ? : status;
+    return 0;
+  }
+
+  grub_unit_test_init ();
+  grub_list_iterate (GRUB_AS_LIST (grub_test_list),
+		     (grub_list_hook_t) run_test);
+  grub_unit_test_fini ();
+
+  exit (status);
+}
+
+/* Other misc. functions necessary for successful linking.  */
+
+char *
+grub_env_get (const char *name __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+grub_err_t
+grub_error (grub_err_t n, const char *fmt, ...)
+{
+  va_list ap;
+
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+
+  return n;
+}
+
+void *
+grub_malloc (grub_size_t size)
+{
+  return malloc (size);
+}
+
+void
+grub_refresh (void)
+{
+  fflush (stdout);
+}
+
+void
+grub_putchar (int c)
+{
+  putchar (c);
+}
+
+int
+grub_getkey (void)
+{
+  return -1;
+}
+
+void
+grub_exit (void)
+{
+  exit (1);
+}
+
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic