2 * Copyright 2008 Google Inc.
3 * Copyright 2014-2015 Andreas Schneider <asn@cryptomilk.org>
4 * Copyright 2015 Jakub Hrozek <jakub.hrozek@posteo.se>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #ifdef HAVE_INTTYPES_H
41 #define vsnprintf _vsnprintf
44 * Backwards compatibility with headers shipped with Visual Studio 2005 and
47 WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID);
54 # define PRIu64 "I64u"
58 # define PRIuMAX PRIu64
62 #define PRIxMAX "I64x"
66 #define PRIXMAX "I64X"
71 #ifndef __PRI64_PREFIX
73 # define __PRI64_PREFIX "l"
75 # define __PRI64_PREFIX "ll"
84 # define PRIu64 __PRI64_PREFIX "u"
88 # define PRIuMAX __PRI64_PREFIX "u"
92 #define PRIxMAX __PRI64_PREFIX "x"
96 #define PRIXMAX __PRI64_PREFIX "X"
103 * This allows to add a platform specific header file. Some embedded platforms
104 * sometimes miss certain types and definitions.
108 * typedef unsigned long int uintptr_t
109 * #define _UINTPTR_T 1
110 * #define _UINTPTR_T_DEFINED 1
112 #ifdef CMOCKA_PLATFORM_INCLUDE
113 # include "cmocka_platform.h"
114 #endif /* CMOCKA_PLATFORM_INCLUDE */
116 #include <cmocka_private.h>
119 /* Size of guard bytes around dynamically allocated blocks. */
120 #define MALLOC_GUARD_SIZE 16
121 /* Pattern used to initialize guard blocks. */
122 #define MALLOC_GUARD_PATTERN 0xEF
123 /* Pattern used to initialize memory allocated with test_malloc(). */
124 #define MALLOC_ALLOC_PATTERN 0xBA
125 #define MALLOC_FREE_PATTERN 0xCD
126 /* Alignment of allocated blocks. NOTE: This must be base2. */
127 #define MALLOC_ALIGNMENT sizeof(size_t)
129 /* Printf formatting for source code locations. */
130 #define SOURCE_LOCATION_FORMAT "%s:%u"
132 #if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
133 # define CMOCKA_THREAD __thread
134 #elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE)
135 # define CMOCKA_THREAD __declspec(thread)
137 # define CMOCKA_THREAD
140 #ifdef HAVE_CLOCK_GETTIME_REALTIME
141 #define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts))
143 #define CMOCKA_CLOCK_GETTIME(clock_id, ts)
147 * Declare and initialize the pointer member of ValuePointer variable name
150 #define declare_initialize_value_pointer_pointer(name, ptr) \
151 ValuePointer name ; \
153 name.x.pointer = (void*)(ptr)
156 * Declare and initialize the value member of ValuePointer variable name
159 #define declare_initialize_value_pointer_value(name, val) \
160 ValuePointer name ; \
163 /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */
164 #define cast_largest_integral_type_to_pointer( \
165 pointer_type, largest_integral_type) \
166 ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer)
168 /* Used to cast LargetIntegralType to void* and vice versa. */
169 typedef union ValuePointer {
170 LargestIntegralType value;
172 #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
173 unsigned int padding;
179 /* Doubly linked list node. */
180 typedef struct ListNode {
183 struct ListNode *next;
184 struct ListNode *prev;
187 /* Debug information for malloc(). */
188 typedef struct MallocBlockInfo {
189 void* block; /* Address of the block returned by malloc(). */
190 size_t allocated_size; /* Total size of the allocated block. */
191 size_t size; /* Request block size. */
192 SourceLocation location; /* Where the block was allocated. */
193 ListNode node; /* Node within list of all allocated blocks. */
196 /* State of each test. */
197 typedef struct TestState {
198 const ListNode *check_point; /* Check point of the test if there's a */
199 /* setup function. */
200 void *state; /* State associated with the test. */
203 /* Determines whether two values are the same. */
204 typedef int (*EqualityFunction)(const void *left, const void *right);
206 /* Value of a symbol and the place it was declared. */
207 typedef struct SymbolValue {
208 SourceLocation location;
209 LargestIntegralType value;
213 * Contains a list of values for a symbol.
214 * NOTE: Each structure referenced by symbol_values_list_head must have a
215 * SourceLocation as its' first member.
217 typedef struct SymbolMapValue {
218 const char *symbol_name;
219 ListNode symbol_values_list_head;
222 /* Used by list_free() to deallocate values referenced by list nodes. */
223 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
225 /* Structure used to check the range of integer types.a */
226 typedef struct CheckIntegerRange {
227 CheckParameterEvent event;
228 LargestIntegralType minimum;
229 LargestIntegralType maximum;
232 /* Structure used to check whether an integer value is in a set. */
233 typedef struct CheckIntegerSet {
234 CheckParameterEvent event;
235 const LargestIntegralType *set;
239 /* Used to check whether a parameter matches the area of memory referenced by
241 typedef struct CheckMemoryData {
242 CheckParameterEvent event;
247 static ListNode* list_initialize(ListNode * const node);
248 static ListNode* list_add(ListNode * const head, ListNode *new_node);
249 static ListNode* list_add_value(ListNode * const head, const void *value,
251 static ListNode* list_remove(
252 ListNode * const node, const CleanupListValue cleanup_value,
253 void * const cleanup_value_data);
254 static void list_remove_free(
255 ListNode * const node, const CleanupListValue cleanup_value,
256 void * const cleanup_value_data);
257 static int list_empty(const ListNode * const head);
258 static int list_find(
259 ListNode * const head, const void *value,
260 const EqualityFunction equal_func, ListNode **output);
261 static int list_first(ListNode * const head, ListNode **output);
262 static ListNode* list_free(
263 ListNode * const head, const CleanupListValue cleanup_value,
264 void * const cleanup_value_data);
266 static void add_symbol_value(
267 ListNode * const symbol_map_head, const char * const symbol_names[],
268 const size_t number_of_symbol_names, const void* value, const int count);
269 static int get_symbol_value(
270 ListNode * const symbol_map_head, const char * const symbol_names[],
271 const size_t number_of_symbol_names, void **output);
272 static void free_value(const void *value, void *cleanup_value_data);
273 static void free_symbol_map_value(
274 const void *value, void *cleanup_value_data);
275 static void remove_always_return_values(ListNode * const map_head,
276 const size_t number_of_symbol_names);
277 static int check_for_leftover_values(
278 const ListNode * const map_head, const char * const error_message,
279 const size_t number_of_symbol_names);
281 * This must be called at the beginning of a test to initialize some data
284 static void initialize_testing(const char *test_name);
286 /* This must be called at the end of a test to free() allocated structures. */
287 static void teardown_testing(const char *test_name);
289 static int cm_error_message_enabled = 1;
290 static CMOCKA_THREAD char *cm_error_message;
292 void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
295 * Keeps track of the calling context returned by setenv() so that the fail()
296 * method can jump out of a test.
298 static CMOCKA_THREAD jmp_buf global_run_test_env;
299 static CMOCKA_THREAD int global_running_test = 0;
301 /* Keeps track of the calling context returned by setenv() so that */
302 /* mock_assert() can optionally jump back to expect_assert_failure(). */
303 jmp_buf global_expect_assert_env;
304 int global_expecting_assert = 0;
305 const char *global_last_failed_assert = NULL;
306 static int global_skip_test;
308 /* Keeps a map of the values that functions will have to return to provide */
309 /* mocked interfaces. */
310 static CMOCKA_THREAD ListNode global_function_result_map_head;
311 /* Location of the last mock value returned was declared. */
312 static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
314 /* Keeps a map of the values that functions expect as parameters to their
315 * mocked interfaces. */
316 static CMOCKA_THREAD ListNode global_function_parameter_map_head;
317 /* Location of last parameter value checked was declared. */
318 static CMOCKA_THREAD SourceLocation global_last_parameter_location;
320 /* List of all currently allocated blocks. */
321 static CMOCKA_THREAD ListNode global_allocated_blocks;
323 static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
326 /* Signals caught by exception_handler(). */
327 static const int exception_signals[] = {
339 /* Default signal functions that should be restored after a test is complete. */
340 typedef void (*SignalFunction)(int signal);
341 static SignalFunction default_signal_functions[
342 ARRAY_SIZE(exception_signals)];
346 /* The default exception filter. */
347 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
349 /* Fatal exceptions. */
350 typedef struct ExceptionCodeInfo {
352 const char* description;
355 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
357 static const ExceptionCodeInfo exception_codes[] = {
358 EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
359 EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
360 EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
361 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
362 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
363 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
364 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
365 EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
366 EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
367 EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
368 EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
369 EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
370 EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
371 EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
372 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
373 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
374 EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
375 EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
376 EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
377 EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
381 enum CMUnitTestStatus {
389 struct CMUnitTestState {
390 const ListNode *check_point; /* Check point of the test if there's a setup function. */
391 const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
392 void *state; /* State associated with the test */
393 const char *error_message; /* The error messages by the test */
394 enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
395 double runtime; /* Time calculations */
398 /* Exit the currently executing test. */
399 static void exit_test(const int quit_application)
401 const char *abort_test = getenv("CMOCKA_TEST_ABORT");
403 if (abort_test != NULL && abort_test[0] == '1') {
404 print_error("%s", cm_error_message);
406 } else if (global_running_test) {
407 longjmp(global_run_test_env, 1);
408 } else if (quit_application) {
413 void _skip(const char * const file, const int line)
415 cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
416 global_skip_test = 1;
420 /* Initialize a SourceLocation structure. */
421 static void initialize_source_location(SourceLocation * const location) {
422 assert_non_null(location);
423 location->file = NULL;
428 /* Determine whether a source location is currently set. */
429 static int source_location_is_set(const SourceLocation * const location) {
430 assert_non_null(location);
431 return location->file && location->line;
435 /* Set a source location. */
436 static void set_source_location(
437 SourceLocation * const location, const char * const file,
439 assert_non_null(location);
440 location->file = file;
441 location->line = line;
445 /* Create function results and expected parameter lists. */
446 void initialize_testing(const char *test_name) {
448 list_initialize(&global_function_result_map_head);
449 initialize_source_location(&global_last_mock_value_location);
450 list_initialize(&global_function_parameter_map_head);
451 initialize_source_location(&global_last_parameter_location);
455 static void fail_if_leftover_values(const char *test_name) {
456 int error_occurred = 0;
458 remove_always_return_values(&global_function_result_map_head, 1);
459 if (check_for_leftover_values(
460 &global_function_result_map_head,
461 "%s() has remaining non-returned values.\n", 1)) {
465 remove_always_return_values(&global_function_parameter_map_head, 2);
466 if (check_for_leftover_values(
467 &global_function_parameter_map_head,
468 "%s parameter still has values that haven't been checked.\n", 2)) {
471 if (error_occurred) {
477 static void teardown_testing(const char *test_name) {
479 list_free(&global_function_result_map_head, free_symbol_map_value,
481 initialize_source_location(&global_last_mock_value_location);
482 list_free(&global_function_parameter_map_head, free_symbol_map_value,
484 initialize_source_location(&global_last_parameter_location);
487 /* Initialize a list node. */
488 static ListNode* list_initialize(ListNode * const node) {
498 * Adds a value at the tail of a given list.
499 * The node referencing the value is allocated from the heap.
501 static ListNode* list_add_value(ListNode * const head, const void *value,
502 const int refcount) {
503 ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
504 assert_non_null(head);
505 assert_non_null(value);
506 new_node->value = value;
507 new_node->refcount = refcount;
508 return list_add(head, new_node);
512 /* Add new_node to the end of the list. */
513 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
514 assert_non_null(head);
515 assert_non_null(new_node);
516 new_node->next = head;
517 new_node->prev = head->prev;
518 head->prev->next = new_node;
519 head->prev = new_node;
524 /* Remove a node from a list. */
525 static ListNode* list_remove(
526 ListNode * const node, const CleanupListValue cleanup_value,
527 void * const cleanup_value_data) {
528 assert_non_null(node);
529 node->prev->next = node->next;
530 node->next->prev = node->prev;
532 cleanup_value(node->value, cleanup_value_data);
538 /* Remove a list node from a list and free the node. */
539 static void list_remove_free(
540 ListNode * const node, const CleanupListValue cleanup_value,
541 void * const cleanup_value_data) {
542 assert_non_null(node);
543 free(list_remove(node, cleanup_value, cleanup_value_data));
548 * Frees memory kept by a linked list The cleanup_value function is called for
549 * every "value" field of nodes in the list, except for the head. In addition
550 * to each list value, cleanup_value_data is passed to each call to
551 * cleanup_value. The head of the list is not deallocated.
553 static ListNode* list_free(
554 ListNode * const head, const CleanupListValue cleanup_value,
555 void * const cleanup_value_data) {
556 assert_non_null(head);
557 while (!list_empty(head)) {
558 list_remove_free(head->next, cleanup_value, cleanup_value_data);
564 /* Determine whether a list is empty. */
565 static int list_empty(const ListNode * const head) {
566 assert_non_null(head);
567 return head->next == head;
572 * Find a value in the list using the equal_func to compare each node with the
575 static int list_find(ListNode * const head, const void *value,
576 const EqualityFunction equal_func, ListNode **output) {
578 assert_non_null(head);
579 for (current = head->next; current != head; current = current->next) {
580 if (equal_func(current->value, value)) {
588 /* Returns the first node of a list */
589 static int list_first(ListNode * const head, ListNode **output) {
590 ListNode *target_node;
591 assert_non_null(head);
592 if (list_empty(head)) {
595 target_node = head->next;
596 *output = target_node;
601 /* Deallocate a value referenced by a list. */
602 static void free_value(const void *value, void *cleanup_value_data) {
603 (void)cleanup_value_data;
604 assert_non_null(value);
609 /* Releases memory associated to a symbol_map_value. */
610 static void free_symbol_map_value(const void *value,
611 void *cleanup_value_data) {
612 SymbolMapValue * const map_value = (SymbolMapValue*)value;
613 const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
614 assert_non_null(value);
615 list_free(&map_value->symbol_values_list_head,
616 children ? free_symbol_map_value : free_value,
617 (void *) ((uintptr_t)children - 1));
623 * Determine whether a symbol name referenced by a symbol_map_value matches the
624 * specified function name.
626 static int symbol_names_match(const void *map_value, const void *symbol) {
627 return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
628 (const char*)symbol);
633 * Adds a value to the queue of values associated with the given hierarchy of
634 * symbols. It's assumed value is allocated from the heap.
636 static void add_symbol_value(ListNode * const symbol_map_head,
637 const char * const symbol_names[],
638 const size_t number_of_symbol_names,
639 const void* value, const int refcount) {
640 const char* symbol_name;
641 ListNode *target_node;
642 SymbolMapValue *target_map_value;
643 assert_non_null(symbol_map_head);
644 assert_non_null(symbol_names);
645 assert_true(number_of_symbol_names);
646 symbol_name = symbol_names[0];
648 if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
650 SymbolMapValue * const new_symbol_map_value =
651 (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
652 new_symbol_map_value->symbol_name = symbol_name;
653 list_initialize(&new_symbol_map_value->symbol_values_list_head);
654 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
658 target_map_value = (SymbolMapValue*)target_node->value;
659 if (number_of_symbol_names == 1) {
660 list_add_value(&target_map_value->symbol_values_list_head,
663 add_symbol_value(&target_map_value->symbol_values_list_head,
664 &symbol_names[1], number_of_symbol_names - 1, value,
671 * Gets the next value associated with the given hierarchy of symbols.
672 * The value is returned as an output parameter with the function returning the
673 * node's old refcount value if a value is found, 0 otherwise. This means that
674 * a return value of 1 indicates the node was just removed from the list.
676 static int get_symbol_value(
677 ListNode * const head, const char * const symbol_names[],
678 const size_t number_of_symbol_names, void **output) {
679 const char* symbol_name;
680 ListNode *target_node;
681 assert_non_null(head);
682 assert_non_null(symbol_names);
683 assert_true(number_of_symbol_names);
684 assert_non_null(output);
685 symbol_name = symbol_names[0];
687 if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
688 SymbolMapValue *map_value;
689 ListNode *child_list;
690 int return_value = 0;
691 assert_non_null(target_node);
692 assert_non_null(target_node->value);
694 map_value = (SymbolMapValue*)target_node->value;
695 child_list = &map_value->symbol_values_list_head;
697 if (number_of_symbol_names == 1) {
698 ListNode *value_node = NULL;
699 return_value = list_first(child_list, &value_node);
700 assert_true(return_value);
701 *output = (void*) value_node->value;
702 return_value = value_node->refcount;
703 if (--value_node->refcount == 0) {
704 list_remove_free(value_node, NULL, NULL);
707 return_value = get_symbol_value(
708 child_list, &symbol_names[1], number_of_symbol_names - 1,
711 if (list_empty(child_list)) {
712 list_remove_free(target_node, free_symbol_map_value, (void*)0);
716 cm_print_error("No entries for symbol %s.\n", symbol_name);
723 * Traverse down a tree of symbol values and remove the first symbol value
724 * in each branch that has a refcount < -1 (i.e should always be returned
725 * and has been returned at least once).
727 static void remove_always_return_values(ListNode * const map_head,
728 const size_t number_of_symbol_names) {
730 assert_non_null(map_head);
731 assert_true(number_of_symbol_names);
732 current = map_head->next;
733 while (current != map_head) {
734 SymbolMapValue * const value = (SymbolMapValue*)current->value;
735 ListNode * const next = current->next;
736 ListNode *child_list;
737 assert_non_null(value);
738 child_list = &value->symbol_values_list_head;
740 if (!list_empty(child_list)) {
741 if (number_of_symbol_names == 1) {
742 ListNode * const child_node = child_list->next;
743 /* If this item has been returned more than once, free it. */
744 if (child_node->refcount < -1) {
745 list_remove_free(child_node, free_value, NULL);
748 remove_always_return_values(child_list,
749 number_of_symbol_names - 1);
753 if (list_empty(child_list)) {
754 list_remove_free(current, free_value, NULL);
761 * Checks if there are any leftover values set up by the test that were never
762 * retrieved through execution, and fail the test if that is the case.
764 static int check_for_leftover_values(
765 const ListNode * const map_head, const char * const error_message,
766 const size_t number_of_symbol_names) {
767 const ListNode *current;
768 int symbols_with_leftover_values = 0;
769 assert_non_null(map_head);
770 assert_true(number_of_symbol_names);
772 for (current = map_head->next; current != map_head;
773 current = current->next) {
774 const SymbolMapValue * const value =
775 (SymbolMapValue*)current->value;
776 const ListNode *child_list;
777 assert_non_null(value);
778 child_list = &value->symbol_values_list_head;
780 if (!list_empty(child_list)) {
781 if (number_of_symbol_names == 1) {
782 const ListNode *child_node;
783 cm_print_error(error_message, value->symbol_name);
785 for (child_node = child_list->next; child_node != child_list;
786 child_node = child_node->next) {
787 const SourceLocation * const location =
788 (const SourceLocation*)child_node->value;
789 cm_print_error(SOURCE_LOCATION_FORMAT
790 ": note: remaining item was declared here\n",
791 location->file, location->line);
794 cm_print_error("%s.", value->symbol_name);
795 check_for_leftover_values(child_list, error_message,
796 number_of_symbol_names - 1);
798 symbols_with_leftover_values ++;
801 return symbols_with_leftover_values;
805 /* Get the next return value for the specified mock function. */
806 LargestIntegralType _mock(const char * const function, const char* const file,
809 const int rc = get_symbol_value(&global_function_result_map_head,
810 &function, 1, &result);
812 SymbolValue * const symbol = (SymbolValue*)result;
813 const LargestIntegralType value = symbol->value;
814 global_last_mock_value_location = symbol->location;
820 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
821 "to mock function %s\n", file, line, function);
822 if (source_location_is_set(&global_last_mock_value_location)) {
823 cm_print_error(SOURCE_LOCATION_FORMAT
824 ": note: Previously returned mock value was declared here\n",
825 global_last_mock_value_location.file,
826 global_last_mock_value_location.line);
828 cm_print_error("There were no previously returned mock values for "
837 /* Add a return value for the specified mock function name. */
838 void _will_return(const char * const function_name, const char * const file,
839 const int line, const LargestIntegralType value,
841 SymbolValue * const return_value =
842 (SymbolValue*)malloc(sizeof(*return_value));
843 assert_true(count > 0 || count == -1);
844 return_value->value = value;
845 set_source_location(&return_value->location, file, line);
846 add_symbol_value(&global_function_result_map_head, &function_name, 1,
847 return_value, count);
852 * Add a custom parameter checking function. If the event parameter is NULL
853 * the event structure is allocated internally by this function. If event
854 * parameter is provided it must be allocated on the heap and doesn't need to
855 * be deallocated by the caller.
858 const char* const function, const char* const parameter,
859 const char* const file, const int line,
860 const CheckParameterValue check_function,
861 const LargestIntegralType check_data,
862 CheckParameterEvent * const event, const int count) {
863 CheckParameterEvent * const check =
864 event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
865 const char* symbols[] = {function, parameter};
866 check->parameter_name = parameter;
867 check->check_value = check_function;
868 check->check_value_data = check_data;
869 set_source_location(&check->location, file, line);
870 add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
875 /* Returns 1 if the specified values are equal. If the values are not equal
876 * an error is displayed and 0 is returned. */
877 static int values_equal_display_error(const LargestIntegralType left,
878 const LargestIntegralType right) {
879 const int equal = left == right;
881 cm_print_error(LargestIntegralTypePrintfFormat " != "
882 LargestIntegralTypePrintfFormat "\n", left, right);
888 * Returns 1 if the specified values are not equal. If the values are equal
889 * an error is displayed and 0 is returned. */
890 static int values_not_equal_display_error(const LargestIntegralType left,
891 const LargestIntegralType right) {
892 const int not_equal = left != right;
894 cm_print_error(LargestIntegralTypePrintfFormat " == "
895 LargestIntegralTypePrintfFormat "\n", left, right);
902 * Determine whether value is contained within check_integer_set.
903 * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
904 * returned and an error is displayed. If invert is 1 and the value is not
905 * in the set 1 is returned, otherwise 0 is returned and an error is
908 static int value_in_set_display_error(
909 const LargestIntegralType value,
910 const CheckIntegerSet * const check_integer_set, const int invert) {
911 int succeeded = invert;
912 assert_non_null(check_integer_set);
914 const LargestIntegralType * const set = check_integer_set->set;
915 const size_t size_of_set = check_integer_set->size_of_set;
917 for (i = 0; i < size_of_set; i++) {
918 if (set[i] == value) {
919 /* If invert = 0 and item is found, succeeded = 1. */
920 /* If invert = 1 and item is found, succeeded = 0. */
921 succeeded = !succeeded;
928 cm_print_error("%" PRIu64 " is %sin the set (", value,
929 invert ? "" : "not ");
930 for (i = 0; i < size_of_set; i++) {
931 cm_print_error("%" PRIu64 ", ", set[i]);
933 cm_print_error(")\n");
940 * Determine whether a value is within the specified range. If the value is
941 * within the specified range 1 is returned. If the value isn't within the
942 * specified range an error is displayed and 0 is returned.
944 static int integer_in_range_display_error(
945 const LargestIntegralType value, const LargestIntegralType range_min,
946 const LargestIntegralType range_max) {
947 if (value >= range_min && value <= range_max) {
950 cm_print_error("%" PRIu64 " is not within the range %" PRIu64 "-%" PRIu64 "\n",
951 value, range_min, range_max);
957 * Determine whether a value is within the specified range. If the value
958 * is not within the range 1 is returned. If the value is within the
959 * specified range an error is displayed and zero is returned.
961 static int integer_not_in_range_display_error(
962 const LargestIntegralType value, const LargestIntegralType range_min,
963 const LargestIntegralType range_max) {
964 if (value < range_min || value > range_max) {
967 cm_print_error("%" PRIu64 " is within the range %" PRIu64 "-%" PRIu64 "\n",
968 value, range_min, range_max);
974 * Determine whether the specified strings are equal. If the strings are equal
975 * 1 is returned. If they're not equal an error is displayed and 0 is
978 static int string_equal_display_error(
979 const char * const left, const char * const right) {
980 if (strcmp(left, right) == 0) {
983 cm_print_error("\"%s\" != \"%s\"\n", left, right);
989 * Determine whether the specified strings are equal. If the strings are not
990 * equal 1 is returned. If they're not equal an error is displayed and 0 is
993 static int string_not_equal_display_error(
994 const char * const left, const char * const right) {
995 if (strcmp(left, right) != 0) {
998 cm_print_error("\"%s\" == \"%s\"\n", left, right);
1004 * Determine whether the specified areas of memory are equal. If they're equal
1005 * 1 is returned otherwise an error is displayed and 0 is returned.
1007 static int memory_equal_display_error(const char* const a, const char* const b,
1008 const size_t size) {
1009 int differences = 0;
1011 for (i = 0; i < size; i++) {
1012 const char l = a[i];
1013 const char r = b[i];
1015 cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
1021 cm_print_error("%d bytes of %p and %p differ\n", differences,
1030 * Determine whether the specified areas of memory are not equal. If they're
1031 * not equal 1 is returned otherwise an error is displayed and 0 is
1034 static int memory_not_equal_display_error(
1035 const char* const a, const char* const b, const size_t size) {
1038 for (i = 0; i < size; i++) {
1039 const char l = a[i];
1040 const char r = b[i];
1046 cm_print_error("%"PRIdS "bytes of %p and %p the same\n", same,
1054 /* CheckParameterValue callback to check whether a value is within a set. */
1055 static int check_in_set(const LargestIntegralType value,
1056 const LargestIntegralType check_value_data) {
1057 return value_in_set_display_error(value,
1058 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1059 check_value_data), 0);
1063 /* CheckParameterValue callback to check whether a value isn't within a set. */
1064 static int check_not_in_set(const LargestIntegralType value,
1065 const LargestIntegralType check_value_data) {
1066 return value_in_set_display_error(value,
1067 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1068 check_value_data), 1);
1072 /* Create the callback data for check_in_set() or check_not_in_set() and
1073 * register a check event. */
1074 static void expect_set(
1075 const char* const function, const char* const parameter,
1076 const char* const file, const int line,
1077 const LargestIntegralType values[], const size_t number_of_values,
1078 const CheckParameterValue check_function, const int count) {
1079 CheckIntegerSet * const check_integer_set =
1080 (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
1081 (sizeof(values[0]) * number_of_values));
1082 LargestIntegralType * const set = (LargestIntegralType*)(
1083 check_integer_set + 1);
1084 declare_initialize_value_pointer_pointer(check_data, check_integer_set);
1085 assert_non_null(values);
1086 assert_true(number_of_values);
1087 memcpy(set, values, number_of_values * sizeof(values[0]));
1088 check_integer_set->set = set;
1089 check_integer_set->size_of_set = number_of_values;
1091 function, parameter, file, line, check_function,
1092 check_data.value, &check_integer_set->event, count);
1096 /* Add an event to check whether a value is in a set. */
1097 void _expect_in_set(
1098 const char* const function, const char* const parameter,
1099 const char* const file, const int line,
1100 const LargestIntegralType values[], const size_t number_of_values,
1102 expect_set(function, parameter, file, line, values, number_of_values,
1103 check_in_set, count);
1107 /* Add an event to check whether a value isn't in a set. */
1108 void _expect_not_in_set(
1109 const char* const function, const char* const parameter,
1110 const char* const file, const int line,
1111 const LargestIntegralType values[], const size_t number_of_values,
1113 expect_set(function, parameter, file, line, values, number_of_values,
1114 check_not_in_set, count);
1118 /* CheckParameterValue callback to check whether a value is within a range. */
1119 static int check_in_range(const LargestIntegralType value,
1120 const LargestIntegralType check_value_data) {
1121 CheckIntegerRange * const check_integer_range =
1122 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1124 assert_non_null(check_integer_range);
1125 return integer_in_range_display_error(value, check_integer_range->minimum,
1126 check_integer_range->maximum);
1130 /* CheckParameterValue callback to check whether a value is not within a range. */
1131 static int check_not_in_range(const LargestIntegralType value,
1132 const LargestIntegralType check_value_data) {
1133 CheckIntegerRange * const check_integer_range =
1134 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1136 assert_non_null(check_integer_range);
1137 return integer_not_in_range_display_error(
1138 value, check_integer_range->minimum, check_integer_range->maximum);
1142 /* Create the callback data for check_in_range() or check_not_in_range() and
1143 * register a check event. */
1144 static void expect_range(
1145 const char* const function, const char* const parameter,
1146 const char* const file, const int line,
1147 const LargestIntegralType minimum, const LargestIntegralType maximum,
1148 const CheckParameterValue check_function, const int count) {
1149 CheckIntegerRange * const check_integer_range =
1150 (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
1151 declare_initialize_value_pointer_pointer(check_data, check_integer_range);
1152 check_integer_range->minimum = minimum;
1153 check_integer_range->maximum = maximum;
1154 _expect_check(function, parameter, file, line, check_function,
1155 check_data.value, &check_integer_range->event, count);
1159 /* Add an event to determine whether a parameter is within a range. */
1160 void _expect_in_range(
1161 const char* const function, const char* const parameter,
1162 const char* const file, const int line,
1163 const LargestIntegralType minimum, const LargestIntegralType maximum,
1165 expect_range(function, parameter, file, line, minimum, maximum,
1166 check_in_range, count);
1170 /* Add an event to determine whether a parameter is not within a range. */
1171 void _expect_not_in_range(
1172 const char* const function, const char* const parameter,
1173 const char* const file, const int line,
1174 const LargestIntegralType minimum, const LargestIntegralType maximum,
1176 expect_range(function, parameter, file, line, minimum, maximum,
1177 check_not_in_range, count);
1181 /* CheckParameterValue callback to check whether a value is equal to an
1182 * expected value. */
1183 static int check_value(const LargestIntegralType value,
1184 const LargestIntegralType check_value_data) {
1185 return values_equal_display_error(value, check_value_data);
1189 /* Add an event to check a parameter equals an expected value. */
1191 const char* const function, const char* const parameter,
1192 const char* const file, const int line,
1193 const LargestIntegralType value, const int count) {
1194 _expect_check(function, parameter, file, line, check_value, value, NULL,
1199 /* CheckParameterValue callback to check whether a value is not equal to an
1200 * expected value. */
1201 static int check_not_value(const LargestIntegralType value,
1202 const LargestIntegralType check_value_data) {
1203 return values_not_equal_display_error(value, check_value_data);
1207 /* Add an event to check a parameter is not equal to an expected value. */
1208 void _expect_not_value(
1209 const char* const function, const char* const parameter,
1210 const char* const file, const int line,
1211 const LargestIntegralType value, const int count) {
1212 _expect_check(function, parameter, file, line, check_not_value, value,
1217 /* CheckParameterValue callback to check whether a parameter equals a string. */
1218 static int check_string(const LargestIntegralType value,
1219 const LargestIntegralType check_value_data) {
1220 return string_equal_display_error(
1221 cast_largest_integral_type_to_pointer(char*, value),
1222 cast_largest_integral_type_to_pointer(char*, check_value_data));
1226 /* Add an event to check whether a parameter is equal to a string. */
1227 void _expect_string(
1228 const char* const function, const char* const parameter,
1229 const char* const file, const int line, const char* string,
1231 declare_initialize_value_pointer_pointer(string_pointer,
1232 discard_const(string));
1233 _expect_check(function, parameter, file, line, check_string,
1234 string_pointer.value, NULL, count);
1238 /* CheckParameterValue callback to check whether a parameter is not equals to
1240 static int check_not_string(const LargestIntegralType value,
1241 const LargestIntegralType check_value_data) {
1242 return string_not_equal_display_error(
1243 cast_largest_integral_type_to_pointer(char*, value),
1244 cast_largest_integral_type_to_pointer(char*, check_value_data));
1248 /* Add an event to check whether a parameter is not equal to a string. */
1249 void _expect_not_string(
1250 const char* const function, const char* const parameter,
1251 const char* const file, const int line, const char* string,
1253 declare_initialize_value_pointer_pointer(string_pointer,
1254 discard_const(string));
1255 _expect_check(function, parameter, file, line, check_not_string,
1256 string_pointer.value, NULL, count);
1259 /* CheckParameterValue callback to check whether a parameter equals an area of
1261 static int check_memory(const LargestIntegralType value,
1262 const LargestIntegralType check_value_data) {
1263 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1264 CheckMemoryData*, check_value_data);
1265 assert_non_null(check);
1266 return memory_equal_display_error(
1267 cast_largest_integral_type_to_pointer(const char*, value),
1268 (const char*)check->memory, check->size);
1272 /* Create the callback data for check_memory() or check_not_memory() and
1273 * register a check event. */
1274 static void expect_memory_setup(
1275 const char* const function, const char* const parameter,
1276 const char* const file, const int line,
1277 const void * const memory, const size_t size,
1278 const CheckParameterValue check_function, const int count) {
1279 CheckMemoryData * const check_data =
1280 (CheckMemoryData*)malloc(sizeof(*check_data) + size);
1281 void * const mem = (void*)(check_data + 1);
1282 declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1283 assert_non_null(memory);
1285 memcpy(mem, memory, size);
1286 check_data->memory = mem;
1287 check_data->size = size;
1288 _expect_check(function, parameter, file, line, check_function,
1289 check_data_pointer.value, &check_data->event, count);
1293 /* Add an event to check whether a parameter matches an area of memory. */
1294 void _expect_memory(
1295 const char* const function, const char* const parameter,
1296 const char* const file, const int line, const void* const memory,
1297 const size_t size, const int count) {
1298 expect_memory_setup(function, parameter, file, line, memory, size,
1299 check_memory, count);
1303 /* CheckParameterValue callback to check whether a parameter is not equal to
1304 * an area of memory. */
1305 static int check_not_memory(const LargestIntegralType value,
1306 const LargestIntegralType check_value_data) {
1307 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1308 CheckMemoryData*, check_value_data);
1309 assert_non_null(check);
1310 return memory_not_equal_display_error(
1311 cast_largest_integral_type_to_pointer(const char*, value),
1312 (const char*)check->memory,
1317 /* Add an event to check whether a parameter doesn't match an area of memory. */
1318 void _expect_not_memory(
1319 const char* const function, const char* const parameter,
1320 const char* const file, const int line, const void* const memory,
1321 const size_t size, const int count) {
1322 expect_memory_setup(function, parameter, file, line, memory, size,
1323 check_not_memory, count);
1327 /* CheckParameterValue callback that always returns 1. */
1328 static int check_any(const LargestIntegralType value,
1329 const LargestIntegralType check_value_data) {
1331 (void)check_value_data;
1336 /* Add an event to allow any value for a parameter. */
1338 const char* const function, const char* const parameter,
1339 const char* const file, const int line, const int count) {
1340 _expect_check(function, parameter, file, line, check_any, 0, NULL,
1345 void _check_expected(
1346 const char * const function_name, const char * const parameter_name,
1347 const char* file, const int line, const LargestIntegralType value) {
1349 const char* symbols[] = {function_name, parameter_name};
1350 const int rc = get_symbol_value(&global_function_parameter_map_head,
1351 symbols, 2, &result);
1353 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1354 int check_succeeded;
1355 global_last_parameter_location = check->location;
1356 check_succeeded = check->check_value(value, check->check_value_data);
1360 if (!check_succeeded) {
1361 cm_print_error(SOURCE_LOCATION_FORMAT
1362 ": error: Check of parameter %s, function %s failed\n"
1363 SOURCE_LOCATION_FORMAT
1364 ": note: Expected parameter declared here\n",
1366 parameter_name, function_name,
1367 global_last_parameter_location.file,
1368 global_last_parameter_location.line);
1372 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
1373 "to check parameter %s of function %s\n", file, line,
1374 parameter_name, function_name);
1375 if (source_location_is_set(&global_last_parameter_location)) {
1376 cm_print_error(SOURCE_LOCATION_FORMAT
1377 ": note: Previously declared parameter value was declared here\n",
1378 global_last_parameter_location.file,
1379 global_last_parameter_location.line);
1381 cm_print_error("There were no previously declared parameter values "
1382 "for this test.\n");
1389 /* Replacement for assert. */
1390 void mock_assert(const int result, const char* const expression,
1391 const char* const file, const int line) {
1393 if (global_expecting_assert) {
1394 global_last_failed_assert = expression;
1395 longjmp(global_expect_assert_env, result);
1397 cm_print_error("ASSERT: %s\n", expression);
1404 void _assert_true(const LargestIntegralType result,
1405 const char * const expression,
1406 const char * const file, const int line) {
1408 cm_print_error("%s\n", expression);
1413 void _assert_return_code(const LargestIntegralType result,
1415 const LargestIntegralType error,
1416 const char * const expression,
1417 const char * const file,
1420 LargestIntegralType valmax;
1431 valmax = 2147483647;
1435 if (rlen > sizeof(valmax)) {
1436 valmax = 2147483647;
1438 valmax = 9223372036854775807L;
1443 if (result > valmax - 1) {
1445 cm_print_error("%s < 0, errno(%" PRIu64 "): %s\n",
1446 expression, error, strerror(error));
1448 cm_print_error("%s < 0\n", expression);
1454 void _assert_int_equal(
1455 const LargestIntegralType a, const LargestIntegralType b,
1456 const char * const file, const int line) {
1457 if (!values_equal_display_error(a, b)) {
1463 void _assert_int_not_equal(
1464 const LargestIntegralType a, const LargestIntegralType b,
1465 const char * const file, const int line) {
1466 if (!values_not_equal_display_error(a, b)) {
1472 void _assert_string_equal(const char * const a, const char * const b,
1473 const char * const file, const int line) {
1474 if (!string_equal_display_error(a, b)) {
1480 void _assert_string_not_equal(const char * const a, const char * const b,
1481 const char *file, const int line) {
1482 if (!string_not_equal_display_error(a, b)) {
1488 void _assert_memory_equal(const void * const a, const void * const b,
1489 const size_t size, const char* const file,
1491 if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1497 void _assert_memory_not_equal(const void * const a, const void * const b,
1498 const size_t size, const char* const file,
1500 if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1507 void _assert_in_range(
1508 const LargestIntegralType value, const LargestIntegralType minimum,
1509 const LargestIntegralType maximum, const char* const file,
1511 if (!integer_in_range_display_error(value, minimum, maximum)) {
1516 void _assert_not_in_range(
1517 const LargestIntegralType value, const LargestIntegralType minimum,
1518 const LargestIntegralType maximum, const char* const file,
1520 if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1525 void _assert_in_set(const LargestIntegralType value,
1526 const LargestIntegralType values[],
1527 const size_t number_of_values, const char* const file,
1529 CheckIntegerSet check_integer_set;
1530 check_integer_set.set = values;
1531 check_integer_set.size_of_set = number_of_values;
1532 if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1537 void _assert_not_in_set(const LargestIntegralType value,
1538 const LargestIntegralType values[],
1539 const size_t number_of_values, const char* const file,
1541 CheckIntegerSet check_integer_set;
1542 check_integer_set.set = values;
1543 check_integer_set.size_of_set = number_of_values;
1544 if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1550 /* Get the list of allocated blocks. */
1551 static ListNode* get_allocated_blocks_list() {
1552 /* If it initialized, initialize the list of allocated blocks. */
1553 if (!global_allocated_blocks.value) {
1554 list_initialize(&global_allocated_blocks);
1555 global_allocated_blocks.value = (void*)1;
1557 return &global_allocated_blocks;
1560 static void *libc_malloc(size_t size)
1563 return malloc(size);
1564 #define malloc test_malloc
1567 static void libc_free(void *ptr)
1571 #define free test_free
1574 static void *libc_realloc(void *ptr, size_t size)
1577 return realloc(ptr, size);
1578 #define realloc test_realloc
1581 static void vcm_print_error(const char* const format,
1582 va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
1584 /* It's important to use the libc malloc and free here otherwise
1585 * the automatic free of leaked blocks can reap the error messages
1587 static void vcm_print_error(const char* const format, va_list args)
1594 len = vsnprintf(buffer, sizeof(buffer), format, args);
1600 if (cm_error_message == NULL) {
1601 /* CREATE MESSAGE */
1603 cm_error_message = libc_malloc(len + 1);
1604 if (cm_error_message == NULL) {
1609 /* APPEND MESSAGE */
1612 msg_len = strlen(cm_error_message);
1613 tmp = libc_realloc(cm_error_message, msg_len + len + 1);
1617 cm_error_message = tmp;
1620 if (((size_t)len) < sizeof(buffer)) {
1621 /* Use len + 1 to also copy '\0' */
1622 memcpy(cm_error_message + msg_len, buffer, len + 1);
1625 vsnprintf(cm_error_message + msg_len, len, format, ap);
1630 static void vcm_free_error(char *err_msg)
1635 /* Use the real malloc in this function. */
1637 void* _test_malloc(const size_t size, const char* file, const int line) {
1639 MallocBlockInfo *block_info;
1640 ListNode * const block_list = get_allocated_blocks_list();
1641 const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
1642 sizeof(*block_info) + MALLOC_ALIGNMENT;
1643 char* const block = (char*)malloc(allocate_size);
1644 assert_non_null(block);
1646 /* Calculate the returned address. */
1647 ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
1648 MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1650 /* Initialize the guard blocks. */
1651 memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1652 memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1653 memset(ptr, MALLOC_ALLOC_PATTERN, size);
1655 block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
1656 sizeof(*block_info)));
1657 set_source_location(&block_info->location, file, line);
1658 block_info->allocated_size = allocate_size;
1659 block_info->size = size;
1660 block_info->block = block;
1661 block_info->node.value = block_info;
1662 list_add(block_list, &block_info->node);
1665 #define malloc test_malloc
1668 void* _test_calloc(const size_t number_of_elements, const size_t size,
1669 const char* file, const int line) {
1670 void* const ptr = _test_malloc(number_of_elements * size, file, line);
1672 memset(ptr, 0, number_of_elements * size);
1678 /* Use the real free in this function. */
1680 void _test_free(void* const ptr, const char* file, const int line) {
1682 char *block = discard_const_p(char, ptr);
1683 MallocBlockInfo *block_info;
1689 _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
1690 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1691 sizeof(*block_info)));
1692 /* Check the guard blocks. */
1694 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1695 block + block_info->size};
1696 for (i = 0; i < ARRAY_SIZE(guards); i++) {
1698 char * const guard = guards[i];
1699 for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1700 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1702 cm_print_error(SOURCE_LOCATION_FORMAT
1703 ": error: Guard block of %p size=%lu is corrupt\n"
1704 SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
1706 ptr, (unsigned long)block_info->size,
1707 block_info->location.file, block_info->location.line,
1714 list_remove(&block_info->node, NULL, NULL);
1716 block = discard_const_p(char, block_info->block);
1717 memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
1720 #define free test_free
1723 void *_test_realloc(void *ptr,
1728 MallocBlockInfo *block_info;
1730 size_t block_size = size;
1734 return _test_malloc(size, file, line);
1741 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1742 sizeof(*block_info)));
1744 new = _test_malloc(size, file, line);
1749 if (block_info->size < size) {
1750 block_size = block_info->size;
1753 memcpy(new, ptr, block_size);
1755 /* Free previous memory */
1756 _test_free(ptr, file, line);
1760 #define realloc test_realloc
1762 /* Crudely checkpoint the current heap state. */
1763 static const ListNode* check_point_allocated_blocks() {
1764 return get_allocated_blocks_list()->prev;
1768 /* Display the blocks allocated after the specified check point. This
1769 * function returns the number of blocks displayed. */
1770 static int display_allocated_blocks(const ListNode * const check_point) {
1771 const ListNode * const head = get_allocated_blocks_list();
1772 const ListNode *node;
1773 int allocated_blocks = 0;
1774 assert_non_null(check_point);
1775 assert_non_null(check_point->next);
1777 for (node = check_point->next; node != head; node = node->next) {
1778 const MallocBlockInfo * const block_info =
1779 (const MallocBlockInfo*)node->value;
1780 assert_non_null(block_info);
1782 if (!allocated_blocks) {
1783 cm_print_error("Blocks allocated...\n");
1785 cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
1786 block_info->location.file,
1787 block_info->location.line,
1789 allocated_blocks ++;
1791 return allocated_blocks;
1795 /* Free all blocks allocated after the specified check point. */
1796 static void free_allocated_blocks(const ListNode * const check_point) {
1797 const ListNode * const head = get_allocated_blocks_list();
1798 const ListNode *node;
1799 assert_non_null(check_point);
1801 node = check_point->next;
1802 assert_non_null(node);
1804 while (node != head) {
1805 MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
1807 free(discard_const_p(char, block_info) + sizeof(*block_info) + MALLOC_GUARD_SIZE);
1812 /* Fail if any any blocks are allocated after the specified check point. */
1813 static void fail_if_blocks_allocated(const ListNode * const check_point,
1814 const char * const test_name) {
1815 const int allocated_blocks = display_allocated_blocks(check_point);
1816 if (allocated_blocks) {
1817 free_allocated_blocks(check_point);
1818 cm_print_error("ERROR: %s leaked %d block(s)\n", test_name,
1825 void _fail(const char * const file, const int line) {
1826 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!\n", file, line);
1832 static void exception_handler(int sig) {
1833 #ifdef HAVE_STRSIGNAL
1834 cm_print_error("Test failed with exception: %s\n", strsignal(sig));
1836 cm_print_error("Test failed with exception: %d\n", sig);
1843 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
1844 EXCEPTION_RECORD * const exception_record =
1845 exception_pointers->ExceptionRecord;
1846 const DWORD code = exception_record->ExceptionCode;
1848 for (i = 0; i < ARRAY_SIZE(exception_codes); i++) {
1849 const ExceptionCodeInfo * const code_info = &exception_codes[i];
1850 if (code == code_info->code) {
1851 static int shown_debug_message = 0;
1853 cm_print_error("%s occurred at %p.\n", code_info->description,
1854 exception_record->ExceptionAddress);
1855 if (!shown_debug_message) {
1858 "To debug in Visual Studio...\n"
1859 "1. Select menu item File->Open Project\n"
1860 "2. Change 'Files of type' to 'Executable Files'\n"
1861 "3. Open this executable.\n"
1862 "4. Select menu item Debug->Start\n"
1864 "Alternatively, set the environment variable \n"
1865 "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
1866 "then click 'Debug' in the popup dialog box.\n"
1868 shown_debug_message = 1;
1871 return EXCEPTION_EXECUTE_HANDLER;
1874 return EXCEPTION_CONTINUE_SEARCH;
1876 #endif /* !_WIN32 */
1878 void cm_print_error(const char * const format, ...)
1881 va_start(args, format);
1882 if (cm_error_message_enabled) {
1883 vcm_print_error(format, args);
1885 vprint_error(format, args);
1890 /* Standard output and error print methods. */
1891 void vprint_message(const char* const format, va_list args) {
1893 vsnprintf(buffer, sizeof(buffer), format, args);
1894 printf("%s", buffer);
1897 OutputDebugString(buffer);
1902 void vprint_error(const char* const format, va_list args) {
1904 vsnprintf(buffer, sizeof(buffer), format, args);
1905 fprintf(stderr, "%s", buffer);
1908 OutputDebugString(buffer);
1913 void print_message(const char* const format, ...) {
1915 va_start(args, format);
1916 vprint_message(format, args);
1921 void print_error(const char* const format, ...) {
1923 va_start(args, format);
1924 vprint_error(format, args);
1929 static enum cm_message_output cm_get_output(void)
1931 enum cm_message_output output = global_msg_output;
1934 env = getenv("CMOCKA_MESSAGE_OUTPUT");
1936 if (strcasecmp(env, "STDOUT") == 0) {
1937 output = CM_OUTPUT_STDOUT;
1938 } else if (strcasecmp(env, "SUBUNIT") == 0) {
1939 output = CM_OUTPUT_SUBUNIT;
1940 } else if (strcasecmp(env, "TAP") == 0) {
1941 output = CM_OUTPUT_TAP;
1942 } else if (strcasecmp(env, "XML") == 0) {
1943 output = CM_OUTPUT_XML;
1950 enum cm_printf_type {
1952 PRINTF_TEST_SUCCESS,
1953 PRINTF_TEST_FAILURE,
1955 PRINTF_TEST_SKIPPED,
1958 static void cmprintf_group_finish_xml(const char *group_name,
1959 size_t total_executed,
1960 size_t total_failed,
1961 size_t total_errors,
1962 size_t total_skipped,
1963 double total_runtime,
1964 struct CMUnitTestState *cm_tests)
1967 int file_opened = 0;
1971 env = getenv("CMOCKA_XML_FILE");
1974 snprintf(buf, sizeof(buf), "%s", env);
1976 fp = fopen(buf, "r");
1978 fp = fopen(buf, "w");
1990 fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
1991 fprintf(fp, "<testsuites>\n");
1992 fprintf(fp, " <testsuite name=\"%s\" time=\"%.3f\" "
1993 "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
1995 total_runtime * 1000, /* miliseconds */
1996 (unsigned)total_executed,
1997 (unsigned)total_failed,
1998 (unsigned)total_errors,
1999 (unsigned)total_skipped);
2001 for (i = 0; i < total_executed; i++) {
2002 struct CMUnitTestState *cmtest = &cm_tests[i];
2004 fprintf(fp, " <testcase name=\"%s\" time=\"%.3f\" >\n",
2005 cmtest->test->name, cmtest->runtime * 1000);
2007 switch (cmtest->status) {
2009 case CM_TEST_FAILED:
2010 if (cmtest->error_message != NULL) {
2011 fprintf(fp, " <failure><![CDATA[%s]]></failure>\n",
2012 cmtest->error_message);
2014 fprintf(fp, " <failure message=\"Unknown error\" />\n");
2017 case CM_TEST_SKIPPED:
2018 fprintf(fp, " <skipped/>\n");
2021 case CM_TEST_PASSED:
2022 case CM_TEST_NOT_STARTED:
2026 fprintf(fp, " </testcase>\n");
2029 fprintf(fp, " </testsuite>\n");
2030 fprintf(fp, "</testsuites>\n");
2037 static void cmprintf_group_start_standard(const size_t num_tests)
2039 print_message("[==========] Running %u test(s).\n",
2040 (unsigned)num_tests);
2043 static void cmprintf_group_finish_standard(size_t total_executed,
2044 size_t total_passed,
2045 size_t total_failed,
2046 size_t total_errors,
2047 struct CMUnitTestState *cm_tests)
2051 print_message("[==========] %u test(s) run.\n", (unsigned)total_executed);
2052 print_error("[ PASSED ] %u test(s).\n",
2053 (unsigned)(total_passed));
2056 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
2057 for (i = 0; i < total_executed; i++) {
2058 struct CMUnitTestState *cmtest = &cm_tests[i];
2060 if (cmtest->status == CM_TEST_FAILED) {
2061 print_error("[ FAILED ] %s\n", cmtest->test->name);
2064 print_error("\n %u FAILED TEST(S)\n",
2065 (unsigned)(total_failed + total_errors));
2069 static void cmprintf_standard(enum cm_printf_type type,
2070 const char *test_name,
2071 const char *error_message)
2074 case PRINTF_TEST_START:
2075 print_message("[ RUN ] %s\n", test_name);
2077 case PRINTF_TEST_SUCCESS:
2078 print_message("[ OK ] %s\n", test_name);
2080 case PRINTF_TEST_FAILURE:
2081 if (error_message != NULL) {
2082 print_error("%s\n", error_message);
2084 print_message("[ FAILED ] %s\n", test_name);
2086 case PRINTF_TEST_SKIPPED:
2087 print_message("[ SKIPPED ] %s\n", test_name);
2089 case PRINTF_TEST_ERROR:
2090 if (error_message != NULL) {
2091 print_error("%s\n", error_message);
2093 print_error("[ ERROR ] %s\n", test_name);
2098 static void cmprintf_group_start_tap(const size_t num_tests)
2100 print_message("1..%u\n", (unsigned)num_tests);
2103 static void cmprintf_tap(enum cm_printf_type type,
2104 uint32_t test_number,
2105 const char *test_name,
2106 const char *error_message)
2109 case PRINTF_TEST_START:
2111 case PRINTF_TEST_SUCCESS:
2112 print_message("ok %u - %s\n", (unsigned)test_number, test_name);
2114 case PRINTF_TEST_FAILURE:
2115 print_message("not ok %u - %s\n", (unsigned)test_number, test_name);
2116 if (error_message != NULL) {
2120 msg = strdup(error_message);
2126 while (p[0] != '\0') {
2129 p = strchr(q, '\n');
2134 print_message("# %s\n", q);
2144 case PRINTF_TEST_SKIPPED:
2145 print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name);
2147 case PRINTF_TEST_ERROR:
2148 print_message("not ok %u - %s %s\n",
2149 (unsigned)test_number, test_name, error_message);
2154 static void cmprintf_subunit(enum cm_printf_type type,
2155 const char *test_name,
2156 const char *error_message)
2159 case PRINTF_TEST_START:
2160 print_message("test: %s\n", test_name);
2162 case PRINTF_TEST_SUCCESS:
2163 print_message("success: %s\n", test_name);
2165 case PRINTF_TEST_FAILURE:
2166 print_message("failure: %s", test_name);
2167 if (error_message != NULL) {
2168 print_message(" [\n%s]\n", error_message);
2171 case PRINTF_TEST_SKIPPED:
2172 print_message("skip: %s\n", test_name);
2174 case PRINTF_TEST_ERROR:
2175 print_message("error: %s [ %s ]\n", test_name, error_message);
2180 static void cmprintf_group_start(const size_t num_tests)
2182 enum cm_message_output output;
2184 output = cm_get_output();
2187 case CM_OUTPUT_STDOUT:
2188 cmprintf_group_start_standard(num_tests);
2190 case CM_OUTPUT_SUBUNIT:
2193 cmprintf_group_start_tap(num_tests);
2200 static void cmprintf_group_finish(const char *group_name,
2201 size_t total_executed,
2202 size_t total_passed,
2203 size_t total_failed,
2204 size_t total_errors,
2205 size_t total_skipped,
2206 double total_runtime,
2207 struct CMUnitTestState *cm_tests)
2209 enum cm_message_output output;
2211 output = cm_get_output();
2214 case CM_OUTPUT_STDOUT:
2215 cmprintf_group_finish_standard(total_executed,
2221 case CM_OUTPUT_SUBUNIT:
2225 cmprintf_group_finish_xml(group_name,
2236 static void cmprintf(enum cm_printf_type type,
2238 const char *test_name,
2239 const char *error_message)
2241 enum cm_message_output output;
2243 output = cm_get_output();
2246 case CM_OUTPUT_STDOUT:
2247 cmprintf_standard(type, test_name, error_message);
2249 case CM_OUTPUT_SUBUNIT:
2250 cmprintf_subunit(type, test_name, error_message);
2253 cmprintf_tap(type, test_number, test_name, error_message);
2260 void cmocka_set_message_output(enum cm_message_output output)
2262 global_msg_output = output;
2265 /****************************************************************************
2267 ****************************************************************************/
2269 #ifdef HAVE_STRUCT_TIMESPEC
2270 static struct timespec cm_tspecdiff(struct timespec time1,
2271 struct timespec time0)
2273 struct timespec ret;
2277 if (time0.tv_nsec > time1.tv_nsec) {
2278 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
2279 time0.tv_nsec -= (long int) (1E9 * xsec);
2280 time0.tv_sec += xsec;
2283 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
2284 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
2285 time0.tv_nsec += (long int) (1E9 * xsec);
2286 time0.tv_sec -= xsec;
2289 ret.tv_sec = time1.tv_sec - time0.tv_sec;
2290 ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
2292 if (time1.tv_sec < time0.tv_sec) {
2296 ret.tv_sec = ret.tv_sec * sign;
2301 static double cm_secdiff(struct timespec clock1, struct timespec clock0)
2304 struct timespec diff;
2306 diff = cm_tspecdiff(clock1, clock0);
2309 ret += (double) diff.tv_nsec / (double) 1E9;
2313 #endif /* HAVE_STRUCT_TIMESPEC */
2315 /****************************************************************************
2316 * CMOCKA TEST RUNNER
2317 ****************************************************************************/
2318 static int cmocka_run_one_test_or_fixture(const char *function_name,
2319 CMUnitTestFunction test_func,
2320 CMFixtureFunction setup_func,
2321 CMFixtureFunction teardown_func,
2323 const void *const heap_check_point)
2325 const ListNode * const volatile check_point = (const ListNode*)
2326 (heap_check_point != NULL ?
2327 heap_check_point : check_point_allocated_blocks());
2328 int handle_exceptions = 1;
2329 void *current_state = NULL;
2332 /* FIXME check only one test or fixture is set */
2334 /* Detect if we should handle exceptions */
2336 handle_exceptions = !IsDebuggerPresent();
2338 #ifdef UNIT_TESTING_DEBUG
2339 handle_exceptions = 0;
2340 #endif /* UNIT_TESTING_DEBUG */
2343 if (handle_exceptions) {
2346 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2347 default_signal_functions[i] = signal(
2348 exception_signals[i], exception_handler);
2351 previous_exception_filter = SetUnhandledExceptionFilter(
2353 #endif /* !_WIN32 */
2356 /* Init the test structure */
2357 initialize_testing(function_name);
2359 global_running_test = 1;
2361 if (state == NULL) {
2362 state = ¤t_state;
2365 if (setjmp(global_run_test_env) == 0) {
2366 if (test_func != NULL) {
2369 fail_if_blocks_allocated(check_point, function_name);
2371 } else if (setup_func != NULL) {
2372 rc = setup_func(state);
2375 * For setup we can ignore any allocated blocks. We just need to
2376 * ensure they're deallocated on tear down.
2378 } else if (teardown_func != NULL) {
2379 rc = teardown_func(state);
2381 fail_if_blocks_allocated(check_point, function_name);
2385 fail_if_leftover_values(function_name);
2386 global_running_test = 0;
2389 global_running_test = 0;
2392 teardown_testing(function_name);
2394 if (handle_exceptions) {
2397 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2398 signal(exception_signals[i], default_signal_functions[i]);
2401 if (previous_exception_filter) {
2402 SetUnhandledExceptionFilter(previous_exception_filter);
2403 previous_exception_filter = NULL;
2405 #endif /* !_WIN32 */
2411 static int cmocka_run_group_fixture(const char *function_name,
2412 CMFixtureFunction setup_func,
2413 CMFixtureFunction teardown_func,
2415 const void *const heap_check_point)
2419 if (setup_func != NULL) {
2420 rc = cmocka_run_one_test_or_fixture(function_name,
2427 rc = cmocka_run_one_test_or_fixture(function_name,
2438 static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
2440 #ifdef HAVE_STRUCT_TIMESPEC
2441 struct timespec start = {
2445 struct timespec finish = {
2453 if (test_state->test->setup_func != NULL) {
2454 /* Setup the memory check point, it will be evaluated on teardown */
2455 test_state->check_point = check_point_allocated_blocks();
2457 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2459 test_state->test->setup_func,
2462 test_state->check_point);
2464 test_state->status = CM_TEST_ERROR;
2465 cm_print_error("Test setup failed");
2470 #ifdef HAVE_STRUCT_TIMESPEC
2471 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
2475 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2476 test_state->test->test_func,
2482 test_state->status = CM_TEST_PASSED;
2484 if (global_skip_test) {
2485 test_state->status = CM_TEST_SKIPPED;
2486 global_skip_test = 0; /* Do not skip the next test */
2488 test_state->status = CM_TEST_FAILED;
2494 test_state->runtime = 0.0;
2496 #ifdef HAVE_STRUCT_TIMESPEC
2497 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
2498 test_state->runtime = cm_secdiff(finish, start);
2502 if (rc == 0 && test_state->test->teardown_func != NULL) {
2503 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2506 test_state->test->teardown_func,
2508 test_state->check_point);
2510 test_state->status = CM_TEST_ERROR;
2511 cm_print_error("Test teardown failed");
2515 test_state->error_message = cm_error_message;
2516 cm_error_message = NULL;
2521 int _cmocka_run_group_tests(const char *group_name,
2522 const struct CMUnitTest * const tests,
2523 const size_t num_tests,
2524 CMFixtureFunction group_setup,
2525 CMFixtureFunction group_teardown)
2527 struct CMUnitTestState *cm_tests;
2528 const ListNode *group_check_point = check_point_allocated_blocks();
2529 void *group_state = NULL;
2530 size_t total_failed = 0;
2531 size_t total_passed = 0;
2532 size_t total_executed = 0;
2533 size_t total_errors = 0;
2534 size_t total_skipped = 0;
2535 double total_runtime = 0;
2539 /* Make sure LargestIntegralType is at least the size of a pointer. */
2540 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
2542 cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests);
2543 if (cm_tests == NULL) {
2547 cmprintf_group_start(num_tests);
2549 /* Setup cmocka test array */
2550 for (i = 0; i < num_tests; i++) {
2551 cm_tests[i] = (struct CMUnitTestState) {
2553 .status = CM_TEST_NOT_STARTED,
2559 /* Run group setup */
2560 if (group_setup != NULL) {
2561 rc = cmocka_run_group_fixture("cmocka_group_setup",
2570 for (i = 0; i < num_tests; i++) {
2571 struct CMUnitTestState *cmtest = &cm_tests[i];
2572 size_t test_number = i + 1;
2574 cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
2576 if (group_state != NULL) {
2577 cm_tests[i].state = group_state;
2579 rc = cmocka_run_one_tests(cmtest);
2581 total_runtime += cmtest->runtime;
2583 switch (cmtest->status) {
2584 case CM_TEST_PASSED:
2585 cmprintf(PRINTF_TEST_SUCCESS,
2588 cmtest->error_message);
2591 case CM_TEST_SKIPPED:
2592 cmprintf(PRINTF_TEST_SKIPPED,
2595 cmtest->error_message);
2598 case CM_TEST_FAILED:
2599 cmprintf(PRINTF_TEST_FAILURE,
2602 cmtest->error_message);
2606 cmprintf(PRINTF_TEST_ERROR,
2609 "Internal cmocka error");
2614 cmprintf(PRINTF_TEST_ERROR,
2617 "Could not run the test - check test fixtures");
2622 cmprintf(PRINTF_TEST_ERROR, 0,
2623 group_name, "Group setup failed");
2627 /* Run group teardown */
2628 if (group_teardown != NULL) {
2629 rc = cmocka_run_group_fixture("cmocka_group_teardown",
2636 cmprintf_group_finish(group_name,
2645 for (i = 0; i < num_tests; i++) {
2646 vcm_free_error(discard_const_p(char, cm_tests[i].error_message));
2648 libc_free(cm_tests);
2649 fail_if_blocks_allocated(group_check_point, "cmocka_group_tests");
2651 return total_failed + total_errors;
2654 /****************************************************************************
2655 * DEPRECATED TEST RUNNER
2656 ****************************************************************************/
2659 const char * const function_name, const UnitTestFunction Function,
2660 void ** const volatile state, const UnitTestFunctionType function_type,
2661 const void* const heap_check_point) {
2662 const ListNode * const volatile check_point = (const ListNode*)
2664 heap_check_point : check_point_allocated_blocks());
2665 void *current_state = NULL;
2666 volatile int rc = 1;
2667 int handle_exceptions = 1;
2669 handle_exceptions = !IsDebuggerPresent();
2671 #ifdef UNIT_TESTING_DEBUG
2672 handle_exceptions = 0;
2673 #endif /* UNIT_TESTING_DEBUG */
2675 cm_error_message_enabled = 0;
2677 if (handle_exceptions) {
2680 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2681 default_signal_functions[i] = signal(
2682 exception_signals[i], exception_handler);
2685 previous_exception_filter = SetUnhandledExceptionFilter(
2687 #endif /* !_WIN32 */
2690 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
2691 print_message("[ RUN ] %s\n", function_name);
2693 initialize_testing(function_name);
2694 global_running_test = 1;
2695 if (setjmp(global_run_test_env) == 0) {
2696 Function(state ? state : ¤t_state);
2697 fail_if_leftover_values(function_name);
2699 /* If this is a setup function then ignore any allocated blocks
2700 * only ensure they're deallocated on tear down. */
2701 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
2702 fail_if_blocks_allocated(check_point, function_name);
2705 global_running_test = 0;
2707 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
2708 print_message("[ OK ] %s\n", function_name);
2712 global_running_test = 0;
2713 print_message("[ FAILED ] %s\n", function_name);
2715 teardown_testing(function_name);
2717 if (handle_exceptions) {
2720 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2721 signal(exception_signals[i], default_signal_functions[i]);
2724 if (previous_exception_filter) {
2725 SetUnhandledExceptionFilter(previous_exception_filter);
2726 previous_exception_filter = NULL;
2728 #endif /* !_WIN32 */
2735 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
2736 /* Whether to execute the next test. */
2737 int run_next_test = 1;
2738 /* Whether the previous test failed. */
2739 int previous_test_failed = 0;
2740 /* Whether the previous setup failed. */
2741 int previous_setup_failed = 0;
2742 /* Check point of the heap state. */
2743 const ListNode * const check_point = check_point_allocated_blocks();
2744 /* Current test being executed. */
2745 size_t current_test = 0;
2746 /* Number of tests executed. */
2747 size_t tests_executed = 0;
2748 /* Number of failed tests. */
2749 size_t total_failed = 0;
2750 /* Number of setup functions. */
2752 /* Number of teardown functions. */
2753 size_t teardowns = 0;
2756 * A stack of test states. A state is pushed on the stack
2757 * when a test setup occurs and popped on tear down.
2759 TestState* test_states =
2760 (TestState*)malloc(number_of_tests * sizeof(*test_states));
2761 /* The number of test states which should be 0 at the end */
2762 long number_of_test_states = 0;
2763 /* Names of the tests that failed. */
2764 const char** failed_names = (const char**)malloc(number_of_tests *
2765 sizeof(*failed_names));
2766 void **current_state = NULL;
2768 /* Count setup and teardown functions */
2769 for (i = 0; i < number_of_tests; i++) {
2770 const UnitTest * const test = &tests[i];
2772 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) {
2776 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) {
2781 print_message("[==========] Running %"PRIdS " test(s).\n",
2782 number_of_tests - setups - teardowns);
2784 /* Make sure LargestIntegralType is at least the size of a pointer. */
2785 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
2787 while (current_test < number_of_tests) {
2788 const ListNode *test_check_point = NULL;
2789 TestState *current_TestState;
2790 const UnitTest * const test = &tests[current_test++];
2791 if (!test->function) {
2795 switch (test->function_type) {
2796 case UNIT_TEST_FUNCTION_TYPE_TEST:
2797 if (! previous_setup_failed) {
2801 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
2802 /* Checkpoint the heap before the setup. */
2803 current_TestState = &test_states[number_of_test_states++];
2804 current_TestState->check_point = check_point_allocated_blocks();
2805 test_check_point = current_TestState->check_point;
2806 current_state = ¤t_TestState->state;
2807 *current_state = NULL;
2811 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
2812 /* Check the heap based on the last setup checkpoint. */
2813 assert_true(number_of_test_states);
2814 current_TestState = &test_states[--number_of_test_states];
2815 test_check_point = current_TestState->check_point;
2816 current_state = ¤t_TestState->state;
2819 print_error("Invalid unit test function type %d\n",
2820 test->function_type);
2825 if (run_next_test) {
2826 int failed = _run_test(test->name, test->function, current_state,
2827 test->function_type, test_check_point);
2829 failed_names[total_failed] = test->name;
2832 switch (test->function_type) {
2833 case UNIT_TEST_FUNCTION_TYPE_TEST:
2834 previous_test_failed = failed;
2835 total_failed += failed;
2839 case UNIT_TEST_FUNCTION_TYPE_SETUP:
2843 /* Skip forward until the next test or setup function. */
2845 previous_setup_failed = 1;
2847 previous_test_failed = 0;
2850 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
2851 /* If this test failed. */
2852 if (failed && !previous_test_failed) {
2858 assert_null("BUG: shouldn't be here!");
2865 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
2866 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
2868 if (total_failed > 0) {
2869 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
2870 for (i = 0; i < total_failed; i++) {
2871 print_error("[ FAILED ] %s\n", failed_names[i]);
2874 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
2877 if (number_of_test_states != 0) {
2878 print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and "
2879 "teardown %"PRIdS " functions\n", setups, teardowns);
2880 total_failed = (size_t)-1;
2884 free((void*)failed_names);
2886 fail_if_blocks_allocated(check_point, "run_tests");
2887 return (int)total_failed;
2890 int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
2892 UnitTestFunction setup = NULL;
2893 const char *setup_name;
2894 size_t num_setups = 0;
2895 UnitTestFunction teardown = NULL;
2896 const char *teardown_name;
2897 size_t num_teardowns = 0;
2898 size_t current_test = 0;
2901 /* Number of tests executed. */
2902 size_t tests_executed = 0;
2903 /* Number of failed tests. */
2904 size_t total_failed = 0;
2905 /* Check point of the heap state. */
2906 const ListNode * const check_point = check_point_allocated_blocks();
2907 const char** failed_names = (const char**)malloc(number_of_tests *
2908 sizeof(*failed_names));
2909 void **current_state = NULL;
2910 TestState group_state;
2912 /* Find setup and teardown function */
2913 for (i = 0; i < number_of_tests; i++) {
2914 const UnitTest * const test = &tests[i];
2916 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
2917 if (setup == NULL) {
2918 setup = test->function;
2919 setup_name = test->name;
2922 print_error("[ ERROR ] More than one group setup function detected\n");
2927 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
2928 if (teardown == NULL) {
2929 teardown = test->function;
2930 teardown_name = test->name;
2933 print_error("[ ERROR ] More than one group teardown function detected\n");
2939 print_message("[==========] Running %"PRIdS " test(s).\n",
2940 number_of_tests - num_setups - num_teardowns);
2942 if (setup != NULL) {
2945 group_state.check_point = check_point_allocated_blocks();
2946 current_state = &group_state.state;
2947 *current_state = NULL;
2948 failed = _run_test(setup_name,
2951 UNIT_TEST_FUNCTION_TYPE_SETUP,
2952 group_state.check_point);
2954 failed_names[total_failed] = setup_name;
2957 total_failed += failed;
2961 while (current_test < number_of_tests) {
2963 const UnitTest * const test = &tests[current_test++];
2964 if (test->function == NULL) {
2968 switch (test->function_type) {
2969 case UNIT_TEST_FUNCTION_TYPE_TEST:
2972 case UNIT_TEST_FUNCTION_TYPE_SETUP:
2973 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
2974 case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
2975 case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
2978 print_error("Invalid unit test function type %d\n",
2979 test->function_type);
2986 failed = _run_test(test->name,
2989 test->function_type,
2992 failed_names[total_failed] = test->name;
2995 total_failed += failed;
3000 if (teardown != NULL) {
3003 failed = _run_test(teardown_name,
3006 UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
3007 group_state.check_point);
3009 failed_names[total_failed] = teardown_name;
3012 total_failed += failed;
3016 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3017 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3020 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3021 for (i = 0; i < total_failed; i++) {
3022 print_error("[ FAILED ] %s\n", failed_names[i]);
3025 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3028 free((void*)failed_names);
3029 fail_if_blocks_allocated(check_point, "run_group_tests");
3031 return (int)total_failed;