@@ -0,0 +1,2 @@ | |||||
-Iinclude | |||||
-Iobj |
@@ -0,0 +1,7 @@ | |||||
*.swp | |||||
*~$ | |||||
tags | |||||
cscope.* | |||||
.ycm_extra_conf.pyc | |||||
/build | |||||
/obj* |
@@ -0,0 +1,109 @@ | |||||
import os | |||||
import ycm_core | |||||
flags = [ | |||||
'-Wall', | |||||
'-Wextra', | |||||
'-Werror', | |||||
'-x', 'c', | |||||
'-Iinclude', | |||||
] | |||||
# Set this to the absolute path to the folder (NOT the file!) containing the | |||||
# compile_commands.json file to use that instead of 'flags'. See here for | |||||
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html | |||||
# | |||||
# Most projects will NOT need to set this to anything; you can just change the | |||||
# 'flags' list of compilation flags. Notice that YCM itself uses that approach. | |||||
compilation_database_folder = 'obj' | |||||
if os.path.exists( compilation_database_folder ): | |||||
database = ycm_core.CompilationDatabase( compilation_database_folder ) | |||||
else: | |||||
database = None | |||||
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] | |||||
def DirectoryOfThisScript(): | |||||
return os.path.dirname( os.path.abspath( __file__ ) ) | |||||
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): | |||||
if not working_directory: | |||||
return list( flags ) | |||||
new_flags = [] | |||||
make_next_absolute = False | |||||
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] | |||||
for flag in flags: | |||||
new_flag = flag | |||||
if make_next_absolute: | |||||
make_next_absolute = False | |||||
if not flag.startswith( '/' ): | |||||
new_flag = os.path.join( working_directory, flag ) | |||||
for path_flag in path_flags: | |||||
if flag == path_flag: | |||||
make_next_absolute = True | |||||
break | |||||
if flag.startswith( path_flag ): | |||||
path = flag[ len( path_flag ): ] | |||||
new_flag = path_flag + os.path.join( working_directory, path ) | |||||
break | |||||
if new_flag: | |||||
new_flags.append( new_flag ) | |||||
return new_flags | |||||
def IsHeaderFile( filename ): | |||||
extension = os.path.splitext( filename )[ 1 ] | |||||
return extension in [ '.h', '.hxx', '.hpp', '.hh' ] | |||||
def GetCompilationInfoForFile( filename ): | |||||
# The compilation_commands.json file generated by CMake does not have entries | |||||
# for header files. So we do our best by asking the db for flags for a | |||||
# corresponding source file, if any. If one exists, the flags for that file | |||||
# should be good enough. | |||||
if IsHeaderFile( filename ): | |||||
basename = os.path.splitext( filename )[ 0 ] | |||||
for extension in SOURCE_EXTENSIONS: | |||||
replacement_file = basename + extension | |||||
if os.path.exists( replacement_file ): | |||||
compilation_info = database.GetCompilationInfoForFile( | |||||
replacement_file ) | |||||
if compilation_info.compiler_flags_: | |||||
return compilation_info | |||||
return None | |||||
return database.GetCompilationInfoForFile( filename ) | |||||
def FlagsForFile( filename, **kwargs ): | |||||
if database: | |||||
# Bear in mind that compilation_info.compiler_flags_ does NOT return a | |||||
# python list, but a "list-like" StringVec object | |||||
compilation_info = GetCompilationInfoForFile( filename ) | |||||
if not compilation_info: | |||||
return None | |||||
final_flags = MakeRelativePathsInFlagsAbsolute( | |||||
compilation_info.compiler_flags_, | |||||
compilation_info.compiler_working_dir_ ) | |||||
# NOTE: This is just for YouCompleteMe; it's highly likely that your project | |||||
# does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR | |||||
# ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. | |||||
try: | |||||
final_flags.remove( '-stdlib=libc++' ) | |||||
except ValueError: | |||||
pass | |||||
else: | |||||
relative_to = DirectoryOfThisScript() | |||||
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) | |||||
return { | |||||
'flags': final_flags, | |||||
'do_cache': True | |||||
} |
@@ -0,0 +1,3 @@ | |||||
opensource@google.com | |||||
Andreas Schneider <asn@cryptomilk.org> | |||||
Jakub Hrozek <jakub.hrozek@posteo.se> |
@@ -0,0 +1,88 @@ | |||||
project(cmocka C) | |||||
# Required cmake version | |||||
cmake_minimum_required(VERSION 2.6.0) | |||||
# global needed variables | |||||
set(APPLICATION_NAME ${PROJECT_NAME}) | |||||
set(APPLICATION_VERSION_MAJOR "1") | |||||
set(APPLICATION_VERSION_MINOR "1") | |||||
set(APPLICATION_VERSION_PATCH "1") | |||||
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}") | |||||
# SOVERSION scheme: CURRENT.AGE.REVISION | |||||
# If there was an incompatible interface change: | |||||
# Increment CURRENT. Set AGE and REVISION to 0 | |||||
# If there was a compatible interface change: | |||||
# Increment AGE. Set REVISION to 0 | |||||
# If the source code was changed, but there were no interface changes: | |||||
# Increment REVISION. | |||||
set(LIBRARY_VERSION "0.4.1") | |||||
set(LIBRARY_SOVERSION "0") | |||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked | |||||
set(CMAKE_MODULE_PATH | |||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules | |||||
) | |||||
# add definitions | |||||
include(DefineCMakeDefaults) | |||||
include(DefinePlatformDefaults) | |||||
include(DefineCompilerFlags) | |||||
include(DefineInstallationPaths) | |||||
include(DefineOptions.cmake) | |||||
include(CPackConfig.cmake) | |||||
include(CheckSymbolExists) | |||||
# disallow in-source build | |||||
include(MacroEnsureOutOfSourceBuild) | |||||
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.") | |||||
# config.h checks | |||||
include(ConfigureChecks.cmake) | |||||
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) | |||||
# MinGW DLL Naming Workaround | |||||
if (MINGW) | |||||
set(CMAKE_SHARED_LIBRARY_PREFIX "") | |||||
endif (MINGW) | |||||
# check subdirectories | |||||
add_subdirectory(doc) | |||||
add_subdirectory(include) | |||||
add_subdirectory(src) | |||||
if (UNIT_TESTING) | |||||
include(AddCMockaTest) | |||||
add_subdirectory(tests) | |||||
endif (UNIT_TESTING) | |||||
add_subdirectory(example) | |||||
# pkg-config file | |||||
configure_file(cmocka.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmocka.pc) | |||||
install( | |||||
FILES | |||||
${CMAKE_CURRENT_BINARY_DIR}/cmocka.pc | |||||
DESTINATION | |||||
${LIB_INSTALL_DIR}/pkgconfig | |||||
COMPONENT | |||||
pkgconfig | |||||
) | |||||
# cmake config files | |||||
set(CMOCKA_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) | |||||
configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY) | |||||
configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY) | |||||
install( | |||||
FILES | |||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake | |||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake | |||||
DESTINATION | |||||
${CMAKE_INSTALL_DIR}/${PROJECT_NAME} | |||||
COMPONENT | |||||
devel | |||||
) |
@@ -0,0 +1,202 @@ | |||||
Apache License | |||||
Version 2.0, January 2004 | |||||
http://www.apache.org/licenses/ | |||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |||||
1. Definitions. | |||||
"License" shall mean the terms and conditions for use, reproduction, | |||||
and distribution as defined by Sections 1 through 9 of this document. | |||||
"Licensor" shall mean the copyright owner or entity authorized by | |||||
the copyright owner that is granting the License. | |||||
"Legal Entity" shall mean the union of the acting entity and all | |||||
other entities that control, are controlled by, or are under common | |||||
control with that entity. For the purposes of this definition, | |||||
"control" means (i) the power, direct or indirect, to cause the | |||||
direction or management of such entity, whether by contract or | |||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the | |||||
outstanding shares, or (iii) beneficial ownership of such entity. | |||||
"You" (or "Your") shall mean an individual or Legal Entity | |||||
exercising permissions granted by this License. | |||||
"Source" form shall mean the preferred form for making modifications, | |||||
including but not limited to software source code, documentation | |||||
source, and configuration files. | |||||
"Object" form shall mean any form resulting from mechanical | |||||
transformation or translation of a Source form, including but | |||||
not limited to compiled object code, generated documentation, | |||||
and conversions to other media types. | |||||
"Work" shall mean the work of authorship, whether in Source or | |||||
Object form, made available under the License, as indicated by a | |||||
copyright notice that is included in or attached to the work | |||||
(an example is provided in the Appendix below). | |||||
"Derivative Works" shall mean any work, whether in Source or Object | |||||
form, that is based on (or derived from) the Work and for which the | |||||
editorial revisions, annotations, elaborations, or other modifications | |||||
represent, as a whole, an original work of authorship. For the purposes | |||||
of this License, Derivative Works shall not include works that remain | |||||
separable from, or merely link (or bind by name) to the interfaces of, | |||||
the Work and Derivative Works thereof. | |||||
"Contribution" shall mean any work of authorship, including | |||||
the original version of the Work and any modifications or additions | |||||
to that Work or Derivative Works thereof, that is intentionally | |||||
submitted to Licensor for inclusion in the Work by the copyright owner | |||||
or by an individual or Legal Entity authorized to submit on behalf of | |||||
the copyright owner. For the purposes of this definition, "submitted" | |||||
means any form of electronic, verbal, or written communication sent | |||||
to the Licensor or its representatives, including but not limited to | |||||
communication on electronic mailing lists, source code control systems, | |||||
and issue tracking systems that are managed by, or on behalf of, the | |||||
Licensor for the purpose of discussing and improving the Work, but | |||||
excluding communication that is conspicuously marked or otherwise | |||||
designated in writing by the copyright owner as "Not a Contribution." | |||||
"Contributor" shall mean Licensor and any individual or Legal Entity | |||||
on behalf of whom a Contribution has been received by Licensor and | |||||
subsequently incorporated within the Work. | |||||
2. Grant of Copyright License. Subject to the terms and conditions of | |||||
this License, each Contributor hereby grants to You a perpetual, | |||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||||
copyright license to reproduce, prepare Derivative Works of, | |||||
publicly display, publicly perform, sublicense, and distribute the | |||||
Work and such Derivative Works in Source or Object form. | |||||
3. Grant of Patent License. Subject to the terms and conditions of | |||||
this License, each Contributor hereby grants to You a perpetual, | |||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||||
(except as stated in this section) patent license to make, have made, | |||||
use, offer to sell, sell, import, and otherwise transfer the Work, | |||||
where such license applies only to those patent claims licensable | |||||
by such Contributor that are necessarily infringed by their | |||||
Contribution(s) alone or by combination of their Contribution(s) | |||||
with the Work to which such Contribution(s) was submitted. If You | |||||
institute patent litigation against any entity (including a | |||||
cross-claim or counterclaim in a lawsuit) alleging that the Work | |||||
or a Contribution incorporated within the Work constitutes direct | |||||
or contributory patent infringement, then any patent licenses | |||||
granted to You under this License for that Work shall terminate | |||||
as of the date such litigation is filed. | |||||
4. Redistribution. You may reproduce and distribute copies of the | |||||
Work or Derivative Works thereof in any medium, with or without | |||||
modifications, and in Source or Object form, provided that You | |||||
meet the following conditions: | |||||
(a) You must give any other recipients of the Work or | |||||
Derivative Works a copy of this License; and | |||||
(b) You must cause any modified files to carry prominent notices | |||||
stating that You changed the files; and | |||||
(c) You must retain, in the Source form of any Derivative Works | |||||
that You distribute, all copyright, patent, trademark, and | |||||
attribution notices from the Source form of the Work, | |||||
excluding those notices that do not pertain to any part of | |||||
the Derivative Works; and | |||||
(d) If the Work includes a "NOTICE" text file as part of its | |||||
distribution, then any Derivative Works that You distribute must | |||||
include a readable copy of the attribution notices contained | |||||
within such NOTICE file, excluding those notices that do not | |||||
pertain to any part of the Derivative Works, in at least one | |||||
of the following places: within a NOTICE text file distributed | |||||
as part of the Derivative Works; within the Source form or | |||||
documentation, if provided along with the Derivative Works; or, | |||||
within a display generated by the Derivative Works, if and | |||||
wherever such third-party notices normally appear. The contents | |||||
of the NOTICE file are for informational purposes only and | |||||
do not modify the License. You may add Your own attribution | |||||
notices within Derivative Works that You distribute, alongside | |||||
or as an addendum to the NOTICE text from the Work, provided | |||||
that such additional attribution notices cannot be construed | |||||
as modifying the License. | |||||
You may add Your own copyright statement to Your modifications and | |||||
may provide additional or different license terms and conditions | |||||
for use, reproduction, or distribution of Your modifications, or | |||||
for any such Derivative Works as a whole, provided Your use, | |||||
reproduction, and distribution of the Work otherwise complies with | |||||
the conditions stated in this License. | |||||
5. Submission of Contributions. Unless You explicitly state otherwise, | |||||
any Contribution intentionally submitted for inclusion in the Work | |||||
by You to the Licensor shall be under the terms and conditions of | |||||
this License, without any additional terms or conditions. | |||||
Notwithstanding the above, nothing herein shall supersede or modify | |||||
the terms of any separate license agreement you may have executed | |||||
with Licensor regarding such Contributions. | |||||
6. Trademarks. This License does not grant permission to use the trade | |||||
names, trademarks, service marks, or product names of the Licensor, | |||||
except as required for reasonable and customary use in describing the | |||||
origin of the Work and reproducing the content of the NOTICE file. | |||||
7. Disclaimer of Warranty. Unless required by applicable law or | |||||
agreed to in writing, Licensor provides the Work (and each | |||||
Contributor provides its Contributions) on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |||||
implied, including, without limitation, any warranties or conditions | |||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |||||
PARTICULAR PURPOSE. You are solely responsible for determining the | |||||
appropriateness of using or redistributing the Work and assume any | |||||
risks associated with Your exercise of permissions under this License. | |||||
8. Limitation of Liability. In no event and under no legal theory, | |||||
whether in tort (including negligence), contract, or otherwise, | |||||
unless required by applicable law (such as deliberate and grossly | |||||
negligent acts) or agreed to in writing, shall any Contributor be | |||||
liable to You for damages, including any direct, indirect, special, | |||||
incidental, or consequential damages of any character arising as a | |||||
result of this License or out of the use or inability to use the | |||||
Work (including but not limited to damages for loss of goodwill, | |||||
work stoppage, computer failure or malfunction, or any and all | |||||
other commercial damages or losses), even if such Contributor | |||||
has been advised of the possibility of such damages. | |||||
9. Accepting Warranty or Additional Liability. While redistributing | |||||
the Work or Derivative Works thereof, You may choose to offer, | |||||
and charge a fee for, acceptance of support, warranty, indemnity, | |||||
or other liability obligations and/or rights consistent with this | |||||
License. However, in accepting such obligations, You may act only | |||||
on Your own behalf and on Your sole responsibility, not on behalf | |||||
of any other Contributor, and only if You agree to indemnify, | |||||
defend, and hold each Contributor harmless for any liability | |||||
incurred by, or claims asserted against, such Contributor by reason | |||||
of your accepting any such warranty or additional liability. | |||||
END OF TERMS AND CONDITIONS | |||||
APPENDIX: How to apply the Apache License to your work. | |||||
To apply the Apache License to your work, attach the following | |||||
boilerplate notice, with the fields enclosed by brackets "[]" | |||||
replaced with your own identifying information. (Don't include | |||||
the brackets!) The text should be enclosed in the appropriate | |||||
comment syntax for the file format. We also recommend that a | |||||
file or class name and description of purpose be included on the | |||||
same "printed page" as the copyright notice for easier | |||||
identification within third-party archives. | |||||
Copyright [yyyy] [name of copyright owner] | |||||
Licensed under the Apache License, Version 2.0 (the "License"); | |||||
you may not use this file except in compliance with the License. | |||||
You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. |
@@ -0,0 +1,53 @@ | |||||
# For help take a look at: | |||||
# http://www.cmake.org/Wiki/CMake:CPackConfiguration | |||||
### general settings | |||||
set(CPACK_PACKAGE_NAME ${APPLICATION_NAME}) | |||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Unit testing framework for C with mock objects") | |||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README") | |||||
set(CPACK_PACKAGE_VENDOR "Andreas Schneider") | |||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) | |||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") | |||||
### versions | |||||
set(CPACK_PACKAGE_VERSION_MAJOR "${APPLICATION_VERSION_MAJOR}") | |||||
set(CPACK_PACKAGE_VERSION_MINOR "${APPLICATION_VERSION_MINOR}") | |||||
set(CPACK_PACKAGE_VERSION_PATCH "${APPLICATION_VERSION_PATCH}") | |||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") | |||||
### source generator | |||||
set(CPACK_SOURCE_GENERATOR "TGZ") | |||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/obj*;tags;cscope.*;.ycm_extra_conf.pyc") | |||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") | |||||
if (WIN32) | |||||
set(CPACK_GENERATOR "ZIP") | |||||
### nsis generator | |||||
find_package(NSIS) | |||||
if (NSIS_MAKE) | |||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS") | |||||
set(CPACK_NSIS_DISPLAY_NAME "CMocka") | |||||
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib") | |||||
set(CPACK_NSIS_MENU_LINKS "http://cmocka.org/" "cmocka homepage") | |||||
endif (NSIS_MAKE) | |||||
endif (WIN32) | |||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "cmocka") | |||||
set(CPACK_PACKAGE_FILE_NAME ${APPLICATION_NAME}-${CPACK_PACKAGE_VERSION}) | |||||
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries") | |||||
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers") | |||||
set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION | |||||
"Libraries used to build programs which use cmocka") | |||||
set(CPACK_COMPONENT_HEADERS_DESCRIPTION | |||||
"C/C++ header files for use with cmocka") | |||||
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries) | |||||
#set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime") | |||||
set(CPACK_COMPONENT_LIBRARIES_GROUP "Development") | |||||
set(CPACK_COMPONENT_HEADERS_GROUP "Development") | |||||
include(CPack) |
@@ -0,0 +1,10 @@ | |||||
set(UPDATE_TYPE "true") | |||||
set(CTEST_PROJECT_NAME "cmocka") | |||||
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") | |||||
set(CTEST_DROP_METHOD "https") | |||||
set(CTEST_DROP_SITE "mock.cryptomilk.org") | |||||
set(CTEST_DROP_LOCATION "/submit.php?project=${CTEST_PROJECT_NAME}") | |||||
set(CTEST_DROP_SITE_CDASH TRUE) | |||||
@@ -0,0 +1,98 @@ | |||||
Fri Apr 07 2016 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 1.1.1 | |||||
* Fixed TAP output | |||||
* Fixed cmocka on Windows x64 | |||||
* Fixed xUnit output durations | |||||
Wed Sep 21 2016 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 1.1.0 | |||||
* Added support to catch multiple exceptions | |||||
* Added support to verify call ordering | |||||
* Added support to pass initial data to test cases | |||||
* Added will_return_maybe() for ignoring mock returns | |||||
* Added subtests for groups using TAP output | |||||
* Added support to write multiple XML files for groups | |||||
* Improved documentation | |||||
* Fixed XML output generataion | |||||
* Fixed Windows builds with VS2015 | |||||
Thu Mar 12 2015 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 1.0.1 | |||||
* Added a macro for assert_ptr_equal(). | |||||
* Fixed test_realloc() if 0 size is passed. | |||||
* Fixed objects packaging bug. | |||||
* Fixed building with newer gcc versions. | |||||
Sun Feb 16 2015 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 1.0.0 | |||||
* Added new test runner with group fixtures. The old runner is deprecated | |||||
* Added an extensible message output formatter | |||||
* Added jUnit XML message output | |||||
* Added subunit message output | |||||
* Added Test Anything Protocol message output | |||||
* Added skip() command | |||||
* Added test_realloc() | |||||
* Added a cmockery compat header | |||||
* Fixed a lot of bugs on Windows | |||||
Thu May 22 2014 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 0.4.1 | |||||
* Added CMOCKA_TEST_ABORT env variable to leave threading apps. | |||||
* Fixed count parameter of expect_check() macro. | |||||
* Fixed reporting the number of tests. | |||||
* Fixed cmake config files. | |||||
Fri Apr 11 2014 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 0.4.0 | |||||
* Added support for group testing. | |||||
* Added assert_return_code(). | |||||
* Added better messages for errors. | |||||
* Added cmake config mode support. | |||||
* Fixed bug with unit_test_setup and unit_test_teardown. | |||||
* Fixed a lot of small bugs. | |||||
Wed Nov 06 2013 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 0.3.2 | |||||
* Fixed FindNSIS detection. | |||||
* Fixed unit_test_setup() and unit_test_teardown(). | |||||
* Fixed GTest and GCC message style conformance | |||||
* Fixed stringification in will_return_always(). | |||||
Wed Jul 10 15:24 2013 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 0.3.1 | |||||
* Fixed pointer conversion on s390 and ppc (32bit big endian). | |||||
* Fixed the customer_database test on big endian. | |||||
Wed Jun 05 08:14 2013 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 0.3.0 | |||||
* Added a better mock object example. | |||||
* Added pkgconfig file. | |||||
* Added new macros mock_type() and mock_ptr_type(). | |||||
* Added more documentation. | |||||
* Fixed installation problems on some platforms. | |||||
Mon Jan 14 11:16 2013 Andreas Schneider <asn@cryptomilk.org> | |||||
* cmocka: version 0.2.0 | |||||
* Added doxygen api documentation. | |||||
* Added new cmake build system. | |||||
* Added support to create windows NSIS installer. | |||||
* Fixed examples which didn't work. | |||||
* Fixed a huge amount of bugs. | |||||
Mon Sep 15 17:21:22 2008 Google Inc. <opensource@google.com> | |||||
* cmockery: version 0.12 | |||||
* Made it possible to specify additional compiler, lib tool and link | |||||
flags on Windows. | |||||
* Added Windows makefile to the tar ball. | |||||
Fri Aug 29 10:50:46 2008 Google Inc. <opensource@google.com> | |||||
* cmockery: version 0.11 | |||||
* Made it possible to specify executable, library and object output | |||||
directories. | |||||
Tue Aug 26 10:18:02 2008 Google Inc. <opensource@google.com> | |||||
* cmockery: initial release: | |||||
A lightweight library to simplify and generalize the process of | |||||
writing unit tests for C applications. |
@@ -0,0 +1,149 @@ | |||||
include(CheckIncludeFile) | |||||
include(CheckSymbolExists) | |||||
include(CheckFunctionExists) | |||||
include(CheckLibraryExists) | |||||
include(CheckTypeSize) | |||||
include(CheckCXXSourceCompiles) | |||||
include(CheckStructHasMember) | |||||
include(TestBigEndian) | |||||
set(PACKAGE ${APPLICATION_NAME}) | |||||
set(VERSION ${APPLICATION_VERSION}) | |||||
set(DATADIR ${DATA_INSTALL_DIR}) | |||||
set(LIBDIR ${LIB_INSTALL_DIR}) | |||||
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}") | |||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR}) | |||||
set(BINARYDIR ${CMAKE_BINARY_DIR}) | |||||
set(SOURCEDIR ${CMAKE_SOURCE_DIR}) | |||||
function(COMPILER_DUMPVERSION _OUTPUT_VERSION) | |||||
# Remove whitespaces from the argument. | |||||
# This is needed for CC="ccache gcc" cmake .. | |||||
string(REPLACE " " "" _C_COMPILER_ARG "${CMAKE_C_COMPILER_ARG1}") | |||||
execute_process( | |||||
COMMAND | |||||
${CMAKE_C_COMPILER} ${_C_COMPILER_ARG} -dumpversion | |||||
OUTPUT_VARIABLE _COMPILER_VERSION | |||||
) | |||||
string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" | |||||
_COMPILER_VERSION ${_COMPILER_VERSION}) | |||||
set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE) | |||||
endfunction() | |||||
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW) | |||||
compiler_dumpversion(GNUCC_VERSION) | |||||
if (NOT GNUCC_VERSION EQUAL 34) | |||||
check_c_compiler_flag("-fvisibility=hidden" WITH_VISIBILITY_HIDDEN) | |||||
endif (NOT GNUCC_VERSION EQUAL 34) | |||||
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW) | |||||
# DEFINITIONS | |||||
if (SOLARIS) | |||||
add_definitions(-D__EXTENSIONS__) | |||||
endif (SOLARIS) | |||||
# HEADER FILES | |||||
check_include_file(assert.h HAVE_ASSERT_H) | |||||
check_include_file(inttypes.h HAVE_INTTYPES_H) | |||||
check_include_file(io.h HAVE_IO_H) | |||||
check_include_file(malloc.h HAVE_MALLOC_H) | |||||
check_include_file(memory.h HAVE_MEMORY_H) | |||||
check_include_file(setjmp.h HAVE_SETJMP_H) | |||||
check_include_file(signal.h HAVE_SIGNAL_H) | |||||
check_include_file(stdarg.h HAVE_STDARG_H) | |||||
check_include_file(stddef.h HAVE_STDDEF_H) | |||||
check_include_file(stdint.h HAVE_STDINT_H) | |||||
check_include_file(stdio.h HAVE_STDIO_H) | |||||
check_include_file(stdlib.h HAVE_STDLIB_H) | |||||
check_include_file(string.h HAVE_STRING_H) | |||||
check_include_file(strings.h HAVE_STRINGS_H) | |||||
check_include_file(sys/stat.h HAVE_SYS_STAT_H) | |||||
check_include_file(sys/types.h HAVE_SYS_TYPES_H) | |||||
check_include_file(time.h HAVE_TIME_H) | |||||
check_include_file(unistd.h HAVE_UNISTD_H) | |||||
if (HAVE_TIME_H) | |||||
check_struct_has_member("struct timespec" tv_sec "time.h" HAVE_STRUCT_TIMESPEC) | |||||
endif (HAVE_TIME_H) | |||||
# FUNCTIONS | |||||
check_function_exists(calloc HAVE_CALLOC) | |||||
check_function_exists(exit HAVE_EXIT) | |||||
check_function_exists(fprintf HAVE_FPRINTF) | |||||
check_function_exists(free HAVE_FREE) | |||||
check_function_exists(longjmp HAVE_LONGJMP) | |||||
check_function_exists(siglongjmp HAVE_SIGLONGJMP) | |||||
check_function_exists(malloc HAVE_MALLOC) | |||||
check_function_exists(memcpy HAVE_MEMCPY) | |||||
check_function_exists(memset HAVE_MEMSET) | |||||
check_function_exists(printf HAVE_PRINTF) | |||||
check_function_exists(setjmp HAVE_SETJMP) | |||||
check_function_exists(signal HAVE_SIGNAL) | |||||
check_function_exists(strsignal HAVE_STRSIGNAL) | |||||
check_function_exists(strcmp HAVE_STRCMP) | |||||
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) | |||||
if (WIN32) | |||||
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S) | |||||
check_function_exists(_vsnprintf HAVE__VSNPRINTF) | |||||
check_function_exists(_snprintf HAVE__SNPRINTF) | |||||
check_function_exists(_snprintf_s HAVE__SNPRINTF_S) | |||||
check_symbol_exists(snprintf stdio.h HAVE_SNPRINTF) | |||||
check_symbol_exists(vsnprintf stdio.h HAVE_VSNPRINTF) | |||||
else (WIN32) | |||||
check_function_exists(sprintf HAVE_SNPRINTF) | |||||
check_function_exists(vsnprintf HAVE_VSNPRINTF) | |||||
endif (WIN32) | |||||
find_library(RT_LIBRARY rt) | |||||
if (RT_LIBRARY AND NOT LINUX) | |||||
set(CMOCKA_REQUIRED_LIBRARIES ${RT_LIBRARY} CACHE INTERNAL "cmocka required system libraries") | |||||
endif () | |||||
# OPTIONS | |||||
check_c_source_compiles(" | |||||
__thread int tls; | |||||
int main(void) { | |||||
return 0; | |||||
}" HAVE_GCC_THREAD_LOCAL_STORAGE) | |||||
if (WIN32) | |||||
check_c_source_compiles(" | |||||
__declspec(thread) int tls; | |||||
int main(void) { | |||||
return 0; | |||||
}" HAVE_MSVC_THREAD_LOCAL_STORAGE) | |||||
endif(WIN32) | |||||
if (HAVE_TIME_H AND HAVE_STRUCT_TIMESPEC AND HAVE_CLOCK_GETTIME) | |||||
if (RT_LIBRARY) | |||||
set(CMAKE_REQUIRED_LIBRARIES ${RT_LIBRARY}) | |||||
endif() | |||||
check_c_source_compiles(" | |||||
#include <time.h> | |||||
int main(void) { | |||||
struct timespec ts; | |||||
clock_gettime(CLOCK_REALTIME, &ts); | |||||
return 0; | |||||
}" HAVE_CLOCK_REALTIME) | |||||
# reset cmake requirements | |||||
set(CMAKE_REQUIRED_INCLUDES) | |||||
set(CMAKE_REQUIRED_LIBRARIES) | |||||
endif () | |||||
# ENDIAN | |||||
if (NOT WIN32) | |||||
set(WORDS_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) | |||||
test_big_endian(WORDS_BIGENDIAN) | |||||
endif (NOT WIN32) |
@@ -0,0 +1,7 @@ | |||||
option(WITH_STATIC_LIB "Build with a static library" OFF) | |||||
option(WITH_CMOCKERY_SUPPORT "Install a cmockery header" OFF) | |||||
option(UNIT_TESTING "Build with unit testing" OFF) | |||||
if (UNIT_TESTING) | |||||
set(WITH_STATIC_LIB ON) | |||||
endif() |
@@ -0,0 +1,102 @@ | |||||
# How to build from source | |||||
## Requirements | |||||
### Common requirements | |||||
In order to build cmocka, you need to install several components: | |||||
- A C compiler | |||||
- [CMake](http://www.cmake.org) >= 2.8.0. | |||||
Note that these version numbers are version we know works correctly. If you | |||||
build and run cmocka successfully with an older version, please let us know. | |||||
## Building | |||||
First, you need to configure the compilation, using CMake. Go inside the | |||||
`build` dir. Create it if it doesn't exist. | |||||
GNU/Linux, MacOS X, MSYS/MinGW: | |||||
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug .. | |||||
make | |||||
On Windows you should choose a makefile gernerator with -G, for example: | |||||
cmake -G "Visual Studio 12 2013" -DCMAKE_BUILD_TYPE=Debug /path/to/source | |||||
You can also use the CMake GUI which is shipped with CMake. It will list all | |||||
available generators for MSVC on Windows. | |||||
### CMake standard options | |||||
Here is a list of the most interesting options provided out of the box by | |||||
CMake. | |||||
- CMAKE_BUILD_TYPE: The type of build (can be Debug Release MinSizeRel | |||||
RelWithDebInfo) | |||||
- CMAKE_INSTALL_PREFIX: The prefix to use when running make install (Default | |||||
to /usr/local on GNU/Linux and MacOS X) | |||||
- CMAKE_C_COMPILER: The path to the C compiler | |||||
- CMAKE_CXX_COMPILER: The path to the C++ compiler | |||||
### CMake options defined for cmocka | |||||
Options are defined in the following files: | |||||
- DefineOptions.cmake | |||||
They can be changed with the -D option: | |||||
`cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=ON ..` | |||||
### Browsing/editing CMake options | |||||
In addition to passing options on the command line, you can browse and edit | |||||
CMake options using `cmakesetup` (Windows), `cmake-gui` or `ccmake` (GNU/Linux | |||||
and MacOS X). | |||||
- Go to the build dir | |||||
- On Windows: run `cmakesetup` | |||||
- On GNU/Linux and MacOS X: run `ccmake ..` | |||||
## Installing | |||||
If you want to install cmocka after compilation run: | |||||
make install | |||||
## Running | |||||
The cmocka library can be found in the `build/src` directory. | |||||
You can run the binaries in `build/examples/*` which is a | |||||
are exsample tests. | |||||
## Testing | |||||
As mention above you can turn on the unit tests and make it possible to easily | |||||
execute them: | |||||
`cmake -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=ON ..` | |||||
After that you can simply call `make test` in the build directory or if you | |||||
want more output simply call `ctest -V`. | |||||
If you want to enable the generation of coverage files you can do this by | |||||
using the following options: | |||||
`cmake -DCMAKE_BUILD_TYPE=Profiling -DUNIT_TESTING=ON ..` | |||||
After building it you will see that you have several coverage options in | |||||
`make help` | |||||
You should have `make ExperimentalCoverage` and running it will create | |||||
coverage files. The result is stored in Testing directory. | |||||
## About this document | |||||
This document is written using [Markdown][] syntax, making it possible to | |||||
provide usable information in both plain text and HTML format. Whenever | |||||
modifying this document please use [Markdown][] syntax. | |||||
[markdown]: http://www.daringfireball.net/projects/markdown |
@@ -0,0 +1,15 @@ | |||||
CMOCKA | |||||
======= | |||||
cmocka is a fork for Google's cmockery unit testing framework to fix bugs and | |||||
support it in future. | |||||
See https://code.google.com/p/cmockery/ | |||||
For information about how to use the cmocka unit testing framework see | |||||
doc/index.html. | |||||
COMPILING | |||||
--------- | |||||
To compile the cmocka library and example applications run, create a build dir, | |||||
and in the build dir call 'cmake /path/to/cmocka' followed by 'make'. On | |||||
Windows you can use the cmake gui. More details can be found in the INSTALL file. |
@@ -0,0 +1,23 @@ | |||||
# - ADD_CMOCKA_TEST(test_name test_source linklib1 ... linklibN) | |||||
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de> | |||||
# Copyright (c) 2007-2010 Andreas Schneider <asn@cynapses.org> | |||||
# | |||||
# Redistribution and use is allowed according to the terms of the BSD license. | |||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | |||||
enable_testing() | |||||
include(CTest) | |||||
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW) | |||||
set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags") | |||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") | |||||
set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") | |||||
set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") | |||||
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW) | |||||
function (ADD_CMOCKA_TEST _testName _testSource) | |||||
add_executable(${_testName} ${_testSource}) | |||||
target_link_libraries(${_testName} ${ARGN}) | |||||
add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName}) | |||||
endfunction (ADD_CMOCKA_TEST) |
@@ -0,0 +1,22 @@ | |||||
Redistribution and use in source and binary forms, with or without | |||||
modification, are permitted provided that the following conditions | |||||
are met: | |||||
1. Redistributions of source code must retain the copyright | |||||
notice, this list of conditions and the following disclaimer. | |||||
2. Redistributions in binary form must reproduce the copyright | |||||
notice, this list of conditions and the following disclaimer in the | |||||
documentation and/or other materials provided with the distribution. | |||||
3. The name of the author may not be used to endorse or promote products | |||||
derived from this software without specific prior written permission. | |||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@@ -0,0 +1,26 @@ | |||||
# - Check whether the C compiler supports a given flag in the | |||||
# context of a stack checking compiler option. | |||||
# CHECK_C_COMPILER_FLAG_SSP(FLAG VARIABLE) | |||||
# | |||||
# FLAG - the compiler flag | |||||
# VARIABLE - variable to store the result | |||||
# | |||||
# This actually calls check_c_source_compiles. | |||||
# See help for CheckCSourceCompiles for a listing of variables | |||||
# that can modify the build. | |||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org> | |||||
# | |||||
# Redistribution and use is allowed according to the terms of the BSD license. | |||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | |||||
include(CheckCSourceCompiles) | |||||
function(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT) | |||||
set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") | |||||
set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") | |||||
check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT}) | |||||
set(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") | |||||
endfunction(CHECK_C_COMPILER_FLAG_SSP) |
@@ -0,0 +1,36 @@ | |||||
# Always include srcdir and builddir in include path | |||||
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in | |||||
# about every subdir | |||||
# since cmake 2.4.0 | |||||
set(CMAKE_INCLUDE_CURRENT_DIR ON) | |||||
# Put the include dirs which are in the source or build tree | |||||
# before all other include dirs, so the headers in the sources | |||||
# are prefered over the already installed ones | |||||
# since cmake 2.4.1 | |||||
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) | |||||
# Use colored output | |||||
# since cmake 2.4.0 | |||||
set(CMAKE_COLOR_MAKEFILE ON) | |||||
# Define the generic version of the libraries here | |||||
set(GENERIC_LIB_VERSION "0.1.0") | |||||
set(GENERIC_LIB_SOVERSION "0") | |||||
# Set the default build type to release with debug info | |||||
if (NOT CMAKE_BUILD_TYPE) | |||||
set(CMAKE_BUILD_TYPE RelWithDebInfo | |||||
CACHE STRING | |||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." | |||||
) | |||||
endif (NOT CMAKE_BUILD_TYPE) | |||||
# Create the compile command database for clang by default | |||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | |||||
if (APPLE) | |||||
set(CMAKE_MACOSX_RPATH ON) | |||||
set(CMAKE_SKIP_BUILD_RPATH FALSE) | |||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) | |||||
endif(APPLE) |
@@ -0,0 +1,79 @@ | |||||
# define system dependent compiler flags | |||||
include(CheckCCompilerFlag) | |||||
include(CheckCCompilerFlagSSP) | |||||
if (UNIX AND NOT WIN32) | |||||
# | |||||
# Define GNUCC compiler flags | |||||
# | |||||
if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)") | |||||
# add -Wconversion ? | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors") | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement") | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security") | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute -Wundef -Wstrict-prototypes") | |||||
# with -fPIC | |||||
check_c_compiler_flag("-fPIC" WITH_FPIC) | |||||
if (WITH_FPIC) | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") | |||||
endif (WITH_FPIC) | |||||
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR) | |||||
if (WITH_STACK_PROTECTOR) | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector") | |||||
endif (WITH_STACK_PROTECTOR) | |||||
if (CMAKE_BUILD_TYPE) | |||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) | |||||
if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel)) | |||||
check_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE) | |||||
if (WITH_FORTIFY_SOURCE) | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wp,-D_FORTIFY_SOURCE=2") | |||||
endif (WITH_FORTIFY_SOURCE) | |||||
endif() | |||||
endif() | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE") | |||||
endif (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)") | |||||
# | |||||
# Check for large filesystem support | |||||
# | |||||
if (CMAKE_SIZEOF_VOID_P MATCHES "8") | |||||
# with large file support | |||||
execute_process( | |||||
COMMAND | |||||
getconf LFS64_CFLAGS | |||||
OUTPUT_VARIABLE | |||||
_lfs_CFLAGS | |||||
ERROR_QUIET | |||||
OUTPUT_STRIP_TRAILING_WHITESPACE | |||||
) | |||||
else (CMAKE_SIZEOF_VOID_P MATCHES "8") | |||||
# with large file support | |||||
execute_process( | |||||
COMMAND | |||||
getconf LFS_CFLAGS | |||||
OUTPUT_VARIABLE | |||||
_lfs_CFLAGS | |||||
ERROR_QUIET | |||||
OUTPUT_STRIP_TRAILING_WHITESPACE | |||||
) | |||||
endif (CMAKE_SIZEOF_VOID_P MATCHES "8") | |||||
if (_lfs_CFLAGS) | |||||
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}") | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_lfs_CFLAGS}") | |||||
endif (_lfs_CFLAGS) | |||||
endif (UNIX AND NOT WIN32) | |||||
if (MSVC) | |||||
# Use secure functions by defaualt and suppress warnings about | |||||
#"deprecated" functions | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1") | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1") | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1") | |||||
endif (MSVC) |
@@ -0,0 +1,109 @@ | |||||
if (UNIX OR OS2) | |||||
IF (NOT APPLICATION_NAME) | |||||
MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME") | |||||
SET(APPLICATION_NAME ${PROJECT_NAME}) | |||||
ENDIF (NOT APPLICATION_NAME) | |||||
# Suffix for Linux | |||||
SET(LIB_SUFFIX | |||||
CACHE STRING "Define suffix of directory name (32/64)" | |||||
) | |||||
SET(EXEC_INSTALL_PREFIX | |||||
"${CMAKE_INSTALL_PREFIX}" | |||||
CACHE PATH "Base directory for executables and libraries" | |||||
) | |||||
SET(SHARE_INSTALL_PREFIX | |||||
"${CMAKE_INSTALL_PREFIX}/share" | |||||
CACHE PATH "Base directory for files which go to share/" | |||||
) | |||||
SET(DATA_INSTALL_PREFIX | |||||
"${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}" | |||||
CACHE PATH "The parent directory where applications can install their data") | |||||
# The following are directories where stuff will be installed to | |||||
SET(BIN_INSTALL_DIR | |||||
"${EXEC_INSTALL_PREFIX}/bin" | |||||
CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)" | |||||
) | |||||
SET(SBIN_INSTALL_DIR | |||||
"${EXEC_INSTALL_PREFIX}/sbin" | |||||
CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)" | |||||
) | |||||
SET(LIB_INSTALL_DIR | |||||
"${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}" | |||||
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)" | |||||
) | |||||
SET(LIBEXEC_INSTALL_DIR | |||||
"${EXEC_INSTALL_PREFIX}/libexec" | |||||
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)" | |||||
) | |||||
SET(PLUGIN_INSTALL_DIR | |||||
"${LIB_INSTALL_DIR}/${APPLICATION_NAME}" | |||||
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})" | |||||
) | |||||
SET(INCLUDE_INSTALL_DIR | |||||
"${CMAKE_INSTALL_PREFIX}/include" | |||||
CACHE PATH "The subdirectory to the header prefix (default prefix/include)" | |||||
) | |||||
set(CMAKE_INSTALL_DIR | |||||
"${LIB_INSTALL_DIR}/cmake" | |||||
CACHE PATH "The subdirectory to install cmake config files") | |||||
SET(DATA_INSTALL_DIR | |||||
"${DATA_INSTALL_PREFIX}" | |||||
CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_NAME})" | |||||
) | |||||
SET(HTML_INSTALL_DIR | |||||
"${DATA_INSTALL_PREFIX}/doc/HTML" | |||||
CACHE PATH "The HTML install dir for documentation (default data/doc/html)" | |||||
) | |||||
SET(ICON_INSTALL_DIR | |||||
"${DATA_INSTALL_PREFIX}/icons" | |||||
CACHE PATH "The icon install dir (default data/icons/)" | |||||
) | |||||
SET(SOUND_INSTALL_DIR | |||||
"${DATA_INSTALL_PREFIX}/sounds" | |||||
CACHE PATH "The install dir for sound files (default data/sounds)" | |||||
) | |||||
SET(LOCALE_INSTALL_DIR | |||||
"${SHARE_INSTALL_PREFIX}/locale" | |||||
CACHE PATH "The install dir for translations (default prefix/share/locale)" | |||||
) | |||||
SET(XDG_APPS_DIR | |||||
"${SHARE_INSTALL_PREFIX}/applications/" | |||||
CACHE PATH "The XDG apps dir" | |||||
) | |||||
SET(XDG_DIRECTORY_DIR | |||||
"${SHARE_INSTALL_PREFIX}/desktop-directories" | |||||
CACHE PATH "The XDG directory" | |||||
) | |||||
SET(SYSCONF_INSTALL_DIR | |||||
"${EXEC_INSTALL_PREFIX}/etc" | |||||
CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)" | |||||
) | |||||
SET(MAN_INSTALL_DIR | |||||
"${SHARE_INSTALL_PREFIX}/man" | |||||
CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)" | |||||
) | |||||
SET(INFO_INSTALL_DIR | |||||
"${SHARE_INSTALL_PREFIX}/info" | |||||
CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)" | |||||
) | |||||
else() | |||||
# Same same | |||||
set(BIN_INSTALL_DIR "bin" CACHE PATH "-") | |||||
set(SBIN_INSTALL_DIR "sbin" CACHE PATH "-") | |||||
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "-") | |||||
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-") | |||||
set(CMAKE_INSTALL_DIR "CMake" CACHE PATH "-") | |||||
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-") | |||||
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-") | |||||
set(ICON_INSTALL_DIR "icons" CACHE PATH "-") | |||||
set(SOUND_INSTALL_DIR "soudns" CACHE PATH "-") | |||||
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-") | |||||
endif () |
@@ -0,0 +1,21 @@ | |||||
# Set system vars | |||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux") | |||||
set(LINUX TRUE) | |||||
endif(CMAKE_SYSTEM_NAME MATCHES "Linux") | |||||
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") | |||||
set(FREEBSD TRUE) | |||||
endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") | |||||
if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") | |||||
set(OPENBSD TRUE) | |||||
endif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") | |||||
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") | |||||
set(NETBSD TRUE) | |||||
endif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") | |||||
if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") | |||||
set(SOLARIS TRUE) | |||||
endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") |
@@ -0,0 +1,51 @@ | |||||
# - Try to find NSIS | |||||
# Once done this will define | |||||
# | |||||
# NSIS_FOUND - system has NSIS | |||||
# NSIS_MAKE - NSIS creator executable | |||||
# | |||||
#============================================================================= | |||||
# Copyright (c) 2010-2013 Andreas Schneider <asn@cryptomilk.org> | |||||
# | |||||
# Distributed under the OSI-approved BSD License (the "License"); | |||||
# see accompanying file Copyright.txt for details. | |||||
# | |||||
# This software is distributed WITHOUT ANY WARRANTY; without even the | |||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |||||
# See the License for more information. | |||||
#============================================================================= | |||||
# | |||||
if (WIN32) | |||||
set(_NSIS_ROOT_HINTS | |||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS;Default]") | |||||
set(_NSIS_ROOT_PATHS | |||||
$ENV{PROGRAMFILES}/NSIS) | |||||
find_path(NSIS_ROOT_PATH | |||||
NAMES | |||||
Include/Library.nsh | |||||
HINTS | |||||
${_NSIS_ROOT_HINTS} | |||||
PATHS | |||||
${_NSIS_ROOT_PATHS} | |||||
) | |||||
mark_as_advanced(NSIS_ROOT_PATH) | |||||
endif (WIN32) | |||||
find_program(NSIS_MAKE | |||||
NAMES | |||||
makensis | |||||
PATHS | |||||
${NSIS_ROOT_PATH} | |||||
) | |||||
include(FindPackageHandleStandardArgs) | |||||
find_package_handle_standard_args(NSIS DEFAULT_MSG NSIS_MAKE) | |||||
if (NSIS_MAKE) | |||||
set(NSIS_FOUND TRUE) | |||||
endif (NSIS_MAKE) | |||||
mark_as_advanced(NSIS_MAKE) |
@@ -0,0 +1,17 @@ | |||||
# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>) | |||||
# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>) | |||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org> | |||||
# | |||||
# Redistribution and use is allowed according to the terms of the BSD license. | |||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | |||||
macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage) | |||||
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource) | |||||
if (_insource) | |||||
message(SEND_ERROR "${_errorMessage}") | |||||
message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.") | |||||
endif (_insource) | |||||
endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD) |
@@ -0,0 +1,140 @@ | |||||
# - Run Doxygen | |||||
# | |||||
# Adds a doxygen target that runs doxygen to generate the html | |||||
# and optionally the LaTeX API documentation. | |||||
# The doxygen target is added to the doc target as a dependency. | |||||
# i.e.: the API documentation is built with: | |||||
# make doc | |||||
# | |||||
# USAGE: GLOBAL INSTALL | |||||
# | |||||
# Install it with: | |||||
# cmake ./ && sudo make install | |||||
# Add the following to the CMakeLists.txt of your project: | |||||
# include(UseDoxygen OPTIONAL) | |||||
# Optionally copy Doxyfile.in in the directory of CMakeLists.txt and edit it. | |||||
# | |||||
# USAGE: INCLUDE IN PROJECT | |||||
# | |||||
# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) | |||||
# include(UseDoxygen) | |||||
# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory. | |||||
# | |||||
# | |||||
# CONFIGURATION | |||||
# | |||||
# To configure Doxygen you can edit Doxyfile.in and set some variables in cmake. | |||||
# Variables you may define are: | |||||
# DOXYFILE_SOURCE_DIR - Path where the Doxygen input files are. | |||||
# Defaults to the current source directory. | |||||
# DOXYFILE_EXTRA_SOURCES - Additional source diretories/files for Doxygen to scan. | |||||
# The Paths should be in double quotes and separated by space. e.g.: | |||||
# "${CMAKE_CURRENT_BINARY_DIR}/foo.c" "${CMAKE_CURRENT_BINARY_DIR}/bar/" | |||||
# | |||||
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored. | |||||
# Defaults to "${CMAKE_CURRENT_BINARY_DIR}/doc". | |||||
# | |||||
# DOXYFILE_LATEX - ON/OFF; Set to "ON" if you want the LaTeX documentation | |||||
# to be built. | |||||
# DOXYFILE_LATEX_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where | |||||
# the Doxygen LaTeX output is stored. Defaults to "latex". | |||||
# | |||||
# DOXYFILE_HTML_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where | |||||
# the Doxygen html output is stored. Defaults to "html". | |||||
# | |||||
# | |||||
# Copyright (c) 2009, 2010, 2011 Tobias Rautenkranz <tobias@rautenkranz.ch> | |||||
# | |||||
# Redistribution and use is allowed according to the terms of the New | |||||
# BSD license. | |||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | |||||
# | |||||
macro(usedoxygen_set_default name value type docstring) | |||||
if(NOT DEFINED "${name}") | |||||
set("${name}" "${value}" CACHE "${type}" "${docstring}") | |||||
endif() | |||||
endmacro() | |||||
find_package(Doxygen) | |||||
if(DOXYGEN_FOUND) | |||||
find_file(DOXYFILE_IN "Doxyfile.in" | |||||
PATHS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_ROOT}/Modules/" | |||||
NO_DEFAULT_PATH | |||||
DOC "Path to the doxygen configuration template file") | |||||
set(DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile") | |||||
include(FindPackageHandleStandardArgs) | |||||
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN") | |||||
endif() | |||||
if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND) | |||||
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc" | |||||
PATH "Doxygen output directory") | |||||
usedoxygen_set_default(DOXYFILE_HTML_DIR "html" | |||||
STRING "Doxygen HTML output directory") | |||||
usedoxygen_set_default(DOXYFILE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" | |||||
PATH "Input files source directory") | |||||
usedoxygen_set_default(DOXYFILE_EXTRA_SOURCE_DIRS "" | |||||
STRING "Additional source files/directories separated by space") | |||||
set(DOXYFILE_SOURCE_DIRS "\"${DOXYFILE_SOURCE_DIR}\" ${DOXYFILE_EXTRA_SOURCES}") | |||||
usedoxygen_set_default(DOXYFILE_LATEX YES BOOL "Generate LaTeX API documentation" OFF) | |||||
usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex" STRING "LaTex output directory") | |||||
mark_as_advanced(DOXYFILE_OUTPUT_DIR DOXYFILE_HTML_DIR DOXYFILE_LATEX_DIR | |||||
DOXYFILE_SOURCE_DIR DOXYFILE_EXTRA_SOURCE_DIRS DOXYFILE_IN) | |||||
set_property(DIRECTORY | |||||
APPEND PROPERTY | |||||
ADDITIONAL_MAKE_CLEAN_FILES | |||||
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}") | |||||
add_custom_target(doxygen | |||||
COMMAND "${DOXYGEN_EXECUTABLE}" | |||||
"${DOXYFILE}" | |||||
COMMENT "Writing documentation to ${DOXYFILE_OUTPUT_DIR}..." | |||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") | |||||
set(DOXYFILE_DOT "NO") | |||||
if(DOXYGEN_DOT_EXECUTABLE) | |||||
set(DOXYFILE_DOT "YES") | |||||
endif() | |||||
## LaTeX | |||||
set(DOXYFILE_PDFLATEX "NO") | |||||
set_property(DIRECTORY APPEND PROPERTY | |||||
ADDITIONAL_MAKE_CLEAN_FILES | |||||
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}") | |||||
if(DOXYFILE_LATEX STREQUAL "ON") | |||||
set(DOXYFILE_GENERATE_LATEX "YES") | |||||
find_package(LATEX) | |||||
find_program(DOXYFILE_MAKE make) | |||||
mark_as_advanced(DOXYFILE_MAKE) | |||||
if(LATEX_COMPILER AND MAKEINDEX_COMPILER AND DOXYFILE_MAKE) | |||||
if(PDFLATEX_COMPILER) | |||||
set(DOXYFILE_PDFLATEX "YES") | |||||
endif() | |||||
add_custom_command(TARGET doxygen | |||||
POST_BUILD | |||||
COMMAND "${DOXYFILE_MAKE}" | |||||
COMMENT "Running LaTeX for Doxygen documentation in ${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}..." | |||||
WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}") | |||||
else() | |||||
set(DOXYGEN_LATEX "NO") | |||||
endif() | |||||
else() | |||||
set(DOXYFILE_GENERATE_LATEX "NO") | |||||
endif() | |||||
configure_file("${DOXYFILE_IN}" "${DOXYFILE}" @ONLY) | |||||
add_custom_target(doc) | |||||
add_dependencies(doc doxygen) | |||||
endif() |
@@ -0,0 +1 @@ | |||||
set(CMOCKA_INLUDE_DIR @PROJECT_SOURCE_DIR@/include) |
@@ -0,0 +1,11 @@ | |||||
set(PACKAGE_VERSION @APPLICATION_VERSION@) | |||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible | |||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") | |||||
set(PACKAGE_VERSION_COMPATIBLE FALSE) | |||||
else() | |||||
set(PACKAGE_VERSION_COMPATIBLE TRUE) | |||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") | |||||
set(PACKAGE_VERSION_EXACT TRUE) | |||||
endif() | |||||
endif() |
@@ -0,0 +1,11 @@ | |||||
get_filename_component(CMOCKA_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) | |||||
if (EXISTS "${CMOCKA_CMAKE_DIR}/CMakeCache.txt") | |||||
# In build tree | |||||
include(${CMOCKA_CMAKE_DIR}/cmocka-build-tree-settings.cmake) | |||||
else() | |||||
set(CMOCKA_INCLUDE_DIR @INCLUDE_INSTALL_DIR@) | |||||
endif() | |||||
set(CMOCKA_LIBRARY @LIB_INSTALL_DIR@/@CMOCKA_LIBRARY_NAME@) | |||||
set(CMOCKA_LIBRARIES @LIB_INSTALL_DIR@/@CMOCKA_LIBRARY_NAME@) |
@@ -0,0 +1,6 @@ | |||||
Name: ${APPLICATION_NAME} | |||||
Description: The cmocka unit testing library | |||||
Version: ${APPLICATION_VERSION} | |||||
Libs: -L${LIB_INSTALL_DIR} -lcmocka | |||||
Cflags: -I${INCLUDE_INSTALL_DIR} | |||||
@@ -0,0 +1,169 @@ | |||||
/* Name of package */ | |||||
#cmakedefine PACKAGE "${APPLICATION_NAME}" | |||||
/* Version number of package */ | |||||
#cmakedefine VERSION "${APPLICATION_VERSION}" | |||||
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}" | |||||
#cmakedefine DATADIR "${DATADIR}" | |||||
#cmakedefine LIBDIR "${LIBDIR}" | |||||
#cmakedefine PLUGINDIR "${PLUGINDIR}" | |||||
#cmakedefine SYSCONFDIR "${SYSCONFDIR}" | |||||
#cmakedefine BINARYDIR "${BINARYDIR}" | |||||
#cmakedefine SOURCEDIR "${SOURCEDIR}" | |||||
/************************** HEADER FILES *************************/ | |||||
/* Define to 1 if you have the <assert.h> header file. */ | |||||
#cmakedefine HAVE_ASSERT_H 1 | |||||
/* Define to 1 if you have the <dlfcn.h> header file. */ | |||||
#cmakedefine HAVE_DLFCN_H 1 | |||||
/* Define to 1 if you have the <inttypes.h> header file. */ | |||||
#cmakedefine HAVE_INTTYPES_H 1 | |||||
/* Define to 1 if you have the <io.h> header file. */ | |||||
#cmakedefine HAVE_IO_H 1 | |||||
/* Define to 1 if you have the <malloc.h> header file. */ | |||||
#cmakedefine HAVE_MALLOC_H 1 | |||||
/* Define to 1 if you have the <memory.h> header file. */ | |||||
#cmakedefine HAVE_MEMORY_H 1 | |||||
/* Define to 1 if you have the <setjmp.h> header file. */ | |||||
#cmakedefine HAVE_SETJMP_H 1 | |||||
/* Define to 1 if you have the <signal.h> header file. */ | |||||
#cmakedefine HAVE_SIGNAL_H 1 | |||||
/* Define to 1 if you have the <stdarg.h> header file. */ | |||||
#cmakedefine HAVE_STDARG_H 1 | |||||
/* Define to 1 if you have the <stddef.h> header file. */ | |||||
#cmakedefine HAVE_STDDEF_H 1 | |||||
/* Define to 1 if you have the <stdint.h> header file. */ | |||||
#cmakedefine HAVE_STDINT_H 1 | |||||
/* Define to 1 if you have the <stdio.h> header file. */ | |||||
#cmakedefine HAVE_STDIO_H 1 | |||||
/* Define to 1 if you have the <stdlib.h> header file. */ | |||||
#cmakedefine HAVE_STDLIB_H 1 | |||||
/* Define to 1 if you have the <strings.h> header file. */ | |||||
#cmakedefine HAVE_STRINGS_H 1 | |||||
/* Define to 1 if you have the <string.h> header file. */ | |||||
#cmakedefine HAVE_STRING_H 1 | |||||
/* Define to 1 if you have the <sys/stat.h> header file. */ | |||||
#cmakedefine HAVE_SYS_STAT_H 1 | |||||
/* Define to 1 if you have the <sys/types.h> header file. */ | |||||
#cmakedefine HAVE_SYS_TYPES_H 1 | |||||
/* Define to 1 if you have the <time.h> header file. */ | |||||
#cmakedefine HAVE_TIME_H 1 | |||||
/* Define to 1 if you have the <unistd.h> header file. */ | |||||
#cmakedefine HAVE_UNISTD_H 1 | |||||
/**************************** STRUCTS ****************************/ | |||||
#cmakedefine HAVE_STRUCT_TIMESPEC 1 | |||||
/*************************** FUNCTIONS ***************************/ | |||||
/* Define to 1 if you have the `calloc' function. */ | |||||
#cmakedefine HAVE_CALLOC 1 | |||||
/* Define to 1 if you have the `exit' function. */ | |||||
#cmakedefine HAVE_EXIT 1 | |||||
/* Define to 1 if you have the `fprintf' function. */ | |||||
#cmakedefine HAVE_FPRINTF 1 | |||||
/* Define to 1 if you have the `snprintf' function. */ | |||||
#cmakedefine HAVE_SNPRINTF 1 | |||||
/* Define to 1 if you have the `_snprintf' function. */ | |||||
#cmakedefine HAVE__SNPRINTF 1 | |||||
/* Define to 1 if you have the `_snprintf_s' function. */ | |||||
#cmakedefine HAVE__SNPRINTF_S 1 | |||||
/* Define to 1 if you have the `vsnprintf' function. */ | |||||
#cmakedefine HAVE_VSNPRINTF 1 | |||||
/* Define to 1 if you have the `_vsnprintf' function. */ | |||||
#cmakedefine HAVE__VSNPRINTF 1 | |||||
/* Define to 1 if you have the `_vsnprintf_s' function. */ | |||||
#cmakedefine HAVE__VSNPRINTF_S 1 | |||||
/* Define to 1 if you have the `free' function. */ | |||||
#cmakedefine HAVE_FREE 1 | |||||
/* Define to 1 if you have the `longjmp' function. */ | |||||
#cmakedefine HAVE_LONGJMP 1 | |||||
/* Define to 1 if you have the `siglongjmp' function. */ | |||||
#cmakedefine HAVE_SIGLONGJMP 1 | |||||
/* Define to 1 if you have the `malloc' function. */ | |||||
#cmakedefine HAVE_MALLOC 1 | |||||
/* Define to 1 if you have the `memcpy' function. */ | |||||
#cmakedefine HAVE_MEMCPY 1 | |||||
/* Define to 1 if you have the `memset' function. */ | |||||
#cmakedefine HAVE_MEMSET 1 | |||||
/* Define to 1 if you have the `printf' function. */ | |||||
#cmakedefine HAVE_PRINTF 1 | |||||
/* Define to 1 if you have the `setjmp' function. */ | |||||
#cmakedefine HAVE_SETJMP 1 | |||||
/* Define to 1 if you have the `signal' function. */ | |||||
#cmakedefine HAVE_SIGNAL 1 | |||||
/* Define to 1 if you have the `snprintf' function. */ | |||||
#cmakedefine HAVE_SNPRINTF 1 | |||||
/* Define to 1 if you have the `strcmp' function. */ | |||||
#cmakedefine HAVE_STRCMP 1 | |||||
/* Define to 1 if you have the `strcpy' function. */ | |||||
#cmakedefine HAVE_STRCPY 1 | |||||
/* Define to 1 if you have the `vsnprintf' function. */ | |||||
#cmakedefine HAVE_VSNPRINTF 1 | |||||
/* Define to 1 if you have the `strsignal' function. */ | |||||
#cmakedefine HAVE_STRSIGNAL 1 | |||||
/* Define to 1 if you have the `clock_gettime' function. */ | |||||
#cmakedefine HAVE_CLOCK_GETTIME 1 | |||||
/**************************** OPTIONS ****************************/ | |||||
/* Check if we have TLS support with GCC */ | |||||
#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1 | |||||
/* Check if we have TLS support with MSVC */ | |||||
#cmakedefine HAVE_MSVC_THREAD_LOCAL_STORAGE 1 | |||||
/* Check if we have CLOCK_REALTIME for clock_gettime() */ | |||||
#cmakedefine HAVE_CLOCK_REALTIME 1 | |||||
/*************************** ENDIAN *****************************/ | |||||
#cmakedefine WORDS_SIZEOF_VOID_P ${WORDS_SIZEOF_VOID_P} | |||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most | |||||
significant byte first (like Motorola and SPARC, unlike Intel). */ | |||||
#cmakedefine WORDS_BIGENDIAN 1 |
@@ -0,0 +1,9 @@ | |||||
coverity_assert_model.c: | |||||
This file is a Coverity Modeling file for projects using CMocka for unit | |||||
testing. The assert functiions could create false positives, to avoid that you | |||||
can load this modeling file in the Coverity web interface. | |||||
coverity_internal_model.c: | |||||
This file is for the CMocka source code itself. |
@@ -0,0 +1,87 @@ | |||||
#define LargestIntegralType unsigned long long | |||||
void _assert_true(const LargestIntegralType result, | |||||
const char* const expression, | |||||
const char * const file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_int_equal( | |||||
const LargestIntegralType a, const LargestIntegralType b, | |||||
const char * const file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_int_not_equal( | |||||
const LargestIntegralType a, const LargestIntegralType b, | |||||
const char * const file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_return_code(const LargestIntegralType result, | |||||
size_t rlen, | |||||
const LargestIntegralType error, | |||||
const char * const expression, | |||||
const char * const file, | |||||
const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_string_equal(const char * const a, const char * const b, | |||||
const char * const file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_string_not_equal(const char * const a, const char * const b, | |||||
const char *file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_memory_equal(const void * const a, const void * const b, | |||||
const size_t size, const char* const file, | |||||
const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_memory_not_equal(const void * const a, const void * const b, | |||||
const size_t size, const char* const file, | |||||
const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_in_range( | |||||
const LargestIntegralType value, const LargestIntegralType minimum, | |||||
const LargestIntegralType maximum, const char* const file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_not_in_range( | |||||
const LargestIntegralType value, const LargestIntegralType minimum, | |||||
const LargestIntegralType maximum, const char* const file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_in_set( | |||||
const LargestIntegralType value, const LargestIntegralType values[], | |||||
const size_t number_of_values, const char* const file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
void _assert_not_in_set( | |||||
const LargestIntegralType value, const LargestIntegralType values[], | |||||
const size_t number_of_values, const char* const file, const int line) | |||||
{ | |||||
__coverity_panic__(); | |||||
} | |||||
@@ -0,0 +1,5 @@ | |||||
/* Functions to help coverity do static analysis on cmocka */ | |||||
void exit_test(const int quit_application) | |||||
{ | |||||
__coverity_panic__(); | |||||
} |
@@ -0,0 +1,5 @@ | |||||
# | |||||
# Build the documentation | |||||
# | |||||
include(UseDoxygen OPTIONAL) | |||||
@@ -0,0 +1,706 @@ | |||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> | |||||
<html><head> | |||||
<title>cmocka</title> | |||||
</head> | |||||
<body> | |||||
<h1>cmocka Unit Testing Framework</h1> | |||||
<p>cmocka is a lightweight library that is used to author C unit tests.</p> | |||||
<ul>Contents | |||||
<li><a href="#Motivation">Motivation</a></li> | |||||
<li><a href="#Overview">Overview</a></li> | |||||
<li><a href="#Test_Execution">Test Execution</a> | |||||
<li><a href="#Exception_Handling">Exception Handling</a></li> | |||||
<li><a href="#Failure_Conditions">Failure Conditions</a></li> | |||||
<li><a href="#Assertions">Assertions</a></li> | |||||
<ul> | |||||
<li><a href="#Assert_Macros">Assert Macros</a></li> | |||||
</ul> | |||||
<li><a href="#Dynamic_Memory_Allocation">Dynamic Memory Allocation</a></li> | |||||
<li><a href="#Mock_Functions">Mock functions</a></li> | |||||
<ul> | |||||
<li><a href="#Return_Values">Return Values</a></li> | |||||
<li><a href="#Checking_Parameters">Checking Parameters</a></li> | |||||
</ul> | |||||
<li><a href="#Test_State">Test State</a></li> | |||||
<li><a href="#Example">Example</a></li> | |||||
</ul> | |||||
<a name="Motivation"><h2>Motivation</h2></a> | |||||
<p>There are a variety of C unit testing frameworks available however many of | |||||
them are fairly complex and require the latest compiler technology. Some | |||||
development requires the use of old compilers which makes it difficult to | |||||
use some unit testing frameworks. In addition many unit testing frameworks | |||||
assume the code being tested is an application or module that is targeted to | |||||
the same platform that will ultimately execute the test. Because of this | |||||
assumption many frameworks require the inclusion of standard C library headers | |||||
in the code module being tested which may collide with the custom or | |||||
incomplete implementation of the C library utilized by the code under test.</p> | |||||
<p>cmocka only requires a test application is linked with the standard C | |||||
library which minimizes conflicts with standard C library headers. Also, | |||||
cmocka tries avoid the use of some of the newer features of C compilers.</p> | |||||
<p>This results in cmocka being a relatively small library that can be used | |||||
to test a variety of exotic code. If a developer wishes to simply test an | |||||
application with the latest compiler then other unit testing frameworks maybe | |||||
preferable.</p> | |||||
<a name="Overview"><h2>Overview</h2></a> | |||||
<p>cmocka tests are compiled into stand-alone executables and linked with | |||||
the cmocka library, the standard C library and module being tested. Any | |||||
symbols external to the module being tested should be mocked - replaced with | |||||
functions that return values determined by the test - within the test | |||||
application. Even though significant differences may exist between the target | |||||
execution environment of a code module and the environment used to test the | |||||
code the unit testing is still valid since its goal is to test the logic of a | |||||
code modules at a functional level and not necessarily all of its interactions | |||||
with the target execution environment.</p> | |||||
<p>It may not be possible to compile a module into a test application without | |||||
some modification, therefore the preprocessor symbol <b>UNIT_TESTING</b> should | |||||
be defined when cmocka unit test applications are compiled so code within the | |||||
module can be conditionally compiled for tests.</p> | |||||
<a name="Test_Execution"><h2>Test Execution</h2></a> | |||||
<p>cmocka unit test cases are functions with the signature | |||||
<b>void function(void **state)</b>. cmocka test applications initialize a | |||||
table with test case function pointers using <b>unit_test*()</b> macros. This | |||||
table is then passed to the <b>run_tests()</b> macro to execute the tests. | |||||
<b>run_tests()</b> sets up the appropriate exception / signal handlers and | |||||
other data structures prior to running each test function. When a unit test | |||||
is complete <b>run_tests()</b> performs various checks to determine whether | |||||
the test succeeded.</p> | |||||
<h4>Using run_tests()</h4> | |||||
<a href="../example/run_tests.c">run_tests.c</a> | |||||
<listing> | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
// A test case that does nothing and succeeds. | |||||
void null_test_success(void **state) { | |||||
} | |||||
int main(int argc, char* argv[]) { | |||||
const UnitTest tests[] = { | |||||
unit_test(null_test_success), | |||||
}; | |||||
return run_tests(tests); | |||||
} | |||||
</listing> | |||||
<a name="Exception_Handling"><h2>Exception Handling</h2></a> | |||||
<p>Before a test function is executed by <b>run_tests()</b>, | |||||
exception / signal handlers are overridden with a handler that simply | |||||
displays an error and exits a test function if an exception occurs. If an | |||||
exception occurs outside of a test function, for example in cmocka itself, | |||||
the application aborts execution and returns an error code.</p> | |||||
<a name="Failure_Conditions"><h2>Failure Conditions</h2></a> | |||||
<p>If a failure occurs during a test function that's executed via | |||||
<b>run_tests()</b>, the test function is aborted and the application's | |||||
execution resumes with the next test function. | |||||
Test failures are ultimately signalled via the cmocka function <b>fail()</b>. | |||||
The following events will result in the cmocka library signalling a test | |||||
failure... | |||||
<ul> | |||||
<li><a href="#Assertions">Assertions</a></li> | |||||
<li><a href="#Exception_Handling">Exceptions</a></li> | |||||
<li><a href="#Dynamic_Memory_Allocation">Memory leaks</a></li> | |||||
<li><a href="#Test_State">Mismatched setup and tear down functions</a></li> | |||||
<li><a href="#Return_Values">Missing mock return values</a></li> | |||||
<li><a href="#Return_Values">Unused mock return values</a></li> | |||||
<li><a href="#Checking_Parameters">Missing expected parameter values</a></li> | |||||
<li><a href="#Checking_Parameters">Unused expected parameter values</a></li> | |||||
</ul> | |||||
</p> | |||||
<a name="Assertions"><h2>Assertions</h2></a> | |||||
<p>Runtime assert macros like the standard C library's <b>assert()</b> should | |||||
be redefined in modules being tested to use cmocka's <b>mock_assert()</b> | |||||
function. Normally <b>mock_assert()</b> signals a | |||||
<a href="#Failure_Conditions">test failure</a>. If a function is called using | |||||
the <b>expect_assert_failure()</b> macro, any calls to <b>mock_assert()</b> | |||||
within the function will result in the execution of the test. If no | |||||
calls to <b>mock_assert()</b> occur during the function called via | |||||
<b>expect_assert_failure()</b> a test failure is signalled.</p> | |||||
<h4>Using mock_assert()</h4> | |||||
<a href="../example/assert_module.c">assert_module.c</a> | |||||
<listing> | |||||
#include <assert.h> | |||||
// If unit testing is enabled override assert with mock_assert(). | |||||
#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 // UNIT_TESTING | |||||
void increment_value(int * const value) { | |||||
assert(value); | |||||
(*value) ++; | |||||
} | |||||
void decrement_value(int * const value) { | |||||
if (value) { | |||||
*value --; | |||||
} | |||||
} | |||||
</listing> | |||||
<a href="../example/assert_module_test.c">assert_module_test.c</a> | |||||
<listing> | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
extern void increment_value(int * const value); | |||||
/* This test case will fail but the assert is caught by run_tests() and the | |||||
* next test is executed. */ | |||||
void increment_value_fail(void **state) { | |||||
increment_value(NULL); | |||||
} | |||||
// This test case succeeds since increment_value() asserts on the NULL pointer. | |||||
void increment_value_assert(void **state) { | |||||
expect_assert_failure(increment_value(NULL)); | |||||
} | |||||
/* This test case fails since decrement_value() doesn't assert on a NULL | |||||
* pointer. */ | |||||
void decrement_value_fail(void **state) { | |||||
expect_assert_failure(decrement_value(NULL)); | |||||
} | |||||
int main(int argc, char *argv[]) { | |||||
const UnitTest tests[] = { | |||||
unit_test(increment_value_fail), | |||||
unit_test(increment_value_assert), | |||||
unit_test(decrement_value_fail), | |||||
}; | |||||
return run_tests(tests); | |||||
} | |||||
</listing> | |||||
<h3><a name="Assert_Macros">Assert Macros</a></h3> | |||||
<p>cmocka provides an assortment of assert macros that tests applications | |||||
should use use in preference to the C standard library's assert macro. On an | |||||
assertion failure a cmocka assert macro will write the failure to the | |||||
standard error stream and signal a test failure. Due to limitations of the | |||||
C language the general C standard library assert() and cmocka's | |||||
assert_true() and assert_false() macros can only display the expression that | |||||
caused the assert failure. cmocka's type specific assert macros, | |||||
assert_{type}_equal() and assert_{type}_not_equal(), display the data that | |||||
caused the assertion failure which increases data visibility aiding | |||||
debugging of failing test cases.</p> | |||||
<h4>Using assert_{type}_equal() macros</h4> | |||||
<a href="../example/assert_macro.c">assert_macro.c</a> | |||||
<listing> | |||||
#include <string.h> | |||||
static const char* status_code_strings[] = { | |||||
"Address not found", | |||||
"Connection dropped", | |||||
"Connection timed out", | |||||
}; | |||||
const char* get_status_code_string(const unsigned int status_code) { | |||||
return status_code_strings[status_code]; | |||||
}; | |||||
unsigned int string_to_status_code(const char* const status_code_string) { | |||||
unsigned int i; | |||||
for (i = 0; i < sizeof(status_code_strings) / | |||||
sizeof(status_code_strings[0]); i++) { | |||||
if (strcmp(status_code_strings[i], status_code_string) == 0) { | |||||
return i; | |||||
} | |||||
} | |||||
return ~0U; | |||||
} | |||||
</listing> | |||||
<a href="../example/assert_macro_test.c">assert_macro_test.c</a> | |||||
<listing> | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
extern const char* get_status_code_string(const unsigned int status_code); | |||||
extern unsigned int string_to_status_code( | |||||
const char* const status_code_string); | |||||
/* This test will fail since the string returned by get_status_code_string(0) | |||||
* doesn't match "Connection timed out". */ | |||||
void get_status_code_string_test(void **state) { | |||||
assert_string_equal(get_status_code_string(0), "Address not found"); | |||||
assert_string_equal(get_status_code_string(1), "Connection timed out"); | |||||
} | |||||
// This test will fail since the status code of "Connection timed out" isn't 1 | |||||
void string_to_status_code_test(void **state) { | |||||
assert_int_equal(string_to_status_code("Address not found"), 0); | |||||
assert_int_equal(string_to_status_code("Connection timed out"), 1); | |||||
} | |||||
int main(int argc, char *argv[]) { | |||||
const UnitTest tests[] = { | |||||
unit_test(get_status_code_string_test), | |||||
unit_test(string_to_status_code_test), | |||||
}; | |||||
return run_tests(tests); | |||||
} | |||||
</listing> | |||||
<a name="Dynamic_Memory_Allocation"><h2>Dynamic Memory Allocation</h2></a> | |||||
<p>To test for memory leaks, buffer overflows and underflows a module being | |||||
tested by cmocka should replace calls to <b>malloc()</b>, <b>calloc()</b> and | |||||
<b>free()</b> to <b>test_malloc()</b>, <b>test_calloc()</b> and | |||||
<b>test_free()</b> respectively. Each time a block is deallocated using | |||||
<b>test_free()</b> it is checked for corruption, if a corrupt block is found | |||||
a <a href="#Failure_Conditions">test failure</a> is signalled. All blocks | |||||
allocated using the <b>test_*()</b> 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.</p> | |||||
<p>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.</p> | |||||
<h4>Using cmocka's Allocators</h4> | |||||
<a href="../example/allocate_module.c">allocate_module.c</a> | |||||
<listing> | |||||
#include <malloc.h> | |||||
#ifdef UNIT_TESTING | |||||
extern void* _test_malloc(const size_t size, const char* file, const int line); | |||||
extern void* _test_calloc(const size_t number_of_elements, const size_t size, | |||||
const char* file, const int line); | |||||
extern void _test_free(void* const ptr, const char* file, const int line); | |||||
#define malloc(size) _test_malloc(size, __FILE__, __LINE__) | |||||
#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) | |||||
#define free(ptr) _test_free(ptr, __FILE__, __LINE__) | |||||
#endif // UNIT_TESTING | |||||
void leak_memory() { | |||||
int * const temporary = (int*)malloc(sizeof(int)); | |||||
*temporary = 0; | |||||
} | |||||
void buffer_overflow() { | |||||
char * const memory = (char*)malloc(sizeof(int)); | |||||
memory[sizeof(int)] = '!'; | |||||
free(memory); | |||||
} | |||||
void buffer_underflow() { | |||||
char * const memory = (char*)malloc(sizeof(int)); | |||||
memory[-1] = '!'; | |||||
free(memory); | |||||
} | |||||
</listing> | |||||
<a href="../example/allocate_module_test.c">allocate_module_test.c</a> | |||||
<listing> | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
extern void leak_memory(); | |||||
extern void buffer_overflow(); | |||||
extern void buffer_underflow(); | |||||
// Test case that fails as leak_memory() leaks a dynamically allocated block. | |||||
void leak_memory_test(void **state) { | |||||
leak_memory(); | |||||
} | |||||
// Test case that fails as buffer_overflow() corrupts an allocated block. | |||||
void buffer_overflow_test(void **state) { | |||||
buffer_overflow(); | |||||
} | |||||
// Test case that fails as buffer_underflow() corrupts an allocated block. | |||||
void buffer_underflow_test(void **state) { | |||||
buffer_underflow(); | |||||
} | |||||
int main(int argc, char* argv[]) { | |||||
const UnitTest tests[] = { | |||||
unit_test(leak_memory_test), | |||||
unit_test(buffer_overflow_test), | |||||
unit_test(buffer_underflow_test), | |||||
}; | |||||
return run_tests(tests); | |||||
} | |||||
</listing> | |||||
<a name="Mock_Functions"><h2>Mock Functions</h2></a> | |||||
<p>A unit test should ideally isolate the function or module being tested | |||||
from any external dependencies. This can be performed using mock functions | |||||
that are either statically or dynamically linked with the module being tested. | |||||
Mock functions must be statically linked when the code being tested directly | |||||
references external functions. Dynamic linking is simply the process of | |||||
setting a function pointer in a table used by the tested module to reference | |||||
a mock function defined in the unit test.</p> | |||||
<a name="Return_Values"><h3>Return Values</h3></a> | |||||
<p>In order to simplify the implementation of mock functions cmocka provides | |||||
functionality which stores return values for mock functions in each test | |||||
case using <b>will_return()</b>. These values are then returned by each mock | |||||
function using calls to <b>mock()</b>. | |||||
Values passed to <b>will_return()</b> are added to a queue for each function | |||||
specified. Each successive call to <b>mock()</b> from a function removes a | |||||
return value from the queue. This makes it possible for a mock function to use | |||||
multiple calls to <b>mock()</b> to return output parameters in addition to a | |||||
return value. In addition this allows the specification of return values for | |||||
multiple calls to a mock function.</p> | |||||
<h4>Using will_return()</h4> | |||||
<a href="../example/database.h">database.h</a> | |||||
<listing> | |||||
typedef struct DatabaseConnection DatabaseConnection; | |||||
/* Function that takes an SQL query string and sets results to an array of | |||||
* pointers with the result of the query. The value returned specifies the | |||||
* number of items in the returned array of results. The returned array of | |||||
* results are statically allocated and should not be deallocated using free() | |||||
*/ | |||||
typedef unsigned int (*QueryDatabase)( | |||||
DatabaseConnection* const connection, const char * const query_string, | |||||
void *** const results); | |||||
// Connection to a database. | |||||
struct DatabaseConnection { | |||||
const char *url; | |||||
unsigned int port; | |||||
QueryDatabase query_database; | |||||
}; | |||||
// Connect to a database. | |||||
DatabaseConnection* connect_to_database(const char * const url, | |||||
const unsigned int port); | |||||
</listing> | |||||
<a href="../example/customer_database.c">customer_database.c</a> | |||||
<listing> | |||||
#include <stddef.h> | |||||
#include <stdio.h> | |||||
#include <database.h> | |||||
#ifdef _WIN32 | |||||
#define snprintf _snprintf | |||||
#endif // _WIN32 | |||||
// Connect to the database containing customer information. | |||||
DatabaseConnection* connect_to_customer_database() { | |||||
return connect_to_database("customers.abcd.org", 321); | |||||
} | |||||
/* Find the ID of a customer by his/her name returning a value > 0 if | |||||
* successful, 0 otherwise. */ | |||||
unsigned int get_customer_id_by_name( | |||||
DatabaseConnection * const connection, | |||||
const char * const customer_name) { | |||||
char query_string[256]; | |||||
int number_of_results; | |||||
void **results; | |||||
snprintf(query_string, sizeof(query_string), | |||||
"SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name); | |||||
number_of_results = connection->query_database(connection, query_string, | |||||
&results); | |||||
if (number_of_results != 1) { | |||||
return -1; | |||||
} | |||||
return (unsigned int)results[0]; | |||||
} | |||||
</listing> | |||||
<a href="../example/customer_database_test.c">customer_database_test.c</a> | |||||
<listing> | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <database.h> | |||||
extern DatabaseConnection* connect_to_customer_database(); | |||||
extern unsigned int get_customer_id_by_name( | |||||
DatabaseConnection * const connection, const char * const customer_name); | |||||
// Mock query database function. | |||||
unsigned int mock_query_database( | |||||
DatabaseConnection* const connection, const char * const query_string, | |||||
void *** const results) { | |||||
*results = (void**)mock(); | |||||
return (unsigned int)mock(); | |||||
} | |||||
// Mock of the connect to database function. | |||||
DatabaseConnection* connect_to_database(const char * const database_url, | |||||
const unsigned int port) { | |||||
return (DatabaseConnection*)mock(); | |||||
} | |||||
void test_connect_to_customer_database(void **state) { | |||||
will_return(connect_to_database, 0x0DA7ABA53); | |||||
assert_true(connect_to_customer_database() == | |||||
(DatabaseConnection*)0x0DA7ABA53); | |||||
} | |||||
/* This test fails as the mock function connect_to_database() will have no | |||||
* value to return. */ | |||||
void fail_connect_to_customer_database(void **state) { | |||||
will_return(connect_to_database, 0x0DA7ABA53); | |||||
assert_true(connect_to_customer_database() == | |||||
(DatabaseConnection*)0x0DA7ABA53); | |||||
} | |||||
void test_get_customer_id_by_name(void **state) { | |||||
DatabaseConnection connection = { | |||||
"somedatabase.somewhere.com", 12345678, mock_query_database | |||||
}; | |||||
// Return a single customer ID when mock_query_database() is called. | |||||
int customer_ids = 543; | |||||
will_return(mock_query_database, &customer_ids); | |||||
will_return(mock_query_database, 1); | |||||
assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543); | |||||
} | |||||
int main(int argc, char* argv[]) { | |||||
const UnitTest tests[] = { | |||||
unit_test(test_connect_to_customer_database), | |||||
unit_test(fail_connect_to_customer_database), | |||||
unit_test(test_get_customer_id_by_name), | |||||
}; | |||||
return run_tests(tests); | |||||
} | |||||
</listing> | |||||
<a name="Checking_Parameters"><h3>Checking Parameters</h3></a> | |||||
<p>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. | |||||
<p>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.</p> | |||||
<h4>Using expect_*()</h4> | |||||
<a href="../example/product_database.c">product_database.c</a> | |||||
<listing> | |||||
#include <database.h> | |||||
// Connect to the database containing customer information. | |||||
DatabaseConnection* connect_to_product_database() { | |||||
return connect_to_database("products.abcd.org", 322); | |||||
} | |||||
</listing> | |||||
<a href="../example/product_database_test.c">product_database_test.c</a> | |||||
<listing> | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <database.h> | |||||
extern DatabaseConnection* connect_to_product_database(); | |||||
/* Mock connect to database function. | |||||
* NOTE: This mock function is very general could be shared between tests | |||||
* that use the imaginary database.h module. */ | |||||
DatabaseConnection* connect_to_database(const char * const url, | |||||
const unsigned int port) { | |||||
check_expected(url); | |||||
check_expected(port); | |||||
return (DatabaseConnection*)mock(); | |||||
} | |||||
void test_connect_to_product_database(void **state) { | |||||
expect_string(connect_to_database, url, "products.abcd.org"); | |||||
expect_value(connect_to_database, port, 322); | |||||
will_return(connect_to_database, 0xDA7ABA53); | |||||
assert_int_equal(connect_to_product_database(), 0xDA7ABA53); | |||||
} | |||||
/* This test will fail since the expected URL is different to the URL that is | |||||
* passed to connect_to_database() by connect_to_product_database(). */ | |||||
void test_connect_to_product_database_bad_url(void **state) { | |||||
expect_string(connect_to_database, url, "products.abcd.com"); | |||||
expect_value(connect_to_database, port, 322); | |||||
will_return(connect_to_database, 0xDA7ABA53); | |||||
assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53); | |||||
} | |||||
/* This test will fail since the mock connect_to_database() will attempt to | |||||
* retrieve a value for the parameter port which isn't specified by this | |||||
* test function. */ | |||||
void test_connect_to_product_database_missing_parameter(void **state) { | |||||
expect_string(connect_to_database, url, "products.abcd.org"); | |||||
will_return(connect_to_database, 0xDA7ABA53); | |||||
assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53); | |||||
} | |||||
int main(int argc, char* argv[]) { | |||||
const UnitTest tests[] = { | |||||
unit_test(test_connect_to_product_database), | |||||
unit_test(test_connect_to_product_database_bad_url), | |||||
unit_test(test_connect_to_product_database_missing_parameter), | |||||
}; | |||||
return run_tests(tests); | |||||
} | |||||
</listing> | |||||
<a name="Test_State"><h2>Test State</h2></a> | |||||
<p>cmocka allows the specification of multiple setup and tear down functions | |||||
for each test case. Setup functions, specified by the <b>unit_test_setup()</b> | |||||
or <b>unit_test_setup_teardown()</b> macros allow common initialization to be | |||||
shared between multiple test cases. In addition, tear down functions, | |||||
specified by the <b>unit_test_teardown()</b> or | |||||
<b>unit_test_setup_teardown()</b> macros provide a code path that is always | |||||
executed for a test case even when it fails.</p> | |||||
<h4>Using unit_test_setup_teardown()</h4> | |||||
<a href="../example/key_value.c">key_value.c</a> | |||||
<listing> | |||||
#include <stddef.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
typedef struct KeyValue { | |||||
unsigned int key; | |||||
const char* value; | |||||
} KeyValue; | |||||
static KeyValue *key_values = NULL; | |||||
static unsigned int number_of_key_values = 0; | |||||
void set_key_values(KeyValue * const new_key_values, | |||||
const unsigned int new_number_of_key_values) { | |||||
key_values = new_key_values; | |||||
number_of_key_values = new_number_of_key_values; | |||||
} | |||||
// Compare two key members of KeyValue structures. | |||||
int key_value_compare_keys(const void *a, const void *b) { | |||||
return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key; | |||||
} | |||||
// Search an array of key value pairs for the item with the specified value. | |||||
KeyValue* find_item_by_value(const char * const value) { | |||||
unsigned int i; | |||||
for (i = 0; i < number_of_key_values; i++) { | |||||
if (strcmp(key_values[i].value, value) == 0) { | |||||
return &key_values[i]; | |||||
} | |||||
} | |||||
return NULL; | |||||
} | |||||
// Sort an array of key value pairs by key. | |||||
void sort_items_by_key() { | |||||
qsort(key_values, number_of_key_values, sizeof(*key_values), | |||||
key_value_compare_keys); | |||||
} | |||||
</listing> | |||||
<a href="../example/key_value_test.c">key_value_test.c</a> | |||||
<listing> | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <string.h> | |||||
#include <cmocka.h> | |||||
/* This is duplicated here from the module setup_teardown.c to reduce the | |||||
* number of files used in this test. */ | |||||
typedef struct KeyValue { | |||||
unsigned int key; | |||||
const char* value; | |||||
} KeyValue; | |||||
void set_key_values(KeyValue * const new_key_values, | |||||
const unsigned int new_number_of_key_values); | |||||
extern KeyValue* find_item_by_value(const char * const value); | |||||
extern void sort_items_by_key(); | |||||
static KeyValue key_values[] = { | |||||
{ 10, "this" }, | |||||
{ 52, "test" }, | |||||
{ 20, "a" }, | |||||
{ 13, "is" }, | |||||
}; | |||||
void create_key_values(void **state) { | |||||
KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values)); | |||||
memcpy(items, key_values, sizeof(key_values)); | |||||
*state = (void*)items; | |||||
set_key_values(items, sizeof(key_values) / sizeof(key_values[0])); | |||||
} | |||||
void destroy_key_values(void **state) { | |||||
test_free(*state); | |||||
set_key_values(NULL, 0); | |||||
} | |||||
void test_find_item_by_value(void **state) { | |||||
unsigned int i; | |||||
for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) { | |||||
KeyValue * const found = find_item_by_value(key_values[i].value); | |||||
assert_true(found); | |||||
assert_int_equal(found->key, key_values[i].key); | |||||
assert_string_equal(found->value, key_values[i].value); | |||||
} | |||||
} | |||||
void test_sort_items_by_key(void **state) { | |||||
unsigned int i; | |||||
KeyValue * const kv = *state; | |||||
sort_items_by_key(); | |||||
for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) { | |||||
assert_true(kv[i - 1].key < kv[i].key); | |||||
} | |||||
} | |||||
int main(int argc, char* argv[]) { | |||||
const UnitTest tests[] = { | |||||
unit_test_setup_teardown(test_find_item_by_value, create_key_values, | |||||
destroy_key_values), | |||||
unit_test_setup_teardown(test_sort_items_by_key, create_key_values, | |||||
destroy_key_values), | |||||
}; | |||||
return run_tests(tests); | |||||
} | |||||
</listing> | |||||
<a name="Example"><h2>Example</h2></a> | |||||
<p>A small command line calculator | |||||
<a href="../example/calculator.c">calculator.c</a> application | |||||
and test application that full exercises the calculator application | |||||
<a href="../example/calculator_test.c">calculator_test.c</a> | |||||
are provided as an example of cmocka's features discussed in this document. | |||||
</p> | |||||
<hr> | |||||
<address></address> | |||||
<!-- hhmts start --> Last modified: Wed Jul 22 12:11:43 PDT 2009 <!-- hhmts end --> | |||||
</body> </html> |
@@ -0,0 +1,133 @@ | |||||
/** | |||||
@mainpage | |||||
This is the online reference for developing with the cmocka library. It | |||||
documents the cmocka C API. | |||||
cmocka is an elegant unit testing framework for C with support for mock | |||||
objects. It only requires the standard C library, works on a lot of platforms | |||||
(including embedded) and with different compilers. | |||||
http://cmocka.org/ | |||||
@section main-features Features | |||||
Tests written with cmocka are compiled into stand-alone executables and linked with the | |||||
CMock library, the standard C library and module being tested. Any symbols | |||||
external to the module being tested should be mocked - replaced with functions | |||||
that return values determined by the test - within the test application. Even | |||||
though significant differences may exist between the target execution | |||||
environment of a code module and the environment used to test the code the unit | |||||
testing is still valid since its goal is to test the logic of a code modules at | |||||
a functional level and not necessarily all of its interactions with the target | |||||
execution environment. | |||||
The CMocka library provides: | |||||
- Support for mock objects. | |||||
- Test fixtures. | |||||
- Only requires a C library | |||||
- Exception handling for signals (SIGSEGV, SIGILL, ...) | |||||
- No use of fork() | |||||
- Very well tested | |||||
- Testing of memory leaks, buffer overflows and underflows. | |||||
- A set of assert macros. | |||||
- Several supported output formats (stdout, TAP, xUnit XML, Subunit) | |||||
- License: Apache License 2.0 | |||||
@section main-test A cmocka test | |||||
Test cases are functions with the signature void function(void **state). Test | |||||
applications initialize a table with test case function pointers using | |||||
unit_test() macros. This table is then passed to the run_tests() macro to | |||||
execute the tests. run_tests() sets up the appropriate exception / signal | |||||
handlers and other data structures prior to running each test function. When a | |||||
unit test is complete run_tests() performs various checks to determine whether | |||||
the test succeeded. | |||||
@code | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
/* A test case that does nothing and succeeds. */ | |||||
static void null_test_success(void **state) { | |||||
(void) state; /* unused */ | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(null_test_success), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} | |||||
@endcode | |||||
@section main-mock Mock objects | |||||
You may already have heard the term "Mock Object". It describes a special case | |||||
of an object that mimics a real instance of an interface in order to provide | |||||
enough of that interface for testing. While there are several unit testing | |||||
frameworks that already provide some easy to use interface for creating | |||||
different kinds of "fake" objects for testing, there may be some confusion in | |||||
terms of how these test objects are programmed and what the behavioral | |||||
differences are between them. | |||||
Mock objects include some logic and the test driver is able to modify the | |||||
behaviour and state. The object can call some functions or act on different | |||||
input (abort a test if it is wrong). The test driver injects what it expects | |||||
the mock object to return. CMocka provides and API to easily mock code. | |||||
<a href="https://lwn.net/Articles/558106/">Learn more ...</a> | |||||
@section main-embedded Embedded platforms | |||||
It is possible that some embedded platforms do not provide definitions for | |||||
required types or that the guards to protect them are not defined. To address | |||||
this issue you can create a header file name 'cmocka_platform.h' with the | |||||
required types and definitions. After that point cmake to the include directory | |||||
using: | |||||
<pre> | |||||
cmake -DCMOCKA_PLATFORM_INCLUDE=/home/compiler/my/include_directory .. | |||||
</pre> | |||||
@section main-threads Threading | |||||
cmocka is not fully thread safe and it is not the goal of it to be it. We have | |||||
several global variables to track test states. They are marked as thread local | |||||
but it is possible that you still run into issues. However if you use cmocka | |||||
for writing tests in an application which uses threads, you can set the | |||||
following envionment variable: | |||||
<pre> | |||||
CMOCKA_TEST_ABORT='1' ./my_threading_test | |||||
</pre> | |||||
With this environment variable set to '1', cmocka will call <tt>abort()</tt> if | |||||
a test fails. | |||||
@section main-output Output formats | |||||
By default, cmocka prints human-readable test output to stderr. It is | |||||
possible to configure several other output formats. The configuration is | |||||
done using the <tt>CMOCKA_MESSAGE_OUTPUT</tt> environment variable. The | |||||
supported values are: | |||||
- <tt>STDOUT</tt> for the default standard output printer | |||||
- <tt>SUBUNIT</tt> for subunit output | |||||
- <tt>TAP</tt> for Test Anything Protocol (TAP) output | |||||
- <tt>XML</tt> for xUnit XML format | |||||
The case doesn't matter. | |||||
The XML output goes to stderr by default. If the environment variable | |||||
<tt>CMOCKA_XML_FILE</tt> exists and the file specified by this variable | |||||
doesn't exist yet, then cmocka will put the output to this file. Note | |||||
that if you are have several groups you should set <tt>CMOCKA_XML_FILE</tt> | |||||
to <tt>CMOCKA_XML_FILE=cm_%%g.xml</tt>. In this %g will be replaced by | |||||
the group_name of the test and a file will be created for each group, | |||||
othwerwise all groups will be printed into the same file. | |||||
*/ |
@@ -0,0 +1,140 @@ | |||||
project(cmocka-examples C) | |||||
include_directories( | |||||
${CMAKE_BINARY_DIR} | |||||
${CMAKE_CURRENT_SOURCE_DIR} | |||||
${CMOCKA_PUBLIC_INCLUDE_DIRS} | |||||
) | |||||
set_source_files_properties( | |||||
calculator.c | |||||
allocate_module.c | |||||
assert_module.c | |||||
PROPERTIES | |||||
COMPILE_DEFINITIONS UNIT_TESTING=1) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set(CMOCKA_DLL_LIB ${CMAKE_BINARY_DIR}/src) | |||||
file(TO_NATIVE_PATH "${CMOCKA_DLL_PATH}" CMOCKA_DLL_PATH) | |||||
set(DLL_PATH_ENV "${CMOCKA_DLL_PATH};$ENV{PATH}") | |||||
# | |||||
# IMPORTANT NOTE: The set_tests_properties(), below, internally | |||||
# stores its name/value pairs with a semicolon delimiter. | |||||
# because of this we must protect the semicolons in the path | |||||
# | |||||
string(REPLACE ";" "\\;" DLL_PATH_ENV "${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
### The most simple test | |||||
add_executable(simple_test simple_test.c) | |||||
target_link_libraries(simple_test ${CMOCKA_SHARED_LIBRARY}) | |||||
add_test(simple_test ${CMAKE_CURRENT_BINARY_DIR}/simple_test) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties(simple_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
### Calulator test | |||||
#TODO investigate dll jmp issue on MinGW | |||||
if (NOT MINGW OR WITH_STATIC_LIB) | |||||
add_executable(calculator_test calculator.c calculator_test.c) | |||||
add_test(calculator_test ${CMAKE_CURRENT_BINARY_DIR}/calculator_test) | |||||
if (WIN32 OR CYGWIN) | |||||
set_tests_properties(calculator_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN) | |||||
if (MINGW) | |||||
target_link_libraries(calculator_test ${CMOCKA_STATIC_LIBRARY}) | |||||
else (MINGW) | |||||
target_link_libraries(calculator_test ${CMOCKA_SHARED_LIBRARY}) | |||||
endif (MINGW) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties(calculator_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
endif (NOT MINGW OR WITH_STATIC_LIB) | |||||
### Allocate module test | |||||
add_executable(allocate_module_test allocate_module.c allocate_module_test.c) | |||||
target_link_libraries(allocate_module_test ${CMOCKA_SHARED_LIBRARY}) | |||||
# This is a test that should detect leaks and overflows and will fail for that | |||||
add_test(allocate_module_test ${CMAKE_CURRENT_BINARY_DIR}/allocate_module_test) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties(allocate_module_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties( | |||||
allocate_module_test | |||||
PROPERTIES | |||||
WILL_FAIL 1 | |||||
) | |||||
### Assert macro test | |||||
add_executable(assert_macro_test assert_macro.c assert_macro_test.c) | |||||
target_link_libraries(assert_macro_test ${CMOCKA_SHARED_LIBRARY}) | |||||
add_test(assert_macro_test ${CMAKE_CURRENT_BINARY_DIR}/assert_macro_test) | |||||
set_tests_properties( | |||||
assert_macro_test | |||||
PROPERTIES | |||||
WILL_FAIL 1 | |||||
) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties(assert_macro_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
### Assert module test | |||||
add_executable(assert_module_test assert_module.c assert_module_test.c) | |||||
target_link_libraries(assert_module_test ${CMOCKA_SHARED_LIBRARY}) | |||||
add_test(assert_module_test ${CMAKE_CURRENT_BINARY_DIR}/assert_module_test) | |||||
set_tests_properties( | |||||
assert_module_test | |||||
PROPERTIES | |||||
WILL_FAIL 1 | |||||
) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties(assert_module_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
### Customer database test | |||||
add_executable(customer_database_test customer_database.c customer_database_test.c) | |||||
target_link_libraries(customer_database_test ${CMOCKA_SHARED_LIBRARY}) | |||||
add_test(customer_database_test ${CMAKE_CURRENT_BINARY_DIR}/customer_database_test) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties(customer_database_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
### Key Value Test | |||||
add_executable(key_value_test key_value.c key_value_test.c) | |||||
target_link_libraries(key_value_test ${CMOCKA_SHARED_LIBRARY}) | |||||
add_test(key_value_test ${CMAKE_CURRENT_BINARY_DIR}/key_value_test) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties(key_value_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
### Product database test | |||||
add_executable(product_database_test product_database.c product_database_test.c) | |||||
target_link_libraries(product_database_test ${CMOCKA_SHARED_LIBRARY}) | |||||
add_test(product_database_test ${CMAKE_CURRENT_BINARY_DIR}/product_database_test) | |||||
set_tests_properties( | |||||
product_database_test | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ FAILED \\] 2 test" | |||||
) | |||||
if (WIN32 OR CYGWIN OR MINGW) | |||||
set_tests_properties(product_database_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR CYGWIN OR MINGW) | |||||
# TODO Execute "$CMAKE_LINKER --help" and check for --wrap | |||||
if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)" AND NOT APPLE) | |||||
add_subdirectory(chef_wrap) | |||||
endif() |
@@ -0,0 +1,55 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#ifdef HAVE_MALLOC_H | |||||
#include <malloc.h> | |||||
#endif | |||||
#include <sys/types.h> | |||||
#include <stdlib.h> | |||||
#ifdef UNIT_TESTING | |||||
extern void* _test_malloc(const size_t size, const char* file, const int line); | |||||
extern void* _test_calloc(const size_t number_of_elements, const size_t size, | |||||
const char* file, const int line); | |||||
extern void _test_free(void* const ptr, const char* file, const int line); | |||||
#define malloc(size) _test_malloc(size, __FILE__, __LINE__) | |||||
#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) | |||||
#define free(ptr) _test_free(ptr, __FILE__, __LINE__) | |||||
#endif // UNIT_TESTING | |||||
void leak_memory(void); | |||||
void buffer_overflow(void); | |||||
void buffer_underflow(void); | |||||
void leak_memory(void) { | |||||
int * const temporary = (int*)malloc(sizeof(int)); | |||||
*temporary = 0; | |||||
} | |||||
void buffer_overflow(void) { | |||||
char * const memory = (char*)malloc(sizeof(int)); | |||||
memory[sizeof(int)] = '!'; | |||||
free(memory); | |||||
} | |||||
void buffer_underflow(void) { | |||||
char * const memory = (char*)malloc(sizeof(int)); | |||||
memory[-1] = '!'; | |||||
free(memory); | |||||
} |
@@ -0,0 +1,53 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
extern void leak_memory(void); | |||||
extern void buffer_overflow(void); | |||||
extern void buffer_underflow(void); | |||||
/* Test case that fails as leak_memory() leaks a dynamically allocated block. */ | |||||
static void leak_memory_test(void **state) { | |||||
(void) state; /* unused */ | |||||
leak_memory(); | |||||
} | |||||
/* Test case that fails as buffer_overflow() corrupts an allocated block. */ | |||||
static void buffer_overflow_test(void **state) { | |||||
(void) state; /* unused */ | |||||
buffer_overflow(); | |||||
} | |||||
/* Test case that fails as buffer_underflow() corrupts an allocated block. */ | |||||
static void buffer_underflow_test(void **state) { | |||||
(void) state; /* unused */ | |||||
buffer_underflow(); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(leak_memory_test), | |||||
cmocka_unit_test(buffer_overflow_test), | |||||
cmocka_unit_test(buffer_underflow_test), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,39 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <string.h> | |||||
#include "assert_macro.h" | |||||
static const char* status_code_strings[] = { | |||||
"Address not found", | |||||
"Connection dropped", | |||||
"Connection timed out", | |||||
}; | |||||
const char* get_status_code_string(const unsigned int status_code) { | |||||
return status_code_strings[status_code]; | |||||
} | |||||
unsigned int string_to_status_code(const char* const status_code_string) { | |||||
unsigned int i; | |||||
for (i = 0; i < sizeof(status_code_strings) / | |||||
sizeof(status_code_strings[0]); i++) { | |||||
if (strcmp(status_code_strings[i], status_code_string) == 0) { | |||||
return i; | |||||
} | |||||
} | |||||
return ~0U; | |||||
} |
@@ -0,0 +1,2 @@ | |||||
const char* get_status_code_string(const unsigned int status_code); | |||||
unsigned int string_to_status_code(const char* const status_code_string); |
@@ -0,0 +1,46 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include "assert_macro.h" | |||||
/* This test will fail since the string returned by get_status_code_string(0) | |||||
* doesn't match "Connection timed out". */ | |||||
static void get_status_code_string_test(void **state) { | |||||
(void) state; /* unused */ | |||||
assert_string_equal(get_status_code_string(0), "Address not found"); | |||||
assert_string_equal(get_status_code_string(1), "Connection timed out"); | |||||
} | |||||
/* This test will fail since the status code of "Connection timed out" isn't 1 */ | |||||
static void string_to_status_code_test(void **state) { | |||||
(void) state; /* unused */ | |||||
assert_int_equal(string_to_status_code("Address not found"), 0); | |||||
assert_int_equal(string_to_status_code("Connection timed out"), 1); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(get_status_code_string_test), | |||||
cmocka_unit_test(string_to_status_code_test), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,38 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <assert.h> | |||||
#include "assert_module.h" | |||||
/* If unit testing is enabled override assert with mock_assert(). */ | |||||
#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(((expression) ? 1 : 0), #expression, __FILE__, __LINE__); | |||||
#endif /* UNIT_TESTING */ | |||||
void increment_value(int * const value) { | |||||
assert(value); | |||||
(*value) ++; | |||||
} | |||||
void decrement_value(int * const value) { | |||||
if (value) { | |||||
(*value) --; | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
void increment_value(int * const value); | |||||
void decrement_value(int * const value); |
@@ -0,0 +1,56 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include "assert_module.h" | |||||
extern void increment_value(int * const value); | |||||
/* This test case will fail but the assert is caught by run_tests() and the | |||||
* next test is executed. */ | |||||
static void increment_value_fail(void **state) { | |||||
(void) state; | |||||
increment_value(NULL); | |||||
} | |||||
/* This test case succeeds since increment_value() asserts on the NULL | |||||
* pointer. */ | |||||
static void increment_value_assert(void **state) { | |||||
(void) state; | |||||
expect_assert_failure(increment_value(NULL)); | |||||
} | |||||
/* This test case fails since decrement_value() doesn't assert on a NULL | |||||
* pointer. */ | |||||
static void decrement_value_fail(void **state) { | |||||
(void) state; | |||||
expect_assert_failure(decrement_value(NULL)); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(increment_value_fail), | |||||
cmocka_unit_test(increment_value_assert), | |||||
cmocka_unit_test(decrement_value_fail), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,286 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
/* A calculator example used to demonstrate the cmocka testing library. */ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <assert.h> | |||||
#ifdef HAVE_MALLOC_H | |||||
#include <malloc.h> | |||||
#endif | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
/* If this is being built for a unit test. */ | |||||
#ifdef UNIT_TESTING | |||||
/* Redirect printf to a function in the test application so it's possible to | |||||
* test the standard output. */ | |||||
#ifdef printf | |||||
#undef printf | |||||
#endif /* printf */ | |||||
extern int example_test_printf(const char *format, ...); | |||||
#define printf example_test_printf | |||||
extern void print_message(const char *format, ...); | |||||
/* Redirect fprintf to a function in the test application so it's possible to | |||||
* test error messages. */ | |||||
#ifdef fprintf | |||||
#undef fprintf | |||||
#endif /* fprintf */ | |||||
#define fprintf example_test_fprintf | |||||
extern int example_test_fprintf(FILE * const file, const char *format, ...); | |||||
/* Redirect assert to mock_assert() so assertions can be caught by cmocka. */ | |||||
#ifdef assert | |||||
#undef assert | |||||
#endif /* assert */ | |||||
#define assert(expression) \ | |||||
mock_assert((int)(expression), #expression, __FILE__, __LINE__) | |||||
void mock_assert(const int result, const char* expression, const char *file, | |||||
const int line); | |||||
/* Redirect calloc and free to test_calloc() and test_free() so cmocka can | |||||
* check for memory leaks. */ | |||||
#ifdef calloc | |||||
#undef calloc | |||||
#endif /* calloc */ | |||||
#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) | |||||
#ifdef free | |||||
#undef free | |||||
#endif /* free */ | |||||
#define free(ptr) _test_free(ptr, __FILE__, __LINE__) | |||||
void* _test_calloc(const size_t number_of_elements, const size_t size, | |||||
const char* file, const int line); | |||||
void _test_free(void* const ptr, const char* file, const int line); | |||||
int example_main(int argc, char *argv[]); | |||||
/* main is defined in the unit test so redefine name of the the main function | |||||
* here. */ | |||||
#define main example_main | |||||
/* All functions in this object need to be exposed to the test application, | |||||
* so redefine static to nothing. */ | |||||
#define static | |||||
#endif /* UNIT_TESTING */ | |||||
/* A binary arithmetic integer operation (add, subtract etc.) */ | |||||
typedef int (*BinaryOperator)(int a, int b); | |||||
/* Structure which maps operator strings to functions. */ | |||||
typedef struct OperatorFunction { | |||||
const char* operator; | |||||
BinaryOperator function; | |||||
} OperatorFunction; | |||||
BinaryOperator find_operator_function_by_string( | |||||
const size_t number_of_operator_functions, | |||||
const OperatorFunction * const operator_functions, | |||||
const char* const operator_string); | |||||
int perform_operation( | |||||
int number_of_arguments, char *arguments[], | |||||
const size_t number_of_operator_functions, | |||||
const OperatorFunction * const operator_functions, | |||||
int * const number_of_intermediate_values, | |||||
int ** const intermediate_values, int * const error_occurred); | |||||
static int add(int a, int b); | |||||
static int subtract(int a, int b); | |||||
static int multiply(int a, int b); | |||||
static int divide(int a, int b); | |||||
/* Associate operator strings to functions. */ | |||||
static OperatorFunction operator_function_map[] = { | |||||
{"+", add}, | |||||
{"-", subtract}, | |||||
{"*", multiply}, | |||||
{"/", divide}, | |||||
}; | |||||
static int add(int a, int b) { | |||||
return a + b; | |||||
} | |||||
static int subtract(int a, int b) { | |||||
return a - b; | |||||
} | |||||
static int multiply(int a, int b) { | |||||
return a * b; | |||||
} | |||||
static int divide(int a, int b) { | |||||
assert(b); /* Check for divide by zero. */ | |||||
return a / b; | |||||
} | |||||
/* Searches the specified array of operator_functions for the function | |||||
* associated with the specified operator_string. This function returns the | |||||
* function associated with operator_string if successful, NULL otherwise. | |||||
*/ | |||||
BinaryOperator find_operator_function_by_string( | |||||
const size_t number_of_operator_functions, | |||||
const OperatorFunction * const operator_functions, | |||||
const char* const operator_string) { | |||||
size_t i; | |||||
assert(!number_of_operator_functions || operator_functions); | |||||
assert(operator_string != NULL); | |||||
for (i = 0; i < number_of_operator_functions; i++) { | |||||
const OperatorFunction *const operator_function = | |||||
&operator_functions[i]; | |||||
if (strcmp(operator_function->operator, operator_string) == 0) { | |||||
return operator_function->function; | |||||
} | |||||
} | |||||
return NULL; | |||||
} | |||||
/* Perform a series of binary arithmetic integer operations with no operator | |||||
* precedence. | |||||
* | |||||
* The input expression is specified by arguments which is an array of | |||||
* containing number_of_arguments strings. Operators invoked by the expression | |||||
* are specified by the array operator_functions containing | |||||
* number_of_operator_functions, OperatorFunction structures. The value of | |||||
* each binary operation is stored in a pointer returned to intermediate_values | |||||
* which is allocated by malloc(). | |||||
* | |||||
* If successful, this function returns the integer result of the operations. | |||||
* If an error occurs while performing the operation error_occurred is set to | |||||
* 1, the operation is aborted and 0 is returned. | |||||
*/ | |||||
int perform_operation( | |||||
int number_of_arguments, char *arguments[], | |||||
const size_t number_of_operator_functions, | |||||
const OperatorFunction * const operator_functions, | |||||
int * const number_of_intermediate_values, | |||||
int ** const intermediate_values, int * const error_occurred) { | |||||
char *end_of_integer; | |||||
int value; | |||||
int i; | |||||
assert(!number_of_arguments || arguments); | |||||
assert(!number_of_operator_functions || operator_functions); | |||||
assert(error_occurred != NULL); | |||||
assert(number_of_intermediate_values != NULL); | |||||
assert(intermediate_values != NULL); | |||||
*error_occurred = 0; | |||||
*number_of_intermediate_values = 0; | |||||
*intermediate_values = NULL; | |||||
if (!number_of_arguments) | |||||
return 0; | |||||
/* Parse the first value. */ | |||||
value = (int)strtol(arguments[0], &end_of_integer, 10); | |||||
if (end_of_integer == arguments[0]) { | |||||
/* If an error occurred while parsing the integer. */ | |||||
fprintf(stderr, "Unable to parse integer from argument %s\n", | |||||
arguments[0]); | |||||
*error_occurred = 1; | |||||
return 0; | |||||
} | |||||
/* Allocate an array for the output values. */ | |||||
*intermediate_values = calloc(((number_of_arguments - 1) / 2), | |||||
sizeof(**intermediate_values)); | |||||
i = 1; | |||||
while (i < number_of_arguments) { | |||||
int other_value; | |||||
const char* const operator_string = arguments[i]; | |||||
const BinaryOperator function = find_operator_function_by_string( | |||||
number_of_operator_functions, operator_functions, operator_string); | |||||
int * const intermediate_value = | |||||
&((*intermediate_values)[*number_of_intermediate_values]); | |||||
(*number_of_intermediate_values) ++; | |||||
if (!function) { | |||||
fprintf(stderr, "Unknown operator %s, argument %d\n", | |||||
operator_string, i); | |||||
*error_occurred = 1; | |||||
break; | |||||
} | |||||
i ++; | |||||
if (i == number_of_arguments) { | |||||
fprintf(stderr, "Binary operator %s missing argument\n", | |||||
operator_string); | |||||
*error_occurred = 1; | |||||
break; | |||||
} | |||||
other_value = (int)strtol(arguments[i], &end_of_integer, 10); | |||||
if (end_of_integer == arguments[i]) { | |||||
/* If an error occurred while parsing the integer. */ | |||||
fprintf(stderr, "Unable to parse integer %s of argument %d\n", | |||||
arguments[i], i); | |||||
*error_occurred = 1; | |||||
break; | |||||
} | |||||
i ++; | |||||
/* Perform the operation and store the intermediate value. */ | |||||
*intermediate_value = function(value, other_value); | |||||
value = *intermediate_value; | |||||
} | |||||
if (*error_occurred) { | |||||
free(*intermediate_values); | |||||
*intermediate_values = NULL; | |||||
*number_of_intermediate_values = 0; | |||||
return 0; | |||||
} | |||||
return value; | |||||
} | |||||
int main(int argc, char *argv[]) { | |||||
int return_value; | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values; | |||||
/* Peform the operation. */ | |||||
const int result = perform_operation( | |||||
argc - 1, &argv[1], | |||||
sizeof(operator_function_map) / sizeof(operator_function_map[0]), | |||||
operator_function_map, &number_of_intermediate_values, | |||||
&intermediate_values, &return_value); | |||||
/* If no errors occurred display the result. */ | |||||
if (!return_value && argc > 1) { | |||||
int i; | |||||
int intermediate_value_index = 0; | |||||
printf("%s\n", argv[1]); | |||||
for (i = 2; i < argc; i += 2) { | |||||
assert(intermediate_value_index < number_of_intermediate_values); | |||||
printf(" %s %s = %d\n", argv[i], argv[i + 1], | |||||
intermediate_values[intermediate_value_index++]); | |||||
} | |||||
printf("= %d\n", result); | |||||
} | |||||
if (intermediate_values) { | |||||
free(intermediate_values); | |||||
} | |||||
return return_value; | |||||
} |
@@ -0,0 +1,482 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include "cmocka.h" | |||||
#include <stdio.h> | |||||
#ifdef _WIN32 | |||||
/* Compatibility with the Windows standard C library. */ | |||||
#define vsnprintf _vsnprintf | |||||
#endif /* _WIN32 */ | |||||
#define array_length(x) (sizeof(x) / sizeof((x)[0])) | |||||
/* To simplify this code, these functions and data structures could have been | |||||
* separated out from the application example.c into a header shared with | |||||
* test application. However, this example illustrates how it's possible to | |||||
* test existing code with little modification. */ | |||||
typedef int (*BinaryOperator)(int a, int b); | |||||
typedef struct OperatorFunction { | |||||
const char* operator; | |||||
BinaryOperator function; | |||||
} OperatorFunction; | |||||
extern int add(int a, int b); | |||||
extern int subtract(int a, int b); | |||||
extern int multiply(int a, int b); | |||||
extern int divide(int a, int b); | |||||
extern BinaryOperator find_operator_function_by_string( | |||||
const size_t number_of_operator_functions, | |||||
const OperatorFunction * const operator_functions, | |||||
const char* const operator_string); | |||||
extern int perform_operation( | |||||
int number_of_arguments, char *arguments[], | |||||
const size_t number_of_operator_functions, | |||||
const OperatorFunction * const operator_functions, | |||||
int * const number_of_intermediate_values, | |||||
int ** const intermediate_values, int * const error_occurred); | |||||
extern int example_main(int argc, char *argv[]); | |||||
int example_test_fprintf(FILE* const file, const char *format, ...) CMOCKA_PRINTF_ATTRIBUTE(2, 3); | |||||
int example_test_printf(const char *format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); | |||||
static char temporary_buffer[256]; | |||||
/* A mock fprintf function that checks the value of strings printed to the | |||||
* standard error stream. */ | |||||
int example_test_fprintf(FILE* const file, const char *format, ...) { | |||||
int return_value; | |||||
va_list args; | |||||
assert_true(file == stderr); | |||||
va_start(args, format); | |||||
return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer), | |||||
format, args); | |||||
check_expected_ptr(temporary_buffer); | |||||
va_end(args); | |||||
return return_value; | |||||
} | |||||
/* A mock printf function that checks the value of strings printed to the | |||||
* standard output stream. */ | |||||
int example_test_printf(const char *format, ...) { | |||||
int return_value; | |||||
va_list args; | |||||
va_start(args, format); | |||||
return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer), | |||||
format, args); | |||||
check_expected_ptr(temporary_buffer); | |||||
va_end(args); | |||||
return return_value; | |||||
} | |||||
/* A mock binary operator function. */ | |||||
static int binary_operator(int a, int b) { | |||||
check_expected(a); | |||||
check_expected(b); | |||||
return (int)mock(); | |||||
} | |||||
/* Ensure add() adds two integers correctly. */ | |||||
static void test_add(void **state) { | |||||
(void) state; /* unused */ | |||||
assert_int_equal(add(3, 3), 6); | |||||
assert_int_equal(add(3, -3), 0); | |||||
} | |||||
/* Ensure subtract() subtracts two integers correctly. */ | |||||
static void test_subtract(void **state) { | |||||
(void) state; /* unused */ | |||||
assert_int_equal(subtract(3, 3), 0); | |||||
assert_int_equal(subtract(3, -3), 6); | |||||
} | |||||
/* Ensure multiple() mulitplies two integers correctly. */ | |||||
static void test_multiply(void **state) { | |||||
(void) state; /* unused */ | |||||
assert_int_equal(multiply(3, 3), 9); | |||||
assert_int_equal(multiply(3, 0), 0); | |||||
} | |||||
/* Ensure divide() divides one integer by another correctly. */ | |||||
static void test_divide(void **state) { | |||||
(void) state; /* unused */ | |||||
assert_int_equal(divide(10, 2), 5); | |||||
assert_int_equal(divide(2, 10), 0); | |||||
} | |||||
/* Ensure divide() asserts when trying to divide by zero. */ | |||||
static void test_divide_by_zero(void **state) { | |||||
(void) state; /* unused */ | |||||
expect_assert_failure(divide(100, 0)); | |||||
} | |||||
/* Ensure find_operator_function_by_string() asserts when a NULL pointer is | |||||
* specified as the table to search. */ | |||||
static void test_find_operator_function_by_string_null_functions(void **state) { | |||||
(void) state; /* unused */ | |||||
expect_assert_failure(find_operator_function_by_string(1, NULL, "test")); | |||||
} | |||||
/* Ensure find_operator_function_by_string() asserts when a NULL pointer is | |||||
* specified as the string to search for. */ | |||||
static void test_find_operator_function_by_string_null_string(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
}; | |||||
(void) state; /* unused */ | |||||
expect_assert_failure(find_operator_function_by_string( | |||||
array_length(operator_functions), operator_functions, NULL)); | |||||
} | |||||
/* Ensure find_operator_function_by_string() returns NULL when a NULL pointer | |||||
* is specified as the table to search when the table size is 0. */ | |||||
static void test_find_operator_function_by_string_valid_null_functions(void **state) { | |||||
(void) state; /* unused */ | |||||
assert_null(find_operator_function_by_string(0, NULL, "test")); | |||||
} | |||||
/* Ensure find_operator_function_by_string() returns NULL when searching for | |||||
* an operator string that isn't in the specified table. */ | |||||
static void test_find_operator_function_by_string_not_found(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
{"-", binary_operator}, | |||||
{"/", binary_operator}, | |||||
}; | |||||
(void) state; /* unused */ | |||||
assert_null(find_operator_function_by_string( | |||||
array_length(operator_functions), operator_functions, "test")); | |||||
} | |||||
/* Ensure find_operator_function_by_string() returns the correct function when | |||||
* searching for an operator string that is in the specified table. */ | |||||
static void test_find_operator_function_by_string_found(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", (BinaryOperator)0x12345678}, | |||||
{"-", (BinaryOperator)0xDEADBEEF}, | |||||
{"/", (BinaryOperator)0xABADCAFE}, | |||||
}; | |||||
(void) state; /* unused */ | |||||
assert_int_equal( | |||||
cast_ptr_to_largest_integral_type( | |||||
find_operator_function_by_string(array_length(operator_functions), | |||||
operator_functions, | |||||
"-")), | |||||
0xDEADBEEF); | |||||
} | |||||
/* Ensure perform_operation() asserts when a NULL arguments array is specified. */ | |||||
static void test_perform_operation_null_args(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
}; | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
expect_assert_failure(perform_operation( | |||||
1, NULL, array_length(operator_functions), operator_functions, | |||||
&number_of_intermediate_values, &intermediate_values, | |||||
&error_occurred)); | |||||
} | |||||
/* Ensure perform_operation() asserts when a NULL operator_functions array is | |||||
* specified. */ | |||||
static void test_perform_operation_null_operator_functions(void **state) { | |||||
const char *args[] = { | |||||
"1", "+", "2", "*", "4" | |||||
}; | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
expect_assert_failure(perform_operation( | |||||
array_length(args), (char **) args, 1, NULL, &number_of_intermediate_values, | |||||
&intermediate_values, &error_occurred)); | |||||
} | |||||
/* Ensure perform_operation() asserts when a NULL pointer is specified for | |||||
* number_of_intermediate_values. */ | |||||
static void test_perform_operation_null_number_of_intermediate_values(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
}; | |||||
const char *args[] = { | |||||
"1", "+", "2", "*", "4" | |||||
}; | |||||
int *intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
expect_assert_failure(perform_operation( | |||||
array_length(args), (char **) args, 1, operator_functions, NULL, | |||||
&intermediate_values, &error_occurred)); | |||||
} | |||||
/* Ensure perform_operation() asserts when a NULL pointer is specified for | |||||
* intermediate_values. */ | |||||
static void test_perform_operation_null_intermediate_values(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
}; | |||||
const char *args[] = { | |||||
"1", "+", "2", "*", "4" | |||||
}; | |||||
int number_of_intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
expect_assert_failure(perform_operation( | |||||
array_length(args), (char **) args, array_length(operator_functions), | |||||
operator_functions, &number_of_intermediate_values, NULL, | |||||
&error_occurred)); | |||||
} | |||||
/* Ensure perform_operation() returns 0 when no arguments are specified. */ | |||||
static void test_perform_operation_no_arguments(void **state) { | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
assert_int_equal(perform_operation( | |||||
0, NULL, 0, NULL, &number_of_intermediate_values, &intermediate_values, | |||||
&error_occurred), 0); | |||||
assert_int_equal(error_occurred, 0); | |||||
} | |||||
/* Ensure perform_operation() returns an error if the first argument isn't | |||||
* an integer string. */ | |||||
static void test_perform_operation_first_arg_not_integer(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
}; | |||||
const char *args[] = { | |||||
"test", "+", "2", "*", "4" | |||||
}; | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
expect_string(example_test_fprintf, temporary_buffer, | |||||
"Unable to parse integer from argument test\n"); | |||||
assert_int_equal(perform_operation( | |||||
array_length(args), (char **) args, array_length(operator_functions), | |||||
operator_functions, &number_of_intermediate_values, | |||||
&intermediate_values, &error_occurred), 0); | |||||
assert_int_equal(error_occurred, 1); | |||||
} | |||||
/* Ensure perform_operation() returns an error when parsing an unknown | |||||
* operator. */ | |||||
static void test_perform_operation_unknown_operator(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
}; | |||||
const char *args[] = { | |||||
"1", "*", "2", "*", "4" | |||||
}; | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
expect_string(example_test_fprintf, temporary_buffer, | |||||
"Unknown operator *, argument 1\n"); | |||||
assert_int_equal(perform_operation( | |||||
array_length(args), (char **) args, array_length(operator_functions), | |||||
operator_functions, &number_of_intermediate_values, | |||||
&intermediate_values, &error_occurred), 0); | |||||
assert_int_equal(error_occurred, 1); | |||||
} | |||||
/* Ensure perform_operation() returns an error when nothing follows an | |||||
* operator. */ | |||||
static void test_perform_operation_missing_argument(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
}; | |||||
const char *args[] = { | |||||
"1", "+", | |||||
}; | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
expect_string(example_test_fprintf, temporary_buffer, | |||||
"Binary operator + missing argument\n"); | |||||
assert_int_equal(perform_operation( | |||||
array_length(args), (char **) args, array_length(operator_functions), | |||||
operator_functions, &number_of_intermediate_values, | |||||
&intermediate_values, &error_occurred), 0); | |||||
assert_int_equal(error_occurred, 1); | |||||
} | |||||
/* Ensure perform_operation() returns an error when an integer doesn't follow | |||||
* an operator. */ | |||||
static void test_perform_operation_no_integer_after_operator(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
}; | |||||
const char *args[] = { | |||||
"1", "+", "test", | |||||
}; | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
expect_string(example_test_fprintf, temporary_buffer, | |||||
"Unable to parse integer test of argument 2\n"); | |||||
assert_int_equal(perform_operation( | |||||
array_length(args), (char **) args, array_length(operator_functions), | |||||
operator_functions, &number_of_intermediate_values, | |||||
&intermediate_values, &error_occurred), 0); | |||||
assert_int_equal(error_occurred, 1); | |||||
} | |||||
/* Ensure perform_operation() succeeds given valid input parameters. */ | |||||
static void test_perform_operation(void **state) { | |||||
const OperatorFunction operator_functions[] = { | |||||
{"+", binary_operator}, | |||||
{"*", binary_operator}, | |||||
}; | |||||
const char *args[] = { | |||||
"1", "+", "3", "*", "10", | |||||
}; | |||||
int number_of_intermediate_values; | |||||
int *intermediate_values = NULL; | |||||
int error_occurred; | |||||
(void) state; /* unused */ | |||||
/* Setup return values of mock operator functions. */ | |||||
/* Addition. */ | |||||
expect_value(binary_operator, a, 1); | |||||
expect_value(binary_operator, b, 3); | |||||
will_return(binary_operator, 4); | |||||
/* Multiplication. */ | |||||
expect_value(binary_operator, a, 4); | |||||
expect_value(binary_operator, b, 10); | |||||
will_return(binary_operator, 40); | |||||
assert_int_equal(perform_operation( | |||||
array_length(args), (char **) args, array_length(operator_functions), | |||||
operator_functions, &number_of_intermediate_values, | |||||
&intermediate_values, &error_occurred), 40); | |||||
assert_int_equal(error_occurred, 0); | |||||
assert_non_null(intermediate_values); | |||||
assert_int_equal(intermediate_values[0], 4); | |||||
assert_int_equal(intermediate_values[1], 40); | |||||
test_free(intermediate_values); | |||||
} | |||||
/* Ensure main() in example.c succeeds given no arguments. */ | |||||
static void test_example_main_no_args(void **state) { | |||||
const char *args[] = { | |||||
"example", | |||||
}; | |||||
(void) state; /* unused */ | |||||
assert_int_equal(example_main(array_length(args), (char **) args), 0); | |||||
} | |||||
/* Ensure main() in example.c succeeds given valid input arguments. */ | |||||
static void test_example_main(void **state) { | |||||
const char *args[] = { | |||||
"example", "1", "+", "3", "*", "10", | |||||
}; | |||||
(void) state; /* unused */ | |||||
expect_string(example_test_printf, temporary_buffer, "1\n"); | |||||
expect_string(example_test_printf, temporary_buffer, " + 3 = 4\n"); | |||||
expect_string(example_test_printf, temporary_buffer, " * 10 = 40\n"); | |||||
expect_string(example_test_printf, temporary_buffer, "= 40\n"); | |||||
assert_int_equal(example_main(array_length(args), (char **) args), 0); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_add), | |||||
cmocka_unit_test(test_subtract), | |||||
cmocka_unit_test(test_multiply), | |||||
cmocka_unit_test(test_divide), | |||||
cmocka_unit_test(test_divide_by_zero), | |||||
cmocka_unit_test(test_find_operator_function_by_string_null_functions), | |||||
cmocka_unit_test(test_find_operator_function_by_string_null_string), | |||||
cmocka_unit_test(test_find_operator_function_by_string_valid_null_functions), | |||||
cmocka_unit_test(test_find_operator_function_by_string_not_found), | |||||
cmocka_unit_test(test_find_operator_function_by_string_found), | |||||
cmocka_unit_test(test_perform_operation_null_args), | |||||
cmocka_unit_test(test_perform_operation_null_operator_functions), | |||||
cmocka_unit_test(test_perform_operation_null_number_of_intermediate_values), | |||||
cmocka_unit_test(test_perform_operation_null_intermediate_values), | |||||
cmocka_unit_test(test_perform_operation_no_arguments), | |||||
cmocka_unit_test(test_perform_operation_first_arg_not_integer), | |||||
cmocka_unit_test(test_perform_operation_unknown_operator), | |||||
cmocka_unit_test(test_perform_operation_missing_argument), | |||||
cmocka_unit_test(test_perform_operation_no_integer_after_operator), | |||||
cmocka_unit_test(test_perform_operation), | |||||
cmocka_unit_test(test_example_main_no_args), | |||||
cmocka_unit_test(test_example_main), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,20 @@ | |||||
project(cmocka-wrap-examples C) | |||||
include_directories( | |||||
${CMAKE_BINARY_DIR} | |||||
${CMAKE_CURRENT_SOURCE_DIR} | |||||
${CMOCKA_PUBLIC_INCLUDE_DIRS} | |||||
) | |||||
add_executable(waiter_test_wrap waiter_test_wrap.c chef.c) | |||||
target_link_libraries(waiter_test_wrap ${CMOCKA_SHARED_LIBRARY}) | |||||
add_test(waiter_test_wrap ${CMAKE_CURRENT_BINARY_DIR}/waiter_test_wrap) | |||||
set_target_properties(waiter_test_wrap | |||||
PROPERTIES | |||||
LINK_FLAGS "-Wl,--wrap=chef_cook" | |||||
) | |||||
if (WIN32 OR MINGW OR CYGWIN) | |||||
set_tests_properties(waiter_test_wrap PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") | |||||
endif (WIN32 OR MINGW OR CYGWIN) |
@@ -0,0 +1,54 @@ | |||||
/* | |||||
* Copyright 2013 (c) Andreas Schneider <asn@cynapses.org> | |||||
* Jakub Hrozek <jakub.hrozek@gmail.com> | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <stdio.h> | |||||
#include <errno.h> | |||||
#include <stdbool.h> | |||||
#include <string.h> | |||||
#include "chef.h" | |||||
/* This is the real chef, just not implemented yet, currently it always | |||||
* returns ENOSYS | |||||
*/ | |||||
int chef_cook(const char *order, char **dish_out) | |||||
{ | |||||
if (order == NULL || dish_out == NULL) return EINVAL; | |||||
return -ENOSYS; | |||||
} | |||||
/* Print chef return codes as string */ | |||||
const char *chef_strerror(int error) | |||||
{ | |||||
switch (error) { | |||||
case 0: | |||||
return "Success"; | |||||
case -1: | |||||
return "Unknown dish"; | |||||
case -2: | |||||
return "Not enough ingredients for the dish"; | |||||
} | |||||
return "Unknown error!"; | |||||
} | |||||
@@ -0,0 +1,19 @@ | |||||
/* | |||||
* Copyright 2013 (c) Andreas Schneider <asn@cynapses.org> | |||||
* Jakub Hrozek <jakub.hrozek@gmail.com> | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
int chef_cook(const char *order, char **dish_out); | |||||
const char *chef_strerror(int error); |
@@ -0,0 +1,176 @@ | |||||
/* | |||||
* Copyright 2013 (c) Andreas Schneider <asn@cynapses.org> | |||||
* Jakub Hrozek <jakub.hrozek@gmail.com> | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <errno.h> | |||||
#include <stdbool.h> | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include "waiter_test_wrap.h" | |||||
#include "chef.h" | |||||
/* | |||||
* This is a mocked Chef object. A real Chef would look if he knows | |||||
* the dish in some kind of internal database and check his storage for | |||||
* ingredients. This chef simply retrieves this information from the test | |||||
* that is calling him. | |||||
* | |||||
* This object is also wrapped - if any code links with this file and is | |||||
* compiled with linker option --wrap chef_cook, any calls of that code to | |||||
* chef_cook will end up calling __wrap_chef_cook. | |||||
* | |||||
* If for any reason the wrapped function wanted to call the real chef_cook() | |||||
* function, it could do so by calling the special symbol __real_chef_cook(). | |||||
* | |||||
* Please note that when setting return codes for the chef_cook function, we | |||||
* use this wrapper as a parameter for the will_return() macro, not the | |||||
* real function. | |||||
* | |||||
* A chef object would return: | |||||
* 0 - cooking dish went fine | |||||
* -1 - unknown dish | |||||
* -2 - ran out of ingredients for the dish | |||||
* any other error code -- unexpected error while cooking | |||||
* | |||||
* The return codes should be consistent between the real and mocked objects. | |||||
*/ | |||||
int __wrap_chef_cook(const char *order, char **dish_out) | |||||
{ | |||||
bool has_ingredients; | |||||
bool knows_dish; | |||||
char *dish; | |||||
check_expected_ptr(order); | |||||
knows_dish = mock_type(bool); | |||||
if (knows_dish == false) { | |||||
return -1; | |||||
} | |||||
has_ingredients = mock_type(bool); | |||||
if (has_ingredients == false) { | |||||
return -2; | |||||
} | |||||
dish = mock_ptr_type(char *); | |||||
*dish_out = strdup(dish); | |||||
if (*dish_out == NULL) return ENOMEM; | |||||
return mock_type(int); | |||||
} | |||||
/* Waiter return codes: | |||||
* 0 - success | |||||
* -1 - kitchen failed | |||||
* -2 - kitchen succeeded, but cooked a different food | |||||
*/ | |||||
static int waiter_process(const char *order, char **dish) | |||||
{ | |||||
int rv; | |||||
rv = chef_cook(order, dish); | |||||
if (rv != 0) { | |||||
fprintf(stderr, "Chef couldn't cook %s: %s\n", | |||||
order, chef_strerror(rv)); | |||||
return -1; | |||||
} | |||||
/* Check if we received the dish we wanted from the kitchen */ | |||||
if (strcmp(order, *dish) != 0) { | |||||
free(*dish); | |||||
*dish = NULL; | |||||
return -2; | |||||
} | |||||
return 0; | |||||
} | |||||
static void test_order_hotdog(void **state) | |||||
{ | |||||
int rv; | |||||
char *dish; | |||||
(void) state; /* unused */ | |||||
/* We expect the chef to receive an order for a hotdog */ | |||||
expect_string(__wrap_chef_cook, order, "hotdog"); | |||||
/* And we tell the test chef that ke knows how to cook a hotdog | |||||
* and has the ingredients | |||||
*/ | |||||
will_return(__wrap_chef_cook, true); | |||||
will_return(__wrap_chef_cook, true); | |||||
/* The result will be a hotdog and the cooking process will succeed */ | |||||
will_return(__wrap_chef_cook, cast_ptr_to_largest_integral_type("hotdog")); | |||||
will_return(__wrap_chef_cook, 0); | |||||
/* Test the waiter */ | |||||
rv = waiter_process("hotdog", &dish); | |||||
/* We expect the cook to succeed cooking the hotdog */ | |||||
assert_int_equal(rv, 0); | |||||
/* And actually receive one */ | |||||
assert_string_equal(dish, "hotdog"); | |||||
if (dish != NULL) { | |||||
free(dish); | |||||
} | |||||
} | |||||
static void test_bad_dish(void **state) | |||||
{ | |||||
int rv; | |||||
char *dish; | |||||
(void) state; /* unused */ | |||||
/* We expect the chef to receive an order for a hotdog */ | |||||
expect_string(__wrap_chef_cook, order, "hotdog"); | |||||
/* And we tell the test chef that ke knows how to cook a hotdog | |||||
* and has the ingredients | |||||
*/ | |||||
will_return(__wrap_chef_cook, true); | |||||
will_return(__wrap_chef_cook, true); | |||||
/* The result will be a burger and the cooking process will succeed. | |||||
* We expect the waiter to handle the bad dish and return an error | |||||
* code | |||||
*/ | |||||
will_return(__wrap_chef_cook, cast_ptr_to_largest_integral_type("burger")); | |||||
will_return(__wrap_chef_cook, 0); | |||||
/* Test the waiter */ | |||||
rv = waiter_process("hotdog", &dish); | |||||
/* According to the documentation the waiter should return -2 now */ | |||||
assert_int_equal(rv, -2); | |||||
/* And do not give the bad dish to the customer */ | |||||
assert_null(dish); | |||||
} | |||||
int main(void) | |||||
{ | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_order_hotdog), | |||||
cmocka_unit_test(test_bad_dish), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,2 @@ | |||||
int __wrap_chef_cook(const char *order, char **dish_out); |
@@ -0,0 +1,51 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stddef.h> | |||||
#include <stdio.h> | |||||
#include <database.h> | |||||
#ifdef _WIN32 | |||||
#define snprintf _snprintf | |||||
#endif /* _WIN32 */ | |||||
DatabaseConnection* connect_to_customer_database(void); | |||||
unsigned int get_customer_id_by_name( | |||||
DatabaseConnection * const connection, | |||||
const char * const customer_name); | |||||
/* Connect to the database containing customer information. */ | |||||
DatabaseConnection* connect_to_customer_database(void) { | |||||
return connect_to_database("customers.abcd.org", 321); | |||||
} | |||||
/* Find the ID of a customer by his/her name returning a value > 0 if | |||||
* successful, 0 otherwise. */ | |||||
unsigned int get_customer_id_by_name( | |||||
DatabaseConnection * const connection, | |||||
const char * const customer_name) { | |||||
char query_string[256]; | |||||
int number_of_results; | |||||
void **results; | |||||
snprintf(query_string, sizeof(query_string), | |||||
"SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name); | |||||
number_of_results = connection->query_database(connection, query_string, | |||||
&results); | |||||
if (number_of_results != 1) { | |||||
return -1; | |||||
} | |||||
return (unsigned int)*((int *)results); | |||||
} |
@@ -0,0 +1,89 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <database.h> | |||||
extern DatabaseConnection* connect_to_customer_database(void); | |||||
extern unsigned int get_customer_id_by_name( | |||||
DatabaseConnection * const connection, const char * const customer_name); | |||||
/* Mock query database function. */ | |||||
static unsigned int mock_query_database(DatabaseConnection* const connection, | |||||
const char * const query_string, | |||||
void *** const results) { | |||||
(void) connection; /* unused */ | |||||
(void) query_string; /* unused */ | |||||
*results = (void **)mock_ptr_type(int *); | |||||
return mock_ptr_type(int); | |||||
} | |||||
/* Mock of the connect to database function. */ | |||||
DatabaseConnection* connect_to_database(const char * const database_url, | |||||
const unsigned int port) { | |||||
(void) database_url; /* unused */ | |||||
(void) port; /* unused */ | |||||
return (DatabaseConnection*)((size_t)mock()); | |||||
} | |||||
static void test_connect_to_customer_database(void **state) { | |||||
(void) state; /* unused */ | |||||
will_return(connect_to_database, 0x0DA7ABA53); | |||||
assert_int_equal((size_t)connect_to_customer_database(), 0x0DA7ABA53); | |||||
} | |||||
/* This test fails as the mock function connect_to_database() will have no | |||||
* value to return. */ | |||||
#if 0 | |||||
static void fail_connect_to_customer_database(void **state) { | |||||
(void) state; /* unused */ | |||||
assert_true(connect_to_customer_database() == | |||||
(DatabaseConnection*)0x0DA7ABA53); | |||||
} | |||||
#endif | |||||
static void test_get_customer_id_by_name(void **state) { | |||||
DatabaseConnection connection = { | |||||
"somedatabase.somewhere.com", 12345678, mock_query_database | |||||
}; | |||||
/* Return a single customer ID when mock_query_database() is called. */ | |||||
int customer_ids = 543; | |||||
int rc; | |||||
(void) state; /* unused */ | |||||
will_return(mock_query_database, | |||||
cast_ptr_to_largest_integral_type(&customer_ids)); | |||||
will_return(mock_query_database, 1); | |||||
rc = get_customer_id_by_name(&connection, "john doe"); | |||||
assert_int_equal(rc, 543); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_connect_to_customer_database), | |||||
cmocka_unit_test(test_get_customer_id_by_name), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,37 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
typedef struct DatabaseConnection DatabaseConnection; | |||||
/* Function that takes an SQL query string and sets results to an array of | |||||
* pointers with the result of the query. The value returned specifies the | |||||
* number of items in the returned array of results. The returned array of | |||||
* results are statically allocated and should not be deallocated using free() | |||||
*/ | |||||
typedef unsigned int (*QueryDatabase)( | |||||
DatabaseConnection* const connection, const char * const query_string, | |||||
void *** const results); | |||||
/* Connection to a database. */ | |||||
struct DatabaseConnection { | |||||
const char *url; | |||||
unsigned int port; | |||||
QueryDatabase query_database; | |||||
}; | |||||
/* Connect to a database. */ | |||||
DatabaseConnection* connect_to_database(const char * const url, | |||||
const unsigned int port); | |||||
@@ -0,0 +1,51 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stddef.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include "key_value.h" | |||||
static KeyValue *key_values = NULL; | |||||
static unsigned int number_of_key_values = 0; | |||||
void set_key_values(KeyValue * const new_key_values, | |||||
const unsigned int new_number_of_key_values) { | |||||
key_values = new_key_values; | |||||
number_of_key_values = new_number_of_key_values; | |||||
} | |||||
/* Compare two key members of KeyValue structures. */ | |||||
static int key_value_compare_keys(const void *a, const void *b) { | |||||
return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key; | |||||
} | |||||
/* Search an array of key value pairs for the item with the specified value. */ | |||||
KeyValue* find_item_by_value(const char * const value) { | |||||
unsigned int i; | |||||
for (i = 0; i < number_of_key_values; i++) { | |||||
if (strcmp(key_values[i].value, value) == 0) { | |||||
return &key_values[i]; | |||||
} | |||||
} | |||||
return NULL; | |||||
} | |||||
/* Sort an array of key value pairs by key. */ | |||||
void sort_items_by_key(void) { | |||||
qsort(key_values, number_of_key_values, sizeof(*key_values), | |||||
key_value_compare_keys); | |||||
} |
@@ -0,0 +1,27 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
typedef struct KeyValue { | |||||
unsigned int key; | |||||
const char* value; | |||||
} KeyValue; | |||||
void set_key_values(KeyValue * const new_key_values, | |||||
const unsigned int new_number_of_key_values); | |||||
KeyValue* find_item_by_value(const char * const value); | |||||
void sort_items_by_key(void); |
@@ -0,0 +1,77 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <string.h> | |||||
#include <cmocka.h> | |||||
#include "key_value.h" | |||||
static KeyValue key_values[] = { | |||||
{ 10, "this" }, | |||||
{ 52, "test" }, | |||||
{ 20, "a" }, | |||||
{ 13, "is" }, | |||||
}; | |||||
static int create_key_values(void **state) { | |||||
KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values)); | |||||
memcpy(items, key_values, sizeof(key_values)); | |||||
*state = (void*)items; | |||||
set_key_values(items, sizeof(key_values) / sizeof(key_values[0])); | |||||
return 0; | |||||
} | |||||
static int destroy_key_values(void **state) { | |||||
test_free(*state); | |||||
set_key_values(NULL, 0); | |||||
return 0; | |||||
} | |||||
static void test_find_item_by_value(void **state) { | |||||
unsigned int i; | |||||
(void) state; /* unused */ | |||||
for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) { | |||||
KeyValue * const found = find_item_by_value(key_values[i].value); | |||||
assert_true(found != NULL); | |||||
assert_int_equal(found->key, key_values[i].key); | |||||
assert_string_equal(found->value, key_values[i].value); | |||||
} | |||||
} | |||||
static void test_sort_items_by_key(void **state) { | |||||
unsigned int i; | |||||
KeyValue * const kv = *state; | |||||
sort_items_by_key(); | |||||
for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) { | |||||
assert_true(kv[i - 1].key < kv[i].key); | |||||
} | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test_setup_teardown(test_find_item_by_value, | |||||
create_key_values, destroy_key_values), | |||||
cmocka_unit_test_setup_teardown(test_sort_items_by_key, | |||||
create_key_values, destroy_key_values), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,24 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <database.h> | |||||
DatabaseConnection* connect_to_product_database(void); | |||||
/* Connect to the database containing customer information. */ | |||||
DatabaseConnection* connect_to_product_database(void) { | |||||
return connect_to_database("products.abcd.org", 322); | |||||
} | |||||
@@ -0,0 +1,72 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <database.h> | |||||
extern DatabaseConnection* connect_to_product_database(void); | |||||
/* Mock connect to database function. | |||||
* NOTE: This mock function is very general could be shared between tests | |||||
* that use the imaginary database.h module. */ | |||||
DatabaseConnection* connect_to_database(const char * const url, | |||||
const unsigned int port) { | |||||
check_expected_ptr(url); | |||||
check_expected(port); | |||||
return (DatabaseConnection*)((size_t)mock()); | |||||
} | |||||
static void test_connect_to_product_database(void **state) { | |||||
(void) state; /* unused */ | |||||
expect_string(connect_to_database, url, "products.abcd.org"); | |||||
expect_value(connect_to_database, port, 322); | |||||
will_return(connect_to_database, 0xDA7ABA53); | |||||
assert_int_equal((size_t)connect_to_product_database(), 0xDA7ABA53); | |||||
} | |||||
/* This test will fail since the expected URL is different to the URL that is | |||||
* passed to connect_to_database() by connect_to_product_database(). */ | |||||
static void test_connect_to_product_database_bad_url(void **state) { | |||||
(void) state; /* unused */ | |||||
expect_string(connect_to_database, url, "products.abcd.com"); | |||||
expect_value(connect_to_database, port, 322); | |||||
will_return(connect_to_database, 0xDA7ABA53); | |||||
assert_int_equal((size_t)connect_to_product_database(), 0xDA7ABA53); | |||||
} | |||||
/* This test will fail since the mock connect_to_database() will attempt to | |||||
* retrieve a value for the parameter port which isn't specified by this | |||||
* test function. */ | |||||
static void test_connect_to_product_database_missing_parameter(void **state) { | |||||
(void) state; /* unused */ | |||||
expect_string(connect_to_database, url, "products.abcd.org"); | |||||
will_return(connect_to_database, 0xDA7ABA53); | |||||
assert_int_equal((size_t)connect_to_product_database(), 0xDA7ABA53); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_connect_to_product_database), | |||||
cmocka_unit_test(test_connect_to_product_database_bad_url), | |||||
cmocka_unit_test(test_connect_to_product_database_missing_parameter), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,17 @@ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
/* A test case that does nothing and succeeds. */ | |||||
static void null_test_success(void **state) { | |||||
(void) state; /* unused */ | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(null_test_success), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,10 @@ | |||||
DEFS_TO_REMOVE=-DHAVE_SETJMP_H -DHAVE_STDIO_H | |||||
all: | |||||
gcc -I../../include $(DEFS_TO_REMOVE) -o cmocka.o -c ../../src/cmocka.c | |||||
gcc -I../../include -o simple_test.o -c simple_test.c | |||||
gcc -o a.out cmocka.o simple_test.o | |||||
clean: | |||||
rm -rf *.o | |||||
rm -rf a.out |
@@ -0,0 +1,17 @@ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
/* A test case that does nothing and succeeds. */ | |||||
static void null_test_success(void **state) { | |||||
(void) state; /* unused */ | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(null_test_success), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,27 @@ | |||||
project(cmocka-headers C) | |||||
set(cmocka_HDRS | |||||
cmocka.h | |||||
cmocka_pbc.h | |||||
) | |||||
install( | |||||
FILES | |||||
${cmocka_HDRS} | |||||
DESTINATION | |||||
${INCLUDE_INSTALL_DIR} | |||||
COMPONENT | |||||
headers | |||||
) | |||||
if (WITH_CMOCKERY_SUPPORT) | |||||
install( | |||||
FILES | |||||
cmockery/cmockery.h | |||||
cmockery/pbc.h | |||||
DESTINATION | |||||
${INCLUDE_INSTALL_DIR}/cmockery | |||||
COMPONENT | |||||
headers | |||||
) | |||||
endif() |
@@ -0,0 +1,62 @@ | |||||
/* | |||||
* Copyright 2014 Luis Pabon, Jr. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
/* | |||||
* Programming by Contract is a programming methodology | |||||
* which binds the caller and the function called to a | |||||
* contract. The contract is represented using Hoare Triple: | |||||
* {P} C {Q} | |||||
* where {P} is the precondition before executing command C, | |||||
* and {Q} is the postcondition. | |||||
* | |||||
* See also: | |||||
* http://en.wikipedia.org/wiki/Design_by_contract | |||||
* http://en.wikipedia.org/wiki/Hoare_logic | |||||
* http://dlang.org/dbc.html | |||||
*/ | |||||
#ifndef CMOCKA_PBC_H_ | |||||
#define CMOCKA_PBC_H_ | |||||
#if defined(UNIT_TESTING) || defined (DEBUG) | |||||
#include <assert.h> | |||||
/* | |||||
* Checks caller responsibility against contract | |||||
*/ | |||||
#define REQUIRE(cond) assert(cond) | |||||
/* | |||||
* Checks function reponsability against contract. | |||||
*/ | |||||
#define ENSURE(cond) assert(cond) | |||||
/* | |||||
* While REQUIRE and ENSURE apply to functions, INVARIANT | |||||
* applies to classes/structs. It ensures that intances | |||||
* of the class/struct are consistent. In other words, | |||||
* that the instance has not been corrupted. | |||||
*/ | |||||
#define INVARIANT(invariant_fnc) do{ (invariant_fnc) } while (0); | |||||
#else | |||||
#define REQUIRE(cond) do { } while (0); | |||||
#define ENSURE(cond) do { } while (0); | |||||
#define INVARIANT(invariant_fnc) do{ } while (0); | |||||
#endif /* defined(UNIT_TESTING) || defined (DEBUG) */ | |||||
#endif /* CMOCKA_PBC_H_ */ | |||||
@@ -0,0 +1,163 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#ifndef CMOCKA_PRIVATE_H_ | |||||
#define CMOCKA_PRIVATE_H_ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <stdint.h> | |||||
#ifdef _WIN32 | |||||
#include <windows.h> | |||||
# ifdef _MSC_VER | |||||
# include <stdio.h> /* _snprintf */ | |||||
# undef inline | |||||
# define inline __inline | |||||
# ifndef va_copy | |||||
# define va_copy(dest, src) (dest = src) | |||||
# endif | |||||
# define strcasecmp _stricmp | |||||
# define strncasecmp _strnicmp | |||||
# if defined(HAVE__SNPRINTF_S) | |||||
# undef snprintf | |||||
# define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__) | |||||
# else /* HAVE__SNPRINTF_S */ | |||||
# if defined(HAVE__SNPRINTF) | |||||
# undef snprintf | |||||
# define snprintf _snprintf | |||||
# else /* HAVE__SNPRINTF */ | |||||
# if !defined(HAVE_SNPRINTF) | |||||
# error "no snprintf compatible function found" | |||||
# endif /* HAVE_SNPRINTF */ | |||||
# endif /* HAVE__SNPRINTF */ | |||||
# endif /* HAVE__SNPRINTF_S */ | |||||
# if defined(HAVE__VSNPRINTF_S) | |||||
# undef vsnprintf | |||||
# define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v)) | |||||
# else /* HAVE__VSNPRINTF_S */ | |||||
# if defined(HAVE__VSNPRINTF) | |||||
# undef vsnprintf | |||||
# define vsnprintf _vsnprintf | |||||
# else | |||||
# if !defined(HAVE_VSNPRINTF) | |||||
# error "No vsnprintf compatible function found" | |||||
# endif /* HAVE_VSNPRINTF */ | |||||
# endif /* HAVE__VSNPRINTF */ | |||||
# endif /* HAVE__VSNPRINTF_S */ | |||||
# endif /* _MSC_VER */ | |||||
/* | |||||
* Backwards compatibility with headers shipped with Visual Studio 2005 and | |||||
* earlier. | |||||
*/ | |||||
WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); | |||||
#ifndef PRIdS | |||||
# define PRIdS "Id" | |||||
#endif | |||||
#ifndef PRIu64 | |||||
# define PRIu64 "I64u" | |||||
#endif | |||||
#ifndef PRIuMAX | |||||
# define PRIuMAX PRIu64 | |||||
#endif | |||||
#ifndef PRIxMAX | |||||
#define PRIxMAX "I64x" | |||||
#endif | |||||
#ifndef PRIXMAX | |||||
#define PRIXMAX "I64X" | |||||
#endif | |||||
#else /* _WIN32 */ | |||||
#ifndef __PRI64_PREFIX | |||||
# if __WORDSIZE == 64 | |||||
# define __PRI64_PREFIX "l" | |||||
# else | |||||
# define __PRI64_PREFIX "ll" | |||||
# endif | |||||
#endif | |||||
#ifndef PRIdS | |||||
# define PRIdS "zd" | |||||
#endif | |||||
#ifndef PRIu64 | |||||
# define PRIu64 __PRI64_PREFIX "u" | |||||
#endif | |||||
#ifndef PRIuMAX | |||||
# define PRIuMAX __PRI64_PREFIX "u" | |||||
#endif | |||||
#ifndef PRIxMAX | |||||
#define PRIxMAX __PRI64_PREFIX "x" | |||||
#endif | |||||
#ifndef PRIXMAX | |||||
#define PRIXMAX __PRI64_PREFIX "X" | |||||
#endif | |||||
#endif /* _WIN32 */ | |||||
/** Free memory space */ | |||||
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) | |||||
/** Zero a structure */ | |||||
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) | |||||
/** Zero a structure given a pointer to the structure */ | |||||
#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) | |||||
/** Get the size of an array */ | |||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) | |||||
/** Overwrite the complete string with 'X' */ | |||||
#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0) | |||||
/** | |||||
* This is a hack to fix warnings. The idea is to use this everywhere that we | |||||
* get the "discarding const" warning by the compiler. That doesn't actually | |||||
* fix the real issue, but marks the place and you can search the code for | |||||
* discard_const. | |||||
* | |||||
* Please use this macro only when there is no other way to fix the warning. | |||||
* We should use this function in only in a very few places. | |||||
* | |||||
* Also, please call this via the discard_const_p() macro interface, as that | |||||
* makes the return type safe. | |||||
*/ | |||||
#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) | |||||
/** | |||||
* Type-safe version of discard_const | |||||
*/ | |||||
#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) | |||||
#endif /* CMOCKA_PRIVATE_H_ */ |
@@ -0,0 +1 @@ | |||||
#include <cmocka.h> |
@@ -0,0 +1 @@ | |||||
#include <cmocka_pbc.h> |
@@ -0,0 +1,118 @@ | |||||
project(cmocka-library C) | |||||
set(CMOCKA_PLATFORM_INCLUDE CACHE PATH "Path to include directory for cmocka_platform.h") | |||||
set(CMOCKA_PUBLIC_INCLUDE_DIRS | |||||
${cmocka_SOURCE_DIR}/include | |||||
${CMOCKA_PLATFORM_INCLUDE} | |||||
CACHE INTERNAL "cmocka public include directories" | |||||
) | |||||
set(CMOCKA_PRIVATE_INCLUDE_DIRS | |||||
${cmocka_BINARY_DIR} | |||||
) | |||||
set(CMOCKA_SHARED_LIBRARY | |||||
cmocka_shared | |||||
CACHE INTERNAL "cmocka shared library" | |||||
) | |||||
if (WITH_STATIC_LIB) | |||||
set(CMOCKA_STATIC_LIBRARY | |||||
cmocka_static | |||||
CACHE INTERNAL "cmocka static library" | |||||
) | |||||
endif (WITH_STATIC_LIB) | |||||
set(CMOCKA_LINK_LIBRARIES | |||||
${CMOCKA_REQUIRED_LIBRARIES} | |||||
CACHE INTERNAL "cmocka link libraries" | |||||
) | |||||
set(cmocka_SRCS | |||||
cmocka.c | |||||
) | |||||
if (WIN32) | |||||
set(cmocka_SRCS | |||||
${cmocka_SRCS} | |||||
cmocka.def | |||||
) | |||||
endif (WIN32) | |||||
include_directories( | |||||
${CMOCKA_PUBLIC_INCLUDE_DIRS} | |||||
${CMOCKA_PRIVATE_INCLUDE_DIRS} | |||||
) | |||||
add_definitions(-DHAVE_CONFIG_H=1) | |||||
if (CMOCKA_PLATFORM_INCLUDE) | |||||
add_definitions(-DCMOCKA_PLATFORM_INCLUDE=1) | |||||
endif() | |||||
add_library(${CMOCKA_SHARED_LIBRARY} SHARED ${cmocka_SRCS}) | |||||
target_link_libraries(${CMOCKA_SHARED_LIBRARY} ${CMOCKA_LINK_LIBRARIES}) | |||||
set_target_properties( | |||||
${CMOCKA_SHARED_LIBRARY} | |||||
PROPERTIES | |||||
OUTPUT_NAME | |||||
cmocka | |||||
DEFINE_SYMBOL | |||||
CMOCKA_EXPORTS | |||||
) | |||||
if (NOT WIN32) | |||||
set_target_properties( | |||||
${CMOCKA_SHARED_LIBRARY} | |||||
PROPERTIES | |||||
VERSION | |||||
${LIBRARY_VERSION} | |||||
SOVERSION | |||||
${LIBRARY_SOVERSION} | |||||
) | |||||
endif (NOT WIN32) | |||||
install( | |||||
TARGETS ${CMOCKA_SHARED_LIBRARY} | |||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR} | |||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR} | |||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR} | |||||
COMPONENT libraries | |||||
) | |||||
if (WITH_STATIC_LIB) | |||||
add_library(${CMOCKA_STATIC_LIBRARY} STATIC ${cmocka_SRCS}) | |||||
set_target_properties( | |||||
${CMOCKA_STATIC_LIBRARY} | |||||
PROPERTIES | |||||
VERSION | |||||
${LIBRARY_VERSION} | |||||
SOVERSION | |||||
${LIBRARY_SOVERSION} | |||||
OUTPUT_NAME | |||||
cmocka | |||||
) | |||||
install( | |||||
TARGETS ${CMOCKA_STATIC_LIBRARY} | |||||
DESTINATION ${LIB_INSTALL_DIR} | |||||
COMPONENT libraries | |||||
) | |||||
endif (WITH_STATIC_LIB) | |||||
if (POLICY CMP0026) | |||||
cmake_policy(SET CMP0026 OLD) | |||||
endif() | |||||
# | |||||
# In order to run tests we will need to set the approriate environment | |||||
# variable so that the test program can locate its dependent DLL's. First | |||||
# we want to know what directory our dependent DLL was installed into: | |||||
# | |||||
get_target_property(_cmocka_dir cmocka_shared LOCATION_${CMOCKA_BUILD_TYPE}) | |||||
get_filename_component(_cmocka_path "${_cmocka_dir}" PATH) | |||||
file(TO_NATIVE_PATH "${_cmocka_path}" _cmocka_path_native) | |||||
set(CMOCKA_DLL_PATH "${_cmocka_path_native}" PARENT_SCOPE) |
@@ -0,0 +1,49 @@ | |||||
LIBRARY cmocka | |||||
EXPORTS | |||||
_assert_in_range | |||||
_assert_in_set | |||||
_assert_int_equal | |||||
_assert_int_not_equal | |||||
_assert_memory_equal | |||||
_assert_memory_not_equal | |||||
_assert_not_in_range | |||||
_assert_not_in_set | |||||
_assert_return_code | |||||
_assert_string_equal | |||||
_assert_string_not_equal | |||||
_assert_true | |||||
_check_expected | |||||
_cmocka_run_group_tests | |||||
_expect_any | |||||
_expect_check | |||||
_expect_function_call | |||||
_expect_in_range | |||||
_expect_in_set | |||||
_expect_memory | |||||
_expect_not_in_range | |||||
_expect_not_in_set | |||||
_expect_not_memory | |||||
_expect_not_string | |||||
_expect_not_value | |||||
_expect_string | |||||
_expect_value | |||||
_fail | |||||
_function_called | |||||
_mock | |||||
_run_test | |||||
_run_tests | |||||
_skip | |||||
_test_calloc | |||||
_test_free | |||||
_test_malloc | |||||
_test_realloc | |||||
_will_return | |||||
cmocka_set_message_output | |||||
global_expect_assert_env | |||||
global_expecting_assert | |||||
global_last_failed_assert | |||||
mock_assert | |||||
print_error | |||||
print_message | |||||
vprint_error | |||||
vprint_message |
@@ -0,0 +1,243 @@ | |||||
project(tests C) | |||||
include_directories( | |||||
${CMAKE_BINARY_DIR} | |||||
${CMAKE_CURRENT_SOURCE_DIR} | |||||
${CMAKE_SOURCE_DIR}/include | |||||
) | |||||
set(CMOCKA_TESTS | |||||
test_alloc | |||||
test_group_setup_assert | |||||
test_group_setup_fail | |||||
test_fixtures | |||||
test_group_fixtures | |||||
test_groups | |||||
test_assert_macros | |||||
test_assert_macros_fail | |||||
test_exception_handler | |||||
test_basics | |||||
test_skip | |||||
test_setup_fail | |||||
test_ordering | |||||
test_ordering_fail | |||||
test_returns | |||||
test_returns_fail) | |||||
foreach(_CMOCKA_TEST ${CMOCKA_TESTS}) | |||||
add_cmocka_test(${_CMOCKA_TEST} ${_CMOCKA_TEST}.c ${CMOCKA_STATIC_LIBRARY}) | |||||
endforeach() | |||||
### Special Cases | |||||
if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)") | |||||
set_source_files_properties(test_cmockery.c PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations") | |||||
endif() | |||||
add_cmocka_test(test_cmockery test_cmockery.c ${CMOCKA_STATIC_LIBRARY}) | |||||
### Exceptions | |||||
# test_skip | |||||
set_tests_properties( | |||||
test_skip | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ SKIPPED \\] test_check_skip" | |||||
) | |||||
# test_assert_macros_fail | |||||
set_tests_properties( | |||||
test_assert_macros_fail | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ FAILED \\] 1 test" | |||||
) | |||||
# test_ordering ensure proper failures | |||||
set_tests_properties( | |||||
test_ordering_fail | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ FAILED \\] 7 test" | |||||
) | |||||
# test_returns_fail ensure proper failures | |||||
set_tests_properties( | |||||
test_returns_fail | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ FAILED \\] 3 test" | |||||
) | |||||
# test_exception_handler | |||||
if (WIN32) | |||||
set_tests_properties( | |||||
test_exception_handler | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"EXCEPTION_ACCESS_VIOLATION occurred at") | |||||
else() | |||||
set_tests_properties( | |||||
test_exception_handler | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"Test failed with exception: (Segmentation fault|Segmentation Fault|11)" | |||||
) | |||||
endif (WIN32) | |||||
set_tests_properties( | |||||
test_setup_fail | |||||
PROPERTIES | |||||
WILL_FAIL | |||||
1 | |||||
) | |||||
set_tests_properties( | |||||
test_group_setup_assert | |||||
PROPERTIES | |||||
WILL_FAIL | |||||
1 | |||||
) | |||||
set_tests_properties( | |||||
test_group_setup_fail | |||||
PROPERTIES | |||||
WILL_FAIL | |||||
1 | |||||
) | |||||
add_test (test_setup_fail_1_failed test_setup_fail) | |||||
set_tests_properties( | |||||
test_setup_fail_1_failed | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ ERROR \\] int_test_ignored" | |||||
) | |||||
add_test (test_setup_fail_1_passed test_setup_fail) | |||||
set_tests_properties( | |||||
test_setup_fail_1_passed | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ PASSED \\] 1 test\\(s\\)." | |||||
) | |||||
add_test (test_setup_fail_match_failed test_setup_fail) | |||||
set_tests_properties( | |||||
test_setup_fail_match_failed | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ ERROR \\] int_test_ignored" | |||||
) | |||||
add_test (test_setup_fail_match_passed test_setup_fail) | |||||
set_tests_properties( | |||||
test_setup_fail_match_passed | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
"\\[ OK \\] int_test_success" | |||||
) | |||||
### Output formats | |||||
# test output of success, failure, skip, fixture failure | |||||
set(OUTPUT_TESTS | |||||
test_basics | |||||
test_assert_macros_fail | |||||
test_groups | |||||
test_skip | |||||
test_setup_fail) | |||||
set(TEST_OUTPUT_FMTS | |||||
tap | |||||
subunit | |||||
xml) | |||||
set(test_basics_tap_out | |||||
"^1\\.\\.2" | |||||
"ok 1 - null_test_success" | |||||
"ok 2 - int_test_success" | |||||
"# ok - tests") | |||||
set(test_assert_macros_fail_tap_out | |||||
"^1\\.\\.1" | |||||
"not ok 1 - test_assert_return_code_fail" | |||||
"#[^\n\r]+[\n\r]#[^\n\r]+[\n\r]# not ok - tests") | |||||
set(test_groups_tap_out | |||||
"^1\\.\\.1" | |||||
"ok 1 - null_test_success" | |||||
"# ok - test_group1" | |||||
"1\\.\\.1" | |||||
"ok 1 - int_test_success" | |||||
"# ok - test_group2") | |||||
set(test_skip_tap_out | |||||
"not ok 1 # SKIP") | |||||
set(test_setup_fail_tap_out | |||||
"not ok 1 - int_test_ignored Could not run test: Test setup failed") | |||||
set(test_basics_subunit_out | |||||
"^test: null_test_success" | |||||
"success: null_test_success") | |||||
set(test_assert_macros_fail_subunit_out | |||||
"failure: test_assert_return_code_fail \\[") | |||||
set(test_groups_subunit_out | |||||
"^test: null_test_success" | |||||
"success: null_test_success") | |||||
set(test_skip_subunit_out | |||||
"^test: test_check_skip" | |||||
"skip: test_check_skip") | |||||
set(test_setup_fail_subunit_out | |||||
"error: int_test_ignored \\[ Could not run test: Test setup failed \\]") | |||||
set(test_basics_xml_out | |||||
"<testsuite name=\"tests\" time=\"[0-9.]+\" tests=\"2\" failures=\"0\" errors=\"0\" skipped=\"0\" >" | |||||
"<testcase name=\"null_test_success\" time=\"[0-9.]+\" >.*</testcase>") | |||||
set(test_assert_macros_fail_xml_out | |||||
"<testcase name=\"test_assert_return_code_fail\" time=\"[0-9.]+\" >" | |||||
"<failure>") | |||||
set(test_groups_xml_out | |||||
"^<\\?xml version=\"1.0\" encoding=\"UTF-8\" \\?>" | |||||
"<testsuites>" | |||||
"<testsuite name=\"test_group1\" time=\"[0-9.]+\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\" >" | |||||
"<testcase name=\"null_test_success\" time=\"[0-9.]+\" >" | |||||
"</testcase>" | |||||
"</testsuite>" | |||||
".*<testsuite name=\"test_group2\" time=\"[0-9.]+\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\" >" | |||||
"<testcase name=\"int_test_success\" time=\"[0-9.]+\" >" | |||||
"</testcase>" | |||||
"</testsuite>" | |||||
"</testsuites>") | |||||
set(test_skip_xml_out | |||||
"<testcase name=\"test_check_skip\" time=\"[0-9.]+\" >" | |||||
"<skipped/>") | |||||
set(test_setup_fail_xml_out | |||||
"<testcase name=\"int_test_ignored\" time=\"[0-9.]+\" >" | |||||
"<failure><!\\[CDATA\\[Test setup failed\\]\\]></failure>") | |||||
foreach(_TEST_OUTPUT_FMT ${TEST_OUTPUT_FMTS}) | |||||
foreach(_OUTPUT_TEST ${OUTPUT_TESTS}) | |||||
set(TEST_NAME ${_OUTPUT_TEST}_${_TEST_OUTPUT_FMT}) | |||||
add_test(${TEST_NAME} ${_OUTPUT_TEST}) | |||||
set_property( | |||||
TEST | |||||
${TEST_NAME} | |||||
PROPERTY | |||||
ENVIRONMENT CMOCKA_MESSAGE_OUTPUT=${_TEST_OUTPUT_FMT} | |||||
) | |||||
list(LENGTH ${TEST_NAME}_out len) | |||||
list(GET ${TEST_NAME}_out 0 output) | |||||
if(len GREATER 1) | |||||
list(REMOVE_AT ${TEST_NAME}_out 0) | |||||
foreach(line ${${TEST_NAME}_out}) | |||||
set(output "${output}[ \n\r]+${line}") | |||||
endforeach() | |||||
endif() | |||||
set_tests_properties( | |||||
${TEST_NAME} | |||||
PROPERTIES | |||||
PASS_REGULAR_EXPRESSION | |||||
${output} | |||||
) | |||||
endforeach() | |||||
endforeach() |
@@ -0,0 +1,74 @@ | |||||
## The directory to run ctest in. | |||||
set(CTEST_DIRECTORY "$ENV{HOME}/workspace/tmp/dashboards/cmocka") | |||||
## The hostname of the machine | |||||
set(CTEST_SITE "host.cmocka.org") | |||||
## The buildname | |||||
set(CTEST_BUILD_NAME "Linux_GCC_x86_64_default") | |||||
## The Makefile generator to use | |||||
set(CTEST_CMAKE_GENERATOR "Unix Makefiles") | |||||
## The Build configuration to use. | |||||
set(CTEST_BUILD_CONFIGURATION "Debug") | |||||
## The build options for the project | |||||
set(CTEST_BUILD_OPTIONS "-DUNIT_TESTING=ON -DWITH_CMOCKERY_SUPPORT=ON") | |||||
#set(CTEST_CUSTOM_MEMCHECK_IGNORE torture_rand) | |||||
## The Model to set: Nightly, Continous, Experimental | |||||
set(CTEST_MODEL "Experimental") | |||||
## The URL to the git repository | |||||
set(CTEST_GIT_REPOSITORY "git://git.cryptomilk.org/projects/cmocka.git") | |||||
## The branch | |||||
#set(CTEST_GIT_BRANCH "--branch v0-5") | |||||
## Wether to enable memory checking. | |||||
set(WITH_MEMCHECK FALSE) | |||||
## Wether to enable code coverage. | |||||
set(WITH_COVERAGE FALSE) | |||||
####################################################################### | |||||
if (WITH_COVERAGE AND NOT WIN32) | |||||
set(CTEST_BUILD_CONFIGURATION "Profiling") | |||||
endif (WITH_COVERAGE AND NOT WIN32) | |||||
set(CTEST_SOURCE_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/source") | |||||
set(CTEST_BINARY_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/build") | |||||
set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/valgrind.supp) | |||||
find_program(CTEST_GIT_COMMAND NAMES git) | |||||
find_program(CTEST_COVERAGE_COMMAND NAMES gcov) | |||||
find_program(CTEST_MEMORYCHECK_COMMAND NAMES valgrind) | |||||
if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}") | |||||
set(CTEST_CHECKOUT_COMMAND "${CTEST_GIT_COMMAND} clone ${CTEST_GIT_BRANCH} ${CTEST_GIT_REPOSITORY} ${CTEST_SOURCE_DIRECTORY}") | |||||
endif() | |||||
set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}") | |||||
set(CTEST_CONFIGURE_COMMAND "${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}") | |||||
set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} ${CTEST_BUILD_OPTIONS}") | |||||
set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} \"-G${CTEST_CMAKE_GENERATOR}\"") | |||||
set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} \"${CTEST_SOURCE_DIRECTORY}\"") | |||||
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) | |||||
ctest_start(${CTEST_MODEL} TRACK ${CTEST_MODEL}) | |||||
ctest_update(SOURCE ${CTEST_SOURCE_DIRECTORY}) | |||||
ctest_configure(BUILD ${CTEST_BINARY_DIRECTORY}) | |||||
ctest_build(BUILD ${CTEST_BINARY_DIRECTORY}) | |||||
ctest_test(BUILD ${CTEST_BINARY_DIRECTORY}) | |||||
if (WITH_MEMCHECK AND CTEST_COVERAGE_COMMAND) | |||||
ctest_coverage(BUILD ${CTEST_BINARY_DIRECTORY}) | |||||
endif (WITH_MEMCHECK AND CTEST_COVERAGE_COMMAND) | |||||
if (WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) | |||||
ctest_memcheck(BUILD ${CTEST_BINARY_DIRECTORY}) | |||||
endif (WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) | |||||
ctest_submit() |
@@ -0,0 +1,6 @@ | |||||
DEFS=-I../../include -DHAVE_STDIO_H -DHAVE_SETJMP_H | |||||
all: | |||||
gcc $(DEFS) -o cmocka.o -c ../../src/cmocka.c | |||||
gcc $(DEFS) -o test_basics.o -c ../test_basics.c | |||||
gcc $(DEFS) -o a.out test_basics.o cmocka.o |
@@ -0,0 +1,91 @@ | |||||
#include "config.h" | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <cmocka_private.h> | |||||
#include <stdlib.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
static void torture_test_malloc(void **state) | |||||
{ | |||||
char *str; | |||||
size_t str_len; | |||||
size_t len; | |||||
(void)state; /* unsused */ | |||||
str_len = 12; | |||||
str = (char *)test_malloc(str_len); | |||||
assert_non_null(str); | |||||
len = snprintf(str, str_len, "test string"); | |||||
assert_int_equal(len, 11); | |||||
len = strlen(str); | |||||
assert_int_equal(len, 11); | |||||
test_free(str); | |||||
} | |||||
static void torture_test_realloc(void **state) | |||||
{ | |||||
char *str; | |||||
char *tmp; | |||||
size_t str_len; | |||||
size_t len; | |||||
(void)state; /* unsused */ | |||||
str_len = 16; | |||||
str = (char *)test_malloc(str_len); | |||||
assert_non_null(str); | |||||
len = snprintf(str, str_len, "test string 123"); | |||||
assert_int_equal(len, 15); | |||||
len = strlen(str); | |||||
assert_int_equal(len, 15); | |||||
str_len = 20; | |||||
tmp = test_realloc(str, str_len); | |||||
assert_non_null(tmp); | |||||
str = tmp; | |||||
len = strlen(str); | |||||
assert_string_equal(tmp, "test string 123"); | |||||
snprintf(str + len, str_len - len, "4567"); | |||||
assert_string_equal(tmp, "test string 1234567"); | |||||
test_free(str); | |||||
} | |||||
static void torture_test_realloc_set0(void **state) | |||||
{ | |||||
char *str; | |||||
size_t str_len; | |||||
(void)state; /* unsused */ | |||||
str_len = 16; | |||||
str = (char *)test_malloc(str_len); | |||||
assert_non_null(str); | |||||
/* realloc(ptr, 0) is like a free() */ | |||||
str = (char *)test_realloc(str, 0); | |||||
assert_null(str); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest alloc_tests[] = { | |||||
cmocka_unit_test(torture_test_malloc), | |||||
cmocka_unit_test(torture_test_realloc), | |||||
cmocka_unit_test(torture_test_realloc_set0), | |||||
}; | |||||
return cmocka_run_group_tests(alloc_tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,41 @@ | |||||
#include "config.h" | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <cmocka_private.h> | |||||
#include <errno.h> | |||||
#include <sys/types.h> | |||||
#include <sys/stat.h> | |||||
#ifdef HAVE_UNISTD_H | |||||
#include <unistd.h> | |||||
#endif | |||||
#include <fcntl.h> | |||||
/************************************** | |||||
*** assert_return_code | |||||
**************************************/ | |||||
static void test_assert_return_code(void **state) | |||||
{ | |||||
struct stat sb; | |||||
int rc; | |||||
(void)state; /* unused */ | |||||
rc = stat(".", &sb); | |||||
assert_return_code(rc, 0); | |||||
#ifndef _MSC_VER | |||||
assert_true(S_ISDIR(sb.st_mode)); | |||||
#endif | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_assert_return_code), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,43 @@ | |||||
#include "config.h" | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <cmocka_private.h> | |||||
#include <errno.h> | |||||
#include <sys/types.h> | |||||
#include <sys/stat.h> | |||||
#ifdef HAVE_UNISTD_H | |||||
#include <unistd.h> | |||||
#endif | |||||
#ifdef HAVE_IO_H | |||||
#include <io.h> | |||||
#endif | |||||
#include <fcntl.h> | |||||
/************************************** | |||||
*** assert_return_code | |||||
**************************************/ | |||||
static void test_assert_return_code_fail(void **state) | |||||
{ | |||||
int fd; | |||||
(void)state; /* unused */ | |||||
fd = open("this_file_doesnt_exist.cmocka", 0); | |||||
assert_return_code(fd, errno); | |||||
if (fd >= 0) { | |||||
close(fd); | |||||
} | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_assert_return_code_fail), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,62 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
/* Use the unit test allocators */ | |||||
#define UNIT_TESTING 1 | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
static int setup(void **state) { | |||||
int *answer = malloc(sizeof(int)); | |||||
assert_non_null(answer); | |||||
*answer = 42; | |||||
*state = answer; | |||||
return 0; | |||||
} | |||||
static int teardown(void **state) { | |||||
free(*state); | |||||
return 0; | |||||
} | |||||
/* A test case that does nothing and succeeds. */ | |||||
static void null_test_success(void **state) { | |||||
(void) state; | |||||
} | |||||
/* A test case that does check if an int is equal. */ | |||||
static void int_test_success(void **state) { | |||||
int *answer = *state; | |||||
assert_int_equal(*answer, 42); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(null_test_success), | |||||
cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,32 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmockery/cmockery.h> | |||||
/* A test case that does nothing and succeeds. */ | |||||
static void null_test_success(void **state) { | |||||
(void) state; /* unused */ | |||||
} | |||||
int main(void) { | |||||
const UnitTest tests[] = { | |||||
unit_test(null_test_success), | |||||
}; | |||||
return run_tests(tests); | |||||
} |
@@ -0,0 +1,30 @@ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <stdlib.h> | |||||
struct test_segv { | |||||
int x; | |||||
int y; | |||||
}; | |||||
static void test_segfault_recovery(void **state) | |||||
{ | |||||
struct test_segv *s = NULL; | |||||
(void) state; /* unused */ | |||||
s->x = 1; | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_segfault_recovery), | |||||
cmocka_unit_test(test_segfault_recovery), | |||||
cmocka_unit_test(test_segfault_recovery), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,82 @@ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <stdlib.h> | |||||
static int setup_only(void **state) | |||||
{ | |||||
*state = malloc(1); | |||||
return 0; | |||||
} | |||||
static int teardown_only(void **state) | |||||
{ | |||||
free(*state); | |||||
return 0; | |||||
} | |||||
static void malloc_setup_test(void **state) | |||||
{ | |||||
assert_non_null(*state); | |||||
free(*state); | |||||
} | |||||
static void malloc_teardown_test(void **state) | |||||
{ | |||||
*state = malloc(1); | |||||
assert_non_null(*state); | |||||
} | |||||
static int prestate_setup(void **state) | |||||
{ | |||||
int *val = (int *)*state, *a; | |||||
a = malloc(sizeof(int)); | |||||
*a = *val + 1; | |||||
*state = a; | |||||
return 0; | |||||
} | |||||
static int prestate_teardown(void **state) | |||||
{ | |||||
free(*state); | |||||
return 0; | |||||
} | |||||
static void prestate_setup_test(void **state) | |||||
{ | |||||
int *a = (int *)*state; | |||||
assert_non_null(a); | |||||
assert_int_equal(*a, 43); | |||||
} | |||||
static void prestate_test(void **state) | |||||
{ | |||||
int *a = (int *)*state; | |||||
assert_non_null(a); | |||||
assert_int_equal(*a, 42); | |||||
} | |||||
int main(void) { | |||||
int prestate = 42; | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test_setup(malloc_setup_test, setup_only), | |||||
cmocka_unit_test_setup(malloc_setup_test, setup_only), | |||||
cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), | |||||
cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), | |||||
cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), | |||||
cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), | |||||
cmocka_unit_test_prestate(prestate_test, &prestate), | |||||
cmocka_unit_test_prestate_setup_teardown(prestate_setup_test, prestate_setup, prestate_teardown, &prestate), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,50 @@ | |||||
/* Use the unit test allocators */ | |||||
#define UNIT_TESTING 1 | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
static int group_setup(void **state) | |||||
{ | |||||
int *answer = malloc(sizeof(int)); | |||||
assert_non_null(answer); | |||||
*answer = 42; | |||||
*state = answer; | |||||
return 0; | |||||
} | |||||
static int group_teardown(void **state) | |||||
{ | |||||
int *answer = (int *)*state; | |||||
free(answer); | |||||
return 0; | |||||
} | |||||
static void test_value_equal(void **state) | |||||
{ | |||||
int a = *((int *)*state); | |||||
assert_int_equal(a, 42); | |||||
} | |||||
static void test_value_range(void **state) | |||||
{ | |||||
int a = *((int *)*state); | |||||
assert_in_range(a, 0, 100); | |||||
} | |||||
int main(void) { | |||||
int prestate = 1337; | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_value_equal), | |||||
cmocka_unit_test(test_value_range), | |||||
cmocka_unit_test_prestate(test_value_equal, &prestate), | |||||
}; | |||||
return cmocka_run_group_tests(tests, group_setup, group_teardown); | |||||
} |
@@ -0,0 +1,37 @@ | |||||
/* Use the unit test allocators */ | |||||
#define UNIT_TESTING 1 | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
static int group_setup_failing(void **state) | |||||
{ | |||||
(void) state; /* unused */ | |||||
assert_int_equal(0, 1); | |||||
return 0; | |||||
} | |||||
static void test_true(void **state) | |||||
{ | |||||
(void) state; /* unused */ | |||||
assert_true(1); | |||||
} | |||||
static void test_false(void **state) | |||||
{ | |||||
(void) state; /* unused */ | |||||
assert_false(0); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_true), | |||||
cmocka_unit_test(test_false), | |||||
}; | |||||
return cmocka_run_group_tests(tests, group_setup_failing, NULL); | |||||
} |
@@ -0,0 +1,34 @@ | |||||
/* Use the unit test allocators */ | |||||
#define UNIT_TESTING 1 | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
static int group_setup_failing(void **state) | |||||
{ | |||||
(void) state; /* unused */ | |||||
return 1; /* To indicate the failure */ | |||||
} | |||||
static void test_true(void **state) | |||||
{ | |||||
(void) state; /* unused */ | |||||
assert_true(1); | |||||
} | |||||
static void test_false(void **state) | |||||
{ | |||||
(void) state; /* unused */ | |||||
assert_false(0); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_true), | |||||
cmocka_unit_test(test_false), | |||||
}; | |||||
return cmocka_run_group_tests(tests, group_setup_failing, NULL); | |||||
} |
@@ -0,0 +1,69 @@ | |||||
/* | |||||
* Copyright 2016 David Schneider <schneidav81@gmail.com> | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
/* Use the unit test allocators */ | |||||
#define UNIT_TESTING 1 | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
static int setup(void **state) { | |||||
int *answer = malloc(sizeof(int)); | |||||
assert_non_null(answer); | |||||
*answer = 42; | |||||
*state = answer; | |||||
return 0; | |||||
} | |||||
static int teardown(void **state) { | |||||
free(*state); | |||||
return 0; | |||||
} | |||||
/* A test case that does nothing and succeeds. */ | |||||
static void null_test_success(void **state) { | |||||
(void) state; | |||||
} | |||||
/* A test case that does check if an int is equal. */ | |||||
static void int_test_success(void **state) { | |||||
int *answer = *state; | |||||
assert_int_equal(*answer, 42); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest test_group1[] = { | |||||
cmocka_unit_test(null_test_success), | |||||
}; | |||||
const struct CMUnitTest test_group2[] = { | |||||
cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), | |||||
}; | |||||
int result = 0; | |||||
result += cmocka_run_group_tests(test_group1, NULL, NULL); | |||||
result += cmocka_run_group_tests(test_group2, NULL, NULL); | |||||
return result; | |||||
} |
@@ -0,0 +1,112 @@ | |||||
#include "config.h" | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <cmocka_private.h> | |||||
static void mock_test_a_called(void) | |||||
{ | |||||
function_called(); | |||||
} | |||||
static void mock_test_b_called(void) | |||||
{ | |||||
function_called(); | |||||
} | |||||
static void mock_test_c_called(void) | |||||
{ | |||||
function_called(); | |||||
} | |||||
static void test_does_succeed_for_expected(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call(mock_test_a_called); | |||||
expect_function_call(mock_test_a_called); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
} | |||||
static void test_does_succeed_for_multiple_calls(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call(mock_test_a_called); | |||||
expect_function_calls(mock_test_a_called, 2); | |||||
expect_function_call(mock_test_a_called); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
} | |||||
static void test_ordering_does_ignore_calls(void **state) | |||||
{ | |||||
(void)state; | |||||
ignore_function_calls(mock_test_a_called); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
} | |||||
static void test_ordering_does_ignore_no_calls(void **state) | |||||
{ | |||||
(void)state; | |||||
ignore_function_calls(mock_test_a_called); | |||||
} | |||||
static void test_ordering_does_expect_at_least_one_call(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call_any(mock_test_a_called); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
} | |||||
static void test_ordering_does_work_across_different_functions(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call(mock_test_a_called); | |||||
expect_function_call(mock_test_b_called); | |||||
expect_function_call(mock_test_a_called); | |||||
mock_test_a_called(); | |||||
mock_test_b_called(); | |||||
mock_test_a_called(); | |||||
} | |||||
static void test_ordering_ignores_out_of_order_properly(void **state) | |||||
{ | |||||
(void)state; | |||||
ignore_function_calls(mock_test_a_called); | |||||
ignore_function_calls(mock_test_b_called); | |||||
expect_function_calls(mock_test_c_called, 2); | |||||
mock_test_c_called(); | |||||
mock_test_b_called(); | |||||
mock_test_c_called(); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_does_succeed_for_expected) | |||||
,cmocka_unit_test(test_does_succeed_for_multiple_calls) | |||||
,cmocka_unit_test(test_ordering_does_ignore_no_calls) | |||||
,cmocka_unit_test(test_ordering_does_ignore_calls) | |||||
,cmocka_unit_test(test_ordering_does_expect_at_least_one_call) | |||||
,cmocka_unit_test(test_ordering_does_work_across_different_functions) | |||||
,cmocka_unit_test(test_ordering_ignores_out_of_order_properly) | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,95 @@ | |||||
#include "config.h" | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <cmocka_private.h> | |||||
static void mock_test_a_called(void) | |||||
{ | |||||
function_called(); | |||||
} | |||||
static void mock_test_b_called(void) | |||||
{ | |||||
function_called(); | |||||
} | |||||
static void mock_test_c_called(void) | |||||
{ | |||||
function_called(); | |||||
} | |||||
static void test_does_fail_for_unexpected_call(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call(mock_test_a_called); | |||||
expect_function_call(mock_test_a_called); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
mock_test_a_called(); | |||||
} | |||||
static void test_does_fail_for_unmade_expected_call(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call(mock_test_a_called); | |||||
expect_function_call(mock_test_a_called); | |||||
mock_test_a_called(); | |||||
} | |||||
static void test_ordering_fails_out_of_order(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call(mock_test_a_called); | |||||
expect_function_call(mock_test_b_called); | |||||
expect_function_call(mock_test_a_called); | |||||
mock_test_b_called(); | |||||
} | |||||
static void test_ordering_fails_out_of_order_for_at_least_once_calls(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call_any(mock_test_a_called); | |||||
ignore_function_calls(mock_test_b_called); | |||||
mock_test_b_called(); | |||||
mock_test_c_called(); | |||||
} | |||||
/* Primarily used to test error message */ | |||||
static void test_fails_out_of_order_if_no_calls_found_on_any(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_call_any(mock_test_a_called); | |||||
ignore_function_calls(mock_test_b_called); | |||||
mock_test_a_called(); | |||||
mock_test_c_called(); | |||||
} | |||||
static void test_fails_if_zero_count_used(void **state) | |||||
{ | |||||
(void)state; | |||||
expect_function_calls(mock_test_a_called, 0); | |||||
mock_test_a_called(); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_does_fail_for_unexpected_call) | |||||
,cmocka_unit_test(test_does_fail_for_unmade_expected_call) | |||||
,cmocka_unit_test(test_does_fail_for_unmade_expected_call) | |||||
,cmocka_unit_test(test_ordering_fails_out_of_order) | |||||
,cmocka_unit_test(test_ordering_fails_out_of_order_for_at_least_once_calls) | |||||
,cmocka_unit_test(test_fails_out_of_order_if_no_calls_found_on_any) | |||||
,cmocka_unit_test(test_fails_if_zero_count_used) | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,69 @@ | |||||
#include "config.h" | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <cmocka_private.h> | |||||
#include <stdlib.h> | |||||
int mock_function(void); | |||||
void mock_function_call_times(size_t times, int expectedValue); | |||||
int mock_function(void) | |||||
{ | |||||
return (int) mock(); | |||||
} | |||||
void mock_function_call_times(size_t times, int expectedValue) | |||||
{ | |||||
size_t i; | |||||
for (i = 0u; i < times; ++i) | |||||
{ | |||||
assert_int_equal(expectedValue, mock_function()); | |||||
} | |||||
} | |||||
static void test_will_return_maybe_for_no_calls(void **state) | |||||
{ | |||||
(void) state; | |||||
will_return_maybe(mock_function, 32); | |||||
} | |||||
static void test_will_return_maybe_for_one_mock_call(void **state) | |||||
{ | |||||
int value; | |||||
(void) state; | |||||
value = rand(); | |||||
will_return_maybe(mock_function, value); | |||||
mock_function_call_times(1u, value); | |||||
} | |||||
static void test_will_return_maybe_for_more_than_one_call(void **state) | |||||
{ | |||||
int value; | |||||
size_t numberOfCalls; | |||||
(void)state; | |||||
value = rand(); | |||||
numberOfCalls = (size_t) ((rand()) % 20 + 2); | |||||
will_return_maybe(mock_function, value); | |||||
mock_function_call_times(numberOfCalls, value); | |||||
} | |||||
int main(int argc, char **argv) { | |||||
const struct CMUnitTest alloc_tests[] = { | |||||
cmocka_unit_test(test_will_return_maybe_for_no_calls) | |||||
,cmocka_unit_test(test_will_return_maybe_for_one_mock_call) | |||||
,cmocka_unit_test(test_will_return_maybe_for_more_than_one_call) | |||||
}; | |||||
(void)argc; | |||||
(void)argv; | |||||
return cmocka_run_group_tests(alloc_tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,77 @@ | |||||
#include "config.h" | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
#include <cmocka_private.h> | |||||
#include <stdlib.h> | |||||
int mock_function(void); | |||||
void mock_function_call_times(size_t times, int expectedValue); | |||||
int mock_function(void) | |||||
{ | |||||
return (int) mock(); | |||||
} | |||||
void mock_function_call_times(size_t times, int expectedValue) | |||||
{ | |||||
size_t i; | |||||
for (i = 0u; i < times; ++i) | |||||
{ | |||||
assert_int_equal(expectedValue, mock_function()); | |||||
} | |||||
} | |||||
static void test_will_return_fails_for_no_calls(void **state) | |||||
{ | |||||
(void) state; | |||||
will_return(mock_function, 32); | |||||
} | |||||
static void test_will_return_count_fails_for_unreturned_items(void **state) | |||||
{ | |||||
int value; | |||||
size_t numberOfCalls; | |||||
(void) state; | |||||
value = rand(); | |||||
numberOfCalls = (size_t) ((rand()) % 20 + 2); | |||||
will_return_count(mock_function, value, numberOfCalls); | |||||
mock_function_call_times(numberOfCalls - 1u, value); | |||||
} | |||||
static void test_will_return_always_fails_for_no_calls(void **state) | |||||
{ | |||||
int value; | |||||
(void) state; | |||||
value = rand(); | |||||
will_return_always(mock_function, value); | |||||
} | |||||
static int teardown(void **state) { | |||||
free(*state); | |||||
return 0; | |||||
} | |||||
int main(int argc, char **argv) { | |||||
const struct CMUnitTest alloc_tests[] = { | |||||
cmocka_unit_test_teardown(test_will_return_fails_for_no_calls, teardown) | |||||
,cmocka_unit_test_teardown(test_will_return_count_fails_for_unreturned_items, teardown) | |||||
,cmocka_unit_test_teardown(test_will_return_always_fails_for_no_calls, teardown) | |||||
}; | |||||
(void)argc; | |||||
(void)argv; | |||||
return cmocka_run_group_tests(alloc_tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,54 @@ | |||||
#define UNIT_TESTING 1 | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
static int setup_fail(void **state) { | |||||
*state = NULL; | |||||
/* We need to fail in setup */ | |||||
return -1; | |||||
} | |||||
static void int_test_ignored(void **state) { | |||||
/* should not be called */ | |||||
assert_non_null(*state); | |||||
} | |||||
static int setup_ok(void **state) { | |||||
int *answer; | |||||
answer = malloc(sizeof(int)); | |||||
if (answer == NULL) { | |||||
return -1; | |||||
} | |||||
*answer = 42; | |||||
*state = answer; | |||||
return 0; | |||||
} | |||||
/* A test case that does check if an int is equal. */ | |||||
static void int_test_success(void **state) { | |||||
int *answer = *state; | |||||
assert_int_equal(*answer, 42); | |||||
} | |||||
static int teardown(void **state) { | |||||
free(*state); | |||||
return 0; | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test_setup_teardown(int_test_ignored, setup_fail, teardown), | |||||
cmocka_unit_test_setup_teardown(int_test_success, setup_ok, teardown), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} |
@@ -0,0 +1,39 @@ | |||||
/* | |||||
* Copyright 2008 Google Inc. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stddef.h> | |||||
#include <setjmp.h> | |||||
#include <cmocka.h> | |||||
/* A test case that does check if an int is equal. */ | |||||
static void test_check_skip(void **state) { | |||||
(void)state; /* unused */ | |||||
skip(); | |||||
assert_true(0); | |||||
} | |||||
int main(void) { | |||||
const struct CMUnitTest tests[] = { | |||||
cmocka_unit_test(test_check_skip), | |||||
}; | |||||
return cmocka_run_group_tests(tests, NULL, NULL); | |||||
} | |||||
@@ -0,0 +1,6 @@ | |||||
[submodule "bssl/src"] | |||||
path = bssl/src | |||||
url = https://github.com/google/boringssl.git | |||||
[submodule "mbedtls/src"] | |||||
path = mbedtls/src | |||||
url = https://github.com/ARMmbed/mbedtls.git |
@@ -0,0 +1,278 @@ | |||||
# Additional information | |||||
A lot of, mostly useless, details | |||||
## Appendix A | |||||
Default NDK flags | |||||
* CC: | |||||
``` | |||||
--target=aarch64-none-linux-android | |||||
-DBORINGSSL_IMPLEMENTATION | |||||
-g | |||||
-DANDROID | |||||
-ffunction-sections | |||||
-funwind-tables | |||||
-fstack-protector-strong | |||||
-no-canonical-prefixes | |||||
-Wa,--noexecstack | |||||
-Wformat | |||||
-Werror=format-security | |||||
-Werror | |||||
-Wformat=2 | |||||
-Wsign-compare | |||||
-Wmissing-field-initializers | |||||
-Wwrite-strings | |||||
-Wall | |||||
-ggdb | |||||
-fvisibility=hidden | |||||
-fno-common | |||||
-Wnewline-eof | |||||
-fcolor-diagnostics | |||||
-Wimplicit-fallthrough | |||||
-Wmissing-prototypes | |||||
-Wold-style-definition | |||||
-Wstrict-prototypes | |||||
-Wshadow | |||||
-D_XOPEN_SOURCE=700 | |||||
-O2 | |||||
-DNDEBUG | |||||
-fPIC | |||||
``` | |||||
* CPP: | |||||
``` | |||||
-cc1 | |||||
-triple aarch64-none-linux-android | |||||
-emit-obj | |||||
-mnoexecstack | |||||
-disable-free | |||||
-disable-llvm-verifier | |||||
-discard-value-names | |||||
-mrelocation-model pic | |||||
-pic-level 2 | |||||
-pic-is-pie | |||||
-mthread-model posix | |||||
-mdisable-fp-elim | |||||
-fmath-errno | |||||
-masm-verbose | |||||
-mconstructor-aliases | |||||
-munwind-tables | |||||
-fuse-init-array | |||||
-target-cpu generic | |||||
-target-feature +neon | |||||
-target-abi aapcs | |||||
-dwarf-column-info | |||||
-debug-info-kind=limited | |||||
-dwarf-version=4 | |||||
-debugger-tuning=gdb | |||||
-ffunction-sections | |||||
-D BORINGSSL_IMPLEMENTATION | |||||
-D ANDROID | |||||
-D NDEBUG | |||||
-O2 | |||||
-Wformat | |||||
-Werror=format-security | |||||
-Werror | |||||
-Wformat=2 | |||||
-Wsign-compare | |||||
-Wmissing-field-initializers | |||||
-Wwrite-strings | |||||
-Wall | |||||
-Wnewline-eof | |||||
-Wimplicit-fallthrough | |||||
-Wmissing-declarations | |||||
-Wmissing-prototypes | |||||
-Wshadow | |||||
-std=c++11 | |||||
-fdeprecated-macro | |||||
-fdebug-compilation-dir /home/hdc/repos/mbedtls_vs_boringssl/bssl/src/build/crypto | |||||
-ferror-limit 19 | |||||
-fmessage-length 238 | |||||
-fvisibility hidden | |||||
-femulated-tls | |||||
-stack-protector 2 | |||||
-fallow-half-arguments-and-returns | |||||
-fno-rtti | |||||
-fno-signed-char | |||||
-fobjc-runtime=gcc | |||||
-fno-common | |||||
-fdiagnostics-show-option | |||||
-fcolor-diagnostics | |||||
-vectorize-loops | |||||
-vectorize-slp | |||||
``` | |||||
## Appendix B | |||||
Test platform settings | |||||
``` | |||||
[ro.build.id]: [OPR6.170623.013] | |||||
[ro.bootimage.build.date]: [Wed Oct 11 15:46:15 BST 2017] | |||||
[ro.bootimage.build.fingerprint]: [Android/hikey/hikey:8.0.0/OPR6.170623.013/110:userdebug/test-keys] | |||||
[ro.product.cpu.abi]: [arm64-v8a] | |||||
[ro.product.cpu.abilist]: [arm64-v8a,armeabi-v7a,armeabi] | |||||
[ro.product.cpu.abilist32]: [armeabi-v7a,armeabi] | |||||
[ro.product.cpu.abilist64]: [arm64-v8a] | |||||
[ro.build.version.sdk]: [26] | |||||
[ro.build.version.security_patch]: [2017-08-05] | |||||
``` | |||||
## Appendix C | |||||
Performance measures provied by ``bssl speed``: | |||||
| Operation | Small | Default | | |||||
|-----------|------|---------| | |||||
|RSA 2048 signing | (59.5 ops/sec) | (108.1 ops/sec) | | |||||
|RSA 2048 verify | (2377.5 ops/sec) | (4078.3 ops/sec) | | |||||
|RSA 4096 signing | (8.3 ops/sec) | (14.9 ops/sec) | | |||||
|RSA 4096 verify | (668.0 ops/sec) | (1088.4 ops/sec) | | |||||
|AES-128-GCM (16 bytes) | (497832.2 ops/sec): 8.0 MB/s | (1690241.1 ops/sec): 27.0 MB/s | | |||||
|AES-128-GCM (1350 bytes) | (17675.4 ops/sec): 23.9 MB/s | (291430.3 ops/sec): 393.4 MB/s | | |||||
|AES-128-GCM (8192 bytes) | (2991.6 ops/sec): 24.5 MB/s | (57088.8 ops/sec): 467.7 MB/s | | |||||
|AES-256-GCM (16 bytes) | (444847.4 ops/sec): 7.1 MB/s | (1615148.8 ops/sec): 25.8 MB/s | | |||||
|AES-256-GCM (1350 bytes) | (14792.6 ops/sec): 20.0 MB/s | (254718.5 ops/sec): 343.9 MB/s | | |||||
|AES-256-GCM (8192 bytes) | (2525.7 ops/sec): 20.7 MB/s | (49056.6 ops/sec): 401.9 MB/s | | |||||
|ChaCha20-Poly1305 (16 bytes) | (385043.6 ops/sec): 6.2 MB/s | (460788.5 ops/sec): 7.4 MB/s | | |||||
|ChaCha20-Poly1305 (1350 bytes) | (33108.8 ops/sec): 44.7 MB/s | (67622.8 ops/sec): 91.3 MB/s | | |||||
|ChaCha20-Poly1305 (8192 bytes) | (5905.1 ops/sec): 48.4 MB/s | (13219.5 ops/sec): 108.3 MB/s | | |||||
|DES-EDE3-CBC-SHA1 (16 bytes) | (100311.5 ops/sec): 1.6 MB/s | (110073.3 ops/sec): 1.8 MB/s | | |||||
|DES-EDE3-CBC-SHA1 (1350 bytes) | (3787.2 ops/sec): 5.1 MB/s | (3926.7 ops/sec): 5.3 MB/s | | |||||
|DES-EDE3-CBC-SHA1 (8192 bytes) | (638.4 ops/sec): 5.2 MB/s | (661.2 ops/sec): 5.4 MB/s | | |||||
|AES-128-CBC-SHA1 (16 bytes) | (268159.9 ops/sec): 4.3 MB/s | (540844.8 ops/sec): 8.7 MB/s | | |||||
|AES-128-CBC-SHA1 (1350 bytes) | (22535.6 ops/sec): 30.4 MB/s | (162597.6 ops/sec): 219.5 MB/s | | |||||
|AES-128-CBC-SHA1 (8192 bytes) | (3959.9 ops/sec): 32.4 MB/s | (37787.3 ops/sec): 309.6 MB/s | | |||||
|AES-256-CBC-SHA1 (16 bytes) | (244904.2 ops/sec): 3.9 MB/s | (524976.9 ops/sec): 8.4 MB/s | | |||||
|AES-256-CBC-SHA1 (1350 bytes) | (18272.3 ops/sec): 24.7 MB/s | (141626.7 ops/sec): 191.2 MB/s | | |||||
|AES-256-CBC-SHA1 (8192 bytes) | (3181.3 ops/sec): 26.1 MB/s | (31195.9 ops/sec): 255.6 MB/s | | |||||
|AES-128-GCM-SIV (16 bytes) | (244929.5 ops/sec): 3.9 MB/s | (776750.7 ops/sec): 12.4 MB/s | | |||||
|AES-128-GCM-SIV (1350 bytes) | (14640.5 ops/sec): 19.8 MB/s | (66627.7 ops/sec): 89.9 MB/s | | |||||
|AES-128-GCM-SIV (8192 bytes) | (2531.6 ops/sec): 20.7 MB/s | (11850.0 ops/sec): 97.1 MB/s | | |||||
|AES-256-GCM-SIV (16 bytes) | (171899.3 ops/sec): 2.8 MB/s | (660748.9 ops/sec): 10.6 MB/s | | |||||
|AES-256-GCM-SIV (1350 bytes) | (12489.6 ops/sec): 16.9 MB/s | (61124.5 ops/sec): 82.5 MB/s | | |||||
|AES-256-GCM-SIV (8192 bytes) | (2182.7 ops/sec): 17.9 MB/s | (10936.1 ops/sec): 89.6 MB/s | | |||||
|AES-128-GCM-SIV (16 bytes) | (239698.0 ops/sec): 3.8 MB/s | (733661.0 ops/sec): 11.7 MB/s | | |||||
|AES-128-GCM-SIV (1350 bytes) | (14616.0 ops/sec): 19.7 MB/s | (65984.0 ops/sec): 89.1 MB/s | | |||||
|AES-128-GCM-SIV (8192 bytes) | (2529.8 ops/sec): 20.7 MB/s | (11745.7 ops/sec): 96.2 MB/s | | |||||
|AES-256-GCM-SIV (16 bytes) | (170826.1 ops/sec): 2.7 MB/s | (626465.6 ops/sec): 10.0 MB/s | | |||||
|AES-256-GCM-SIV (1350 bytes) | (12474.8 ops/sec): 16.8 MB/s | (60595.5 ops/sec): 81.8 MB/s | | |||||
|AES-256-GCM-SIV (8192 bytes) | (2182.1 ops/sec): 17.9 MB/s | (10841.9 ops/sec): 88.8 MB/s | | |||||
|AES-128-CCM-Bluetooth (16 bytes) | (438558.8 ops/sec): 7.0 MB/s | (1405567.1 ops/sec): 22.5 MB/s | | |||||
|AES-128-CCM-Bluetooth (1350 bytes) | (14776.5 ops/sec): 19.9 MB/s | (140168.4 ops/sec): 189.2 MB/s | | |||||
|AES-128-CCM-Bluetooth (8192 bytes) | (2498.7 ops/sec): 20.5 MB/s | (25890.2 ops/sec): 212.1 MB/s | | |||||
|SHA-1 (16 bytes) | (1244563.2 ops/sec): 19.9 MB/s | (2567122.0 ops/sec): 41.1 MB/s | | |||||
|SHA-1 (256 bytes) | (341934.0 ops/sec): 87.5 MB/s | (1162590.8 ops/sec): 297.6 MB/s | | |||||
|SHA-1 (8192 bytes) | (14574.3 ops/sec): 119.4 MB/s | (66844.3 ops/sec): 547.6 MB/s | | |||||
|SHA-256 (16 bytes) | (691326.6 ops/sec): 11.1 MB/s | (2431927.0 ops/sec): 38.9 MB/s | | |||||
|SHA-256 (256 bytes) | (166138.9 ops/sec): 42.5 MB/s | (1120621.2 ops/sec): 286.9 MB/s | | |||||
|SHA-256 (8192 bytes) | (6824.7 ops/sec): 55.9 MB/s | (63214.7 ops/sec): 517.9 MB/s | | |||||
|SHA-512 (16 bytes) | (688007.9 ops/sec): 11.0 MB/s | (729988.3 ops/sec): 11.7 MB/s | | |||||
|SHA-512 (256 bytes) | (272146.5 ops/sec): 69.7 MB/s | (289178.7 ops/sec): 74.0 MB/s | | |||||
|SHA-512 (8192 bytes) | (14014.7 ops/sec): 114.8 MB/s | (14759.6 ops/sec): 120.9 MB/s | | |||||
|RNG (16 bytes) | (137217.4 ops/sec): 2.2 MB/s | (249239.3 ops/sec): 4.0 MB/s | | |||||
|RNG (256 bytes) | (69898.9 ops/sec): 17.9 MB/s | (224698.5 ops/sec): 57.5 MB/s | | |||||
|RNG (8192 bytes) | (4058.7 ops/sec): 33.2 MB/s | (55705.4 ops/sec): 456.3 MB/s | | |||||
|ECDH P-224 operations | (151.0 ops/sec) | (1602.4 ops/sec) | | |||||
|ECDH P-256 operations | (594.7 ops/sec) | (642.8 ops/sec) | | |||||
|ECDH P-384 operations | (59.0 ops/sec) | (97.4 ops/sec) | | |||||
|ECDH P-521 operations | (27.1 ops/sec) | (43.4 ops/sec) | | |||||
|ECDSA P-224 signing | (277.8 ops/sec) | (3312.7 ops/sec) | | |||||
|ECDSA P-224 verify | (241.2 ops/sec) | (1451.7 ops/sec) | | |||||
|ECDSA P-256 signing | (1396.6 ops/sec) | (1738.5 ops/sec) | | |||||
|ECDSA P-256 verify | (672.1 ops/sec) | (704.2 ops/sec) | | |||||
|ECDSA P-384 signing | (107.0 ops/sec) | (177.6 ops/sec) | | |||||
|ECDSA P-384 verify | (94.4 ops/sec) | (156.9 ops/sec) | | |||||
|ECDSA P-521 signing | (49.0 ops/sec) | (78.2 ops/sec) | | |||||
|ECDSA P-521 verify | (43.8 ops/sec) | (70.8 ops/sec) | | |||||
Performance measures provided by ``benchmark``: | |||||
| Algo | Small | Normal | | |||||
|-------------------------------|----------------------|----------------------| | |||||
|MD5 | 131223 KiB/s | 131761 KiB/s | | |||||
|RIPEMD160 | 81451 KiB/s | 89899 KiB/s | | |||||
|SHA-1 | 104117 KiB/s | 104375 KiB/s | | |||||
|SHA-256 | 46809 KiB/s | 52044 KiB/s | | |||||
|SHA-512 | 56760 KiB/s | 57648 KiB/s | | |||||
|ARC4 | 65014 KiB/s | 65023 KiB/s | | |||||
|3DES | 7785 KiB/s | 7885 KiB/s | | |||||
|DES | 19071 KiB/s | 19512 KiB/s | | |||||
|AES-CBC-128 | 32460 KiB/s | 35995 KiB/s | | |||||
|AES-CBC-192 | 28392 KiB/s | 31044 KiB/s | | |||||
|AES-CBC-256 | 25213 KiB/s | 27296 KiB/s | | |||||
|AES-GCM-128 | 16399 KiB/s | 16398 KiB/s | | |||||
|AES-GCM-192 | 15272 KiB/s | 15271 KiB/s | | |||||
|AES-GCM-256 | 14287 KiB/s | 14286 KiB/s | | |||||
|AES-CCM-128 | 15824 KiB/s | 15887 KiB/s | | |||||
|AES-CCM-192 | 13853 KiB/s | 13899 KiB/s | | |||||
|AES-CCM-256 | 12315 KiB/s | 12356 KiB/s | | |||||
|CAMELLIA-CBC-128 | 19735 KiB/s | 26762 KiB/s | | |||||
|CAMELLIA-CBC-192 | 15458 KiB/s | 20839 KiB/s | | |||||
|CAMELLIA-CBC-256 | 15459 KiB/s | 20839 KiB/s | | |||||
|BLOWFISH-CBC-128 | 25188 KiB/s | 28955 KiB/s | | |||||
|BLOWFISH-CBC-192 | 25189 KiB/s | 28954 KiB/s | | |||||
|BLOWFISH-CBC-256 | 25183 KiB/s | 28955 KiB/s | | |||||
|CTR_DRBG (NOPR) | 27122 KiB/s | 27050 KiB/s | | |||||
|CTR_DRBG (PR) | 18397 KiB/s | 19111 KiB/s | | |||||
|HMAC_DRBG SHA-1 (NOPR) | 6746 KiB/s | 6968 KiB/s | | |||||
|HMAC_DRBG SHA-1 (PR) | 6208 KiB/s | 6426 KiB/s | | |||||
|HMAC_DRBG SHA-256 (NOPR) | 5321 KiB/s | 5795 KiB/s | | |||||
|HMAC_DRBG SHA-256 (PR) | 4657 KiB/s | 5083 KiB/s | | |||||
|RSA-2048 | 652 public/s | 653 public/s | | |||||
|RSA-2048 | 17 private/s | 17 private/s | | |||||
|RSA-4096 | 168 public/s | 168 public/s | | |||||
|RSA-4096 | 3 private/s | 3 private/s | | |||||
|DHE-2048 | 3 handshake/s | 3 handshake/s | | |||||
|DH-2048 | 5 handshake/s | 6 handshake/s | | |||||
|DHE-3072 | 1 handshake/s | 1 handshake/s | | |||||
|DH-3072 | 2 handshake/s | 2 handshake/s | | |||||
|ECDSA-secp521r1 | 70 sign/s | 74 sign/s | | |||||
|ECDSA-brainpoolP512r1 | 8 sign/s | 9 sign/s | | |||||
|ECDSA-secp384r1 | 126 sign/s | 133 sign/s | | |||||
|ECDSA-brainpoolP384r1 | 16 sign/s | 18 sign/s | | |||||
|ECDSA-secp256r1 | 189 sign/s | 195 sign/s | | |||||
|ECDSA-secp256k1 | 176 sign/s | 189 sign/s | | |||||
|ECDSA-brainpoolP256r1 | 27 sign/s | 31 sign/s | | |||||
|ECDSA-secp224r1 | 277 sign/s | 291 sign/s | | |||||
|ECDSA-secp224k1 | 216 sign/s | 230 sign/s | | |||||
|ECDSA-secp192r1 | 329 sign/s | 352 sign/s | | |||||
|ECDSA-secp192k1 | 264 sign/s | 277 sign/s | | |||||
|ECDSA-secp521r1 | 19 verify/s | 21 verify/s | | |||||
|ECDSA-brainpoolP512r1 | 2 verify/s | 2 verify/s | | |||||
|ECDSA-secp384r1 | 35 verify/s | 36 verify/s | | |||||
|ECDSA-brainpoolP384r1 | 4 verify/s | 4 verify/s | | |||||
|ECDSA-secp256r1 | 54 verify/s | 57 verify/s | | |||||
|ECDSA-secp256k1 | 53 verify/s | 57 verify/s | | |||||
|ECDSA-brainpoolP256r1 | 7 verify/s | 8 verify/s | | |||||
|ECDSA-secp224r1 | 82 verify/s | 86 verify/s | | |||||
|ECDSA-secp224k1 | 63 verify/s | 67 verify/s | | |||||
|ECDSA-secp192r1 | 102 verify/s | 110 verify/s | | |||||
|ECDSA-secp192k1 | 77 verify/s | 82 verify/s | | |||||
|ECDHE-secp521r1 | 20 handshake/s | 21 handshake/s | | |||||
|ECDHE-brainpoolP512r1 | 2 handshake/s | 2 handshake/s | | |||||
|ECDHE-secp384r1 | 37 handshake/s | 39 handshake/s | | |||||
|ECDHE-brainpoolP384r1 | 4 handshake/s | 4 handshake/s | | |||||
|ECDHE-secp256r1 | 57 handshake/s | 60 handshake/s | | |||||
|ECDHE-secp256k1 | 56 handshake/s | 60 handshake/s | | |||||
|ECDHE-brainpoolP256r1 | 7 handshake/s | 8 handshake/s | | |||||
|ECDHE-secp224r1 | 89 handshake/s | 92 handshake/s | | |||||
|ECDHE-secp224k1 | 67 handshake/s | 71 handshake/s | | |||||
|ECDHE-secp192r1 | 111 handshake/s | 118 handshake/s | | |||||
|ECDHE-secp192k1 | 83 handshake/s | 87 handshake/s | | |||||
|ECDHE-Curve25519 | 41 handshake/s | 41 handshake/s | | |||||
|ECDH-secp521r1 | 27 handshake/s | 28 handshake/s | | |||||
|ECDH-brainpoolP512r1 | 3 handshake/s | 3 handshake/s | | |||||
|ECDH-secp384r1 | 49 handshake/s | 51 handshake/s | | |||||
|ECDH-brainpoolP384r1 | 5 handshake/s | 5 handshake/s | | |||||
|ECDH-secp256r1 | 77 handshake/s | 81 handshake/s | | |||||
|ECDH-secp256k1 | 78 handshake/s | 82 handshake/s | | |||||
|ECDH-brainpoolP256r1 | 9 handshake/s | 11 handshake/s | | |||||
|ECDH-secp224r1 | 121 handshake/s | 126 handshake/s | | |||||
|ECDH-secp224k1 | 91 handshake/s | 97 handshake/s | | |||||
|ECDH-secp192r1 | 150 handshake/s | 159 handshake/s | | |||||
|ECDH-secp192k1 | 113 handshake/s | 120 handshake/s | | |||||
|ECDH-Curve25519 | 80 handshake/s | 82 handshake/s | | |||||
@@ -0,0 +1,3 @@ | |||||
# BoringSSL and mbedTLS comparison | |||||
See here: http://hdc.amongbytes.com/post/201804-comparing-mbedtls-to-boringssl/ |
@@ -0,0 +1,29 @@ | |||||
include ../common.mk | |||||
BUILD_DIR = src/build | |||||
MAKE = cmake --build . | |||||
all: prepare build | |||||
clean: | |||||
rm -rf $(BUILD_DIR) | |||||
prepare: clean | |||||
rm -rf $(BUILD_DIR) | |||||
mkdir -p $(BUILD_DIR) | |||||
cd $(BUILD_DIR); \ | |||||
cmake \ | |||||
-DANDROID_TOOLCHAIN_NAME=aarch64-linux-android-clang5.0 \ | |||||
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \ | |||||
-DANDROID_NATIVE_API_LEVEL=$(NDK_TARGETVER) \ | |||||
-DCMAKE_BUILD_TYPE=Release \ | |||||
-DANDROID_ABI=arm64-v8a \ | |||||
-DOPENSSL_SMALL=1 \ | |||||
-DCMAKE_C_FLAGS_RELEASE="-Os -fdata-sections -Wno-error=unused-command-line-argument" \ | |||||
-DCMAKE_CXX_FLAGS_RELEASE="-Os -fdata-sections -Wno-error=unused-command-line-argument" \ | |||||
-DCMAKE_EXE_LINKER_FLAGS="-Wl,--gc-sections -Wno-error=unused-command-line-argument" \ | |||||
.. | |||||
build: | |||||
cd $(BUILD_DIR); \ | |||||
$(MAKE) | |||||
python ../print_bssl_size.py " -fdata-sections (+)" |
@@ -0,0 +1,22 @@ | |||||
include ../common.mk | |||||
BUILD_DIR = src/build | |||||
MAKE = cmake --build . | |||||
all: prepare build | |||||
prepare: | |||||
rm -rf $(BUILD_DIR) | |||||
mkdir -p $(BUILD_DIR) | |||||
cd $(BUILD_DIR); \ | |||||
cmake -DCMAKE_BUILD_TYPE=Release \ | |||||
-DCMAKE_BUILD_TYPE=Release \ | |||||
-DOPENSSL_SMALL=1 \ | |||||
-DCMAKE_C_FLAGS_RELEASE="-Os -fdata-sections" \ | |||||
-DCMAKE_CXX_FLAGS_RELEASE="-Os -fdata-sections" \ | |||||
-DCMAKE_EXE_LINKER_FLAGS="-Wl,--gc-sections" \ | |||||
.. | |||||
build: | |||||
cd $(BUILD_DIR); \ | |||||
$(MAKE) |
@@ -0,0 +1,5 @@ | |||||
# Constants and makefile shit used in build | |||||
mkfile_path = $(abspath $(lastword $(MAKEFILE_LIST))) | |||||
current_dir = $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) | |||||
ANDROID_NDK = /opt/android-ndk | |||||
NDK_TARGETVER = 27 |
@@ -0,0 +1,48 @@ | |||||
include ../common.mk | |||||
## NDK configuration. | |||||
NDK = $(ANDROID_NDK) | |||||
NDK_TARGETARCH = aarch64-linux-android | |||||
NDK_TARGETSHORTARCH = arm64 | |||||
NDK_TOOLVER = 4.9 | |||||
NDK_HOSTARCH = linux-x86_64 | |||||
NDK_TOOLS = $(NDK)/toolchains/llvm/prebuilt/$(NDK_HOSTARCH)/bin | |||||
NDK_SYSROOT = $(NDK)/sysroot | |||||
NDK_TOOL = $(NDK_TOOLS)/clang | |||||
NDK_LIBS = $(NDK)/toolchains/$(NDK_TARGETARCH)-$(NDK_TOOLVER)/prebuilt/linux-x86_64/lib/gcc/$(NDK_TARGETARCH)/4.9.x | |||||
NDK_INCLUDES = -I$(NDK)/sysroot/usr/include -I$(NDK)/sysroot/usr/include/$(NDK_TARGETARCH) | |||||
NDK_SYSROOT = $(NDK)/platforms/android-$(NDK_TARGETVER)/arch-$(NDK_TARGETSHORTARCH) | |||||
OPT = -std=c99 -Os \ | |||||
-fdata-sections \ | |||||
-ffunction-sections \ | |||||
-fPIE \ | |||||
-Wall \ | |||||
-target $(NDK_TARGETARCH) | |||||
CFLAGS = $(OPT) \ | |||||
$(NDK_INCLUDES) \ | |||||
-D__ANDROID_API__=$(NDK_TARGETVER) \ | |||||
-D_SOCKLEN_T_DECLARED | |||||
LDFLAGS = $(OPT) \ | |||||
-pie \ | |||||
-Wl,--gc-sections \ | |||||
--sysroot=$(NDK_SYSROOT) \ | |||||
-B $(ANDROID_NDK)/toolchains/$(NDK_TARGETARCH)-$(NDK_TOOLVER)/prebuilt/linux-x86_64/$(NDK_TARGETARCH)/bin \ | |||||
-L$(NDK_LIBS) | |||||
all: | |||||
CC=$(NDK_TOOL) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" make -C src | |||||
clean: | |||||
make -C src clean | |||||
push: | |||||
adb root | |||||
adb remount | |||||
adb shell "rm -rf /data/app/mbedtls/*" | |||||
adb shell "mkdir -p /data/app/mbedtls" | |||||
adb push src/programs/ssl/ssl_client1 /data/app/mbedtls/ | |||||
adb push src/programs/ssl/ssl_server /data/app/mbedtls/ | |||||
adb push src/programs/test/benchmark /data/app/mbedtls/ |
@@ -0,0 +1,13 @@ | |||||
include ../common.mk | |||||
OPT = -D_SOCKLEN_T_DECLARED -Os -fdata-sections | |||||
CFLAGS = $(OPT) | |||||
LDFLAGS = | |||||
all: | |||||
CC=gcc CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" make -C src | |||||
clean: | |||||
make -C src clean | |||||