lib: rpc: The registered interfaces are a lists of singletons that are never removed.
[Samba.git] / third_party / cmocka / cmocka.c
blob14b2765b78196c8df035b4ae37ef06da85434776
1 /*
2 * Copyright 2008 Google Inc.
3 * Copyright 2014-2015 Andreas Schneider <asn@cryptomilk.org>
4 * Copyright 2015 Jakub Hrozek <jakub.hrozek@posteo.se>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
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 typedef struct MallocBlockInfo {
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. */
157 } MallocBlockInfo;
159 /* State of each test. */
160 typedef struct TestState {
161 const ListNode *check_point; /* Check point of the test if there's a */
162 /* setup function. */
163 void *state; /* State associated with the test. */
164 } TestState;
166 /* Determines whether two values are the same. */
167 typedef int (*EqualityFunction)(const void *left, const void *right);
169 /* Value of a symbol and the place it was declared. */
170 typedef struct SymbolValue {
171 SourceLocation location;
172 LargestIntegralType value;
173 } SymbolValue;
176 * Contains a list of values for a symbol.
177 * NOTE: Each structure referenced by symbol_values_list_head must have a
178 * SourceLocation as its' first member.
180 typedef struct SymbolMapValue {
181 const char *symbol_name;
182 ListNode symbol_values_list_head;
183 } SymbolMapValue;
185 /* Where a particular ordering was located and its symbol name */
186 typedef struct FuncOrderingValue {
187 SourceLocation location;
188 const char * function;
189 } FuncOrderingValue;
191 /* Used by list_free() to deallocate values referenced by list nodes. */
192 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
194 /* Structure used to check the range of integer types.a */
195 typedef struct CheckIntegerRange {
196 CheckParameterEvent event;
197 LargestIntegralType minimum;
198 LargestIntegralType maximum;
199 } CheckIntegerRange;
201 /* Structure used to check whether an integer value is in a set. */
202 typedef struct CheckIntegerSet {
203 CheckParameterEvent event;
204 const LargestIntegralType *set;
205 size_t size_of_set;
206 } CheckIntegerSet;
208 /* Used to check whether a parameter matches the area of memory referenced by
209 * this structure. */
210 typedef struct CheckMemoryData {
211 CheckParameterEvent event;
212 const void *memory;
213 size_t size;
214 } CheckMemoryData;
216 static ListNode* list_initialize(ListNode * const node);
217 static ListNode* list_add(ListNode * const head, ListNode *new_node);
218 static ListNode* list_add_value(ListNode * const head, const void *value,
219 const int count);
220 static ListNode* list_remove(
221 ListNode * const node, const CleanupListValue cleanup_value,
222 void * const cleanup_value_data);
223 static void list_remove_free(
224 ListNode * const node, const CleanupListValue cleanup_value,
225 void * const cleanup_value_data);
226 static int list_empty(const ListNode * const head);
227 static int list_find(
228 ListNode * const head, const void *value,
229 const EqualityFunction equal_func, ListNode **output);
230 static int list_first(ListNode * const head, ListNode **output);
231 static ListNode* list_free(
232 ListNode * const head, const CleanupListValue cleanup_value,
233 void * const cleanup_value_data);
235 static void add_symbol_value(
236 ListNode * const symbol_map_head, const char * const symbol_names[],
237 const size_t number_of_symbol_names, const void* value, const int count);
238 static int get_symbol_value(
239 ListNode * const symbol_map_head, const char * const symbol_names[],
240 const size_t number_of_symbol_names, void **output);
241 static void free_value(const void *value, void *cleanup_value_data);
242 static void free_symbol_map_value(
243 const void *value, void *cleanup_value_data);
244 static void remove_always_return_values(ListNode * const map_head,
245 const size_t number_of_symbol_names);
247 static int check_for_leftover_values_list(const ListNode * head,
248 const char * const error_message);
250 static int check_for_leftover_values(
251 const ListNode * const map_head, const char * const error_message,
252 const size_t number_of_symbol_names);
254 static void remove_always_return_values_from_list(ListNode * const map_head);
257 * This must be called at the beginning of a test to initialize some data
258 * structures.
260 static void initialize_testing(const char *test_name);
262 /* This must be called at the end of a test to free() allocated structures. */
263 static void teardown_testing(const char *test_name);
265 static enum cm_message_output cm_get_output(void);
267 static int cm_error_message_enabled = 1;
268 static CMOCKA_THREAD char *cm_error_message;
270 void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
273 * Keeps track of the calling context returned by setenv() so that the fail()
274 * method can jump out of a test.
276 static CMOCKA_THREAD cm_jmp_buf global_run_test_env;
277 static CMOCKA_THREAD int global_running_test = 0;
279 /* Keeps track of the calling context returned by setenv() so that */
280 /* mock_assert() can optionally jump back to expect_assert_failure(). */
281 jmp_buf global_expect_assert_env;
282 int global_expecting_assert = 0;
283 const char *global_last_failed_assert = NULL;
284 static int global_skip_test;
286 /* Keeps a map of the values that functions will have to return to provide */
287 /* mocked interfaces. */
288 static CMOCKA_THREAD ListNode global_function_result_map_head;
289 /* Location of the last mock value returned was declared. */
290 static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
292 /* Keeps a map of the values that functions expect as parameters to their
293 * mocked interfaces. */
294 static CMOCKA_THREAD ListNode global_function_parameter_map_head;
295 /* Location of last parameter value checked was declared. */
296 static CMOCKA_THREAD SourceLocation global_last_parameter_location;
298 /* List (acting as FIFO) of call ordering. */
299 static CMOCKA_THREAD ListNode global_call_ordering_head;
300 /* Location of last call ordering that was declared. */
301 static CMOCKA_THREAD SourceLocation global_last_call_ordering_location;
303 /* List of all currently allocated blocks. */
304 static CMOCKA_THREAD ListNode global_allocated_blocks;
306 static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
308 #ifndef _WIN32
309 /* Signals caught by exception_handler(). */
310 static const int exception_signals[] = {
311 SIGFPE,
312 SIGILL,
313 SIGSEGV,
314 #ifdef SIGBUS
315 SIGBUS,
316 #endif
317 #ifdef SIGSYS
318 SIGSYS,
319 #endif
322 /* Default signal functions that should be restored after a test is complete. */
323 typedef void (*SignalFunction)(int signal);
324 static SignalFunction default_signal_functions[
325 ARRAY_SIZE(exception_signals)];
327 #else /* _WIN32 */
329 /* The default exception filter. */
330 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
332 /* Fatal exceptions. */
333 typedef struct ExceptionCodeInfo {
334 DWORD code;
335 const char* description;
336 } ExceptionCodeInfo;
338 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
340 static const ExceptionCodeInfo exception_codes[] = {
341 EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
342 EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
343 EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
344 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
345 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
346 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
347 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
348 EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
349 EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
350 EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
351 EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
352 EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
353 EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
354 EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
355 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
356 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
357 EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
358 EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
359 EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
360 EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
362 #endif /* !_WIN32 */
364 enum CMUnitTestStatus {
365 CM_TEST_NOT_STARTED,
366 CM_TEST_PASSED,
367 CM_TEST_FAILED,
368 CM_TEST_ERROR,
369 CM_TEST_SKIPPED,
372 struct CMUnitTestState {
373 const ListNode *check_point; /* Check point of the test if there's a setup function. */
374 const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
375 void *state; /* State associated with the test */
376 const char *error_message; /* The error messages by the test */
377 enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
378 double runtime; /* Time calculations */
381 /* Exit the currently executing test. */
382 static void exit_test(const int quit_application)
384 const char *abort_test = getenv("CMOCKA_TEST_ABORT");
386 if (abort_test != NULL && abort_test[0] == '1') {
387 print_error("%s", cm_error_message);
388 abort();
389 } else if (global_running_test) {
390 cm_longjmp(global_run_test_env, 1);
391 } else if (quit_application) {
392 exit(-1);
396 void _skip(const char * const file, const int line)
398 cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
399 global_skip_test = 1;
400 exit_test(1);
403 /* Initialize a SourceLocation structure. */
404 static void initialize_source_location(SourceLocation * const location) {
405 assert_non_null(location);
406 location->file = NULL;
407 location->line = 0;
411 /* Determine whether a source location is currently set. */
412 static int source_location_is_set(const SourceLocation * const location) {
413 assert_non_null(location);
414 return location->file && location->line;
418 /* Set a source location. */
419 static void set_source_location(
420 SourceLocation * const location, const char * const file,
421 const int line) {
422 assert_non_null(location);
423 location->file = file;
424 location->line = line;
428 static int c_strreplace(char *src,
429 size_t src_len,
430 const char *pattern,
431 const char *repl,
432 int *str_replaced)
434 char *p = NULL;
436 p = strstr(src, pattern);
437 if (p == NULL) {
438 return -1;
441 do {
442 size_t of = p - src;
443 size_t l = strlen(src);
444 size_t pl = strlen(pattern);
445 size_t rl = strlen(repl);
447 /* overflow check */
448 if (src_len <= l + MAX(pl, rl) + 1) {
449 return -1;
452 if (rl != pl) {
453 memmove(src + of + rl, src + of + pl, l - of - pl + 1);
456 strncpy(src + of, repl, rl);
458 if (str_replaced != NULL) {
459 *str_replaced = 1;
461 p = strstr(src, pattern);
462 } while (p != NULL);
464 return 0;
467 /* Create function results and expected parameter lists. */
468 void initialize_testing(const char *test_name) {
469 (void)test_name;
470 list_initialize(&global_function_result_map_head);
471 initialize_source_location(&global_last_mock_value_location);
472 list_initialize(&global_function_parameter_map_head);
473 initialize_source_location(&global_last_parameter_location);
474 list_initialize(&global_call_ordering_head);
475 initialize_source_location(&global_last_parameter_location);
479 static void fail_if_leftover_values(const char *test_name) {
480 int error_occurred = 0;
481 (void)test_name;
482 remove_always_return_values(&global_function_result_map_head, 1);
483 if (check_for_leftover_values(
484 &global_function_result_map_head,
485 "%s() has remaining non-returned values.\n", 1)) {
486 error_occurred = 1;
489 remove_always_return_values(&global_function_parameter_map_head, 2);
490 if (check_for_leftover_values(
491 &global_function_parameter_map_head,
492 "%s parameter still has values that haven't been checked.\n", 2)) {
493 error_occurred = 1;
496 remove_always_return_values_from_list(&global_call_ordering_head);
497 if (check_for_leftover_values_list(&global_call_ordering_head,
498 "%s function was expected to be called but was not not.\n")) {
499 error_occurred = 1;
501 if (error_occurred) {
502 exit_test(1);
507 static void teardown_testing(const char *test_name) {
508 (void)test_name;
509 list_free(&global_function_result_map_head, free_symbol_map_value,
510 (void*)0);
511 initialize_source_location(&global_last_mock_value_location);
512 list_free(&global_function_parameter_map_head, free_symbol_map_value,
513 (void*)1);
514 initialize_source_location(&global_last_parameter_location);
515 list_free(&global_call_ordering_head, free_value,
516 (void*)0);
517 initialize_source_location(&global_last_call_ordering_location);
520 /* Initialize a list node. */
521 static ListNode* list_initialize(ListNode * const node) {
522 node->value = NULL;
523 node->next = node;
524 node->prev = node;
525 node->refcount = 1;
526 return node;
531 * Adds a value at the tail of a given list.
532 * The node referencing the value is allocated from the heap.
534 static ListNode* list_add_value(ListNode * const head, const void *value,
535 const int refcount) {
536 ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
537 assert_non_null(head);
538 assert_non_null(value);
539 new_node->value = value;
540 new_node->refcount = refcount;
541 return list_add(head, new_node);
545 /* Add new_node to the end of the list. */
546 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
547 assert_non_null(head);
548 assert_non_null(new_node);
549 new_node->next = head;
550 new_node->prev = head->prev;
551 head->prev->next = new_node;
552 head->prev = new_node;
553 return new_node;
557 /* Remove a node from a list. */
558 static ListNode* list_remove(
559 ListNode * const node, const CleanupListValue cleanup_value,
560 void * const cleanup_value_data) {
561 assert_non_null(node);
562 node->prev->next = node->next;
563 node->next->prev = node->prev;
564 if (cleanup_value) {
565 cleanup_value(node->value, cleanup_value_data);
567 return node;
571 /* Remove a list node from a list and free the node. */
572 static void list_remove_free(
573 ListNode * const node, const CleanupListValue cleanup_value,
574 void * const cleanup_value_data) {
575 assert_non_null(node);
576 free(list_remove(node, cleanup_value, cleanup_value_data));
581 * Frees memory kept by a linked list The cleanup_value function is called for
582 * every "value" field of nodes in the list, except for the head. In addition
583 * to each list value, cleanup_value_data is passed to each call to
584 * cleanup_value. The head of the list is not deallocated.
586 static ListNode* list_free(
587 ListNode * const head, const CleanupListValue cleanup_value,
588 void * const cleanup_value_data) {
589 assert_non_null(head);
590 while (!list_empty(head)) {
591 list_remove_free(head->next, cleanup_value, cleanup_value_data);
593 return head;
597 /* Determine whether a list is empty. */
598 static int list_empty(const ListNode * const head) {
599 assert_non_null(head);
600 return head->next == head;
605 * Find a value in the list using the equal_func to compare each node with the
606 * value.
608 static int list_find(ListNode * const head, const void *value,
609 const EqualityFunction equal_func, ListNode **output) {
610 ListNode *current;
611 assert_non_null(head);
612 for (current = head->next; current != head; current = current->next) {
613 if (equal_func(current->value, value)) {
614 *output = current;
615 return 1;
618 return 0;
621 /* Returns the first node of a list */
622 static int list_first(ListNode * const head, ListNode **output) {
623 ListNode *target_node;
624 assert_non_null(head);
625 if (list_empty(head)) {
626 return 0;
628 target_node = head->next;
629 *output = target_node;
630 return 1;
634 /* Deallocate a value referenced by a list. */
635 static void free_value(const void *value, void *cleanup_value_data) {
636 (void)cleanup_value_data;
637 assert_non_null(value);
638 free((void*)value);
642 /* Releases memory associated to a symbol_map_value. */
643 static void free_symbol_map_value(const void *value,
644 void *cleanup_value_data) {
645 SymbolMapValue * const map_value = (SymbolMapValue*)value;
646 const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
647 assert_non_null(value);
648 list_free(&map_value->symbol_values_list_head,
649 children ? free_symbol_map_value : free_value,
650 (void *) ((uintptr_t)children - 1));
651 free(map_value);
656 * Determine whether a symbol name referenced by a symbol_map_value matches the
657 * specified function name.
659 static int symbol_names_match(const void *map_value, const void *symbol) {
660 return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
661 (const char*)symbol);
665 * Adds a value to the queue of values associated with the given hierarchy of
666 * symbols. It's assumed value is allocated from the heap.
668 static void add_symbol_value(ListNode * const symbol_map_head,
669 const char * const symbol_names[],
670 const size_t number_of_symbol_names,
671 const void* value, const int refcount) {
672 const char* symbol_name;
673 ListNode *target_node;
674 SymbolMapValue *target_map_value;
675 assert_non_null(symbol_map_head);
676 assert_non_null(symbol_names);
677 assert_true(number_of_symbol_names);
678 symbol_name = symbol_names[0];
680 if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
681 &target_node)) {
682 SymbolMapValue * const new_symbol_map_value =
683 (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
684 new_symbol_map_value->symbol_name = symbol_name;
685 list_initialize(&new_symbol_map_value->symbol_values_list_head);
686 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
690 target_map_value = (SymbolMapValue*)target_node->value;
691 if (number_of_symbol_names == 1) {
692 list_add_value(&target_map_value->symbol_values_list_head,
693 value, refcount);
694 } else {
695 add_symbol_value(&target_map_value->symbol_values_list_head,
696 &symbol_names[1], number_of_symbol_names - 1, value,
697 refcount);
703 * Gets the next value associated with the given hierarchy of symbols.
704 * The value is returned as an output parameter with the function returning the
705 * node's old refcount value if a value is found, 0 otherwise. This means that
706 * a return value of 1 indicates the node was just removed from the list.
708 static int get_symbol_value(
709 ListNode * const head, const char * const symbol_names[],
710 const size_t number_of_symbol_names, void **output) {
711 const char* symbol_name;
712 ListNode *target_node;
713 assert_non_null(head);
714 assert_non_null(symbol_names);
715 assert_true(number_of_symbol_names);
716 assert_non_null(output);
717 symbol_name = symbol_names[0];
719 if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
720 SymbolMapValue *map_value;
721 ListNode *child_list;
722 int return_value = 0;
723 assert_non_null(target_node);
724 assert_non_null(target_node->value);
726 map_value = (SymbolMapValue*)target_node->value;
727 child_list = &map_value->symbol_values_list_head;
729 if (number_of_symbol_names == 1) {
730 ListNode *value_node = NULL;
731 return_value = list_first(child_list, &value_node);
732 assert_true(return_value);
733 *output = (void*) value_node->value;
734 return_value = value_node->refcount;
735 if (value_node->refcount - 1 == 0) {
736 list_remove_free(value_node, NULL, NULL);
737 } else if (value_node->refcount > WILL_RETURN_ONCE) {
738 --value_node->refcount;
740 } else {
741 return_value = get_symbol_value(
742 child_list, &symbol_names[1], number_of_symbol_names - 1,
743 output);
745 if (list_empty(child_list)) {
746 list_remove_free(target_node, free_symbol_map_value, (void*)0);
748 return return_value;
749 } else {
750 cm_print_error("No entries for symbol %s.\n", symbol_name);
752 return 0;
756 * Taverse a list of nodes and remove first symbol value in list that has a
757 * refcount < -1 (i.e. should always be returned and has been returned at
758 * least once).
761 static void remove_always_return_values_from_list(ListNode * const map_head)
763 ListNode * current = NULL;
764 ListNode * next = NULL;
765 assert_non_null(map_head);
767 for (current = map_head->next, next = current->next;
768 current != map_head;
769 current = next, next = current->next) {
770 if (current->refcount < -1) {
771 list_remove_free(current, free_value, NULL);
777 * Traverse down a tree of symbol values and remove the first symbol value
778 * in each branch that has a refcount < -1 (i.e should always be returned
779 * and has been returned at least once).
781 static void remove_always_return_values(ListNode * const map_head,
782 const size_t number_of_symbol_names) {
783 ListNode *current;
784 assert_non_null(map_head);
785 assert_true(number_of_symbol_names);
786 current = map_head->next;
787 while (current != map_head) {
788 SymbolMapValue * const value = (SymbolMapValue*)current->value;
789 ListNode * const next = current->next;
790 ListNode *child_list;
791 assert_non_null(value);
792 child_list = &value->symbol_values_list_head;
794 if (!list_empty(child_list)) {
795 if (number_of_symbol_names == 1) {
796 ListNode * const child_node = child_list->next;
797 /* If this item has been returned more than once, free it. */
798 if (child_node->refcount < -1) {
799 list_remove_free(child_node, free_value, NULL);
801 } else {
802 remove_always_return_values(child_list,
803 number_of_symbol_names - 1);
807 if (list_empty(child_list)) {
808 list_remove_free(current, free_value, NULL);
810 current = next;
814 static int check_for_leftover_values_list(const ListNode * head,
815 const char * const error_message)
817 ListNode *child_node;
818 int leftover_count = 0;
819 if (!list_empty(head))
821 for (child_node = head->next; child_node != head;
822 child_node = child_node->next, ++leftover_count) {
823 const FuncOrderingValue *const o =
824 (const FuncOrderingValue*) child_node->value;
825 cm_print_error(error_message, o->function);
826 cm_print_error(SOURCE_LOCATION_FORMAT
827 ": note: remaining item was declared here\n",
828 o->location.file, o->location.line);
831 return leftover_count;
835 * Checks if there are any leftover values set up by the test that were never
836 * retrieved through execution, and fail the test if that is the case.
838 static int check_for_leftover_values(
839 const ListNode * const map_head, const char * const error_message,
840 const size_t number_of_symbol_names) {
841 const ListNode *current;
842 int symbols_with_leftover_values = 0;
843 assert_non_null(map_head);
844 assert_true(number_of_symbol_names);
846 for (current = map_head->next; current != map_head;
847 current = current->next) {
848 const SymbolMapValue * const value =
849 (SymbolMapValue*)current->value;
850 const ListNode *child_list;
851 assert_non_null(value);
852 child_list = &value->symbol_values_list_head;
854 if (!list_empty(child_list)) {
855 if (number_of_symbol_names == 1) {
856 const ListNode *child_node;
857 cm_print_error(error_message, value->symbol_name);
859 for (child_node = child_list->next; child_node != child_list;
860 child_node = child_node->next) {
861 const SourceLocation * const location =
862 (const SourceLocation*)child_node->value;
863 cm_print_error(SOURCE_LOCATION_FORMAT
864 ": note: remaining item was declared here\n",
865 location->file, location->line);
867 } else {
868 cm_print_error("%s.", value->symbol_name);
869 check_for_leftover_values(child_list, error_message,
870 number_of_symbol_names - 1);
872 symbols_with_leftover_values ++;
875 return symbols_with_leftover_values;
879 /* Get the next return value for the specified mock function. */
880 LargestIntegralType _mock(const char * const function, const char* const file,
881 const int line) {
882 void *result;
883 const int rc = get_symbol_value(&global_function_result_map_head,
884 &function, 1, &result);
885 if (rc) {
886 SymbolValue * const symbol = (SymbolValue*)result;
887 const LargestIntegralType value = symbol->value;
888 global_last_mock_value_location = symbol->location;
889 if (rc == 1) {
890 free(symbol);
892 return value;
893 } else {
894 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
895 "to mock function %s\n", file, line, function);
896 if (source_location_is_set(&global_last_mock_value_location)) {
897 cm_print_error(SOURCE_LOCATION_FORMAT
898 ": note: Previously returned mock value was declared here\n",
899 global_last_mock_value_location.file,
900 global_last_mock_value_location.line);
901 } else {
902 cm_print_error("There were no previously returned mock values for "
903 "this test.\n");
905 exit_test(1);
907 return 0;
910 /* Ensure that function is being called in proper order */
911 void _function_called(const char *const function,
912 const char *const file,
913 const int line)
915 ListNode *first_value_node = NULL;
916 ListNode *value_node = NULL;
917 int rc;
919 rc = list_first(&global_call_ordering_head, &value_node);
920 first_value_node = value_node;
921 if (rc) {
922 FuncOrderingValue *expected_call;
923 int cmp;
925 expected_call = (FuncOrderingValue *)value_node->value;
927 cmp = strcmp(expected_call->function, function);
928 if (value_node->refcount < -1) {
930 * Search through value nodes until either function is found or
931 * encounter a non-zero refcount greater than -2
933 if (cmp != 0) {
934 value_node = value_node->next;
935 expected_call = (FuncOrderingValue *)value_node->value;
937 cmp = strcmp(expected_call->function, function);
938 while (value_node->refcount < -1 &&
939 cmp != 0 &&
940 value_node != first_value_node->prev) {
941 value_node = value_node->next;
942 if (value_node == NULL) {
943 break;
945 expected_call = (FuncOrderingValue *)value_node->value;
946 if (expected_call == NULL) {
947 continue;
949 cmp = strcmp(expected_call->function, function);
952 if (expected_call == NULL || value_node == first_value_node->prev) {
953 cm_print_error(SOURCE_LOCATION_FORMAT
954 ": error: No expected mock calls matching "
955 "called() invocation in %s",
956 file, line,
957 function);
958 exit_test(1);
963 if (cmp == 0) {
964 if (value_node->refcount > -2 && --value_node->refcount == 0) {
965 list_remove_free(value_node, free_value, NULL);
967 } else {
968 cm_print_error(SOURCE_LOCATION_FORMAT
969 ": error: Expected call to %s but received called() "
970 "in %s\n",
971 file, line,
972 expected_call->function,
973 function);
974 exit_test(1);
976 } else {
977 cm_print_error(SOURCE_LOCATION_FORMAT
978 ": error: No mock calls expected but called() was "
979 "invoked in %s\n",
980 file, line,
981 function);
982 exit_test(1);
986 /* Add a return value for the specified mock function name. */
987 void _will_return(const char * const function_name, const char * const file,
988 const int line, const LargestIntegralType value,
989 const int count) {
990 SymbolValue * const return_value =
991 (SymbolValue*)malloc(sizeof(*return_value));
992 assert_true(count != 0);
993 return_value->value = value;
994 set_source_location(&return_value->location, file, line);
995 add_symbol_value(&global_function_result_map_head, &function_name, 1,
996 return_value, count);
1001 * Add a custom parameter checking function. If the event parameter is NULL
1002 * the event structure is allocated internally by this function. If event
1003 * parameter is provided it must be allocated on the heap and doesn't need to
1004 * be deallocated by the caller.
1006 void _expect_check(
1007 const char* const function, const char* const parameter,
1008 const char* const file, const int line,
1009 const CheckParameterValue check_function,
1010 const LargestIntegralType check_data,
1011 CheckParameterEvent * const event, const int count) {
1012 CheckParameterEvent * const check =
1013 event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
1014 const char* symbols[] = {function, parameter};
1015 check->parameter_name = parameter;
1016 check->check_value = check_function;
1017 check->check_value_data = check_data;
1018 set_source_location(&check->location, file, line);
1019 add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
1020 count);
1024 * Add an call expectations that a particular function is called correctly.
1025 * This is used for code under test that makes calls to several functions
1026 * in depended upon components (mocks).
1029 void _expect_function_call(
1030 const char * const function_name,
1031 const char * const file,
1032 const int line,
1033 const int count)
1035 FuncOrderingValue *ordering;
1037 assert_non_null(function_name);
1038 assert_non_null(file);
1039 assert_true(count != 0);
1041 ordering = (FuncOrderingValue *)malloc(sizeof(*ordering));
1043 set_source_location(&ordering->location, file, line);
1044 ordering->function = function_name;
1046 list_add_value(&global_call_ordering_head, ordering, count);
1049 /* Returns 1 if the specified values are equal. If the values are not equal
1050 * an error is displayed and 0 is returned. */
1051 static int values_equal_display_error(const LargestIntegralType left,
1052 const LargestIntegralType right) {
1053 const int equal = left == right;
1054 if (!equal) {
1055 cm_print_error(LargestIntegralTypePrintfFormat " != "
1056 LargestIntegralTypePrintfFormat "\n", left, right);
1058 return equal;
1062 * Returns 1 if the specified values are not equal. If the values are equal
1063 * an error is displayed and 0 is returned. */
1064 static int values_not_equal_display_error(const LargestIntegralType left,
1065 const LargestIntegralType right) {
1066 const int not_equal = left != right;
1067 if (!not_equal) {
1068 cm_print_error(LargestIntegralTypePrintfFormat " == "
1069 LargestIntegralTypePrintfFormat "\n", left, right);
1071 return not_equal;
1076 * Determine whether value is contained within check_integer_set.
1077 * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
1078 * returned and an error is displayed. If invert is 1 and the value is not
1079 * in the set 1 is returned, otherwise 0 is returned and an error is
1080 * displayed.
1082 static int value_in_set_display_error(
1083 const LargestIntegralType value,
1084 const CheckIntegerSet * const check_integer_set, const int invert) {
1085 int succeeded = invert;
1086 assert_non_null(check_integer_set);
1088 const LargestIntegralType * const set = check_integer_set->set;
1089 const size_t size_of_set = check_integer_set->size_of_set;
1090 size_t i;
1091 for (i = 0; i < size_of_set; i++) {
1092 if (set[i] == value) {
1093 /* If invert = 0 and item is found, succeeded = 1. */
1094 /* If invert = 1 and item is found, succeeded = 0. */
1095 succeeded = !succeeded;
1096 break;
1099 if (succeeded) {
1100 return 1;
1102 cm_print_error(LargestIntegralTypePrintfFormatDecimal
1103 " is %sin the set (",
1104 value, invert ? "" : "not ");
1105 for (i = 0; i < size_of_set; i++) {
1106 cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]);
1108 cm_print_error(")\n");
1110 return 0;
1115 * Determine whether a value is within the specified range. If the value is
1116 * within the specified range 1 is returned. If the value isn't within the
1117 * specified range an error is displayed and 0 is returned.
1119 static int integer_in_range_display_error(
1120 const LargestIntegralType value, const LargestIntegralType range_min,
1121 const LargestIntegralType range_max) {
1122 if (value >= range_min && value <= range_max) {
1123 return 1;
1125 cm_print_error(LargestIntegralTypePrintfFormatDecimal
1126 " is not within the range "
1127 LargestIntegralTypePrintfFormatDecimal "-"
1128 LargestIntegralTypePrintfFormatDecimal "\n",
1129 value, range_min, range_max);
1130 return 0;
1135 * Determine whether a value is within the specified range. If the value
1136 * is not within the range 1 is returned. If the value is within the
1137 * specified range an error is displayed and zero is returned.
1139 static int integer_not_in_range_display_error(
1140 const LargestIntegralType value, const LargestIntegralType range_min,
1141 const LargestIntegralType range_max) {
1142 if (value < range_min || value > range_max) {
1143 return 1;
1145 cm_print_error(LargestIntegralTypePrintfFormatDecimal
1146 " is within the range "
1147 LargestIntegralTypePrintfFormatDecimal "-"
1148 LargestIntegralTypePrintfFormatDecimal "\n",
1149 value, range_min, range_max);
1150 return 0;
1155 * Determine whether the specified strings are equal. If the strings are equal
1156 * 1 is returned. If they're not equal an error is displayed and 0 is
1157 * returned.
1159 static int string_equal_display_error(
1160 const char * const left, const char * const right) {
1161 if (strcmp(left, right) == 0) {
1162 return 1;
1164 cm_print_error("\"%s\" != \"%s\"\n", left, right);
1165 return 0;
1170 * Determine whether the specified strings are equal. If the strings are not
1171 * equal 1 is returned. If they're not equal an error is displayed and 0 is
1172 * returned
1174 static int string_not_equal_display_error(
1175 const char * const left, const char * const right) {
1176 if (strcmp(left, right) != 0) {
1177 return 1;
1179 cm_print_error("\"%s\" == \"%s\"\n", left, right);
1180 return 0;
1185 * Determine whether the specified areas of memory are equal. If they're equal
1186 * 1 is returned otherwise an error is displayed and 0 is returned.
1188 static int memory_equal_display_error(const char* const a, const char* const b,
1189 const size_t size) {
1190 int differences = 0;
1191 size_t i;
1192 for (i = 0; i < size; i++) {
1193 const char l = a[i];
1194 const char r = b[i];
1195 if (l != r) {
1196 cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
1197 i, l, r);
1198 differences ++;
1201 if (differences) {
1202 cm_print_error("%d bytes of %p and %p differ\n",
1203 differences, (void *)a, (void *)b);
1204 return 0;
1206 return 1;
1211 * Determine whether the specified areas of memory are not equal. If they're
1212 * not equal 1 is returned otherwise an error is displayed and 0 is
1213 * returned.
1215 static int memory_not_equal_display_error(
1216 const char* const a, const char* const b, const size_t size) {
1217 size_t same = 0;
1218 size_t i;
1219 for (i = 0; i < size; i++) {
1220 const char l = a[i];
1221 const char r = b[i];
1222 if (l == r) {
1223 same ++;
1226 if (same == size) {
1227 cm_print_error("%"PRIdS "bytes of %p and %p the same\n",
1228 same, (void *)a, (void *)b);
1229 return 0;
1231 return 1;
1235 /* CheckParameterValue callback to check whether a value is within a set. */
1236 static int check_in_set(const LargestIntegralType value,
1237 const LargestIntegralType check_value_data) {
1238 return value_in_set_display_error(value,
1239 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1240 check_value_data), 0);
1244 /* CheckParameterValue callback to check whether a value isn't within a set. */
1245 static int check_not_in_set(const LargestIntegralType value,
1246 const LargestIntegralType check_value_data) {
1247 return value_in_set_display_error(value,
1248 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1249 check_value_data), 1);
1253 /* Create the callback data for check_in_set() or check_not_in_set() and
1254 * register a check event. */
1255 static void expect_set(
1256 const char* const function, const char* const parameter,
1257 const char* const file, const int line,
1258 const LargestIntegralType values[], const size_t number_of_values,
1259 const CheckParameterValue check_function, const int count) {
1260 CheckIntegerSet * const check_integer_set =
1261 (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
1262 (sizeof(values[0]) * number_of_values));
1263 LargestIntegralType * const set = (LargestIntegralType*)(
1264 check_integer_set + 1);
1265 declare_initialize_value_pointer_pointer(check_data, check_integer_set);
1266 assert_non_null(values);
1267 assert_true(number_of_values);
1268 memcpy(set, values, number_of_values * sizeof(values[0]));
1269 check_integer_set->set = set;
1270 check_integer_set->size_of_set = number_of_values;
1271 _expect_check(
1272 function, parameter, file, line, check_function,
1273 check_data.value, &check_integer_set->event, count);
1277 /* Add an event to check whether a value is in a set. */
1278 void _expect_in_set(
1279 const char* const function, const char* const parameter,
1280 const char* const file, const int line,
1281 const LargestIntegralType values[], const size_t number_of_values,
1282 const int count) {
1283 expect_set(function, parameter, file, line, values, number_of_values,
1284 check_in_set, count);
1288 /* Add an event to check whether a value isn't in a set. */
1289 void _expect_not_in_set(
1290 const char* const function, const char* const parameter,
1291 const char* const file, const int line,
1292 const LargestIntegralType values[], const size_t number_of_values,
1293 const int count) {
1294 expect_set(function, parameter, file, line, values, number_of_values,
1295 check_not_in_set, count);
1299 /* CheckParameterValue callback to check whether a value is within a range. */
1300 static int check_in_range(const LargestIntegralType value,
1301 const LargestIntegralType check_value_data) {
1302 CheckIntegerRange * const check_integer_range =
1303 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1304 check_value_data);
1305 assert_non_null(check_integer_range);
1306 return integer_in_range_display_error(value, check_integer_range->minimum,
1307 check_integer_range->maximum);
1311 /* CheckParameterValue callback to check whether a value is not within a range. */
1312 static int check_not_in_range(const LargestIntegralType value,
1313 const LargestIntegralType check_value_data) {
1314 CheckIntegerRange * const check_integer_range =
1315 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1316 check_value_data);
1317 assert_non_null(check_integer_range);
1318 return integer_not_in_range_display_error(
1319 value, check_integer_range->minimum, check_integer_range->maximum);
1323 /* Create the callback data for check_in_range() or check_not_in_range() and
1324 * register a check event. */
1325 static void expect_range(
1326 const char* const function, const char* const parameter,
1327 const char* const file, const int line,
1328 const LargestIntegralType minimum, const LargestIntegralType maximum,
1329 const CheckParameterValue check_function, const int count) {
1330 CheckIntegerRange * const check_integer_range =
1331 (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
1332 declare_initialize_value_pointer_pointer(check_data, check_integer_range);
1333 check_integer_range->minimum = minimum;
1334 check_integer_range->maximum = maximum;
1335 _expect_check(function, parameter, file, line, check_function,
1336 check_data.value, &check_integer_range->event, count);
1340 /* Add an event to determine whether a parameter is within a range. */
1341 void _expect_in_range(
1342 const char* const function, const char* const parameter,
1343 const char* const file, const int line,
1344 const LargestIntegralType minimum, const LargestIntegralType maximum,
1345 const int count) {
1346 expect_range(function, parameter, file, line, minimum, maximum,
1347 check_in_range, count);
1351 /* Add an event to determine whether a parameter is not within a range. */
1352 void _expect_not_in_range(
1353 const char* const function, const char* const parameter,
1354 const char* const file, const int line,
1355 const LargestIntegralType minimum, const LargestIntegralType maximum,
1356 const int count) {
1357 expect_range(function, parameter, file, line, minimum, maximum,
1358 check_not_in_range, count);
1362 /* CheckParameterValue callback to check whether a value is equal to an
1363 * expected value. */
1364 static int check_value(const LargestIntegralType value,
1365 const LargestIntegralType check_value_data) {
1366 return values_equal_display_error(value, check_value_data);
1370 /* Add an event to check a parameter equals an expected value. */
1371 void _expect_value(
1372 const char* const function, const char* const parameter,
1373 const char* const file, const int line,
1374 const LargestIntegralType value, const int count) {
1375 _expect_check(function, parameter, file, line, check_value, value, NULL,
1376 count);
1380 /* CheckParameterValue callback to check whether a value is not equal to an
1381 * expected value. */
1382 static int check_not_value(const LargestIntegralType value,
1383 const LargestIntegralType check_value_data) {
1384 return values_not_equal_display_error(value, check_value_data);
1388 /* Add an event to check a parameter is not equal to an expected value. */
1389 void _expect_not_value(
1390 const char* const function, const char* const parameter,
1391 const char* const file, const int line,
1392 const LargestIntegralType value, const int count) {
1393 _expect_check(function, parameter, file, line, check_not_value, value,
1394 NULL, count);
1398 /* CheckParameterValue callback to check whether a parameter equals a string. */
1399 static int check_string(const LargestIntegralType value,
1400 const LargestIntegralType check_value_data) {
1401 return string_equal_display_error(
1402 cast_largest_integral_type_to_pointer(char*, value),
1403 cast_largest_integral_type_to_pointer(char*, check_value_data));
1407 /* Add an event to check whether a parameter is equal to a string. */
1408 void _expect_string(
1409 const char* const function, const char* const parameter,
1410 const char* const file, const int line, const char* string,
1411 const int count) {
1412 declare_initialize_value_pointer_pointer(string_pointer,
1413 discard_const(string));
1414 _expect_check(function, parameter, file, line, check_string,
1415 string_pointer.value, NULL, count);
1419 /* CheckParameterValue callback to check whether a parameter is not equals to
1420 * a string. */
1421 static int check_not_string(const LargestIntegralType value,
1422 const LargestIntegralType check_value_data) {
1423 return string_not_equal_display_error(
1424 cast_largest_integral_type_to_pointer(char*, value),
1425 cast_largest_integral_type_to_pointer(char*, check_value_data));
1429 /* Add an event to check whether a parameter is not equal to a string. */
1430 void _expect_not_string(
1431 const char* const function, const char* const parameter,
1432 const char* const file, const int line, const char* string,
1433 const int count) {
1434 declare_initialize_value_pointer_pointer(string_pointer,
1435 discard_const(string));
1436 _expect_check(function, parameter, file, line, check_not_string,
1437 string_pointer.value, NULL, count);
1440 /* CheckParameterValue callback to check whether a parameter equals an area of
1441 * memory. */
1442 static int check_memory(const LargestIntegralType value,
1443 const LargestIntegralType check_value_data) {
1444 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1445 CheckMemoryData*, check_value_data);
1446 assert_non_null(check);
1447 return memory_equal_display_error(
1448 cast_largest_integral_type_to_pointer(const char*, value),
1449 (const char*)check->memory, check->size);
1453 /* Create the callback data for check_memory() or check_not_memory() and
1454 * register a check event. */
1455 static void expect_memory_setup(
1456 const char* const function, const char* const parameter,
1457 const char* const file, const int line,
1458 const void * const memory, const size_t size,
1459 const CheckParameterValue check_function, const int count) {
1460 CheckMemoryData * const check_data =
1461 (CheckMemoryData*)malloc(sizeof(*check_data) + size);
1462 void * const mem = (void*)(check_data + 1);
1463 declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1464 assert_non_null(memory);
1465 assert_true(size);
1466 memcpy(mem, memory, size);
1467 check_data->memory = mem;
1468 check_data->size = size;
1469 _expect_check(function, parameter, file, line, check_function,
1470 check_data_pointer.value, &check_data->event, count);
1474 /* Add an event to check whether a parameter matches an area of memory. */
1475 void _expect_memory(
1476 const char* const function, const char* const parameter,
1477 const char* const file, const int line, const void* const memory,
1478 const size_t size, const int count) {
1479 expect_memory_setup(function, parameter, file, line, memory, size,
1480 check_memory, count);
1484 /* CheckParameterValue callback to check whether a parameter is not equal to
1485 * an area of memory. */
1486 static int check_not_memory(const LargestIntegralType value,
1487 const LargestIntegralType check_value_data) {
1488 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1489 CheckMemoryData*, check_value_data);
1490 assert_non_null(check);
1491 return memory_not_equal_display_error(
1492 cast_largest_integral_type_to_pointer(const char*, value),
1493 (const char*)check->memory,
1494 check->size);
1498 /* Add an event to check whether a parameter doesn't match an area of memory. */
1499 void _expect_not_memory(
1500 const char* const function, const char* const parameter,
1501 const char* const file, const int line, const void* const memory,
1502 const size_t size, const int count) {
1503 expect_memory_setup(function, parameter, file, line, memory, size,
1504 check_not_memory, count);
1508 /* CheckParameterValue callback that always returns 1. */
1509 static int check_any(const LargestIntegralType value,
1510 const LargestIntegralType check_value_data) {
1511 (void)value;
1512 (void)check_value_data;
1513 return 1;
1517 /* Add an event to allow any value for a parameter. */
1518 void _expect_any(
1519 const char* const function, const char* const parameter,
1520 const char* const file, const int line, const int count) {
1521 _expect_check(function, parameter, file, line, check_any, 0, NULL,
1522 count);
1526 void _check_expected(
1527 const char * const function_name, const char * const parameter_name,
1528 const char* file, const int line, const LargestIntegralType value) {
1529 void *result;
1530 const char* symbols[] = {function_name, parameter_name};
1531 const int rc = get_symbol_value(&global_function_parameter_map_head,
1532 symbols, 2, &result);
1533 if (rc) {
1534 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1535 int check_succeeded;
1536 global_last_parameter_location = check->location;
1537 check_succeeded = check->check_value(value, check->check_value_data);
1538 if (rc == 1) {
1539 free(check);
1541 if (!check_succeeded) {
1542 cm_print_error(SOURCE_LOCATION_FORMAT
1543 ": error: Check of parameter %s, function %s failed\n"
1544 SOURCE_LOCATION_FORMAT
1545 ": note: Expected parameter declared here\n",
1546 file, line,
1547 parameter_name, function_name,
1548 global_last_parameter_location.file,
1549 global_last_parameter_location.line);
1550 _fail(file, line);
1552 } else {
1553 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
1554 "to check parameter %s of function %s\n", file, line,
1555 parameter_name, function_name);
1556 if (source_location_is_set(&global_last_parameter_location)) {
1557 cm_print_error(SOURCE_LOCATION_FORMAT
1558 ": note: Previously declared parameter value was declared here\n",
1559 global_last_parameter_location.file,
1560 global_last_parameter_location.line);
1561 } else {
1562 cm_print_error("There were no previously declared parameter values "
1563 "for this test.\n");
1565 exit_test(1);
1570 /* Replacement for assert. */
1571 void mock_assert(const int result, const char* const expression,
1572 const char* const file, const int line) {
1573 if (!result) {
1574 if (global_expecting_assert) {
1575 global_last_failed_assert = expression;
1576 longjmp(global_expect_assert_env, result);
1577 } else {
1578 cm_print_error("ASSERT: %s\n", expression);
1579 _fail(file, line);
1585 void _assert_true(const LargestIntegralType result,
1586 const char * const expression,
1587 const char * const file, const int line) {
1588 if (!result) {
1589 cm_print_error("%s\n", expression);
1590 _fail(file, line);
1594 void _assert_return_code(const LargestIntegralType result,
1595 size_t rlen,
1596 const LargestIntegralType error,
1597 const char * const expression,
1598 const char * const file,
1599 const int line)
1601 LargestIntegralType valmax;
1604 switch (rlen) {
1605 case 1:
1606 valmax = 255;
1607 break;
1608 case 2:
1609 valmax = 32767;
1610 break;
1611 case 4:
1612 valmax = 2147483647;
1613 break;
1614 case 8:
1615 default:
1616 if (rlen > sizeof(valmax)) {
1617 valmax = 2147483647;
1618 } else {
1619 valmax = 9223372036854775807L;
1621 break;
1624 if (result > valmax - 1) {
1625 if (error > 0) {
1626 cm_print_error("%s < 0, errno("
1627 LargestIntegralTypePrintfFormatDecimal "): %s\n",
1628 expression, error, strerror((int)error));
1629 } else {
1630 cm_print_error("%s < 0\n", expression);
1632 _fail(file, line);
1636 void _assert_int_equal(
1637 const LargestIntegralType a, const LargestIntegralType b,
1638 const char * const file, const int line) {
1639 if (!values_equal_display_error(a, b)) {
1640 _fail(file, line);
1645 void _assert_int_not_equal(
1646 const LargestIntegralType a, const LargestIntegralType b,
1647 const char * const file, const int line) {
1648 if (!values_not_equal_display_error(a, b)) {
1649 _fail(file, line);
1654 void _assert_string_equal(const char * const a, const char * const b,
1655 const char * const file, const int line) {
1656 if (!string_equal_display_error(a, b)) {
1657 _fail(file, line);
1662 void _assert_string_not_equal(const char * const a, const char * const b,
1663 const char *file, const int line) {
1664 if (!string_not_equal_display_error(a, b)) {
1665 _fail(file, line);
1670 void _assert_memory_equal(const void * const a, const void * const b,
1671 const size_t size, const char* const file,
1672 const int line) {
1673 if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1674 _fail(file, line);
1679 void _assert_memory_not_equal(const void * const a, const void * const b,
1680 const size_t size, const char* const file,
1681 const int line) {
1682 if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1683 size)) {
1684 _fail(file, line);
1689 void _assert_in_range(
1690 const LargestIntegralType value, const LargestIntegralType minimum,
1691 const LargestIntegralType maximum, const char* const file,
1692 const int line) {
1693 if (!integer_in_range_display_error(value, minimum, maximum)) {
1694 _fail(file, line);
1698 void _assert_not_in_range(
1699 const LargestIntegralType value, const LargestIntegralType minimum,
1700 const LargestIntegralType maximum, const char* const file,
1701 const int line) {
1702 if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1703 _fail(file, line);
1707 void _assert_in_set(const LargestIntegralType value,
1708 const LargestIntegralType values[],
1709 const size_t number_of_values, const char* const file,
1710 const int line) {
1711 CheckIntegerSet check_integer_set;
1712 check_integer_set.set = values;
1713 check_integer_set.size_of_set = number_of_values;
1714 if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1715 _fail(file, line);
1719 void _assert_not_in_set(const LargestIntegralType value,
1720 const LargestIntegralType values[],
1721 const size_t number_of_values, const char* const file,
1722 const int line) {
1723 CheckIntegerSet check_integer_set;
1724 check_integer_set.set = values;
1725 check_integer_set.size_of_set = number_of_values;
1726 if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1727 _fail(file, line);
1732 /* Get the list of allocated blocks. */
1733 static ListNode* get_allocated_blocks_list(void) {
1734 /* If it initialized, initialize the list of allocated blocks. */
1735 if (!global_allocated_blocks.value) {
1736 list_initialize(&global_allocated_blocks);
1737 global_allocated_blocks.value = (void*)1;
1739 return &global_allocated_blocks;
1742 static void *libc_malloc(size_t size)
1744 #undef malloc
1745 return malloc(size);
1746 #define malloc test_malloc
1749 static void libc_free(void *ptr)
1751 #undef free
1752 free(ptr);
1753 #define free test_free
1756 static void *libc_realloc(void *ptr, size_t size)
1758 #undef realloc
1759 return realloc(ptr, size);
1760 #define realloc test_realloc
1763 static void vcm_print_error(const char* const format,
1764 va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
1766 /* It's important to use the libc malloc and free here otherwise
1767 * the automatic free of leaked blocks can reap the error messages
1769 static void vcm_print_error(const char* const format, va_list args)
1771 char buffer[1024];
1772 size_t msg_len = 0;
1773 va_list ap;
1774 int len;
1775 va_copy(ap, args);
1777 len = vsnprintf(buffer, sizeof(buffer), format, args);
1778 if (len < 0) {
1779 /* TODO */
1780 goto end;
1783 if (cm_error_message == NULL) {
1784 /* CREATE MESSAGE */
1786 cm_error_message = libc_malloc(len + 1);
1787 if (cm_error_message == NULL) {
1788 /* TODO */
1789 goto end;
1791 } else {
1792 /* APPEND MESSAGE */
1793 char *tmp;
1795 msg_len = strlen(cm_error_message);
1796 tmp = libc_realloc(cm_error_message, msg_len + len + 1);
1797 if (tmp == NULL) {
1798 goto end;
1800 cm_error_message = tmp;
1803 if (((size_t)len) < sizeof(buffer)) {
1804 /* Use len + 1 to also copy '\0' */
1805 memcpy(cm_error_message + msg_len, buffer, len + 1);
1806 } else {
1807 vsnprintf(cm_error_message + msg_len, len, format, ap);
1809 end:
1810 va_end(ap);
1814 static void vcm_free_error(char *err_msg)
1816 libc_free(err_msg);
1819 /* Use the real malloc in this function. */
1820 #undef malloc
1821 void* _test_malloc(const size_t size, const char* file, const int line) {
1822 char* ptr;
1823 MallocBlockInfo *block_info;
1824 ListNode * const block_list = get_allocated_blocks_list();
1825 const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
1826 sizeof(*block_info) + MALLOC_ALIGNMENT;
1827 char* const block = (char*)malloc(allocate_size);
1828 assert_non_null(block);
1830 /* Calculate the returned address. */
1831 ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
1832 MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1834 /* Initialize the guard blocks. */
1835 memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1836 memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1837 memset(ptr, MALLOC_ALLOC_PATTERN, size);
1839 block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
1840 sizeof(*block_info)));
1841 set_source_location(&block_info->location, file, line);
1842 block_info->allocated_size = allocate_size;
1843 block_info->size = size;
1844 block_info->block = block;
1845 block_info->node.value = block_info;
1846 list_add(block_list, &block_info->node);
1847 return ptr;
1849 #define malloc test_malloc
1852 void* _test_calloc(const size_t number_of_elements, const size_t size,
1853 const char* file, const int line) {
1854 void* const ptr = _test_malloc(number_of_elements * size, file, line);
1855 if (ptr) {
1856 memset(ptr, 0, number_of_elements * size);
1858 return ptr;
1862 /* Use the real free in this function. */
1863 #undef free
1864 void _test_free(void* const ptr, const char* file, const int line) {
1865 unsigned int i;
1866 char *block = discard_const_p(char, ptr);
1867 MallocBlockInfo *block_info;
1869 if (ptr == NULL) {
1870 return;
1873 _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
1874 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1875 sizeof(*block_info)));
1876 /* Check the guard blocks. */
1878 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1879 block + block_info->size};
1880 for (i = 0; i < ARRAY_SIZE(guards); i++) {
1881 unsigned int j;
1882 char * const guard = guards[i];
1883 for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1884 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1885 if (diff) {
1886 cm_print_error(SOURCE_LOCATION_FORMAT
1887 ": error: Guard block of %p size=%lu is corrupt\n"
1888 SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
1889 file, line,
1890 ptr, (unsigned long)block_info->size,
1891 block_info->location.file, block_info->location.line,
1892 (void *)&guard[j]);
1893 _fail(file, line);
1898 list_remove(&block_info->node, NULL, NULL);
1900 block = discard_const_p(char, block_info->block);
1901 memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
1902 free(block);
1904 #define free test_free
1906 #undef realloc
1907 void *_test_realloc(void *ptr,
1908 const size_t size,
1909 const char *file,
1910 const int line)
1912 MallocBlockInfo *block_info;
1913 char *block = ptr;
1914 size_t block_size = size;
1915 void *new_block;
1917 if (ptr == NULL) {
1918 return _test_malloc(size, file, line);
1921 if (size == 0) {
1922 _test_free(ptr, file, line);
1923 return NULL;
1926 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1927 sizeof(*block_info)));
1929 new_block = _test_malloc(size, file, line);
1930 if (new_block == NULL) {
1931 return NULL;
1934 if (block_info->size < size) {
1935 block_size = block_info->size;
1938 memcpy(new_block, ptr, block_size);
1940 /* Free previous memory */
1941 _test_free(ptr, file, line);
1943 return new_block;
1945 #define realloc test_realloc
1947 /* Crudely checkpoint the current heap state. */
1948 static const ListNode* check_point_allocated_blocks(void) {
1949 return get_allocated_blocks_list()->prev;
1953 /* Display the blocks allocated after the specified check point. This
1954 * function returns the number of blocks displayed. */
1955 static int display_allocated_blocks(const ListNode * const check_point) {
1956 const ListNode * const head = get_allocated_blocks_list();
1957 const ListNode *node;
1958 int allocated_blocks = 0;
1959 assert_non_null(check_point);
1960 assert_non_null(check_point->next);
1962 for (node = check_point->next; node != head; node = node->next) {
1963 const MallocBlockInfo * const block_info =
1964 (const MallocBlockInfo*)node->value;
1965 assert_non_null(block_info);
1967 if (!allocated_blocks) {
1968 cm_print_error("Blocks allocated...\n");
1970 cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
1971 block_info->location.file,
1972 block_info->location.line,
1973 block_info->block);
1974 allocated_blocks ++;
1976 return allocated_blocks;
1980 /* Free all blocks allocated after the specified check point. */
1981 static void free_allocated_blocks(const ListNode * const check_point) {
1982 const ListNode * const head = get_allocated_blocks_list();
1983 const ListNode *node;
1984 assert_non_null(check_point);
1986 node = check_point->next;
1987 assert_non_null(node);
1989 while (node != head) {
1990 MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
1991 node = node->next;
1992 free(discard_const_p(char, block_info) + sizeof(*block_info) + MALLOC_GUARD_SIZE);
1997 /* Fail if any any blocks are allocated after the specified check point. */
1998 static void fail_if_blocks_allocated(const ListNode * const check_point,
1999 const char * const test_name) {
2000 const int allocated_blocks = display_allocated_blocks(check_point);
2001 if (allocated_blocks) {
2002 free_allocated_blocks(check_point);
2003 cm_print_error("ERROR: %s leaked %d block(s)\n", test_name,
2004 allocated_blocks);
2005 exit_test(1);
2010 void _fail(const char * const file, const int line) {
2011 enum cm_message_output output = cm_get_output();
2013 switch(output) {
2014 case CM_OUTPUT_STDOUT:
2015 cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
2016 break;
2017 default:
2018 cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
2019 break;
2021 exit_test(1);
2025 #ifndef _WIN32
2026 static void exception_handler(int sig) {
2027 const char *sig_strerror = "";
2029 #ifdef HAVE_STRSIGNAL
2030 sig_strerror = strsignal(sig);
2031 #endif
2033 cm_print_error("Test failed with exception: %s(%d)",
2034 sig_strerror, sig);
2035 exit_test(1);
2038 #else /* _WIN32 */
2040 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
2041 EXCEPTION_RECORD * const exception_record =
2042 exception_pointers->ExceptionRecord;
2043 const DWORD code = exception_record->ExceptionCode;
2044 unsigned int i;
2045 for (i = 0; i < ARRAY_SIZE(exception_codes); i++) {
2046 const ExceptionCodeInfo * const code_info = &exception_codes[i];
2047 if (code == code_info->code) {
2048 static int shown_debug_message = 0;
2049 fflush(stdout);
2050 cm_print_error("%s occurred at %p.\n", code_info->description,
2051 exception_record->ExceptionAddress);
2052 if (!shown_debug_message) {
2053 cm_print_error(
2054 "\n"
2055 "To debug in Visual Studio...\n"
2056 "1. Select menu item File->Open Project\n"
2057 "2. Change 'Files of type' to 'Executable Files'\n"
2058 "3. Open this executable.\n"
2059 "4. Select menu item Debug->Start\n"
2060 "\n"
2061 "Alternatively, set the environment variable \n"
2062 "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
2063 "then click 'Debug' in the popup dialog box.\n"
2064 "\n");
2065 shown_debug_message = 1;
2067 exit_test(0);
2068 return EXCEPTION_EXECUTE_HANDLER;
2071 return EXCEPTION_CONTINUE_SEARCH;
2073 #endif /* !_WIN32 */
2075 void cm_print_error(const char * const format, ...)
2077 va_list args;
2078 va_start(args, format);
2079 if (cm_error_message_enabled) {
2080 vcm_print_error(format, args);
2081 } else {
2082 vprint_error(format, args);
2084 va_end(args);
2087 /* Standard output and error print methods. */
2088 void vprint_message(const char* const format, va_list args) {
2089 char buffer[1024];
2090 vsnprintf(buffer, sizeof(buffer), format, args);
2091 printf("%s", buffer);
2092 fflush(stdout);
2093 #ifdef _WIN32
2094 OutputDebugString(buffer);
2095 #endif /* _WIN32 */
2099 void vprint_error(const char* const format, va_list args) {
2100 char buffer[1024];
2101 vsnprintf(buffer, sizeof(buffer), format, args);
2102 fprintf(stderr, "%s", buffer);
2103 fflush(stderr);
2104 #ifdef _WIN32
2105 OutputDebugString(buffer);
2106 #endif /* _WIN32 */
2110 void print_message(const char* const format, ...) {
2111 va_list args;
2112 va_start(args, format);
2113 vprint_message(format, args);
2114 va_end(args);
2118 void print_error(const char* const format, ...) {
2119 va_list args;
2120 va_start(args, format);
2121 vprint_error(format, args);
2122 va_end(args);
2125 /* New formatter */
2126 static enum cm_message_output cm_get_output(void)
2128 enum cm_message_output output = global_msg_output;
2129 char *env;
2131 env = getenv("CMOCKA_MESSAGE_OUTPUT");
2132 if (env != NULL) {
2133 if (strcasecmp(env, "STDOUT") == 0) {
2134 output = CM_OUTPUT_STDOUT;
2135 } else if (strcasecmp(env, "SUBUNIT") == 0) {
2136 output = CM_OUTPUT_SUBUNIT;
2137 } else if (strcasecmp(env, "TAP") == 0) {
2138 output = CM_OUTPUT_TAP;
2139 } else if (strcasecmp(env, "XML") == 0) {
2140 output = CM_OUTPUT_XML;
2144 return output;
2147 enum cm_printf_type {
2148 PRINTF_TEST_START,
2149 PRINTF_TEST_SUCCESS,
2150 PRINTF_TEST_FAILURE,
2151 PRINTF_TEST_ERROR,
2152 PRINTF_TEST_SKIPPED,
2155 static int xml_printed;
2156 static int file_append;
2158 static void cmprintf_group_finish_xml(const char *group_name,
2159 size_t total_executed,
2160 size_t total_failed,
2161 size_t total_errors,
2162 size_t total_skipped,
2163 double total_runtime,
2164 struct CMUnitTestState *cm_tests)
2166 FILE *fp = stdout;
2167 int file_opened = 0;
2168 int multiple_files = 0;
2169 char *env;
2170 size_t i;
2172 env = getenv("CMOCKA_XML_FILE");
2173 if (env != NULL) {
2174 char buf[1024];
2175 int rc;
2177 snprintf(buf, sizeof(buf), "%s", env);
2179 rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files);
2180 if (rc < 0) {
2181 snprintf(buf, sizeof(buf), "%s", env);
2184 fp = fopen(buf, "r");
2185 if (fp == NULL) {
2186 fp = fopen(buf, "w");
2187 if (fp != NULL) {
2188 file_append = 1;
2189 file_opened = 1;
2190 } else {
2191 fp = stderr;
2193 } else {
2194 fclose(fp);
2195 if (file_append) {
2196 fp = fopen(buf, "a");
2197 if (fp != NULL) {
2198 file_opened = 1;
2199 xml_printed = 1;
2200 } else {
2201 fp = stderr;
2203 } else {
2204 fp = stderr;
2209 if (!xml_printed || (file_opened && !file_append)) {
2210 fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
2211 if (!file_opened) {
2212 xml_printed = 1;
2216 fprintf(fp, "<testsuites>\n");
2217 fprintf(fp, " <testsuite name=\"%s\" time=\"%.3f\" "
2218 "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
2219 group_name,
2220 total_runtime, /* seconds */
2221 (unsigned)total_executed,
2222 (unsigned)total_failed,
2223 (unsigned)total_errors,
2224 (unsigned)total_skipped);
2226 for (i = 0; i < total_executed; i++) {
2227 struct CMUnitTestState *cmtest = &cm_tests[i];
2229 fprintf(fp, " <testcase name=\"%s\" time=\"%.3f\" >\n",
2230 cmtest->test->name, cmtest->runtime);
2232 switch (cmtest->status) {
2233 case CM_TEST_ERROR:
2234 case CM_TEST_FAILED:
2235 if (cmtest->error_message != NULL) {
2236 fprintf(fp, " <failure><![CDATA[%s]]></failure>\n",
2237 cmtest->error_message);
2238 } else {
2239 fprintf(fp, " <failure message=\"Unknown error\" />\n");
2241 break;
2242 case CM_TEST_SKIPPED:
2243 fprintf(fp, " <skipped/>\n");
2244 break;
2246 case CM_TEST_PASSED:
2247 case CM_TEST_NOT_STARTED:
2248 break;
2251 fprintf(fp, " </testcase>\n");
2254 fprintf(fp, " </testsuite>\n");
2255 fprintf(fp, "</testsuites>\n");
2257 if (file_opened) {
2258 fclose(fp);
2262 static void cmprintf_group_start_standard(const size_t num_tests)
2264 print_message("[==========] Running %u test(s).\n",
2265 (unsigned)num_tests);
2268 static void cmprintf_group_finish_standard(size_t total_executed,
2269 size_t total_passed,
2270 size_t total_failed,
2271 size_t total_errors,
2272 size_t total_skipped,
2273 struct CMUnitTestState *cm_tests)
2275 size_t i;
2277 print_message("[==========] %u test(s) run.\n", (unsigned)total_executed);
2278 print_error("[ PASSED ] %u test(s).\n",
2279 (unsigned)(total_passed));
2281 if (total_skipped) {
2282 print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped);
2283 for (i = 0; i < total_executed; i++) {
2284 struct CMUnitTestState *cmtest = &cm_tests[i];
2286 if (cmtest->status == CM_TEST_SKIPPED) {
2287 print_error("[ SKIPPED ] %s\n", cmtest->test->name);
2290 print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped));
2293 if (total_failed) {
2294 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
2295 for (i = 0; i < total_executed; i++) {
2296 struct CMUnitTestState *cmtest = &cm_tests[i];
2298 if (cmtest->status == CM_TEST_FAILED) {
2299 print_error("[ FAILED ] %s\n", cmtest->test->name);
2302 print_error("\n %u FAILED TEST(S)\n",
2303 (unsigned)(total_failed + total_errors));
2307 static void cmprintf_standard(enum cm_printf_type type,
2308 const char *test_name,
2309 const char *error_message)
2311 switch (type) {
2312 case PRINTF_TEST_START:
2313 print_message("[ RUN ] %s\n", test_name);
2314 break;
2315 case PRINTF_TEST_SUCCESS:
2316 print_message("[ OK ] %s\n", test_name);
2317 break;
2318 case PRINTF_TEST_FAILURE:
2319 if (error_message != NULL) {
2320 print_error("[ ERROR ] --- %s\n", error_message);
2322 print_message("[ FAILED ] %s\n", test_name);
2323 break;
2324 case PRINTF_TEST_SKIPPED:
2325 print_message("[ SKIPPED ] %s\n", test_name);
2326 break;
2327 case PRINTF_TEST_ERROR:
2328 if (error_message != NULL) {
2329 print_error("%s\n", error_message);
2331 print_error("[ ERROR ] %s\n", test_name);
2332 break;
2336 static void cmprintf_group_start_tap(const size_t num_tests)
2338 print_message("1..%u\n", (unsigned)num_tests);
2341 static void cmprintf_group_finish_tap(const char *group_name,
2342 size_t total_executed,
2343 size_t total_passed,
2344 size_t total_skipped)
2346 const char *status = "not ok";
2347 if (total_passed + total_skipped == total_executed) {
2348 status = "ok";
2350 print_message("# %s - %s\n", status, group_name);
2353 static void cmprintf_tap(enum cm_printf_type type,
2354 uint32_t test_number,
2355 const char *test_name,
2356 const char *error_message)
2358 switch (type) {
2359 case PRINTF_TEST_START:
2360 break;
2361 case PRINTF_TEST_SUCCESS:
2362 print_message("ok %u - %s\n", (unsigned)test_number, test_name);
2363 break;
2364 case PRINTF_TEST_FAILURE:
2365 print_message("not ok %u - %s\n", (unsigned)test_number, test_name);
2366 if (error_message != NULL) {
2367 char *msg;
2368 char *p;
2370 msg = strdup(error_message);
2371 if (msg == NULL) {
2372 return;
2374 p = msg;
2376 while (p[0] != '\0') {
2377 char *q = p;
2379 p = strchr(q, '\n');
2380 if (p != NULL) {
2381 p[0] = '\0';
2384 print_message("# %s\n", q);
2386 if (p == NULL) {
2387 break;
2389 p++;
2391 libc_free(msg);
2393 break;
2394 case PRINTF_TEST_SKIPPED:
2395 print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name);
2396 break;
2397 case PRINTF_TEST_ERROR:
2398 print_message("not ok %u - %s %s\n",
2399 (unsigned)test_number, test_name, error_message);
2400 break;
2404 static void cmprintf_subunit(enum cm_printf_type type,
2405 const char *test_name,
2406 const char *error_message)
2408 switch (type) {
2409 case PRINTF_TEST_START:
2410 print_message("test: %s\n", test_name);
2411 break;
2412 case PRINTF_TEST_SUCCESS:
2413 print_message("success: %s\n", test_name);
2414 break;
2415 case PRINTF_TEST_FAILURE:
2416 print_message("failure: %s", test_name);
2417 if (error_message != NULL) {
2418 print_message(" [\n%s]\n", error_message);
2420 break;
2421 case PRINTF_TEST_SKIPPED:
2422 print_message("skip: %s\n", test_name);
2423 break;
2424 case PRINTF_TEST_ERROR:
2425 print_message("error: %s [ %s ]\n", test_name, error_message);
2426 break;
2430 static void cmprintf_group_start(const size_t num_tests)
2432 enum cm_message_output output;
2434 output = cm_get_output();
2436 switch (output) {
2437 case CM_OUTPUT_STDOUT:
2438 cmprintf_group_start_standard(num_tests);
2439 break;
2440 case CM_OUTPUT_SUBUNIT:
2441 break;
2442 case CM_OUTPUT_TAP:
2443 cmprintf_group_start_tap(num_tests);
2444 break;
2445 case CM_OUTPUT_XML:
2446 break;
2450 static void cmprintf_group_finish(const char *group_name,
2451 size_t total_executed,
2452 size_t total_passed,
2453 size_t total_failed,
2454 size_t total_errors,
2455 size_t total_skipped,
2456 double total_runtime,
2457 struct CMUnitTestState *cm_tests)
2459 enum cm_message_output output;
2461 output = cm_get_output();
2463 switch (output) {
2464 case CM_OUTPUT_STDOUT:
2465 cmprintf_group_finish_standard(total_executed,
2466 total_passed,
2467 total_failed,
2468 total_errors,
2469 total_skipped,
2470 cm_tests);
2471 break;
2472 case CM_OUTPUT_SUBUNIT:
2473 break;
2474 case CM_OUTPUT_TAP:
2475 cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped);
2476 break;
2477 case CM_OUTPUT_XML:
2478 cmprintf_group_finish_xml(group_name,
2479 total_executed,
2480 total_failed,
2481 total_errors,
2482 total_skipped,
2483 total_runtime,
2484 cm_tests);
2485 break;
2489 static void cmprintf(enum cm_printf_type type,
2490 size_t test_number,
2491 const char *test_name,
2492 const char *error_message)
2494 enum cm_message_output output;
2496 output = cm_get_output();
2498 switch (output) {
2499 case CM_OUTPUT_STDOUT:
2500 cmprintf_standard(type, test_name, error_message);
2501 break;
2502 case CM_OUTPUT_SUBUNIT:
2503 cmprintf_subunit(type, test_name, error_message);
2504 break;
2505 case CM_OUTPUT_TAP:
2506 cmprintf_tap(type, test_number, test_name, error_message);
2507 break;
2508 case CM_OUTPUT_XML:
2509 break;
2513 void cmocka_set_message_output(enum cm_message_output output)
2515 global_msg_output = output;
2518 /****************************************************************************
2519 * TIME CALCULATIONS
2520 ****************************************************************************/
2522 #ifdef HAVE_STRUCT_TIMESPEC
2523 static struct timespec cm_tspecdiff(struct timespec time1,
2524 struct timespec time0)
2526 struct timespec ret;
2527 int xsec = 0;
2528 int sign = 1;
2530 if (time0.tv_nsec > time1.tv_nsec) {
2531 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
2532 time0.tv_nsec -= (long int) (1E9 * xsec);
2533 time0.tv_sec += xsec;
2536 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
2537 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
2538 time0.tv_nsec += (long int) (1E9 * xsec);
2539 time0.tv_sec -= xsec;
2542 ret.tv_sec = time1.tv_sec - time0.tv_sec;
2543 ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
2545 if (time1.tv_sec < time0.tv_sec) {
2546 sign = -1;
2549 ret.tv_sec = ret.tv_sec * sign;
2551 return ret;
2554 static double cm_secdiff(struct timespec clock1, struct timespec clock0)
2556 double ret;
2557 struct timespec diff;
2559 diff = cm_tspecdiff(clock1, clock0);
2561 ret = diff.tv_sec;
2562 ret += (double) diff.tv_nsec / (double) 1E9;
2564 return ret;
2566 #endif /* HAVE_STRUCT_TIMESPEC */
2568 /****************************************************************************
2569 * CMOCKA TEST RUNNER
2570 ****************************************************************************/
2571 static int cmocka_run_one_test_or_fixture(const char *function_name,
2572 CMUnitTestFunction test_func,
2573 CMFixtureFunction setup_func,
2574 CMFixtureFunction teardown_func,
2575 void ** const volatile state,
2576 const void *const heap_check_point)
2578 const ListNode * const volatile check_point = (const ListNode*)
2579 (heap_check_point != NULL ?
2580 heap_check_point : check_point_allocated_blocks());
2581 int handle_exceptions = 1;
2582 void *current_state = NULL;
2583 int rc = 0;
2585 /* FIXME check only one test or fixture is set */
2587 /* Detect if we should handle exceptions */
2588 #ifdef _WIN32
2589 handle_exceptions = !IsDebuggerPresent();
2590 #endif /* _WIN32 */
2591 #ifdef UNIT_TESTING_DEBUG
2592 handle_exceptions = 0;
2593 #endif /* UNIT_TESTING_DEBUG */
2596 if (handle_exceptions) {
2597 #ifndef _WIN32
2598 unsigned int i;
2599 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2600 default_signal_functions[i] = signal(
2601 exception_signals[i], exception_handler);
2603 #else /* _WIN32 */
2604 previous_exception_filter = SetUnhandledExceptionFilter(
2605 exception_filter);
2606 #endif /* !_WIN32 */
2609 /* Init the test structure */
2610 initialize_testing(function_name);
2612 global_running_test = 1;
2614 if (cm_setjmp(global_run_test_env) == 0) {
2615 if (test_func != NULL) {
2616 test_func(state != NULL ? state : &current_state);
2618 fail_if_blocks_allocated(check_point, function_name);
2619 rc = 0;
2620 } else if (setup_func != NULL) {
2621 rc = setup_func(state != NULL ? state : &current_state);
2624 * For setup we can ignore any allocated blocks. We just need to
2625 * ensure they're deallocated on tear down.
2627 } else if (teardown_func != NULL) {
2628 rc = teardown_func(state != NULL ? state : &current_state);
2630 fail_if_blocks_allocated(check_point, function_name);
2631 } else {
2632 /* ERROR */
2634 fail_if_leftover_values(function_name);
2635 global_running_test = 0;
2636 } else {
2637 /* TEST FAILED */
2638 global_running_test = 0;
2639 rc = -1;
2641 teardown_testing(function_name);
2643 if (handle_exceptions) {
2644 #ifndef _WIN32
2645 unsigned int i;
2646 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2647 signal(exception_signals[i], default_signal_functions[i]);
2649 #else /* _WIN32 */
2650 if (previous_exception_filter) {
2651 SetUnhandledExceptionFilter(previous_exception_filter);
2652 previous_exception_filter = NULL;
2654 #endif /* !_WIN32 */
2657 return rc;
2660 static int cmocka_run_group_fixture(const char *function_name,
2661 CMFixtureFunction setup_func,
2662 CMFixtureFunction teardown_func,
2663 void **state,
2664 const void *const heap_check_point)
2666 int rc;
2668 if (setup_func != NULL) {
2669 rc = cmocka_run_one_test_or_fixture(function_name,
2670 NULL,
2671 setup_func,
2672 NULL,
2673 state,
2674 heap_check_point);
2675 } else {
2676 rc = cmocka_run_one_test_or_fixture(function_name,
2677 NULL,
2678 NULL,
2679 teardown_func,
2680 state,
2681 heap_check_point);
2684 return rc;
2687 static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
2689 #ifdef HAVE_STRUCT_TIMESPEC
2690 struct timespec start = {
2691 .tv_sec = 0,
2692 .tv_nsec = 0,
2694 struct timespec finish = {
2695 .tv_sec = 0,
2696 .tv_nsec = 0,
2698 #endif
2699 int rc = 0;
2701 /* Run setup */
2702 if (test_state->test->setup_func != NULL) {
2703 /* Setup the memory check point, it will be evaluated on teardown */
2704 test_state->check_point = check_point_allocated_blocks();
2706 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2707 NULL,
2708 test_state->test->setup_func,
2709 NULL,
2710 &test_state->state,
2711 test_state->check_point);
2712 if (rc != 0) {
2713 test_state->status = CM_TEST_ERROR;
2714 cm_print_error("Test setup failed");
2718 /* Run test */
2719 #ifdef HAVE_STRUCT_TIMESPEC
2720 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
2721 #endif
2723 if (rc == 0) {
2724 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2725 test_state->test->test_func,
2726 NULL,
2727 NULL,
2728 &test_state->state,
2729 NULL);
2730 if (rc == 0) {
2731 test_state->status = CM_TEST_PASSED;
2732 } else {
2733 if (global_skip_test) {
2734 test_state->status = CM_TEST_SKIPPED;
2735 global_skip_test = 0; /* Do not skip the next test */
2736 } else {
2737 test_state->status = CM_TEST_FAILED;
2740 rc = 0;
2743 test_state->runtime = 0.0;
2745 #ifdef HAVE_STRUCT_TIMESPEC
2746 CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
2747 test_state->runtime = cm_secdiff(finish, start);
2748 #endif
2750 /* Run teardown */
2751 if (rc == 0 && test_state->test->teardown_func != NULL) {
2752 rc = cmocka_run_one_test_or_fixture(test_state->test->name,
2753 NULL,
2754 NULL,
2755 test_state->test->teardown_func,
2756 &test_state->state,
2757 test_state->check_point);
2758 if (rc != 0) {
2759 test_state->status = CM_TEST_ERROR;
2760 cm_print_error("Test teardown failed");
2764 test_state->error_message = cm_error_message;
2765 cm_error_message = NULL;
2767 return rc;
2770 int _cmocka_run_group_tests(const char *group_name,
2771 const struct CMUnitTest * const tests,
2772 const size_t num_tests,
2773 CMFixtureFunction group_setup,
2774 CMFixtureFunction group_teardown)
2776 struct CMUnitTestState *cm_tests;
2777 const ListNode *group_check_point = check_point_allocated_blocks();
2778 void *group_state = NULL;
2779 size_t total_tests = 0;
2780 size_t total_failed = 0;
2781 size_t total_passed = 0;
2782 size_t total_executed = 0;
2783 size_t total_errors = 0;
2784 size_t total_skipped = 0;
2785 double total_runtime = 0;
2786 size_t i;
2787 int rc;
2789 /* Make sure LargestIntegralType is at least the size of a pointer. */
2790 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
2792 cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests);
2793 if (cm_tests == NULL) {
2794 return -1;
2797 /* Setup cmocka test array */
2798 for (i = 0; i < num_tests; i++) {
2799 if (tests[i].name != NULL &&
2800 (tests[i].test_func != NULL
2801 || tests[i].setup_func != NULL
2802 || tests[i].teardown_func != NULL)) {
2803 cm_tests[i] = (struct CMUnitTestState) {
2804 .test = &tests[i],
2805 .status = CM_TEST_NOT_STARTED,
2806 .state = NULL,
2808 total_tests++;
2812 cmprintf_group_start(total_tests);
2814 rc = 0;
2816 /* Run group setup */
2817 if (group_setup != NULL) {
2818 rc = cmocka_run_group_fixture("cmocka_group_setup",
2819 group_setup,
2820 NULL,
2821 &group_state,
2822 group_check_point);
2825 if (rc == 0) {
2826 /* Execute tests */
2827 for (i = 0; i < total_tests; i++) {
2828 struct CMUnitTestState *cmtest = &cm_tests[i];
2829 size_t test_number = i + 1;
2831 cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
2833 if (group_state != NULL) {
2834 cmtest->state = group_state;
2835 } else if (cmtest->test->initial_state != NULL) {
2836 cmtest->state = cmtest->test->initial_state;
2839 rc = cmocka_run_one_tests(cmtest);
2840 total_executed++;
2841 total_runtime += cmtest->runtime;
2842 if (rc == 0) {
2843 switch (cmtest->status) {
2844 case CM_TEST_PASSED:
2845 cmprintf(PRINTF_TEST_SUCCESS,
2846 test_number,
2847 cmtest->test->name,
2848 cmtest->error_message);
2849 total_passed++;
2850 break;
2851 case CM_TEST_SKIPPED:
2852 cmprintf(PRINTF_TEST_SKIPPED,
2853 test_number,
2854 cmtest->test->name,
2855 cmtest->error_message);
2856 total_skipped++;
2857 break;
2858 case CM_TEST_FAILED:
2859 cmprintf(PRINTF_TEST_FAILURE,
2860 test_number,
2861 cmtest->test->name,
2862 cmtest->error_message);
2863 total_failed++;
2864 break;
2865 default:
2866 cmprintf(PRINTF_TEST_ERROR,
2867 test_number,
2868 cmtest->test->name,
2869 "Internal cmocka error");
2870 total_errors++;
2871 break;
2873 } else {
2874 cmprintf(PRINTF_TEST_ERROR,
2875 test_number,
2876 cmtest->test->name,
2877 "Could not run the test - check test fixtures");
2878 total_errors++;
2881 } else {
2882 if (cm_error_message != NULL) {
2883 print_error("[ ERROR ] --- %s\n", cm_error_message);
2884 vcm_free_error(cm_error_message);
2885 cm_error_message = NULL;
2887 cmprintf(PRINTF_TEST_ERROR, 0,
2888 group_name, "[ FAILED ] GROUP SETUP");
2889 total_errors++;
2892 /* Run group teardown */
2893 if (group_teardown != NULL) {
2894 rc = cmocka_run_group_fixture("cmocka_group_teardown",
2895 NULL,
2896 group_teardown,
2897 &group_state,
2898 group_check_point);
2899 if (rc != 0) {
2900 if (cm_error_message != NULL) {
2901 print_error("[ ERROR ] --- %s\n", cm_error_message);
2902 vcm_free_error(cm_error_message);
2903 cm_error_message = NULL;
2905 cmprintf(PRINTF_TEST_ERROR, 0,
2906 group_name, "[ FAILED ] GROUP TEARDOWN");
2910 cmprintf_group_finish(group_name,
2911 total_executed,
2912 total_passed,
2913 total_failed,
2914 total_errors,
2915 total_skipped,
2916 total_runtime,
2917 cm_tests);
2919 for (i = 0; i < total_tests; i++) {
2920 vcm_free_error(discard_const_p(char, cm_tests[i].error_message));
2922 libc_free(cm_tests);
2923 fail_if_blocks_allocated(group_check_point, "cmocka_group_tests");
2925 return total_failed + total_errors;
2928 /****************************************************************************
2929 * DEPRECATED TEST RUNNER
2930 ****************************************************************************/
2932 int _run_test(
2933 const char * const function_name, const UnitTestFunction Function,
2934 void ** const volatile state, const UnitTestFunctionType function_type,
2935 const void* const heap_check_point) {
2936 const ListNode * const volatile check_point = (const ListNode*)
2937 (heap_check_point ?
2938 heap_check_point : check_point_allocated_blocks());
2939 void *current_state = NULL;
2940 volatile int rc = 1;
2941 int handle_exceptions = 1;
2942 #ifdef _WIN32
2943 handle_exceptions = !IsDebuggerPresent();
2944 #endif /* _WIN32 */
2945 #ifdef UNIT_TESTING_DEBUG
2946 handle_exceptions = 0;
2947 #endif /* UNIT_TESTING_DEBUG */
2949 cm_error_message_enabled = 0;
2951 if (handle_exceptions) {
2952 #ifndef _WIN32
2953 unsigned int i;
2954 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2955 default_signal_functions[i] = signal(
2956 exception_signals[i], exception_handler);
2958 #else /* _WIN32 */
2959 previous_exception_filter = SetUnhandledExceptionFilter(
2960 exception_filter);
2961 #endif /* !_WIN32 */
2964 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
2965 print_message("[ RUN ] %s\n", function_name);
2967 initialize_testing(function_name);
2968 global_running_test = 1;
2969 if (cm_setjmp(global_run_test_env) == 0) {
2970 Function(state ? state : &current_state);
2971 fail_if_leftover_values(function_name);
2973 /* If this is a setup function then ignore any allocated blocks
2974 * only ensure they're deallocated on tear down. */
2975 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
2976 fail_if_blocks_allocated(check_point, function_name);
2979 global_running_test = 0;
2981 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
2982 print_message("[ OK ] %s\n", function_name);
2984 rc = 0;
2985 } else {
2986 global_running_test = 0;
2987 print_message("[ FAILED ] %s\n", function_name);
2989 teardown_testing(function_name);
2991 if (handle_exceptions) {
2992 #ifndef _WIN32
2993 unsigned int i;
2994 for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2995 signal(exception_signals[i], default_signal_functions[i]);
2997 #else /* _WIN32 */
2998 if (previous_exception_filter) {
2999 SetUnhandledExceptionFilter(previous_exception_filter);
3000 previous_exception_filter = NULL;
3002 #endif /* !_WIN32 */
3005 return rc;
3009 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
3010 /* Whether to execute the next test. */
3011 int run_next_test = 1;
3012 /* Whether the previous test failed. */
3013 int previous_test_failed = 0;
3014 /* Whether the previous setup failed. */
3015 int previous_setup_failed = 0;
3016 /* Check point of the heap state. */
3017 const ListNode * const check_point = check_point_allocated_blocks();
3018 /* Current test being executed. */
3019 size_t current_test = 0;
3020 /* Number of tests executed. */
3021 size_t tests_executed = 0;
3022 /* Number of failed tests. */
3023 size_t total_failed = 0;
3024 /* Number of setup functions. */
3025 size_t setups = 0;
3026 /* Number of teardown functions. */
3027 size_t teardowns = 0;
3028 size_t i;
3030 * A stack of test states. A state is pushed on the stack
3031 * when a test setup occurs and popped on tear down.
3033 TestState* test_states =
3034 (TestState*)malloc(number_of_tests * sizeof(*test_states));
3035 /* The number of test states which should be 0 at the end */
3036 long number_of_test_states = 0;
3037 /* Names of the tests that failed. */
3038 const char** failed_names = (const char**)malloc(number_of_tests *
3039 sizeof(*failed_names));
3040 void **current_state = NULL;
3042 /* Count setup and teardown functions */
3043 for (i = 0; i < number_of_tests; i++) {
3044 const UnitTest * const test = &tests[i];
3046 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) {
3047 setups++;
3050 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) {
3051 teardowns++;
3055 print_message("[==========] Running %"PRIdS " test(s).\n",
3056 number_of_tests - setups - teardowns);
3058 /* Make sure LargestIntegralType is at least the size of a pointer. */
3059 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
3061 while (current_test < number_of_tests) {
3062 const ListNode *test_check_point = NULL;
3063 TestState *current_TestState;
3064 const UnitTest * const test = &tests[current_test++];
3065 if (!test->function) {
3066 continue;
3069 switch (test->function_type) {
3070 case UNIT_TEST_FUNCTION_TYPE_TEST:
3071 if (! previous_setup_failed) {
3072 run_next_test = 1;
3074 break;
3075 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
3076 /* Checkpoint the heap before the setup. */
3077 current_TestState = &test_states[number_of_test_states++];
3078 current_TestState->check_point = check_point_allocated_blocks();
3079 test_check_point = current_TestState->check_point;
3080 current_state = &current_TestState->state;
3081 *current_state = NULL;
3082 run_next_test = 1;
3083 break;
3085 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3086 /* Check the heap based on the last setup checkpoint. */
3087 assert_true(number_of_test_states);
3088 current_TestState = &test_states[--number_of_test_states];
3089 test_check_point = current_TestState->check_point;
3090 current_state = &current_TestState->state;
3091 break;
3092 default:
3093 print_error("Invalid unit test function type %d\n",
3094 test->function_type);
3095 exit_test(1);
3096 break;
3099 if (run_next_test) {
3100 int failed = _run_test(test->name, test->function, current_state,
3101 test->function_type, test_check_point);
3102 if (failed) {
3103 failed_names[total_failed] = test->name;
3106 switch (test->function_type) {
3107 case UNIT_TEST_FUNCTION_TYPE_TEST:
3108 previous_test_failed = failed;
3109 total_failed += failed;
3110 tests_executed ++;
3111 break;
3113 case UNIT_TEST_FUNCTION_TYPE_SETUP:
3114 if (failed) {
3115 total_failed ++;
3116 tests_executed ++;
3117 /* Skip forward until the next test or setup function. */
3118 run_next_test = 0;
3119 previous_setup_failed = 1;
3121 previous_test_failed = 0;
3122 break;
3124 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3125 /* If this test failed. */
3126 if (failed && !previous_test_failed) {
3127 total_failed ++;
3129 break;
3130 default:
3131 #ifndef _HPUX
3132 assert_null("BUG: shouldn't be here!");
3133 #endif
3134 break;
3139 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3140 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3142 if (total_failed > 0) {
3143 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3144 for (i = 0; i < total_failed; i++) {
3145 print_error("[ FAILED ] %s\n", failed_names[i]);
3147 } else {
3148 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3151 if (number_of_test_states != 0) {
3152 print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and "
3153 "teardown %"PRIdS " functions\n", setups, teardowns);
3154 total_failed = (size_t)-1;
3157 free(test_states);
3158 free((void*)failed_names);
3160 fail_if_blocks_allocated(check_point, "run_tests");
3161 return (int)total_failed;
3164 int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
3166 UnitTestFunction setup = NULL;
3167 const char *setup_name;
3168 size_t num_setups = 0;
3169 UnitTestFunction teardown = NULL;
3170 const char *teardown_name;
3171 size_t num_teardowns = 0;
3172 size_t current_test = 0;
3173 size_t i;
3175 /* Number of tests executed. */
3176 size_t tests_executed = 0;
3177 /* Number of failed tests. */
3178 size_t total_failed = 0;
3179 /* Check point of the heap state. */
3180 const ListNode * const check_point = check_point_allocated_blocks();
3181 const char** failed_names = (const char**)malloc(number_of_tests *
3182 sizeof(*failed_names));
3183 void **current_state = NULL;
3184 TestState group_state;
3186 /* Find setup and teardown function */
3187 for (i = 0; i < number_of_tests; i++) {
3188 const UnitTest * const test = &tests[i];
3190 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
3191 if (setup == NULL) {
3192 setup = test->function;
3193 setup_name = test->name;
3194 num_setups = 1;
3195 } else {
3196 print_error("[ ERROR ] More than one group setup function detected\n");
3197 exit_test(1);
3201 if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
3202 if (teardown == NULL) {
3203 teardown = test->function;
3204 teardown_name = test->name;
3205 num_teardowns = 1;
3206 } else {
3207 print_error("[ ERROR ] More than one group teardown function detected\n");
3208 exit_test(1);
3213 print_message("[==========] Running %"PRIdS " test(s).\n",
3214 number_of_tests - num_setups - num_teardowns);
3216 if (setup != NULL) {
3217 int failed;
3219 group_state.check_point = check_point_allocated_blocks();
3220 current_state = &group_state.state;
3221 *current_state = NULL;
3222 failed = _run_test(setup_name,
3223 setup,
3224 current_state,
3225 UNIT_TEST_FUNCTION_TYPE_SETUP,
3226 group_state.check_point);
3227 if (failed) {
3228 failed_names[total_failed] = setup_name;
3231 total_failed += failed;
3232 tests_executed++;
3235 while (current_test < number_of_tests) {
3236 int run_test = 0;
3237 const UnitTest * const test = &tests[current_test++];
3238 if (test->function == NULL) {
3239 continue;
3242 switch (test->function_type) {
3243 case UNIT_TEST_FUNCTION_TYPE_TEST:
3244 run_test = 1;
3245 break;
3246 case UNIT_TEST_FUNCTION_TYPE_SETUP:
3247 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3248 case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
3249 case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
3250 break;
3251 default:
3252 print_error("Invalid unit test function type %d\n",
3253 test->function_type);
3254 break;
3257 if (run_test) {
3258 int failed;
3260 failed = _run_test(test->name,
3261 test->function,
3262 current_state,
3263 test->function_type,
3264 NULL);
3265 if (failed) {
3266 failed_names[total_failed] = test->name;
3269 total_failed += failed;
3270 tests_executed++;
3274 if (teardown != NULL) {
3275 int failed;
3277 failed = _run_test(teardown_name,
3278 teardown,
3279 current_state,
3280 UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
3281 group_state.check_point);
3282 if (failed) {
3283 failed_names[total_failed] = teardown_name;
3286 total_failed += failed;
3287 tests_executed++;
3290 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3291 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3293 if (total_failed) {
3294 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3295 for (i = 0; i < total_failed; i++) {
3296 print_error("[ FAILED ] %s\n", failed_names[i]);
3298 } else {
3299 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3302 free((void*)failed_names);
3303 fail_if_blocks_allocated(check_point, "run_group_tests");
3305 return (int)total_failed;