#define CMOCKA_H_
#ifdef _WIN32
-#if _MSC_VER < 1500
-#ifdef __cplusplus
+# ifdef _MSC_VER
+
+# ifndef inline
+#define inline __inline
+# endif /* inline */
+
+# if _MSC_VER < 1500
+# ifdef __cplusplus
extern "C" {
-#endif /* __cplusplus */
+# endif /* __cplusplus */
int __stdcall IsDebuggerPresent();
-#ifdef __cplusplus
+# ifdef __cplusplus
} /* extern "C" */
-#endif /* __cplusplus */
-#endif /* _MSC_VER < 1500 */
+# endif /* __cplusplus */
+# endif /* _MSC_VER < 1500 */
+# endif /* _MSC_VER */
#endif /* _WIN32 */
/*
/* GCC have printf type attribute check. */
#ifdef __GNUC__
-#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
+#define CMOCKA_PRINTF_ATTRIBUTE(a,b) \
+ __attribute__ ((__format__ (__printf__, a, b)))
#else
-#define PRINTF_ATTRIBUTE(a,b)
+#define CMOCKA_PRINTF_ATTRIBUTE(a,b)
#endif /* __GNUC__ */
/**
/* Printf format used to display LargestIntegralType. */
#ifndef LargestIntegralTypePrintfFormat
#ifdef _WIN32
-#define LargestIntegralTypePrintfFormat "%I64x"
+#define LargestIntegralTypePrintfFormat "0x%I64x"
#else
-#define LargestIntegralTypePrintfFormat "%llx"
+#define LargestIntegralTypePrintfFormat "%#llx"
#endif /* _WIN32 */
#endif /* LargestIntegralTypePrintfFormat */
((LargestIntegralType)((size_t)(value)))
/* Smallest integral type capable of holding a pointer. */
-#ifndef _UINTPTR_T
-#define _UINTPTR_T
-#ifdef _WIN32
-
-/* WIN32 is an ILP32 platform */
-typedef unsigned long uintptr_t;
-
-/* what about 64-bit windows?
- * what's the right preprocessor symbol?
-typedef unsigned long long uintptr_t */
-
-#else /* _WIN32 */
+#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED)
+# if defined(_WIN32)
+ /* WIN32 is an ILP32 platform */
+ typedef unsigned int uintptr_t;
+# elif defined(_WIN64)
+ typedef unsigned long int uintptr_t
+# else /* _WIN32 */
/* ILP32 and LP64 platforms */
-#ifdef __WORDSIZE /* glibc */
-# if __WORDSIZE == 64
-typedef unsigned long int uintptr_t;
-# else
-typedef unsigned int uintptr_t;
-# endif /* __WORDSIZE == 64 */
-#else /* __WORDSIZE */
-
-# if defined(_LP64) || defined(_I32LPx)
-typedef unsigned long int uintptr_t;
-# else
-typedef unsigned int uintptr_t;
-# endif
-
-#endif /* __WORDSIZE */
-
-#endif /* _WIN32 */
-#endif /* _UINTPTR_T */
+# ifdef __WORDSIZE /* glibc */
+# if __WORDSIZE == 64
+ typedef unsigned long int uintptr_t;
+# else
+ typedef unsigned int uintptr_t;
+# endif /* __WORDSIZE == 64 */
+# else /* __WORDSIZE */
+# if defined(_LP64) || defined(_I32LPx)
+ typedef unsigned long int uintptr_t;
+# else
+ typedef unsigned int uintptr_t;
+# endif
+# endif /* __WORDSIZE */
+# endif /* _WIN32 */
+
+# define _UINTPTR_T
+# define _UINTPTR_T_DEFINED
+#endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */
/* Perform an unsigned cast to uintptr_t. */
#define cast_to_pointer_integral_type(value) \
* real objects. Instead of calling the real objects, the tested object calls a
* mock object that merely asserts that the correct methods were called, with
* the expected parameters, in the correct order.
+ *
+ * <ul>
+ * <li><strong>will_return(function, value)</strong> - The will_return() macro
+ * pushes a value onto a stack of mock values. This macro is intended to be
+ * used by the unit test itself, while programming the behaviour of the mocked
+ * object.</li>
+ *
+ * <li><strong>mock()</strong> - the mock macro pops a value from a stack of
+ * test values. The user of the mock() macro is the mocked object that uses it
+ * to learn how it should behave.</li>
+ * </ul>
+ *
+ * Because the will_return() and mock() are intended to be used in pairs, the
+ * cmocka library would fail the test if there are more values pushed onto the
+ * stack using will_return() than consumed with mock() and vice-versa.
+ *
+ * The following unit test stub illustrates how would a unit test instruct the
+ * mock object to return a particular value:
+ *
+ * @code
+ * will_return(chef_cook, "hotdog");
+ * will_return(chef_cook, 0);
+ * @endcode
+ *
+ * Now the mock object can check if the parameter it received is the parameter
+ * which is expected by the test driver. This can be done the following way:
+ *
+ * @code
+ * int chef_cook(const char *order, char **dish_out)
+ * {
+ * check_expected(order);
+ * }
+ * @endcode
+ *
+ * For a complete example please at a look
+ * <a href="http://git.cryptomilk.org/projects/cmocka.git/tree/example/chef_wrap/waiter_test_wrap.c">here</a>.
*
* @{
*/
#define mock() _mock(__func__, __FILE__, __LINE__)
#endif
+#ifdef DOXYGEN
+/**
+ * @brief Retrieve a typed return value of the current function.
+ *
+ * The value would be casted to type internally to avoid having the
+ * caller to do the cast manually.
+ *
+ * @param[in] #type The expected type of the return value
+ *
+ * @return The value which was stored to return by this function.
+ *
+ * @code
+ * int param;
+ *
+ * param = mock_type(int);
+ * @endcode
+ *
+ * @see will_return()
+ * @see mock()
+ * @see mock_ptr_type()
+ */
+void *mock_type(#type);
+#else
+#define mock_type(type) ((type) mock())
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Retrieve a typed return value of the current function.
+ *
+ * The value would be casted to type internally to avoid having the
+ * caller to do the cast manually but also casted to uintptr_t to make
+ * sure the result has a valid size to be used as a pointer.
+ *
+ * @param[in] #type The expected type of the return value
+ *
+ * @return The value which was stored to return by this function.
+ *
+ * @code
+ * char *param;
+ *
+ * param = mock_ptr_type(char *);
+ * @endcode
+ *
+ * @see will_return()
+ * @see mock()
+ * @see mock_type()
+ */
+void *mock_ptr_type(#type);
+#else
+#define mock_ptr_type(type) ((type) (uintptr_t) mock())
+#endif
+
+
#ifdef DOXYGEN
/**
* @brief Store a value to be returned by mock() later.
cast_to_largest_integral_type(value), count)
#endif
+#ifdef DOXYGEN
+/**
+ * @brief Store a value that will be always returned by mock().
+ *
+ * @param[in] #function The function which should return the given value.
+ *
+ * @param[in] value The value to be returned by mock().
+ *
+ * This is equivalent to:
+ * @code
+ * will_return_count(function, value, -1);
+ * @endcode
+ *
+ * @see will_return_count()
+ * @see mock()
+ */
+void will_return_always(#function, void *value);
+#else
+#define will_return_always(function, value) \
+ will_return_count(function, (value), -1)
+#endif
+
/** @} */
+/**
+ * @defgroup cmocka_param Checking Parameters
+ * @ingroup cmocka
+ *
+ * Functionality to store expected values for mock function parameters.
+ *
+ * In addition to storing the return values of mock functions, cmocka provides
+ * functionality to store expected values for mock function parameters using
+ * the expect_*() functions provided. A mock function parameter can then be
+ * validated using the check_expected() macro.
+ *
+ * Successive calls to expect_*() macros for a parameter queues values to check
+ * the specified parameter. check_expected() checks a function parameter
+ * against the next value queued using expect_*(), if the parameter check fails
+ * a test failure is signalled. In addition if check_expected() is called and
+ * no more parameter values are queued a test failure occurs.
+ *
+ * The following test stub illustrates how to do this. First is the the function
+ * we call in the test driver:
+ *
+ * @code
+ * static void test_driver(void **state)
+ * {
+ * expect_string(chef_cook, order, "hotdog");
+ * }
+ * @endcode
+ *
+ * Now the chef_cook function can check if the parameter we got passed is the
+ * parameter which is expected by the test driver. This can be done the
+ * following way:
+ *
+ * @code
+ * int chef_cook(const char *order, char **dish_out)
+ * {
+ * check_expected(order);
+ * }
+ * @endcode
+ *
+ * For a complete example please at a look at
+ * <a href="http://git.cryptomilk.org/projects/cmocka.git/tree/example/chef_wrap/waiter_test_wrap.c">here</a>
+ *
+ * @{
+ */
+
/*
* Add a custom parameter checking function. If the event parameter is NULL
* the event structure is allocated internally by this function. If event
* parameter is provided it must be allocated on the heap and doesn't need to
* be deallocated by the caller.
*/
+#ifdef DOXYGEN
+/**
+ * @brief Add a custom parameter checking function.
+ *
+ * If the event parameter is NULL the event structure is allocated internally
+ * by this function. If the parameter is provided it must be allocated on the
+ * heap and doesn't need to be deallocated by the caller.
+ *
+ * @param[in] #function The function to add a custom parameter checking
+ * function for.
+ *
+ * @param[in] #parameter The parameters passed to the function.
+ *
+ * @param[in] #check_function The check function to call.
+ *
+ * @param[in] check_data The data to pass to the check function.
+ */
+void expect_check(#function, #parameter, #check_function, const void *check_data);
+#else
#define expect_check(function, parameter, check_function, check_data) \
_expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \
- cast_to_largest_integral_type(check_data), NULL, 0)
+ cast_to_largest_integral_type(check_data), NULL, 1)
+#endif
-/*
- * Add an event to check a parameter, using check_expected(), against a set of
- * values. See will_return() for a description of the count parameter.
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is part of the provided
+ * array.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value_array[] The array to check for the value.
+ *
+ * @see check_expected().
*/
+void expect_in_set(#function, #parameter, uintmax_t value_array[]);
+#else
#define expect_in_set(function, parameter, value_array) \
expect_in_set_count(function, parameter, value_array, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is part of the provided
+ * array.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value_array[] The array to check for the value.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_in_set_count(#function, #parameter, uintmax_t value_array[], size_t count);
+#else
#define expect_in_set_count(function, parameter, value_array, count) \
_expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \
sizeof(value_array) / sizeof((value_array)[0]), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is not part of the
+ * provided array.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value_array[] The array to check for the value.
+ *
+ * @see check_expected().
+ */
+void expect_not_in_set(#function, #parameter, uintmax_t value_array[]);
+#else
#define expect_not_in_set(function, parameter, value_array) \
expect_not_in_set_count(function, parameter, value_array, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is not part of the
+ * provided array.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value_array[] The array to check for the value.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_in_set_count(#function, #parameter, uintmax_t value_array[], size_t count);
+#else
#define expect_not_in_set_count(function, parameter, value_array, count) \
_expect_not_in_set( \
#function, #parameter, __FILE__, __LINE__, value_array, \
sizeof(value_array) / sizeof((value_array)[0]), count)
+#endif
-/*
- * Add an event to check a parameter, using check_expected(), against a
- * signed range. Where range is minimum <= value <= maximum.
- * See will_return() for a description of the count parameter.
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check a parameter is inside a numerical range.
+ * The check would succeed if minimum <= value <= maximum.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] minimum The lower boundary of the interval to check against.
+ *
+ * @param[in] maximum The upper boundary of the interval to check against.
+ *
+ * @see check_expected().
*/
+void expect_in_range(#function, #parameter, uintmax_t minimum, uintmax_t maximum);
+#else
#define expect_in_range(function, parameter, minimum, maximum) \
expect_in_range_count(function, parameter, minimum, maximum, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check a parameter is inside a
+ * numerical range. The check would succeed if minimum <= value <= maximum.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] minimum The lower boundary of the interval to check against.
+ *
+ * @param[in] maximum The upper boundary of the interval to check against.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_in_range_count(#function, #parameter, uintmax_t minimum, uintmax_t maximum, size_t count);
+#else
#define expect_in_range_count(function, parameter, minimum, maximum, count) \
_expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \
maximum, count)
+#endif
-/*
- * Add an event to check a parameter, using check_expected(), against a
- * signed range. Where range is value < minimum or value > maximum.
- * See will_return() for a description of the count parameter.
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check a parameter is outside a numerical range.
+ * The check would succeed if minimum > value > maximum.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] minimum The lower boundary of the interval to check against.
+ *
+ * @param[in] maximum The upper boundary of the interval to check against.
+ *
+ * @see check_expected().
*/
+void expect_not_in_range(#function, #parameter, uintmax_t minimum, uintmax_t maximum);
+#else
#define expect_not_in_range(function, parameter, minimum, maximum) \
expect_not_in_range_count(function, parameter, minimum, maximum, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check a parameter is outside a
+ * numerical range. The check would succeed if minimum > value > maximum.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] minimum The lower boundary of the interval to check against.
+ *
+ * @param[in] maximum The upper boundary of the interval to check against.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_in_range_count(#function, #parameter, uintmax_t minimum, uintmax_t maximum, size_t count);
+#else
#define expect_not_in_range_count(function, parameter, minimum, maximum, \
count) \
_expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \
minimum, maximum, count)
+#endif
-/*
- * Add an event to check whether a parameter, using check_expected(), is or
- * isn't a value. See will_return() for a description of the count parameter.
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if a parameter is the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value The value to check.
+ *
+ * @see check_expected().
*/
+void expect_value(#function, #parameter, uintmax_t value);
+#else
#define expect_value(function, parameter, value) \
expect_value_count(function, parameter, value, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter is the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value The value to check.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_value_count(#function, #parameter, uintmax_t value, size_t count);
+#else
#define expect_value_count(function, parameter, value, count) \
_expect_value(#function, #parameter, __FILE__, __LINE__, \
cast_to_largest_integral_type(value), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if a parameter isn't the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value The value to check.
+ *
+ * @see check_expected().
+ */
+void expect_not_value(#function, #parameter, uintmax_t value);
+#else
#define expect_not_value(function, parameter, value) \
expect_not_value_count(function, parameter, value, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter isn't the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value The value to check.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_value_count(#function, #parameter, uintmax_t value, size_t count);
+#else
#define expect_not_value_count(function, parameter, value, count) \
_expect_not_value(#function, #parameter, __FILE__, __LINE__, \
cast_to_largest_integral_type(value), count)
+#endif
-/*
- * Add an event to check whether a parameter, using check_expected(),
- * is or isn't a string. See will_return() for a description of the count
- * parameter.
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is equal to the
+ * provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] string The string value to compare.
+ *
+ * @see check_expected().
+ */
+void expect_string(#function, #parameter, const char *string);
+#else
+#define expect_string(function, parameter, string) \
+ expect_string_count(function, parameter, string, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is equal to the
+ * provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] string The string value to compare.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
*/
-#define expect_string(function, parameter, string) \
- expect_string_count(function, parameter, string, 1)
+void expect_string_count(#function, #parameter, const char *string, size_t count);
+#else
#define expect_string_count(function, parameter, string, count) \
_expect_string(#function, #parameter, __FILE__, __LINE__, \
(const char*)(string), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value isn't equal to the
+ * provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] string The string value to compare.
+ *
+ * @see check_expected().
+ */
+void expect_not_string(#function, #parameter, const char *string);
+#else
#define expect_not_string(function, parameter, string) \
expect_not_string_count(function, parameter, string, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value isn't equal to the
+ * provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] string The string value to compare.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_string_count(#function, #parameter, const char *string, size_t count);
+#else
#define expect_not_string_count(function, parameter, string, count) \
_expect_not_string(#function, #parameter, __FILE__, __LINE__, \
(const char*)(string), count)
+#endif
-/*
- * Add an event to check whether a parameter, using check_expected() does or
- * doesn't match an area of memory. See will_return() for a description of
- * the count parameter.
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter does match an area of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] memory The memory to compare.
+ *
+ * @param[in] size The size of the memory to compare.
+ *
+ * @see check_expected().
*/
+void expect_memory(#function, #parameter, void *memory, size_t size);
+#else
#define expect_memory(function, parameter, memory, size) \
expect_memory_count(function, parameter, memory, size, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if the parameter does match an area
+ * of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] memory The memory to compare.
+ *
+ * @param[in] size The size of the memory to compare.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_memory_count(#function, #parameter, void *memory, size_t size, size_t count);
+#else
#define expect_memory_count(function, parameter, memory, size, count) \
_expect_memory(#function, #parameter, __FILE__, __LINE__, \
(const void*)(memory), size, count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter doesn't match an area of
+ * memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] memory The memory to compare.
+ *
+ * @param[in] size The size of the memory to compare.
+ *
+ * @see check_expected().
+ */
+void expect_not_memory(#function, #parameter, void *memory, size_t size);
+#else
#define expect_not_memory(function, parameter, memory, size) \
expect_not_memory_count(function, parameter, memory, size, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if the parameter doesn't match an
+ * area of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] memory The memory to compare.
+ *
+ * @param[in] size The size of the memory to compare.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_memory_count(#function, #parameter, void *memory, size_t size, size_t count);
+#else
#define expect_not_memory_count(function, parameter, memory, size, count) \
_expect_not_memory(#function, #parameter, __FILE__, __LINE__, \
(const void*)(memory), size, count)
+#endif
-/*
- * Add an event to allow any value for a parameter checked using
- * check_expected(). See will_return() for a description of the count
- * parameter.
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if a parameter (of any value) has been passed.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @see check_expected().
*/
+void expect_any(#function, #parameter);
+#else
#define expect_any(function, parameter) \
expect_any_count(function, parameter, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter (of any value) has
+ * been passed.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_any_count(#function, #parameter, size_t count);
+#else
#define expect_any_count(function, parameter, count) \
_expect_any(#function, #parameter, __FILE__, __LINE__, count)
+#endif
-/*
- * Determine whether a function parameter is correct. This ensures the next
- * value queued by one of the expect_*() macros matches the specified variable.
+#ifdef DOXYGEN
+/**
+ * @brief Determine whether a function parameter is correct.
+ *
+ * This ensures the next value queued by one of the expect_*() macros matches
+ * the specified variable.
+ *
+ * This function needs to be called in the mock object.
+ *
+ * @param[in] #parameter The parameter to check.
*/
+void check_expected(#parameter);
+#else
#define check_expected(parameter) \
_check_expected(__func__, #parameter, __FILE__, __LINE__, \
cast_to_largest_integral_type(parameter))
+#endif
+
+/** @} */
/**
* @defgroup cmocka_asserts Assert Macros
__FILE__, __LINE__)
#endif
+#ifdef DOXYGEN
+/**
+ * @brief Assert if the return_code is smaller than 0.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the return code is smaller than 0. If the function
+ * you check sets an errno if it fails you can pass it to the function and
+ * it will be printed as part of the error message.
+ *
+ * @param[in] rc The return code to evaluate.
+ *
+ * @param[in] error Pass errno here or 0.
+ */
+void assert_return_code(int rc, int error);
+#else
+#define assert_return_code(rc, error) \
+ _assert_return_code(cast_to_largest_integral_type(rc), \
+ sizeof(rc), \
+ cast_to_largest_integral_type(error), \
+ #rc, __FILE__, __LINE__)
+#endif
+
#ifdef DOXYGEN
/**
* @brief Assert that the given pointer is non-NULL.
*/
void assert_in_range(uintmax_t value, uintmax_t minimum, uintmax_t maximum);
#else
-/* Assert that the specified value is >= minimum and <= maximum. */
#define assert_in_range(value, minimum, maximum) \
_assert_in_range( \
cast_to_largest_integral_type(value), \
cast_to_largest_integral_type(maximum), __FILE__, __LINE__)
#endif
-/* Assert that the specified value is < minumum or > maximum */
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is smaller than the minimum and
+ * bigger than the maximum.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is in range.
+ *
+ * @param[in] value The value to check.
+ *
+ * @param[in] minimum The minimum value to compare.
+ *
+ * @param[in] maximum The maximum value to compare.
+ */
+void assert_not_in_range(uintmax_t value, uintmax_t minimum, uintmax_t maximum);
+#else
#define assert_not_in_range(value, minimum, maximum) \
_assert_not_in_range( \
cast_to_largest_integral_type(value), \
cast_to_largest_integral_type(minimum), \
cast_to_largest_integral_type(maximum), __FILE__, __LINE__)
+#endif
-/* Assert that the specified value is within a set. */
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is within a set.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is not within a set.
+ *
+ * @param[in] value The value to look up
+ *
+ * @param[in] values[] The array to check for the value.
+ *
+ * @param[in] count The size of the values array.
+ */
+void assert_in_set(uintmax_t value, uintmax_t values[], size_t count);
+#else
#define assert_in_set(value, values, number_of_values) \
_assert_in_set(value, values, number_of_values, __FILE__, __LINE__)
-/* Assert that the specified value is not within a set. */
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is not within a set.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is within a set.
+ *
+ * @param[in] value The value to look up
+ *
+ * @param[in] values[] The array to check for the value.
+ *
+ * @param[in] count The size of the values array.
+ */
+void assert_not_in_set(uintmax_t value, uintmax_t values[], size_t count);
+#else
#define assert_not_in_set(value, values, number_of_values) \
_assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__)
+#endif
/** @} */
#define fail() _fail(__FILE__, __LINE__)
#endif
+#ifdef DOXYGEN
+/**
+ * @brief Forces the test to fail immediately and quit, printing the reason.
+ */
+void fail_msg(const char *msg, ...);
+#else
+#define fail_msg(msg, ...) do { \
+ print_error("ERROR: " msg "\n", ##__VA_ARGS__); \
+ fail(); \
+} while (0)
+#endif
+
#ifdef DOXYGEN
/**
* @brief Generic method to run a single test.
#define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL)
#endif
+static inline void _unit_test_dummy(void **state) {
+ (void)state;
+}
+
/** Initializes a UnitTest structure. */
#define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST }
+#define _unit_test_setup(test, setup) \
+ { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP }
+
/** Initializes a UnitTest structure with a setup function. */
#define unit_test_setup(test, setup) \
- { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP }
+ _unit_test_setup(test, setup), \
+ unit_test(test), \
+ _unit_test_teardown(test, _unit_test_dummy)
+
+#define _unit_test_teardown(test, teardown) \
+ { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN }
/** Initializes a UnitTest structure with a teardown function. */
#define unit_test_teardown(test, teardown) \
- { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN }
+ _unit_test_setup(test, _unit_test_dummy), \
+ unit_test(test), \
+ _unit_test_teardown(test, teardown)
+
+#define group_test_setup(setup) \
+ { "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP }
+
+#define group_test_teardown(teardown) \
+ { "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN }
/**
* Initialize an array of UnitTest structures with a setup function for a test
* and a teardown function. Either setup or teardown can be NULL.
*/
#define unit_test_setup_teardown(test, setup, teardown) \
- unit_test_setup(test, setup), \
+ _unit_test_setup(test, setup), \
unit_test(test), \
- unit_test_teardown(test, teardown)
+ _unit_test_teardown(test, teardown)
#ifdef DOXYGEN
/**
#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof(tests)[0])
#endif
+#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof(tests)[0])
+
/** @} */
-/* Dynamic allocators */
+/**
+ * @defgroup cmocka_alloc Dynamic Memory Allocation
+ * @ingroup cmocka
+ *
+ * Memory leaks, buffer overflows and underflows can be checked using cmocka.
+ *
+ * To test for memory leaks, buffer overflows and underflows a module being
+ * tested by cmocka should replace calls to malloc(), calloc() and free() to
+ * test_malloc(), test_calloc() and test_free() respectively. Each time a block
+ * is deallocated using test_free() it is checked for corruption, if a corrupt
+ * block is found a test failure is signalled. All blocks allocated using the
+ * test_*() allocation functions are tracked by the cmocka library. When a test
+ * completes if any allocated blocks (memory leaks) remain they are reported
+ * and a test failure is signalled.
+ *
+ * For simplicity cmocka currently executes all tests in one process. Therefore
+ * all test cases in a test application share a single address space which
+ * means memory corruption from a single test case could potentially cause the
+ * test application to exit prematurely.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding malloc.
+ *
+ * @param[in] size The bytes which should be allocated.
+ *
+ * @return A pointer to the allocated memory or NULL on error.
+ *
+ * @code
+ * #ifdef UNIT_TESTING
+ * extern void* _test_malloc(const size_t size, const char* file, const int line);
+ *
+ * #define malloc(size) _test_malloc(size, __FILE__, __LINE__)
+ * #endif
+ *
+ * void leak_memory() {
+ * int * const temporary = (int*)malloc(sizeof(int));
+ * *temporary = 0;
+ * }
+ * @endcode
+ *
+ * @see malloc(3)
+ */
+void *test_malloc(size_t size);
+#else
#define test_malloc(size) _test_malloc(size, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding calloc.
+ *
+ * The memory is set to zero.
+ *
+ * @param[in] nmemb The number of elements for an array to be allocated.
+ *
+ * @param[in] size The size in bytes of each array element to allocate.
+ *
+ * @return A pointer to the allocated memory, NULL on error.
+ *
+ * @see calloc(3)
+ */
+void *test_calloc(size_t nmemb, size_t size);
+#else
#define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding free(3).
+ *
+ * @param[in] ptr The pointer to the memory space to free.
+ *
+ * @see free(3).
+ */
+void test_free(void *ptr);
+#else
#define test_free(ptr) _test_free(ptr, __FILE__, __LINE__)
+#endif
/* Redirect malloc, calloc and free to the unit test allocators. */
-#if UNIT_TESTING
+#ifdef UNIT_TESTING
#define malloc test_malloc
#define calloc test_calloc
#define free test_free
#endif /* UNIT_TESTING */
-/*
- * Ensure mock_assert() is called. If mock_assert() is called the assert
- * expression string is returned.
- * For example:
+/** @} */
+
+
+/**
+ * @defgroup cmocka_mock_assert Standard Assertions
+ * @ingroup cmocka
+ *
+ * How to handle assert(3) of the standard C library.
+ *
+ * Runtime assert macros like the standard C library's assert() should be
+ * redefined in modules being tested to use cmocka's mock_assert() function.
+ * Normally mock_assert() signals a test failure. If a function is called using
+ * the expect_assert_failure() macro, any calls to mock_assert() within the
+ * function will result in the execution of the test. If no calls to
+ * mock_assert() occur during the function called via expect_assert_failure() a
+ * test failure is signalled.
+ *
+ * @{
+ */
+
+/**
+ * @brief Function to replace assert(3) in tested code.
+ *
+ * In conjuction with check_assert() it's possible to determine whether an
+ * assert condition has failed without stopping a test.
+ *
+ * @param[in] result The expression to assert.
+ *
+ * @param[in] expression The expression as string.
+ *
+ * @param[in] file The file mock_assert() is called.
+ *
+ * @param[in] line The line mock_assert() is called.
+ *
+ * @code
+ * #ifdef UNIT_TESTING
+ * extern void mock_assert(const int result, const char* const expression,
+ * const char * const file, const int line);
+ *
+ * #undef assert
+ * #define assert(expression) \
+ * mock_assert((int)(expression), #expression, __FILE__, __LINE__);
+ * #endif
+ *
+ * void increment_value(int * const value) {
+ * assert(value);
+ * (*value) ++;
+ * }
+ * @endcode
+ *
+ * @see assert(3)
+ * @see expect_assert_failure
+ */
+void mock_assert(const int result, const char* const expression,
+ const char * const file, const int line);
+
+#ifdef DOXYGEN
+/**
+ * @brief Ensure that mock_assert() is called.
+ *
+ * If mock_assert() is called the assert expression string is returned.
+ *
+ * @param[in] fn_call The function will will call mock_assert().
*
+ * @code
* #define assert mock_assert
*
* void showmessage(const char *message) {
* printf("succeeded\n");
* return 0;
* }
+ * @endcode
+ *
*/
+void expect_assert_failure(function fn_call);
+#else
#define expect_assert_failure(function_call) \
{ \
const int result = setjmp(global_expect_assert_env); \
_fail(__FILE__, __LINE__); \
} \
}
+#endif
+
+/** @} */
/* Function prototype for setup, test and teardown functions. */
typedef void (*UnitTestFunction)(void **state);
UNIT_TEST_FUNCTION_TYPE_TEST = 0,
UNIT_TEST_FUNCTION_TYPE_SETUP,
UNIT_TEST_FUNCTION_TYPE_TEARDOWN,
+ UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP,
+ UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
} UnitTestFunctionType;
/*
UnitTestFunctionType function_type;
} UnitTest;
+typedef struct GroupTest {
+ UnitTestFunction setup;
+ UnitTestFunction teardown;
+ const UnitTest *tests;
+ const size_t number_of_tests;
+} GroupTest;
/* Location within some source code. */
typedef struct SourceLocation {
const char * const function_name, const char * const parameter_name,
const char* file, const int line, const LargestIntegralType value);
-/*
- * Can be used to replace assert in tested code so that in conjuction with
- * check_assert() it's possible to determine whether an assert condition has
- * failed without stopping a test.
- */
-void mock_assert(const int result, const char* const expression,
- const char * const file, const int line);
-
void _will_return(const char * const function_name, const char * const file,
const int line, const LargestIntegralType value,
const int count);
void _assert_true(const LargestIntegralType result,
const char* const expression,
const char * const file, const int line);
+void _assert_return_code(const LargestIntegralType result,
+ size_t rlen,
+ const LargestIntegralType error,
+ const char * const expression,
+ const char * const file,
+ const int line);
void _assert_int_equal(
const LargestIntegralType a, const LargestIntegralType b,
const char * const file, const int line);
void ** const volatile state, const UnitTestFunctionType function_type,
const void* const heap_check_point);
int _run_tests(const UnitTest * const tests, const size_t number_of_tests);
+int _run_group_tests(const UnitTest * const tests,
+ const size_t number_of_tests);
/* Standard output and error print methods. */
-void print_message(const char* const format, ...) PRINTF_ATTRIBUTE(1, 2);
-void print_error(const char* const format, ...) PRINTF_ATTRIBUTE(1, 2);
-void vprint_message(const char* const format, va_list args) PRINTF_ATTRIBUTE(1, 0);
-void vprint_error(const char* const format, va_list args) PRINTF_ATTRIBUTE(1, 0);
+void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
+void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
+void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
+void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
/** @} */