tests FEATURE include tests into build system
basic tests of ly_set implementation
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0202a3a..6827dc0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,19 +21,19 @@
set(CMAKE_BUILD_TYPE debug)
endif()
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=c89")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=c99")
set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_C_FLAGS_PACKAGE "-g -O2 -DNDEBUG")
set(CMAKE_C_FLAGS_DEBUG "-g -O0")
# options
-#if((CMAKE_BUILD_TYPE STREQUAL debug) OR (CMAKE_BUILD_TYPE STREQUAL Package))
-# option(ENABLE_BUILD_TESTS "Build tests" ON)
-# option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" ON)
-#else()
-# option(ENABLE_BUILD_TESTS "Build tests" OFF)
-# option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" OFF)
-#endif()
+if((CMAKE_BUILD_TYPE STREQUAL debug) OR (CMAKE_BUILD_TYPE STREQUAL Package))
+ option(ENABLE_BUILD_TESTS "Build tests" ON)
+ option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" ON)
+else()
+ option(ENABLE_BUILD_TESTS "Build tests" OFF)
+ option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" OFF)
+endif()
#option(ENABLE_CALLGRIND_TESTS "Build performance tests to be run with callgrind" OFF)
#option(ENABLE_CACHE "Enable data caching for schemas and hash tables for data (time-efficient at the cost of increased space-complexity)" ON)
@@ -270,12 +270,12 @@
# YANG extensions plugins
#set(EXTENSIONS_LIST "nacm" "metadata" "yangdata")
# if the tests are enabled, build libyang_ext_test
-#if(ENABLE_BUILD_TESTS)
-# find_package(CMocka 1.0.0)
+if(ENABLE_BUILD_TESTS)
+ find_package(CMocka 1.0.0)
# if(CMOCKA_FOUND AND CMAKE_BUILD_TYPE MATCHES debug)
# list(APPEND EXTENSIONS_LIST "libyang_ext_test")
# endif(CMOCKA_FOUND AND CMAKE_BUILD_TYPE MATCHES debug)
-#endif(ENABLE_BUILD_TESTS)
+endif(ENABLE_BUILD_TESTS)
#if(ENABLE_STATIC)
# set(EXTENSIONS_LIST_SIZE " 0 ")
@@ -327,19 +327,19 @@
# yang2yin
#add_executable(yang2yin ${yang2yinsrc})
-#if(ENABLE_VALGRIND_TESTS)
-# set(ENABLE_BUILD_TESTS ON)
-#endif()
+if(ENABLE_VALGRIND_TESTS)
+ set(ENABLE_BUILD_TESTS ON)
+endif()
-#if(ENABLE_BUILD_TESTS)
-# if(CMOCKA_FOUND)
-# enable_testing()
-# add_subdirectory(tests)
-# else(CMOCKA_FOUND)
-# message(STATUS "Disabling tests because of missing CMocka")
-# set(ENABLE_BUILD_TESTS NO)
-# endif(CMOCKA_FOUND)
-#endif(ENABLE_BUILD_TESTS)
+if(ENABLE_BUILD_TESTS)
+ if(CMOCKA_FOUND)
+ enable_testing()
+ add_subdirectory(tests)
+ else(CMOCKA_FOUND)
+ message(STATUS "Disabling tests because of missing CMocka")
+ set(ENABLE_BUILD_TESTS NO)
+ endif(CMOCKA_FOUND)
+endif(ENABLE_BUILD_TESTS)
#if(GEN_LANGUAGE_BINDINGS AND GEN_CPP_BINDINGS)
# add_subdirectory(swig)
diff --git a/CMakeModules/FindCMocka.cmake b/CMakeModules/FindCMocka.cmake
new file mode 100644
index 0000000..2dd9fc5
--- /dev/null
+++ b/CMakeModules/FindCMocka.cmake
@@ -0,0 +1,49 @@
+# - Try to find CMocka
+# Once done this will define
+#
+# CMOCKA_ROOT_DIR - Set this variable to the root installation of CMocka
+#
+# Read-Only variables:
+# CMOCKA_FOUND - system has CMocka
+# CMOCKA_INCLUDE_DIR - the CMocka include directory
+# CMOCKA_LIBRARIES - Link these to use CMocka
+# CMOCKA_DEFINITIONS - Compiler switches required for using CMocka
+#
+#=============================================================================
+# Copyright (c) 2011-2012 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.
+#=============================================================================
+#
+
+find_path(CMOCKA_INCLUDE_DIR
+ NAMES
+ cmocka.h
+ PATHS
+ ${CMOCKA_ROOT_DIR}/include
+)
+
+find_library(CMOCKA_LIBRARY
+ NAMES
+ cmocka
+ PATHS
+ ${CMOCKA_ROOT_DIR}/include
+)
+
+if (CMOCKA_LIBRARY)
+ set(CMOCKA_LIBRARIES
+ ${CMOCKA_LIBRARIES}
+ ${CMOCKA_LIBRARY}
+ )
+endif (CMOCKA_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(CMocka DEFAULT_MSG CMOCKA_LIBRARIES CMOCKA_INCLUDE_DIR)
+
+# show the CMOCKA_INCLUDE_DIR and CMOCKA_LIBRARIES variables only in the advanced view
+mark_as_advanced(CMOCKA_INCLUDE_DIR CMOCKA_LIBRARIES)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..5cd8733
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,46 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+# Correct RPATH usage on OS X
+set(CMAKE_MACOSX_RPATH TRUE)
+
+# Set TESTS_DIR to realpath
+#get_filename_component(TESTS_DIR "${CMAKE_SOURCE_DIR}/tests" REALPATH)
+
+if(ENABLE_STATIC AND ENABLE_VALGRIND_TESTS)
+ message(WARNING "Can't run C valgrind tests on a static build")
+else()
+ find_program(VALGRIND_FOUND valgrind)
+endif()
+
+include_directories(SYSTEM ${CMOCKA_INCLUDE_DIR})
+
+set(tests)
+add_subdirectory(src)
+
+foreach(test_name IN LISTS tests)
+ string(REGEX REPLACE "[a-z]*_" "" name "${test_name}")
+ string(REGEX REPLACE "([a-z]*)_.*" "\\1" prefix "${test_name}")
+ add_executable(${test_name} ${prefix}/${name}.c)
+endforeach(test_name)
+
+# Set common attributes of all tests
+foreach(test_name IN LISTS tests)
+ target_link_libraries(${test_name} ${CMOCKA_LIBRARIES} yang)
+ add_test(NAME ${test_name} COMMAND ${test_name})
+# set_property(TEST ${test_name} PROPERTY ENVIRONMENT "LIBYANG_EXTENSIONS_PLUGINS_DIR=${CMAKE_BINARY_DIR}/src/extensions")
+# set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT "LIBYANG_USER_TYPES_PLUGINS_DIR=${CMAKE_BINARY_DIR}/src/user_types")
+ set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT "MALLOC_CHECK_=3")
+endforeach(test_name)
+
+if(ENABLE_VALGRIND_TESTS)
+ if(VALGRIND_FOUND)
+ foreach(test_name IN LISTS tests)
+ add_test(${test_name}_valgrind valgrind --leak-check=full --show-leak-kinds=all --suppressions=${PROJECT_SOURCE_DIR}/tests/ld.supp --error-exitcode=1
+ ${CMAKE_BINARY_DIR}/tests/${test_name})
+# set_property(TEST ${test_name}_valgrind PROPERTY ENVIRONMENT "LIBYANG_EXTENSIONS_PLUGINS_DIR=${CMAKE_BINARY_DIR}/src/extensions")
+# set_property(TEST ${test_name}_valgrind APPEND PROPERTY ENVIRONMENT "LIBYANG_USER_TYPES_PLUGINS_DIR=${CMAKE_BINARY_DIR}/src/user_types")
+ endforeach(test_name)
+ else(VALGRIND_FOUND)
+ message(WARNING "valgrind executable not found! Disabling memory leaks tests.")
+ endif(VALGRIND_FOUND)
+endif()
\ No newline at end of file
diff --git a/tests/ld.supp b/tests/ld.supp
new file mode 100644
index 0000000..53876b6
--- /dev/null
+++ b/tests/ld.supp
@@ -0,0 +1,10 @@
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Leak
+ match-leak-kinds: reachable
+ fun:calloc
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.2.5
+ fun:lyext_load_plugins
+ fun:ly_ctx_new
+}
diff --git a/tests/src/CMakeLists.txt b/tests/src/CMakeLists.txt
new file mode 100644
index 0000000..56eefd6
--- /dev/null
+++ b/tests/src/CMakeLists.txt
@@ -0,0 +1,2 @@
+set(local_tests src_set)
+set(tests ${tests} ${local_tests} PARENT_SCOPE)
diff --git a/tests/src/set.c b/tests/src/set.c
new file mode 100644
index 0000000..28b6f59
--- /dev/null
+++ b/tests/src/set.c
@@ -0,0 +1,147 @@
+/*
+ * @file set.c
+ * @author: Radek Krejci <rkrejci@cesnet.cz>
+ * @brief unit tests for functions from set.c
+ *
+ * Copyright (c) 2018 CESNET, z.s.p.o.
+ *
+ * This source code is licensed under BSD 3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#define _BSD_SOURCE
+#define _DEFAULT_SOURCE
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <string.h>
+
+#include "libyang.h"
+#include "../../src/set.c"
+
+#define BUFSIZE 1024
+char logbuf[BUFSIZE] = {0};
+
+static void
+logger(LY_LOG_LEVEL level, const char *msg, const char *path)
+{
+ (void) level; /* unused */
+ (void) path; /* unused */
+
+ strncpy(logbuf, msg, BUFSIZE - 1);
+}
+
+static int
+logger_setup(void **state)
+{
+ (void) state; /* unused */
+
+ ly_set_log_clb(logger, 0);
+
+ return 0;
+}
+
+static void
+test_basics(void **state)
+{
+ (void) state; /* unused */
+
+ struct ly_set *set;
+ char *str;
+ unsigned int u;
+ void *ptr;
+
+ /* creation - everything is empty */
+ set = ly_set_new();
+ assert_non_null(set);
+ assert_int_equal(0, set->count);
+ assert_int_equal(0, set->size);
+ assert_null(set->objs);
+
+ /* add a testing object */
+ str = strdup("test string");
+ assert_non_null(str);
+
+ ly_set_add(set, str, 0);
+ assert_int_not_equal(0, set->size);
+ assert_int_equal(1, set->count);
+ assert_non_null(set->objs);
+ assert_non_null(set->objs[0]);
+
+ /* check the presence of the testing data */
+ assert_int_equal(0, ly_set_contains(set, str));
+ assert_int_equal(-1, ly_set_contains(set, str - 1));
+
+ /* remove data, but keep the set */
+ u = set->size;
+ ptr = set->objs;
+ ly_set_clean(set, free);
+ assert_int_equal(0, set->count);
+ assert_int_equal(u, set->size);
+ assert_ptr_equal(ptr, set->objs);
+
+ /* remove buffer, but keep the set object */
+ ly_set_erase(set, NULL);
+ assert_int_equal(0, set->count);
+ assert_int_equal(0, set->size);
+ assert_ptr_equal(NULL, set->objs);
+
+ /* final cleanup */
+ ly_set_free(set, NULL);
+}
+
+static void
+test_inval(void **state)
+{
+ struct ly_set set;
+ memset(&set, 0, sizeof set);
+
+ ly_set_clean(NULL, NULL);
+ assert_string_equal(logbuf, "Invalid argument set (ly_set_clean()).");
+
+ ly_set_erase(NULL, NULL);
+ assert_string_equal(logbuf, "Invalid argument set (ly_set_erase()).");
+
+ ly_set_free(NULL, NULL);
+ assert_string_equal(logbuf, "Invalid argument set (ly_set_free()).");
+
+ assert_null(ly_set_dup(NULL));
+ assert_string_equal(logbuf, "Invalid argument set (ly_set_dup()).");
+
+ assert_int_equal(-1, ly_set_add(NULL, NULL, 0));
+ assert_string_equal(logbuf, "Invalid argument set (ly_set_add()).");
+ assert_int_equal(-1, ly_set_add(&set, NULL, 0));
+ assert_string_equal(logbuf, "Invalid argument object (ly_set_add()).");
+
+ assert_int_equal(-1, ly_set_merge(NULL, NULL, 0));
+ assert_string_equal(logbuf, "Invalid argument trg (ly_set_merge()).");
+ assert_int_equal(0, ly_set_merge(&set, NULL, 0));
+ assert_string_equal(logbuf, "Invalid argument src (ly_set_merge()).");
+
+ assert_int_equal(LY_EINVAL, ly_set_rm_index(NULL, 0));
+ assert_string_equal(logbuf, "Invalid argument set (ly_set_rm_index()).");
+ assert_int_equal(LY_EINVAL, ly_set_rm_index(&set, 1));
+ assert_string_equal(logbuf, "Invalid argument index (ly_set_rm_index()).");
+
+ assert_int_equal(LY_EINVAL, ly_set_rm(NULL, NULL));
+ assert_string_equal(logbuf, "Invalid argument set (ly_set_rm()).");
+ assert_int_equal(LY_EINVAL, ly_set_rm(&set, NULL));
+ assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
+ assert_int_equal(LY_EINVAL, ly_set_rm(&set, &state));
+ assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
+}
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_basics),
+ cmocka_unit_test_setup(test_inval, logger_setup),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}