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
39 * This allows to add a platform specific header file. Some embedded platforms
40 * sometimes miss certain types and definitions.
44 * typedef unsigned long int uintptr_t
45 * #define _UINTPTR_T 1
46 * #define _UINTPTR_T_DEFINED 1
48 #ifdef CMOCKA_PLATFORM_INCLUDE
49 # include "cmocka_platform.h"
50 #endif /* CMOCKA_PLATFORM_INCLUDE */
52 #include <cmocka_private.h>
55 /* Size of guard bytes around dynamically allocated blocks. */
56 #define MALLOC_GUARD_SIZE 16
57 /* Pattern used to initialize guard blocks. */
58 #define MALLOC_GUARD_PATTERN 0xEF
59 /* Pattern used to initialize memory allocated with test_malloc(). */
60 #define MALLOC_ALLOC_PATTERN 0xBA
61 #define MALLOC_FREE_PATTERN 0xCD
62 /* Alignment of allocated blocks. NOTE: This must be base2. */
63 #define MALLOC_ALIGNMENT sizeof(size_t)
65 /* Printf formatting for source code locations. */
66 #define SOURCE_LOCATION_FORMAT "%s:%u"
68 #if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
69 # define CMOCKA_THREAD __thread
70 #elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE)
71 # define CMOCKA_THREAD __declspec(thread)
73 # define CMOCKA_THREAD
76 #ifdef HAVE_CLOCK_GETTIME_REALTIME
77 #define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts))
79 #define CMOCKA_CLOCK_GETTIME(clock_id, ts)
83 * Declare and initialize the pointer member of ValuePointer variable name
86 #define declare_initialize_value_pointer_pointer(name, ptr) \
89 name.x.pointer = (void*)(ptr)
92 * Declare and initialize the value member of ValuePointer variable name
95 #define declare_initialize_value_pointer_value(name, val) \
99 /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */
100 #define cast_largest_integral_type_to_pointer( \
101 pointer_type, largest_integral_type) \
102 ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer)
104 /* Used to cast LargetIntegralType to void* and vice versa. */
105 typedef union ValuePointer {
106 LargestIntegralType value;
108 #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
109 unsigned int padding;
115 /* Doubly linked list node. */
116 typedef struct ListNode {
119 struct ListNode *next;
120 struct ListNode *prev;
123 /* Debug information for malloc(). */
124 typedef struct MallocBlockInfo {
125 void* block; /* Address of the block returned by malloc(). */
126 size_t allocated_size; /* Total size of the allocated block. */
127 size_t size; /* Request block size. */
128 SourceLocation location; /* Where the block was allocated. */
129 ListNode node; /* Node within list of all allocated blocks. */
132 /* State of each test. */
133 typedef struct TestState {
134 const ListNode *check_point; /* Check point of the test if there's a */
135 /* setup function. */
136 void *state; /* State associated with the test. */
139 /* Determines whether two values are the same. */
140 typedef int (*EqualityFunction)(const void *left, const void *right);
142 /* Value of a symbol and the place it was declared. */
143 typedef struct SymbolValue {
144 SourceLocation location;
145 LargestIntegralType value;
149 * Contains a list of values for a symbol.
150 * NOTE: Each structure referenced by symbol_values_list_head must have a
151 * SourceLocation as its' first member.
153 typedef struct SymbolMapValue {
154 const char *symbol_name;
155 ListNode symbol_values_list_head;
158 /* Used by list_free() to deallocate values referenced by list nodes. */
159 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
161 /* Structure used to check the range of integer types.a */
162 typedef struct CheckIntegerRange {
163 CheckParameterEvent event;
164 LargestIntegralType minimum;
165 LargestIntegralType maximum;
168 /* Structure used to check whether an integer value is in a set. */
169 typedef struct CheckIntegerSet {
170 CheckParameterEvent event;
171 const LargestIntegralType *set;
175 /* Used to check whether a parameter matches the area of memory referenced by
177 typedef struct CheckMemoryData {
178 CheckParameterEvent event;
183 static ListNode* list_initialize(ListNode * const node);
184 static ListNode* list_add(ListNode * const head, ListNode *new_node);
185 static ListNode* list_add_value(ListNode * const head, const void *value,
187 static ListNode* list_remove(
188 ListNode * const node, const CleanupListValue cleanup_value,
189 void * const cleanup_value_data);
190 static void list_remove_free(
191 ListNode * const node, const CleanupListValue cleanup_value,
192 void * const cleanup_value_data);
193 static int list_empty(const ListNode * const head);
194 static int list_find(
195 ListNode * const head, const void *value,
196 const EqualityFunction equal_func, ListNode **output);
197 static int list_first(ListNode * const head, ListNode **output);
198 static ListNode* list_free(
199 ListNode * const head, const CleanupListValue cleanup_value,
200 void * const cleanup_value_data);
202 static void add_symbol_value(
203 ListNode * const symbol_map_head, const char * const symbol_names[],
204 const size_t number_of_symbol_names, const void* value, const int count);
205 static int get_symbol_value(
206 ListNode * const symbol_map_head, const char * const symbol_names[],
207 const size_t number_of_symbol_names, void **output);
208 static void free_value(const void *value, void *cleanup_value_data);
209 static void free_symbol_map_value(
210 const void *value, void *cleanup_value_data);
211 static void remove_always_return_values(ListNode * const map_head,
212 const size_t number_of_symbol_names);
213 static int check_for_leftover_values(
214 const ListNode * const map_head, const char * const error_message,
215 const size_t number_of_symbol_names);
217 * This must be called at the beginning of a test to initialize some data
220 static void initialize_testing(const char *test_name);
222 /* This must be called at the end of a test to free() allocated structures. */
223 static void teardown_testing(const char *test_name);
225 static int cm_error_message_enabled = 1;
226 static CMOCKA_THREAD char *cm_error_message;
228 void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
231 * Keeps track of the calling context returned by setenv() so that the fail()
232 * method can jump out of a test.
234 static CMOCKA_THREAD jmp_buf global_run_test_env;
235 static CMOCKA_THREAD int global_running_test = 0;
237 /* Keeps track of the calling context returned by setenv() so that */
238 /* mock_assert() can optionally jump back to expect_assert_failure(). */
239 jmp_buf global_expect_assert_env;
240 int global_expecting_assert = 0;
241 const char *global_last_failed_assert = NULL;
242 static int global_skip_test;
244 /* Keeps a map of the values that functions will have to return to provide */
245 /* mocked interfaces. */
246 static CMOCKA_THREAD ListNode global_function_result_map_head;
247 /* Location of the last mock value returned was declared. */
248 static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
250 /* Keeps a map of the values that functions expect as parameters to their
251 * mocked interfaces. */
252 static CMOCKA_THREAD ListNode global_function_parameter_map_head;
253 /* Location of last parameter value checked was declared. */
254 static CMOCKA_THREAD SourceLocation global_last_parameter_location;
256 /* List of all currently allocated blocks. */
257 static CMOCKA_THREAD ListNode global_allocated_blocks;
259 static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
262 /* Signals caught by exception_handler(). */
263 static const int exception_signals[] = {
275 /* Default signal functions that should be restored after a test is complete. */
276 typedef void (*SignalFunction)(int signal);
277 static SignalFunction default_signal_functions[
278 ARRAY_SIZE(exception_signals)];
282 /* The default exception filter. */
283 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
285 /* Fatal exceptions. */
286 typedef struct ExceptionCodeInfo {
288 const char* description;
291 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
293 static const ExceptionCodeInfo exception_codes[] = {
294 EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
295 EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
296 EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
297 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
298 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
299 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
300 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
301 EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
302 EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
303 EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
304 EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
305 EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
306 EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
307 EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
308 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
309 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
310 EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
311 EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
312 EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
313 EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
317 enum CMUnitTestStatus {
325 struct CMUnitTestState {
326 const ListNode *check_point; /* Check point of the test if there's a setup function. */
327 const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
328 void *state; /* State associated with the test */
329 const char *error_message; /* The error messages by the test */
330 enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
331 double runtime; /* Time calculations */
334 /* Exit the currently executing test. */
335 static void exit_test(const int quit_application)
337 const char *abort_test = getenv("CMOCKA_TEST_ABORT");
339 if (abort_test != NULL && abort_test[0] == '1') {
340 print_error("%s", cm_error_message);
342 } else if (global_running_test) {
343 longjmp(global_run_test_env, 1);
344 } else if (quit_application) {
349 void _skip(const char * const file, const int line)
351 cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
352 global_skip_test = 1;
356 /* Initialize a SourceLocation structure. */
357 static void initialize_source_location(SourceLocation * const location) {
358 assert_non_null(location);
359 location->file = NULL;
364 /* Determine whether a source location is currently set. */
365 static int source_location_is_set(const SourceLocation * const location) {
366 assert_non_null(location);
367 return location->file && location->line;
371 /* Set a source location. */
372 static void set_source_location(
373 SourceLocation * const location, const char * const file,
375 assert_non_null(location);
376 location->file = file;
377 location->line = line;
381 /* Create function results and expected parameter lists. */
382 void initialize_testing(const char *test_name) {
384 list_initialize(&global_function_result_map_head);
385 initialize_source_location(&global_last_mock_value_location);
386 list_initialize(&global_function_parameter_map_head);
387 initialize_source_location(&global_last_parameter_location);
391 static void fail_if_leftover_values(const char *test_name) {
392 int error_occurred = 0;
394 remove_always_return_values(&global_function_result_map_head, 1);
395 if (check_for_leftover_values(
396 &global_function_result_map_head,
397 "%s() has remaining non-returned values.\n", 1)) {
401 remove_always_return_values(&global_function_parameter_map_head, 2);
402 if (check_for_leftover_values(
403 &global_function_parameter_map_head,
404 "%s parameter still has values that haven't been checked.\n", 2)) {
407 if (error_occurred) {
413 static void teardown_testing(const char *test_name) {
415 list_free(&global_function_result_map_head, free_symbol_map_value,
417 initialize_source_location(&global_last_mock_value_location);
418 list_free(&global_function_parameter_map_head, free_symbol_map_value,
420 initialize_source_location(&global_last_parameter_location);
423 /* Initialize a list node. */
424 static ListNode* list_initialize(ListNode * const node) {
434 * Adds a value at the tail of a given list.
435 * The node referencing the value is allocated from the heap.
437 static ListNode* list_add_value(ListNode * const head, const void *value,
438 const int refcount) {
439 ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
440 assert_non_null(head);
441 assert_non_null(value);
442 new_node->value = value;
443 new_node->refcount = refcount;
444 return list_add(head, new_node);
448 /* Add new_node to the end of the list. */
449 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
450 assert_non_null(head);
451 assert_non_null(new_node);
452 new_node->next = head;
453 new_node->prev = head->prev;
454 head->prev->next = new_node;
455 head->prev = new_node;
460 /* Remove a node from a list. */
461 static ListNode* list_remove(
462 ListNode * const node, const CleanupListValue cleanup_value,
463 void * const cleanup_value_data) {
464 assert_non_null(node);
465 node->prev->next = node->next;
466 node->next->prev = node->prev;
468 cleanup_value(node->value, cleanup_value_data);
474 /* Remove a list node from a list and free the node. */
475 static void list_remove_free(
476 ListNode * const node, const CleanupListValue cleanup_value,
477 void * const cleanup_value_data) {
478 assert_non_null(node);
479 free(list_remove(node, cleanup_value, cleanup_value_data));
484 * Frees memory kept by a linked list The cleanup_value function is called for
485 * every "value" field of nodes in the list, except for the head. In addition
486 * to each list value, cleanup_value_data is passed to each call to
487 * cleanup_value. The head of the list is not deallocated.
489 static ListNode* list_free(
490 ListNode * const head, const CleanupListValue cleanup_value,
491 void * const cleanup_value_data) {
492 assert_non_null(head);
493 while (!list_empty(head)) {
494 list_remove_free(head->next, cleanup_value, cleanup_value_data);
500 /* Determine whether a list is empty. */
501 static int list_empty(const ListNode * const head) {
502 assert_non_null(head);
503 return head->next == head;
508 * Find a value in the list using the equal_func to compare each node with the
511 static int list_find(ListNode * const head, const void *value,
512 const EqualityFunction equal_func, ListNode **output) {
514 assert_non_null(head);
515 for (current = head->next; current != head; current = current->next) {
516 if (equal_func(current->value, value)) {
524 /* Returns the first node of a list */
525 static int list_first(ListNode * const head, ListNode **output) {
526 ListNode *target_node;
527 assert_non_null(head);
528 if (list_empty(head)) {
531 target_node = head->next;
532 *output = target_node;
537 /* Deallocate a value referenced by a list. */
538 static void free_value(const void *value, void *cleanup_value_data) {
539 (void)cleanup_value_data;
540 assert_non_null(value);
545 /* Releases memory associated to a symbol_map_value. */
546 static void free_symbol_map_value(const void *value,
547 void *cleanup_value_data) {
548 SymbolMapValue * const map_value = (SymbolMapValue*)value;
549 const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
550 assert_non_null(value);
551 list_free(&map_value->symbol_values_list_head,
552 children ? free_symbol_map_value : free_value,
553 (void *) ((uintptr_t)children - 1));
559 * Determine whether a symbol name referenced by a symbol_map_value matches the
560 * specified function name.
562 static int symbol_names_match(const void *map_value, const void *symbol) {
563 return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
564 (const char*)symbol);
569 * Adds a value to the queue of values associated with the given hierarchy of
570 * symbols. It's assumed value is allocated from the heap.
572 static void add_symbol_value(ListNode * const symbol_map_head,
573 const char * const symbol_names[],
574 const size_t number_of_symbol_names,
575 const void* value, const int refcount) {
576 const char* symbol_name;
577 ListNode *target_node;
578 SymbolMapValue *target_map_value;
579 assert_non_null(symbol_map_head);
580 assert_non_null(symbol_names);
581 assert_true(number_of_symbol_names);
582 symbol_name = symbol_names[0];
584 if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
586 SymbolMapValue * const new_symbol_map_value =
587 (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
588 new_symbol_map_value->symbol_name = symbol_name;
589 list_initialize(&new_symbol_map_value->symbol_values_list_head);
590 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
594 target_map_value = (SymbolMapValue*)target_node->value;
595 if (number_of_symbol_names == 1) {
596 list_add_value(&target_map_value->symbol_values_list_head,
599 add_symbol_value(&target_map_value->symbol_values_list_head,
600 &symbol_names[1], number_of_symbol_names - 1, value,
607 * Gets the next value associated with the given hierarchy of symbols.
608 * The value is returned as an output parameter with the function returning the
609 * node's old refcount value if a value is found, 0 otherwise. This means that
610 * a return value of 1 indicates the node was just removed from the list.
612 static int get_symbol_value(
613 ListNode * const head, const char * const symbol_names[],
614 const size_t number_of_symbol_names, void **output) {
615 const char* symbol_name;
616 ListNode *target_node;
617 assert_non_null(head);
618 assert_non_null(symbol_names);
619 assert_true(number_of_symbol_names);
620 assert_non_null(output);
621 symbol_name = symbol_names[0];
623 if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
624 SymbolMapValue *map_value;
625 ListNode *child_list;
626 int return_value = 0;
627 assert_non_null(target_node);
628 assert_non_null(target_node->value);
630 map_value = (SymbolMapValue*)target_node->value;
631 child_list = &map_value->symbol_values_list_head;
633 if (number_of_symbol_names == 1) {
634 ListNode *value_node = NULL;
635 return_value = list_first(child_list, &value_node);
636 assert_true(return_value);
637 *output = (void*) value_node->value;
638 return_value = value_node->refcount;
639 if (--value_node->refcount == 0) {
640 list_remove_free(value_node, NULL, NULL);
643 return_value = get_symbol_value(
644 child_list, &symbol_names[1], number_of_symbol_names - 1,
647 if (list_empty(child_list)) {
648 list_remove_free(target_node, free_symbol_map_value, (void*)0);
652 cm_print_error("No entries for symbol %s.\n", symbol_name);
659 * Traverse down a tree of symbol values and remove the first symbol value
660 * in each branch that has a refcount < -1 (i.e should always be returned
661 * and has been returned at least once).
663 static void remove_always_return_values(ListNode * const map_head,
664 const size_t number_of_symbol_names) {
666 assert_non_null(map_head);
667 assert_true(number_of_symbol_names);
668 current = map_head->next;
669 while (current != map_head) {
670 SymbolMapValue * const value = (SymbolMapValue*)current->value;
671 ListNode * const next = current->next;
672 ListNode *child_list;
673 assert_non_null(value);
674 child_list = &value->symbol_values_list_head;
676 if (!list_empty(child_list)) {
677 if (number_of_symbol_names == 1) {
678 ListNode * const child_node = child_list->next;
679 /* If this item has been returned more than once, free it. */
680 if (child_node->refcount < -1) {
681 list_remove_free(child_node, free_value, NULL);
684 remove_always_return_values(child_list,
685 number_of_symbol_names - 1);
689 if (list_empty(child_list)) {
690 list_remove_free(current, free_value, NULL);
697 * Checks if there are any leftover values set up by the test that were never
698 * retrieved through execution, and fail the test if that is the case.
700 static int check_for_leftover_values(
701 const ListNode * const map_head, const char * const error_message,
702 const size_t number_of_symbol_names) {
703 const ListNode *current;
704 int symbols_with_leftover_values = 0;
705 assert_non_null(map_head);
706 assert_true(number_of_symbol_names);
708 for (current = map_head->next; current != map_head;
709 current = current->next) {
710 const SymbolMapValue * const value =
711 (SymbolMapValue*)current->value;
712 const ListNode *child_list;
713 assert_non_null(value);
714 child_list = &value->symbol_values_list_head;
716 if (!list_empty(child_list)) {
717 if (number_of_symbol_names == 1) {
718 const ListNode *child_node;
719 cm_print_error(error_message, value->symbol_name);
721 for (child_node = child_list->next; child_node != child_list;
722 child_node = child_node->next) {
723 const SourceLocation * const location =
724 (const SourceLocation*)child_node->value;
725 cm_print_error(SOURCE_LOCATION_FORMAT
726 ": note: remaining item was declared here\n",
727 location->file, location->line);
730 cm_print_error("%s.", value->symbol_name);
731 check_for_leftover_values(child_list, error_message,
732 number_of_symbol_names - 1);
734 symbols_with_leftover_values ++;
737 return symbols_with_leftover_values;
741 /* Get the next return value for the specified mock function. */
742 LargestIntegralType _mock(const char * const function, const char* const file,
745 const int rc = get_symbol_value(&global_function_result_map_head,
746 &function, 1, &result);
748 SymbolValue * const symbol = (SymbolValue*)result;
749 const LargestIntegralType value = symbol->value;
750 global_last_mock_value_location = symbol->location;
756 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
757 "to mock function %s\n", file, line, function);
758 if (source_location_is_set(&global_last_mock_value_location)) {
759 cm_print_error(SOURCE_LOCATION_FORMAT
760 ": note: Previously returned mock value was declared here\n",
761 global_last_mock_value_location.file,
762 global_last_mock_value_location.line);
764 cm_print_error("There were no previously returned mock values for "
773 /* Add a return value for the specified mock function name. */
774 void _will_return(const char * const function_name, const char * const file,
775 const int line, const LargestIntegralType value,
777 SymbolValue * const return_value =
778 (SymbolValue*)malloc(sizeof(*return_value));
779 assert_true(count > 0 || count == -1);
780 return_value->value = value;
781 set_source_location(&return_value->location, file, line);
782 add_symbol_value(&global_function_result_map_head, &function_name, 1,
783 return_value, count);
788 * Add a custom parameter checking function. If the event parameter is NULL
789 * the event structure is allocated internally by this function. If event
790 * parameter is provided it must be allocated on the heap and doesn't need to
791 * be deallocated by the caller.
794 const char* const function, const char* const parameter,
795 const char* const file, const int line,
796 const CheckParameterValue check_function,
797 const LargestIntegralType check_data,
798 CheckParameterEvent * const event, const int count) {
799 CheckParameterEvent * const check =
800 event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
801 const char* symbols[] = {function, parameter};
802 check->parameter_name = parameter;
803 check->check_value = check_function;
804 check->check_value_data = check_data;
805 set_source_location(&check->location, file, line);
806 add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
811 /* Returns 1 if the specified values are equal. If the values are not equal
812 * an error is displayed and 0 is returned. */
813 static int values_equal_display_error(const LargestIntegralType left,
814 const LargestIntegralType right) {
815 const int equal = left == right;
817 cm_print_error(LargestIntegralTypePrintfFormat " != "
818 LargestIntegralTypePrintfFormat "\n", left, right);
824 * Returns 1 if the specified values are not equal. If the values are equal
825 * an error is displayed and 0 is returned. */
826 static int values_not_equal_display_error(const LargestIntegralType left,
827 const LargestIntegralType right) {
828 const int not_equal = left != right;
830 cm_print_error(LargestIntegralTypePrintfFormat " == "
831 LargestIntegralTypePrintfFormat "\n", left, right);
838 * Determine whether value is contained within check_integer_set.
839 * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
840 * returned and an error is displayed. If invert is 1 and the value is not
841 * in the set 1 is returned, otherwise 0 is returned and an error is
844 static int value_in_set_display_error(
845 const LargestIntegralType value,
846 const CheckIntegerSet * const check_integer_set, const int invert) {
847 int succeeded = invert;
848 assert_non_null(check_integer_set);
850 const LargestIntegralType * const set = check_integer_set->set;
851 const size_t size_of_set = check_integer_set->size_of_set;
853 for (i = 0; i < size_of_set; i++) {
854 if (set[i] == value) {
855 /* If invert = 0 and item is found, succeeded = 1. */
856 /* If invert = 1 and item is found, succeeded = 0. */
857 succeeded = !succeeded;
864 cm_print_error("%" PRIu64 " is %sin the set (", value,
865 invert ? "" : "not ");
866 for (i = 0; i < size_of_set; i++) {
867 cm_print_error("%" PRIu64 ", ", set[i]);
869 cm_print_error(")\n");
876 * Determine whether a value is within the specified range. If the value is
877 * within the specified range 1 is returned. If the value isn't within the
878 * specified range an error is displayed and 0 is returned.
880 static int integer_in_range_display_error(
881 const LargestIntegralType value, const LargestIntegralType range_min,
882 const LargestIntegralType range_max) {
883 if (value >= range_min && value <= range_max) {
886 cm_print_error("%" PRIu64 " is not within the range %" PRIu64 "-%" PRIu64 "\n",
887 value, range_min, range_max);
893 * Determine whether a value is within the specified range. If the value
894 * is not within the range 1 is returned. If the value is within the
895 * specified range an error is displayed and zero is returned.
897 static int integer_not_in_range_display_error(
898 const LargestIntegralType value, const LargestIntegralType range_min,
899 const LargestIntegralType range_max) {
900 if (value < range_min || value > range_max) {
903 cm_print_error("%" PRIu64 " is within the range %" PRIu64 "-%" PRIu64 "\n",
904 value, range_min, range_max);
910 * Determine whether the specified strings are equal. If the strings are equal
911 * 1 is returned. If they're not equal an error is displayed and 0 is
914 static int string_equal_display_error(
915 const char * const left, const char * const right) {
916 if (strcmp(left, right) == 0) {
919 cm_print_error("\"%s\" != \"%s\"\n", left, right);
925 * Determine whether the specified strings are equal. If the strings are not
926 * equal 1 is returned. If they're not equal an error is displayed and 0 is
929 static int string_not_equal_display_error(
930 const char * const left, const char * const right) {
931 if (strcmp(left, right) != 0) {
934 cm_print_error("\"%s\" == \"%s\"\n", left, right);
940 * Determine whether the specified areas of memory are equal. If they're equal
941 * 1 is returned otherwise an error is displayed and 0 is returned.
943 static int memory_equal_display_error(const char* const a, const char* const b,
947 for (i = 0; i < size; i++) {
951 cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
957 cm_print_error("%d bytes of %p and %p differ\n", differences,
966 * Determine whether the specified areas of memory are not equal. If they're
967 * not equal 1 is returned otherwise an error is displayed and 0 is
970 static int memory_not_equal_display_error(
971 const char* const a, const char* const b, const size_t size) {
974 for (i = 0; i < size; i++) {
982 cm_print_error("%"PRIdS "bytes of %p and %p the same\n", same,
990 /* CheckParameterValue callback to check whether a value is within a set. */
991 static int check_in_set(const LargestIntegralType value,
992 const LargestIntegralType check_value_data) {
993 return value_in_set_display_error(value,
994 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
995 check_value_data), 0);
999 /* CheckParameterValue callback to check whether a value isn't within a set. */
1000 static int check_not_in_set(const LargestIntegralType value,
1001 const LargestIntegralType check_value_data) {
1002 return value_in_set_display_error(value,
1003 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1004 check_value_data), 1);
1008 /* Create the callback data for check_in_set() or check_not_in_set() and
1009 * register a check event. */
1010 static void expect_set(
1011 const char* const function, const char* const parameter,
1012 const char* const file, const int line,
1013 const LargestIntegralType values[], const size_t number_of_values,
1014 const CheckParameterValue check_function, const int count) {
1015 CheckIntegerSet * const check_integer_set =
1016 (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
1017 (sizeof(values[0]) * number_of_values));
1018 LargestIntegralType * const set = (LargestIntegralType*)(
1019 check_integer_set + 1);
1020 declare_initialize_value_pointer_pointer(check_data, check_integer_set);
1021 assert_non_null(values);
1022 assert_true(number_of_values);
1023 memcpy(set, values, number_of_values * sizeof(values[0]));
1024 check_integer_set->set = set;
1025 check_integer_set->size_of_set = number_of_values;
1027 function, parameter, file, line, check_function,
1028 check_data.value, &check_integer_set->event, count);
1032 /* Add an event to check whether a value is in a set. */
1033 void _expect_in_set(
1034 const char* const function, const char* const parameter,
1035 const char* const file, const int line,
1036 const LargestIntegralType values[], const size_t number_of_values,
1038 expect_set(function, parameter, file, line, values, number_of_values,
1039 check_in_set, count);
1043 /* Add an event to check whether a value isn't in a set. */
1044 void _expect_not_in_set(
1045 const char* const function, const char* const parameter,
1046 const char* const file, const int line,
1047 const LargestIntegralType values[], const size_t number_of_values,
1049 expect_set(function, parameter, file, line, values, number_of_values,
1050 check_not_in_set, count);
1054 /* CheckParameterValue callback to check whether a value is within a range. */
1055 static int check_in_range(const LargestIntegralType value,
1056 const LargestIntegralType check_value_data) {
1057 CheckIntegerRange * const check_integer_range =
1058 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1060 assert_non_null(check_integer_range);
1061 return integer_in_range_display_error(value, check_integer_range->minimum,
1062 check_integer_range->maximum);
1066 /* CheckParameterValue callback to check whether a value is not within a range. */
1067 static int check_not_in_range(const LargestIntegralType value,
1068 const LargestIntegralType check_value_data) {
1069 CheckIntegerRange * const check_integer_range =
1070 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1072 assert_non_null(check_integer_range);
1073 return integer_not_in_range_display_error(
1074 value, check_integer_range->minimum, check_integer_range->maximum);
1078 /* Create the callback data for check_in_range() or check_not_in_range() and
1079 * register a check event. */
1080 static void expect_range(
1081 const char* const function, const char* const parameter,
1082 const char* const file, const int line,
1083 const LargestIntegralType minimum, const LargestIntegralType maximum,
1084 const CheckParameterValue check_function, const int count) {
1085 CheckIntegerRange * const check_integer_range =
1086 (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
1087 declare_initialize_value_pointer_pointer(check_data, check_integer_range);
1088 check_integer_range->minimum = minimum;
1089 check_integer_range->maximum = maximum;
1090 _expect_check(function, parameter, file, line, check_function,
1091 check_data.value, &check_integer_range->event, count);
1095 /* Add an event to determine whether a parameter is within a range. */
1096 void _expect_in_range(
1097 const char* const function, const char* const parameter,
1098 const char* const file, const int line,
1099 const LargestIntegralType minimum, const LargestIntegralType maximum,
1101 expect_range(function, parameter, file, line, minimum, maximum,
1102 check_in_range, count);
1106 /* Add an event to determine whether a parameter is not within a range. */
1107 void _expect_not_in_range(
1108 const char* const function, const char* const parameter,
1109 const char* const file, const int line,
1110 const LargestIntegralType minimum, const LargestIntegralType maximum,
1112 expect_range(function, parameter, file, line, minimum, maximum,
1113 check_not_in_range, count);
1117 /* CheckParameterValue callback to check whether a value is equal to an
1118 * expected value. */
1119 static int check_value(const LargestIntegralType value,
1120 const LargestIntegralType check_value_data) {
1121 return values_equal_display_error(value, check_value_data);
1125 /* Add an event to check a parameter equals an expected value. */
1127 const char* const function, const char* const parameter,
1128 const char* const file, const int line,
1129 const LargestIntegralType value, const int count) {
1130 _expect_check(function, parameter, file, line, check_value, value, NULL,
1135 /* CheckParameterValue callback to check whether a value is not equal to an
1136 * expected value. */
1137 static int check_not_value(const LargestIntegralType value,
1138 const LargestIntegralType check_value_data) {
1139 return values_not_equal_display_error(value, check_value_data);
1143 /* Add an event to check a parameter is not equal to an expected value. */
1144 void _expect_not_value(
1145 const char* const function, const char* const parameter,
1146 const char* const file, const int line,
1147 const LargestIntegralType value, const int count) {
1148 _expect_check(function, parameter, file, line, check_not_value, value,
1153 /* CheckParameterValue callback to check whether a parameter equals a string. */
1154 static int check_string(const LargestIntegralType value,
1155 const LargestIntegralType check_value_data) {
1156 return string_equal_display_error(
1157 cast_largest_integral_type_to_pointer(char*, value),
1158 cast_largest_integral_type_to_pointer(char*, check_value_data));
1162 /* Add an event to check whether a parameter is equal to a string. */
1163 void _expect_string(
1164 const char* const function, const char* const parameter,
1165 const char* const file, const int line, const char* string,
1167 declare_initialize_value_pointer_pointer(string_pointer,
1168 discard_const(string));
1169 _expect_check(function, parameter, file, line, check_string,
1170 string_pointer.value, NULL, count);
1174 /* CheckParameterValue callback to check whether a parameter is not equals to
1176 static int check_not_string(const LargestIntegralType value,
1177 const LargestIntegralType check_value_data) {
1178 return string_not_equal_display_error(
1179 cast_largest_integral_type_to_pointer(char*, value),
1180 cast_largest_integral_type_to_pointer(char*, check_value_data));
1184 /* Add an event to check whether a parameter is not equal to a string. */
1185 void _expect_not_string(
1186 const char* const function, const char* const parameter,
1187 const char* const file, const int line, const char* string,
1189 declare_initialize_value_pointer_pointer(string_pointer,
1190 discard_const(string));
1191 _expect_check(function, parameter, file, line, check_not_string,
1192 string_pointer.value, NULL, count);
1195 /* CheckParameterValue callback to check whether a parameter equals an area of
1197 static int check_memory(const LargestIntegralType value,
1198 const LargestIntegralType check_value_data) {
1199 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1200 CheckMemoryData*, check_value_data);
1201 assert_non_null(check);
1202 return memory_equal_display_error(
1203 cast_largest_integral_type_to_pointer(const char*, value),
1204 (const char*)check->memory, check->size);
1208 /* Create the callback data for check_memory() or check_not_memory() and
1209 * register a check event. */
1210 static void expect_memory_setup(
1211 const char* const function, const char* const parameter,
1212 const char* const file, const int line,
1213 const void * const memory, const size_t size,
1214 const CheckParameterValue check_function, const int count) {
1215 CheckMemoryData * const check_data =
1216 (CheckMemoryData*)malloc(sizeof(*check_data) + size);
1217 void * const mem = (void*)(check_data + 1);
1218 declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1219 assert_non_null(memory);
1221 memcpy(mem, memory, size);
1222 check_data->memory = mem;
1223 check_data->size = size;
1224 _expect_check(function, parameter, file, line, check_function,
1225 check_data_pointer.value, &check_data->event, count);
1229 /* Add an event to check whether a parameter matches an area of memory. */
1230 void _expect_memory(
1231 const char* const function, const char* const parameter,
1232 const char* const file, const int line, const void* const memory,
1233 const size_t size, const int count) {
1234 expect_memory_setup(function, parameter, file, line, memory, size,
1235 check_memory, count);
1239 /* CheckParameterValue callback to check whether a parameter is not equal to
1240 * an area of memory. */
1241 static int check_not_memory(const LargestIntegralType value,
1242 const LargestIntegralType check_value_data) {
1243 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1244 CheckMemoryData*, check_value_data);
1245 assert_non_null(check);
1246 return memory_not_equal_display_error(
1247 cast_largest_integral_type_to_pointer(const char*, value),
1248 (const char*)check->memory,
1253 /* Add an event to check whether a parameter doesn't match an area of memory. */
1254 void _expect_not_memory(
1255 const char* const function, const char* const parameter,
1256 const char* const file, const int line, const void* const memory,
1257 const size_t size, const int count) {
1258 expect_memory_setup(function, parameter, file, line, memory, size,
1259 check_not_memory, count);
1263 /* CheckParameterValue callback that always returns 1. */
1264 static int check_any(const LargestIntegralType value,
1265 const LargestIntegralType check_value_data) {
1267 (void)check_value_data;
1272 /* Add an event to allow any value for a parameter. */
1274 const char* const function, const char* const parameter,
1275 const char* const file, const int line, const int count) {
1276 _expect_check(function, parameter, file, line, check_any, 0, NULL,
1281 void _check_expected(
1282 const char * const function_name, const char * const parameter_name,
1283 const char* file, const int line, const LargestIntegralType value) {
1285 const char* symbols[] = {function_name, parameter_name};
1286 const int rc = get_symbol_value(&global_function_parameter_map_head,
1287 symbols, 2, &result);
1289 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1290 int check_succeeded;
1291 global_last_parameter_location = check->location;
1292 check_succeeded = check->check_value(value, check->check_value_data);
1296 if (!check_succeeded) {
1297 cm_print_error(SOURCE_LOCATION_FORMAT
1298 ": error: Check of parameter %s, function %s failed\n"
1299 SOURCE_LOCATION_FORMAT
1300 ": note: Expected parameter declared here\n",
1302 parameter_name, function_name,
1303 global_last_parameter_location.file,
1304 global_last_parameter_location.line);
1308 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
1309 "to check parameter %s of function %s\n", file, line,
1310 parameter_name, function_name);
1311 if (source_location_is_set(&global_last_parameter_location)) {
1312 cm_print_error(SOURCE_LOCATION_FORMAT
1313 ": note: Previously declared parameter value was declared here\n",
1314 global_last_parameter_location.file,
1315 global_last_parameter_location.line);
1317 cm_print_error("There were no previously declared parameter values "
1318 "for this test.\n");
1325 /* Replacement for assert. */
1326 void mock_assert(const int result, const char* const expression,
1327 const char* const file, const int line) {
1329 if (global_expecting_assert) {
1330 global_last_failed_assert = expression;
1331 longjmp(global_expect_assert_env, result);
1333 cm_print_error("ASSERT: %s\n", expression);
1340 void _assert_true(const LargestIntegralType result,
1341 const char * const expression,
1342 const char * const file, const int line) {
1344 cm_print_error("%s\n", expression);
1349 void _assert_return_code(const LargestIntegralType result,
1351 const LargestIntegralType error,
1352 const char * const expression,
1353 const char * const file,
1356 LargestIntegralType valmax;
1367 valmax = 2147483647;
1371 if (rlen > sizeof(valmax)) {
1372 valmax = 2147483647;
1374 valmax = 9223372036854775807L;
1379 if (result > valmax - 1) {
1381 cm_print_error("%s < 0, errno(%" PRIu64 "): %s\n",
1382 expression, error, strerror(error));
1384 cm_print_error("%s < 0\n", expression);
1390 void _assert_int_equal(
1391 const LargestIntegralType a, const LargestIntegralType b,
1392 const char * const file, const int line) {
1393 if (!values_equal_display_error(a, b)) {
1399 void _assert_int_not_equal(
1400 const LargestIntegralType a, const LargestIntegralType b,
1401 const char * const file, const int line) {
1402 if (!values_not_equal_display_error(a, b)) {
1408 void _assert_string_equal(const char * const a, const char * const b,
1409 const char * const file, const int line) {
1410 if (!string_equal_display_error(a, b)) {
1416 void _assert_string_not_equal(const char * const a, const char * const b,
1417 const char *file, const int line) {
1418 if (!string_not_equal_display_error(a, b)) {
1424 void _assert_memory_equal(const void * const a, const void * const b,
1425 const size_t size, const char* const file,
1427 if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1433 void _assert_memory_not_equal(const void * const a, const void * const b,
1434 const size_t size, const char* const file,
1436 if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1443 void _assert_in_range(
1444 const LargestIntegralType value, const LargestIntegralType minimum,
1445 const LargestIntegralType maximum, const char* const file,
1447 if (!integer_in_range_display_error(value, minimum, maximum)) {
1452 void _assert_not_in_range(
1453 const LargestIntegralType value, const LargestIntegralType minimum,
1454 const LargestIntegralType maximum, const char* const file,
1456 if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1461 void _assert_in_set(const LargestIntegralType value,
1462 const LargestIntegralType values[],
1463 const size_t number_of_values, const char* const file,
1465 CheckIntegerSet check_integer_set;
1466 check_integer_set.set = values;
1467 check_integer_set.size_of_set = number_of_values;
1468 if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1473 void _assert_not_in_set(const LargestIntegralType value,
1474 const LargestIntegralType values[],
1475 const size_t number_of_values, const char* const file,
1477 CheckIntegerSet check_integer_set;
1478 check_integer_set.set = values;
1479 check_integer_set.size_of_set = number_of_values;
1480 if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1486 /* Get the list of allocated blocks. */
1487 static ListNode* get_allocated_blocks_list() {
1488 /* If it initialized, initialize the list of allocated blocks. */
1489 if (!global_allocated_blocks.value) {
1490 list_initialize(&global_allocated_blocks);
1491 global_allocated_blocks.value = (void*)1;
1493 return &global_allocated_blocks;
1496 static void *libc_malloc(size_t size)
1499 return malloc(size);
1500 #define malloc test_malloc
1503 static void libc_free(void *ptr)
1507 #define free test_free
1510 static void *libc_realloc(void *ptr, size_t size)
1513 return realloc(ptr, size);
1514 #define realloc test_realloc
1517 static void vcm_print_error(const char* const format,
1518 va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
1520 /* It's important to use the libc malloc and free here otherwise
1521 * the automatic free of leaked blocks can reap the error messages
1523 static void vcm_print_error(const char* const format, va_list args)
1530 len = vsnprintf(buffer, sizeof(buffer), format, args);
1536 if (cm_error_message == NULL) {
1537 /* CREATE MESSAGE */
1539 cm_error_message = libc_malloc(len + 1);
1540 if (cm_error_message == NULL) {
1545 /* APPEND MESSAGE */
1548 msg_len = strlen(cm_error_message);
1549 tmp = libc_realloc(cm_error_message, msg_len + len + 1);
1553 cm_error_message = tmp;
1556 if (((size_t)len) < sizeof(buffer)) {
1557 /* Use len + 1 to also copy '\0' */
1558 memcpy(cm_error_message + msg_len, buffer, len + 1);
1561 vsnprintf(cm_error_message + msg_len, len, format, ap);
1566 static void vcm_free_error(char *err_msg)
1571 /* Use the real malloc in this function. */
1573 void* _test_malloc(const size_t size, const char* file, const int line) {
1575 MallocBlockInfo *block_info;
1576 ListNode * const block_list = get_allocated_blocks_list();
1577 const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
1578 sizeof(*block_info) + MALLOC_ALIGNMENT;
1579 char* const block = (char*)malloc(allocate_size);
1580 assert_non_null(block);
1582 /* Calculate the returned address. */
1583 ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
1584 MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1586 /* Initialize the guard blocks. */
1587 memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1588 memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1589 memset(ptr, MALLOC_ALLOC_PATTERN, size);
1591 block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
1592 sizeof(*block_info)));
1593 set_source_location(&block_info->location, file, line);
1594 block_info->allocated_size = allocate_size;
1595 block_info->size = size;
1596 block_info->block = block;
1597 block_info->node.value = block_info;
1598 list_add(block_list, &block_info->node);
1601 #define malloc test_malloc
1604 void* _test_calloc(const size_t number_of_elements, const size_t size,
1605 const char* file, const int line) {
1606 void* const ptr = _test_malloc(number_of_elements * size, file, line);
1608 memset(ptr, 0, number_of_elements * size);
1614 /* Use the real free in this function. */
1616 void _test_free(void* const ptr, const char* file, const int line) {
1618 char *block = discard_const_p(char, ptr);
1619 MallocBlockInfo *block_info;
1625 _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
1626 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1627 sizeof(*block_info)));
1628 /* Check the guard blocks. */
1630 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1631 block + block_info->size};
1632 for (i = 0; i < ARRAY_SIZE(guards); i++) {
1634 char * const guard = guards[i];
1635 for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1636 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1638 cm_print_error(SOURCE_LOCATION_FORMAT
1639 ": error: Guard block of %p size=%lu is corrupt\n"
1640 SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
1642 ptr, (unsigned long)block_info->size,
1643 block_info->location.file, block_info->location.line,
1650 list_remove(&block_info->node, NULL, NULL);
1652 block = discard_const_p(char, block_info->block);
1653 memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
1656 #define free test_free
1659 void *_test_realloc(void *ptr,
1664 MallocBlockInfo *block_info;
1666 size_t block_size = size;
1670 return _test_malloc(size, file, line);
1677 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1678 sizeof(*block_info)));
1680 new = _test_malloc(size, file, line);
1685 if (block_info->size < size) {
1686 block_size = block_info->size;
1689 memcpy(new, ptr, block_size);
1691 /* Free previous memory */
1692 _test_free(ptr, file, line);
1696 #define realloc test_realloc
1698 /* Crudely checkpoint the current heap state. */
1699 static const ListNode* check_point_allocated_blocks() {
1700 return get_allocated_blocks_list()->prev;
1704 /* Display the blocks allocated after the specified check point. This
1705 * function returns the number of blocks displayed. */
1706 static int display_allocated_blocks(const ListNode * const check_point) {
1707 const ListNode * const head = get_allocated_blocks_list();
1708 const ListNode *node;
1709 int allocated_blocks = 0;
1710 assert_non_null(check_point);
1711 assert_non_null(check_point->next);
1713 for (node = check_point->next; node != head; node = node->next) {
1714 const MallocBlockInfo * const block_info =
1715 (const MallocBlockInfo*)node->value;
1716 assert_non_null(block_info);
1718 if (!allocated_blocks) {
1719 cm_print_error("Blocks allocated...\n");
1721 cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
1722 block_info->location.file,
1723 block_info->location.line,
1725 allocated_blocks ++;
1727 return allocated_blocks;
1731 /* Free all blocks allocated after the specified check point. */
1732 static void free_allocated_blocks(const ListNode * const check_point) {
1733 const ListNode * const head = get_allocated_blocks_list();
1734 const ListNode *node;
1735 assert_non_null(check_point);
1737 node = check_point->next;
1738 assert_non_null(node);
1740 while (node != head) {
1741 MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
1743 free(discard_const_p(char, block_info) + sizeof(*block_info) + MALLOC_GUARD_SIZE);
1748 /* Fail if any any blocks are allocated after the specified check point. */
1749 static void fail_if_blocks_allocated(const ListNode * const check_point,
1750 const char * const test_name) {
1751 const int allocated_blocks = display_allocated_blocks(check_point);
1752 if (allocated_blocks) {
1753 free_allocated_blocks(check_point);
1754 cm_print_error("ERROR: %s leaked %d block(s)\n", test_name,
1761 void _fail(const char * const file, const int line) {
1762 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!\n", file, line);
1768 static void exception_handler(int sig) {
1769 #ifdef HAVE_STRSIGNAL
1770 cm_print_error("Test failed with exception: %s\n", strsignal(sig));
1772 cm_print_error("Test failed with exception: %d\n", sig);
1779 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
1780 EXCEPTION_RECORD * const exception_record =
1781 exception_pointers->ExceptionRecord;
1782 const DWORD code = exception_record->ExceptionCode;
1784 for (i = 0; i < ARRAY_SIZE(exception_codes); i++) {
1785 const ExceptionCodeInfo * const code_info = &exception_codes[i];
1786 if (code == code_info->code) {
1787 static int shown_debug_message = 0;
1789 cm_print_error("%s occurred at %p.\n", code_info->description,
1790 exception_record->ExceptionAddress);
1791 if (!shown_debug_message) {
1794 "To debug in Visual Studio...\n"
1795 "1. Select menu item File->Open Project\n"
1796 "2. Change 'Files of type' to 'Executable Files'\n"
1797 "3. Open this executable.\n"
1798 "4. Select menu item Debug->Start\n"
1800 "Alternatively, set the environment variable \n"
1801 "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
1802 "then click 'Debug' in the popup dialog box.\n"
1804 shown_debug_message = 1;
1807 return EXCEPTION_EXECUTE_HANDLER;
1810 return EXCEPTION_CONTINUE_SEARCH;
1812 #endif /* !_WIN32 */
1814 void cm_print_error(const char * const format, ...)
1817 va_start(args, format);
1818 if (cm_error_message_enabled) {
1819 vcm_print_error(format, args);
1821 vprint_error(format, args);
1826 /* Standard output and error print methods. */
1827 void vprint_message(const char* const format, va_list args) {
1829 vsnprintf(buffer, sizeof(buffer), format, args);
1830 printf("%s", buffer);
1833 OutputDebugString(buffer);
1838 void vprint_error(const char* const format, va_list args) {
1840 vsnprintf(buffer, sizeof(buffer), format, args);
1841 fprintf(stderr, "%s", buffer);
1844 OutputDebugString(buffer);
1849 void print_message(const char* const format, ...) {
1851 va_start(args, format);
1852 vprint_message(format, args);
1857 void print_error(const char* const format, ...) {
1859 va_start(args, format);
1860 vprint_error(format, args);
1865 static enum cm_message_output cm_get_output(void)
1867 enum cm_message_output output = global_msg_output;
1870 env = getenv("CMOCKA_MESSAGE_OUTPUT");
1872 if (strcasecmp(env, "STDOUT") == 0) {
1873 output = CM_OUTPUT_STDOUT;
1874 } else if (strcasecmp(env, "SUBUNIT") == 0) {
1875 output = CM_OUTPUT_SUBUNIT;
1876 } else if (strcasecmp(env, "TAP") == 0) {
1877 output = CM_OUTPUT_TAP;
1878 } else if (strcasecmp(env, "XML") == 0) {
1879 output = CM_OUTPUT_XML;
1886 enum cm_printf_type {
1888 PRINTF_TEST_SUCCESS,
1889 PRINTF_TEST_FAILURE,
1891 PRINTF_TEST_SKIPPED,
1894 static void cmprintf_group_finish_xml(const char *group_name,
1895 size_t total_executed,
1896 size_t total_failed,
1897 size_t total_errors,
1898 size_t total_skipped,
1899 double total_runtime,
1900 struct CMUnitTestState *cm_tests)
1903 int file_opened = 0;
1907 env = getenv("CMOCKA_XML_FILE");
1910 snprintf(buf, sizeof(buf), "%s", env);
1912 fp = fopen(buf, "r");
1914 fp = fopen(buf, "w");
1926 fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
1927 fprintf(fp, "<testsuites>\n");
1928 fprintf(fp, " <testsuite name=\"%s\" time=\"%.3f\" "
1929 "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
1931 total_runtime * 1000, /* miliseconds */
1932 (unsigned)total_executed,
1933 (unsigned)total_failed,
1934 (unsigned)total_errors,
1935 (unsigned)total_skipped);
1937 for (i = 0; i < total_executed; i++) {
1938 struct CMUnitTestState *cmtest = &cm_tests[i];
1940 fprintf(fp, " <testcase name=\"%s\" time=\"%.3f\" >\n",
1941 cmtest->test->name, cmtest->runtime * 1000);
1943 switch (cmtest->status) {
1945 case CM_TEST_FAILED:
1946 if (cmtest->error_message != NULL) {
1947 fprintf(fp, " <failure><![CDATA[%s]]></failure>\n",
1948 cmtest->error_message);
1950 fprintf(fp, " <failure message=\"Unknown error\" />\n");
1953 case CM_TEST_SKIPPED:
1954 fprintf(fp, " <skipped/>\n");
1957 case CM_TEST_PASSED:
1958 case CM_TEST_NOT_STARTED:
1962 fprintf(fp, " </testcase>\n");
1965 fprintf(fp, " </testsuite>\n");
1966 fprintf(fp, "</testsuites>\n");
1973 static void cmprintf_group_start_standard(const size_t num_tests)
1975 print_message("[==========] Running %u test(s).\n",
1976 (unsigned)num_tests);
1979 static void cmprintf_group_finish_standard(size_t total_executed,
1980 size_t total_passed,
1981 size_t total_failed,
1982 size_t total_errors,
1983 struct CMUnitTestState *cm_tests)
1987 print_message("[==========] %u test(s) run.\n", (unsigned)total_executed);
1988 print_error("[ PASSED ] %u test(s).\n",
1989 (unsigned)(total_passed));
1992 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
1993 for (i = 0; i < total_executed; i++) {
1994 struct CMUnitTestState *cmtest = &cm_tests[i];
1996 if (cmtest->status == CM_TEST_FAILED) {
1997 print_error("[ FAILED ] %s\n", cmtest->test->name);
2000 print_error("\n %u FAILED TEST(S)\n",
2001 (unsigned)(total_failed + total_errors));
2005 static void cmprintf_standard(enum cm_printf_type type,
2006 const char *test_name,
2007 const char *error_message)
2010 case PRINTF_TEST_START:
2011 print_message("[ RUN ] %s\n", test_name);
2013 case PRINTF_TEST_SUCCESS:
2014 print_message("[ OK ] %s\n", test_name);
2016 case PRINTF_TEST_FAILURE:
2017 if (error_message != NULL) {
2018 print_error("%s\n", error_message);
2020 print_message("[ FAILED ] %s\n", test_name);
2022 case PRINTF_TEST_SKIPPED:
2023 print_message("[ SKIPPED ] %s\n", test_name);
2025 case PRINTF_TEST_ERROR:
2026 if (error_message != NULL) {
2027 print_error("%s\n", error_message);
2029 print_error("[ ERROR ] %s\n", test_name);
2034 static void cmprintf_group_start_tap(const size_t num_tests)
2036 print_message("1..%u\n", (unsigned)num_tests);
2039 static void cmprintf_tap(enum cm_printf_type type,
2040 uint32_t test_number,
2041 const char *test_name,
2042 const char *error_message)
2045 case PRINTF_TEST_START:
2047 case PRINTF_TEST_SUCCESS:
2048 print_message("ok %u - %s\n", (unsigned)test_number, test_name);
2050 case PRINTF_TEST_FAILURE:
2051 print_message("not ok %u - %s\n", (unsigned)test_number, test_name);
2052 if (error_message != NULL) {
2056 msg = strdup(error_message);
2062 while (p[0] != '\0') {
2065 p = strchr(q, '\n');
2070 print_message("# %s\n", q);
2080 case PRINTF_TEST_SKIPPED:
2081 print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name);
2083 case PRINTF_TEST_ERROR:
2084 print_message("not ok %u - %s %s\n",
2085 (unsigned)test_number, test_name, error_message);
2090 static void cmprintf_subunit(enum cm_printf_type type,
2091 const char *test_name,
2092 const char *error_message)
2095 case PRINTF_TEST_START:
2096 print_message("test: %s\n", test_name);
2098 case PRINTF_TEST_SUCCESS:
2099 print_message("success: %s\n", test_name);
2101 case PRINTF_TEST_FAILURE:
2102 print_message("failure: %s", test_name);
2103 if (error_message != NULL) {
2104 print_message(" [\n%s]\n", error_message);
2107 case PRINTF_TEST_SKIPPED:
2108 print_message("skip: %s\n", test_name);
2110 case PRINTF_TEST_ERROR:
2111 print_message("error: %s [ %s ]\n", test_name, error_message);
2116 static void cmprintf_group_start(const size_t num_tests)
2118 enum cm_message_output output;
2120 output = cm_get_output();
2123 case CM_OUTPUT_STDOUT:
2124 cmprintf_group_start_standard(num_tests);
2126 case CM_OUTPUT_SUBUNIT:
2129 cmprintf_group_start_tap(num_tests);
2136 static void cmprintf_group_finish(const char *group_name,
2137 size_t total_executed,
2138 size_t total_passed,
2139 size_t total_failed,
2140 size_t total_errors,
2141 size_t total_skipped,
2142 double total_runtime,
2143 struct CMUnitTestState *cm_tests)
2145 enum cm_message_output output;
2147 output = cm_get_output();
2150 case CM_OUTPUT_STDOUT:
2151 cmprintf_group_finish_standard(total_executed,
2157 case CM_OUTPUT_SUBUNIT:
2161 cmprintf_group_finish_xml(group_name,
2172 static void cmprintf(enum cm_printf_type type,
2174 const char *test_name,
2175 const char *error_message)
2177 enum cm_message_output output;
2179 output = cm_get_output();
2182 case CM_OUTPUT_STDOUT:
2183 cmprintf_standard(type, test_name, error_message);
2185 case CM_OUTPUT_SUBUNIT:
2186 cmprintf_subunit(type, test_name, error_message);
2189 cmprintf_tap(type, test_number, test_name, error_message);
2196 void cmocka_set_message_output(enum cm_message_output output)
2198 global_msg_output = output;
2201 /****************************************************************************
2203 ****************************************************************************/
2205 #ifdef HAVE_STRUCT_TIMESPEC
2206 static struct timespec cm_tspecdiff(struct timespec time1,
2207 struct timespec time0)
2209 struct timespec ret;
2213 if (time0.tv_nsec > time1.tv_nsec) {
2214 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
2215 time0.tv_nsec -= (long int) (1E9 * xsec);
2216 time0.tv_sec += xsec;
2219 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
2220 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
2221 time0.tv_nsec += (long int) (1E9 * xsec);
2222 time0.tv_sec -= xsec;
2225 ret.tv_sec = time1.tv_sec - time0.tv_sec;
2226 ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
2228 if (time1.tv_sec < time0.tv_sec) {
2232 ret.tv_sec = ret.tv_sec * sign;
2237 static double cm_secdiff(struct timespec clock1, struct timespec clock0)
2240 struct timespec diff;
2242 diff = cm_tspecdiff(clock1, clock0);
2245 ret += (double) diff.tv_nsec / (double) 1E9;
2249 #endif /* HAVE_STRUCT_TIMESPEC */
2251 /****************************************************************************
2252 * CMOCKA TEST RUNNER
2253 ****************************************************************************/
2254 static int cmocka_run_one_test_or_fixture(const char *function_name,
2255 CMUnitTestFunction test_func,
2256 CMFixtureFunction setup_func,
2257 CMFixtureFunction teardown_func,
2258 void ** const volatile state,
2259 const void *const heap_check_point)
2261 const ListNode * const volatile check_point = (const ListNode*)
2262 (heap_check_point != NULL ?
2263 heap_check_point : check_point_allocated_blocks());
2264 int handle_exceptions = 1;
2265 void *current_state = NULL;
2268 /* FIXME check only one test or fixture is set */
2270 /* Detect if we should handle exceptions */
2272 handle_exceptions = !IsDebuggerPresent();
2274 #ifdef UNIT_TESTING_DEBUG
2275 handle_exceptions = 0;
2276 #endif /* UNIT_TESTING_DEBUG */
2279 if (handle_exceptions) {
2282 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2283 default_signal_functions[i] = signal(
2284 exception_signals[i], exception_handler);
2287 previous_exception_filter = SetUnhandledExceptionFilter(
2289 #endif /* !_WIN32 */
2292 /* Init the test structure */
2293 initialize_testing(function_name);
2295 global_running_test = 1;
2297 if (setjmp(global_run_test_env) == 0) {
2298 if (test_func != NULL) {
2299 test_func(state != NULL ? state : ¤t_state);
2301 fail_if_blocks_allocated(check_point, function_name);
2303 } else if (setup_func != NULL) {
2304 rc = setup_func(state != NULL ? state : ¤t_state);
2307 * For setup we can ignore any allocated blocks. We just need to
2308 * ensure they're deallocated on tear down.
2310 } else if (teardown_func != NULL) {
2311 rc = teardown_func(state != NULL ? state : ¤t_state);
2313 fail_if_blocks_allocated(check_point, function_name);
2317 fail_if_leftover_values(function_name);
2318 global_running_test = 0;
2321 global_running_test = 0;
2324 teardown_testing(function_name);
2326 if (handle_exceptions) {
2329 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2330 signal(exception_signals[i], default_signal_functions[i]);
2333 if (previous_exception_filter) {
2334 SetUnhandledExceptionFilter(previous_exception_filter);
2335 previous_exception_filter = NULL;
2337 #endif /* !_WIN32 */
2343 static int cmocka_run_group_fixture(const char *function_name,
2344 CMFixtureFunction setup_func,
2345 CMFixtureFunction teardown_func,
2347 const void *const heap_check_point)
2351 if (setup_func != NULL) {
2352 rc = cmocka_run_one_test_or_fixture(function_name,
2359 rc = cmocka_run_one_test_or_fixture(function_name,
2370 static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
2372 #ifdef HAVE_STRUCT_TIMESPEC
2373 struct timespec start = {
2377 struct timespec finish = {
2385 if (test_state->test->setup_func != NULL) {
2386 /* Setup the memory check point, it will be evaluated on teardown */
2387 test_state->check_point = check_point_allocated_blocks();
2389 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2391 test_state->test->setup_func,
2394 test_state->check_point);
2396 test_state->status = CM_TEST_ERROR;
2397 cm_print_error("Test setup failed");
2402 #ifdef HAVE_STRUCT_TIMESPEC
2403 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
2407 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2408 test_state->test->test_func,
2414 test_state->status = CM_TEST_PASSED;
2416 if (global_skip_test) {
2417 test_state->status = CM_TEST_SKIPPED;
2418 global_skip_test = 0; /* Do not skip the next test */
2420 test_state->status = CM_TEST_FAILED;
2426 test_state->runtime = 0.0;
2428 #ifdef HAVE_STRUCT_TIMESPEC
2429 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
2430 test_state->runtime = cm_secdiff(finish, start);
2434 if (rc == 0 && test_state->test->teardown_func != NULL) {
2435 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2438 test_state->test->teardown_func,
2440 test_state->check_point);
2442 test_state->status = CM_TEST_ERROR;
2443 cm_print_error("Test teardown failed");
2447 test_state->error_message = cm_error_message;
2448 cm_error_message = NULL;
2453 int _cmocka_run_group_tests(const char *group_name,
2454 const struct CMUnitTest * const tests,
2455 const size_t num_tests,
2456 CMFixtureFunction group_setup,
2457 CMFixtureFunction group_teardown)
2459 struct CMUnitTestState *cm_tests;
2460 const ListNode *group_check_point = check_point_allocated_blocks();
2461 void *group_state = NULL;
2462 size_t total_failed = 0;
2463 size_t total_passed = 0;
2464 size_t total_executed = 0;
2465 size_t total_errors = 0;
2466 size_t total_skipped = 0;
2467 double total_runtime = 0;
2471 /* Make sure LargestIntegralType is at least the size of a pointer. */
2472 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
2474 cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests);
2475 if (cm_tests == NULL) {
2479 cmprintf_group_start(num_tests);
2481 /* Setup cmocka test array */
2482 for (i = 0; i < num_tests; i++) {
2483 cm_tests[i] = (struct CMUnitTestState) {
2485 .status = CM_TEST_NOT_STARTED,
2492 /* Run group setup */
2493 if (group_setup != NULL) {
2494 rc = cmocka_run_group_fixture("cmocka_group_setup",
2503 for (i = 0; i < num_tests; i++) {
2504 struct CMUnitTestState *cmtest = &cm_tests[i];
2505 size_t test_number = i + 1;
2507 cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
2509 if (group_state != NULL) {
2510 cm_tests[i].state = group_state;
2512 rc = cmocka_run_one_tests(cmtest);
2514 total_runtime += cmtest->runtime;
2516 switch (cmtest->status) {
2517 case CM_TEST_PASSED:
2518 cmprintf(PRINTF_TEST_SUCCESS,
2521 cmtest->error_message);
2524 case CM_TEST_SKIPPED:
2525 cmprintf(PRINTF_TEST_SKIPPED,
2528 cmtest->error_message);
2531 case CM_TEST_FAILED:
2532 cmprintf(PRINTF_TEST_FAILURE,
2535 cmtest->error_message);
2539 cmprintf(PRINTF_TEST_ERROR,
2542 "Internal cmocka error");
2547 cmprintf(PRINTF_TEST_ERROR,
2550 "Could not run the test - check test fixtures");
2555 cmprintf(PRINTF_TEST_ERROR, 0,
2556 group_name, "Group setup failed");
2560 /* Run group teardown */
2561 if (group_teardown != NULL) {
2562 rc = cmocka_run_group_fixture("cmocka_group_teardown",
2569 cmprintf_group_finish(group_name,
2578 for (i = 0; i < num_tests; i++) {
2579 vcm_free_error(discard_const_p(char, cm_tests[i].error_message));
2581 libc_free(cm_tests);
2582 fail_if_blocks_allocated(group_check_point, "cmocka_group_tests");
2584 return total_failed + total_errors;
2587 /****************************************************************************
2588 * DEPRECATED TEST RUNNER
2589 ****************************************************************************/
2592 const char * const function_name, const UnitTestFunction Function,
2593 void ** const volatile state, const UnitTestFunctionType function_type,
2594 const void* const heap_check_point) {
2595 const ListNode * const volatile check_point = (const ListNode*)
2597 heap_check_point : check_point_allocated_blocks());
2598 void *current_state = NULL;
2599 volatile int rc = 1;
2600 int handle_exceptions = 1;
2602 handle_exceptions = !IsDebuggerPresent();
2604 #ifdef UNIT_TESTING_DEBUG
2605 handle_exceptions = 0;
2606 #endif /* UNIT_TESTING_DEBUG */
2608 cm_error_message_enabled = 0;
2610 if (handle_exceptions) {
2613 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2614 default_signal_functions[i] = signal(
2615 exception_signals[i], exception_handler);
2618 previous_exception_filter = SetUnhandledExceptionFilter(
2620 #endif /* !_WIN32 */
2623 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
2624 print_message("[ RUN ] %s\n", function_name);
2626 initialize_testing(function_name);
2627 global_running_test = 1;
2628 if (setjmp(global_run_test_env) == 0) {
2629 Function(state ? state : ¤t_state);
2630 fail_if_leftover_values(function_name);
2632 /* If this is a setup function then ignore any allocated blocks
2633 * only ensure they're deallocated on tear down. */
2634 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
2635 fail_if_blocks_allocated(check_point, function_name);
2638 global_running_test = 0;
2640 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
2641 print_message("[ OK ] %s\n", function_name);
2645 global_running_test = 0;
2646 print_message("[ FAILED ] %s\n", function_name);
2648 teardown_testing(function_name);
2650 if (handle_exceptions) {
2653 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2654 signal(exception_signals[i], default_signal_functions[i]);
2657 if (previous_exception_filter) {
2658 SetUnhandledExceptionFilter(previous_exception_filter);
2659 previous_exception_filter = NULL;
2661 #endif /* !_WIN32 */
2668 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
2669 /* Whether to execute the next test. */
2670 int run_next_test = 1;
2671 /* Whether the previous test failed. */
2672 int previous_test_failed = 0;
2673 /* Whether the previous setup failed. */
2674 int previous_setup_failed = 0;
2675 /* Check point of the heap state. */
2676 const ListNode * const check_point = check_point_allocated_blocks();
2677 /* Current test being executed. */
2678 size_t current_test = 0;
2679 /* Number of tests executed. */
2680 size_t tests_executed = 0;
2681 /* Number of failed tests. */
2682 size_t total_failed = 0;
2683 /* Number of setup functions. */
2685 /* Number of teardown functions. */
2686 size_t teardowns = 0;
2689 * A stack of test states. A state is pushed on the stack
2690 * when a test setup occurs and popped on tear down.
2692 TestState* test_states =
2693 (TestState*)malloc(number_of_tests * sizeof(*test_states));
2694 /* The number of test states which should be 0 at the end */
2695 long number_of_test_states = 0;
2696 /* Names of the tests that failed. */
2697 const char** failed_names = (const char**)malloc(number_of_tests *
2698 sizeof(*failed_names));
2699 void **current_state = NULL;
2701 /* Count setup and teardown functions */
2702 for (i = 0; i < number_of_tests; i++) {
2703 const UnitTest * const test = &tests[i];
2705 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) {
2709 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) {
2714 print_message("[==========] Running %"PRIdS " test(s).\n",
2715 number_of_tests - setups - teardowns);
2717 /* Make sure LargestIntegralType is at least the size of a pointer. */
2718 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
2720 while (current_test < number_of_tests) {
2721 const ListNode *test_check_point = NULL;
2722 TestState *current_TestState;
2723 const UnitTest * const test = &tests[current_test++];
2724 if (!test->function) {
2728 switch (test->function_type) {
2729 case UNIT_TEST_FUNCTION_TYPE_TEST:
2730 if (! previous_setup_failed) {
2734 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
2735 /* Checkpoint the heap before the setup. */
2736 current_TestState = &test_states[number_of_test_states++];
2737 current_TestState->check_point = check_point_allocated_blocks();
2738 test_check_point = current_TestState->check_point;
2739 current_state = ¤t_TestState->state;
2740 *current_state = NULL;
2744 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
2745 /* Check the heap based on the last setup checkpoint. */
2746 assert_true(number_of_test_states);
2747 current_TestState = &test_states[--number_of_test_states];
2748 test_check_point = current_TestState->check_point;
2749 current_state = ¤t_TestState->state;
2752 print_error("Invalid unit test function type %d\n",
2753 test->function_type);
2758 if (run_next_test) {
2759 int failed = _run_test(test->name, test->function, current_state,
2760 test->function_type, test_check_point);
2762 failed_names[total_failed] = test->name;
2765 switch (test->function_type) {
2766 case UNIT_TEST_FUNCTION_TYPE_TEST:
2767 previous_test_failed = failed;
2768 total_failed += failed;
2772 case UNIT_TEST_FUNCTION_TYPE_SETUP:
2776 /* Skip forward until the next test or setup function. */
2778 previous_setup_failed = 1;
2780 previous_test_failed = 0;
2783 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
2784 /* If this test failed. */
2785 if (failed && !previous_test_failed) {
2791 assert_null("BUG: shouldn't be here!");
2798 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
2799 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
2801 if (total_failed > 0) {
2802 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
2803 for (i = 0; i < total_failed; i++) {
2804 print_error("[ FAILED ] %s\n", failed_names[i]);
2807 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
2810 if (number_of_test_states != 0) {
2811 print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and "
2812 "teardown %"PRIdS " functions\n", setups, teardowns);
2813 total_failed = (size_t)-1;
2817 free((void*)failed_names);
2819 fail_if_blocks_allocated(check_point, "run_tests");
2820 return (int)total_failed;
2823 int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
2825 UnitTestFunction setup = NULL;
2826 const char *setup_name;
2827 size_t num_setups = 0;
2828 UnitTestFunction teardown = NULL;
2829 const char *teardown_name;
2830 size_t num_teardowns = 0;
2831 size_t current_test = 0;
2834 /* Number of tests executed. */
2835 size_t tests_executed = 0;
2836 /* Number of failed tests. */
2837 size_t total_failed = 0;
2838 /* Check point of the heap state. */
2839 const ListNode * const check_point = check_point_allocated_blocks();
2840 const char** failed_names = (const char**)malloc(number_of_tests *
2841 sizeof(*failed_names));
2842 void **current_state = NULL;
2843 TestState group_state;
2845 /* Find setup and teardown function */
2846 for (i = 0; i < number_of_tests; i++) {
2847 const UnitTest * const test = &tests[i];
2849 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
2850 if (setup == NULL) {
2851 setup = test->function;
2852 setup_name = test->name;
2855 print_error("[ ERROR ] More than one group setup function detected\n");
2860 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
2861 if (teardown == NULL) {
2862 teardown = test->function;
2863 teardown_name = test->name;
2866 print_error("[ ERROR ] More than one group teardown function detected\n");
2872 print_message("[==========] Running %"PRIdS " test(s).\n",
2873 number_of_tests - num_setups - num_teardowns);
2875 if (setup != NULL) {
2878 group_state.check_point = check_point_allocated_blocks();
2879 current_state = &group_state.state;
2880 *current_state = NULL;
2881 failed = _run_test(setup_name,
2884 UNIT_TEST_FUNCTION_TYPE_SETUP,
2885 group_state.check_point);
2887 failed_names[total_failed] = setup_name;
2890 total_failed += failed;
2894 while (current_test < number_of_tests) {
2896 const UnitTest * const test = &tests[current_test++];
2897 if (test->function == NULL) {
2901 switch (test->function_type) {
2902 case UNIT_TEST_FUNCTION_TYPE_TEST:
2905 case UNIT_TEST_FUNCTION_TYPE_SETUP:
2906 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
2907 case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
2908 case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
2911 print_error("Invalid unit test function type %d\n",
2912 test->function_type);
2919 failed = _run_test(test->name,
2922 test->function_type,
2925 failed_names[total_failed] = test->name;
2928 total_failed += failed;
2933 if (teardown != NULL) {
2936 failed = _run_test(teardown_name,
2939 UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
2940 group_state.check_point);
2942 failed_names[total_failed] = teardown_name;
2945 total_failed += failed;
2949 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
2950 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
2953 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
2954 for (i = 0; i < total_failed; i++) {
2955 print_error("[ FAILED ] %s\n", failed_names[i]);
2958 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
2961 free((void*)failed_names);
2962 fail_if_blocks_allocated(check_point, "run_group_tests");
2964 return (int)total_failed;