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.
37 #define vsnprintf _vsnprintf
40 /* Backwards compatibility with headers shipped with Visual Studio 2005 and
43 WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID);
46 // Size of guard bytes around dynamically allocated blocks.
47 #define MALLOC_GUARD_SIZE 16
48 // Pattern used to initialize guard blocks.
49 #define MALLOC_GUARD_PATTERN 0xEF
50 // Pattern used to initialize memory allocated with test_malloc().
51 #define MALLOC_ALLOC_PATTERN 0xBA
52 #define MALLOC_FREE_PATTERN 0xCD
53 // Alignment of allocated blocks. NOTE: This must be base2.
54 #define MALLOC_ALIGNMENT sizeof(size_t)
56 // Printf formatting for source code locations.
57 #define SOURCE_LOCATION_FORMAT "%s:%d"
59 // Calculates the number of elements in an array.
60 #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
62 // Declare and initialize the pointer member of ValuePointer variable name
64 #define declare_initialize_value_pointer_pointer(name, ptr) \
67 name.pointer = (void*)(ptr)
69 // Declare and initialize the value member of ValuePointer variable name
71 #define declare_initialize_value_pointer_value(name, val) \
75 // Cast a LargestIntegralType to pointer_type via a ValuePointer.
76 #define cast_largest_integral_type_to_pointer( \
77 pointer_type, largest_integral_type) \
78 ((pointer_type)((ValuePointer*)&(largest_integral_type))->pointer)
80 // Used to cast LargetIntegralType to void* and vice versa.
81 typedef union ValuePointer {
82 LargestIntegralType value;
86 // Doubly linked list node.
87 typedef struct ListNode {
90 struct ListNode *next;
91 struct ListNode *prev;
94 // Debug information for malloc().
95 typedef struct MallocBlockInfo {
96 void* block; // Address of the block returned by malloc().
97 size_t allocated_size; // Total size of the allocated block.
98 size_t size; // Request block size.
99 SourceLocation location; // Where the block was allocated.
100 ListNode node; // Node within list of all allocated blocks.
103 // State of each test.
104 typedef struct TestState {
105 const ListNode *check_point; // Check point of the test if there's a
107 void *state; // State associated with the test.
110 // Determines whether two values are the same.
111 typedef int (*EqualityFunction)(const void *left, const void *right);
113 // Value of a symbol and the place it was declared.
114 typedef struct SymbolValue {
115 SourceLocation location;
116 LargestIntegralType value;
119 /* Contains a list of values for a symbol.
120 * NOTE: Each structure referenced by symbol_values_list_head must have a
121 * SourceLocation as its' first member.
123 typedef struct SymbolMapValue {
124 const char *symbol_name;
125 ListNode symbol_values_list_head;
128 // Used by list_free() to deallocate values referenced by list nodes.
129 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
131 // Structure used to check the range of integer types.
132 typedef struct CheckIntegerRange {
133 CheckParameterEvent event;
134 LargestIntegralType minimum;
135 LargestIntegralType maximum;
138 // Structure used to check whether an integer value is in a set.
139 typedef struct CheckIntegerSet {
140 CheckParameterEvent event;
141 const LargestIntegralType *set;
145 /* Used to check whether a parameter matches the area of memory referenced by
147 typedef struct CheckMemoryData {
148 CheckParameterEvent event;
153 static ListNode* list_initialize(ListNode * const node);
154 static ListNode* list_add(ListNode * const head, ListNode *new_node);
155 static ListNode* list_add_value(ListNode * const head, const void *value,
157 static ListNode* list_remove(
158 ListNode * const node, const CleanupListValue cleanup_value,
159 void * const cleanup_value_data);
160 static void list_remove_free(
161 ListNode * const node, const CleanupListValue cleanup_value,
162 void * const cleanup_value_data);
163 static int list_empty(const ListNode * const head);
164 static int list_find(
165 ListNode * const head, const void *value,
166 const EqualityFunction equal_func, ListNode **output);
167 static int list_first(ListNode * const head, ListNode **output);
168 static ListNode* list_free(
169 ListNode * const head, const CleanupListValue cleanup_value,
170 void * const cleanup_value_data);
172 static void add_symbol_value(
173 ListNode * const symbol_map_head, const char * const symbol_names[],
174 const size_t number_of_symbol_names, const void* value, const int count);
175 static int get_symbol_value(
176 ListNode * const symbol_map_head, const char * const symbol_names[],
177 const size_t number_of_symbol_names, void **output);
178 static void free_value(const void *value, void *cleanup_value_data);
179 static void free_symbol_map_value(
180 const void *value, void *cleanup_value_data);
181 static void remove_always_return_values(ListNode * const map_head,
182 const size_t number_of_symbol_names);
183 static int check_for_leftover_values(
184 const ListNode * const map_head, const char * const error_message,
185 const size_t number_of_symbol_names);
186 // This must be called at the beginning of a test to initialize some data
188 static void initialize_testing(const char *test_name);
189 // This must be called at the end of a test to free() allocated structures.
190 static void teardown_testing(const char *test_name);
193 // Keeps track of the calling context returned by setenv() so that the fail()
194 // method can jump out of a test.
195 static jmp_buf global_run_test_env;
196 static int global_running_test = 0;
198 // Keeps track of the calling context returned by setenv() so that
199 // mock_assert() can optionally jump back to expect_assert_failure().
200 jmp_buf global_expect_assert_env;
201 int global_expecting_assert = 0;
203 // Keeps a map of the values that functions will have to return to provide
204 // mocked interfaces.
205 static ListNode global_function_result_map_head;
206 // Location of the last mock value returned was declared.
207 static SourceLocation global_last_mock_value_location;
209 /* Keeps a map of the values that functions expect as parameters to their
210 * mocked interfaces. */
211 static ListNode global_function_parameter_map_head;
212 // Location of last parameter value checked was declared.
213 static SourceLocation global_last_parameter_location;
215 // List of all currently allocated blocks.
216 static ListNode global_allocated_blocks;
219 // Signals caught by exception_handler().
220 static const int exception_signals[] = {
228 // Default signal functions that should be restored after a test is complete.
229 typedef void (*SignalFunction)(int signal);
230 static SignalFunction default_signal_functions[
231 ARRAY_LENGTH(exception_signals)];
235 // The default exception filter.
236 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
239 typedef struct ExceptionCodeInfo {
241 const char* description;
244 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
246 static const ExceptionCodeInfo exception_codes[] = {
247 EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
248 EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
249 EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
250 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
251 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
252 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
253 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
254 EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
255 EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
256 EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
257 EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
258 EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
259 EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
260 EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
261 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
262 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
263 EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
264 EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
265 EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
266 EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
271 // Exit the currently executing test.
272 static void exit_test(const int quit_application) {
273 if (global_running_test) {
274 longjmp(global_run_test_env, 1);
275 } else if (quit_application) {
281 // Initialize a SourceLocation structure.
282 static void initialize_source_location(SourceLocation * const location) {
283 assert_true(location);
284 location->file = NULL;
289 // Determine whether a source location is currently set.
290 static int source_location_is_set(const SourceLocation * const location) {
291 assert_true(location);
292 return location->file && location->line;
296 // Set a source location.
297 static void set_source_location(
298 SourceLocation * const location, const char * const file,
300 assert_true(location);
301 location->file = file;
302 location->line = line;
306 // Create function results and expected parameter lists.
307 void initialize_testing(const char *test_name) {
308 list_initialize(&global_function_result_map_head);
309 initialize_source_location(&global_last_mock_value_location);
310 list_initialize(&global_function_parameter_map_head);
311 initialize_source_location(&global_last_parameter_location);
315 void fail_if_leftover_values(const char *test_name) {
316 int error_occurred = 0;
317 remove_always_return_values(&global_function_result_map_head, 1);
318 if (check_for_leftover_values(
319 &global_function_result_map_head,
320 "%s() has remaining non-returned values.\n", 1)) {
324 remove_always_return_values(&global_function_parameter_map_head, 2);
325 if (check_for_leftover_values(
326 &global_function_parameter_map_head,
327 "%s parameter still has values that haven't been checked.\n", 2)) {
330 if (error_occurred) {
336 void teardown_testing(const char *test_name) {
337 list_free(&global_function_result_map_head, free_symbol_map_value,
339 initialize_source_location(&global_last_mock_value_location);
340 list_free(&global_function_parameter_map_head, free_symbol_map_value,
342 initialize_source_location(&global_last_parameter_location);
345 // Initialize a list node.
346 static ListNode* list_initialize(ListNode * const node) {
355 /* Adds a value at the tail of a given list.
356 * The node referencing the value is allocated from the heap. */
357 static ListNode* list_add_value(ListNode * const head, const void *value,
358 const int refcount) {
359 ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
362 new_node->value = value;
363 new_node->refcount = refcount;
364 return list_add(head, new_node);
368 // Add new_node to the end of the list.
369 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
371 assert_true(new_node);
372 new_node->next = head;
373 new_node->prev = head->prev;
374 head->prev->next = new_node;
375 head->prev = new_node;
380 // Remove a node from a list.
381 static ListNode* list_remove(
382 ListNode * const node, const CleanupListValue cleanup_value,
383 void * const cleanup_value_data) {
385 node->prev->next = node->next;
386 node->next->prev = node->prev;
388 cleanup_value(node->value, cleanup_value_data);
394 /* Remove a list node from a list and free the node. */
395 static void list_remove_free(
396 ListNode * const node, const CleanupListValue cleanup_value,
397 void * const cleanup_value_data) {
399 free(list_remove(node, cleanup_value, cleanup_value_data));
403 /* Frees memory kept by a linked list
404 * The cleanup_value function is called for every "value" field of nodes in the
405 * list, except for the head. In addition to each list value,
406 * cleanup_value_data is passed to each call to cleanup_value. The head
407 * of the list is not deallocated.
409 static ListNode* list_free(
410 ListNode * const head, const CleanupListValue cleanup_value,
411 void * const cleanup_value_data) {
413 while (!list_empty(head)) {
414 list_remove_free(head->next, cleanup_value, cleanup_value_data);
420 // Determine whether a list is empty.
421 static int list_empty(const ListNode * const head) {
423 return head->next == head;
427 /* Find a value in the list using the equal_func to compare each node with the
430 static int list_find(ListNode * const head, const void *value,
431 const EqualityFunction equal_func, ListNode **output) {
434 for (current = head->next; current != head; current = current->next) {
435 if (equal_func(current->value, value)) {
443 // Returns the first node of a list
444 static int list_first(ListNode * const head, ListNode **output) {
445 ListNode *target_node;
447 if (list_empty(head)) {
450 target_node = head->next;
451 *output = target_node;
456 // Deallocate a value referenced by a list.
457 static void free_value(const void *value, void *cleanup_value_data) {
463 // Releases memory associated to a symbol_map_value.
464 static void free_symbol_map_value(const void *value,
465 void *cleanup_value_data) {
466 SymbolMapValue * const map_value = (SymbolMapValue*)value;
467 const unsigned int children = (unsigned int)cleanup_value_data;
469 list_free(&map_value->symbol_values_list_head,
470 children ? free_symbol_map_value : free_value,
471 (void*)(children - 1));
476 /* Determine whether a symbol name referenced by a symbol_map_value
477 * matches the specified function name. */
478 static int symbol_names_match(const void *map_value, const void *symbol) {
479 return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
480 (const char*)symbol);
484 /* Adds a value to the queue of values associated with the given
485 * hierarchy of symbols. It's assumed value is allocated from the heap.
487 static void add_symbol_value(ListNode * const symbol_map_head,
488 const char * const symbol_names[],
489 const size_t number_of_symbol_names,
490 const void* value, const int refcount) {
491 const char* symbol_name;
492 ListNode *target_node;
493 SymbolMapValue *target_map_value;
494 assert_true(symbol_map_head);
495 assert_true(symbol_names);
496 assert_true(number_of_symbol_names);
497 symbol_name = symbol_names[0];
499 if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
501 SymbolMapValue * const new_symbol_map_value =
502 malloc(sizeof(*new_symbol_map_value));
503 new_symbol_map_value->symbol_name = symbol_name;
504 list_initialize(&new_symbol_map_value->symbol_values_list_head);
505 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
509 target_map_value = (SymbolMapValue*)target_node->value;
510 if (number_of_symbol_names == 1) {
511 list_add_value(&target_map_value->symbol_values_list_head,
514 add_symbol_value(&target_map_value->symbol_values_list_head,
515 &symbol_names[1], number_of_symbol_names - 1, value,
521 /* Gets the next value associated with the given hierarchy of symbols.
522 * The value is returned as an output parameter with the function returning the
523 * node's old refcount value if a value is found, 0 otherwise.
524 * This means that a return value of 1 indicates the node was just removed from
527 static int get_symbol_value(
528 ListNode * const head, const char * const symbol_names[],
529 const size_t number_of_symbol_names, void **output) {
530 const char* symbol_name;
531 ListNode *target_node;
533 assert_true(symbol_names);
534 assert_true(number_of_symbol_names);
536 symbol_name = symbol_names[0];
538 if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
539 SymbolMapValue *map_value;
540 ListNode *child_list;
541 int return_value = 0;
542 assert_true(target_node);
543 assert_true(target_node->value);
545 map_value = (SymbolMapValue*)target_node->value;
546 child_list = &map_value->symbol_values_list_head;
548 if (number_of_symbol_names == 1) {
549 ListNode *value_node = NULL;
550 return_value = list_first(child_list, &value_node);
551 assert_true(return_value);
552 *output = (void*) value_node->value;
553 return_value = value_node->refcount;
554 if (--value_node->refcount == 0) {
555 list_remove_free(value_node, NULL, NULL);
558 return_value = get_symbol_value(
559 child_list, &symbol_names[1], number_of_symbol_names - 1,
562 if (list_empty(child_list)) {
563 list_remove_free(target_node, free_symbol_map_value, (void*)0);
567 print_error("No entries for symbol %s.\n", symbol_name);
573 /* Traverse down a tree of symbol values and remove the first symbol value
574 * in each branch that has a refcount < -1 (i.e should always be returned
575 * and has been returned at least once).
577 static void remove_always_return_values(ListNode * const map_head,
578 const size_t number_of_symbol_names) {
580 assert_true(map_head);
581 assert_true(number_of_symbol_names);
582 current = map_head->next;
583 while (current != map_head) {
584 SymbolMapValue * const value = (SymbolMapValue*)current->value;
585 ListNode * const next = current->next;
586 ListNode *child_list;
588 child_list = &value->symbol_values_list_head;
590 if (!list_empty(child_list)) {
591 if (number_of_symbol_names == 1) {
592 ListNode * const child_node = child_list->next;
593 // If this item has been returned more than once, free it.
594 if (child_node->refcount < -1) {
595 list_remove_free(child_node, free_value, NULL);
598 remove_always_return_values(child_list,
599 number_of_symbol_names - 1);
603 if (list_empty(child_list)) {
604 list_remove_free(current, free_value, NULL);
610 /* Checks if there are any leftover values set up by the test that were never
611 * retrieved through execution, and fail the test if that is the case.
613 static int check_for_leftover_values(
614 const ListNode * const map_head, const char * const error_message,
615 const size_t number_of_symbol_names) {
616 const ListNode *current;
617 int symbols_with_leftover_values = 0;
618 assert_true(map_head);
619 assert_true(number_of_symbol_names);
621 for (current = map_head->next; current != map_head;
622 current = current->next) {
623 const SymbolMapValue * const value =
624 (SymbolMapValue*)current->value;
625 const ListNode *child_list;
627 child_list = &value->symbol_values_list_head;
629 if (!list_empty(child_list)) {
630 if (number_of_symbol_names == 1) {
631 const ListNode *child_node;
632 print_error(error_message, value->symbol_name);
633 print_error(" Remaining item(s) declared at...\n");
635 for (child_node = child_list->next; child_node != child_list;
636 child_node = child_node->next) {
637 const SourceLocation * const location = child_node->value;
638 print_error(" " SOURCE_LOCATION_FORMAT "\n",
639 location->file, location->line);
642 print_error("%s.", value->symbol_name);
643 check_for_leftover_values(child_list, error_message,
644 number_of_symbol_names - 1);
646 symbols_with_leftover_values ++;
649 return symbols_with_leftover_values;
653 // Get the next return value for the specified mock function.
654 LargestIntegralType _mock(const char * const function, const char* const file,
657 const int rc = get_symbol_value(&global_function_result_map_head,
658 &function, 1, &result);
660 SymbolValue * const symbol = (SymbolValue*)result;
661 const LargestIntegralType value = symbol->value;
662 global_last_mock_value_location = symbol->location;
668 print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value "
669 "to mock function %s\n", file, line, function);
670 if (source_location_is_set(&global_last_mock_value_location)) {
671 print_error("Previously returned mock value was declared at "
672 SOURCE_LOCATION_FORMAT "\n",
673 global_last_mock_value_location.file,
674 global_last_mock_value_location.line);
676 print_error("There were no previously returned mock values for "
685 // Add a return value for the specified mock function name.
686 void _will_return(const char * const function_name, const char * const file,
687 const int line, const LargestIntegralType value,
689 SymbolValue * const return_value = malloc(sizeof(*return_value));
690 assert_true(count > 0 || count == -1);
691 return_value->value = value;
692 set_source_location(&return_value->location, file, line);
693 add_symbol_value(&global_function_result_map_head, &function_name, 1,
694 return_value, count);
698 /* Add a custom parameter checking function. If the event parameter is NULL
699 * the event structure is allocated internally by this function. If event
700 * parameter is provided it must be allocated on the heap and doesn't need to
701 * be deallocated by the caller.
704 const char* const function, const char* const parameter,
705 const char* const file, const int line,
706 const CheckParameterValue check_function,
707 const LargestIntegralType check_data,
708 CheckParameterEvent * const event, const int count) {
709 CheckParameterEvent * const check =
710 event ? event : malloc(sizeof(*check));
711 const char* symbols[] = {function, parameter};
712 check->parameter_name = parameter;
713 check->check_value = check_function;
714 check->check_value_data = check_data;
715 set_source_location(&check->location, file, line);
716 add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
721 /* Returns 1 if the specified values are equal. If the values are not equal
722 * an error is displayed and 0 is returned. */
723 static int values_equal_display_error(const LargestIntegralType left,
724 const LargestIntegralType right) {
725 const int equal = left == right;
727 print_error(LargestIntegralTypePrintfFormat " != "
728 LargestIntegralTypePrintfFormat "\n", left, right);
733 /* Returns 1 if the specified values are not equal. If the values are equal
734 * an error is displayed and 0 is returned. */
735 static int values_not_equal_display_error(const LargestIntegralType left,
736 const LargestIntegralType right) {
737 const int not_equal = left != right;
739 print_error(LargestIntegralTypePrintfFormat " == "
740 LargestIntegralTypePrintfFormat "\n", left, right);
746 /* Determine whether value is contained within check_integer_set.
747 * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
748 * returned and an error is displayed. If invert is 1 and the value is not
749 * in the set 1 is returned, otherwise 0 is returned and an error is
751 static int value_in_set_display_error(
752 const LargestIntegralType value,
753 const CheckIntegerSet * const check_integer_set, const int invert) {
754 int succeeded = invert;
755 assert_true(check_integer_set);
757 const LargestIntegralType * const set = check_integer_set->set;
758 const size_t size_of_set = check_integer_set->size_of_set;
760 for (i = 0; i < size_of_set; i++) {
761 if (set[i] == value) {
762 // If invert = 0 and item is found, succeeded = 1.
763 // If invert = 1 and item is found, succeeded = 0.
764 succeeded = !succeeded;
771 print_error("%d is %sin the set (", value, invert ? "" : "not ");
772 for (i = 0; i < size_of_set; i++) {
773 print_error("%d, ", set[i]);
781 /* Determine whether a value is within the specified range. If the value is
782 * within the specified range 1 is returned. If the value isn't within the
783 * specified range an error is displayed and 0 is returned. */
784 static int integer_in_range_display_error(
785 const LargestIntegralType value, const LargestIntegralType range_min,
786 const LargestIntegralType range_max) {
787 if (value >= range_min && value <= range_max) {
790 print_error("%d is not within the range %d-%d\n", value, range_min,
796 /* Determine whether a value is within the specified range. If the value
797 * is not within the range 1 is returned. If the value is within the
798 * specified range an error is displayed and zero is returned. */
799 static int integer_not_in_range_display_error(
800 const LargestIntegralType value, const LargestIntegralType range_min,
801 const LargestIntegralType range_max) {
802 if (value < range_min || value > range_max) {
805 print_error("%d is within the range %d-%d\n", value, range_min,
811 /* Determine whether the specified strings are equal. If the strings are equal
812 * 1 is returned. If they're not equal an error is displayed and 0 is
814 static int string_equal_display_error(
815 const char * const left, const char * const right) {
816 if (strcmp(left, right) == 0) {
819 print_error("\"%s\" != \"%s\"\n", left, right);
824 /* Determine whether the specified strings are equal. If the strings are not
825 * equal 1 is returned. If they're not equal an error is displayed and 0 is
827 static int string_not_equal_display_error(
828 const char * const left, const char * const right) {
829 if (strcmp(left, right) != 0) {
832 print_error("\"%s\" == \"%s\"\n", left, right);
837 /* Determine whether the specified areas of memory are equal. If they're equal
838 * 1 is returned otherwise an error is displayed and 0 is returned. */
839 static int memory_equal_display_error(const char* const a, const char* const b,
843 for (i = 0; i < size; i++) {
847 print_error("difference at offset %d 0x%02x 0x%02x\n", i, l, r);
852 print_error("%d bytes of 0x%08x and 0x%08x differ\n", differences,
860 /* Determine whether the specified areas of memory are not equal. If they're
861 * not equal 1 is returned otherwise an error is displayed and 0 is
863 static int memory_not_equal_display_error(
864 const char* const a, const char* const b, const size_t size) {
867 for (i = 0; i < size; i++) {
875 print_error("%d bytes of 0x%08x and 0x%08x the same\n", same,
883 // CheckParameterValue callback to check whether a value is within a set.
884 static int check_in_set(const LargestIntegralType value,
885 const LargestIntegralType check_value_data) {
886 return value_in_set_display_error(value,
887 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
888 check_value_data), 0);
892 // CheckParameterValue callback to check whether a value isn't within a set.
893 static int check_not_in_set(const LargestIntegralType value,
894 const LargestIntegralType check_value_data) {
895 return value_in_set_display_error(value,
896 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
897 check_value_data), 1);
901 /* Create the callback data for check_in_set() or check_not_in_set() and
902 * register a check event. */
903 static void expect_set(
904 const char* const function, const char* const parameter,
905 const char* const file, const int line,
906 const LargestIntegralType values[], const size_t number_of_values,
907 const CheckParameterValue check_function, const int count) {
908 CheckIntegerSet * const check_integer_set =
909 malloc(sizeof(*check_integer_set) +
910 (sizeof(values[0]) * number_of_values));
911 LargestIntegralType * const set = (LargestIntegralType*)(
912 check_integer_set + 1);
913 declare_initialize_value_pointer_pointer(check_data, check_integer_set);
915 assert_true(number_of_values);
916 memcpy(set, values, number_of_values * sizeof(values[0]));
917 check_integer_set->set = set;
919 function, parameter, file, line, check_function,
920 check_data.value, &check_integer_set->event, count);
924 // Add an event to check whether a value is in a set.
926 const char* const function, const char* const parameter,
927 const char* const file, const int line,
928 const LargestIntegralType values[], const size_t number_of_values,
930 expect_set(function, parameter, file, line, values, number_of_values,
931 check_in_set, count);
935 // Add an event to check whether a value isn't in a set.
936 void _expect_not_in_set(
937 const char* const function, const char* const parameter,
938 const char* const file, const int line,
939 const LargestIntegralType values[], const size_t number_of_values,
941 expect_set(function, parameter, file, line, values, number_of_values,
942 check_not_in_set, count);
946 // CheckParameterValue callback to check whether a value is within a range.
947 static int check_in_range(const LargestIntegralType value,
948 const LargestIntegralType check_value_data) {
949 CheckIntegerRange * const check_integer_range =
950 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
952 assert_true(check_integer_range);
953 return integer_in_range_display_error(value, check_integer_range->minimum,
954 check_integer_range->maximum);
958 // CheckParameterValue callback to check whether a value is not within a range.
959 static int check_not_in_range(const LargestIntegralType value,
960 const LargestIntegralType check_value_data) {
961 CheckIntegerRange * const check_integer_range =
962 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
964 assert_true(check_integer_range);
965 return integer_not_in_range_display_error(
966 value, check_integer_range->minimum, check_integer_range->maximum);
970 /* Create the callback data for check_in_range() or check_not_in_range() and
971 * register a check event. */
972 static void expect_range(
973 const char* const function, const char* const parameter,
974 const char* const file, const int line,
975 const LargestIntegralType minimum, const LargestIntegralType maximum,
976 const CheckParameterValue check_function, const int count) {
977 CheckIntegerRange * const check_integer_range =
978 malloc(sizeof(*check_integer_range));
979 declare_initialize_value_pointer_pointer(check_data, check_integer_range);
980 check_integer_range->minimum = minimum;
981 check_integer_range->maximum = maximum;
982 _expect_check(function, parameter, file, line, check_function,
983 check_data.value, &check_integer_range->event, count);
987 // Add an event to determine whether a parameter is within a range.
988 void _expect_in_range(
989 const char* const function, const char* const parameter,
990 const char* const file, const int line,
991 const LargestIntegralType minimum, const LargestIntegralType maximum,
993 expect_range(function, parameter, file, line, minimum, maximum,
994 check_in_range, count);
998 // Add an event to determine whether a parameter is not within a range.
999 void _expect_not_in_range(
1000 const char* const function, const char* const parameter,
1001 const char* const file, const int line,
1002 const LargestIntegralType minimum, const LargestIntegralType maximum,
1004 expect_range(function, parameter, file, line, minimum, maximum,
1005 check_not_in_range, count);
1009 /* CheckParameterValue callback to check whether a value is equal to an
1010 * expected value. */
1011 static int check_value(const LargestIntegralType value,
1012 const LargestIntegralType check_value_data) {
1013 return values_equal_display_error(value, check_value_data);
1017 // Add an event to check a parameter equals an expected value.
1019 const char* const function, const char* const parameter,
1020 const char* const file, const int line,
1021 const LargestIntegralType value, const int count) {
1022 _expect_check(function, parameter, file, line, check_value, value, NULL,
1027 /* CheckParameterValue callback to check whether a value is not equal to an
1028 * expected value. */
1029 static int check_not_value(const LargestIntegralType value,
1030 const LargestIntegralType check_value_data) {
1031 return values_not_equal_display_error(value, check_value_data);
1035 // Add an event to check a parameter is not equal to an expected value.
1036 void _expect_not_value(
1037 const char* const function, const char* const parameter,
1038 const char* const file, const int line,
1039 const LargestIntegralType value, const int count) {
1040 _expect_check(function, parameter, file, line, check_not_value, value,
1045 // CheckParameterValue callback to check whether a parameter equals a string.
1046 static int check_string(const LargestIntegralType value,
1047 const LargestIntegralType check_value_data) {
1048 return string_equal_display_error(
1049 cast_largest_integral_type_to_pointer(char*, value),
1050 cast_largest_integral_type_to_pointer(char*, check_value_data));
1054 // Add an event to check whether a parameter is equal to a string.
1055 void _expect_string(
1056 const char* const function, const char* const parameter,
1057 const char* const file, const int line, const char* string,
1059 declare_initialize_value_pointer_pointer(string_pointer, (char*)string);
1060 _expect_check(function, parameter, file, line, check_string,
1061 string_pointer.value, NULL, count);
1065 /* CheckParameterValue callback to check whether a parameter is not equals to
1067 static int check_not_string(const LargestIntegralType value,
1068 const LargestIntegralType check_value_data) {
1069 return string_not_equal_display_error(
1070 cast_largest_integral_type_to_pointer(char*, value),
1071 cast_largest_integral_type_to_pointer(char*, check_value_data));
1075 // Add an event to check whether a parameter is not equal to a string.
1076 void _expect_not_string(
1077 const char* const function, const char* const parameter,
1078 const char* const file, const int line, const char* string,
1080 declare_initialize_value_pointer_pointer(string_pointer, (char*)string);
1081 _expect_check(function, parameter, file, line, check_not_string,
1082 string_pointer.value, NULL, count);
1085 /* CheckParameterValue callback to check whether a parameter equals an area of
1087 static int check_memory(const LargestIntegralType value,
1088 const LargestIntegralType check_value_data) {
1089 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1090 CheckMemoryData*, check_value_data);
1092 return memory_equal_display_error(
1093 cast_largest_integral_type_to_pointer(void*, value),
1094 check->memory, check->size);
1098 /* Create the callback data for check_memory() or check_not_memory() and
1099 * register a check event. */
1100 static void expect_memory_setup(
1101 const char* const function, const char* const parameter,
1102 const char* const file, const int line,
1103 const void * const memory, const size_t size,
1104 const CheckParameterValue check_function, const int count) {
1105 CheckMemoryData * const check_data = malloc(sizeof(*check_data) + size);
1106 void * const mem = (void*)(check_data + 1);
1107 declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1108 assert_true(memory);
1110 memcpy(mem, memory, size);
1111 check_data->memory = mem;
1112 check_data->size = size;
1113 _expect_check(function, parameter, file, line, check_function,
1114 check_data_pointer.value, &check_data->event, count);
1118 // Add an event to check whether a parameter matches an area of memory.
1119 void _expect_memory(
1120 const char* const function, const char* const parameter,
1121 const char* const file, const int line, const void* const memory,
1122 const size_t size, const int count) {
1123 expect_memory_setup(function, parameter, file, line, memory, size,
1124 check_memory, count);
1128 /* CheckParameterValue callback to check whether a parameter is not equal to
1129 * an area of memory. */
1130 static int check_not_memory(const LargestIntegralType value,
1131 const LargestIntegralType check_value_data) {
1132 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1133 CheckMemoryData*, check_value_data);
1135 return memory_not_equal_display_error(
1136 cast_largest_integral_type_to_pointer(void*, value), check->memory,
1141 // Add an event to check whether a parameter doesn't match an area of memory.
1142 void _expect_not_memory(
1143 const char* const function, const char* const parameter,
1144 const char* const file, const int line, const void* const memory,
1145 const size_t size, const int count) {
1146 expect_memory_setup(function, parameter, file, line, memory, size,
1147 check_not_memory, count);
1151 // CheckParameterValue callback that always returns 1.
1152 static int check_any(const LargestIntegralType value,
1153 const LargestIntegralType check_value_data) {
1158 // Add an event to allow any value for a parameter.
1160 const char* const function, const char* const parameter,
1161 const char* const file, const int line, const int count) {
1162 _expect_check(function, parameter, file, line, check_any, 0, NULL,
1167 void _check_expected(
1168 const char * const function_name, const char * const parameter_name,
1169 const char* file, const int line, const LargestIntegralType value) {
1171 const char* symbols[] = {function_name, parameter_name};
1172 const int rc = get_symbol_value(&global_function_parameter_map_head,
1173 symbols, 2, &result);
1175 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1176 int check_succeeded;
1177 global_last_parameter_location = check->location;
1178 check_succeeded = check->check_value(value, check->check_value_data);
1182 if (!check_succeeded) {
1183 print_error("ERROR: Check of parameter %s, function %s failed\n"
1184 "Expected parameter declared at "
1185 SOURCE_LOCATION_FORMAT "\n",
1186 parameter_name, function_name,
1187 global_last_parameter_location.file,
1188 global_last_parameter_location.line);
1192 print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value "
1193 "to check parameter %s of function %s\n", file, line,
1194 parameter_name, function_name);
1195 if (source_location_is_set(&global_last_parameter_location)) {
1196 print_error("Previously declared parameter value was declared at "
1197 SOURCE_LOCATION_FORMAT "\n",
1198 global_last_parameter_location.file,
1199 global_last_parameter_location.line);
1201 print_error("There were no previously declared parameter values "
1202 "for this test.\n");
1209 // Replacement for assert.
1210 void mock_assert(const int result, const char* const expression,
1211 const char* const file, const int line) {
1213 if (global_expecting_assert) {
1214 longjmp(global_expect_assert_env, (int)expression);
1216 print_error("ASSERT: %s\n", expression);
1223 void _assert_true(const LargestIntegralType result,
1224 const char * const expression,
1225 const char * const file, const int line) {
1227 print_error("%s\n", expression);
1232 void _assert_int_equal(
1233 const LargestIntegralType a, const LargestIntegralType b,
1234 const char * const file, const int line) {
1235 if (!values_equal_display_error(a, b)) {
1241 void _assert_int_not_equal(
1242 const LargestIntegralType a, const LargestIntegralType b,
1243 const char * const file, const int line) {
1244 if (!values_not_equal_display_error(a, b)) {
1250 void _assert_string_equal(const char * const a, const char * const b,
1251 const char * const file, const int line) {
1252 if (!string_equal_display_error(a, b)) {
1258 void _assert_string_not_equal(const char * const a, const char * const b,
1259 const char *file, const int line) {
1260 if (!string_not_equal_display_error(a, b)) {
1266 void _assert_memory_equal(const void * const a, const void * const b,
1267 const size_t size, const char* const file,
1269 if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1275 void _assert_memory_not_equal(const void * const a, const void * const b,
1276 const size_t size, const char* const file,
1278 if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1285 void _assert_in_range(
1286 const LargestIntegralType value, const LargestIntegralType minimum,
1287 const LargestIntegralType maximum, const char* const file,
1289 if (!integer_in_range_display_error(value, minimum, maximum)) {
1294 void _assert_not_in_range(
1295 const LargestIntegralType value, const LargestIntegralType minimum,
1296 const LargestIntegralType maximum, const char* const file,
1298 if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1303 void _assert_in_set(const LargestIntegralType value,
1304 const LargestIntegralType values[],
1305 const size_t number_of_values, const char* const file,
1307 CheckIntegerSet check_integer_set;
1308 check_integer_set.set = values;
1309 check_integer_set.size_of_set = number_of_values;
1310 if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1315 void _assert_not_in_set(const LargestIntegralType value,
1316 const LargestIntegralType values[],
1317 const size_t number_of_values, const char* const file,
1319 CheckIntegerSet check_integer_set;
1320 check_integer_set.set = values;
1321 check_integer_set.size_of_set = number_of_values;
1322 if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1328 // Get the list of allocated blocks.
1329 static ListNode* get_allocated_blocks_list() {
1330 // If it initialized, initialize the list of allocated blocks.
1331 if (!global_allocated_blocks.value) {
1332 list_initialize(&global_allocated_blocks);
1333 global_allocated_blocks.value = (void*)1;
1335 return &global_allocated_blocks;
1338 // Use the real malloc in this function.
1340 void* _test_malloc(const size_t size, const char* file, const int line) {
1342 MallocBlockInfo *block_info;
1343 ListNode * const block_list = get_allocated_blocks_list();
1344 const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
1345 sizeof(*block_info) + MALLOC_ALIGNMENT;
1346 char* const block = (char*)malloc(allocate_size);
1349 // Calculate the returned address.
1350 ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
1351 MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1353 // Initialize the guard blocks.
1354 memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1355 memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1356 memset(ptr, MALLOC_ALLOC_PATTERN, size);
1358 block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
1359 sizeof(*block_info)));
1360 set_source_location(&block_info->location, file, line);
1361 block_info->allocated_size = allocate_size;
1362 block_info->size = size;
1363 block_info->block = block;
1364 block_info->node.value = block_info;
1365 list_add(block_list, &block_info->node);
1368 #define malloc test_malloc
1371 void* _test_calloc(const size_t number_of_elements, const size_t size,
1372 const char* file, const int line) {
1373 void* const ptr = _test_malloc(number_of_elements * size, file, line);
1375 memset(ptr, 0, number_of_elements * size);
1381 // Use the real free in this function.
1383 void _test_free(void* const ptr, const char* file, const int line) {
1385 char *block = (char*)ptr;
1386 MallocBlockInfo *block_info;
1387 _assert_true((int)ptr, "ptr", file, line);
1388 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1389 sizeof(*block_info)));
1390 // Check the guard blocks.
1392 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1393 block + block_info->size};
1394 for (i = 0; i < ARRAY_LENGTH(guards); i++) {
1396 char * const guard = guards[i];
1397 for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1398 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1401 "Guard block of 0x%08x size=%d allocated by "
1402 SOURCE_LOCATION_FORMAT " at 0x%08x is corrupt\n",
1403 (size_t)ptr, block_info->size,
1404 block_info->location.file, block_info->location.line,
1411 list_remove(&block_info->node, NULL, NULL);
1413 block = block_info->block;
1414 memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
1417 #define free test_free
1420 // Crudely checkpoint the current heap state.
1421 static const ListNode* check_point_allocated_blocks() {
1422 return get_allocated_blocks_list()->prev;
1426 /* Display the blocks allocated after the specified check point. This
1427 * function returns the number of blocks displayed. */
1428 static int display_allocated_blocks(const ListNode * const check_point) {
1429 const ListNode * const head = get_allocated_blocks_list();
1430 const ListNode *node;
1431 int allocated_blocks = 0;
1432 assert_true(check_point);
1433 assert_true(check_point->next);
1435 for (node = check_point->next; node != head; node = node->next) {
1436 const MallocBlockInfo * const block_info = node->value;
1437 assert_true(block_info);
1439 if (!allocated_blocks) {
1440 print_error("Blocks allocated...\n");
1442 print_error(" 0x%08x : " SOURCE_LOCATION_FORMAT "\n",
1443 block_info->block, block_info->location.file,
1444 block_info->location.line);
1445 allocated_blocks ++;
1447 return allocated_blocks;
1451 // Free all blocks allocated after the specified check point.
1452 static void free_allocated_blocks(const ListNode * const check_point) {
1453 const ListNode * const head = get_allocated_blocks_list();
1454 const ListNode *node;
1455 assert_true(check_point);
1457 node = check_point->next;
1460 while (node != head) {
1461 MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
1463 free((char*)block_info + sizeof(*block_info) + MALLOC_GUARD_SIZE);
1468 // Fail if any any blocks are allocated after the specified check point.
1469 static void fail_if_blocks_allocated(const ListNode * const check_point,
1470 const char * const test_name) {
1471 const int allocated_blocks = display_allocated_blocks(check_point);
1472 if (allocated_blocks) {
1473 free_allocated_blocks(check_point);
1474 print_error("ERROR: %s leaked %d block(s)\n", test_name,
1481 void _fail(const char * const file, const int line) {
1482 print_error("ERROR: " SOURCE_LOCATION_FORMAT " Failure!\n", file, line);
1488 static void exception_handler(int sig) {
1490 print_error("%d\n", sig);
1492 print_error("%s\n", strsignal(sig));
1499 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
1500 EXCEPTION_RECORD * const exception_record =
1501 exception_pointers->ExceptionRecord;
1502 const DWORD code = exception_record->ExceptionCode;
1504 for (i = 0; i < ARRAY_LENGTH(exception_codes); i++) {
1505 const ExceptionCodeInfo * const code_info = &exception_codes[i];
1506 if (code == code_info->code) {
1507 static int shown_debug_message = 0;
1509 print_error("%s occurred at 0x%08x.\n", code_info->description,
1510 exception_record->ExceptionAddress);
1511 if (!shown_debug_message) {
1514 "To debug in Visual Studio...\n"
1515 "1. Select menu item File->Open Project\n"
1516 "2. Change 'Files of type' to 'Executable Files'\n"
1517 "3. Open this executable.\n"
1518 "4. Select menu item Debug->Start\n"
1520 "Alternatively, set the environment variable \n"
1521 "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
1522 "then click 'Debug' in the popup dialog box.\n"
1524 shown_debug_message = 1;
1527 return EXCEPTION_EXECUTE_HANDLER;
1530 return EXCEPTION_CONTINUE_SEARCH;
1535 // Standard output and error print methods.
1536 void vprint_message(const char* const format, va_list args) {
1538 vsnprintf(buffer, sizeof(buffer), format, args);
1542 OutputDebugString(buffer);
1547 void vprint_error(const char* const format, va_list args) {
1549 vsnprintf(buffer, sizeof(buffer), format, args);
1550 fprintf(stderr, buffer);
1553 OutputDebugString(buffer);
1558 void print_message(const char* const format, ...) {
1560 va_start(args, format);
1561 vprint_message(format, args);
1566 void print_error(const char* const format, ...) {
1568 va_start(args, format);
1569 vprint_error(format, args);
1575 const char * const function_name, const UnitTestFunction Function,
1576 void ** const state, const UnitTestFunctionType function_type,
1577 const void* const heap_check_point) {
1578 const ListNode * const check_point = heap_check_point ?
1579 heap_check_point : check_point_allocated_blocks();
1580 void *current_state = NULL;
1582 int handle_exceptions = 1;
1584 handle_exceptions = !IsDebuggerPresent();
1586 #if UNIT_TESTING_DEBUG
1587 handle_exceptions = 0;
1588 #endif // UNIT_TESTING_DEBUG
1590 if (handle_exceptions) {
1593 for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) {
1594 default_signal_functions[i] = signal(
1595 exception_signals[i], exception_handler);
1598 previous_exception_filter = SetUnhandledExceptionFilter(
1603 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
1604 print_message("[ RUN ] %s\n", function_name);
1606 initialize_testing(function_name);
1607 global_running_test = 1;
1608 if (setjmp(global_run_test_env) == 0) {
1609 Function(state ? state : ¤t_state);
1610 fail_if_leftover_values(function_name);
1612 /* If this is a setup function then ignore any allocated blocks
1613 * only ensure they're deallocated on tear down. */
1614 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
1615 fail_if_blocks_allocated(check_point, function_name);
1618 global_running_test = 0;
1620 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
1621 print_message("[ OK ] %s\n", function_name);
1625 global_running_test = 0;
1626 print_message("[ FAILED ] %s\n", function_name);
1628 teardown_testing(function_name);
1630 if (handle_exceptions) {
1633 for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) {
1634 signal(exception_signals[i], default_signal_functions[i]);
1637 if (previous_exception_filter) {
1638 SetUnhandledExceptionFilter(previous_exception_filter);
1639 previous_exception_filter = NULL;
1648 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
1649 // Whether to execute the next test.
1650 int run_next_test = 1;
1651 // Whether the previous test failed.
1652 int previous_test_failed = 0;
1653 // Check point of the heap state.
1654 const ListNode * const check_point = check_point_allocated_blocks();
1655 // Current test being executed.
1656 size_t current_test = 0;
1657 // Number of tests executed.
1658 size_t tests_executed = 0;
1659 // Number of failed tests.
1660 size_t total_failed = 0;
1661 // Number of setup functions.
1663 // Number of teardown functions.
1664 size_t teardowns = 0;
1665 /* A stack of test states. A state is pushed on the stack
1666 * when a test setup occurs and popped on tear down. */
1667 TestState* test_states = malloc(number_of_tests * sizeof(*test_states));
1668 size_t number_of_test_states = 0;
1669 // Names of the tests that failed.
1670 const char** failed_names = malloc(number_of_tests *
1671 sizeof(*failed_names));
1672 void **current_state = NULL;
1674 print_message("[==========] Running %d test(s).\n", number_of_tests);
1676 // Make sure LargestIntegralType is at least the size of a pointer.
1677 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
1679 while (current_test < number_of_tests) {
1680 const ListNode *test_check_point = NULL;
1681 TestState *current_TestState;
1682 const UnitTest * const test = &tests[current_test++];
1683 if (!test->function) {
1687 switch (test->function_type) {
1688 case UNIT_TEST_FUNCTION_TYPE_TEST:
1691 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
1692 // Checkpoint the heap before the setup.
1693 current_TestState = &test_states[number_of_test_states++];
1694 current_TestState->check_point = check_point_allocated_blocks();
1695 test_check_point = current_TestState->check_point;
1696 current_state = ¤t_TestState->state;
1697 *current_state = NULL;
1702 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1703 // Check the heap based on the last setup checkpoint.
1704 assert_true(number_of_test_states);
1705 current_TestState = &test_states[--number_of_test_states];
1706 test_check_point = current_TestState->check_point;
1707 current_state = ¤t_TestState->state;
1711 print_error("Invalid unit test function type %d\n",
1712 test->function_type);
1717 if (run_next_test) {
1718 int failed = _run_test(test->name, test->function, current_state,
1719 test->function_type, test_check_point);
1721 failed_names[total_failed] = test->name;
1724 switch (test->function_type) {
1725 case UNIT_TEST_FUNCTION_TYPE_TEST:
1726 previous_test_failed = failed;
1727 total_failed += failed;
1731 case UNIT_TEST_FUNCTION_TYPE_SETUP:
1735 // Skip forward until the next test or setup function.
1738 previous_test_failed = 0;
1741 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1742 // If this test failed.
1743 if (failed && !previous_test_failed) {
1749 assert_false("BUG: shouldn't be here!");
1756 print_message("[==========] %d test(s) run.\n", tests_executed);
1757 print_error("[ PASSED ] %d test(s).\n", tests_executed - total_failed);
1761 print_error("[ FAILED ] %d test(s), listed below:\n", total_failed);
1762 for (i = 0; i < total_failed; i++) {
1763 print_error("[ FAILED ] %s\n", failed_names[i]);
1766 print_error("\n %d FAILED TEST(S)\n", total_failed);
1769 if (number_of_test_states) {
1770 print_error("[ ERROR ] Mismatched number of setup %d and "
1771 "teardown %d functions\n", setups, teardowns);
1776 free((void*)failed_names);
1778 fail_if_blocks_allocated(check_point, "run_tests");
1779 return (int)total_failed;