]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/cunit/lib/common/Basic/Basic.c
Update
[l4.git] / l4 / pkg / cunit / lib / common / Basic / Basic.c
1 /*!
2  * \file   lib/src/Basic/Basic.c
3  * \brief  
4  *
5  * \date   01/30/2007
6  * \author Bjoern Doebel <doebel@os.inf.tu-dresden.de
7  *
8  */
9 /*
10  * (c) 2007-2009 Technische Universität Dresden
11  * This file is part of TUD:OS and distributed under the terms of the
12  * GNU General Public License 2.
13  * Please see the COPYING-GPL-2 file for details.
14  */
15 /*
16  *  CUnit - A Unit testing framework library for C.
17  *  Copyright (C) 2004, 2005  Anil Kumar, Jerry St.Clair
18  *
19  *  This library is free software; you can redistribute it and/or
20  *  modify it under the terms of the GNU Library General Public
21  *  License as published by the Free Software Foundation; either
22  *  version 2 of the License, or (at your option) any later version.
23  *
24  *  This library is distributed in the hope that it will be useful,
25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27  *  Library General Public License for more details.
28  *
29  *  You should have received a copy of the GNU Library General Public
30  *  License along with this library; if not, write to the Free Software
31  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
32  */
33
34 /*
35  *  Implementation for basic test runner interface.
36  *
37  *  Created By  : Jerry St.Clair  (11-Aug-2004)
38  *  Comment     : Initial implementation of basic test runner interface
39  *  EMail       : jds2@users.sourceforge.net
40  *
41  *  Modified    : 8-Jan-2005 (JDS)
42  *  Comment     : Fixed reporting bug (bug report cunit-Bugs-1093861).
43  *  Email       : jds2@users.sourceforge.net
44  *
45  *  Modified    : 30-Apr-2005 (JDS)
46  *  Comment     : Added notification of suite cleanup failure.
47  *  Email       : jds2@users.sourceforge.net
48  */
49
50 /** @file
51  * Basic interface with output to stdout.
52  */
53 /** @addtogroup Basic
54  * @{
55  */
56
57 #ifndef DDE_LINUX
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <ctype.h>
61 #include <assert.h>
62 #include <string.h>
63
64 #include <l4/log/log.h>
65 #else
66 #include "dde_support.h"
67 #endif
68
69 #include <CUnit.h>
70 #include <TestDB.h>
71 #include <Util.h>
72 #include <TestRun.h>
73 #include <Basic.h>
74
75 /** Pointer to the currently running suite. */
76 static CU_pSuite f_pRunningSuite = NULL;
77 /** Current run mode. */
78 static CU_BasicRunMode f_run_mode = CU_BRM_NORMAL;
79
80 /* Forward declaration of module functions */
81 static CU_ErrorCode basic_initialize(void);
82 static CU_ErrorCode basic_run_all_tests(CU_pTestRegistry pRegistry);
83 static CU_ErrorCode basic_run_suite(CU_pSuite pSuite);
84 static CU_ErrorCode basic_run_single_test(CU_pSuite pSuite, CU_pTest pTest);
85
86 static void basic_test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite);
87 static void basic_test_complete_message_handler(const CU_pTest pTest, const CU_pSuite pSuite, const CU_pFailureRecord pFailureList);
88 static void basic_all_tests_complete_message_handler(const CU_pFailureRecord pFailure);
89 static void basic_suite_init_failure_message_handler(const CU_pSuite pSuite);
90 static void basic_suite_cleanup_failure_message_handler(const CU_pSuite pSuite);
91
92 /*------------------------------------------------------------------------*/
93 /** Run all registered CUnit tests using the basic interface.
94  *  The default CU_BasicRunMode is used unless it has been
95  *  previously changed using CU_basic_set_mode().  The CUnit test
96  *  registry must have been initialized before calling this function.
97  *  @return A CU_ErrorCode indicating the framework error condition, including
98  *          CUE_NOREGISTRY - Registry has not been initialized.
99  */
100 CU_ErrorCode CU_basic_run_tests(void)
101 {
102   CU_ErrorCode error;
103
104   if (NULL == CU_get_registry()) {
105     if (CU_BRM_SILENT != f_run_mode)
106       LOG_printf("\n\nFATAL ERROR - Test registry is not initialized.\n");
107     error = CUE_NOREGISTRY;
108   }
109   else if (CUE_SUCCESS == (error = basic_initialize()))
110     error = basic_run_all_tests(NULL);
111
112   return error;
113 }
114
115 /*------------------------------------------------------------------------*/
116 /** Run all tests for a specific suite in the basic interface.
117  *  If pSuite is NULL, the function returns without taking any
118  *  action. The default CU_BasicRunMode is used unless it has
119  *  been changed using CU_basic_set_mode().
120  *  @param pSuite The CU_Suite to run.
121  *  @return A CU_ErrorCode indicating the framework error condition, including
122  *          CUE_NOSUITE - pSuite was NULL.
123  */
124 CU_ErrorCode CU_basic_run_suite(CU_pSuite pSuite)
125 {
126   CU_ErrorCode error;
127
128   if (NULL != pSuite)
129     error = CUE_NOSUITE;
130   else if (CUE_SUCCESS == (error = basic_initialize()))
131     error = basic_run_suite(pSuite);
132
133   return error;
134 }
135
136 /*------------------------------------------------------------------------*/
137 /** Run a single test in a specific suite in the basic interface.
138  *  If pSuite or pTest is NULL, the function returns without
139  *  taking any action.  The default CU_BasicRunMode is used unless
140  *  it has been changed using CU_basic_set_mode.
141  *  @param pSuite The CU_Suite holding the CU_Test to run.
142  *  @param pTest  The CU_Test to run.
143  *  @return A CU_ErrorCode indicating the framework error condition, including
144  *          CUE_NOSUITE - pSuite was NULL.
145  *          CUE_NOTEST  - pTest was NULL.
146  */
147 CU_ErrorCode CU_basic_run_test(CU_pSuite pSuite, CU_pTest pTest)
148 {
149   CU_ErrorCode error;
150
151   if (NULL != pSuite)
152     error = CUE_NOSUITE;
153   else if (NULL != pTest)
154     error = CUE_NOTEST;
155   else if (CUE_SUCCESS == (error = basic_initialize()))
156     error = basic_run_single_test(pSuite, pTest);
157
158   return error;
159 }
160
161 /*------------------------------------------------------------------------*/
162 /** Set the run mode for the basic interface.
163  *  @param mode The new CU_BasicRunMode for subsequent test
164  *              runs using the basic interface.
165  */
166 void CU_basic_set_mode(CU_BasicRunMode mode)
167 {
168   f_run_mode = mode;
169 }
170
171 /*------------------------------------------------------------------------*/
172 /** Retrieve the current run mode for the basic interface.
173  *  @return The current CU_BasicRunMode setting for test
174  *              runs using the basic interface.
175  */
176 CU_BasicRunMode CU_basic_get_mode(void)
177 {
178   return f_run_mode;
179 }
180
181 /*------------------------------------------------------------------------*/
182 /** Print a summary of run failures to stdout.
183  *  This is provided for user convenience upon request, and
184  *  does not take into account the current run mode.  The
185  *  failures are printed to stdout independent of the most
186  *  recent run mode.
187  *  @param pFailure List of CU_pFailureRecord's to output.
188  */
189 void CU_basic_show_failures(CU_pFailureRecord pFailure)
190 {
191   int i;
192
193   for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) {
194     LOG_printf("\n  %d. %s:%u  - %s", i,
195         (NULL != pFailure->strFileName) ? pFailure->strFileName : "",
196         pFailure->uiLineNumber,
197         (NULL != pFailure->strCondition) ? pFailure->strCondition : "");
198   }
199 }
200
201 /*------------------------------------------------------------------------*/
202 /** Perform inialization actions for the basic interface.
203  *  This includes setting output to unbuffered, printing a
204  *  welcome message, and setting the test run handlers.
205  *  @return An error code indicating the framework error condition.
206  */
207 static CU_ErrorCode basic_initialize(void)
208 {
209   /* Unbuffered output so everything reaches the screen */
210 #ifndef DDE_LINUX
211   setvbuf(stdout, NULL, _IONBF, 0);
212   setvbuf(stderr, NULL, _IONBF, 0);
213 #endif
214
215   CU_set_error(CUE_SUCCESS);
216
217   if (CU_BRM_SILENT != f_run_mode)
218     LOG_printf("\n\n     CUnit - A Unit testing framework for C - Version " CU_VERSION
219                "\n     http://cunit.sourceforge.net/\n\n");
220
221   CU_set_test_start_handler(basic_test_start_message_handler);
222   CU_set_test_complete_handler(basic_test_complete_message_handler);
223   CU_set_all_test_complete_handler(basic_all_tests_complete_message_handler);
224   CU_set_suite_init_failure_handler(basic_suite_init_failure_message_handler);
225   CU_set_suite_cleanup_failure_handler(basic_suite_cleanup_failure_message_handler);
226
227   return CU_get_error();
228 }
229
230 /*------------------------------------------------------------------------*/
231 /** Run all tests within the basic interface.
232  *  If non-NULL, the test registry is changed to the specified
233  *  registry before running the tests, and reset to the original
234  *  registry when done.  If NULL, the default CUnit test registry
235  *  will be used.
236  *  @param pRegistry The CU_pTestRegistry containing the tests
237  *                   to be run.  If NULL, use the default registry.
238  *  @return An error code indicating the error status
239  *          during the test run.
240  */
241 static CU_ErrorCode basic_run_all_tests(CU_pTestRegistry pRegistry)
242 {
243   CU_pTestRegistry pOldRegistry = NULL;
244   CU_ErrorCode result;
245
246   f_pRunningSuite = NULL;
247
248   if (NULL != pRegistry)
249     pOldRegistry = CU_set_registry(pRegistry);
250   result = CU_run_all_tests();
251   if (NULL != pRegistry)
252     CU_set_registry(pOldRegistry);
253   return result;
254 }
255
256 /*------------------------------------------------------------------------*/
257 /** Run a specified suite within the basic interface.
258  *  @param pSuite The suite to be run (non-NULL).
259  *  @return An error code indicating the error status
260  *          during the test run.
261  */
262 static CU_ErrorCode basic_run_suite(CU_pSuite pSuite)
263 {
264   f_pRunningSuite = NULL;
265   return CU_run_suite(pSuite);
266 }
267
268 /*------------------------------------------------------------------------*/
269 /** Run a single test for the specified suite within
270  *  the console interface.
271  *  @param pSuite The suite containing the test to be run (non-NULL).
272  *  @param pTest  The test to be run (non-NULL).
273  *  @return An error code indicating the error status
274  *          during the test run.
275  */
276 static CU_ErrorCode basic_run_single_test(CU_pSuite pSuite, CU_pTest pTest)
277 {
278   f_pRunningSuite = NULL;
279   return CU_run_test(pSuite, pTest);
280 }
281
282 /*------------------------------------------------------------------------*/
283 /** Handler function called at start of each test.
284  *  @param pTest  The test being run.
285  *  @param pSuite The suite containing the test.
286  */
287 static void basic_test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite)
288 {
289   assert(pSuite);
290   assert(pTest);
291
292   if (CU_BRM_VERBOSE == f_run_mode) {
293     if ((NULL == f_pRunningSuite) || (f_pRunningSuite != pSuite)) {
294       LOG_printf("\nSuite: %s", (NULL != pSuite->pName) ? pSuite->pName : "");
295       LOG_printf("\n  Test: %s ... ", (NULL != pTest->pName) ? pTest->pName : "");
296       f_pRunningSuite = pSuite;
297     }
298     else {
299       LOG_printf("\n  Test: %s ... ", (NULL != pTest->pName) ? pTest->pName : "");
300     }
301   }
302 }
303
304 /*------------------------------------------------------------------------*/
305 /** Handler function called at completion of each test.
306  *  @param pTest   The test being run.
307  *  @param pSuite  The suite containing the test.
308  *  @param pFailure Pointer to the 1st failure record for this test.
309  */
310 static void basic_test_complete_message_handler(const CU_pTest pTest, 
311                                                 const CU_pSuite pSuite, 
312                                                 const CU_pFailureRecord pFailureList)
313 {
314   CU_pFailureRecord pFailure = pFailureList;
315   int i;
316
317   assert(NULL != pSuite);
318   assert(NULL != pTest);
319
320   if (NULL == pFailure) {
321     if (CU_BRM_VERBOSE == f_run_mode) {
322       LOG_printf("passed");
323     }
324   }
325   else {
326     switch (f_run_mode) {
327       case CU_BRM_VERBOSE:
328         LOG_printf("FAILED");
329         break;
330       case CU_BRM_NORMAL:
331         LOG_printf("\nSuite %s, Test %s had failures:", 
332                         (NULL != pSuite->pName) ? pSuite->pName : "",
333                         (NULL != pTest->pName) ? pTest->pName : "");
334         break;
335       default:  /* gcc wants all enums covered.  ok. */
336         break;
337     }
338     if (CU_BRM_SILENT != f_run_mode) {
339       for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) {
340         LOG_printf("\n    %d. %s:%u  - %s", i,
341             (NULL != pFailure->strFileName) ? pFailure->strFileName : "",
342             pFailure->uiLineNumber,
343             (NULL != pFailure->strCondition) ? pFailure->strCondition : "");
344       }
345     }
346   }
347 }
348
349 /*------------------------------------------------------------------------*/
350 /** Handler function called at completion of all tests in a suite.
351  *  @param pFailure Pointer to the test failure record list.
352  */
353 static void basic_all_tests_complete_message_handler(const CU_pFailureRecord pFailure)
354 {
355   CU_pRunSummary pRunSummary = CU_get_run_summary();
356   CU_pTestRegistry pRegistry = CU_get_registry();
357
358   CU_UNREFERENCED_PARAMETER(pFailure); /* not used in basic interface */
359
360   assert(NULL != pRunSummary);
361   assert(NULL != pRegistry);
362
363   if (CU_BRM_SILENT != f_run_mode)
364     LOG_printf("\n\n--Run Summary: Type      Total     Ran  Passed  Failed"
365                      "\n               suites %8u%8u     n/a%8u"
366                      "\n               tests  %8u%8u%8u%8u"
367                      "\n               asserts%8u%8u%8u%8u\n",
368                     pRegistry->uiNumberOfSuites,
369                     pRunSummary->nSuitesRun,
370                     pRunSummary->nSuitesFailed,
371                     pRegistry->uiNumberOfTests,
372                     pRunSummary->nTestsRun,
373                     pRunSummary->nTestsRun - pRunSummary->nTestsFailed,
374                     pRunSummary->nTestsFailed,
375                     pRunSummary->nAsserts,
376                     pRunSummary->nAsserts,
377                     pRunSummary->nAsserts - pRunSummary->nAssertsFailed,
378                     pRunSummary->nAssertsFailed);
379 }
380
381 /*------------------------------------------------------------------------*/
382 /** Handler function called when suite initialization fails.
383  *  @param pSuite The suite for which initialization failed.
384  */
385 static void basic_suite_init_failure_message_handler(const CU_pSuite pSuite)
386 {
387   assert(NULL != pSuite);
388
389   if (CU_BRM_SILENT != f_run_mode)
390     LOG_printf("\nWARNING - Suite initialization failed for %s.",
391             (NULL != pSuite->pName) ? pSuite->pName : "");
392 }
393
394 /*------------------------------------------------------------------------*/
395 /** Handler function called when suite cleanup fails.
396  *  @param pSuite The suite for which cleanup failed.
397  */
398 static void basic_suite_cleanup_failure_message_handler(const CU_pSuite pSuite)
399 {
400   assert(NULL != pSuite);
401
402   if (CU_BRM_SILENT != f_run_mode)
403     LOG_printf("\nWARNING - Suite cleanup failed for %s.",
404             (NULL != pSuite->pName) ? pSuite->pName : "");
405 }
406
407 /** @} */