2 * Copyright 2008 Google Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
34 #define vsnprintf _vsnprintf
37 * Backwards compatibility with headers shipped with Visual Studio 2005 and
40 WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID);
55 #include <cmocka_private.h>
58 /* Size of guard bytes around dynamically allocated blocks. */
59 #define MALLOC_GUARD_SIZE 16
60 /* Pattern used to initialize guard blocks. */
61 #define MALLOC_GUARD_PATTERN 0xEF
62 /* Pattern used to initialize memory allocated with test_malloc(). */
63 #define MALLOC_ALLOC_PATTERN 0xBA
64 #define MALLOC_FREE_PATTERN 0xCD
65 /* Alignment of allocated blocks. NOTE: This must be base2. */
66 #define MALLOC_ALIGNMENT sizeof(size_t)
68 /* Printf formatting for source code locations. */
69 #define SOURCE_LOCATION_FORMAT "%s:%u"
71 /* Calculates the number of elements in an array. */
72 #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
75 * Declare and initialize the pointer member of ValuePointer variable name
78 #define declare_initialize_value_pointer_pointer(name, ptr) \
81 name.x.pointer = (void*)(ptr)
84 * Declare and initialize the value member of ValuePointer variable name
87 #define declare_initialize_value_pointer_value(name, val) \
91 /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */
92 #define cast_largest_integral_type_to_pointer( \
93 pointer_type, largest_integral_type) \
94 ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer)
96 /* Used to cast LargetIntegralType to void* and vice versa. */
97 typedef union ValuePointer {
98 LargestIntegralType value;
100 #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
101 unsigned int padding;
107 /* Doubly linked list node. */
108 typedef struct ListNode {
111 struct ListNode *next;
112 struct ListNode *prev;
115 /* Debug information for malloc(). */
116 typedef struct MallocBlockInfo {
117 void* block; /* Address of the block returned by malloc(). */
118 size_t allocated_size; /* Total size of the allocated block. */
119 size_t size; /* Request block size. */
120 SourceLocation location; /* Where the block was allocated. */
121 ListNode node; /* Node within list of all allocated blocks. */
124 /* State of each test. */
125 typedef struct TestState {
126 const ListNode *check_point; /* Check point of the test if there's a */
127 /* setup function. */
128 void *state; /* State associated with the test. */
131 /* Determines whether two values are the same. */
132 typedef int (*EqualityFunction)(const void *left, const void *right);
134 /* Value of a symbol and the place it was declared. */
135 typedef struct SymbolValue {
136 SourceLocation location;
137 LargestIntegralType value;
141 * Contains a list of values for a symbol.
142 * NOTE: Each structure referenced by symbol_values_list_head must have a
143 * SourceLocation as its' first member.
145 typedef struct SymbolMapValue {
146 const char *symbol_name;
147 ListNode symbol_values_list_head;
150 /* Used by list_free() to deallocate values referenced by list nodes. */
151 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
153 /* Structure used to check the range of integer types.a */
154 typedef struct CheckIntegerRange {
155 CheckParameterEvent event;
156 LargestIntegralType minimum;
157 LargestIntegralType maximum;
160 /* Structure used to check whether an integer value is in a set. */
161 typedef struct CheckIntegerSet {
162 CheckParameterEvent event;
163 const LargestIntegralType *set;
167 /* Used to check whether a parameter matches the area of memory referenced by
169 typedef struct CheckMemoryData {
170 CheckParameterEvent event;
175 static ListNode* list_initialize(ListNode * const node);
176 static ListNode* list_add(ListNode * const head, ListNode *new_node);
177 static ListNode* list_add_value(ListNode * const head, const void *value,
179 static ListNode* list_remove(
180 ListNode * const node, const CleanupListValue cleanup_value,
181 void * const cleanup_value_data);
182 static void list_remove_free(
183 ListNode * const node, const CleanupListValue cleanup_value,
184 void * const cleanup_value_data);
185 static int list_empty(const ListNode * const head);
186 static int list_find(
187 ListNode * const head, const void *value,
188 const EqualityFunction equal_func, ListNode **output);
189 static int list_first(ListNode * const head, ListNode **output);
190 static ListNode* list_free(
191 ListNode * const head, const CleanupListValue cleanup_value,
192 void * const cleanup_value_data);
194 static void add_symbol_value(
195 ListNode * const symbol_map_head, const char * const symbol_names[],
196 const size_t number_of_symbol_names, const void* value, const int count);
197 static int get_symbol_value(
198 ListNode * const symbol_map_head, const char * const symbol_names[],
199 const size_t number_of_symbol_names, void **output);
200 static void free_value(const void *value, void *cleanup_value_data);
201 static void free_symbol_map_value(
202 const void *value, void *cleanup_value_data);
203 static void remove_always_return_values(ListNode * const map_head,
204 const size_t number_of_symbol_names);
205 static int check_for_leftover_values(
206 const ListNode * const map_head, const char * const error_message,
207 const size_t number_of_symbol_names);
209 * This must be called at the beginning of a test to initialize some data
212 static void initialize_testing(const char *test_name);
214 /* This must be called at the end of a test to free() allocated structures. */
215 static void teardown_testing(const char *test_name);
219 * Keeps track of the calling context returned by setenv() so that the fail()
220 * method can jump out of a test.
222 static jmp_buf global_run_test_env;
223 static int global_running_test = 0;
225 /* Keeps track of the calling context returned by setenv() so that */
226 /* mock_assert() can optionally jump back to expect_assert_failure(). */
227 jmp_buf global_expect_assert_env;
228 int global_expecting_assert = 0;
229 const char *global_last_failed_assert = NULL;
231 /* Keeps a map of the values that functions will have to return to provide */
232 /* mocked interfaces. */
233 static ListNode global_function_result_map_head;
234 /* Location of the last mock value returned was declared. */
235 static SourceLocation global_last_mock_value_location;
237 /* Keeps a map of the values that functions expect as parameters to their
238 * mocked interfaces. */
239 static ListNode global_function_parameter_map_head;
240 /* Location of last parameter value checked was declared. */
241 static SourceLocation global_last_parameter_location;
243 /* List of all currently allocated blocks. */
244 static ListNode global_allocated_blocks;
247 /* Signals caught by exception_handler(). */
248 static const int exception_signals[] = {
256 /* Default signal functions that should be restored after a test is complete. */
257 typedef void (*SignalFunction)(int signal);
258 static SignalFunction default_signal_functions[
259 ARRAY_LENGTH(exception_signals)];
263 /* The default exception filter. */
264 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
266 /* Fatal exceptions. */
267 typedef struct ExceptionCodeInfo {
269 const char* description;
272 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
274 static const ExceptionCodeInfo exception_codes[] = {
275 EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
276 EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
277 EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
278 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
279 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
280 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
281 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
282 EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
283 EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
284 EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
285 EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
286 EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
287 EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
288 EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
289 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
290 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
291 EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
292 EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
293 EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
294 EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
299 /* Exit the currently executing test. */
300 static void exit_test(const int quit_application)
302 const char *abort_test = getenv("CMOCKA_TEST_ABORT");
304 if (abort_test != NULL && abort_test[0] == '1') {
306 } else if (global_running_test) {
307 longjmp(global_run_test_env, 1);
308 } else if (quit_application) {
314 /* Initialize a SourceLocation structure. */
315 static void initialize_source_location(SourceLocation * const location) {
316 assert_non_null(location);
317 location->file = NULL;
322 /* Determine whether a source location is currently set. */
323 static int source_location_is_set(const SourceLocation * const location) {
324 assert_non_null(location);
325 return location->file && location->line;
329 /* Set a source location. */
330 static void set_source_location(
331 SourceLocation * const location, const char * const file,
333 assert_non_null(location);
334 location->file = file;
335 location->line = line;
339 /* Create function results and expected parameter lists. */
340 void initialize_testing(const char *test_name) {
342 list_initialize(&global_function_result_map_head);
343 initialize_source_location(&global_last_mock_value_location);
344 list_initialize(&global_function_parameter_map_head);
345 initialize_source_location(&global_last_parameter_location);
349 static void fail_if_leftover_values(const char *test_name) {
350 int error_occurred = 0;
352 remove_always_return_values(&global_function_result_map_head, 1);
353 if (check_for_leftover_values(
354 &global_function_result_map_head,
355 "%s() has remaining non-returned values.\n", 1)) {
359 remove_always_return_values(&global_function_parameter_map_head, 2);
360 if (check_for_leftover_values(
361 &global_function_parameter_map_head,
362 "%s parameter still has values that haven't been checked.\n", 2)) {
365 if (error_occurred) {
371 static void teardown_testing(const char *test_name) {
373 list_free(&global_function_result_map_head, free_symbol_map_value,
375 initialize_source_location(&global_last_mock_value_location);
376 list_free(&global_function_parameter_map_head, free_symbol_map_value,
378 initialize_source_location(&global_last_parameter_location);
381 /* Initialize a list node. */
382 static ListNode* list_initialize(ListNode * const node) {
392 * Adds a value at the tail of a given list.
393 * The node referencing the value is allocated from the heap.
395 static ListNode* list_add_value(ListNode * const head, const void *value,
396 const int refcount) {
397 ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
398 assert_non_null(head);
399 assert_non_null(value);
400 new_node->value = value;
401 new_node->refcount = refcount;
402 return list_add(head, new_node);
406 /* Add new_node to the end of the list. */
407 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
408 assert_non_null(head);
409 assert_non_null(new_node);
410 new_node->next = head;
411 new_node->prev = head->prev;
412 head->prev->next = new_node;
413 head->prev = new_node;
418 /* Remove a node from a list. */
419 static ListNode* list_remove(
420 ListNode * const node, const CleanupListValue cleanup_value,
421 void * const cleanup_value_data) {
422 assert_non_null(node);
423 node->prev->next = node->next;
424 node->next->prev = node->prev;
426 cleanup_value(node->value, cleanup_value_data);
432 /* Remove a list node from a list and free the node. */
433 static void list_remove_free(
434 ListNode * const node, const CleanupListValue cleanup_value,
435 void * const cleanup_value_data) {
436 assert_non_null(node);
437 free(list_remove(node, cleanup_value, cleanup_value_data));
442 * Frees memory kept by a linked list The cleanup_value function is called for
443 * every "value" field of nodes in the list, except for the head. In addition
444 * to each list value, cleanup_value_data is passed to each call to
445 * cleanup_value. The head of the list is not deallocated.
447 static ListNode* list_free(
448 ListNode * const head, const CleanupListValue cleanup_value,
449 void * const cleanup_value_data) {
450 assert_non_null(head);
451 while (!list_empty(head)) {
452 list_remove_free(head->next, cleanup_value, cleanup_value_data);
458 /* Determine whether a list is empty. */
459 static int list_empty(const ListNode * const head) {
460 assert_non_null(head);
461 return head->next == head;
466 * Find a value in the list using the equal_func to compare each node with the
469 static int list_find(ListNode * const head, const void *value,
470 const EqualityFunction equal_func, ListNode **output) {
472 assert_non_null(head);
473 for (current = head->next; current != head; current = current->next) {
474 if (equal_func(current->value, value)) {
482 /* Returns the first node of a list */
483 static int list_first(ListNode * const head, ListNode **output) {
484 ListNode *target_node;
485 assert_non_null(head);
486 if (list_empty(head)) {
489 target_node = head->next;
490 *output = target_node;
495 /* Deallocate a value referenced by a list. */
496 static void free_value(const void *value, void *cleanup_value_data) {
497 (void)cleanup_value_data;
498 assert_non_null(value);
503 /* Releases memory associated to a symbol_map_value. */
504 static void free_symbol_map_value(const void *value,
505 void *cleanup_value_data) {
506 SymbolMapValue * const map_value = (SymbolMapValue*)value;
507 const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
508 assert_non_null(value);
509 list_free(&map_value->symbol_values_list_head,
510 children ? free_symbol_map_value : free_value,
511 (void *) ((uintptr_t)children - 1));
517 * Determine whether a symbol name referenced by a symbol_map_value matches the
518 * specified function name.
520 static int symbol_names_match(const void *map_value, const void *symbol) {
521 return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
522 (const char*)symbol);
527 * Adds a value to the queue of values associated with the given hierarchy of
528 * symbols. It's assumed value is allocated from the heap.
530 static void add_symbol_value(ListNode * const symbol_map_head,
531 const char * const symbol_names[],
532 const size_t number_of_symbol_names,
533 const void* value, const int refcount) {
534 const char* symbol_name;
535 ListNode *target_node;
536 SymbolMapValue *target_map_value;
537 assert_non_null(symbol_map_head);
538 assert_non_null(symbol_names);
539 assert_true(number_of_symbol_names);
540 symbol_name = symbol_names[0];
542 if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
544 SymbolMapValue * const new_symbol_map_value =
545 (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
546 new_symbol_map_value->symbol_name = symbol_name;
547 list_initialize(&new_symbol_map_value->symbol_values_list_head);
548 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
552 target_map_value = (SymbolMapValue*)target_node->value;
553 if (number_of_symbol_names == 1) {
554 list_add_value(&target_map_value->symbol_values_list_head,
557 add_symbol_value(&target_map_value->symbol_values_list_head,
558 &symbol_names[1], number_of_symbol_names - 1, value,
565 * Gets the next value associated with the given hierarchy of symbols.
566 * The value is returned as an output parameter with the function returning the
567 * node's old refcount value if a value is found, 0 otherwise. This means that
568 * a return value of 1 indicates the node was just removed from the list.
570 static int get_symbol_value(
571 ListNode * const head, const char * const symbol_names[],
572 const size_t number_of_symbol_names, void **output) {
573 const char* symbol_name;
574 ListNode *target_node;
575 assert_non_null(head);
576 assert_non_null(symbol_names);
577 assert_true(number_of_symbol_names);
578 assert_non_null(output);
579 symbol_name = symbol_names[0];
581 if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
582 SymbolMapValue *map_value;
583 ListNode *child_list;
584 int return_value = 0;
585 assert_non_null(target_node);
586 assert_non_null(target_node->value);
588 map_value = (SymbolMapValue*)target_node->value;
589 child_list = &map_value->symbol_values_list_head;
591 if (number_of_symbol_names == 1) {
592 ListNode *value_node = NULL;
593 return_value = list_first(child_list, &value_node);
594 assert_true(return_value);
595 *output = (void*) value_node->value;
596 return_value = value_node->refcount;
597 if (--value_node->refcount == 0) {
598 list_remove_free(value_node, NULL, NULL);
601 return_value = get_symbol_value(
602 child_list, &symbol_names[1], number_of_symbol_names - 1,
605 if (list_empty(child_list)) {
606 list_remove_free(target_node, free_symbol_map_value, (void*)0);
610 print_error("No entries for symbol %s.\n", symbol_name);
617 * Traverse down a tree of symbol values and remove the first symbol value
618 * in each branch that has a refcount < -1 (i.e should always be returned
619 * and has been returned at least once).
621 static void remove_always_return_values(ListNode * const map_head,
622 const size_t number_of_symbol_names) {
624 assert_non_null(map_head);
625 assert_true(number_of_symbol_names);
626 current = map_head->next;
627 while (current != map_head) {
628 SymbolMapValue * const value = (SymbolMapValue*)current->value;
629 ListNode * const next = current->next;
630 ListNode *child_list;
631 assert_non_null(value);
632 child_list = &value->symbol_values_list_head;
634 if (!list_empty(child_list)) {
635 if (number_of_symbol_names == 1) {
636 ListNode * const child_node = child_list->next;
637 /* If this item has been returned more than once, free it. */
638 if (child_node->refcount < -1) {
639 list_remove_free(child_node, free_value, NULL);
642 remove_always_return_values(child_list,
643 number_of_symbol_names - 1);
647 if (list_empty(child_list)) {
648 list_remove_free(current, free_value, NULL);
655 * Checks if there are any leftover values set up by the test that were never
656 * retrieved through execution, and fail the test if that is the case.
658 static int check_for_leftover_values(
659 const ListNode * const map_head, const char * const error_message,
660 const size_t number_of_symbol_names) {
661 const ListNode *current;
662 int symbols_with_leftover_values = 0;
663 assert_non_null(map_head);
664 assert_true(number_of_symbol_names);
666 for (current = map_head->next; current != map_head;
667 current = current->next) {
668 const SymbolMapValue * const value =
669 (SymbolMapValue*)current->value;
670 const ListNode *child_list;
671 assert_non_null(value);
672 child_list = &value->symbol_values_list_head;
674 if (!list_empty(child_list)) {
675 if (number_of_symbol_names == 1) {
676 const ListNode *child_node;
677 print_error(error_message, value->symbol_name);
679 for (child_node = child_list->next; child_node != child_list;
680 child_node = child_node->next) {
681 const SourceLocation * const location =
682 (const SourceLocation*)child_node->value;
683 print_error(SOURCE_LOCATION_FORMAT
684 ": note: remaining item was declared here\n",
685 location->file, location->line);
688 print_error("%s.", value->symbol_name);
689 check_for_leftover_values(child_list, error_message,
690 number_of_symbol_names - 1);
692 symbols_with_leftover_values ++;
695 return symbols_with_leftover_values;
699 /* Get the next return value for the specified mock function. */
700 LargestIntegralType _mock(const char * const function, const char* const file,
703 const int rc = get_symbol_value(&global_function_result_map_head,
704 &function, 1, &result);
706 SymbolValue * const symbol = (SymbolValue*)result;
707 const LargestIntegralType value = symbol->value;
708 global_last_mock_value_location = symbol->location;
714 print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
715 "to mock function %s\n", file, line, function);
716 if (source_location_is_set(&global_last_mock_value_location)) {
717 print_error(SOURCE_LOCATION_FORMAT
718 ": note: Previously returned mock value was declared here\n",
719 global_last_mock_value_location.file,
720 global_last_mock_value_location.line);
722 print_error("There were no previously returned mock values for "
731 /* Add a return value for the specified mock function name. */
732 void _will_return(const char * const function_name, const char * const file,
733 const int line, const LargestIntegralType value,
735 SymbolValue * const return_value =
736 (SymbolValue*)malloc(sizeof(*return_value));
737 assert_true(count > 0 || count == -1);
738 return_value->value = value;
739 set_source_location(&return_value->location, file, line);
740 add_symbol_value(&global_function_result_map_head, &function_name, 1,
741 return_value, count);
746 * Add a custom parameter checking function. If the event parameter is NULL
747 * the event structure is allocated internally by this function. If event
748 * parameter is provided it must be allocated on the heap and doesn't need to
749 * be deallocated by the caller.
752 const char* const function, const char* const parameter,
753 const char* const file, const int line,
754 const CheckParameterValue check_function,
755 const LargestIntegralType check_data,
756 CheckParameterEvent * const event, const int count) {
757 CheckParameterEvent * const check =
758 event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
759 const char* symbols[] = {function, parameter};
760 check->parameter_name = parameter;
761 check->check_value = check_function;
762 check->check_value_data = check_data;
763 set_source_location(&check->location, file, line);
764 add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
769 /* Returns 1 if the specified values are equal. If the values are not equal
770 * an error is displayed and 0 is returned. */
771 static int values_equal_display_error(const LargestIntegralType left,
772 const LargestIntegralType right) {
773 const int equal = left == right;
775 print_error(LargestIntegralTypePrintfFormat " != "
776 LargestIntegralTypePrintfFormat "\n", left, right);
782 * Returns 1 if the specified values are not equal. If the values are equal
783 * an error is displayed and 0 is returned. */
784 static int values_not_equal_display_error(const LargestIntegralType left,
785 const LargestIntegralType right) {
786 const int not_equal = left != right;
788 print_error(LargestIntegralTypePrintfFormat " == "
789 LargestIntegralTypePrintfFormat "\n", left, right);
796 * Determine whether value is contained within check_integer_set.
797 * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
798 * returned and an error is displayed. If invert is 1 and the value is not
799 * in the set 1 is returned, otherwise 0 is returned and an error is
802 static int value_in_set_display_error(
803 const LargestIntegralType value,
804 const CheckIntegerSet * const check_integer_set, const int invert) {
805 int succeeded = invert;
806 assert_non_null(check_integer_set);
808 const LargestIntegralType * const set = check_integer_set->set;
809 const size_t size_of_set = check_integer_set->size_of_set;
811 for (i = 0; i < size_of_set; i++) {
812 if (set[i] == value) {
813 /* If invert = 0 and item is found, succeeded = 1. */
814 /* If invert = 1 and item is found, succeeded = 0. */
815 succeeded = !succeeded;
822 print_error("%llu is %sin the set (", value, invert ? "" : "not ");
823 for (i = 0; i < size_of_set; i++) {
824 print_error("%llu, ", set[i]);
833 * Determine whether a value is within the specified range. If the value is
834 * within the specified range 1 is returned. If the value isn't within the
835 * specified range an error is displayed and 0 is returned.
837 static int integer_in_range_display_error(
838 const LargestIntegralType value, const LargestIntegralType range_min,
839 const LargestIntegralType range_max) {
840 if (value >= range_min && value <= range_max) {
843 print_error("%llu is not within the range %llu-%llu\n", value, range_min,
850 * Determine whether a value is within the specified range. If the value
851 * is not within the range 1 is returned. If the value is within the
852 * specified range an error is displayed and zero is returned.
854 static int integer_not_in_range_display_error(
855 const LargestIntegralType value, const LargestIntegralType range_min,
856 const LargestIntegralType range_max) {
857 if (value < range_min || value > range_max) {
860 print_error("%llu is within the range %llu-%llu\n", value, range_min,
867 * Determine whether the specified strings are equal. If the strings are equal
868 * 1 is returned. If they're not equal an error is displayed and 0 is
871 static int string_equal_display_error(
872 const char * const left, const char * const right) {
873 if (strcmp(left, right) == 0) {
876 print_error("\"%s\" != \"%s\"\n", left, right);
882 * Determine whether the specified strings are equal. If the strings are not
883 * equal 1 is returned. If they're not equal an error is displayed and 0 is
886 static int string_not_equal_display_error(
887 const char * const left, const char * const right) {
888 if (strcmp(left, right) != 0) {
891 print_error("\"%s\" == \"%s\"\n", left, right);
897 * Determine whether the specified areas of memory are equal. If they're equal
898 * 1 is returned otherwise an error is displayed and 0 is returned.
900 static int memory_equal_display_error(const char* const a, const char* const b,
904 for (i = 0; i < size; i++) {
908 print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
914 print_error("%d bytes of %p and %p differ\n", differences,
923 * Determine whether the specified areas of memory are not equal. If they're
924 * not equal 1 is returned otherwise an error is displayed and 0 is
927 static int memory_not_equal_display_error(
928 const char* const a, const char* const b, const size_t size) {
931 for (i = 0; i < size; i++) {
939 print_error("%"PRIdS "bytes of %p and %p the same\n", same,
947 /* CheckParameterValue callback to check whether a value is within a set. */
948 static int check_in_set(const LargestIntegralType value,
949 const LargestIntegralType check_value_data) {
950 return value_in_set_display_error(value,
951 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
952 check_value_data), 0);
956 /* CheckParameterValue callback to check whether a value isn't within a set. */
957 static int check_not_in_set(const LargestIntegralType value,
958 const LargestIntegralType check_value_data) {
959 return value_in_set_display_error(value,
960 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
961 check_value_data), 1);
965 /* Create the callback data for check_in_set() or check_not_in_set() and
966 * register a check event. */
967 static void expect_set(
968 const char* const function, const char* const parameter,
969 const char* const file, const int line,
970 const LargestIntegralType values[], const size_t number_of_values,
971 const CheckParameterValue check_function, const int count) {
972 CheckIntegerSet * const check_integer_set =
973 (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
974 (sizeof(values[0]) * number_of_values));
975 LargestIntegralType * const set = (LargestIntegralType*)(
976 check_integer_set + 1);
977 declare_initialize_value_pointer_pointer(check_data, check_integer_set);
978 assert_non_null(values);
979 assert_true(number_of_values);
980 memcpy(set, values, number_of_values * sizeof(values[0]));
981 check_integer_set->set = set;
983 function, parameter, file, line, check_function,
984 check_data.value, &check_integer_set->event, count);
988 /* Add an event to check whether a value is in a set. */
990 const char* const function, const char* const parameter,
991 const char* const file, const int line,
992 const LargestIntegralType values[], const size_t number_of_values,
994 expect_set(function, parameter, file, line, values, number_of_values,
995 check_in_set, count);
999 /* Add an event to check whether a value isn't in a set. */
1000 void _expect_not_in_set(
1001 const char* const function, const char* const parameter,
1002 const char* const file, const int line,
1003 const LargestIntegralType values[], const size_t number_of_values,
1005 expect_set(function, parameter, file, line, values, number_of_values,
1006 check_not_in_set, count);
1010 /* CheckParameterValue callback to check whether a value is within a range. */
1011 static int check_in_range(const LargestIntegralType value,
1012 const LargestIntegralType check_value_data) {
1013 CheckIntegerRange * const check_integer_range =
1014 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1016 assert_non_null(check_integer_range);
1017 return integer_in_range_display_error(value, check_integer_range->minimum,
1018 check_integer_range->maximum);
1022 /* CheckParameterValue callback to check whether a value is not within a range. */
1023 static int check_not_in_range(const LargestIntegralType value,
1024 const LargestIntegralType check_value_data) {
1025 CheckIntegerRange * const check_integer_range =
1026 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1028 assert_non_null(check_integer_range);
1029 return integer_not_in_range_display_error(
1030 value, check_integer_range->minimum, check_integer_range->maximum);
1034 /* Create the callback data for check_in_range() or check_not_in_range() and
1035 * register a check event. */
1036 static void expect_range(
1037 const char* const function, const char* const parameter,
1038 const char* const file, const int line,
1039 const LargestIntegralType minimum, const LargestIntegralType maximum,
1040 const CheckParameterValue check_function, const int count) {
1041 CheckIntegerRange * const check_integer_range =
1042 (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
1043 declare_initialize_value_pointer_pointer(check_data, check_integer_range);
1044 check_integer_range->minimum = minimum;
1045 check_integer_range->maximum = maximum;
1046 _expect_check(function, parameter, file, line, check_function,
1047 check_data.value, &check_integer_range->event, count);
1051 /* Add an event to determine whether a parameter is within a range. */
1052 void _expect_in_range(
1053 const char* const function, const char* const parameter,
1054 const char* const file, const int line,
1055 const LargestIntegralType minimum, const LargestIntegralType maximum,
1057 expect_range(function, parameter, file, line, minimum, maximum,
1058 check_in_range, count);
1062 /* Add an event to determine whether a parameter is not within a range. */
1063 void _expect_not_in_range(
1064 const char* const function, const char* const parameter,
1065 const char* const file, const int line,
1066 const LargestIntegralType minimum, const LargestIntegralType maximum,
1068 expect_range(function, parameter, file, line, minimum, maximum,
1069 check_not_in_range, count);
1073 /* CheckParameterValue callback to check whether a value is equal to an
1074 * expected value. */
1075 static int check_value(const LargestIntegralType value,
1076 const LargestIntegralType check_value_data) {
1077 return values_equal_display_error(value, check_value_data);
1081 /* Add an event to check a parameter equals an expected value. */
1083 const char* const function, const char* const parameter,
1084 const char* const file, const int line,
1085 const LargestIntegralType value, const int count) {
1086 _expect_check(function, parameter, file, line, check_value, value, NULL,
1091 /* CheckParameterValue callback to check whether a value is not equal to an
1092 * expected value. */
1093 static int check_not_value(const LargestIntegralType value,
1094 const LargestIntegralType check_value_data) {
1095 return values_not_equal_display_error(value, check_value_data);
1099 /* Add an event to check a parameter is not equal to an expected value. */
1100 void _expect_not_value(
1101 const char* const function, const char* const parameter,
1102 const char* const file, const int line,
1103 const LargestIntegralType value, const int count) {
1104 _expect_check(function, parameter, file, line, check_not_value, value,
1109 /* CheckParameterValue callback to check whether a parameter equals a string. */
1110 static int check_string(const LargestIntegralType value,
1111 const LargestIntegralType check_value_data) {
1112 return string_equal_display_error(
1113 cast_largest_integral_type_to_pointer(char*, value),
1114 cast_largest_integral_type_to_pointer(char*, check_value_data));
1118 /* Add an event to check whether a parameter is equal to a string. */
1119 void _expect_string(
1120 const char* const function, const char* const parameter,
1121 const char* const file, const int line, const char* string,
1123 declare_initialize_value_pointer_pointer(string_pointer,
1124 discard_const(string));
1125 _expect_check(function, parameter, file, line, check_string,
1126 string_pointer.value, NULL, count);
1130 /* CheckParameterValue callback to check whether a parameter is not equals to
1132 static int check_not_string(const LargestIntegralType value,
1133 const LargestIntegralType check_value_data) {
1134 return string_not_equal_display_error(
1135 cast_largest_integral_type_to_pointer(char*, value),
1136 cast_largest_integral_type_to_pointer(char*, check_value_data));
1140 /* Add an event to check whether a parameter is not equal to a string. */
1141 void _expect_not_string(
1142 const char* const function, const char* const parameter,
1143 const char* const file, const int line, const char* string,
1145 declare_initialize_value_pointer_pointer(string_pointer,
1146 discard_const(string));
1147 _expect_check(function, parameter, file, line, check_not_string,
1148 string_pointer.value, NULL, count);
1151 /* CheckParameterValue callback to check whether a parameter equals an area of
1153 static int check_memory(const LargestIntegralType value,
1154 const LargestIntegralType check_value_data) {
1155 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1156 CheckMemoryData*, check_value_data);
1157 assert_non_null(check);
1158 return memory_equal_display_error(
1159 cast_largest_integral_type_to_pointer(const char*, value),
1160 (const char*)check->memory, check->size);
1164 /* Create the callback data for check_memory() or check_not_memory() and
1165 * register a check event. */
1166 static void expect_memory_setup(
1167 const char* const function, const char* const parameter,
1168 const char* const file, const int line,
1169 const void * const memory, const size_t size,
1170 const CheckParameterValue check_function, const int count) {
1171 CheckMemoryData * const check_data =
1172 (CheckMemoryData*)malloc(sizeof(*check_data) + size);
1173 void * const mem = (void*)(check_data + 1);
1174 declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1175 assert_non_null(memory);
1177 memcpy(mem, memory, size);
1178 check_data->memory = mem;
1179 check_data->size = size;
1180 _expect_check(function, parameter, file, line, check_function,
1181 check_data_pointer.value, &check_data->event, count);
1185 /* Add an event to check whether a parameter matches an area of memory. */
1186 void _expect_memory(
1187 const char* const function, const char* const parameter,
1188 const char* const file, const int line, const void* const memory,
1189 const size_t size, const int count) {
1190 expect_memory_setup(function, parameter, file, line, memory, size,
1191 check_memory, count);
1195 /* CheckParameterValue callback to check whether a parameter is not equal to
1196 * an area of memory. */
1197 static int check_not_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_not_equal_display_error(
1203 cast_largest_integral_type_to_pointer(const char*, value),
1204 (const char*)check->memory,
1209 /* Add an event to check whether a parameter doesn't match an area of memory. */
1210 void _expect_not_memory(
1211 const char* const function, const char* const parameter,
1212 const char* const file, const int line, const void* const memory,
1213 const size_t size, const int count) {
1214 expect_memory_setup(function, parameter, file, line, memory, size,
1215 check_not_memory, count);
1219 /* CheckParameterValue callback that always returns 1. */
1220 static int check_any(const LargestIntegralType value,
1221 const LargestIntegralType check_value_data) {
1223 (void)check_value_data;
1228 /* Add an event to allow any value for a parameter. */
1230 const char* const function, const char* const parameter,
1231 const char* const file, const int line, const int count) {
1232 _expect_check(function, parameter, file, line, check_any, 0, NULL,
1237 void _check_expected(
1238 const char * const function_name, const char * const parameter_name,
1239 const char* file, const int line, const LargestIntegralType value) {
1241 const char* symbols[] = {function_name, parameter_name};
1242 const int rc = get_symbol_value(&global_function_parameter_map_head,
1243 symbols, 2, &result);
1245 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1246 int check_succeeded;
1247 global_last_parameter_location = check->location;
1248 check_succeeded = check->check_value(value, check->check_value_data);
1252 if (!check_succeeded) {
1253 print_error(SOURCE_LOCATION_FORMAT
1254 ": error: Check of parameter %s, function %s failed\n"
1255 SOURCE_LOCATION_FORMAT
1256 ": note: Expected parameter declared here\n",
1258 parameter_name, function_name,
1259 global_last_parameter_location.file,
1260 global_last_parameter_location.line);
1264 print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
1265 "to check parameter %s of function %s\n", file, line,
1266 parameter_name, function_name);
1267 if (source_location_is_set(&global_last_parameter_location)) {
1268 print_error(SOURCE_LOCATION_FORMAT
1269 ": note: Previously declared parameter value was declared here\n",
1270 global_last_parameter_location.file,
1271 global_last_parameter_location.line);
1273 print_error("There were no previously declared parameter values "
1274 "for this test.\n");
1281 /* Replacement for assert. */
1282 void mock_assert(const int result, const char* const expression,
1283 const char* const file, const int line) {
1285 if (global_expecting_assert) {
1286 global_last_failed_assert = expression;
1287 longjmp(global_expect_assert_env, result);
1289 print_error("ASSERT: %s\n", expression);
1296 void _assert_true(const LargestIntegralType result,
1297 const char * const expression,
1298 const char * const file, const int line) {
1300 print_error("%s\n", expression);
1305 void _assert_return_code(const LargestIntegralType result,
1307 const LargestIntegralType error,
1308 const char * const expression,
1309 const char * const file,
1312 LargestIntegralType valmax;
1323 valmax = 2147483647;
1327 if (rlen > sizeof(valmax)) {
1328 valmax = 2147483647;
1330 valmax = 9223372036854775807L;
1335 if (result > valmax - 1) {
1337 print_error("%s < 0, errno(%llu): %s\n",
1338 expression, error, strerror(error));
1340 print_error("%s < 0\n", expression);
1346 void _assert_int_equal(
1347 const LargestIntegralType a, const LargestIntegralType b,
1348 const char * const file, const int line) {
1349 if (!values_equal_display_error(a, b)) {
1355 void _assert_int_not_equal(
1356 const LargestIntegralType a, const LargestIntegralType b,
1357 const char * const file, const int line) {
1358 if (!values_not_equal_display_error(a, b)) {
1364 void _assert_string_equal(const char * const a, const char * const b,
1365 const char * const file, const int line) {
1366 if (!string_equal_display_error(a, b)) {
1372 void _assert_string_not_equal(const char * const a, const char * const b,
1373 const char *file, const int line) {
1374 if (!string_not_equal_display_error(a, b)) {
1380 void _assert_memory_equal(const void * const a, const void * const b,
1381 const size_t size, const char* const file,
1383 if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1389 void _assert_memory_not_equal(const void * const a, const void * const b,
1390 const size_t size, const char* const file,
1392 if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1399 void _assert_in_range(
1400 const LargestIntegralType value, const LargestIntegralType minimum,
1401 const LargestIntegralType maximum, const char* const file,
1403 if (!integer_in_range_display_error(value, minimum, maximum)) {
1408 void _assert_not_in_range(
1409 const LargestIntegralType value, const LargestIntegralType minimum,
1410 const LargestIntegralType maximum, const char* const file,
1412 if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1417 void _assert_in_set(const LargestIntegralType value,
1418 const LargestIntegralType values[],
1419 const size_t number_of_values, const char* const file,
1421 CheckIntegerSet check_integer_set;
1422 check_integer_set.set = values;
1423 check_integer_set.size_of_set = number_of_values;
1424 if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1429 void _assert_not_in_set(const LargestIntegralType value,
1430 const LargestIntegralType values[],
1431 const size_t number_of_values, const char* const file,
1433 CheckIntegerSet check_integer_set;
1434 check_integer_set.set = values;
1435 check_integer_set.size_of_set = number_of_values;
1436 if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1442 /* Get the list of allocated blocks. */
1443 static ListNode* get_allocated_blocks_list() {
1444 /* If it initialized, initialize the list of allocated blocks. */
1445 if (!global_allocated_blocks.value) {
1446 list_initialize(&global_allocated_blocks);
1447 global_allocated_blocks.value = (void*)1;
1449 return &global_allocated_blocks;
1452 /* Use the real malloc in this function. */
1454 void* _test_malloc(const size_t size, const char* file, const int line) {
1456 MallocBlockInfo *block_info;
1457 ListNode * const block_list = get_allocated_blocks_list();
1458 const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
1459 sizeof(*block_info) + MALLOC_ALIGNMENT;
1460 char* const block = (char*)malloc(allocate_size);
1461 assert_non_null(block);
1463 /* Calculate the returned address. */
1464 ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
1465 MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1467 /* Initialize the guard blocks. */
1468 memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1469 memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1470 memset(ptr, MALLOC_ALLOC_PATTERN, size);
1472 block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
1473 sizeof(*block_info)));
1474 set_source_location(&block_info->location, file, line);
1475 block_info->allocated_size = allocate_size;
1476 block_info->size = size;
1477 block_info->block = block;
1478 block_info->node.value = block_info;
1479 list_add(block_list, &block_info->node);
1482 #define malloc test_malloc
1485 void* _test_calloc(const size_t number_of_elements, const size_t size,
1486 const char* file, const int line) {
1487 void* const ptr = _test_malloc(number_of_elements * size, file, line);
1489 memset(ptr, 0, number_of_elements * size);
1495 /* Use the real free in this function. */
1497 void _test_free(void* const ptr, const char* file, const int line) {
1499 char *block = discard_const_p(char, ptr);
1501 MallocBlockInfo *block_info;
1502 _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
1503 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1504 sizeof(*block_info)));
1505 /* Check the guard blocks. */
1507 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1508 block + block_info->size};
1509 for (i = 0; i < ARRAY_LENGTH(guards); i++) {
1511 char * const guard = guards[i];
1512 for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1513 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1515 print_error(SOURCE_LOCATION_FORMAT
1516 ": error: Guard block of %p size=%lu is corrupt\n"
1517 SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
1519 ptr, (unsigned long)block_info->size,
1520 block_info->location.file, block_info->location.line,
1527 list_remove(&block_info->node, NULL, NULL);
1529 block = discard_const_p(char, block_info->block);
1530 memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
1533 #define free test_free
1536 /* Crudely checkpoint the current heap state. */
1537 static const ListNode* check_point_allocated_blocks() {
1538 return get_allocated_blocks_list()->prev;
1542 /* Display the blocks allocated after the specified check point. This
1543 * function returns the number of blocks displayed. */
1544 static int display_allocated_blocks(const ListNode * const check_point) {
1545 const ListNode * const head = get_allocated_blocks_list();
1546 const ListNode *node;
1547 int allocated_blocks = 0;
1548 assert_non_null(check_point);
1549 assert_non_null(check_point->next);
1551 for (node = check_point->next; node != head; node = node->next) {
1552 const MallocBlockInfo * const block_info =
1553 (const MallocBlockInfo*)node->value;
1554 assert_non_null(block_info);
1556 if (!allocated_blocks) {
1557 print_error("Blocks allocated...\n");
1559 print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
1560 block_info->location.file,
1561 block_info->location.line,
1563 allocated_blocks ++;
1565 return allocated_blocks;
1569 /* Free all blocks allocated after the specified check point. */
1570 static void free_allocated_blocks(const ListNode * const check_point) {
1571 const ListNode * const head = get_allocated_blocks_list();
1572 const ListNode *node;
1573 assert_non_null(check_point);
1575 node = check_point->next;
1576 assert_non_null(node);
1578 while (node != head) {
1579 MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
1581 free(discard_const_p(char, block_info) + sizeof(*block_info) + MALLOC_GUARD_SIZE);
1586 /* Fail if any any blocks are allocated after the specified check point. */
1587 static void fail_if_blocks_allocated(const ListNode * const check_point,
1588 const char * const test_name) {
1589 const int allocated_blocks = display_allocated_blocks(check_point);
1590 if (allocated_blocks) {
1591 free_allocated_blocks(check_point);
1592 print_error("ERROR: %s leaked %d block(s)\n", test_name,
1599 void _fail(const char * const file, const int line) {
1600 print_error(SOURCE_LOCATION_FORMAT ": error: Failure!\n", file, line);
1606 static void exception_handler(int sig) {
1607 #ifdef HAVE_STRSIGNAL
1608 print_error("Test failed with exception: %s\n", strsignal(sig));
1610 print_error("Test failed with exception: %d\n", sig);
1617 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
1618 EXCEPTION_RECORD * const exception_record =
1619 exception_pointers->ExceptionRecord;
1620 const DWORD code = exception_record->ExceptionCode;
1622 for (i = 0; i < ARRAY_LENGTH(exception_codes); i++) {
1623 const ExceptionCodeInfo * const code_info = &exception_codes[i];
1624 if (code == code_info->code) {
1625 static int shown_debug_message = 0;
1627 print_error("%s occurred at 0x%08x.\n", code_info->description,
1628 exception_record->ExceptionAddress);
1629 if (!shown_debug_message) {
1632 "To debug in Visual Studio...\n"
1633 "1. Select menu item File->Open Project\n"
1634 "2. Change 'Files of type' to 'Executable Files'\n"
1635 "3. Open this executable.\n"
1636 "4. Select menu item Debug->Start\n"
1638 "Alternatively, set the environment variable \n"
1639 "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
1640 "then click 'Debug' in the popup dialog box.\n"
1642 shown_debug_message = 1;
1645 return EXCEPTION_EXECUTE_HANDLER;
1648 return EXCEPTION_CONTINUE_SEARCH;
1650 #endif /* !_WIN32 */
1653 /* Standard output and error print methods. */
1654 void vprint_message(const char* const format, va_list args) {
1656 vsnprintf(buffer, sizeof(buffer), format, args);
1657 printf("%s", buffer);
1660 OutputDebugString(buffer);
1665 void vprint_error(const char* const format, va_list args) {
1667 vsnprintf(buffer, sizeof(buffer), format, args);
1668 fprintf(stderr, "%s", buffer);
1671 OutputDebugString(buffer);
1676 void print_message(const char* const format, ...) {
1678 va_start(args, format);
1679 vprint_message(format, args);
1684 void print_error(const char* const format, ...) {
1686 va_start(args, format);
1687 vprint_error(format, args);
1693 const char * const function_name, const UnitTestFunction Function,
1694 void ** const volatile state, const UnitTestFunctionType function_type,
1695 const void* const heap_check_point) {
1696 const ListNode * const volatile check_point = (const ListNode*)
1698 heap_check_point : check_point_allocated_blocks());
1699 void *current_state = NULL;
1700 volatile int rc = 1;
1701 int handle_exceptions = 1;
1703 handle_exceptions = !IsDebuggerPresent();
1705 #ifdef UNIT_TESTING_DEBUG
1706 handle_exceptions = 0;
1707 #endif /* UNIT_TESTING_DEBUG */
1709 if (handle_exceptions) {
1712 for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) {
1713 default_signal_functions[i] = signal(
1714 exception_signals[i], exception_handler);
1717 previous_exception_filter = SetUnhandledExceptionFilter(
1719 #endif /* !_WIN32 */
1722 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
1723 print_message("[ RUN ] %s\n", function_name);
1725 initialize_testing(function_name);
1726 global_running_test = 1;
1727 if (setjmp(global_run_test_env) == 0) {
1728 Function(state ? state : ¤t_state);
1729 fail_if_leftover_values(function_name);
1731 /* If this is a setup function then ignore any allocated blocks
1732 * only ensure they're deallocated on tear down. */
1733 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
1734 fail_if_blocks_allocated(check_point, function_name);
1737 global_running_test = 0;
1739 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
1740 print_message("[ OK ] %s\n", function_name);
1744 global_running_test = 0;
1745 print_message("[ FAILED ] %s\n", function_name);
1747 teardown_testing(function_name);
1749 if (handle_exceptions) {
1752 for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) {
1753 signal(exception_signals[i], default_signal_functions[i]);
1756 if (previous_exception_filter) {
1757 SetUnhandledExceptionFilter(previous_exception_filter);
1758 previous_exception_filter = NULL;
1760 #endif /* !_WIN32 */
1767 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
1768 /* Whether to execute the next test. */
1769 int run_next_test = 1;
1770 /* Whether the previous test failed. */
1771 int previous_test_failed = 0;
1772 /* Whether the previous setup failed. */
1773 int previous_setup_failed = 0;
1774 /* Check point of the heap state. */
1775 const ListNode * const check_point = check_point_allocated_blocks();
1776 /* Current test being executed. */
1777 size_t current_test = 0;
1778 /* Number of tests executed. */
1779 size_t tests_executed = 0;
1780 /* Number of failed tests. */
1781 size_t total_failed = 0;
1782 /* Number of setup functions. */
1784 /* Number of teardown functions. */
1785 size_t teardowns = 0;
1787 * A stack of test states. A state is pushed on the stack
1788 * when a test setup occurs and popped on tear down.
1790 TestState* test_states =
1791 (TestState*)malloc(number_of_tests * sizeof(*test_states));
1792 size_t number_of_test_states = 0;
1793 /* Names of the tests that failed. */
1794 const char** failed_names = (const char**)malloc(number_of_tests *
1795 sizeof(*failed_names));
1796 void **current_state = NULL;
1798 print_message("[==========] Running %"PRIdS " test(s).\n", number_of_tests);
1800 /* Make sure LargestIntegralType is at least the size of a pointer. */
1801 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
1803 while (current_test < number_of_tests) {
1804 const ListNode *test_check_point = NULL;
1805 TestState *current_TestState;
1806 const UnitTest * const test = &tests[current_test++];
1807 if (!test->function) {
1811 switch (test->function_type) {
1812 case UNIT_TEST_FUNCTION_TYPE_TEST:
1813 if (! previous_setup_failed) {
1817 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
1818 /* Checkpoint the heap before the setup. */
1819 current_TestState = &test_states[number_of_test_states++];
1820 current_TestState->check_point = check_point_allocated_blocks();
1821 test_check_point = current_TestState->check_point;
1822 current_state = ¤t_TestState->state;
1823 *current_state = NULL;
1828 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1829 /* Check the heap based on the last setup checkpoint. */
1830 assert_true(number_of_test_states);
1831 current_TestState = &test_states[--number_of_test_states];
1832 test_check_point = current_TestState->check_point;
1833 current_state = ¤t_TestState->state;
1837 print_error("Invalid unit test function type %d\n",
1838 test->function_type);
1843 if (run_next_test) {
1844 int failed = _run_test(test->name, test->function, current_state,
1845 test->function_type, test_check_point);
1847 failed_names[total_failed] = test->name;
1850 switch (test->function_type) {
1851 case UNIT_TEST_FUNCTION_TYPE_TEST:
1852 previous_test_failed = failed;
1853 total_failed += failed;
1857 case UNIT_TEST_FUNCTION_TYPE_SETUP:
1861 /* Skip forward until the next test or setup function. */
1863 previous_setup_failed = 1;
1865 previous_test_failed = 0;
1868 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1869 /* If this test failed. */
1870 if (failed && !previous_test_failed) {
1876 assert_null("BUG: shouldn't be here!");
1883 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
1884 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
1888 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
1889 for (i = 0; i < total_failed; i++) {
1890 print_error("[ FAILED ] %s\n", failed_names[i]);
1893 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
1896 if (number_of_test_states) {
1897 print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and "
1898 "teardown %"PRIdS " functions\n", setups, teardowns);
1899 total_failed = (size_t)-1;
1903 free((void*)failed_names);
1905 fail_if_blocks_allocated(check_point, "run_tests");
1906 return (int)total_failed;
1909 int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
1911 UnitTestFunction setup = NULL;
1912 const char *setup_name;
1913 size_t num_setups = 0;
1914 UnitTestFunction teardown = NULL;
1915 const char *teardown_name;
1916 size_t num_teardowns = 0;
1917 size_t current_test = 0;
1920 /* Number of tests executed. */
1921 size_t tests_executed = 0;
1922 /* Number of failed tests. */
1923 size_t total_failed = 0;
1924 /* Check point of the heap state. */
1925 const ListNode * const check_point = check_point_allocated_blocks();
1926 const char** failed_names = (const char**)malloc(number_of_tests *
1927 sizeof(*failed_names));
1928 void **current_state = NULL;
1929 TestState group_state;
1931 /* Find setup and teardown function */
1932 for (i = 0; i < number_of_tests; i++) {
1933 const UnitTest * const test = &tests[i];
1935 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
1936 if (setup == NULL) {
1937 setup = test->function;
1938 setup_name = test->name;
1941 print_error("[ ERROR ] More than one group setup function detected\n");
1946 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
1947 if (teardown == NULL) {
1948 teardown = test->function;
1949 teardown_name = test->name;
1952 print_error("[ ERROR ] More than one group teardown function detected\n");
1958 print_message("[==========] Running %"PRIdS " test(s).\n",
1959 number_of_tests - num_setups - num_teardowns);
1961 if (setup != NULL) {
1964 group_state.check_point = check_point_allocated_blocks();
1965 current_state = &group_state.state;
1966 *current_state = NULL;
1967 failed = _run_test(setup_name,
1970 UNIT_TEST_FUNCTION_TYPE_SETUP,
1971 group_state.check_point);
1973 failed_names[total_failed] = setup_name;
1976 total_failed += failed;
1980 while (current_test < number_of_tests) {
1982 const UnitTest * const test = &tests[current_test++];
1983 if (test->function == NULL) {
1987 switch (test->function_type) {
1988 case UNIT_TEST_FUNCTION_TYPE_TEST:
1991 case UNIT_TEST_FUNCTION_TYPE_SETUP:
1992 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1993 case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
1994 case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
1997 print_error("Invalid unit test function type %d\n",
1998 test->function_type);
2005 failed = _run_test(test->name,
2008 test->function_type,
2011 failed_names[total_failed] = test->name;
2014 total_failed += failed;
2019 if (teardown != NULL) {
2022 failed = _run_test(teardown_name,
2025 UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
2026 group_state.check_point);
2028 failed_names[total_failed] = teardown_name;
2031 total_failed += failed;
2035 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
2036 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
2039 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
2040 for (i = 0; i < total_failed; i++) {
2041 print_error("[ FAILED ] %s\n", failed_names[i]);
2044 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
2047 free((void*)failed_names);
2048 fail_if_blocks_allocated(check_point, "run_group_tests");
2050 return (int)total_failed;