2 * Copyright 2008 Google Inc.
3 * Copyright 2014-2015 Andreas Schneider <asn@cryptomilk.org>
4 * Copyright 2015 Jakub Hrozek <jakub.hrozek@posteo.se>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #ifdef HAVE_INTTYPES_H
48 * This allows to add a platform specific header file. Some embedded platforms
49 * sometimes miss certain types and definitions.
53 * typedef unsigned long int uintptr_t
54 * #define _UINTPTR_T 1
55 * #define _UINTPTR_T_DEFINED 1
57 #ifdef CMOCKA_PLATFORM_INCLUDE
58 # include "cmocka_platform.h"
59 #endif /* CMOCKA_PLATFORM_INCLUDE */
62 #include <cmocka_private.h>
64 /* Size of guard bytes around dynamically allocated blocks. */
65 #define MALLOC_GUARD_SIZE 16
66 /* Pattern used to initialize guard blocks. */
67 #define MALLOC_GUARD_PATTERN 0xEF
68 /* Pattern used to initialize memory allocated with test_malloc(). */
69 #define MALLOC_ALLOC_PATTERN 0xBA
70 #define MALLOC_FREE_PATTERN 0xCD
71 /* Alignment of allocated blocks. NOTE: This must be base2. */
72 #define MALLOC_ALIGNMENT sizeof(size_t)
74 /* Printf formatting for source code locations. */
75 #define SOURCE_LOCATION_FORMAT "%s:%u"
77 #if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
78 # define CMOCKA_THREAD __thread
79 #elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE)
80 # define CMOCKA_THREAD __declspec(thread)
82 # define CMOCKA_THREAD
85 #ifdef HAVE_CLOCK_GETTIME_REALTIME
86 #define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts))
88 #define CMOCKA_CLOCK_GETTIME(clock_id, ts)
92 * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp.
94 #ifdef HAVE_SIGLONGJMP
95 # define cm_jmp_buf sigjmp_buf
96 # define cm_setjmp(env) sigsetjmp(env, 1)
97 # define cm_longjmp(env, val) siglongjmp(env, val)
99 # define cm_jmp_buf jmp_buf
100 # define cm_setjmp(env) setjmp(env)
101 # define cm_longjmp(env, val) longjmp(env, val)
106 * Declare and initialize the pointer member of ValuePointer variable name
109 #define declare_initialize_value_pointer_pointer(name, ptr) \
110 ValuePointer name ; \
112 name.x.pointer = (void*)(ptr)
115 * Declare and initialize the value member of ValuePointer variable name
118 #define declare_initialize_value_pointer_value(name, val) \
119 ValuePointer name ; \
122 /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */
123 #define cast_largest_integral_type_to_pointer( \
124 pointer_type, largest_integral_type) \
125 ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer)
127 /* Used to cast LargetIntegralType to void* and vice versa. */
128 typedef union ValuePointer {
129 LargestIntegralType value;
131 #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
132 unsigned int padding;
138 /* Doubly linked list node. */
139 typedef struct ListNode {
142 struct ListNode *next;
143 struct ListNode *prev;
146 /* Debug information for malloc(). */
147 typedef struct MallocBlockInfo {
148 void* block; /* Address of the block returned by malloc(). */
149 size_t allocated_size; /* Total size of the allocated block. */
150 size_t size; /* Request block size. */
151 SourceLocation location; /* Where the block was allocated. */
152 ListNode node; /* Node within list of all allocated blocks. */
155 /* State of each test. */
156 typedef struct TestState {
157 const ListNode *check_point; /* Check point of the test if there's a */
158 /* setup function. */
159 void *state; /* State associated with the test. */
162 /* Determines whether two values are the same. */
163 typedef int (*EqualityFunction)(const void *left, const void *right);
165 /* Value of a symbol and the place it was declared. */
166 typedef struct SymbolValue {
167 SourceLocation location;
168 LargestIntegralType value;
172 * Contains a list of values for a symbol.
173 * NOTE: Each structure referenced by symbol_values_list_head must have a
174 * SourceLocation as its' first member.
176 typedef struct SymbolMapValue {
177 const char *symbol_name;
178 ListNode symbol_values_list_head;
181 /* Where a particular ordering was located and its symbol name */
182 typedef struct FuncOrderingValue {
183 SourceLocation location;
184 const char * function;
187 /* Used by list_free() to deallocate values referenced by list nodes. */
188 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
190 /* Structure used to check the range of integer types.a */
191 typedef struct CheckIntegerRange {
192 CheckParameterEvent event;
193 LargestIntegralType minimum;
194 LargestIntegralType maximum;
197 /* Structure used to check whether an integer value is in a set. */
198 typedef struct CheckIntegerSet {
199 CheckParameterEvent event;
200 const LargestIntegralType *set;
204 /* Used to check whether a parameter matches the area of memory referenced by
206 typedef struct CheckMemoryData {
207 CheckParameterEvent event;
212 static ListNode* list_initialize(ListNode * const node);
213 static ListNode* list_add(ListNode * const head, ListNode *new_node);
214 static ListNode* list_add_value(ListNode * const head, const void *value,
216 static ListNode* list_remove(
217 ListNode * const node, const CleanupListValue cleanup_value,
218 void * const cleanup_value_data);
219 static void list_remove_free(
220 ListNode * const node, const CleanupListValue cleanup_value,
221 void * const cleanup_value_data);
222 static int list_empty(const ListNode * const head);
223 static int list_find(
224 ListNode * const head, const void *value,
225 const EqualityFunction equal_func, ListNode **output);
226 static int list_first(ListNode * const head, ListNode **output);
227 static ListNode* list_free(
228 ListNode * const head, const CleanupListValue cleanup_value,
229 void * const cleanup_value_data);
231 static void add_symbol_value(
232 ListNode * const symbol_map_head, const char * const symbol_names[],
233 const size_t number_of_symbol_names, const void* value, const int count);
234 static int get_symbol_value(
235 ListNode * const symbol_map_head, const char * const symbol_names[],
236 const size_t number_of_symbol_names, void **output);
237 static void free_value(const void *value, void *cleanup_value_data);
238 static void free_symbol_map_value(
239 const void *value, void *cleanup_value_data);
240 static void remove_always_return_values(ListNode * const map_head,
241 const size_t number_of_symbol_names);
243 static int check_for_leftover_values_list(const ListNode * head,
244 const char * const error_message);
246 static int check_for_leftover_values(
247 const ListNode * const map_head, const char * const error_message,
248 const size_t number_of_symbol_names);
250 static void remove_always_return_values_from_list(ListNode * const map_head);
253 * This must be called at the beginning of a test to initialize some data
256 static void initialize_testing(const char *test_name);
258 /* This must be called at the end of a test to free() allocated structures. */
259 static void teardown_testing(const char *test_name);
261 static enum cm_message_output cm_get_output(void);
263 static int cm_error_message_enabled = 1;
264 static CMOCKA_THREAD char *cm_error_message;
266 void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
269 * Keeps track of the calling context returned by setenv() so that the fail()
270 * method can jump out of a test.
272 static CMOCKA_THREAD cm_jmp_buf global_run_test_env;
273 static CMOCKA_THREAD int global_running_test = 0;
275 /* Keeps track of the calling context returned by setenv() so that */
276 /* mock_assert() can optionally jump back to expect_assert_failure(). */
277 jmp_buf global_expect_assert_env;
278 int global_expecting_assert = 0;
279 const char *global_last_failed_assert = NULL;
280 static int global_skip_test;
282 /* Keeps a map of the values that functions will have to return to provide */
283 /* mocked interfaces. */
284 static CMOCKA_THREAD ListNode global_function_result_map_head;
285 /* Location of the last mock value returned was declared. */
286 static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
288 /* Keeps a map of the values that functions expect as parameters to their
289 * mocked interfaces. */
290 static CMOCKA_THREAD ListNode global_function_parameter_map_head;
291 /* Location of last parameter value checked was declared. */
292 static CMOCKA_THREAD SourceLocation global_last_parameter_location;
294 /* List (acting as FIFO) of call ordering. */
295 static CMOCKA_THREAD ListNode global_call_ordering_head;
296 /* Location of last call ordering that was declared. */
297 static CMOCKA_THREAD SourceLocation global_last_call_ordering_location;
299 /* List of all currently allocated blocks. */
300 static CMOCKA_THREAD ListNode global_allocated_blocks;
302 static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
305 /* Signals caught by exception_handler(). */
306 static const int exception_signals[] = {
318 /* Default signal functions that should be restored after a test is complete. */
319 typedef void (*SignalFunction)(int signal);
320 static SignalFunction default_signal_functions[
321 ARRAY_SIZE(exception_signals)];
325 /* The default exception filter. */
326 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
328 /* Fatal exceptions. */
329 typedef struct ExceptionCodeInfo {
331 const char* description;
334 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
336 static const ExceptionCodeInfo exception_codes[] = {
337 EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
338 EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
339 EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
340 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
341 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
342 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
343 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
344 EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
345 EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
346 EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
347 EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
348 EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
349 EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
350 EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
351 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
352 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
353 EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
354 EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
355 EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
356 EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
360 enum CMUnitTestStatus {
368 struct CMUnitTestState {
369 const ListNode *check_point; /* Check point of the test if there's a setup function. */
370 const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
371 void *state; /* State associated with the test */
372 const char *error_message; /* The error messages by the test */
373 enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
374 double runtime; /* Time calculations */
377 /* Exit the currently executing test. */
378 static void exit_test(const int quit_application)
380 const char *abort_test = getenv("CMOCKA_TEST_ABORT");
382 if (abort_test != NULL && abort_test[0] == '1') {
383 print_error("%s", cm_error_message);
385 } else if (global_running_test) {
386 cm_longjmp(global_run_test_env, 1);
387 } else if (quit_application) {
392 void _skip(const char * const file, const int line)
394 cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
395 global_skip_test = 1;
399 /* Initialize a SourceLocation structure. */
400 static void initialize_source_location(SourceLocation * const location) {
401 assert_non_null(location);
402 location->file = NULL;
407 /* Determine whether a source location is currently set. */
408 static int source_location_is_set(const SourceLocation * const location) {
409 assert_non_null(location);
410 return location->file && location->line;
414 /* Set a source location. */
415 static void set_source_location(
416 SourceLocation * const location, const char * const file,
418 assert_non_null(location);
419 location->file = file;
420 location->line = line;
424 /* Create function results and expected parameter lists. */
425 void initialize_testing(const char *test_name) {
427 list_initialize(&global_function_result_map_head);
428 initialize_source_location(&global_last_mock_value_location);
429 list_initialize(&global_function_parameter_map_head);
430 initialize_source_location(&global_last_parameter_location);
431 list_initialize(&global_call_ordering_head);
432 initialize_source_location(&global_last_parameter_location);
436 static void fail_if_leftover_values(const char *test_name) {
437 int error_occurred = 0;
439 remove_always_return_values(&global_function_result_map_head, 1);
440 if (check_for_leftover_values(
441 &global_function_result_map_head,
442 "%s() has remaining non-returned values.\n", 1)) {
446 remove_always_return_values(&global_function_parameter_map_head, 2);
447 if (check_for_leftover_values(
448 &global_function_parameter_map_head,
449 "%s parameter still has values that haven't been checked.\n", 2)) {
453 remove_always_return_values_from_list(&global_call_ordering_head);
454 if (check_for_leftover_values_list(&global_call_ordering_head,
455 "%s function was expected to be called but was not not.\n")) {
458 if (error_occurred) {
464 static void teardown_testing(const char *test_name) {
466 list_free(&global_function_result_map_head, free_symbol_map_value,
468 initialize_source_location(&global_last_mock_value_location);
469 list_free(&global_function_parameter_map_head, free_symbol_map_value,
471 initialize_source_location(&global_last_parameter_location);
472 list_free(&global_call_ordering_head, free_value,
474 initialize_source_location(&global_last_call_ordering_location);
477 /* Initialize a list node. */
478 static ListNode* list_initialize(ListNode * const node) {
488 * Adds a value at the tail of a given list.
489 * The node referencing the value is allocated from the heap.
491 static ListNode* list_add_value(ListNode * const head, const void *value,
492 const int refcount) {
493 ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
494 assert_non_null(head);
495 assert_non_null(value);
496 new_node->value = value;
497 new_node->refcount = refcount;
498 return list_add(head, new_node);
502 /* Add new_node to the end of the list. */
503 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
504 assert_non_null(head);
505 assert_non_null(new_node);
506 new_node->next = head;
507 new_node->prev = head->prev;
508 head->prev->next = new_node;
509 head->prev = new_node;
514 /* Remove a node from a list. */
515 static ListNode* list_remove(
516 ListNode * const node, const CleanupListValue cleanup_value,
517 void * const cleanup_value_data) {
518 assert_non_null(node);
519 node->prev->next = node->next;
520 node->next->prev = node->prev;
522 cleanup_value(node->value, cleanup_value_data);
528 /* Remove a list node from a list and free the node. */
529 static void list_remove_free(
530 ListNode * const node, const CleanupListValue cleanup_value,
531 void * const cleanup_value_data) {
532 assert_non_null(node);
533 free(list_remove(node, cleanup_value, cleanup_value_data));
538 * Frees memory kept by a linked list The cleanup_value function is called for
539 * every "value" field of nodes in the list, except for the head. In addition
540 * to each list value, cleanup_value_data is passed to each call to
541 * cleanup_value. The head of the list is not deallocated.
543 static ListNode* list_free(
544 ListNode * const head, const CleanupListValue cleanup_value,
545 void * const cleanup_value_data) {
546 assert_non_null(head);
547 while (!list_empty(head)) {
548 list_remove_free(head->next, cleanup_value, cleanup_value_data);
554 /* Determine whether a list is empty. */
555 static int list_empty(const ListNode * const head) {
556 assert_non_null(head);
557 return head->next == head;
562 * Find a value in the list using the equal_func to compare each node with the
565 static int list_find(ListNode * const head, const void *value,
566 const EqualityFunction equal_func, ListNode **output) {
568 assert_non_null(head);
569 for (current = head->next; current != head; current = current->next) {
570 if (equal_func(current->value, value)) {
578 /* Returns the first node of a list */
579 static int list_first(ListNode * const head, ListNode **output) {
580 ListNode *target_node;
581 assert_non_null(head);
582 if (list_empty(head)) {
585 target_node = head->next;
586 *output = target_node;
591 /* Deallocate a value referenced by a list. */
592 static void free_value(const void *value, void *cleanup_value_data) {
593 (void)cleanup_value_data;
594 assert_non_null(value);
599 /* Releases memory associated to a symbol_map_value. */
600 static void free_symbol_map_value(const void *value,
601 void *cleanup_value_data) {
602 SymbolMapValue * const map_value = (SymbolMapValue*)value;
603 const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
604 assert_non_null(value);
605 list_free(&map_value->symbol_values_list_head,
606 children ? free_symbol_map_value : free_value,
607 (void *) ((uintptr_t)children - 1));
613 * Determine whether a symbol name referenced by a symbol_map_value matches the
614 * specified function name.
616 static int symbol_names_match(const void *map_value, const void *symbol) {
617 return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
618 (const char*)symbol);
622 * Adds a value to the queue of values associated with the given hierarchy of
623 * symbols. It's assumed value is allocated from the heap.
625 static void add_symbol_value(ListNode * const symbol_map_head,
626 const char * const symbol_names[],
627 const size_t number_of_symbol_names,
628 const void* value, const int refcount) {
629 const char* symbol_name;
630 ListNode *target_node;
631 SymbolMapValue *target_map_value;
632 assert_non_null(symbol_map_head);
633 assert_non_null(symbol_names);
634 assert_true(number_of_symbol_names);
635 symbol_name = symbol_names[0];
637 if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
639 SymbolMapValue * const new_symbol_map_value =
640 (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
641 new_symbol_map_value->symbol_name = symbol_name;
642 list_initialize(&new_symbol_map_value->symbol_values_list_head);
643 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
647 target_map_value = (SymbolMapValue*)target_node->value;
648 if (number_of_symbol_names == 1) {
649 list_add_value(&target_map_value->symbol_values_list_head,
652 add_symbol_value(&target_map_value->symbol_values_list_head,
653 &symbol_names[1], number_of_symbol_names - 1, value,
660 * Gets the next value associated with the given hierarchy of symbols.
661 * The value is returned as an output parameter with the function returning the
662 * node's old refcount value if a value is found, 0 otherwise. This means that
663 * a return value of 1 indicates the node was just removed from the list.
665 static int get_symbol_value(
666 ListNode * const head, const char * const symbol_names[],
667 const size_t number_of_symbol_names, void **output) {
668 const char* symbol_name;
669 ListNode *target_node;
670 assert_non_null(head);
671 assert_non_null(symbol_names);
672 assert_true(number_of_symbol_names);
673 assert_non_null(output);
674 symbol_name = symbol_names[0];
676 if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
677 SymbolMapValue *map_value;
678 ListNode *child_list;
679 int return_value = 0;
680 assert_non_null(target_node);
681 assert_non_null(target_node->value);
683 map_value = (SymbolMapValue*)target_node->value;
684 child_list = &map_value->symbol_values_list_head;
686 if (number_of_symbol_names == 1) {
687 ListNode *value_node = NULL;
688 return_value = list_first(child_list, &value_node);
689 assert_true(return_value);
690 *output = (void*) value_node->value;
691 return_value = value_node->refcount;
692 if (value_node->refcount - 1 == 0) {
693 list_remove_free(value_node, NULL, NULL);
694 } else if (value_node->refcount > -2) {
695 --value_node->refcount;
698 return_value = get_symbol_value(
699 child_list, &symbol_names[1], number_of_symbol_names - 1,
702 if (list_empty(child_list)) {
703 list_remove_free(target_node, free_symbol_map_value, (void*)0);
707 cm_print_error("No entries for symbol %s.\n", symbol_name);
713 * Taverse a list of nodes and remove first symbol value in list that has a
714 * refcount < -1 (i.e. should always be returned and has been returned at
718 static void remove_always_return_values_from_list(ListNode * const map_head)
720 ListNode * current = NULL;
721 ListNode * next = NULL;
722 assert_non_null(map_head);
724 for (current = map_head->next, next = current->next;
726 current = next, next = current->next) {
727 if (current->refcount < -1) {
728 list_remove_free(current, free_value, NULL);
734 * Traverse down a tree of symbol values and remove the first symbol value
735 * in each branch that has a refcount < -1 (i.e should always be returned
736 * and has been returned at least once).
738 static void remove_always_return_values(ListNode * const map_head,
739 const size_t number_of_symbol_names) {
741 assert_non_null(map_head);
742 assert_true(number_of_symbol_names);
743 current = map_head->next;
744 while (current != map_head) {
745 SymbolMapValue * const value = (SymbolMapValue*)current->value;
746 ListNode * const next = current->next;
747 ListNode *child_list;
748 assert_non_null(value);
749 child_list = &value->symbol_values_list_head;
751 if (!list_empty(child_list)) {
752 if (number_of_symbol_names == 1) {
753 ListNode * const child_node = child_list->next;
754 /* If this item has been returned more than once, free it. */
755 if (child_node->refcount < -1) {
756 list_remove_free(child_node, free_value, NULL);
759 remove_always_return_values(child_list,
760 number_of_symbol_names - 1);
764 if (list_empty(child_list)) {
765 list_remove_free(current, free_value, NULL);
771 static int check_for_leftover_values_list(const ListNode * head,
772 const char * const error_message)
774 ListNode *child_node;
775 int leftover_count = 0;
776 if (!list_empty(head))
778 for (child_node = head->next; child_node != head;
779 child_node = child_node->next, ++leftover_count) {
780 const FuncOrderingValue *const o =
781 (const FuncOrderingValue*) child_node->value;
782 cm_print_error(error_message, o->function);
783 cm_print_error(SOURCE_LOCATION_FORMAT
784 ": note: remaining item was declared here\n",
785 o->location.file, o->location.line);
788 return leftover_count;
792 * Checks if there are any leftover values set up by the test that were never
793 * retrieved through execution, and fail the test if that is the case.
795 static int check_for_leftover_values(
796 const ListNode * const map_head, const char * const error_message,
797 const size_t number_of_symbol_names) {
798 const ListNode *current;
799 int symbols_with_leftover_values = 0;
800 assert_non_null(map_head);
801 assert_true(number_of_symbol_names);
803 for (current = map_head->next; current != map_head;
804 current = current->next) {
805 const SymbolMapValue * const value =
806 (SymbolMapValue*)current->value;
807 const ListNode *child_list;
808 assert_non_null(value);
809 child_list = &value->symbol_values_list_head;
811 if (!list_empty(child_list)) {
812 if (number_of_symbol_names == 1) {
813 const ListNode *child_node;
814 cm_print_error(error_message, value->symbol_name);
816 for (child_node = child_list->next; child_node != child_list;
817 child_node = child_node->next) {
818 const SourceLocation * const location =
819 (const SourceLocation*)child_node->value;
820 cm_print_error(SOURCE_LOCATION_FORMAT
821 ": note: remaining item was declared here\n",
822 location->file, location->line);
825 cm_print_error("%s.", value->symbol_name);
826 check_for_leftover_values(child_list, error_message,
827 number_of_symbol_names - 1);
829 symbols_with_leftover_values ++;
832 return symbols_with_leftover_values;
836 /* Get the next return value for the specified mock function. */
837 LargestIntegralType _mock(const char * const function, const char* const file,
840 const int rc = get_symbol_value(&global_function_result_map_head,
841 &function, 1, &result);
843 SymbolValue * const symbol = (SymbolValue*)result;
844 const LargestIntegralType value = symbol->value;
845 global_last_mock_value_location = symbol->location;
851 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
852 "to mock function %s\n", file, line, function);
853 if (source_location_is_set(&global_last_mock_value_location)) {
854 cm_print_error(SOURCE_LOCATION_FORMAT
855 ": note: Previously returned mock value was declared here\n",
856 global_last_mock_value_location.file,
857 global_last_mock_value_location.line);
859 cm_print_error("There were no previously returned mock values for "
867 /* Ensure that function is being called in proper order */
868 void _function_called(const char *const function,
869 const char *const file,
872 ListNode *first_value_node = NULL;
873 ListNode *value_node = NULL;
874 FuncOrderingValue *expected_call;
877 rc = list_first(&global_call_ordering_head, &value_node);
878 first_value_node = value_node;
882 expected_call = (FuncOrderingValue *)value_node->value;
883 cmp = strcmp(expected_call->function, function);
884 if (value_node->refcount < -1) {
886 * Search through value nodes until either function is found or
887 * encounter a non-zero refcount greater than -2
890 value_node = value_node->next;
891 expected_call = (FuncOrderingValue *)value_node->value;
893 cmp = strcmp(expected_call->function, function);
894 while (value_node->refcount < -1 &&
896 value_node != first_value_node->prev) {
897 value_node = value_node->next;
898 if (value_node == NULL) {
901 expected_call = (FuncOrderingValue *)value_node->value;
902 if (expected_call == NULL) {
905 cmp = strcmp(expected_call->function, function);
908 if (value_node == first_value_node->prev) {
909 cm_print_error(SOURCE_LOCATION_FORMAT
910 ": error: No expected mock calls matching "
911 "called() invocation in %s",
920 if (value_node->refcount > -2 && --value_node->refcount == 0) {
921 list_remove_free(value_node, free_value, NULL);
924 cm_print_error(SOURCE_LOCATION_FORMAT
925 ": error: Expected call to %s but received called() "
928 expected_call->function,
933 cm_print_error(SOURCE_LOCATION_FORMAT
934 ": error: No mock calls expected but called() was "
942 /* Add a return value for the specified mock function name. */
943 void _will_return(const char * const function_name, const char * const file,
944 const int line, const LargestIntegralType value,
946 SymbolValue * const return_value =
947 (SymbolValue*)malloc(sizeof(*return_value));
948 assert_true(count != 0);
949 return_value->value = value;
950 set_source_location(&return_value->location, file, line);
951 add_symbol_value(&global_function_result_map_head, &function_name, 1,
952 return_value, count);
957 * Add a custom parameter checking function. If the event parameter is NULL
958 * the event structure is allocated internally by this function. If event
959 * parameter is provided it must be allocated on the heap and doesn't need to
960 * be deallocated by the caller.
963 const char* const function, const char* const parameter,
964 const char* const file, const int line,
965 const CheckParameterValue check_function,
966 const LargestIntegralType check_data,
967 CheckParameterEvent * const event, const int count) {
968 CheckParameterEvent * const check =
969 event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
970 const char* symbols[] = {function, parameter};
971 check->parameter_name = parameter;
972 check->check_value = check_function;
973 check->check_value_data = check_data;
974 set_source_location(&check->location, file, line);
975 add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
980 * Add an call expectations that a particular function is called correctly.
981 * This is used for code under test that makes calls to several functions
982 * in depended upon components (mocks).
985 void _expect_function_call(
986 const char * const function_name,
987 const char * const file,
991 FuncOrderingValue *ordering;
993 assert_non_null(function_name);
994 assert_non_null(file);
995 assert_true(count != 0);
997 ordering = (FuncOrderingValue *)malloc(sizeof(*ordering));
999 set_source_location(&ordering->location, file, line);
1000 ordering->function = function_name;
1002 list_add_value(&global_call_ordering_head, ordering, count);
1005 /* Returns 1 if the specified values are equal. If the values are not equal
1006 * an error is displayed and 0 is returned. */
1007 static int values_equal_display_error(const LargestIntegralType left,
1008 const LargestIntegralType right) {
1009 const int equal = left == right;
1011 cm_print_error(LargestIntegralTypePrintfFormat " != "
1012 LargestIntegralTypePrintfFormat "\n", left, right);
1018 * Returns 1 if the specified values are not equal. If the values are equal
1019 * an error is displayed and 0 is returned. */
1020 static int values_not_equal_display_error(const LargestIntegralType left,
1021 const LargestIntegralType right) {
1022 const int not_equal = left != right;
1024 cm_print_error(LargestIntegralTypePrintfFormat " == "
1025 LargestIntegralTypePrintfFormat "\n", left, right);
1032 * Determine whether value is contained within check_integer_set.
1033 * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
1034 * returned and an error is displayed. If invert is 1 and the value is not
1035 * in the set 1 is returned, otherwise 0 is returned and an error is
1038 static int value_in_set_display_error(
1039 const LargestIntegralType value,
1040 const CheckIntegerSet * const check_integer_set, const int invert) {
1041 int succeeded = invert;
1042 assert_non_null(check_integer_set);
1044 const LargestIntegralType * const set = check_integer_set->set;
1045 const size_t size_of_set = check_integer_set->size_of_set;
1047 for (i = 0; i < size_of_set; i++) {
1048 if (set[i] == value) {
1049 /* If invert = 0 and item is found, succeeded = 1. */
1050 /* If invert = 1 and item is found, succeeded = 0. */
1051 succeeded = !succeeded;
1058 cm_print_error("%" PRIu64 " is %sin the set (", value,
1059 invert ? "" : "not ");
1060 for (i = 0; i < size_of_set; i++) {
1061 cm_print_error("%" PRIu64 ", ", set[i]);
1063 cm_print_error(")\n");
1070 * Determine whether a value is within the specified range. If the value is
1071 * within the specified range 1 is returned. If the value isn't within the
1072 * specified range an error is displayed and 0 is returned.
1074 static int integer_in_range_display_error(
1075 const LargestIntegralType value, const LargestIntegralType range_min,
1076 const LargestIntegralType range_max) {
1077 if (value >= range_min && value <= range_max) {
1080 cm_print_error("%" PRIu64 " is not within the range %" PRIu64 "-%" PRIu64 "\n",
1081 value, range_min, range_max);
1087 * Determine whether a value is within the specified range. If the value
1088 * is not within the range 1 is returned. If the value is within the
1089 * specified range an error is displayed and zero is returned.
1091 static int integer_not_in_range_display_error(
1092 const LargestIntegralType value, const LargestIntegralType range_min,
1093 const LargestIntegralType range_max) {
1094 if (value < range_min || value > range_max) {
1097 cm_print_error("%" PRIu64 " is within the range %" PRIu64 "-%" PRIu64 "\n",
1098 value, range_min, range_max);
1104 * Determine whether the specified strings are equal. If the strings are equal
1105 * 1 is returned. If they're not equal an error is displayed and 0 is
1108 static int string_equal_display_error(
1109 const char * const left, const char * const right) {
1110 if (strcmp(left, right) == 0) {
1113 cm_print_error("\"%s\" != \"%s\"\n", left, right);
1119 * Determine whether the specified strings are equal. If the strings are not
1120 * equal 1 is returned. If they're not equal an error is displayed and 0 is
1123 static int string_not_equal_display_error(
1124 const char * const left, const char * const right) {
1125 if (strcmp(left, right) != 0) {
1128 cm_print_error("\"%s\" == \"%s\"\n", left, right);
1134 * Determine whether the specified areas of memory are equal. If they're equal
1135 * 1 is returned otherwise an error is displayed and 0 is returned.
1137 static int memory_equal_display_error(const char* const a, const char* const b,
1138 const size_t size) {
1139 int differences = 0;
1141 for (i = 0; i < size; i++) {
1142 const char l = a[i];
1143 const char r = b[i];
1145 cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
1151 cm_print_error("%d bytes of %p and %p differ\n",
1152 differences, (void *)a, (void *)b);
1160 * Determine whether the specified areas of memory are not equal. If they're
1161 * not equal 1 is returned otherwise an error is displayed and 0 is
1164 static int memory_not_equal_display_error(
1165 const char* const a, const char* const b, const size_t size) {
1168 for (i = 0; i < size; i++) {
1169 const char l = a[i];
1170 const char r = b[i];
1176 cm_print_error("%"PRIdS "bytes of %p and %p the same\n",
1177 same, (void *)a, (void *)b);
1184 /* CheckParameterValue callback to check whether a value is within a set. */
1185 static int check_in_set(const LargestIntegralType value,
1186 const LargestIntegralType check_value_data) {
1187 return value_in_set_display_error(value,
1188 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1189 check_value_data), 0);
1193 /* CheckParameterValue callback to check whether a value isn't within a set. */
1194 static int check_not_in_set(const LargestIntegralType value,
1195 const LargestIntegralType check_value_data) {
1196 return value_in_set_display_error(value,
1197 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1198 check_value_data), 1);
1202 /* Create the callback data for check_in_set() or check_not_in_set() and
1203 * register a check event. */
1204 static void expect_set(
1205 const char* const function, const char* const parameter,
1206 const char* const file, const int line,
1207 const LargestIntegralType values[], const size_t number_of_values,
1208 const CheckParameterValue check_function, const int count) {
1209 CheckIntegerSet * const check_integer_set =
1210 (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
1211 (sizeof(values[0]) * number_of_values));
1212 LargestIntegralType * const set = (LargestIntegralType*)(
1213 check_integer_set + 1);
1214 declare_initialize_value_pointer_pointer(check_data, check_integer_set);
1215 assert_non_null(values);
1216 assert_true(number_of_values);
1217 memcpy(set, values, number_of_values * sizeof(values[0]));
1218 check_integer_set->set = set;
1219 check_integer_set->size_of_set = number_of_values;
1221 function, parameter, file, line, check_function,
1222 check_data.value, &check_integer_set->event, count);
1226 /* Add an event to check whether a value is in a set. */
1227 void _expect_in_set(
1228 const char* const function, const char* const parameter,
1229 const char* const file, const int line,
1230 const LargestIntegralType values[], const size_t number_of_values,
1232 expect_set(function, parameter, file, line, values, number_of_values,
1233 check_in_set, count);
1237 /* Add an event to check whether a value isn't in a set. */
1238 void _expect_not_in_set(
1239 const char* const function, const char* const parameter,
1240 const char* const file, const int line,
1241 const LargestIntegralType values[], const size_t number_of_values,
1243 expect_set(function, parameter, file, line, values, number_of_values,
1244 check_not_in_set, count);
1248 /* CheckParameterValue callback to check whether a value is within a range. */
1249 static int check_in_range(const LargestIntegralType value,
1250 const LargestIntegralType check_value_data) {
1251 CheckIntegerRange * const check_integer_range =
1252 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1254 assert_non_null(check_integer_range);
1255 return integer_in_range_display_error(value, check_integer_range->minimum,
1256 check_integer_range->maximum);
1260 /* CheckParameterValue callback to check whether a value is not within a range. */
1261 static int check_not_in_range(const LargestIntegralType value,
1262 const LargestIntegralType check_value_data) {
1263 CheckIntegerRange * const check_integer_range =
1264 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1266 assert_non_null(check_integer_range);
1267 return integer_not_in_range_display_error(
1268 value, check_integer_range->minimum, check_integer_range->maximum);
1272 /* Create the callback data for check_in_range() or check_not_in_range() and
1273 * register a check event. */
1274 static void expect_range(
1275 const char* const function, const char* const parameter,
1276 const char* const file, const int line,
1277 const LargestIntegralType minimum, const LargestIntegralType maximum,
1278 const CheckParameterValue check_function, const int count) {
1279 CheckIntegerRange * const check_integer_range =
1280 (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
1281 declare_initialize_value_pointer_pointer(check_data, check_integer_range);
1282 check_integer_range->minimum = minimum;
1283 check_integer_range->maximum = maximum;
1284 _expect_check(function, parameter, file, line, check_function,
1285 check_data.value, &check_integer_range->event, count);
1289 /* Add an event to determine whether a parameter is within a range. */
1290 void _expect_in_range(
1291 const char* const function, const char* const parameter,
1292 const char* const file, const int line,
1293 const LargestIntegralType minimum, const LargestIntegralType maximum,
1295 expect_range(function, parameter, file, line, minimum, maximum,
1296 check_in_range, count);
1300 /* Add an event to determine whether a parameter is not within a range. */
1301 void _expect_not_in_range(
1302 const char* const function, const char* const parameter,
1303 const char* const file, const int line,
1304 const LargestIntegralType minimum, const LargestIntegralType maximum,
1306 expect_range(function, parameter, file, line, minimum, maximum,
1307 check_not_in_range, count);
1311 /* CheckParameterValue callback to check whether a value is equal to an
1312 * expected value. */
1313 static int check_value(const LargestIntegralType value,
1314 const LargestIntegralType check_value_data) {
1315 return values_equal_display_error(value, check_value_data);
1319 /* Add an event to check a parameter equals an expected value. */
1321 const char* const function, const char* const parameter,
1322 const char* const file, const int line,
1323 const LargestIntegralType value, const int count) {
1324 _expect_check(function, parameter, file, line, check_value, value, NULL,
1329 /* CheckParameterValue callback to check whether a value is not equal to an
1330 * expected value. */
1331 static int check_not_value(const LargestIntegralType value,
1332 const LargestIntegralType check_value_data) {
1333 return values_not_equal_display_error(value, check_value_data);
1337 /* Add an event to check a parameter is not equal to an expected value. */
1338 void _expect_not_value(
1339 const char* const function, const char* const parameter,
1340 const char* const file, const int line,
1341 const LargestIntegralType value, const int count) {
1342 _expect_check(function, parameter, file, line, check_not_value, value,
1347 /* CheckParameterValue callback to check whether a parameter equals a string. */
1348 static int check_string(const LargestIntegralType value,
1349 const LargestIntegralType check_value_data) {
1350 return string_equal_display_error(
1351 cast_largest_integral_type_to_pointer(char*, value),
1352 cast_largest_integral_type_to_pointer(char*, check_value_data));
1356 /* Add an event to check whether a parameter is equal to a string. */
1357 void _expect_string(
1358 const char* const function, const char* const parameter,
1359 const char* const file, const int line, const char* string,
1361 declare_initialize_value_pointer_pointer(string_pointer,
1362 discard_const(string));
1363 _expect_check(function, parameter, file, line, check_string,
1364 string_pointer.value, NULL, count);
1368 /* CheckParameterValue callback to check whether a parameter is not equals to
1370 static int check_not_string(const LargestIntegralType value,
1371 const LargestIntegralType check_value_data) {
1372 return string_not_equal_display_error(
1373 cast_largest_integral_type_to_pointer(char*, value),
1374 cast_largest_integral_type_to_pointer(char*, check_value_data));
1378 /* Add an event to check whether a parameter is not equal to a string. */
1379 void _expect_not_string(
1380 const char* const function, const char* const parameter,
1381 const char* const file, const int line, const char* string,
1383 declare_initialize_value_pointer_pointer(string_pointer,
1384 discard_const(string));
1385 _expect_check(function, parameter, file, line, check_not_string,
1386 string_pointer.value, NULL, count);
1389 /* CheckParameterValue callback to check whether a parameter equals an area of
1391 static int check_memory(const LargestIntegralType value,
1392 const LargestIntegralType check_value_data) {
1393 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1394 CheckMemoryData*, check_value_data);
1395 assert_non_null(check);
1396 return memory_equal_display_error(
1397 cast_largest_integral_type_to_pointer(const char*, value),
1398 (const char*)check->memory, check->size);
1402 /* Create the callback data for check_memory() or check_not_memory() and
1403 * register a check event. */
1404 static void expect_memory_setup(
1405 const char* const function, const char* const parameter,
1406 const char* const file, const int line,
1407 const void * const memory, const size_t size,
1408 const CheckParameterValue check_function, const int count) {
1409 CheckMemoryData * const check_data =
1410 (CheckMemoryData*)malloc(sizeof(*check_data) + size);
1411 void * const mem = (void*)(check_data + 1);
1412 declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1413 assert_non_null(memory);
1415 memcpy(mem, memory, size);
1416 check_data->memory = mem;
1417 check_data->size = size;
1418 _expect_check(function, parameter, file, line, check_function,
1419 check_data_pointer.value, &check_data->event, count);
1423 /* Add an event to check whether a parameter matches an area of memory. */
1424 void _expect_memory(
1425 const char* const function, const char* const parameter,
1426 const char* const file, const int line, const void* const memory,
1427 const size_t size, const int count) {
1428 expect_memory_setup(function, parameter, file, line, memory, size,
1429 check_memory, count);
1433 /* CheckParameterValue callback to check whether a parameter is not equal to
1434 * an area of memory. */
1435 static int check_not_memory(const LargestIntegralType value,
1436 const LargestIntegralType check_value_data) {
1437 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1438 CheckMemoryData*, check_value_data);
1439 assert_non_null(check);
1440 return memory_not_equal_display_error(
1441 cast_largest_integral_type_to_pointer(const char*, value),
1442 (const char*)check->memory,
1447 /* Add an event to check whether a parameter doesn't match an area of memory. */
1448 void _expect_not_memory(
1449 const char* const function, const char* const parameter,
1450 const char* const file, const int line, const void* const memory,
1451 const size_t size, const int count) {
1452 expect_memory_setup(function, parameter, file, line, memory, size,
1453 check_not_memory, count);
1457 /* CheckParameterValue callback that always returns 1. */
1458 static int check_any(const LargestIntegralType value,
1459 const LargestIntegralType check_value_data) {
1461 (void)check_value_data;
1466 /* Add an event to allow any value for a parameter. */
1468 const char* const function, const char* const parameter,
1469 const char* const file, const int line, const int count) {
1470 _expect_check(function, parameter, file, line, check_any, 0, NULL,
1475 void _check_expected(
1476 const char * const function_name, const char * const parameter_name,
1477 const char* file, const int line, const LargestIntegralType value) {
1479 const char* symbols[] = {function_name, parameter_name};
1480 const int rc = get_symbol_value(&global_function_parameter_map_head,
1481 symbols, 2, &result);
1483 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1484 int check_succeeded;
1485 global_last_parameter_location = check->location;
1486 check_succeeded = check->check_value(value, check->check_value_data);
1490 if (!check_succeeded) {
1491 cm_print_error(SOURCE_LOCATION_FORMAT
1492 ": error: Check of parameter %s, function %s failed\n"
1493 SOURCE_LOCATION_FORMAT
1494 ": note: Expected parameter declared here\n",
1496 parameter_name, function_name,
1497 global_last_parameter_location.file,
1498 global_last_parameter_location.line);
1502 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
1503 "to check parameter %s of function %s\n", file, line,
1504 parameter_name, function_name);
1505 if (source_location_is_set(&global_last_parameter_location)) {
1506 cm_print_error(SOURCE_LOCATION_FORMAT
1507 ": note: Previously declared parameter value was declared here\n",
1508 global_last_parameter_location.file,
1509 global_last_parameter_location.line);
1511 cm_print_error("There were no previously declared parameter values "
1512 "for this test.\n");
1519 /* Replacement for assert. */
1520 void mock_assert(const int result, const char* const expression,
1521 const char* const file, const int line) {
1523 if (global_expecting_assert) {
1524 global_last_failed_assert = expression;
1525 longjmp(global_expect_assert_env, result);
1527 cm_print_error("ASSERT: %s\n", expression);
1534 void _assert_true(const LargestIntegralType result,
1535 const char * const expression,
1536 const char * const file, const int line) {
1538 cm_print_error("%s\n", expression);
1543 void _assert_return_code(const LargestIntegralType result,
1545 const LargestIntegralType error,
1546 const char * const expression,
1547 const char * const file,
1550 LargestIntegralType valmax;
1561 valmax = 2147483647;
1565 if (rlen > sizeof(valmax)) {
1566 valmax = 2147483647;
1568 valmax = 9223372036854775807L;
1573 if (result > valmax - 1) {
1575 cm_print_error("%s < 0, errno(%" PRIu64 "): %s\n",
1576 expression, error, strerror((int)error));
1578 cm_print_error("%s < 0\n", expression);
1584 void _assert_int_equal(
1585 const LargestIntegralType a, const LargestIntegralType b,
1586 const char * const file, const int line) {
1587 if (!values_equal_display_error(a, b)) {
1593 void _assert_int_not_equal(
1594 const LargestIntegralType a, const LargestIntegralType b,
1595 const char * const file, const int line) {
1596 if (!values_not_equal_display_error(a, b)) {
1602 void _assert_string_equal(const char * const a, const char * const b,
1603 const char * const file, const int line) {
1604 if (!string_equal_display_error(a, b)) {
1610 void _assert_string_not_equal(const char * const a, const char * const b,
1611 const char *file, const int line) {
1612 if (!string_not_equal_display_error(a, b)) {
1618 void _assert_memory_equal(const void * const a, const void * const b,
1619 const size_t size, const char* const file,
1621 if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1627 void _assert_memory_not_equal(const void * const a, const void * const b,
1628 const size_t size, const char* const file,
1630 if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1637 void _assert_in_range(
1638 const LargestIntegralType value, const LargestIntegralType minimum,
1639 const LargestIntegralType maximum, const char* const file,
1641 if (!integer_in_range_display_error(value, minimum, maximum)) {
1646 void _assert_not_in_range(
1647 const LargestIntegralType value, const LargestIntegralType minimum,
1648 const LargestIntegralType maximum, const char* const file,
1650 if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1655 void _assert_in_set(const LargestIntegralType value,
1656 const LargestIntegralType values[],
1657 const size_t number_of_values, const char* const file,
1659 CheckIntegerSet check_integer_set;
1660 check_integer_set.set = values;
1661 check_integer_set.size_of_set = number_of_values;
1662 if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1667 void _assert_not_in_set(const LargestIntegralType value,
1668 const LargestIntegralType values[],
1669 const size_t number_of_values, const char* const file,
1671 CheckIntegerSet check_integer_set;
1672 check_integer_set.set = values;
1673 check_integer_set.size_of_set = number_of_values;
1674 if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1680 /* Get the list of allocated blocks. */
1681 static ListNode* get_allocated_blocks_list() {
1682 /* If it initialized, initialize the list of allocated blocks. */
1683 if (!global_allocated_blocks.value) {
1684 list_initialize(&global_allocated_blocks);
1685 global_allocated_blocks.value = (void*)1;
1687 return &global_allocated_blocks;
1690 static void *libc_malloc(size_t size)
1693 return malloc(size);
1694 #define malloc test_malloc
1697 static void libc_free(void *ptr)
1701 #define free test_free
1704 static void *libc_realloc(void *ptr, size_t size)
1707 return realloc(ptr, size);
1708 #define realloc test_realloc
1711 static void vcm_print_error(const char* const format,
1712 va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
1714 /* It's important to use the libc malloc and free here otherwise
1715 * the automatic free of leaked blocks can reap the error messages
1717 static void vcm_print_error(const char* const format, va_list args)
1724 len = vsnprintf(buffer, sizeof(buffer), format, args);
1730 if (cm_error_message == NULL) {
1731 /* CREATE MESSAGE */
1733 cm_error_message = libc_malloc(len + 1);
1734 if (cm_error_message == NULL) {
1739 /* APPEND MESSAGE */
1742 msg_len = strlen(cm_error_message);
1743 tmp = libc_realloc(cm_error_message, msg_len + len + 1);
1747 cm_error_message = tmp;
1750 if (((size_t)len) < sizeof(buffer)) {
1751 /* Use len + 1 to also copy '\0' */
1752 memcpy(cm_error_message + msg_len, buffer, len + 1);
1755 vsnprintf(cm_error_message + msg_len, len, format, ap);
1760 static void vcm_free_error(char *err_msg)
1765 /* Use the real malloc in this function. */
1767 void* _test_malloc(const size_t size, const char* file, const int line) {
1769 MallocBlockInfo *block_info;
1770 ListNode * const block_list = get_allocated_blocks_list();
1771 const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
1772 sizeof(*block_info) + MALLOC_ALIGNMENT;
1773 char* const block = (char*)malloc(allocate_size);
1774 assert_non_null(block);
1776 /* Calculate the returned address. */
1777 ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
1778 MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1780 /* Initialize the guard blocks. */
1781 memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1782 memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1783 memset(ptr, MALLOC_ALLOC_PATTERN, size);
1785 block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
1786 sizeof(*block_info)));
1787 set_source_location(&block_info->location, file, line);
1788 block_info->allocated_size = allocate_size;
1789 block_info->size = size;
1790 block_info->block = block;
1791 block_info->node.value = block_info;
1792 list_add(block_list, &block_info->node);
1795 #define malloc test_malloc
1798 void* _test_calloc(const size_t number_of_elements, const size_t size,
1799 const char* file, const int line) {
1800 void* const ptr = _test_malloc(number_of_elements * size, file, line);
1802 memset(ptr, 0, number_of_elements * size);
1808 /* Use the real free in this function. */
1810 void _test_free(void* const ptr, const char* file, const int line) {
1812 char *block = discard_const_p(char, ptr);
1813 MallocBlockInfo *block_info;
1819 _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
1820 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1821 sizeof(*block_info)));
1822 /* Check the guard blocks. */
1824 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1825 block + block_info->size};
1826 for (i = 0; i < ARRAY_SIZE(guards); i++) {
1828 char * const guard = guards[i];
1829 for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1830 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1832 cm_print_error(SOURCE_LOCATION_FORMAT
1833 ": error: Guard block of %p size=%lu is corrupt\n"
1834 SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
1836 ptr, (unsigned long)block_info->size,
1837 block_info->location.file, block_info->location.line,
1844 list_remove(&block_info->node, NULL, NULL);
1846 block = discard_const_p(char, block_info->block);
1847 memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
1850 #define free test_free
1853 void *_test_realloc(void *ptr,
1858 MallocBlockInfo *block_info;
1860 size_t block_size = size;
1864 return _test_malloc(size, file, line);
1868 _test_free(ptr, file, line);
1872 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1873 sizeof(*block_info)));
1875 new = _test_malloc(size, file, line);
1880 if (block_info->size < size) {
1881 block_size = block_info->size;
1884 memcpy(new, ptr, block_size);
1886 /* Free previous memory */
1887 _test_free(ptr, file, line);
1891 #define realloc test_realloc
1893 /* Crudely checkpoint the current heap state. */
1894 static const ListNode* check_point_allocated_blocks() {
1895 return get_allocated_blocks_list()->prev;
1899 /* Display the blocks allocated after the specified check point. This
1900 * function returns the number of blocks displayed. */
1901 static int display_allocated_blocks(const ListNode * const check_point) {
1902 const ListNode * const head = get_allocated_blocks_list();
1903 const ListNode *node;
1904 int allocated_blocks = 0;
1905 assert_non_null(check_point);
1906 assert_non_null(check_point->next);
1908 for (node = check_point->next; node != head; node = node->next) {
1909 const MallocBlockInfo * const block_info =
1910 (const MallocBlockInfo*)node->value;
1911 assert_non_null(block_info);
1913 if (!allocated_blocks) {
1914 cm_print_error("Blocks allocated...\n");
1916 cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
1917 block_info->location.file,
1918 block_info->location.line,
1920 allocated_blocks ++;
1922 return allocated_blocks;
1926 /* Free all blocks allocated after the specified check point. */
1927 static void free_allocated_blocks(const ListNode * const check_point) {
1928 const ListNode * const head = get_allocated_blocks_list();
1929 const ListNode *node;
1930 assert_non_null(check_point);
1932 node = check_point->next;
1933 assert_non_null(node);
1935 while (node != head) {
1936 MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
1938 free(discard_const_p(char, block_info) + sizeof(*block_info) + MALLOC_GUARD_SIZE);
1943 /* Fail if any any blocks are allocated after the specified check point. */
1944 static void fail_if_blocks_allocated(const ListNode * const check_point,
1945 const char * const test_name) {
1946 const int allocated_blocks = display_allocated_blocks(check_point);
1947 if (allocated_blocks) {
1948 free_allocated_blocks(check_point);
1949 cm_print_error("ERROR: %s leaked %d block(s)\n", test_name,
1956 void _fail(const char * const file, const int line) {
1957 enum cm_message_output output = cm_get_output();
1960 case CM_OUTPUT_STDOUT:
1961 cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
1964 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
1972 static void exception_handler(int sig) {
1973 const char *sig_strerror = "";
1975 #ifdef HAVE_STRSIGNAL
1976 sig_strerror = strsignal(sig);
1979 cm_print_error("Test failed with exception: %s(%d)",
1986 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
1987 EXCEPTION_RECORD * const exception_record =
1988 exception_pointers->ExceptionRecord;
1989 const DWORD code = exception_record->ExceptionCode;
1991 for (i = 0; i < ARRAY_SIZE(exception_codes); i++) {
1992 const ExceptionCodeInfo * const code_info = &exception_codes[i];
1993 if (code == code_info->code) {
1994 static int shown_debug_message = 0;
1996 cm_print_error("%s occurred at %p.\n", code_info->description,
1997 exception_record->ExceptionAddress);
1998 if (!shown_debug_message) {
2001 "To debug in Visual Studio...\n"
2002 "1. Select menu item File->Open Project\n"
2003 "2. Change 'Files of type' to 'Executable Files'\n"
2004 "3. Open this executable.\n"
2005 "4. Select menu item Debug->Start\n"
2007 "Alternatively, set the environment variable \n"
2008 "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
2009 "then click 'Debug' in the popup dialog box.\n"
2011 shown_debug_message = 1;
2014 return EXCEPTION_EXECUTE_HANDLER;
2017 return EXCEPTION_CONTINUE_SEARCH;
2019 #endif /* !_WIN32 */
2021 void cm_print_error(const char * const format, ...)
2024 va_start(args, format);
2025 if (cm_error_message_enabled) {
2026 vcm_print_error(format, args);
2028 vprint_error(format, args);
2033 /* Standard output and error print methods. */
2034 void vprint_message(const char* const format, va_list args) {
2036 vsnprintf(buffer, sizeof(buffer), format, args);
2037 printf("%s", buffer);
2040 OutputDebugString(buffer);
2045 void vprint_error(const char* const format, va_list args) {
2047 vsnprintf(buffer, sizeof(buffer), format, args);
2048 fprintf(stderr, "%s", buffer);
2051 OutputDebugString(buffer);
2056 void print_message(const char* const format, ...) {
2058 va_start(args, format);
2059 vprint_message(format, args);
2064 void print_error(const char* const format, ...) {
2066 va_start(args, format);
2067 vprint_error(format, args);
2072 static enum cm_message_output cm_get_output(void)
2074 enum cm_message_output output = global_msg_output;
2077 env = getenv("CMOCKA_MESSAGE_OUTPUT");
2079 if (strcasecmp(env, "STDOUT") == 0) {
2080 output = CM_OUTPUT_STDOUT;
2081 } else if (strcasecmp(env, "SUBUNIT") == 0) {
2082 output = CM_OUTPUT_SUBUNIT;
2083 } else if (strcasecmp(env, "TAP") == 0) {
2084 output = CM_OUTPUT_TAP;
2085 } else if (strcasecmp(env, "XML") == 0) {
2086 output = CM_OUTPUT_XML;
2093 enum cm_printf_type {
2095 PRINTF_TEST_SUCCESS,
2096 PRINTF_TEST_FAILURE,
2098 PRINTF_TEST_SKIPPED,
2101 static void cmprintf_group_finish_xml(const char *group_name,
2102 size_t total_executed,
2103 size_t total_failed,
2104 size_t total_errors,
2105 size_t total_skipped,
2106 double total_runtime,
2107 struct CMUnitTestState *cm_tests)
2110 int file_opened = 0;
2114 env = getenv("CMOCKA_XML_FILE");
2117 snprintf(buf, sizeof(buf), "%s", env);
2119 fp = fopen(buf, "r");
2121 fp = fopen(buf, "w");
2133 fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
2134 fprintf(fp, "<testsuites>\n");
2135 fprintf(fp, " <testsuite name=\"%s\" time=\"%.3f\" "
2136 "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
2138 total_runtime * 1000, /* miliseconds */
2139 (unsigned)total_executed,
2140 (unsigned)total_failed,
2141 (unsigned)total_errors,
2142 (unsigned)total_skipped);
2144 for (i = 0; i < total_executed; i++) {
2145 struct CMUnitTestState *cmtest = &cm_tests[i];
2147 fprintf(fp, " <testcase name=\"%s\" time=\"%.3f\" >\n",
2148 cmtest->test->name, cmtest->runtime * 1000);
2150 switch (cmtest->status) {
2152 case CM_TEST_FAILED:
2153 if (cmtest->error_message != NULL) {
2154 fprintf(fp, " <failure><![CDATA[%s]]></failure>\n",
2155 cmtest->error_message);
2157 fprintf(fp, " <failure message=\"Unknown error\" />\n");
2160 case CM_TEST_SKIPPED:
2161 fprintf(fp, " <skipped/>\n");
2164 case CM_TEST_PASSED:
2165 case CM_TEST_NOT_STARTED:
2169 fprintf(fp, " </testcase>\n");
2172 fprintf(fp, " </testsuite>\n");
2173 fprintf(fp, "</testsuites>\n");
2180 static void cmprintf_group_start_standard(const size_t num_tests)
2182 print_message("[==========] Running %u test(s).\n",
2183 (unsigned)num_tests);
2186 static void cmprintf_group_finish_standard(size_t total_executed,
2187 size_t total_passed,
2188 size_t total_failed,
2189 size_t total_errors,
2190 size_t total_skipped,
2191 struct CMUnitTestState *cm_tests)
2195 print_message("[==========] %u test(s) run.\n", (unsigned)total_executed);
2196 print_error("[ PASSED ] %u test(s).\n",
2197 (unsigned)(total_passed));
2199 if (total_skipped) {
2200 print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped);
2201 for (i = 0; i < total_executed; i++) {
2202 struct CMUnitTestState *cmtest = &cm_tests[i];
2204 if (cmtest->status == CM_TEST_SKIPPED) {
2205 print_error("[ SKIPPED ] %s\n", cmtest->test->name);
2208 print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped));
2212 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
2213 for (i = 0; i < total_executed; i++) {
2214 struct CMUnitTestState *cmtest = &cm_tests[i];
2216 if (cmtest->status == CM_TEST_FAILED) {
2217 print_error("[ FAILED ] %s\n", cmtest->test->name);
2220 print_error("\n %u FAILED TEST(S)\n",
2221 (unsigned)(total_failed + total_errors));
2225 static void cmprintf_standard(enum cm_printf_type type,
2226 const char *test_name,
2227 const char *error_message)
2230 case PRINTF_TEST_START:
2231 print_message("[ RUN ] %s\n", test_name);
2233 case PRINTF_TEST_SUCCESS:
2234 print_message("[ OK ] %s\n", test_name);
2236 case PRINTF_TEST_FAILURE:
2237 if (error_message != NULL) {
2238 print_error("[ ERROR ] --- %s\n", error_message);
2240 print_message("[ FAILED ] %s\n", test_name);
2242 case PRINTF_TEST_SKIPPED:
2243 print_message("[ SKIPPED ] %s\n", test_name);
2245 case PRINTF_TEST_ERROR:
2246 if (error_message != NULL) {
2247 print_error("%s\n", error_message);
2249 print_error("[ ERROR ] %s\n", test_name);
2254 static void cmprintf_group_start_tap(const size_t num_tests)
2256 print_message("\t1..%u\n", (unsigned)num_tests);
2259 static void cmprintf_group_finish_tap(const char *group_name,
2260 size_t total_executed,
2261 size_t total_passed,
2262 size_t total_skipped)
2264 const char *status = "not ok";
2265 if (total_passed + total_skipped == total_executed) {
2268 print_message("%s - %s\n", status, group_name);
2271 static void cmprintf_tap(enum cm_printf_type type,
2272 uint32_t test_number,
2273 const char *test_name,
2274 const char *error_message)
2277 case PRINTF_TEST_START:
2279 case PRINTF_TEST_SUCCESS:
2280 print_message("\tok %u - %s\n", (unsigned)test_number, test_name);
2282 case PRINTF_TEST_FAILURE:
2283 print_message("\tnot ok %u - %s\n", (unsigned)test_number, test_name);
2284 if (error_message != NULL) {
2288 msg = strdup(error_message);
2294 while (p[0] != '\0') {
2297 p = strchr(q, '\n');
2302 print_message("\t# %s\n", q);
2312 case PRINTF_TEST_SKIPPED:
2313 print_message("\tnot ok %u # SKIP %s\n", (unsigned)test_number, test_name);
2315 case PRINTF_TEST_ERROR:
2316 print_message("\tnot ok %u - %s %s\n",
2317 (unsigned)test_number, test_name, error_message);
2322 static void cmprintf_subunit(enum cm_printf_type type,
2323 const char *test_name,
2324 const char *error_message)
2327 case PRINTF_TEST_START:
2328 print_message("test: %s\n", test_name);
2330 case PRINTF_TEST_SUCCESS:
2331 print_message("success: %s\n", test_name);
2333 case PRINTF_TEST_FAILURE:
2334 print_message("failure: %s", test_name);
2335 if (error_message != NULL) {
2336 print_message(" [\n%s]\n", error_message);
2339 case PRINTF_TEST_SKIPPED:
2340 print_message("skip: %s\n", test_name);
2342 case PRINTF_TEST_ERROR:
2343 print_message("error: %s [ %s ]\n", test_name, error_message);
2348 static void cmprintf_group_start(const size_t num_tests)
2350 enum cm_message_output output;
2352 output = cm_get_output();
2355 case CM_OUTPUT_STDOUT:
2356 cmprintf_group_start_standard(num_tests);
2358 case CM_OUTPUT_SUBUNIT:
2361 cmprintf_group_start_tap(num_tests);
2368 static void cmprintf_group_finish(const char *group_name,
2369 size_t total_executed,
2370 size_t total_passed,
2371 size_t total_failed,
2372 size_t total_errors,
2373 size_t total_skipped,
2374 double total_runtime,
2375 struct CMUnitTestState *cm_tests)
2377 enum cm_message_output output;
2379 output = cm_get_output();
2382 case CM_OUTPUT_STDOUT:
2383 cmprintf_group_finish_standard(total_executed,
2390 case CM_OUTPUT_SUBUNIT:
2393 cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped);
2396 cmprintf_group_finish_xml(group_name,
2407 static void cmprintf(enum cm_printf_type type,
2409 const char *test_name,
2410 const char *error_message)
2412 enum cm_message_output output;
2414 output = cm_get_output();
2417 case CM_OUTPUT_STDOUT:
2418 cmprintf_standard(type, test_name, error_message);
2420 case CM_OUTPUT_SUBUNIT:
2421 cmprintf_subunit(type, test_name, error_message);
2424 cmprintf_tap(type, test_number, test_name, error_message);
2431 void cmocka_set_message_output(enum cm_message_output output)
2433 global_msg_output = output;
2436 /****************************************************************************
2438 ****************************************************************************/
2440 #ifdef HAVE_STRUCT_TIMESPEC
2441 static struct timespec cm_tspecdiff(struct timespec time1,
2442 struct timespec time0)
2444 struct timespec ret;
2448 if (time0.tv_nsec > time1.tv_nsec) {
2449 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
2450 time0.tv_nsec -= (long int) (1E9 * xsec);
2451 time0.tv_sec += xsec;
2454 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
2455 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
2456 time0.tv_nsec += (long int) (1E9 * xsec);
2457 time0.tv_sec -= xsec;
2460 ret.tv_sec = time1.tv_sec - time0.tv_sec;
2461 ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
2463 if (time1.tv_sec < time0.tv_sec) {
2467 ret.tv_sec = ret.tv_sec * sign;
2472 static double cm_secdiff(struct timespec clock1, struct timespec clock0)
2475 struct timespec diff;
2477 diff = cm_tspecdiff(clock1, clock0);
2480 ret += (double) diff.tv_nsec / (double) 1E9;
2484 #endif /* HAVE_STRUCT_TIMESPEC */
2486 /****************************************************************************
2487 * CMOCKA TEST RUNNER
2488 ****************************************************************************/
2489 static int cmocka_run_one_test_or_fixture(const char *function_name,
2490 CMUnitTestFunction test_func,
2491 CMFixtureFunction setup_func,
2492 CMFixtureFunction teardown_func,
2493 void ** const volatile state,
2494 const void *const heap_check_point)
2496 const ListNode * const volatile check_point = (const ListNode*)
2497 (heap_check_point != NULL ?
2498 heap_check_point : check_point_allocated_blocks());
2499 int handle_exceptions = 1;
2500 void *current_state = NULL;
2503 /* FIXME check only one test or fixture is set */
2505 /* Detect if we should handle exceptions */
2507 handle_exceptions = !IsDebuggerPresent();
2509 #ifdef UNIT_TESTING_DEBUG
2510 handle_exceptions = 0;
2511 #endif /* UNIT_TESTING_DEBUG */
2514 if (handle_exceptions) {
2517 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2518 default_signal_functions[i] = signal(
2519 exception_signals[i], exception_handler);
2522 previous_exception_filter = SetUnhandledExceptionFilter(
2524 #endif /* !_WIN32 */
2527 /* Init the test structure */
2528 initialize_testing(function_name);
2530 global_running_test = 1;
2532 if (cm_setjmp(global_run_test_env) == 0) {
2533 if (test_func != NULL) {
2534 test_func(state != NULL ? state : ¤t_state);
2536 fail_if_blocks_allocated(check_point, function_name);
2538 } else if (setup_func != NULL) {
2539 rc = setup_func(state != NULL ? state : ¤t_state);
2542 * For setup we can ignore any allocated blocks. We just need to
2543 * ensure they're deallocated on tear down.
2545 } else if (teardown_func != NULL) {
2546 rc = teardown_func(state != NULL ? state : ¤t_state);
2548 fail_if_blocks_allocated(check_point, function_name);
2552 fail_if_leftover_values(function_name);
2553 global_running_test = 0;
2556 global_running_test = 0;
2559 teardown_testing(function_name);
2561 if (handle_exceptions) {
2564 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2565 signal(exception_signals[i], default_signal_functions[i]);
2568 if (previous_exception_filter) {
2569 SetUnhandledExceptionFilter(previous_exception_filter);
2570 previous_exception_filter = NULL;
2572 #endif /* !_WIN32 */
2578 static int cmocka_run_group_fixture(const char *function_name,
2579 CMFixtureFunction setup_func,
2580 CMFixtureFunction teardown_func,
2582 const void *const heap_check_point)
2586 if (setup_func != NULL) {
2587 rc = cmocka_run_one_test_or_fixture(function_name,
2594 rc = cmocka_run_one_test_or_fixture(function_name,
2605 static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
2607 #ifdef HAVE_STRUCT_TIMESPEC
2608 struct timespec start = {
2612 struct timespec finish = {
2620 if (test_state->test->setup_func != NULL) {
2621 /* Setup the memory check point, it will be evaluated on teardown */
2622 test_state->check_point = check_point_allocated_blocks();
2624 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2626 test_state->test->setup_func,
2629 test_state->check_point);
2631 test_state->status = CM_TEST_ERROR;
2632 cm_print_error("Test setup failed");
2637 #ifdef HAVE_STRUCT_TIMESPEC
2638 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
2642 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2643 test_state->test->test_func,
2649 test_state->status = CM_TEST_PASSED;
2651 if (global_skip_test) {
2652 test_state->status = CM_TEST_SKIPPED;
2653 global_skip_test = 0; /* Do not skip the next test */
2655 test_state->status = CM_TEST_FAILED;
2661 test_state->runtime = 0.0;
2663 #ifdef HAVE_STRUCT_TIMESPEC
2664 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
2665 test_state->runtime = cm_secdiff(finish, start);
2669 if (rc == 0 && test_state->test->teardown_func != NULL) {
2670 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2673 test_state->test->teardown_func,
2675 test_state->check_point);
2677 test_state->status = CM_TEST_ERROR;
2678 cm_print_error("Test teardown failed");
2682 test_state->error_message = cm_error_message;
2683 cm_error_message = NULL;
2688 int _cmocka_run_group_tests(const char *group_name,
2689 const struct CMUnitTest * const tests,
2690 const size_t num_tests,
2691 CMFixtureFunction group_setup,
2692 CMFixtureFunction group_teardown)
2694 struct CMUnitTestState *cm_tests;
2695 const ListNode *group_check_point = check_point_allocated_blocks();
2696 void *group_state = NULL;
2697 size_t total_tests = 0;
2698 size_t total_failed = 0;
2699 size_t total_passed = 0;
2700 size_t total_executed = 0;
2701 size_t total_errors = 0;
2702 size_t total_skipped = 0;
2703 double total_runtime = 0;
2707 /* Make sure LargestIntegralType is at least the size of a pointer. */
2708 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
2710 cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests);
2711 if (cm_tests == NULL) {
2715 /* Setup cmocka test array */
2716 for (i = 0; i < num_tests; i++) {
2717 if (tests[i].name != NULL &&
2718 (tests[i].test_func != NULL
2719 || tests[i].setup_func != NULL
2720 || tests[i].teardown_func != NULL)) {
2721 cm_tests[i] = (struct CMUnitTestState) {
2723 .status = CM_TEST_NOT_STARTED,
2730 cmprintf_group_start(total_tests);
2734 /* Run group setup */
2735 if (group_setup != NULL) {
2736 rc = cmocka_run_group_fixture("cmocka_group_setup",
2745 for (i = 0; i < total_tests; i++) {
2746 struct CMUnitTestState *cmtest = &cm_tests[i];
2747 size_t test_number = i + 1;
2749 cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
2751 if (group_state != NULL) {
2752 cmtest->state = group_state;
2753 } else if (cmtest->test->initial_state != NULL) {
2754 cmtest->state = cmtest->test->initial_state;
2757 rc = cmocka_run_one_tests(cmtest);
2759 total_runtime += cmtest->runtime;
2761 switch (cmtest->status) {
2762 case CM_TEST_PASSED:
2763 cmprintf(PRINTF_TEST_SUCCESS,
2766 cmtest->error_message);
2769 case CM_TEST_SKIPPED:
2770 cmprintf(PRINTF_TEST_SKIPPED,
2773 cmtest->error_message);
2776 case CM_TEST_FAILED:
2777 cmprintf(PRINTF_TEST_FAILURE,
2780 cmtest->error_message);
2784 cmprintf(PRINTF_TEST_ERROR,
2787 "Internal cmocka error");
2792 cmprintf(PRINTF_TEST_ERROR,
2795 "Could not run the test - check test fixtures");
2800 if (cm_error_message != NULL) {
2801 print_error("[ ERROR ] --- %s\n", cm_error_message);
2802 vcm_free_error(cm_error_message);
2803 cm_error_message = NULL;
2805 cmprintf(PRINTF_TEST_ERROR, 0,
2806 group_name, "[ FAILED ] GROUP SETUP");
2810 /* Run group teardown */
2811 if (group_teardown != NULL) {
2812 rc = cmocka_run_group_fixture("cmocka_group_teardown",
2818 if (cm_error_message != NULL) {
2819 print_error("[ ERROR ] --- %s\n", cm_error_message);
2820 vcm_free_error(cm_error_message);
2821 cm_error_message = NULL;
2823 cmprintf(PRINTF_TEST_ERROR, 0,
2824 group_name, "[ FAILED ] GROUP TEARDOWN");
2828 cmprintf_group_finish(group_name,
2837 for (i = 0; i < total_tests; i++) {
2838 vcm_free_error(discard_const_p(char, cm_tests[i].error_message));
2840 libc_free(cm_tests);
2841 fail_if_blocks_allocated(group_check_point, "cmocka_group_tests");
2843 return total_failed + total_errors;
2846 /****************************************************************************
2847 * DEPRECATED TEST RUNNER
2848 ****************************************************************************/
2851 const char * const function_name, const UnitTestFunction Function,
2852 void ** const volatile state, const UnitTestFunctionType function_type,
2853 const void* const heap_check_point) {
2854 const ListNode * const volatile check_point = (const ListNode*)
2856 heap_check_point : check_point_allocated_blocks());
2857 void *current_state = NULL;
2858 volatile int rc = 1;
2859 int handle_exceptions = 1;
2861 handle_exceptions = !IsDebuggerPresent();
2863 #ifdef UNIT_TESTING_DEBUG
2864 handle_exceptions = 0;
2865 #endif /* UNIT_TESTING_DEBUG */
2867 cm_error_message_enabled = 0;
2869 if (handle_exceptions) {
2872 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2873 default_signal_functions[i] = signal(
2874 exception_signals[i], exception_handler);
2877 previous_exception_filter = SetUnhandledExceptionFilter(
2879 #endif /* !_WIN32 */
2882 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
2883 print_message("[ RUN ] %s\n", function_name);
2885 initialize_testing(function_name);
2886 global_running_test = 1;
2887 if (cm_setjmp(global_run_test_env) == 0) {
2888 Function(state ? state : ¤t_state);
2889 fail_if_leftover_values(function_name);
2891 /* If this is a setup function then ignore any allocated blocks
2892 * only ensure they're deallocated on tear down. */
2893 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
2894 fail_if_blocks_allocated(check_point, function_name);
2897 global_running_test = 0;
2899 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
2900 print_message("[ OK ] %s\n", function_name);
2904 global_running_test = 0;
2905 print_message("[ FAILED ] %s\n", function_name);
2907 teardown_testing(function_name);
2909 if (handle_exceptions) {
2912 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2913 signal(exception_signals[i], default_signal_functions[i]);
2916 if (previous_exception_filter) {
2917 SetUnhandledExceptionFilter(previous_exception_filter);
2918 previous_exception_filter = NULL;
2920 #endif /* !_WIN32 */
2927 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
2928 /* Whether to execute the next test. */
2929 int run_next_test = 1;
2930 /* Whether the previous test failed. */
2931 int previous_test_failed = 0;
2932 /* Whether the previous setup failed. */
2933 int previous_setup_failed = 0;
2934 /* Check point of the heap state. */
2935 const ListNode * const check_point = check_point_allocated_blocks();
2936 /* Current test being executed. */
2937 size_t current_test = 0;
2938 /* Number of tests executed. */
2939 size_t tests_executed = 0;
2940 /* Number of failed tests. */
2941 size_t total_failed = 0;
2942 /* Number of setup functions. */
2944 /* Number of teardown functions. */
2945 size_t teardowns = 0;
2948 * A stack of test states. A state is pushed on the stack
2949 * when a test setup occurs and popped on tear down.
2951 TestState* test_states =
2952 (TestState*)malloc(number_of_tests * sizeof(*test_states));
2953 /* The number of test states which should be 0 at the end */
2954 long number_of_test_states = 0;
2955 /* Names of the tests that failed. */
2956 const char** failed_names = (const char**)malloc(number_of_tests *
2957 sizeof(*failed_names));
2958 void **current_state = NULL;
2960 /* Count setup and teardown functions */
2961 for (i = 0; i < number_of_tests; i++) {
2962 const UnitTest * const test = &tests[i];
2964 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) {
2968 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) {
2973 print_message("[==========] Running %"PRIdS " test(s).\n",
2974 number_of_tests - setups - teardowns);
2976 /* Make sure LargestIntegralType is at least the size of a pointer. */
2977 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
2979 while (current_test < number_of_tests) {
2980 const ListNode *test_check_point = NULL;
2981 TestState *current_TestState;
2982 const UnitTest * const test = &tests[current_test++];
2983 if (!test->function) {
2987 switch (test->function_type) {
2988 case UNIT_TEST_FUNCTION_TYPE_TEST:
2989 if (! previous_setup_failed) {
2993 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
2994 /* Checkpoint the heap before the setup. */
2995 current_TestState = &test_states[number_of_test_states++];
2996 current_TestState->check_point = check_point_allocated_blocks();
2997 test_check_point = current_TestState->check_point;
2998 current_state = ¤t_TestState->state;
2999 *current_state = NULL;
3003 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3004 /* Check the heap based on the last setup checkpoint. */
3005 assert_true(number_of_test_states);
3006 current_TestState = &test_states[--number_of_test_states];
3007 test_check_point = current_TestState->check_point;
3008 current_state = ¤t_TestState->state;
3011 print_error("Invalid unit test function type %d\n",
3012 test->function_type);
3017 if (run_next_test) {
3018 int failed = _run_test(test->name, test->function, current_state,
3019 test->function_type, test_check_point);
3021 failed_names[total_failed] = test->name;
3024 switch (test->function_type) {
3025 case UNIT_TEST_FUNCTION_TYPE_TEST:
3026 previous_test_failed = failed;
3027 total_failed += failed;
3031 case UNIT_TEST_FUNCTION_TYPE_SETUP:
3035 /* Skip forward until the next test or setup function. */
3037 previous_setup_failed = 1;
3039 previous_test_failed = 0;
3042 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3043 /* If this test failed. */
3044 if (failed && !previous_test_failed) {
3050 assert_null("BUG: shouldn't be here!");
3057 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3058 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3060 if (total_failed > 0) {
3061 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3062 for (i = 0; i < total_failed; i++) {
3063 print_error("[ FAILED ] %s\n", failed_names[i]);
3066 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3069 if (number_of_test_states != 0) {
3070 print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and "
3071 "teardown %"PRIdS " functions\n", setups, teardowns);
3072 total_failed = (size_t)-1;
3076 free((void*)failed_names);
3078 fail_if_blocks_allocated(check_point, "run_tests");
3079 return (int)total_failed;
3082 int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
3084 UnitTestFunction setup = NULL;
3085 const char *setup_name;
3086 size_t num_setups = 0;
3087 UnitTestFunction teardown = NULL;
3088 const char *teardown_name;
3089 size_t num_teardowns = 0;
3090 size_t current_test = 0;
3093 /* Number of tests executed. */
3094 size_t tests_executed = 0;
3095 /* Number of failed tests. */
3096 size_t total_failed = 0;
3097 /* Check point of the heap state. */
3098 const ListNode * const check_point = check_point_allocated_blocks();
3099 const char** failed_names = (const char**)malloc(number_of_tests *
3100 sizeof(*failed_names));
3101 void **current_state = NULL;
3102 TestState group_state;
3104 /* Find setup and teardown function */
3105 for (i = 0; i < number_of_tests; i++) {
3106 const UnitTest * const test = &tests[i];
3108 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
3109 if (setup == NULL) {
3110 setup = test->function;
3111 setup_name = test->name;
3114 print_error("[ ERROR ] More than one group setup function detected\n");
3119 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
3120 if (teardown == NULL) {
3121 teardown = test->function;
3122 teardown_name = test->name;
3125 print_error("[ ERROR ] More than one group teardown function detected\n");
3131 print_message("[==========] Running %"PRIdS " test(s).\n",
3132 number_of_tests - num_setups - num_teardowns);
3134 if (setup != NULL) {
3137 group_state.check_point = check_point_allocated_blocks();
3138 current_state = &group_state.state;
3139 *current_state = NULL;
3140 failed = _run_test(setup_name,
3143 UNIT_TEST_FUNCTION_TYPE_SETUP,
3144 group_state.check_point);
3146 failed_names[total_failed] = setup_name;
3149 total_failed += failed;
3153 while (current_test < number_of_tests) {
3155 const UnitTest * const test = &tests[current_test++];
3156 if (test->function == NULL) {
3160 switch (test->function_type) {
3161 case UNIT_TEST_FUNCTION_TYPE_TEST:
3164 case UNIT_TEST_FUNCTION_TYPE_SETUP:
3165 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3166 case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
3167 case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
3170 print_error("Invalid unit test function type %d\n",
3171 test->function_type);
3178 failed = _run_test(test->name,
3181 test->function_type,
3184 failed_names[total_failed] = test->name;
3187 total_failed += failed;
3192 if (teardown != NULL) {
3195 failed = _run_test(teardown_name,
3198 UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
3199 group_state.check_point);
3201 failed_names[total_failed] = teardown_name;
3204 total_failed += failed;
3208 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3209 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3212 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3213 for (i = 0; i < total_failed; i++) {
3214 print_error("[ FAILED ] %s\n", failed_names[i]);
3217 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3220 free((void*)failed_names);
3221 fail_if_blocks_allocated(check_point, "run_group_tests");
3223 return (int)total_failed;