vfs_fruit: use "fake_fd" instead of "created"
[Samba.git] / third_party / cmocka / cmocka.c
blobb21fe15536c9d9e5bd51c2bd78ced96a992fbd69
1 /*
2 * Copyright 2008 Google Inc.
3 * Copyright 2014-2018 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.
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
22 #ifdef HAVE_MALLOC_H
23 #include <malloc.h>
24 #endif
26 #ifdef HAVE_INTTYPES_H
27 #include <inttypes.h>
28 #endif
30 #ifdef HAVE_SIGNAL_H
31 #include <signal.h>
32 #endif
34 #ifdef HAVE_STRINGS_H
35 #include <strings.h>
36 #endif
38 #include <stdint.h>
39 #include <setjmp.h>
40 #include <stdarg.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <time.h>
48 * This allows to add a platform specific header file. Some embedded platforms
49 * sometimes miss certain types and definitions.
51 * Example:
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 */
61 #include <cmocka.h>
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)
81 #else
82 # define CMOCKA_THREAD
83 #endif
85 #ifdef HAVE_CLOCK_REALTIME
86 #define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts))
87 #else
88 #define CMOCKA_CLOCK_GETTIME(clock_id, ts)
89 #endif
91 #ifndef MAX
92 #define MAX(a,b) ((a) < (b) ? (b) : (a))
93 #endif
95 /**
96 * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp.
98 #ifdef HAVE_SIGLONGJMP
99 # define cm_jmp_buf sigjmp_buf
100 # define cm_setjmp(env) sigsetjmp(env, 1)
101 # define cm_longjmp(env, val) siglongjmp(env, val)
102 #else
103 # define cm_jmp_buf jmp_buf
104 # define cm_setjmp(env) setjmp(env)
105 # define cm_longjmp(env, val) longjmp(env, val)
106 #endif
110 * Declare and initialize the pointer member of ValuePointer variable name
111 * with ptr.
113 #define declare_initialize_value_pointer_pointer(name, ptr) \
114 ValuePointer name ; \
115 name.value = 0; \
116 name.x.pointer = (void*)(ptr)
119 * Declare and initialize the value member of ValuePointer variable name
120 * with val.
122 #define declare_initialize_value_pointer_value(name, val) \
123 ValuePointer name ; \
124 name.value = val
126 /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */
127 #define cast_largest_integral_type_to_pointer( \
128 pointer_type, largest_integral_type) \
129 ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer)
131 /* Used to cast LargetIntegralType to void* and vice versa. */
132 typedef union ValuePointer {
133 LargestIntegralType value;
134 struct {
135 #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
136 unsigned int padding;
137 #endif
138 void *pointer;
139 } x;
140 } ValuePointer;
142 /* Doubly linked list node. */
143 typedef struct ListNode {
144 const void *value;
145 int refcount;
146 struct ListNode *next;
147 struct ListNode *prev;
148 } ListNode;
150 /* Debug information for malloc(). */
151 struct MallocBlockInfoData {
152 void* block; /* Address of the block returned by malloc(). */
153 size_t allocated_size; /* Total size of the allocated block. */
154 size_t size; /* Request block size. */
155 SourceLocation location; /* Where the block was allocated. */
156 ListNode node; /* Node within list of all allocated blocks. */
159 typedef union {
160 struct MallocBlockInfoData *data;
161 char *ptr;
162 } MallocBlockInfo;
164 /* State of each test. */
165 typedef struct TestState {
166 const ListNode *check_point; /* Check point of the test if there's a */
167 /* setup function. */
168 void *state; /* State associated with the test. */
169 } TestState;
171 /* Determines whether two values are the same. */
172 typedef int (*EqualityFunction)(const void *left, const void *right);
174 /* Value of a symbol and the place it was declared. */
175 typedef struct SymbolValue {
176 SourceLocation location;
177 LargestIntegralType value;
178 } SymbolValue;
181 * Contains a list of values for a symbol.
182 * NOTE: Each structure referenced by symbol_values_list_head must have a
183 * SourceLocation as its' first member.
185 typedef struct SymbolMapValue {
186 const char *symbol_name;
187 ListNode symbol_values_list_head;
188 } SymbolMapValue;
190 /* Where a particular ordering was located and its symbol name */
191 typedef struct FuncOrderingValue {
192 SourceLocation location;
193 const char * function;
194 } FuncOrderingValue;
196 /* Used by list_free() to deallocate values referenced by list nodes. */
197 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
199 /* Structure used to check the range of integer types.a */
200 typedef struct CheckIntegerRange {
201 CheckParameterEvent event;
202 LargestIntegralType minimum;
203 LargestIntegralType maximum;
204 } CheckIntegerRange;
206 /* Structure used to check whether an integer value is in a set. */
207 typedef struct CheckIntegerSet {
208 CheckParameterEvent event;
209 const LargestIntegralType *set;
210 size_t size_of_set;
211 } CheckIntegerSet;
213 /* Used to check whether a parameter matches the area of memory referenced by
214 * this structure. */
215 typedef struct CheckMemoryData {
216 CheckParameterEvent event;
217 const void *memory;
218 size_t size;
219 } CheckMemoryData;
221 static ListNode* list_initialize(ListNode * const node);
222 static ListNode* list_add(ListNode * const head, ListNode *new_node);
223 static ListNode* list_add_value(ListNode * const head, const void *value,
224 const int count);
225 static ListNode* list_remove(
226 ListNode * const node, const CleanupListValue cleanup_value,
227 void * const cleanup_value_data);
228 static void list_remove_free(
229 ListNode * const node, const CleanupListValue cleanup_value,
230 void * const cleanup_value_data);
231 static int list_empty(const ListNode * const head);
232 static int list_find(
233 ListNode * const head, const void *value,
234 const EqualityFunction equal_func, ListNode **output);
235 static int list_first(ListNode * const head, ListNode **output);
236 static ListNode* list_free(
237 ListNode * const head, const CleanupListValue cleanup_value,
238 void * const cleanup_value_data);
240 static void add_symbol_value(
241 ListNode * const symbol_map_head, const char * const symbol_names[],
242 const size_t number_of_symbol_names, const void* value, const int count);
243 static int get_symbol_value(
244 ListNode * const symbol_map_head, const char * const symbol_names[],
245 const size_t number_of_symbol_names, void **output);
246 static void free_value(const void *value, void *cleanup_value_data);
247 static void free_symbol_map_value(
248 const void *value, void *cleanup_value_data);
249 static void remove_always_return_values(ListNode * const map_head,
250 const size_t number_of_symbol_names);
252 static size_t check_for_leftover_values_list(const ListNode * head,
253 const char * const error_message);
255 static size_t check_for_leftover_values(
256 const ListNode * const map_head, const char * const error_message,
257 const size_t number_of_symbol_names);
259 static void remove_always_return_values_from_list(ListNode * const map_head);
262 * This must be called at the beginning of a test to initialize some data
263 * structures.
265 static void initialize_testing(const char *test_name);
267 /* This must be called at the end of a test to free() allocated structures. */
268 static void teardown_testing(const char *test_name);
270 static enum cm_message_output cm_get_output(void);
272 static int cm_error_message_enabled = 1;
273 static CMOCKA_THREAD char *cm_error_message;
275 void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
278 * Keeps track of the calling context returned by setenv() so that the fail()
279 * method can jump out of a test.
281 static CMOCKA_THREAD cm_jmp_buf global_run_test_env;
282 static CMOCKA_THREAD int global_running_test = 0;
284 /* Keeps track of the calling context returned by setenv() so that */
285 /* mock_assert() can optionally jump back to expect_assert_failure(). */
286 jmp_buf global_expect_assert_env;
287 int global_expecting_assert = 0;
288 const char *global_last_failed_assert = NULL;
289 static int global_skip_test;
291 /* Keeps a map of the values that functions will have to return to provide */
292 /* mocked interfaces. */
293 static CMOCKA_THREAD ListNode global_function_result_map_head;
294 /* Location of the last mock value returned was declared. */
295 static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
297 /* Keeps a map of the values that functions expect as parameters to their
298 * mocked interfaces. */
299 static CMOCKA_THREAD ListNode global_function_parameter_map_head;
300 /* Location of last parameter value checked was declared. */
301 static CMOCKA_THREAD SourceLocation global_last_parameter_location;
303 /* List (acting as FIFO) of call ordering. */
304 static CMOCKA_THREAD ListNode global_call_ordering_head;
305 /* Location of last call ordering that was declared. */
306 static CMOCKA_THREAD SourceLocation global_last_call_ordering_location;
308 /* List of all currently allocated blocks. */
309 static CMOCKA_THREAD ListNode global_allocated_blocks;
311 static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
313 static const char *global_test_filter_pattern;
315 #ifndef _WIN32
316 /* Signals caught by exception_handler(). */
317 static const int exception_signals[] = {
318 SIGFPE,
319 SIGILL,
320 SIGSEGV,
321 #ifdef SIGBUS
322 SIGBUS,
323 #endif
324 #ifdef SIGSYS
325 SIGSYS,
326 #endif
329 /* Default signal functions that should be restored after a test is complete. */
330 typedef void (*SignalFunction)(int signal);
331 static SignalFunction default_signal_functions[
332 ARRAY_SIZE(exception_signals)];
334 #else /* _WIN32 */
336 /* The default exception filter. */
337 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
339 /* Fatal exceptions. */
340 typedef struct ExceptionCodeInfo {
341 DWORD code;
342 const char* description;
343 } ExceptionCodeInfo;
345 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
347 static const ExceptionCodeInfo exception_codes[] = {
348 EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
349 EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
350 EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
351 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
352 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
353 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
354 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
355 EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
356 EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
357 EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
358 EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
359 EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
360 EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
361 EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
362 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
363 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
364 EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
365 EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
366 EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
367 EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
369 #endif /* !_WIN32 */
371 enum CMUnitTestStatus {
372 CM_TEST_NOT_STARTED,
373 CM_TEST_PASSED,
374 CM_TEST_FAILED,
375 CM_TEST_ERROR,
376 CM_TEST_SKIPPED,
379 struct CMUnitTestState {
380 const ListNode *check_point; /* Check point of the test if there's a setup function. */
381 const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
382 void *state; /* State associated with the test */
383 const char *error_message; /* The error messages by the test */
384 enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
385 double runtime; /* Time calculations */
388 /* Exit the currently executing test. */
389 static void exit_test(const int quit_application)
391 const char *env = getenv("CMOCKA_TEST_ABORT");
392 int abort_test = 0;
394 if (env != NULL && strlen(env) == 1) {
395 abort_test = (env[0] == '1');
398 if (global_skip_test == 0 &&
399 abort_test == 1) {
400 print_error("%s", cm_error_message);
401 abort();
402 } else if (global_running_test) {
403 cm_longjmp(global_run_test_env, 1);
404 } else if (quit_application) {
405 exit(-1);
409 void _skip(const char * const file, const int line)
411 cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
412 global_skip_test = 1;
413 exit_test(1);
416 /* Initialize a SourceLocation structure. */
417 static void initialize_source_location(SourceLocation * const location) {
418 assert_non_null(location);
419 location->file = NULL;
420 location->line = 0;
424 /* Determine whether a source location is currently set. */
425 static int source_location_is_set(const SourceLocation * const location) {
426 assert_non_null(location);
427 return location->file && location->line;
431 /* Set a source location. */
432 static void set_source_location(
433 SourceLocation * const location, const char * const file,
434 const int line) {
435 assert_non_null(location);
436 location->file = file;
437 location->line = line;
441 static int c_strreplace(char *src,
442 size_t src_len,
443 const char *pattern,
444 const char *repl,
445 int *str_replaced)
447 char *p = NULL;
449 p = strstr(src, pattern);
450 if (p == NULL) {
451 return -1;
454 do {
455 size_t of = p - src;
456 size_t l = strlen(src);
457 size_t pl = strlen(pattern);
458 size_t rl = strlen(repl);
460 /* overflow check */
461 if (src_len <= l + MAX(pl, rl) + 1) {
462 return -1;
465 if (rl != pl) {
466 memmove(src + of + rl, src + of + pl, l - of - pl + 1);
469 memcpy(src + of, repl, rl);
471 if (str_replaced != NULL) {
472 *str_replaced = 1;
474 p = strstr(src, pattern);
475 } while (p != NULL);
477 return 0;
480 static int c_strmatch(const char *str, const char *pattern)
482 int ok;
484 if (str == NULL || pattern == NULL) {
485 return 0;
488 for (;;) {
489 /* Check if pattern is done */
490 if (*pattern == '\0') {
491 /* If string is at the end, we're good */
492 if (*str == '\0') {
493 return 1;
496 return 0;
499 if (*pattern == '*') {
500 /* Move on */
501 pattern++;
503 /* If we are at the end, everything is fine */
504 if (*pattern == '\0') {
505 return 1;
508 /* Try to match each position */
509 for (; *str != '\0'; str++) {
510 ok = c_strmatch(str, pattern);
511 if (ok) {
512 return 1;
516 /* No match */
517 return 0;
520 /* If we are at the end, leave */
521 if (*str == '\0') {
522 return 0;
525 /* Check if we have a single wildcard or matching char */
526 if (*pattern != '?' && *str != *pattern) {
527 return 0;
530 /* Move string and pattern */
531 str++;
532 pattern++;
535 return 0;
538 /* Create function results and expected parameter lists. */
539 void initialize_testing(const char *test_name) {
540 (void)test_name;
541 list_initialize(&global_function_result_map_head);
542 initialize_source_location(&global_last_mock_value_location);
543 list_initialize(&global_function_parameter_map_head);
544 initialize_source_location(&global_last_parameter_location);
545 list_initialize(&global_call_ordering_head);
546 initialize_source_location(&global_last_parameter_location);
550 static void fail_if_leftover_values(const char *test_name) {
551 int error_occurred = 0;
552 (void)test_name;
553 remove_always_return_values(&global_function_result_map_head, 1);
554 if (check_for_leftover_values(
555 &global_function_result_map_head,
556 "%s() has remaining non-returned values.\n", 1)) {
557 error_occurred = 1;
560 remove_always_return_values(&global_function_parameter_map_head, 2);
561 if (check_for_leftover_values(
562 &global_function_parameter_map_head,
563 "'%s' parameter still has values that haven't been checked.\n",
564 2)) {
565 error_occurred = 1;
568 remove_always_return_values_from_list(&global_call_ordering_head);
569 if (check_for_leftover_values_list(&global_call_ordering_head,
570 "%s function was expected to be called but was not not.\n")) {
571 error_occurred = 1;
573 if (error_occurred) {
574 exit_test(1);
579 static void teardown_testing(const char *test_name) {
580 (void)test_name;
581 list_free(&global_function_result_map_head, free_symbol_map_value,
582 (void*)0);
583 initialize_source_location(&global_last_mock_value_location);
584 list_free(&global_function_parameter_map_head, free_symbol_map_value,
585 (void*)1);
586 initialize_source_location(&global_last_parameter_location);
587 list_free(&global_call_ordering_head, free_value,
588 (void*)0);
589 initialize_source_location(&global_last_call_ordering_location);
592 /* Initialize a list node. */
593 static ListNode* list_initialize(ListNode * const node) {
594 node->value = NULL;
595 node->next = node;
596 node->prev = node;
597 node->refcount = 1;
598 return node;
603 * Adds a value at the tail of a given list.
604 * The node referencing the value is allocated from the heap.
606 static ListNode* list_add_value(ListNode * const head, const void *value,
607 const int refcount) {
608 ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
609 assert_non_null(head);
610 assert_non_null(value);
611 new_node->value = value;
612 new_node->refcount = refcount;
613 return list_add(head, new_node);
617 /* Add new_node to the end of the list. */
618 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
619 assert_non_null(head);
620 assert_non_null(new_node);
621 new_node->next = head;
622 new_node->prev = head->prev;
623 head->prev->next = new_node;
624 head->prev = new_node;
625 return new_node;
629 /* Remove a node from a list. */
630 static ListNode* list_remove(
631 ListNode * const node, const CleanupListValue cleanup_value,
632 void * const cleanup_value_data) {
633 assert_non_null(node);
634 node->prev->next = node->next;
635 node->next->prev = node->prev;
636 if (cleanup_value) {
637 cleanup_value(node->value, cleanup_value_data);
639 return node;
643 /* Remove a list node from a list and free the node. */
644 static void list_remove_free(
645 ListNode * const node, const CleanupListValue cleanup_value,
646 void * const cleanup_value_data) {
647 assert_non_null(node);
648 free(list_remove(node, cleanup_value, cleanup_value_data));
653 * Frees memory kept by a linked list The cleanup_value function is called for
654 * every "value" field of nodes in the list, except for the head. In addition
655 * to each list value, cleanup_value_data is passed to each call to
656 * cleanup_value. The head of the list is not deallocated.
658 static ListNode* list_free(
659 ListNode * const head, const CleanupListValue cleanup_value,
660 void * const cleanup_value_data) {
661 assert_non_null(head);
662 while (!list_empty(head)) {
663 list_remove_free(head->next, cleanup_value, cleanup_value_data);
665 return head;
669 /* Determine whether a list is empty. */
670 static int list_empty(const ListNode * const head) {
671 assert_non_null(head);
672 return head->next == head;
677 * Find a value in the list using the equal_func to compare each node with the
678 * value.
680 static int list_find(ListNode * const head, const void *value,
681 const EqualityFunction equal_func, ListNode **output) {
682 ListNode *current;
683 assert_non_null(head);
684 for (current = head->next; current != head; current = current->next) {
685 if (equal_func(current->value, value)) {
686 *output = current;
687 return 1;
690 return 0;
693 /* Returns the first node of a list */
694 static int list_first(ListNode * const head, ListNode **output) {
695 ListNode *target_node = NULL;
696 assert_non_null(head);
697 if (list_empty(head)) {
698 return 0;
700 target_node = head->next;
701 *output = target_node;
702 return 1;
706 /* Deallocate a value referenced by a list. */
707 static void free_value(const void *value, void *cleanup_value_data) {
708 (void)cleanup_value_data;
709 assert_non_null(value);
710 free((void*)value);
714 /* Releases memory associated to a symbol_map_value. */
715 static void free_symbol_map_value(const void *value,
716 void *cleanup_value_data) {
717 SymbolMapValue * const map_value = (SymbolMapValue*)value;
718 const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
719 assert_non_null(value);
720 list_free(&map_value->symbol_values_list_head,
721 children ? free_symbol_map_value : free_value,
722 (void *) ((uintptr_t)children - 1));
723 free(map_value);
728 * Determine whether a symbol name referenced by a symbol_map_value matches the
729 * specified function name.
731 static int symbol_names_match(const void *map_value, const void *symbol) {
732 return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
733 (const char*)symbol);
737 * Adds a value to the queue of values associated with the given hierarchy of
738 * symbols. It's assumed value is allocated from the heap.
740 static void add_symbol_value(ListNode * const symbol_map_head,
741 const char * const symbol_names[],
742 const size_t number_of_symbol_names,
743 const void* value, const int refcount) {
744 const char* symbol_name;
745 ListNode *target_node;
746 SymbolMapValue *target_map_value;
747 assert_non_null(symbol_map_head);
748 assert_non_null(symbol_names);
749 assert_true(number_of_symbol_names);
750 symbol_name = symbol_names[0];
752 if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
753 &target_node)) {
754 SymbolMapValue * const new_symbol_map_value =
755 (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
756 new_symbol_map_value->symbol_name = symbol_name;
757 list_initialize(&new_symbol_map_value->symbol_values_list_head);
758 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
762 target_map_value = (SymbolMapValue*)target_node->value;
763 if (number_of_symbol_names == 1) {
764 list_add_value(&target_map_value->symbol_values_list_head,
765 value, refcount);
766 } else {
767 add_symbol_value(&target_map_value->symbol_values_list_head,
768 &symbol_names[1], number_of_symbol_names - 1, value,
769 refcount);
775 * Gets the next value associated with the given hierarchy of symbols.
776 * The value is returned as an output parameter with the function returning the
777 * node's old refcount value if a value is found, 0 otherwise. This means that
778 * a return value of 1 indicates the node was just removed from the list.
780 static int get_symbol_value(
781 ListNode * const head, const char * const symbol_names[],
782 const size_t number_of_symbol_names, void **output) {
783 const char* symbol_name = NULL;
784 ListNode *target_node = NULL;
785 assert_non_null(head);
786 assert_non_null(symbol_names);
787 assert_true(number_of_symbol_names);
788 assert_non_null(output);
789 symbol_name = symbol_names[0];
791 if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
792 SymbolMapValue *map_value = NULL;
793 ListNode *child_list = NULL;
794 int return_value = 0;
795 assert_non_null(target_node);
796 assert_non_null(target_node->value);
798 map_value = (SymbolMapValue*)target_node->value;
799 child_list = &map_value->symbol_values_list_head;
801 if (number_of_symbol_names == 1) {
802 ListNode *value_node = NULL;
803 return_value = list_first(child_list, &value_node);
804 assert_true(return_value);
805 /* Add a check to silence clang analyzer */
806 if (return_value == 0) {
807 goto out;
809 *output = (void*) value_node->value;
810 return_value = value_node->refcount;
811 if (value_node->refcount - 1 == 0) {
812 list_remove_free(value_node, NULL, NULL);
813 } else if (value_node->refcount > WILL_RETURN_ONCE) {
814 --value_node->refcount;
816 } else {
817 return_value = get_symbol_value(
818 child_list, &symbol_names[1], number_of_symbol_names - 1,
819 output);
821 if (list_empty(child_list)) {
822 list_remove_free(target_node, free_symbol_map_value, (void*)0);
824 return return_value;
826 out:
827 cm_print_error("No entries for symbol %s.\n", symbol_name);
828 return 0;
832 * Taverse a list of nodes and remove first symbol value in list that has a
833 * refcount < -1 (i.e. should always be returned and has been returned at
834 * least once).
837 static void remove_always_return_values_from_list(ListNode * const map_head)
839 ListNode * current = NULL;
840 ListNode * next = NULL;
841 assert_non_null(map_head);
843 for (current = map_head->next, next = current->next;
844 current != map_head;
845 current = next, next = current->next) {
846 if (current->refcount < -1) {
847 list_remove_free(current, free_value, NULL);
853 * Traverse down a tree of symbol values and remove the first symbol value
854 * in each branch that has a refcount < -1 (i.e should always be returned
855 * and has been returned at least once).
857 static void remove_always_return_values(ListNode * const map_head,
858 const size_t number_of_symbol_names) {
859 ListNode *current;
860 assert_non_null(map_head);
861 assert_true(number_of_symbol_names);
862 current = map_head->next;
863 while (current != map_head) {
864 SymbolMapValue * const value = (SymbolMapValue*)current->value;
865 ListNode * const next = current->next;
866 ListNode *child_list;
867 assert_non_null(value);
868 child_list = &value->symbol_values_list_head;
870 if (!list_empty(child_list)) {
871 if (number_of_symbol_names == 1) {
872 ListNode * const child_node = child_list->next;
873 /* If this item has been returned more than once, free it. */
874 if (child_node->refcount < -1) {
875 list_remove_free(child_node, free_value, NULL);
877 } else {
878 remove_always_return_values(child_list,
879 number_of_symbol_names - 1);
883 if (list_empty(child_list)) {
884 list_remove_free(current, free_value, NULL);
886 current = next;
890 static size_t check_for_leftover_values_list(const ListNode * head,
891 const char * const error_message)
893 ListNode *child_node;
894 size_t leftover_count = 0;
895 if (!list_empty(head))
897 for (child_node = head->next; child_node != head;
898 child_node = child_node->next, ++leftover_count) {
899 const FuncOrderingValue *const o =
900 (const FuncOrderingValue*) child_node->value;
901 cm_print_error(error_message, o->function);
902 cm_print_error(SOURCE_LOCATION_FORMAT
903 ": note: remaining item was declared here\n",
904 o->location.file, o->location.line);
907 return leftover_count;
911 * Checks if there are any leftover values set up by the test that were never
912 * retrieved through execution, and fail the test if that is the case.
914 static size_t check_for_leftover_values(
915 const ListNode * const map_head, const char * const error_message,
916 const size_t number_of_symbol_names) {
917 const ListNode *current;
918 size_t symbols_with_leftover_values = 0;
919 assert_non_null(map_head);
920 assert_true(number_of_symbol_names);
922 for (current = map_head->next; current != map_head;
923 current = current->next) {
924 const SymbolMapValue * const value =
925 (SymbolMapValue*)current->value;
926 const ListNode *child_list;
927 assert_non_null(value);
928 child_list = &value->symbol_values_list_head;
930 if (!list_empty(child_list)) {
931 if (number_of_symbol_names == 1) {
932 const ListNode *child_node;
933 cm_print_error(error_message, value->symbol_name);
935 for (child_node = child_list->next; child_node != child_list;
936 child_node = child_node->next) {
937 const SourceLocation * const location =
938 (const SourceLocation*)child_node->value;
939 cm_print_error(SOURCE_LOCATION_FORMAT
940 ": note: remaining item was declared here\n",
941 location->file, location->line);
943 } else {
944 cm_print_error("%s: ", value->symbol_name);
945 check_for_leftover_values(child_list, error_message,
946 number_of_symbol_names - 1);
948 symbols_with_leftover_values ++;
951 return symbols_with_leftover_values;
955 /* Get the next return value for the specified mock function. */
956 LargestIntegralType _mock(const char * const function, const char* const file,
957 const int line) {
958 void *result;
959 const int rc = get_symbol_value(&global_function_result_map_head,
960 &function, 1, &result);
961 if (rc) {
962 SymbolValue * const symbol = (SymbolValue*)result;
963 const LargestIntegralType value = symbol->value;
964 global_last_mock_value_location = symbol->location;
965 if (rc == 1) {
966 free(symbol);
968 return value;
969 } else {
970 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
971 "to mock function %s\n", file, line, function);
972 if (source_location_is_set(&global_last_mock_value_location)) {
973 cm_print_error(SOURCE_LOCATION_FORMAT
974 ": note: Previously returned mock value was declared here\n",
975 global_last_mock_value_location.file,
976 global_last_mock_value_location.line);
977 } else {
978 cm_print_error("There were no previously returned mock values for "
979 "this test.\n");
981 exit_test(1);
983 return 0;
986 /* Ensure that function is being called in proper order */
987 void _function_called(const char *const function,
988 const char *const file,
989 const int line)
991 ListNode *first_value_node = NULL;
992 ListNode *value_node = NULL;
993 int rc;
995 rc = list_first(&global_call_ordering_head, &value_node);
996 first_value_node = value_node;
997 if (rc) {
998 FuncOrderingValue *expected_call;
999 int cmp;
1001 expected_call = (FuncOrderingValue *)value_node->value;
1003 cmp = strcmp(expected_call->function, function);
1004 if (value_node->refcount < -1) {
1006 * Search through value nodes until either function is found or
1007 * encounter a non-zero refcount greater than -2
1009 if (cmp != 0) {
1010 value_node = value_node->next;
1011 expected_call = (FuncOrderingValue *)value_node->value;
1013 cmp = strcmp(expected_call->function, function);
1014 while (value_node->refcount < -1 &&
1015 cmp != 0 &&
1016 value_node != first_value_node->prev) {
1017 value_node = value_node->next;
1018 if (value_node == NULL) {
1019 break;
1021 expected_call = (FuncOrderingValue *)value_node->value;
1022 if (expected_call == NULL) {
1023 continue;
1025 cmp = strcmp(expected_call->function, function);
1028 if (expected_call == NULL || value_node == first_value_node->prev) {
1029 cm_print_error(SOURCE_LOCATION_FORMAT
1030 ": error: No expected mock calls matching "
1031 "called() invocation in %s",
1032 file, line,
1033 function);
1034 exit_test(1);
1039 if (cmp == 0) {
1040 if (value_node->refcount > -2 && --value_node->refcount == 0) {
1041 list_remove_free(value_node, free_value, NULL);
1043 } else {
1044 cm_print_error(SOURCE_LOCATION_FORMAT
1045 ": error: Expected call to %s but received called() "
1046 "in %s\n",
1047 file, line,
1048 expected_call->function,
1049 function);
1050 exit_test(1);
1052 } else {
1053 cm_print_error(SOURCE_LOCATION_FORMAT
1054 ": error: No mock calls expected but called() was "
1055 "invoked in %s\n",
1056 file, line,
1057 function);
1058 exit_test(1);
1062 /* Add a return value for the specified mock function name. */
1063 void _will_return(const char * const function_name, const char * const file,
1064 const int line, const LargestIntegralType value,
1065 const int count) {
1066 SymbolValue * const return_value =
1067 (SymbolValue*)malloc(sizeof(*return_value));
1068 assert_true(count != 0);
1069 return_value->value = value;
1070 set_source_location(&return_value->location, file, line);
1071 add_symbol_value(&global_function_result_map_head, &function_name, 1,
1072 return_value, count);
1077 * Add a custom parameter checking function. If the event parameter is NULL
1078 * the event structure is allocated internally by this function. If event
1079 * parameter is provided it must be allocated on the heap and doesn't need to
1080 * be deallocated by the caller.
1082 void _expect_check(
1083 const char* const function, const char* const parameter,
1084 const char* const file, const int line,
1085 const CheckParameterValue check_function,
1086 const LargestIntegralType check_data,
1087 CheckParameterEvent * const event, const int count) {
1088 CheckParameterEvent * const check =
1089 event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
1090 const char* symbols[] = {function, parameter};
1091 check->parameter_name = parameter;
1092 check->check_value = check_function;
1093 check->check_value_data = check_data;
1094 set_source_location(&check->location, file, line);
1095 add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
1096 count);
1100 * Add an call expectations that a particular function is called correctly.
1101 * This is used for code under test that makes calls to several functions
1102 * in depended upon components (mocks).
1105 void _expect_function_call(
1106 const char * const function_name,
1107 const char * const file,
1108 const int line,
1109 const int count)
1111 FuncOrderingValue *ordering;
1113 assert_non_null(function_name);
1114 assert_non_null(file);
1115 assert_true(count != 0);
1117 ordering = (FuncOrderingValue *)malloc(sizeof(*ordering));
1119 set_source_location(&ordering->location, file, line);
1120 ordering->function = function_name;
1122 list_add_value(&global_call_ordering_head, ordering, count);
1125 /* Returns 1 if the specified values are equal. If the values are not equal
1126 * an error is displayed and 0 is returned. */
1127 static int values_equal_display_error(const LargestIntegralType left,
1128 const LargestIntegralType right) {
1129 const int equal = left == right;
1130 if (!equal) {
1131 cm_print_error(LargestIntegralTypePrintfFormat " != "
1132 LargestIntegralTypePrintfFormat "\n", left, right);
1134 return equal;
1138 * Returns 1 if the specified values are not equal. If the values are equal
1139 * an error is displayed and 0 is returned. */
1140 static int values_not_equal_display_error(const LargestIntegralType left,
1141 const LargestIntegralType right) {
1142 const int not_equal = left != right;
1143 if (!not_equal) {
1144 cm_print_error(LargestIntegralTypePrintfFormat " == "
1145 LargestIntegralTypePrintfFormat "\n", left, right);
1147 return not_equal;
1152 * Determine whether value is contained within check_integer_set.
1153 * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
1154 * returned and an error is displayed. If invert is 1 and the value is not
1155 * in the set 1 is returned, otherwise 0 is returned and an error is
1156 * displayed.
1158 static int value_in_set_display_error(
1159 const LargestIntegralType value,
1160 const CheckIntegerSet * const check_integer_set, const int invert) {
1161 int succeeded = invert;
1162 assert_non_null(check_integer_set);
1164 const LargestIntegralType * const set = check_integer_set->set;
1165 const size_t size_of_set = check_integer_set->size_of_set;
1166 size_t i;
1167 for (i = 0; i < size_of_set; i++) {
1168 if (set[i] == value) {
1169 /* If invert = 0 and item is found, succeeded = 1. */
1170 /* If invert = 1 and item is found, succeeded = 0. */
1171 succeeded = !succeeded;
1172 break;
1175 if (succeeded) {
1176 return 1;
1178 cm_print_error(LargestIntegralTypePrintfFormatDecimal
1179 " is %sin the set (",
1180 value, invert ? "" : "not ");
1181 for (i = 0; i < size_of_set; i++) {
1182 cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]);
1184 cm_print_error(")\n");
1186 return 0;
1191 * Determine whether a value is within the specified range. If the value is
1192 * within the specified range 1 is returned. If the value isn't within the
1193 * specified range an error is displayed and 0 is returned.
1195 static int integer_in_range_display_error(
1196 const LargestIntegralType value, const LargestIntegralType range_min,
1197 const LargestIntegralType range_max) {
1198 if (value >= range_min && value <= range_max) {
1199 return 1;
1201 cm_print_error(LargestIntegralTypePrintfFormatDecimal
1202 " is not within the range "
1203 LargestIntegralTypePrintfFormatDecimal "-"
1204 LargestIntegralTypePrintfFormatDecimal "\n",
1205 value, range_min, range_max);
1206 return 0;
1211 * Determine whether a value is within the specified range. If the value
1212 * is not within the range 1 is returned. If the value is within the
1213 * specified range an error is displayed and zero is returned.
1215 static int integer_not_in_range_display_error(
1216 const LargestIntegralType value, const LargestIntegralType range_min,
1217 const LargestIntegralType range_max) {
1218 if (value < range_min || value > range_max) {
1219 return 1;
1221 cm_print_error(LargestIntegralTypePrintfFormatDecimal
1222 " is within the range "
1223 LargestIntegralTypePrintfFormatDecimal "-"
1224 LargestIntegralTypePrintfFormatDecimal "\n",
1225 value, range_min, range_max);
1226 return 0;
1231 * Determine whether the specified strings are equal. If the strings are equal
1232 * 1 is returned. If they're not equal an error is displayed and 0 is
1233 * returned.
1235 static int string_equal_display_error(
1236 const char * const left, const char * const right) {
1237 if (strcmp(left, right) == 0) {
1238 return 1;
1240 cm_print_error("\"%s\" != \"%s\"\n", left, right);
1241 return 0;
1246 * Determine whether the specified strings are equal. If the strings are not
1247 * equal 1 is returned. If they're not equal an error is displayed and 0 is
1248 * returned
1250 static int string_not_equal_display_error(
1251 const char * const left, const char * const right) {
1252 if (strcmp(left, right) != 0) {
1253 return 1;
1255 cm_print_error("\"%s\" == \"%s\"\n", left, right);
1256 return 0;
1261 * Determine whether the specified areas of memory are equal. If they're equal
1262 * 1 is returned otherwise an error is displayed and 0 is returned.
1264 static int memory_equal_display_error(const char* const a, const char* const b,
1265 const size_t size) {
1266 size_t differences = 0;
1267 size_t i;
1268 for (i = 0; i < size; i++) {
1269 const char l = a[i];
1270 const char r = b[i];
1271 if (l != r) {
1272 if (differences < 16) {
1273 cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
1274 i, l, r);
1276 differences ++;
1279 if (differences > 0) {
1280 if (differences >= 16) {
1281 cm_print_error("...\n");
1283 cm_print_error("%"PRIdS " bytes of %p and %p differ\n",
1284 differences, (void *)a, (void *)b);
1285 return 0;
1287 return 1;
1292 * Determine whether the specified areas of memory are not equal. If they're
1293 * not equal 1 is returned otherwise an error is displayed and 0 is
1294 * returned.
1296 static int memory_not_equal_display_error(
1297 const char* const a, const char* const b, const size_t size) {
1298 size_t same = 0;
1299 size_t i;
1300 for (i = 0; i < size; i++) {
1301 const char l = a[i];
1302 const char r = b[i];
1303 if (l == r) {
1304 same ++;
1307 if (same == size) {
1308 cm_print_error("%"PRIdS "bytes of %p and %p the same\n",
1309 same, (void *)a, (void *)b);
1310 return 0;
1312 return 1;
1316 /* CheckParameterValue callback to check whether a value is within a set. */
1317 static int check_in_set(const LargestIntegralType value,
1318 const LargestIntegralType check_value_data) {
1319 return value_in_set_display_error(value,
1320 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1321 check_value_data), 0);
1325 /* CheckParameterValue callback to check whether a value isn't within a set. */
1326 static int check_not_in_set(const LargestIntegralType value,
1327 const LargestIntegralType check_value_data) {
1328 return value_in_set_display_error(value,
1329 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1330 check_value_data), 1);
1334 /* Create the callback data for check_in_set() or check_not_in_set() and
1335 * register a check event. */
1336 static void expect_set(
1337 const char* const function, const char* const parameter,
1338 const char* const file, const int line,
1339 const LargestIntegralType values[], const size_t number_of_values,
1340 const CheckParameterValue check_function, const int count) {
1341 CheckIntegerSet * const check_integer_set =
1342 (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
1343 (sizeof(values[0]) * number_of_values));
1344 LargestIntegralType * const set = (LargestIntegralType*)(
1345 check_integer_set + 1);
1346 declare_initialize_value_pointer_pointer(check_data, check_integer_set);
1347 assert_non_null(values);
1348 assert_true(number_of_values);
1349 memcpy(set, values, number_of_values * sizeof(values[0]));
1350 check_integer_set->set = set;
1351 check_integer_set->size_of_set = number_of_values;
1352 _expect_check(
1353 function, parameter, file, line, check_function,
1354 check_data.value, &check_integer_set->event, count);
1358 /* Add an event to check whether a value is in a set. */
1359 void _expect_in_set(
1360 const char* const function, const char* const parameter,
1361 const char* const file, const int line,
1362 const LargestIntegralType values[], const size_t number_of_values,
1363 const int count) {
1364 expect_set(function, parameter, file, line, values, number_of_values,
1365 check_in_set, count);
1369 /* Add an event to check whether a value isn't in a set. */
1370 void _expect_not_in_set(
1371 const char* const function, const char* const parameter,
1372 const char* const file, const int line,
1373 const LargestIntegralType values[], const size_t number_of_values,
1374 const int count) {
1375 expect_set(function, parameter, file, line, values, number_of_values,
1376 check_not_in_set, count);
1380 /* CheckParameterValue callback to check whether a value is within a range. */
1381 static int check_in_range(const LargestIntegralType value,
1382 const LargestIntegralType check_value_data) {
1383 CheckIntegerRange * const check_integer_range =
1384 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1385 check_value_data);
1386 assert_non_null(check_integer_range);
1387 return integer_in_range_display_error(value, check_integer_range->minimum,
1388 check_integer_range->maximum);
1392 /* CheckParameterValue callback to check whether a value is not within a range. */
1393 static int check_not_in_range(const LargestIntegralType value,
1394 const LargestIntegralType check_value_data) {
1395 CheckIntegerRange * const check_integer_range =
1396 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1397 check_value_data);
1398 assert_non_null(check_integer_range);
1399 return integer_not_in_range_display_error(
1400 value, check_integer_range->minimum, check_integer_range->maximum);
1404 /* Create the callback data for check_in_range() or check_not_in_range() and
1405 * register a check event. */
1406 static void expect_range(
1407 const char* const function, const char* const parameter,
1408 const char* const file, const int line,
1409 const LargestIntegralType minimum, const LargestIntegralType maximum,
1410 const CheckParameterValue check_function, const int count) {
1411 CheckIntegerRange * const check_integer_range =
1412 (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
1413 declare_initialize_value_pointer_pointer(check_data, check_integer_range);
1414 check_integer_range->minimum = minimum;
1415 check_integer_range->maximum = maximum;
1416 _expect_check(function, parameter, file, line, check_function,
1417 check_data.value, &check_integer_range->event, count);
1421 /* Add an event to determine whether a parameter is within a range. */
1422 void _expect_in_range(
1423 const char* const function, const char* const parameter,
1424 const char* const file, const int line,
1425 const LargestIntegralType minimum, const LargestIntegralType maximum,
1426 const int count) {
1427 expect_range(function, parameter, file, line, minimum, maximum,
1428 check_in_range, count);
1432 /* Add an event to determine whether a parameter is not within a range. */
1433 void _expect_not_in_range(
1434 const char* const function, const char* const parameter,
1435 const char* const file, const int line,
1436 const LargestIntegralType minimum, const LargestIntegralType maximum,
1437 const int count) {
1438 expect_range(function, parameter, file, line, minimum, maximum,
1439 check_not_in_range, count);
1443 /* CheckParameterValue callback to check whether a value is equal to an
1444 * expected value. */
1445 static int check_value(const LargestIntegralType value,
1446 const LargestIntegralType check_value_data) {
1447 return values_equal_display_error(value, check_value_data);
1451 /* Add an event to check a parameter equals an expected value. */
1452 void _expect_value(
1453 const char* const function, const char* const parameter,
1454 const char* const file, const int line,
1455 const LargestIntegralType value, const int count) {
1456 _expect_check(function, parameter, file, line, check_value, value, NULL,
1457 count);
1461 /* CheckParameterValue callback to check whether a value is not equal to an
1462 * expected value. */
1463 static int check_not_value(const LargestIntegralType value,
1464 const LargestIntegralType check_value_data) {
1465 return values_not_equal_display_error(value, check_value_data);
1469 /* Add an event to check a parameter is not equal to an expected value. */
1470 void _expect_not_value(
1471 const char* const function, const char* const parameter,
1472 const char* const file, const int line,
1473 const LargestIntegralType value, const int count) {
1474 _expect_check(function, parameter, file, line, check_not_value, value,
1475 NULL, count);
1479 /* CheckParameterValue callback to check whether a parameter equals a string. */
1480 static int check_string(const LargestIntegralType value,
1481 const LargestIntegralType check_value_data) {
1482 return string_equal_display_error(
1483 cast_largest_integral_type_to_pointer(char*, value),
1484 cast_largest_integral_type_to_pointer(char*, check_value_data));
1488 /* Add an event to check whether a parameter is equal to a string. */
1489 void _expect_string(
1490 const char* const function, const char* const parameter,
1491 const char* const file, const int line, const char* string,
1492 const int count) {
1493 declare_initialize_value_pointer_pointer(string_pointer,
1494 discard_const(string));
1495 _expect_check(function, parameter, file, line, check_string,
1496 string_pointer.value, NULL, count);
1500 /* CheckParameterValue callback to check whether a parameter is not equals to
1501 * a string. */
1502 static int check_not_string(const LargestIntegralType value,
1503 const LargestIntegralType check_value_data) {
1504 return string_not_equal_display_error(
1505 cast_largest_integral_type_to_pointer(char*, value),
1506 cast_largest_integral_type_to_pointer(char*, check_value_data));
1510 /* Add an event to check whether a parameter is not equal to a string. */
1511 void _expect_not_string(
1512 const char* const function, const char* const parameter,
1513 const char* const file, const int line, const char* string,
1514 const int count) {
1515 declare_initialize_value_pointer_pointer(string_pointer,
1516 discard_const(string));
1517 _expect_check(function, parameter, file, line, check_not_string,
1518 string_pointer.value, NULL, count);
1521 /* CheckParameterValue callback to check whether a parameter equals an area of
1522 * memory. */
1523 static int check_memory(const LargestIntegralType value,
1524 const LargestIntegralType check_value_data) {
1525 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1526 CheckMemoryData*, check_value_data);
1527 assert_non_null(check);
1528 return memory_equal_display_error(
1529 cast_largest_integral_type_to_pointer(const char*, value),
1530 (const char*)check->memory, check->size);
1534 /* Create the callback data for check_memory() or check_not_memory() and
1535 * register a check event. */
1536 static void expect_memory_setup(
1537 const char* const function, const char* const parameter,
1538 const char* const file, const int line,
1539 const void * const memory, const size_t size,
1540 const CheckParameterValue check_function, const int count) {
1541 CheckMemoryData * const check_data =
1542 (CheckMemoryData*)malloc(sizeof(*check_data) + size);
1543 void * const mem = (void*)(check_data + 1);
1544 declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1545 assert_non_null(memory);
1546 assert_true(size);
1547 memcpy(mem, memory, size);
1548 check_data->memory = mem;
1549 check_data->size = size;
1550 _expect_check(function, parameter, file, line, check_function,
1551 check_data_pointer.value, &check_data->event, count);
1555 /* Add an event to check whether a parameter matches an area of memory. */
1556 void _expect_memory(
1557 const char* const function, const char* const parameter,
1558 const char* const file, const int line, const void* const memory,
1559 const size_t size, const int count) {
1560 expect_memory_setup(function, parameter, file, line, memory, size,
1561 check_memory, count);
1565 /* CheckParameterValue callback to check whether a parameter is not equal to
1566 * an area of memory. */
1567 static int check_not_memory(const LargestIntegralType value,
1568 const LargestIntegralType check_value_data) {
1569 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1570 CheckMemoryData*, check_value_data);
1571 assert_non_null(check);
1572 return memory_not_equal_display_error(
1573 cast_largest_integral_type_to_pointer(const char*, value),
1574 (const char*)check->memory,
1575 check->size);
1579 /* Add an event to check whether a parameter doesn't match an area of memory. */
1580 void _expect_not_memory(
1581 const char* const function, const char* const parameter,
1582 const char* const file, const int line, const void* const memory,
1583 const size_t size, const int count) {
1584 expect_memory_setup(function, parameter, file, line, memory, size,
1585 check_not_memory, count);
1589 /* CheckParameterValue callback that always returns 1. */
1590 static int check_any(const LargestIntegralType value,
1591 const LargestIntegralType check_value_data) {
1592 (void)value;
1593 (void)check_value_data;
1594 return 1;
1598 /* Add an event to allow any value for a parameter. */
1599 void _expect_any(
1600 const char* const function, const char* const parameter,
1601 const char* const file, const int line, const int count) {
1602 _expect_check(function, parameter, file, line, check_any, 0, NULL,
1603 count);
1607 void _check_expected(
1608 const char * const function_name, const char * const parameter_name,
1609 const char* file, const int line, const LargestIntegralType value) {
1610 void *result = NULL;
1611 const char* symbols[] = {function_name, parameter_name};
1612 const int rc = get_symbol_value(&global_function_parameter_map_head,
1613 symbols, 2, &result);
1614 if (rc) {
1615 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1616 int check_succeeded;
1617 global_last_parameter_location = check->location;
1618 check_succeeded = check->check_value(value, check->check_value_data);
1619 if (rc == 1) {
1620 free(check);
1622 if (!check_succeeded) {
1623 cm_print_error(SOURCE_LOCATION_FORMAT
1624 ": error: Check of parameter %s, function %s failed\n"
1625 SOURCE_LOCATION_FORMAT
1626 ": note: Expected parameter declared here\n",
1627 file, line,
1628 parameter_name, function_name,
1629 global_last_parameter_location.file,
1630 global_last_parameter_location.line);
1631 _fail(file, line);
1633 } else {
1634 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
1635 "to check parameter %s of function %s\n", file, line,
1636 parameter_name, function_name);
1637 if (source_location_is_set(&global_last_parameter_location)) {
1638 cm_print_error(SOURCE_LOCATION_FORMAT
1639 ": note: Previously declared parameter value was declared here\n",
1640 global_last_parameter_location.file,
1641 global_last_parameter_location.line);
1642 } else {
1643 cm_print_error("There were no previously declared parameter values "
1644 "for this test.\n");
1646 exit_test(1);
1651 /* Replacement for assert. */
1652 void mock_assert(const int result, const char* const expression,
1653 const char* const file, const int line) {
1654 if (!result) {
1655 if (global_expecting_assert) {
1656 global_last_failed_assert = expression;
1657 longjmp(global_expect_assert_env, result);
1658 } else {
1659 cm_print_error("ASSERT: %s\n", expression);
1660 _fail(file, line);
1666 void _assert_true(const LargestIntegralType result,
1667 const char * const expression,
1668 const char * const file, const int line) {
1669 if (!result) {
1670 cm_print_error("%s\n", expression);
1671 _fail(file, line);
1675 void _assert_return_code(const LargestIntegralType result,
1676 size_t rlen,
1677 const LargestIntegralType error,
1678 const char * const expression,
1679 const char * const file,
1680 const int line)
1682 LargestIntegralType valmax;
1685 switch (rlen) {
1686 case 1:
1687 valmax = 255;
1688 break;
1689 case 2:
1690 valmax = 32767;
1691 break;
1692 case 4:
1693 valmax = 2147483647;
1694 break;
1695 case 8:
1696 default:
1697 if (rlen > sizeof(valmax)) {
1698 valmax = 2147483647;
1699 } else {
1700 valmax = 9223372036854775807L;
1702 break;
1705 if (result > valmax - 1) {
1706 if (error > 0) {
1707 cm_print_error("%s < 0, errno("
1708 LargestIntegralTypePrintfFormatDecimal "): %s\n",
1709 expression, error, strerror((int)error));
1710 } else {
1711 cm_print_error("%s < 0\n", expression);
1713 _fail(file, line);
1717 void _assert_int_equal(
1718 const LargestIntegralType a, const LargestIntegralType b,
1719 const char * const file, const int line) {
1720 if (!values_equal_display_error(a, b)) {
1721 _fail(file, line);
1726 void _assert_int_not_equal(
1727 const LargestIntegralType a, const LargestIntegralType b,
1728 const char * const file, const int line) {
1729 if (!values_not_equal_display_error(a, b)) {
1730 _fail(file, line);
1735 void _assert_string_equal(const char * const a, const char * const b,
1736 const char * const file, const int line) {
1737 if (!string_equal_display_error(a, b)) {
1738 _fail(file, line);
1743 void _assert_string_not_equal(const char * const a, const char * const b,
1744 const char *file, const int line) {
1745 if (!string_not_equal_display_error(a, b)) {
1746 _fail(file, line);
1751 void _assert_memory_equal(const void * const a, const void * const b,
1752 const size_t size, const char* const file,
1753 const int line) {
1754 if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1755 _fail(file, line);
1760 void _assert_memory_not_equal(const void * const a, const void * const b,
1761 const size_t size, const char* const file,
1762 const int line) {
1763 if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1764 size)) {
1765 _fail(file, line);
1770 void _assert_in_range(
1771 const LargestIntegralType value, const LargestIntegralType minimum,
1772 const LargestIntegralType maximum, const char* const file,
1773 const int line) {
1774 if (!integer_in_range_display_error(value, minimum, maximum)) {
1775 _fail(file, line);
1779 void _assert_not_in_range(
1780 const LargestIntegralType value, const LargestIntegralType minimum,
1781 const LargestIntegralType maximum, const char* const file,
1782 const int line) {
1783 if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1784 _fail(file, line);
1788 void _assert_in_set(const LargestIntegralType value,
1789 const LargestIntegralType values[],
1790 const size_t number_of_values, const char* const file,
1791 const int line) {
1792 CheckIntegerSet check_integer_set;
1793 check_integer_set.set = values;
1794 check_integer_set.size_of_set = number_of_values;
1795 if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1796 _fail(file, line);
1800 void _assert_not_in_set(const LargestIntegralType value,
1801 const LargestIntegralType values[],
1802 const size_t number_of_values, const char* const file,
1803 const int line) {
1804 CheckIntegerSet check_integer_set;
1805 check_integer_set.set = values;
1806 check_integer_set.size_of_set = number_of_values;
1807 if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1808 _fail(file, line);
1813 /* Get the list of allocated blocks. */
1814 static ListNode* get_allocated_blocks_list(void) {
1815 /* If it initialized, initialize the list of allocated blocks. */
1816 if (!global_allocated_blocks.value) {
1817 list_initialize(&global_allocated_blocks);
1818 global_allocated_blocks.value = (void*)1;
1820 return &global_allocated_blocks;
1823 static void *libc_malloc(size_t size)
1825 #undef malloc
1826 return malloc(size);
1827 #define malloc test_malloc
1830 static void libc_free(void *ptr)
1832 #undef free
1833 free(ptr);
1834 #define free test_free
1837 static void *libc_realloc(void *ptr, size_t size)
1839 #undef realloc
1840 return realloc(ptr, size);
1841 #define realloc test_realloc
1844 static void vcm_print_error(const char* const format,
1845 va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
1847 /* It's important to use the libc malloc and free here otherwise
1848 * the automatic free of leaked blocks can reap the error messages
1850 static void vcm_print_error(const char* const format, va_list args)
1852 char buffer[1024];
1853 size_t msg_len = 0;
1854 va_list ap;
1855 int len;
1856 va_copy(ap, args);
1858 len = vsnprintf(buffer, sizeof(buffer), format, args);
1859 if (len < 0) {
1860 /* TODO */
1861 goto end;
1864 if (cm_error_message == NULL) {
1865 /* CREATE MESSAGE */
1867 cm_error_message = libc_malloc(len + 1);
1868 if (cm_error_message == NULL) {
1869 /* TODO */
1870 goto end;
1872 } else {
1873 /* APPEND MESSAGE */
1874 char *tmp;
1876 msg_len = strlen(cm_error_message);
1877 tmp = libc_realloc(cm_error_message, msg_len + len + 1);
1878 if (tmp == NULL) {
1879 goto end;
1881 cm_error_message = tmp;
1884 if (((size_t)len) < sizeof(buffer)) {
1885 /* Use len + 1 to also copy '\0' */
1886 memcpy(cm_error_message + msg_len, buffer, len + 1);
1887 } else {
1888 vsnprintf(cm_error_message + msg_len, len, format, ap);
1890 end:
1891 va_end(ap);
1895 static void vcm_free_error(char *err_msg)
1897 libc_free(err_msg);
1900 /* Use the real malloc in this function. */
1901 #undef malloc
1902 void* _test_malloc(const size_t size, const char* file, const int line) {
1903 char *ptr = NULL;
1904 MallocBlockInfo block_info;
1905 ListNode * const block_list = get_allocated_blocks_list();
1906 size_t allocate_size;
1907 char *block = NULL;
1909 allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
1910 sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT;
1911 assert_true(allocate_size > size);
1913 block = (char *)malloc(allocate_size);
1914 assert_non_null(block);
1916 /* Calculate the returned address. */
1917 ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE +
1918 sizeof(struct MallocBlockInfoData) +
1919 MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1921 /* Initialize the guard blocks. */
1922 memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1923 memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1924 memset(ptr, MALLOC_ALLOC_PATTERN, size);
1926 block_info.ptr = ptr - (MALLOC_GUARD_SIZE +
1927 sizeof(struct MallocBlockInfoData));
1928 set_source_location(&block_info.data->location, file, line);
1929 block_info.data->allocated_size = allocate_size;
1930 block_info.data->size = size;
1931 block_info.data->block = block;
1932 block_info.data->node.value = block_info.ptr;
1933 list_add(block_list, &block_info.data->node);
1934 return ptr;
1936 #define malloc test_malloc
1939 void* _test_calloc(const size_t number_of_elements, const size_t size,
1940 const char* file, const int line) {
1941 void* const ptr = _test_malloc(number_of_elements * size, file, line);
1942 if (ptr) {
1943 memset(ptr, 0, number_of_elements * size);
1945 return ptr;
1949 /* Use the real free in this function. */
1950 #undef free
1951 void _test_free(void* const ptr, const char* file, const int line) {
1952 unsigned int i;
1953 char *block = discard_const_p(char, ptr);
1954 MallocBlockInfo block_info;
1956 if (ptr == NULL) {
1957 return;
1960 _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
1961 block_info.ptr = block - (MALLOC_GUARD_SIZE +
1962 sizeof(struct MallocBlockInfoData));
1963 /* Check the guard blocks. */
1965 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1966 block + block_info.data->size};
1967 for (i = 0; i < ARRAY_SIZE(guards); i++) {
1968 unsigned int j;
1969 char * const guard = guards[i];
1970 for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1971 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1972 if (diff) {
1973 cm_print_error(SOURCE_LOCATION_FORMAT
1974 ": error: Guard block of %p size=%lu is corrupt\n"
1975 SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
1976 file,
1977 line,
1978 ptr,
1979 (unsigned long)block_info.data->size,
1980 block_info.data->location.file,
1981 block_info.data->location.line,
1982 (void *)&guard[j]);
1983 _fail(file, line);
1988 list_remove(&block_info.data->node, NULL, NULL);
1990 block = discard_const_p(char, block_info.data->block);
1991 memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size);
1992 free(block);
1994 #define free test_free
1996 #undef realloc
1997 void *_test_realloc(void *ptr,
1998 const size_t size,
1999 const char *file,
2000 const int line)
2002 MallocBlockInfo block_info;
2003 char *block = ptr;
2004 size_t block_size = size;
2005 void *new_block;
2007 if (ptr == NULL) {
2008 return _test_malloc(size, file, line);
2011 if (size == 0) {
2012 _test_free(ptr, file, line);
2013 return NULL;
2016 block_info.ptr = block - (MALLOC_GUARD_SIZE +
2017 sizeof(struct MallocBlockInfoData));
2019 new_block = _test_malloc(size, file, line);
2020 if (new_block == NULL) {
2021 return NULL;
2024 if (block_info.data->size < size) {
2025 block_size = block_info.data->size;
2028 memcpy(new_block, ptr, block_size);
2030 /* Free previous memory */
2031 _test_free(ptr, file, line);
2033 return new_block;
2035 #define realloc test_realloc
2037 /* Crudely checkpoint the current heap state. */
2038 static const ListNode* check_point_allocated_blocks(void) {
2039 return get_allocated_blocks_list()->prev;
2043 /* Display the blocks allocated after the specified check point. This
2044 * function returns the number of blocks displayed. */
2045 static size_t display_allocated_blocks(const ListNode * const check_point) {
2046 const ListNode * const head = get_allocated_blocks_list();
2047 const ListNode *node;
2048 size_t allocated_blocks = 0;
2049 assert_non_null(check_point);
2050 assert_non_null(check_point->next);
2052 for (node = check_point->next; node != head; node = node->next) {
2053 const MallocBlockInfo block_info = {
2054 .ptr = discard_const(node->value),
2056 assert_non_null(block_info.ptr);
2058 if (allocated_blocks == 0) {
2059 cm_print_error("Blocks allocated...\n");
2061 cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
2062 block_info.data->location.file,
2063 block_info.data->location.line,
2064 block_info.data->block);
2065 allocated_blocks++;
2067 return allocated_blocks;
2071 /* Free all blocks allocated after the specified check point. */
2072 static void free_allocated_blocks(const ListNode * const check_point) {
2073 const ListNode * const head = get_allocated_blocks_list();
2074 const ListNode *node;
2075 assert_non_null(check_point);
2077 node = check_point->next;
2078 assert_non_null(node);
2080 while (node != head) {
2081 const MallocBlockInfo block_info = {
2082 .ptr = discard_const(node->value),
2084 node = node->next;
2085 free(discard_const_p(char, block_info.data) +
2086 sizeof(struct MallocBlockInfoData) +
2087 MALLOC_GUARD_SIZE);
2092 /* Fail if any any blocks are allocated after the specified check point. */
2093 static void fail_if_blocks_allocated(const ListNode * const check_point,
2094 const char * const test_name) {
2095 const size_t allocated_blocks = display_allocated_blocks(check_point);
2096 if (allocated_blocks > 0) {
2097 free_allocated_blocks(check_point);
2098 cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name,
2099 allocated_blocks);
2100 exit_test(1);
2105 void _fail(const char * const file, const int line) {
2106 enum cm_message_output output = cm_get_output();
2108 switch(output) {
2109 case CM_OUTPUT_STDOUT:
2110 cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
2111 break;
2112 default:
2113 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
2114 break;
2116 exit_test(1);
2120 #ifndef _WIN32
2121 static void exception_handler(int sig) {
2122 const char *sig_strerror = "";
2124 #ifdef HAVE_STRSIGNAL
2125 sig_strerror = strsignal(sig);
2126 #endif
2128 cm_print_error("Test failed with exception: %s(%d)",
2129 sig_strerror, sig);
2130 exit_test(1);
2133 #else /* _WIN32 */
2135 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
2136 EXCEPTION_RECORD * const exception_record =
2137 exception_pointers->ExceptionRecord;
2138 const DWORD code = exception_record->ExceptionCode;
2139 unsigned int i;
2140 for (i = 0; i < ARRAY_SIZE(exception_codes); i++) {
2141 const ExceptionCodeInfo * const code_info = &exception_codes[i];
2142 if (code == code_info->code) {
2143 static int shown_debug_message = 0;
2144 fflush(stdout);
2145 cm_print_error("%s occurred at %p.\n", code_info->description,
2146 exception_record->ExceptionAddress);
2147 if (!shown_debug_message) {
2148 cm_print_error(
2149 "\n"
2150 "To debug in Visual Studio...\n"
2151 "1. Select menu item File->Open Project\n"
2152 "2. Change 'Files of type' to 'Executable Files'\n"
2153 "3. Open this executable.\n"
2154 "4. Select menu item Debug->Start\n"
2155 "\n"
2156 "Alternatively, set the environment variable \n"
2157 "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
2158 "then click 'Debug' in the popup dialog box.\n"
2159 "\n");
2160 shown_debug_message = 1;
2162 exit_test(0);
2163 return EXCEPTION_EXECUTE_HANDLER;
2166 return EXCEPTION_CONTINUE_SEARCH;
2168 #endif /* !_WIN32 */
2170 void cm_print_error(const char * const format, ...)
2172 va_list args;
2173 va_start(args, format);
2174 if (cm_error_message_enabled) {
2175 vcm_print_error(format, args);
2176 } else {
2177 vprint_error(format, args);
2179 va_end(args);
2182 /* Standard output and error print methods. */
2183 void vprint_message(const char* const format, va_list args) {
2184 char buffer[1024];
2185 vsnprintf(buffer, sizeof(buffer), format, args);
2186 printf("%s", buffer);
2187 fflush(stdout);
2188 #ifdef _WIN32
2189 OutputDebugString(buffer);
2190 #endif /* _WIN32 */
2194 void vprint_error(const char* const format, va_list args) {
2195 char buffer[1024];
2196 vsnprintf(buffer, sizeof(buffer), format, args);
2197 fprintf(stderr, "%s", buffer);
2198 fflush(stderr);
2199 #ifdef _WIN32
2200 OutputDebugString(buffer);
2201 #endif /* _WIN32 */
2205 void print_message(const char* const format, ...) {
2206 va_list args;
2207 va_start(args, format);
2208 vprint_message(format, args);
2209 va_end(args);
2213 void print_error(const char* const format, ...) {
2214 va_list args;
2215 va_start(args, format);
2216 vprint_error(format, args);
2217 va_end(args);
2220 /* New formatter */
2221 static enum cm_message_output cm_get_output(void)
2223 enum cm_message_output output = global_msg_output;
2224 char *env;
2226 env = getenv("CMOCKA_MESSAGE_OUTPUT");
2227 if (env != NULL) {
2228 if (strcasecmp(env, "STDOUT") == 0) {
2229 output = CM_OUTPUT_STDOUT;
2230 } else if (strcasecmp(env, "SUBUNIT") == 0) {
2231 output = CM_OUTPUT_SUBUNIT;
2232 } else if (strcasecmp(env, "TAP") == 0) {
2233 output = CM_OUTPUT_TAP;
2234 } else if (strcasecmp(env, "XML") == 0) {
2235 output = CM_OUTPUT_XML;
2239 return output;
2242 enum cm_printf_type {
2243 PRINTF_TEST_START,
2244 PRINTF_TEST_SUCCESS,
2245 PRINTF_TEST_FAILURE,
2246 PRINTF_TEST_ERROR,
2247 PRINTF_TEST_SKIPPED,
2250 static int xml_printed;
2251 static int file_append;
2253 static void cmprintf_group_finish_xml(const char *group_name,
2254 size_t total_executed,
2255 size_t total_failed,
2256 size_t total_errors,
2257 size_t total_skipped,
2258 double total_runtime,
2259 struct CMUnitTestState *cm_tests)
2261 FILE *fp = stdout;
2262 int file_opened = 0;
2263 int multiple_files = 0;
2264 char *env;
2265 size_t i;
2267 env = getenv("CMOCKA_XML_FILE");
2268 if (env != NULL) {
2269 char buf[1024];
2270 int rc;
2272 snprintf(buf, sizeof(buf), "%s", env);
2274 rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files);
2275 if (rc < 0) {
2276 snprintf(buf, sizeof(buf), "%s", env);
2279 fp = fopen(buf, "r");
2280 if (fp == NULL) {
2281 fp = fopen(buf, "w");
2282 if (fp != NULL) {
2283 file_append = 1;
2284 file_opened = 1;
2285 } else {
2286 fp = stderr;
2288 } else {
2289 fclose(fp);
2290 if (file_append) {
2291 fp = fopen(buf, "a");
2292 if (fp != NULL) {
2293 file_opened = 1;
2294 xml_printed = 1;
2295 } else {
2296 fp = stderr;
2298 } else {
2299 fp = stderr;
2304 if (!xml_printed || (file_opened && !file_append)) {
2305 fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
2306 if (!file_opened) {
2307 xml_printed = 1;
2311 fprintf(fp, "<testsuites>\n");
2312 fprintf(fp, " <testsuite name=\"%s\" time=\"%.3f\" "
2313 "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
2314 group_name,
2315 total_runtime, /* seconds */
2316 (unsigned)total_executed,
2317 (unsigned)total_failed,
2318 (unsigned)total_errors,
2319 (unsigned)total_skipped);
2321 for (i = 0; i < total_executed; i++) {
2322 struct CMUnitTestState *cmtest = &cm_tests[i];
2324 fprintf(fp, " <testcase name=\"%s\" time=\"%.3f\" >\n",
2325 cmtest->test->name, cmtest->runtime);
2327 switch (cmtest->status) {
2328 case CM_TEST_ERROR:
2329 case CM_TEST_FAILED:
2330 if (cmtest->error_message != NULL) {
2331 fprintf(fp, " <failure><![CDATA[%s]]></failure>\n",
2332 cmtest->error_message);
2333 } else {
2334 fprintf(fp, " <failure message=\"Unknown error\" />\n");
2336 break;
2337 case CM_TEST_SKIPPED:
2338 fprintf(fp, " <skipped/>\n");
2339 break;
2341 case CM_TEST_PASSED:
2342 case CM_TEST_NOT_STARTED:
2343 break;
2346 fprintf(fp, " </testcase>\n");
2349 fprintf(fp, " </testsuite>\n");
2350 fprintf(fp, "</testsuites>\n");
2352 if (file_opened) {
2353 fclose(fp);
2357 static void cmprintf_group_start_standard(const size_t num_tests)
2359 print_message("[==========] Running %u test(s).\n",
2360 (unsigned)num_tests);
2363 static void cmprintf_group_finish_standard(size_t total_executed,
2364 size_t total_passed,
2365 size_t total_failed,
2366 size_t total_errors,
2367 size_t total_skipped,
2368 struct CMUnitTestState *cm_tests)
2370 size_t i;
2372 print_message("[==========] %u test(s) run.\n", (unsigned)total_executed);
2373 print_error("[ PASSED ] %u test(s).\n",
2374 (unsigned)(total_passed));
2376 if (total_skipped) {
2377 print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped);
2378 for (i = 0; i < total_executed; i++) {
2379 struct CMUnitTestState *cmtest = &cm_tests[i];
2381 if (cmtest->status == CM_TEST_SKIPPED) {
2382 print_error("[ SKIPPED ] %s\n", cmtest->test->name);
2385 print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped));
2388 if (total_failed) {
2389 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
2390 for (i = 0; i < total_executed; i++) {
2391 struct CMUnitTestState *cmtest = &cm_tests[i];
2393 if (cmtest->status == CM_TEST_FAILED) {
2394 print_error("[ FAILED ] %s\n", cmtest->test->name);
2397 print_error("\n %u FAILED TEST(S)\n",
2398 (unsigned)(total_failed + total_errors));
2402 static void cmprintf_standard(enum cm_printf_type type,
2403 const char *test_name,
2404 const char *error_message)
2406 switch (type) {
2407 case PRINTF_TEST_START:
2408 print_message("[ RUN ] %s\n", test_name);
2409 break;
2410 case PRINTF_TEST_SUCCESS:
2411 print_message("[ OK ] %s\n", test_name);
2412 break;
2413 case PRINTF_TEST_FAILURE:
2414 if (error_message != NULL) {
2415 print_error("[ ERROR ] --- %s\n", error_message);
2417 print_message("[ FAILED ] %s\n", test_name);
2418 break;
2419 case PRINTF_TEST_SKIPPED:
2420 print_message("[ SKIPPED ] %s\n", test_name);
2421 break;
2422 case PRINTF_TEST_ERROR:
2423 if (error_message != NULL) {
2424 print_error("%s\n", error_message);
2426 print_error("[ ERROR ] %s\n", test_name);
2427 break;
2431 static void cmprintf_group_start_tap(const size_t num_tests)
2433 print_message("1..%u\n", (unsigned)num_tests);
2436 static void cmprintf_group_finish_tap(const char *group_name,
2437 size_t total_executed,
2438 size_t total_passed,
2439 size_t total_skipped)
2441 const char *status = "not ok";
2442 if (total_passed + total_skipped == total_executed) {
2443 status = "ok";
2445 print_message("# %s - %s\n", status, group_name);
2448 static void cmprintf_tap(enum cm_printf_type type,
2449 uint32_t test_number,
2450 const char *test_name,
2451 const char *error_message)
2453 switch (type) {
2454 case PRINTF_TEST_START:
2455 break;
2456 case PRINTF_TEST_SUCCESS:
2457 print_message("ok %u - %s\n", (unsigned)test_number, test_name);
2458 break;
2459 case PRINTF_TEST_FAILURE:
2460 print_message("not ok %u - %s\n", (unsigned)test_number, test_name);
2461 if (error_message != NULL) {
2462 char *msg;
2463 char *p;
2465 msg = strdup(error_message);
2466 if (msg == NULL) {
2467 return;
2469 p = msg;
2471 while (p[0] != '\0') {
2472 char *q = p;
2474 p = strchr(q, '\n');
2475 if (p != NULL) {
2476 p[0] = '\0';
2479 print_message("# %s\n", q);
2481 if (p == NULL) {
2482 break;
2484 p++;
2486 libc_free(msg);
2488 break;
2489 case PRINTF_TEST_SKIPPED:
2490 print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name);
2491 break;
2492 case PRINTF_TEST_ERROR:
2493 print_message("not ok %u - %s %s\n",
2494 (unsigned)test_number, test_name, error_message);
2495 break;
2499 static void cmprintf_subunit(enum cm_printf_type type,
2500 const char *test_name,
2501 const char *error_message)
2503 switch (type) {
2504 case PRINTF_TEST_START:
2505 print_message("test: %s\n", test_name);
2506 break;
2507 case PRINTF_TEST_SUCCESS:
2508 print_message("success: %s\n", test_name);
2509 break;
2510 case PRINTF_TEST_FAILURE:
2511 print_message("failure: %s", test_name);
2512 if (error_message != NULL) {
2513 print_message(" [\n%s\n]\n", error_message);
2515 break;
2516 case PRINTF_TEST_SKIPPED:
2517 print_message("skip: %s\n", test_name);
2518 break;
2519 case PRINTF_TEST_ERROR:
2520 print_message("error: %s [ %s ]\n", test_name, error_message);
2521 break;
2525 static void cmprintf_group_start(const size_t num_tests)
2527 enum cm_message_output output;
2529 output = cm_get_output();
2531 switch (output) {
2532 case CM_OUTPUT_STDOUT:
2533 cmprintf_group_start_standard(num_tests);
2534 break;
2535 case CM_OUTPUT_SUBUNIT:
2536 break;
2537 case CM_OUTPUT_TAP:
2538 cmprintf_group_start_tap(num_tests);
2539 break;
2540 case CM_OUTPUT_XML:
2541 break;
2545 static void cmprintf_group_finish(const char *group_name,
2546 size_t total_executed,
2547 size_t total_passed,
2548 size_t total_failed,
2549 size_t total_errors,
2550 size_t total_skipped,
2551 double total_runtime,
2552 struct CMUnitTestState *cm_tests)
2554 enum cm_message_output output;
2556 output = cm_get_output();
2558 switch (output) {
2559 case CM_OUTPUT_STDOUT:
2560 cmprintf_group_finish_standard(total_executed,
2561 total_passed,
2562 total_failed,
2563 total_errors,
2564 total_skipped,
2565 cm_tests);
2566 break;
2567 case CM_OUTPUT_SUBUNIT:
2568 break;
2569 case CM_OUTPUT_TAP:
2570 cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped);
2571 break;
2572 case CM_OUTPUT_XML:
2573 cmprintf_group_finish_xml(group_name,
2574 total_executed,
2575 total_failed,
2576 total_errors,
2577 total_skipped,
2578 total_runtime,
2579 cm_tests);
2580 break;
2584 static void cmprintf(enum cm_printf_type type,
2585 size_t test_number,
2586 const char *test_name,
2587 const char *error_message)
2589 enum cm_message_output output;
2591 output = cm_get_output();
2593 switch (output) {
2594 case CM_OUTPUT_STDOUT:
2595 cmprintf_standard(type, test_name, error_message);
2596 break;
2597 case CM_OUTPUT_SUBUNIT:
2598 cmprintf_subunit(type, test_name, error_message);
2599 break;
2600 case CM_OUTPUT_TAP:
2601 cmprintf_tap(type, test_number, test_name, error_message);
2602 break;
2603 case CM_OUTPUT_XML:
2604 break;
2608 void cmocka_set_message_output(enum cm_message_output output)
2610 global_msg_output = output;
2613 void cmocka_set_test_filter(const char *pattern)
2615 global_test_filter_pattern = pattern;
2618 /****************************************************************************
2619 * TIME CALCULATIONS
2620 ****************************************************************************/
2622 #ifdef HAVE_STRUCT_TIMESPEC
2623 static struct timespec cm_tspecdiff(struct timespec time1,
2624 struct timespec time0)
2626 struct timespec ret;
2627 int xsec = 0;
2628 int sign = 1;
2630 if (time0.tv_nsec > time1.tv_nsec) {
2631 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
2632 time0.tv_nsec -= (long int) (1E9 * xsec);
2633 time0.tv_sec += xsec;
2636 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
2637 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
2638 time0.tv_nsec += (long int) (1E9 * xsec);
2639 time0.tv_sec -= xsec;
2642 ret.tv_sec = time1.tv_sec - time0.tv_sec;
2643 ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
2645 if (time1.tv_sec < time0.tv_sec) {
2646 sign = -1;
2649 ret.tv_sec = ret.tv_sec * sign;
2651 return ret;
2654 static double cm_secdiff(struct timespec clock1, struct timespec clock0)
2656 double ret;
2657 struct timespec diff;
2659 diff = cm_tspecdiff(clock1, clock0);
2661 ret = diff.tv_sec;
2662 ret += (double) diff.tv_nsec / (double) 1E9;
2664 return ret;
2666 #endif /* HAVE_STRUCT_TIMESPEC */
2668 /****************************************************************************
2669 * CMOCKA TEST RUNNER
2670 ****************************************************************************/
2671 static int cmocka_run_one_test_or_fixture(const char *function_name,
2672 CMUnitTestFunction test_func,
2673 CMFixtureFunction setup_func,
2674 CMFixtureFunction teardown_func,
2675 void ** const volatile state,
2676 const void *const heap_check_point)
2678 const ListNode * const volatile check_point = (const ListNode*)
2679 (heap_check_point != NULL ?
2680 heap_check_point : check_point_allocated_blocks());
2681 int handle_exceptions = 1;
2682 void *current_state = NULL;
2683 int rc = 0;
2685 /* FIXME check only one test or fixture is set */
2687 /* Detect if we should handle exceptions */
2688 #ifdef _WIN32
2689 handle_exceptions = !IsDebuggerPresent();
2690 #endif /* _WIN32 */
2691 #ifdef UNIT_TESTING_DEBUG
2692 handle_exceptions = 0;
2693 #endif /* UNIT_TESTING_DEBUG */
2696 if (handle_exceptions) {
2697 #ifndef _WIN32
2698 unsigned int i;
2699 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2700 default_signal_functions[i] = signal(
2701 exception_signals[i], exception_handler);
2703 #else /* _WIN32 */
2704 previous_exception_filter = SetUnhandledExceptionFilter(
2705 exception_filter);
2706 #endif /* !_WIN32 */
2709 /* Init the test structure */
2710 initialize_testing(function_name);
2712 global_running_test = 1;
2714 if (cm_setjmp(global_run_test_env) == 0) {
2715 if (test_func != NULL) {
2716 test_func(state != NULL ? state : &current_state);
2718 fail_if_blocks_allocated(check_point, function_name);
2719 rc = 0;
2720 } else if (setup_func != NULL) {
2721 rc = setup_func(state != NULL ? state : &current_state);
2724 * For setup we can ignore any allocated blocks. We just need to
2725 * ensure they're deallocated on tear down.
2727 } else if (teardown_func != NULL) {
2728 rc = teardown_func(state != NULL ? state : &current_state);
2730 fail_if_blocks_allocated(check_point, function_name);
2731 } else {
2732 /* ERROR */
2734 fail_if_leftover_values(function_name);
2735 global_running_test = 0;
2736 } else {
2737 /* TEST FAILED */
2738 global_running_test = 0;
2739 rc = -1;
2741 teardown_testing(function_name);
2743 if (handle_exceptions) {
2744 #ifndef _WIN32
2745 unsigned int i;
2746 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2747 signal(exception_signals[i], default_signal_functions[i]);
2749 #else /* _WIN32 */
2750 if (previous_exception_filter) {
2751 SetUnhandledExceptionFilter(previous_exception_filter);
2752 previous_exception_filter = NULL;
2754 #endif /* !_WIN32 */
2757 return rc;
2760 static int cmocka_run_group_fixture(const char *function_name,
2761 CMFixtureFunction setup_func,
2762 CMFixtureFunction teardown_func,
2763 void **state,
2764 const void *const heap_check_point)
2766 int rc;
2768 if (setup_func != NULL) {
2769 rc = cmocka_run_one_test_or_fixture(function_name,
2770 NULL,
2771 setup_func,
2772 NULL,
2773 state,
2774 heap_check_point);
2775 } else {
2776 rc = cmocka_run_one_test_or_fixture(function_name,
2777 NULL,
2778 NULL,
2779 teardown_func,
2780 state,
2781 heap_check_point);
2784 return rc;
2787 static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
2789 #ifdef HAVE_STRUCT_TIMESPEC
2790 struct timespec start = {
2791 .tv_sec = 0,
2792 .tv_nsec = 0,
2794 struct timespec finish = {
2795 .tv_sec = 0,
2796 .tv_nsec = 0,
2798 #endif
2799 int rc = 0;
2801 /* Run setup */
2802 if (test_state->test->setup_func != NULL) {
2803 /* Setup the memory check point, it will be evaluated on teardown */
2804 test_state->check_point = check_point_allocated_blocks();
2806 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2807 NULL,
2808 test_state->test->setup_func,
2809 NULL,
2810 &test_state->state,
2811 test_state->check_point);
2812 if (rc != 0) {
2813 test_state->status = CM_TEST_ERROR;
2814 cm_print_error("Test setup failed");
2818 /* Run test */
2819 #ifdef HAVE_STRUCT_TIMESPEC
2820 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
2821 #endif
2823 if (rc == 0) {
2824 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2825 test_state->test->test_func,
2826 NULL,
2827 NULL,
2828 &test_state->state,
2829 NULL);
2830 if (rc == 0) {
2831 test_state->status = CM_TEST_PASSED;
2832 } else {
2833 if (global_skip_test) {
2834 test_state->status = CM_TEST_SKIPPED;
2835 global_skip_test = 0; /* Do not skip the next test */
2836 } else {
2837 test_state->status = CM_TEST_FAILED;
2840 rc = 0;
2843 test_state->runtime = 0.0;
2845 #ifdef HAVE_STRUCT_TIMESPEC
2846 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
2847 test_state->runtime = cm_secdiff(finish, start);
2848 #endif
2850 /* Run teardown */
2851 if (rc == 0 && test_state->test->teardown_func != NULL) {
2852 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2853 NULL,
2854 NULL,
2855 test_state->test->teardown_func,
2856 &test_state->state,
2857 test_state->check_point);
2858 if (rc != 0) {
2859 test_state->status = CM_TEST_ERROR;
2860 cm_print_error("Test teardown failed");
2864 test_state->error_message = cm_error_message;
2865 cm_error_message = NULL;
2867 return rc;
2870 int _cmocka_run_group_tests(const char *group_name,
2871 const struct CMUnitTest * const tests,
2872 const size_t num_tests,
2873 CMFixtureFunction group_setup,
2874 CMFixtureFunction group_teardown)
2876 struct CMUnitTestState *cm_tests;
2877 const ListNode *group_check_point = check_point_allocated_blocks();
2878 void *group_state = NULL;
2879 size_t total_tests = 0;
2880 size_t total_failed = 0;
2881 size_t total_passed = 0;
2882 size_t total_executed = 0;
2883 size_t total_errors = 0;
2884 size_t total_skipped = 0;
2885 double total_runtime = 0;
2886 size_t i;
2887 int rc;
2889 /* Make sure LargestIntegralType is at least the size of a pointer. */
2890 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
2892 cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests);
2893 if (cm_tests == NULL) {
2894 return -1;
2897 /* Setup cmocka test array */
2898 for (i = 0; i < num_tests; i++) {
2899 if (tests[i].name != NULL &&
2900 (tests[i].test_func != NULL
2901 || tests[i].setup_func != NULL
2902 || tests[i].teardown_func != NULL)) {
2903 if (global_test_filter_pattern != NULL) {
2904 int ok;
2906 ok = c_strmatch(tests[i].name, global_test_filter_pattern);
2907 if (!ok) {
2908 continue;
2911 cm_tests[total_tests] = (struct CMUnitTestState) {
2912 .test = &tests[i],
2913 .status = CM_TEST_NOT_STARTED,
2914 .state = NULL,
2916 total_tests++;
2920 cmprintf_group_start(total_tests);
2922 rc = 0;
2924 /* Run group setup */
2925 if (group_setup != NULL) {
2926 rc = cmocka_run_group_fixture("cmocka_group_setup",
2927 group_setup,
2928 NULL,
2929 &group_state,
2930 group_check_point);
2933 if (rc == 0) {
2934 /* Execute tests */
2935 for (i = 0; i < total_tests; i++) {
2936 struct CMUnitTestState *cmtest = &cm_tests[i];
2937 size_t test_number = i + 1;
2939 cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
2941 if (group_state != NULL) {
2942 cmtest->state = group_state;
2943 } else if (cmtest->test->initial_state != NULL) {
2944 cmtest->state = cmtest->test->initial_state;
2947 rc = cmocka_run_one_tests(cmtest);
2948 total_executed++;
2949 total_runtime += cmtest->runtime;
2950 if (rc == 0) {
2951 switch (cmtest->status) {
2952 case CM_TEST_PASSED:
2953 cmprintf(PRINTF_TEST_SUCCESS,
2954 test_number,
2955 cmtest->test->name,
2956 cmtest->error_message);
2957 total_passed++;
2958 break;
2959 case CM_TEST_SKIPPED:
2960 cmprintf(PRINTF_TEST_SKIPPED,
2961 test_number,
2962 cmtest->test->name,
2963 cmtest->error_message);
2964 total_skipped++;
2965 break;
2966 case CM_TEST_FAILED:
2967 cmprintf(PRINTF_TEST_FAILURE,
2968 test_number,
2969 cmtest->test->name,
2970 cmtest->error_message);
2971 total_failed++;
2972 break;
2973 default:
2974 cmprintf(PRINTF_TEST_ERROR,
2975 test_number,
2976 cmtest->test->name,
2977 "Internal cmocka error");
2978 total_errors++;
2979 break;
2981 } else {
2982 char err_msg[2048] = {0};
2984 snprintf(err_msg, sizeof(err_msg),
2985 "Could not run test: %s",
2986 cmtest->error_message);
2988 cmprintf(PRINTF_TEST_ERROR,
2989 test_number,
2990 cmtest->test->name,
2991 err_msg);
2992 total_errors++;
2995 } else {
2996 if (cm_error_message != NULL) {
2997 print_error("[ ERROR ] --- %s\n", cm_error_message);
2998 vcm_free_error(cm_error_message);
2999 cm_error_message = NULL;
3001 cmprintf(PRINTF_TEST_ERROR, 0,
3002 group_name, "[ FAILED ] GROUP SETUP");
3003 total_errors++;
3006 /* Run group teardown */
3007 if (group_teardown != NULL) {
3008 rc = cmocka_run_group_fixture("cmocka_group_teardown",
3009 NULL,
3010 group_teardown,
3011 &group_state,
3012 group_check_point);
3013 if (rc != 0) {
3014 if (cm_error_message != NULL) {
3015 print_error("[ ERROR ] --- %s\n", cm_error_message);
3016 vcm_free_error(cm_error_message);
3017 cm_error_message = NULL;
3019 cmprintf(PRINTF_TEST_ERROR, 0,
3020 group_name, "[ FAILED ] GROUP TEARDOWN");
3024 cmprintf_group_finish(group_name,
3025 total_executed,
3026 total_passed,
3027 total_failed,
3028 total_errors,
3029 total_skipped,
3030 total_runtime,
3031 cm_tests);
3033 for (i = 0; i < total_tests; i++) {
3034 vcm_free_error(discard_const_p(char, cm_tests[i].error_message));
3036 libc_free(cm_tests);
3037 fail_if_blocks_allocated(group_check_point, "cmocka_group_tests");
3039 return total_failed + total_errors;
3042 /****************************************************************************
3043 * DEPRECATED TEST RUNNER
3044 ****************************************************************************/
3046 int _run_test(
3047 const char * const function_name, const UnitTestFunction Function,
3048 void ** const volatile state, const UnitTestFunctionType function_type,
3049 const void* const heap_check_point) {
3050 const ListNode * const volatile check_point = (const ListNode*)
3051 (heap_check_point ?
3052 heap_check_point : check_point_allocated_blocks());
3053 void *current_state = NULL;
3054 volatile int rc = 1;
3055 int handle_exceptions = 1;
3056 #ifdef _WIN32
3057 handle_exceptions = !IsDebuggerPresent();
3058 #endif /* _WIN32 */
3059 #ifdef UNIT_TESTING_DEBUG
3060 handle_exceptions = 0;
3061 #endif /* UNIT_TESTING_DEBUG */
3063 cm_error_message_enabled = 0;
3065 if (handle_exceptions) {
3066 #ifndef _WIN32
3067 unsigned int i;
3068 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
3069 default_signal_functions[i] = signal(
3070 exception_signals[i], exception_handler);
3072 #else /* _WIN32 */
3073 previous_exception_filter = SetUnhandledExceptionFilter(
3074 exception_filter);
3075 #endif /* !_WIN32 */
3078 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
3079 print_message("[ RUN ] %s\n", function_name);
3081 initialize_testing(function_name);
3082 global_running_test = 1;
3083 if (cm_setjmp(global_run_test_env) == 0) {
3084 Function(state ? state : &current_state);
3085 fail_if_leftover_values(function_name);
3087 /* If this is a setup function then ignore any allocated blocks
3088 * only ensure they're deallocated on tear down. */
3089 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
3090 fail_if_blocks_allocated(check_point, function_name);
3093 global_running_test = 0;
3095 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
3096 print_message("[ OK ] %s\n", function_name);
3098 rc = 0;
3099 } else {
3100 global_running_test = 0;
3101 print_message("[ FAILED ] %s\n", function_name);
3103 teardown_testing(function_name);
3105 if (handle_exceptions) {
3106 #ifndef _WIN32
3107 unsigned int i;
3108 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
3109 signal(exception_signals[i], default_signal_functions[i]);
3111 #else /* _WIN32 */
3112 if (previous_exception_filter) {
3113 SetUnhandledExceptionFilter(previous_exception_filter);
3114 previous_exception_filter = NULL;
3116 #endif /* !_WIN32 */
3119 return rc;
3123 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
3124 /* Whether to execute the next test. */
3125 int run_next_test = 1;
3126 /* Whether the previous test failed. */
3127 int previous_test_failed = 0;
3128 /* Whether the previous setup failed. */
3129 int previous_setup_failed = 0;
3130 /* Check point of the heap state. */
3131 const ListNode * const check_point = check_point_allocated_blocks();
3132 /* Current test being executed. */
3133 size_t current_test = 0;
3134 /* Number of tests executed. */
3135 size_t tests_executed = 0;
3136 /* Number of failed tests. */
3137 size_t total_failed = 0;
3138 /* Number of setup functions. */
3139 size_t setups = 0;
3140 /* Number of teardown functions. */
3141 size_t teardowns = 0;
3142 size_t i;
3144 * A stack of test states. A state is pushed on the stack
3145 * when a test setup occurs and popped on tear down.
3147 TestState* test_states =
3148 (TestState*)malloc(number_of_tests * sizeof(*test_states));
3149 /* The number of test states which should be 0 at the end */
3150 long number_of_test_states = 0;
3151 /* Names of the tests that failed. */
3152 const char** failed_names = (const char**)malloc(number_of_tests *
3153 sizeof(*failed_names));
3154 void **current_state = NULL;
3156 /* Count setup and teardown functions */
3157 for (i = 0; i < number_of_tests; i++) {
3158 const UnitTest * const test = &tests[i];
3160 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) {
3161 setups++;
3164 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) {
3165 teardowns++;
3169 print_message("[==========] Running %"PRIdS " test(s).\n",
3170 number_of_tests - setups - teardowns);
3172 /* Make sure LargestIntegralType is at least the size of a pointer. */
3173 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
3175 while (current_test < number_of_tests) {
3176 const ListNode *test_check_point = NULL;
3177 TestState *current_TestState;
3178 const UnitTest * const test = &tests[current_test++];
3179 if (!test->function) {
3180 continue;
3183 switch (test->function_type) {
3184 case UNIT_TEST_FUNCTION_TYPE_TEST:
3185 if (! previous_setup_failed) {
3186 run_next_test = 1;
3188 break;
3189 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
3190 /* Checkpoint the heap before the setup. */
3191 current_TestState = &test_states[number_of_test_states++];
3192 current_TestState->check_point = check_point_allocated_blocks();
3193 test_check_point = current_TestState->check_point;
3194 current_state = &current_TestState->state;
3195 *current_state = NULL;
3196 run_next_test = 1;
3197 break;
3199 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3200 /* Check the heap based on the last setup checkpoint. */
3201 assert_true(number_of_test_states);
3202 current_TestState = &test_states[--number_of_test_states];
3203 test_check_point = current_TestState->check_point;
3204 current_state = &current_TestState->state;
3205 break;
3206 default:
3207 print_error("Invalid unit test function type %d\n",
3208 test->function_type);
3209 exit_test(1);
3210 break;
3213 if (run_next_test) {
3214 int failed = _run_test(test->name, test->function, current_state,
3215 test->function_type, test_check_point);
3216 if (failed) {
3217 failed_names[total_failed] = test->name;
3220 switch (test->function_type) {
3221 case UNIT_TEST_FUNCTION_TYPE_TEST:
3222 previous_test_failed = failed;
3223 total_failed += failed;
3224 tests_executed ++;
3225 break;
3227 case UNIT_TEST_FUNCTION_TYPE_SETUP:
3228 if (failed) {
3229 total_failed ++;
3230 tests_executed ++;
3231 /* Skip forward until the next test or setup function. */
3232 run_next_test = 0;
3233 previous_setup_failed = 1;
3235 previous_test_failed = 0;
3236 break;
3238 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3239 /* If this test failed. */
3240 if (failed && !previous_test_failed) {
3241 total_failed ++;
3243 break;
3244 default:
3245 #ifndef _HPUX
3246 assert_null("BUG: shouldn't be here!");
3247 #endif
3248 break;
3253 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3254 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3256 if (total_failed > 0) {
3257 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3258 for (i = 0; i < total_failed; i++) {
3259 print_error("[ FAILED ] %s\n", failed_names[i]);
3261 } else {
3262 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3265 if (number_of_test_states != 0) {
3266 print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and "
3267 "teardown %"PRIdS " functions\n", setups, teardowns);
3268 total_failed = (size_t)-1;
3271 free(test_states);
3272 free((void*)failed_names);
3274 fail_if_blocks_allocated(check_point, "run_tests");
3275 return (int)total_failed;
3278 int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
3280 UnitTestFunction setup = NULL;
3281 const char *setup_name;
3282 size_t num_setups = 0;
3283 UnitTestFunction teardown = NULL;
3284 const char *teardown_name = NULL;
3285 size_t num_teardowns = 0;
3286 size_t current_test = 0;
3287 size_t i;
3289 /* Number of tests executed. */
3290 size_t tests_executed = 0;
3291 /* Number of failed tests. */
3292 size_t total_failed = 0;
3293 /* Check point of the heap state. */
3294 const ListNode * const check_point = check_point_allocated_blocks();
3295 const char **failed_names = NULL;
3296 void **current_state = NULL;
3297 TestState group_state = {
3298 .check_point = NULL,
3301 if (number_of_tests == 0) {
3302 return -1;
3305 failed_names = (const char **)malloc(number_of_tests *
3306 sizeof(*failed_names));
3307 if (failed_names == NULL) {
3308 return -2;
3311 /* Find setup and teardown function */
3312 for (i = 0; i < number_of_tests; i++) {
3313 const UnitTest * const test = &tests[i];
3315 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
3316 if (setup == NULL) {
3317 setup = test->function;
3318 setup_name = test->name;
3319 num_setups = 1;
3320 } else {
3321 print_error("[ ERROR ] More than one group setup function detected\n");
3322 exit_test(1);
3326 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
3327 if (teardown == NULL) {
3328 teardown = test->function;
3329 teardown_name = test->name;
3330 num_teardowns = 1;
3331 } else {
3332 print_error("[ ERROR ] More than one group teardown function detected\n");
3333 exit_test(1);
3338 print_message("[==========] Running %"PRIdS " test(s).\n",
3339 number_of_tests - num_setups - num_teardowns);
3341 if (setup != NULL) {
3342 int failed;
3344 group_state.check_point = check_point_allocated_blocks();
3345 current_state = &group_state.state;
3346 *current_state = NULL;
3347 failed = _run_test(setup_name,
3348 setup,
3349 current_state,
3350 UNIT_TEST_FUNCTION_TYPE_SETUP,
3351 group_state.check_point);
3352 if (failed) {
3353 failed_names[total_failed] = setup_name;
3356 total_failed += failed;
3357 tests_executed++;
3360 while (current_test < number_of_tests) {
3361 int run_test = 0;
3362 const UnitTest * const test = &tests[current_test++];
3363 if (test->function == NULL) {
3364 continue;
3367 switch (test->function_type) {
3368 case UNIT_TEST_FUNCTION_TYPE_TEST:
3369 run_test = 1;
3370 break;
3371 case UNIT_TEST_FUNCTION_TYPE_SETUP:
3372 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3373 case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
3374 case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
3375 break;
3376 default:
3377 print_error("Invalid unit test function type %d\n",
3378 test->function_type);
3379 break;
3382 if (run_test) {
3383 int failed;
3385 failed = _run_test(test->name,
3386 test->function,
3387 current_state,
3388 test->function_type,
3389 NULL);
3390 if (failed) {
3391 failed_names[total_failed] = test->name;
3394 total_failed += failed;
3395 tests_executed++;
3399 if (teardown != NULL) {
3400 int failed;
3402 failed = _run_test(teardown_name,
3403 teardown,
3404 current_state,
3405 UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
3406 group_state.check_point);
3407 if (failed) {
3408 failed_names[total_failed] = teardown_name;
3411 total_failed += failed;
3412 tests_executed++;
3415 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3416 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3418 if (total_failed) {
3419 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3420 for (i = 0; i < total_failed; i++) {
3421 print_error("[ FAILED ] %s\n", failed_names[i]);
3423 } else {
3424 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3427 free((void*)failed_names);
3428 fail_if_blocks_allocated(check_point, "run_group_tests");
3430 return (int)total_failed;