diff --git a/CMakeLists.txt b/CMakeLists.txt index 0005a498..7f726c9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,14 +209,48 @@ include(CTest) enable_testing() if(GIT_FOUND AND ENABLE_GOOGLEMOCK) - add_subdirectory(gmock) + #add_subdirectory(gmock) + + # Download and unpack googletest at configure time + configure_file(gtest/CMakeLists.txt.in gtest-download/CMakeLists.txt) + execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gtest-download ) + if(result) + message(FATAL_ERROR "CMake step for googletest failed: ${result}") + endif() + execute_process(COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gtest-download ) + if(result) + message(FATAL_ERROR "Build step for googletest failed: ${result}") + endif() + + # Prevent overriding the parent project's compiler/linker + # settings on Windows + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + + # Add googletest directly to our build. This defines + # the gtest and gtest_main targets. + add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/gtest-src + ${CMAKE_CURRENT_BINARY_DIR}/gtest-build + EXCLUDE_FROM_ALL) + + # The gtest/gtest_main targets carry header search path + # dependencies automatically when using CMake 2.8.11 or + # later. Otherwise we have to add them here ourselves. + if (CMAKE_VERSION VERSION_LESS 2.8.11) + include_directories("${gtest_SOURCE_DIR}/include") + include_directories("${gmock_SOURCE_DIR}/include") + endif() + add_subdirectory(tests) else() if (ENABLE_GOOGLEMOCK) message(WARNING "googletest based unit tests disabled due to missing git. Please install git.") endif(ENABLE_GOOGLEMOCK) endif() -add_test(NAME vzlogger_unit_tests COMMAND vzlogger_unit_tests WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) +add_test(NAME vzlogger_unit_tests COMMAND vzlogger_unit_tests) ### print some output for the user message("") diff --git a/gmock/CMakeLists.txt b/gmock/CMakeLists.txt deleted file mode 100644 index 96ac4c5d..00000000 --- a/gmock/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -cmake_minimum_required(VERSION 2.8.0) -project(gmock_builder C CXX) -include(ExternalProject) - -ExternalProject_Add(googlemock - GIT_REPOSITORY https://github.com/google/googletest.git - CMAKE_ARGS - PREFIX "${CMAKE_CURRENT_BINARY_DIR}" -# Disable install step - INSTALL_COMMAND "" -# Avoid svn update each time on make - UPDATE_COMMAND "" -) - -# Specify include dir -ExternalProject_Get_Property(googlemock source_dir) -set(GMOCK_INCLUDE_DIRS ${source_dir}/googlemock/include PARENT_SCOPE) -set(GTEST_INCLUDE_DIRS ${source_dir}/googletest/include PARENT_SCOPE) - -# Specify MainTest's link libraries -ExternalProject_Get_Property(googlemock binary_dir) -set(GTEST_LIBS_DIR ${binary_dir}/lib PARENT_SCOPE) -set(GMOCK_LIBS_DIR ${binary_dir}/lib PARENT_SCOPE) - diff --git a/gtest/CMakeLists.txt b/gtest/CMakeLists.txt deleted file mode 100644 index 9b86605c..00000000 --- a/gtest/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -cmake_minimum_required(VERSION 2.8.0) -project(gtest_builder C CXX) -include(ExternalProject) - -ExternalProject_Add(googletest - GIT_REPOSITORY https://github.com/google/googletest.git - CMAKE_ARGS - PREFIX "${CMAKE_CURRENT_BINARY_DIR}" -# Disable install step - INSTALL_COMMAND "" -# Avoid svn update each time on make - UPDATE_COMMAND "" -) - -# Specify include dir -ExternalProject_Get_Property(googletest source_dir) -set(GTEST_INCLUDE_DIRS ${source_dir}/googletest/include PARENT_SCOPE) - -# Specify MainTest's link libraries -ExternalProject_Get_Property(googletest binary_dir) -set(GTEST_LIBS_DIR ${binary_dir}/googletest PARENT_SCOPE) diff --git a/gtest/CMakeLists.txt.in b/gtest/CMakeLists.txt.in new file mode 100644 index 00000000..600b9f67 --- /dev/null +++ b/gtest/CMakeLists.txt.in @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.8.2) + +project(gtest-download NONE) + +include(ExternalProject) +ExternalProject_Add(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG master + SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/gtest-src" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/gtest-build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" +) diff --git a/include/Options.hpp b/include/Options.hpp index 899e5948..a2e50142 100644 --- a/include/Options.hpp +++ b/include/Options.hpp @@ -21,6 +21,7 @@ class Option { Option(const char *key, struct json_object *jso); Option(const char *key, const char *value); + Option(const char *pKey, const std::string &pValue); Option(const char *key, int value); Option(const char *key, double value); Option(const char *key, bool value); diff --git a/src/Options.cpp b/src/Options.cpp index fdbcb0e0..e7bf024e 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -80,6 +80,9 @@ Option::Option(const Option &o) : _key(o._key), _type(o._type), _value_string(o. Option::Option(const char *pKey, const char *pValue) : _key(pKey), _type(type_string), _value_string(pValue) {} +Option::Option(const char *pKey, const std::string &pValue) + : _key(pKey), _type(type_string), _value_string(pValue) {} + Option::Option(const char *pKey, int pValue) : _key(pKey) { value.integer = pValue; _type = type_int; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index db9fab2d..8aa0eeae 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,106 +1,108 @@ -include_directories( - ${GMOCK_INCLUDE_DIRS} - ${GTEST_INCLUDE_DIRS} -) # all *.cpp files here will be used. file(GLOB test_sources *.cpp) -if(NOT SML_FOUND) - list(REMOVE_ITEM test_sources ${CMAKE_CURRENT_SOURCE_DIR}/MeterSML.cpp) -endif(NOT SML_FOUND) - -# remove meterOCR.cpp if not defined -if( NOT OCR_SUPPORT ) -list(REMOVE_ITEM test_sources ${CMAKE_CURRENT_SOURCE_DIR}/ut_MeterOCR.cpp) -endif( NOT OCR_SUPPORT) - -if( NOT OCR_TESSERACT_SUPPORT ) -list(REMOVE_ITEM test_sources ${CMAKE_CURRENT_SOURCE_DIR}/ut_MeterOCRTesseract.cpp) -endif( NOT OCR_TESSERACT_SUPPORT) - -if( NOT ENABLE_SML ) -list(REMOVE_ITEM test_sources ${CMAKE_CURRENT_SOURCE_DIR}/MeterSML.cpp) -endif( NOT ENABLE_SML) - -if(ENABLE_MQTT) - set(MQTT_SOURCES ../src/mqtt.cpp) -else(ENABLE_MQTT) - set(MQTT_SOURCES "") -endif(ENABLE_MQTT) - -if( OMS_SUPPORT ) - set(oms_sources ../src/protocols/MeterOMS.cpp) -elseif( OMS_SUPPORT ) - set(oms_sources "") -endif( OMS_SUPPORT ) - -add_executable(vzlogger_unit_tests ${test_sources} ../src/CurlSessionProvider.cpp ../src/protocols/MeterW1therm.cpp ${oms_sources} ${MQTT_SOURCES}) - -add_dependencies(vzlogger_unit_tests googlemock) +# add required source files +list(APPEND test_sources + ../src/Buffer.cpp + ../src/Channel.cpp + ../src/Config_Options.cpp + ../src/api/Volkszaehler.cpp + ../src/CurlSessionProvider.cpp + ../src/protocols/MeterW1therm.cpp +) -target_link_libraries(vzlogger_unit_tests - ${GTEST_LIBS_DIR}/libgtest.a - ${GMOCK_LIBS_DIR}/libgmock.a +set(test_libraries + gtest + gmock ${JSON_LIBRARY} ${LIBUUID} dl - pthread) -target_link_libraries(vzlogger_unit_tests ${CURL_STATIC_LIBRARIES} ${CURL_LIBRARIES} unistring ${GNUTLS_LIBRARIES} ${OCR_LIBRARIES}) - -if( OMS_SUPPORT ) -target_link_libraries(vzlogger_unit_tests ${MBUS_LIBRARY} ${OPENSSL_LIBRARIES}) -endif( OMS_SUPPORT ) + pthread + ${CURL_STATIC_LIBRARIES} + ${CURL_LIBRARIES} + unistring + ${GNUTLS_LIBRARIES} + ${OCR_LIBRARIES} +) -if(SML_FOUND) - target_link_libraries(vzlogger_unit_tests ${SML_LIBRARY}) -endif(SML_FOUND) +if(SML_FOUND AND ENABLE_SML) + list(APPEND test_sources ../src/protocols/MeterSML.cpp) + list(APPEND test_libraries ${SML_LIBRARY}) +else(SML_FOUND AND ENABLE_SML) + list(REMOVE_ITEM test_sources ${CMAKE_CURRENT_SOURCE_DIR}/MeterSML.cpp) +endif(SML_FOUND AND ENABLE_SML) + +if(OCR_SUPPORT) + list(APPEND test_sources ../src/protocols/MeterOCR.cpp) +else(OCR_SUPPORT) + list(REMOVE_ITEM test_sources ${CMAKE_CURRENT_SOURCE_DIR}/ut_MeterOCR.cpp) +endif(OCR_SUPPORT) + +if(OCR_TESSERACT_SUPPORT) + list(APPEND test_sources ../src/protocols/MeterOCR.cpp) +else(OCR_TESSERACT_SUPPORT) + list(REMOVE_ITEM test_sources + ${CMAKE_CURRENT_SOURCE_DIR}/ut_MeterOCRTesseract.cpp) +endif(OCR_TESSERACT_SUPPORT) if(ENABLE_MQTT) - target_link_libraries(vzlogger_unit_tests ${MQTT_LIBRARY}) + list(APPEND test_sources ../src/mqtt.cpp) + list(APPEND test_libraries ${MQTT_LIBRARY}) endif(ENABLE_MQTT) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") - -add_subdirectory(mocks) - -FIND_PROGRAM( GCOV_PATH gcov ) -FIND_PROGRAM( LCOV_PATH lcov ) -FIND_PROGRAM( GENHTML_PATH genhtml ) - -IF(GCOV_PATH AND LCOV_PATH AND GENHTML_PATH) - MESSAGE("gcov found. Adding target test_coverage ...") +if(OMS_SUPPORT) + list(APPEND test_sources ../src/protocols/MeterOMS.cpp) + list(APPEND test_libraries ${MBUS_LIBRARY} ${OPENSSL_LIBRARIES}) +endif(OMS_SUPPORT) -# Setup target for coverage -# we need to add each single test binary into the command list +add_executable(vzlogger_unit_tests ${test_sources}) +target_link_libraries(vzlogger_unit_tests ${test_libraries}) -ADD_CUSTOM_TARGET(test_coverage - - # Cleanup lcov - ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory . --zerocounters - - # Run tests - COMMAND vzlogger_unit_tests - COMMAND mock_metermap - COMMAND mock_MeterW1therm - COMMAND mock_MeterOMS - COMMAND mock_MeterS0 +configure_file(include/test_config.hpp.in include/test_config.hpp) +target_include_directories(vzlogger_unit_tests + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include +) - # Capturing lcov counters and generating report - COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory . --capture --output-file coverage.info - COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --remove coverage.info 'tests/*' '/usr/*' --output-file coverage.info.cleaned - COMMAND ${GENHTML_PATH} --rc lcov_branch_coverage=1 -o coverage coverage.info.cleaned - COMMAND ${CMAKE_COMMAND} -E remove coverage.info coverage.info.cleaned - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." - ) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") - # Show info where to find the report - ADD_CUSTOM_COMMAND(TARGET test_coverage POST_BUILD - COMMAND ; - COMMENT "Open ./coverage/index.html in your browser to view the coverage report." - ) +add_subdirectory(mocks) -ENDIF() # NOT GCOV_PATH +FIND_PROGRAM(GCOV_PATH gcov) +FIND_PROGRAM(LCOV_PATH lcov) +FIND_PROGRAM(GENHTML_PATH genhtml) +IF(GCOV_PATH AND LCOV_PATH AND GENHTML_PATH) + MESSAGE("gcov found. Adding target test_coverage ...") + + # Setup target for coverage + # we need to add each single test binary into the command list + + ADD_CUSTOM_TARGET(test_coverage + # Cleanup lcov + ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory . --zerocounters + # Run tests + COMMAND vzlogger_unit_tests + COMMAND mock_metermap + COMMAND mock_MeterW1therm + COMMAND mock_MeterOMS + COMMAND mock_MeterS0 + + # Capturing lcov counters and generating report + COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory . --capture --output-file coverage.info + COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --remove coverage.info 'tests/*' '/usr/*' --output-file coverage.info.cleaned + COMMAND ${GENHTML_PATH} --rc lcov_branch_coverage=1 -o coverage coverage.info.cleaned + COMMAND ${CMAKE_COMMAND} -E remove coverage.info coverage.info.cleaned + + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." + ) + + # Show info where to find the report + ADD_CUSTOM_COMMAND(TARGET test_coverage POST_BUILD + COMMAND ; + COMMENT "Open ./coverage/index.html in your browser to view the coverage report." + ) + +ENDIF(GCOV_PATH AND LCOV_PATH AND GENHTML_PATH) diff --git a/tests/MeterSML.cpp b/tests/MeterSML.cpp index 8e0ee0f4..b49e7c3d 100644 --- a/tests/MeterSML.cpp +++ b/tests/MeterSML.cpp @@ -1,20 +1,16 @@ +#include +#include #include -#include "Options.hpp" -#include "protocols/MeterSML.hpp" #include "gtest/gtest.h" - -// this is a dirty hack. we should think about better ways/rules to link against the -// test objects. -// e.g. single files in the tests directory that just include the real file. This way one -// will avoid multiple includes of the same file in a different test case -// (or linking against the real file from the CMakeLists.txt) - -#include "../src/protocols/MeterSML.cpp" +#include +#include int writes_hex(int fd, const char *str); // impl. in MeterD0.cpp TEST(MeterSML, EMH_basic) { + using std::fabs; + char tempfilename[L_tmpnam + 1]; ASSERT_NE(tmpnam_r(tempfilename), (char *)0); std::list