summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt18
-rw-r--r--cmake/Modules/ApplyPkgConfig.cmake35
-rw-r--r--mock/gio_mock.cc123
-rw-r--r--mock/gio_mock.h79
-rw-r--r--mock/mock_hook.h42
-rw-r--r--mock/module_mock.h25
-rw-r--r--mock/test_fixture.cc21
-rw-r--r--mock/test_fixture.h53
-rw-r--r--packaging/buxton2.spec30
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/unit_tests/CMakeLists.txt27
-rw-r--r--test/unit_tests/main.cc25
-rw-r--r--test/unit_tests/test_vconf_compat.cc301
13 files changed, 773 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6169a57..8bb667d 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(buxton2 C)
+PROJECT(buxton2)
# check variables
IF(NOT DEFINED VERSION)
@@ -48,8 +48,20 @@ IF(NOT "${SOCKPATH}" STREQUAL "")
ENDIF()
# pkg-config
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
+INCLUDE(ApplyPkgConfig)
INCLUDE(FindPkgConfig)
+
PKG_CHECK_MODULES(PKGS REQUIRED glib-2.0>=2.36 dlog)
+PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0>=2.36 dlog)
+PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock)
+PKG_CHECK_MODULES(SQLITE3_DEPS REQUIRED sqlite3)
+PKG_CHECK_MODULES(TZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config)
+PKG_CHECK_MODULES(SYSTEMD_DEPS REQUIRED libsystemd)
+PKG_CHECK_MODULES(CYNARA_CLIENT_DEPS REQUIRED cynara-client-async)
+PKG_CHECK_MODULES(GIO_DEPS REQUIRED gio-2.0)
+PKG_CHECK_MODULES(VCONF_INTERNAL_KEYS_DEPS REQUIRED vconf-internal-keys)
+PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
FOREACH(flag ${PKGS_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -58,6 +70,9 @@ ENDFOREACH()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall")
MESSAGE("CFLAGS: ${CMAKE_C_FLAGS}")
+ENABLE_TESTING()
+SET(TARGET_BUXTON2_UNIT_TEST "buxton2-unit-test")
+
# build subdirectories
INCLUDE_DIRECTORIES(common)
@@ -66,6 +81,7 @@ ADD_SUBDIRECTORY(backend)
ADD_SUBDIRECTORY(lib)
ADD_SUBDIRECTORY(client)
ADD_SUBDIRECTORY(vconf-compat)
+ADD_SUBDIRECTORY(test)
IF(BUILD_EXAMPLE)
ADD_SUBDIRECTORY(example)
diff --git a/cmake/Modules/ApplyPkgConfig.cmake b/cmake/Modules/ApplyPkgConfig.cmake
new file mode 100644
index 0000000..97679d7
--- /dev/null
+++ b/cmake/Modules/ApplyPkgConfig.cmake
@@ -0,0 +1,35 @@
+# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+#
+# This function applies external (out of source tree) dependencies
+# to given target. Arguments are:
+# TARGET - valid cmake target
+# PRIVACY - dependency can be inherited by dependent targets or not:
+# PUBLIC - this should be used by default, cause compile/link flags passing
+# PRIVATE - do not passes any settings to dependent targets,
+# may be usefull for static libraries from the inside of the project
+# Argument ARGV2 and following are supposed to be names of checked pkg config
+# packages. This function will use variables created by check_pkg_modules().
+# - ${DEP_NAME}_LIBRARIES
+# - ${DEP_NAME}_INCLUDE_DIRS
+# - ${DEP_NAME}_CFLAGS
+#
+FUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
+ MATH(EXPR DEST_INDEX "${ARGC}-1")
+ FOREACH(I RANGE 2 ${DEST_INDEX})
+ IF(NOT ${ARGV${I}}_FOUND)
+ MESSAGE(FATAL_ERROR "Not found dependency - ${ARGV${I}}_FOUND")
+ ENDIF(NOT ${ARGV${I}}_FOUND)
+ TARGET_LINK_LIBRARIES(${TARGET} ${PRIVACY} "${${ARGV${I}}_LIBRARIES}")
+ TARGET_INCLUDE_DIRECTORIES(${TARGET} ${PRIVACY} SYSTEM "${${ARGV${I}}_INCLUDE_DIRS}")
+ STRING(REPLACE ";" " " CFLAGS_STR "${${ARGV${I}}_CFLAGS}")
+ SET(CFLAGS_LIST ${CFLAGS_STR})
+ SEPARATE_ARGUMENTS(CFLAGS_LIST)
+ FOREACH(OPTION ${CFLAGS_LIST})
+ TARGET_COMPILE_OPTIONS(${TARGET} ${PRIVACY} ${OPTION})
+ ENDFOREACH(OPTION)
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SKIP_BUILD_RPATH true)
+ ENDFOREACH(I RANGE 2 ${DEST_INDEX})
+ENDFUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
diff --git a/mock/gio_mock.cc b/mock/gio_mock.cc
new file mode 100644
index 0000000..0b88132
--- /dev/null
+++ b/mock/gio_mock.cc
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 "gio_mock.h"
+
+#include "mock_hook.h"
+#include "test_fixture.h"
+
+extern "C" GDBusConnection* g_bus_get_sync(GBusType type,
+ GCancellable* cancellable, GError** error) {
+ return MOCK_HOOK_P3(GioMock, g_bus_get_sync, type, cancellable, error);
+}
+
+extern "C" GDBusMessage* g_dbus_connection_send_message_with_reply_sync(
+ GDBusConnection* conn, GDBusMessage* msg, GDBusSendMessageFlags flags,
+ gint timeout, volatile guint32* out_serial, GCancellable* cancellable,
+ GError** error) {
+ return MOCK_HOOK_P7(GioMock, g_dbus_connection_send_message_with_reply_sync,
+ conn, msg, flags, timeout, out_serial, cancellable, error);
+}
+
+extern "C" GDBusMessage* g_dbus_message_new_method_call(const gchar* arg0,
+ const gchar* arg1, const gchar* arg2, const gchar* arg3) {
+ return MOCK_HOOK_P4(GioMock, g_dbus_message_new_method_call, arg0, arg1, arg2,
+ arg3);
+}
+
+extern "C" void g_dbus_message_set_body(GDBusMessage* arg0, GVariant* arg1) {
+ return MOCK_HOOK_P2(GioMock, g_dbus_message_set_body, arg0, arg1);
+}
+
+extern "C" GVariant* g_dbus_message_get_body(GDBusMessage* arg0) {
+ return MOCK_HOOK_P1(GioMock, g_dbus_message_get_body, arg0);
+}
+
+extern "C" gboolean g_dbus_connection_emit_signal(GDBusConnection* arg0,
+ const gchar* arg1, const gchar* arg2, const gchar* arg3, const gchar* arg4,
+ GVariant* arg5, GError** arg6) {
+ return MOCK_HOOK_P7(GioMock, g_dbus_connection_emit_signal,
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6);
+}
+
+extern "C" GDBusNodeInfo* g_dbus_node_info_new_for_xml(
+ const gchar* arg0, GError** arg1) {
+ return MOCK_HOOK_P2(GioMock, g_dbus_node_info_new_for_xml, arg0, arg1);
+}
+
+extern "C" guint g_dbus_connection_register_object(GDBusConnection* arg0,
+ const gchar* arg1, GDBusInterfaceInfo* arg2,
+ const GDBusInterfaceVTable* arg3, gpointer arg4,
+ GDestroyNotify arg5, GError** arg6) {
+ return MOCK_HOOK_P7(GioMock, g_dbus_connection_register_object,
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6);
+}
+
+extern "C" gboolean g_dbus_connection_unregister_object (GDBusConnection *connection,
+ guint registration_id) {
+ return MOCK_HOOK_P2(GioMock, g_dbus_connection_unregister_object,
+ connection, registration_id);
+}
+
+extern "C" guint g_bus_own_name_on_connection(GDBusConnection* arg0,
+ const gchar* arg1, GBusNameOwnerFlags arg2,
+ GBusNameAcquiredCallback arg3, GBusNameLostCallback arg4,
+ gpointer arg5, GDestroyNotify arg6) {
+ return MOCK_HOOK_P7(GioMock, g_bus_own_name_on_connection,
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6);
+}
+
+extern "C" guint g_dbus_connection_signal_subscribe(GDBusConnection* arg0,
+ const gchar* arg1, const gchar* arg2, const gchar* arg3, const gchar* arg4,
+ const gchar* arg5, GDBusSignalFlags arg6, GDBusSignalCallback arg7,
+ gpointer arg8, GDestroyNotify arg9) {
+ return MOCK_HOOK_P10(GioMock, g_dbus_connection_signal_subscribe,
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+}
+
+extern "C" void g_dbus_connection_send_message_with_reply(GDBusConnection* arg0,
+ GDBusMessage* arg1, GDBusSendMessageFlags arg2, gint arg3,
+ volatile guint32* arg4, GCancellable* arg5, GAsyncReadyCallback arg6,
+ gpointer arg7) {
+ return MOCK_HOOK_P8(GioMock, g_dbus_connection_send_message_with_reply,
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+}
+
+extern "C" GDBusMessage* g_dbus_connection_send_message_with_reply_finish(
+ GDBusConnection* arg0, GAsyncResult* arg1, GError** arg2) {
+ return MOCK_HOOK_P3(GioMock, g_dbus_connection_send_message_with_reply_finish,
+ arg0, arg1, arg2);
+}
+
+extern "C" gboolean g_dbus_connection_send_message(GDBusConnection* arg0,
+ GDBusMessage* arg1, GDBusSendMessageFlags arg2,
+ volatile guint32* arg3, GError** arg4) {
+ return MOCK_HOOK_P5(GioMock, g_dbus_connection_send_message,
+ arg0, arg1, arg2, arg3, arg4);
+}
+
+extern "C" void g_dbus_message_set_unix_fd_list(GDBusMessage* arg0,
+ GUnixFDList* arg1) {
+ return MOCK_HOOK_P2(GioMock, g_dbus_message_set_unix_fd_list, arg0, arg1);
+}
+
+extern "C" guint g_bus_watch_name_on_connection(GDBusConnection* arg0,
+ const gchar* arg1, GBusNameWatcherFlags arg2,
+ GBusNameAppearedCallback arg3, GBusNameVanishedCallback arg4, gpointer arg5,
+ GDestroyNotify arg6) {
+ return MOCK_HOOK_P7(GioMock, g_bus_watch_name_on_connection, arg0, arg1, arg2,
+ arg3, arg4, arg5, arg6);
+}
diff --git a/mock/gio_mock.h b/mock/gio_mock.h
new file mode 100644
index 0000000..3867d5c
--- /dev/null
+++ b/mock/gio_mock.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 UNIT_TESTS_MOCK_GIO_MOCK_H_
+#define UNIT_TESTS_MOCK_GIO_MOCK_H_
+
+#include <gio/gio.h>
+#include <gmock/gmock.h>
+
+#include "module_mock.h"
+
+class GioMock : public virtual ModuleMock {
+ public:
+ virtual ~GioMock() {}
+
+ MOCK_METHOD3(g_bus_get_sync,
+ GDBusConnection*(GBusType, GCancellable*, GError**));
+ MOCK_METHOD7(g_bus_own_name_on_connection,
+ guint(GDBusConnection*, const gchar*, GBusNameOwnerFlags,
+ GBusNameAcquiredCallback, GBusNameLostCallback,
+ gpointer, GDestroyNotify));
+
+ MOCK_METHOD4(g_dbus_message_new_method_call,
+ GDBusMessage*(const gchar*, const gchar*, const gchar*, const gchar*));
+ MOCK_METHOD2(g_dbus_message_set_body, void(GDBusMessage*, GVariant*));
+ MOCK_METHOD2(g_dbus_connection_unregister_object,
+ gboolean(GDBusConnection*, guint));
+ MOCK_METHOD1(g_dbus_message_get_body, GVariant*(GDBusMessage*));
+
+ MOCK_METHOD7(g_dbus_connection_send_message_with_reply_sync,
+ GDBusMessage*(GDBusConnection*, GDBusMessage*, GDBusSendMessageFlags,
+ gint, volatile guint32*, GCancellable*, GError**));
+ MOCK_METHOD7(g_dbus_connection_emit_signal,
+ gboolean(GDBusConnection*, const gchar*, const gchar*, const gchar*,
+ const gchar*, GVariant*, GError**));
+ MOCK_METHOD7(g_dbus_connection_register_object,
+ guint(GDBusConnection*, const gchar*, GDBusInterfaceInfo*,
+ const GDBusInterfaceVTable*, gpointer, GDestroyNotify, GError**));
+ MOCK_METHOD10(g_dbus_connection_signal_subscribe,
+ guint(GDBusConnection*, const gchar*, const gchar*, const gchar*,
+ const gchar*, const gchar*, GDBusSignalFlags, GDBusSignalCallback,
+ gpointer, GDestroyNotify));
+ MOCK_METHOD8(g_dbus_connection_send_message_with_reply,
+ void(GDBusConnection*, GDBusMessage*, GDBusSendMessageFlags, gint,
+ volatile guint32*, GCancellable*, GAsyncReadyCallback, gpointer));
+ MOCK_METHOD3(g_dbus_connection_send_message_with_reply_finish,
+ GDBusMessage*(GDBusConnection*, GAsyncResult*, GError**));
+
+ MOCK_METHOD2(g_dbus_node_info_new_for_xml,
+ GDBusNodeInfo*(const gchar*, GError**));
+
+ MOCK_METHOD2(g_dbus_method_invocation_return_value,
+ GDBusNodeInfo*(GDBusMethodInvocation*, GVariant*));
+
+ MOCK_METHOD5(g_dbus_connection_send_message,
+ gboolean(GDBusConnection*, GDBusMessage*, GDBusSendMessageFlags,
+ volatile guint32*, GError**));
+ MOCK_METHOD2(g_dbus_message_set_unix_fd_list,
+ void(GDBusMessage*, GUnixFDList*));
+ MOCK_METHOD7(g_bus_watch_name_on_connection,
+ guint(GDBusConnection*, const gchar*, GBusNameWatcherFlags,
+ GBusNameAppearedCallback, GBusNameVanishedCallback, gpointer,
+ GDestroyNotify));
+};
+
+#endif // UNIT_TESTS_MOCK_GIO_MOCK_H_
diff --git a/mock/mock_hook.h b/mock/mock_hook.h
new file mode 100644
index 0000000..af27bba
--- /dev/null
+++ b/mock/mock_hook.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 UNIT_TESTS_MOCK_MOCK_HOOK_H_
+#define UNIT_TESTS_MOCK_MOCK_HOOK_H_
+
+#define MOCK_HOOK_P0(MOCK_CLASS, f) \
+ TestFixture::GetMock<MOCK_CLASS>().f()
+#define MOCK_HOOK_P1(MOCK_CLASS, f, p1) \
+ TestFixture::GetMock<MOCK_CLASS>().f(p1)
+#define MOCK_HOOK_P2(MOCK_CLASS, f, p1, p2) \
+ TestFixture::GetMock<MOCK_CLASS>().f(p1, p2)
+#define MOCK_HOOK_P3(MOCK_CLASS, f, p1, p2, p3) \
+ TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3)
+#define MOCK_HOOK_P4(MOCK_CLASS, f, p1, p2, p3, p4) \
+ TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4)
+#define MOCK_HOOK_P5(MOCK_CLASS, f, p1, p2, p3, p4, p5) \
+ TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5)
+#define MOCK_HOOK_P6(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6) \
+ TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6)
+#define MOCK_HOOK_P7(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7) \
+ TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6, p7)
+#define MOCK_HOOK_P8(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7, p8) \
+ TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6, p7, p8)
+#define MOCK_HOOK_P10(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) \
+ TestFixture::GetMock<MOCK_CLASS>().f( \
+ p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
+
+#endif // UNIT_TESTS_MOCK_MOCK_HOOK_H_
diff --git a/mock/module_mock.h b/mock/module_mock.h
new file mode 100644
index 0000000..9b19d89
--- /dev/null
+++ b/mock/module_mock.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 UNIT_TESTS_MOCK_MODULE_MOCK_H_
+#define UNIT_TESTS_MOCK_MODULE_MOCK_H_
+
+class ModuleMock {
+ public:
+ virtual ~ModuleMock() {}
+};
+
+#endif // UNIT_TESTS_MOCK_MODULE_MOCK_H_
diff --git a/mock/test_fixture.cc b/mock/test_fixture.cc
new file mode 100644
index 0000000..27f5666
--- /dev/null
+++ b/mock/test_fixture.cc
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 "test_fixture.h"
+
+#include <memory>
+
+std::unique_ptr<ModuleMock> TestFixture::mock_;
diff --git a/mock/test_fixture.h b/mock/test_fixture.h
new file mode 100644
index 0000000..1ea3b8f
--- /dev/null
+++ b/mock/test_fixture.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 UNIT_TESTS_MOCK_TEST_FIXTURE_H_
+#define UNIT_TESTS_MOCK_TEST_FIXTURE_H_
+
+#include <gtest/gtest.h>
+
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <utility>
+
+#include "module_mock.h"
+
+class TestFixture : public ::testing::Test {
+ public:
+ explicit TestFixture(std::unique_ptr<ModuleMock>&& mock) {
+ mock_ = std::move(mock);
+ }
+ virtual ~TestFixture() {
+ mock_.reset();
+ }
+
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+
+ template <typename T>
+ static T& GetMock() {
+ auto ptr = dynamic_cast<T*>(mock_.get());
+ if (!ptr)
+ throw std::invalid_argument("The test does not provide mock of \"" +
+ std::string(typeid(T).name()) + "\"");
+ return *ptr;
+ }
+
+ static std::unique_ptr<ModuleMock> mock_;
+};
+
+#endif // UNIT_TESTS_MOCK_TEST_FIXTURE_H_
diff --git a/packaging/buxton2.spec b/packaging/buxton2.spec
index 8d5587a..a310d7b 100644
--- a/packaging/buxton2.spec
+++ b/packaging/buxton2.spec
@@ -22,6 +22,7 @@ BuildRequires: pkgconfig(cynara-client-async)
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(sqlite3)
BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(gmock)
Requires: security-config
Requires(post): /usr/bin/getent
Requires(post): /usr/bin/chown
@@ -33,6 +34,11 @@ Requires(posttrans): /usr/bin/chmod
Obsoletes: buxton
Provides: buxton
+%if 0%{?gcov:1}
+BuildRequires: lcov
+BuildRequires: zip
+%endif
+
%description
Buxton is a security-enabled configuration management system. It
features a layered approach to configuration storage, with each
@@ -109,17 +115,17 @@ gcov objects for a buxton2 library
cp %{SOURCE1001} .
%build
+
+# for Address space layout randomization
+export CFLAGS="$CFLAGS -fPIE "
+export LDFLAGS="$LDFLAGS -pie"
+
%if 0%{?gcov:1}
export CFLAGS+=" -fprofile-arcs -ftest-coverage"
-export CXXFLAGS+=" -fprofile-arcs -ftest-coverage"
export FFLAGS+=" -fprofile-arcs -ftest-coverage"
export LDFLAGS+=" -lgcov"
%endif
-# for Address space layout randomization
-export CFLAGS="$CFLAGS -fPIE"
-export LDFLAGS="$LDFLAGS -pie"
-
%cmake -DVERSION=%{version} \
-DCONFPATH:PATH=%{_sysconfdir}/%{name}.conf \
-DMODULE_DIR:PATH=%{_libdir}/%{name} \
@@ -138,6 +144,7 @@ mkdir -p gcov-obj
find . -name '*.gcno' -exec cp '{}' gcov-obj ';'
%endif
+
%install
%make_install
@@ -171,6 +178,17 @@ mkdir -p %{buildroot}%{_datadir}/gcov/obj
install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
%endif
+%check
+export LD_LIBRARY_PATH=../../vconf-compat:../../lib
+ctest -V
+
+%if 0%{?gcov:1}
+lcov -c --ignore-errors graph --no-external -q -d . -o buxton2.info
+genhtml buxton2.info -o buxton2.out
+zip -r buxton2.zip buxton2.out
+install -m 0644 buxton2.zip %{buildroot}%{_datadir}/gcov/
+%endif
+
%post
/sbin/ldconfig
@@ -245,5 +263,5 @@ chsmack -a System %{dbdir}/*
%if 0%{?gcov:1}
%files gcov
-%{_datadir}/gcov/obj/*
+%{_datadir}/gcov/*
%endif
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..c90fac8
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(unit_tests)
diff --git a/test/unit_tests/CMakeLists.txt b/test/unit_tests/CMakeLists.txt
new file mode 100644
index 0000000..15c710d
--- /dev/null
+++ b/test/unit_tests/CMakeLists.txt
@@ -0,0 +1,27 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ UNIT_TESTS_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../mock/ UNIT_TESTS_SRCS)
+ADD_EXECUTABLE(${TARGET_BUXTON2_UNIT_TEST}
+ ${UNIT_TESTS_SRCS}
+)
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_BUXTON2_UNIT_TEST} PUBLIC
+ "${CMAKE_CURRENT_SOURCE_DIR}/../"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../../vconf-compat"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../../lib/include"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../../mock"
+)
+
+APPLY_PKG_CONFIG(${TARGET_BUXTON2_UNIT_TEST} PUBLIC
+ GLIB_DEPS
+ GMOCK_DEPS
+ VCONF_INTERNAL_KEYS_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_BUXTON2_UNIT_TEST} PUBLIC vconf buxton2)
+SET_TARGET_PROPERTIES(${TARGET_BUXTON2_UNIT_TEST} PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_BUXTON2_UNIT_TEST} PROPERTIES LINK_FLAGS "-pie")
+
+ADD_TEST(
+ NAME ${TARGET_BUXTON2_UNIT_TEST}
+ COMMAND ${TARGET_BUXTON2_UNIT_TEST}
+)
diff --git a/test/unit_tests/main.cc b/test/unit_tests/main.cc
new file mode 100644
index 0000000..5f340cd
--- /dev/null
+++ b/test/unit_tests/main.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+int main(int argc, char** argv) {
+ int ret = -1;
+ try {
+ testing::InitGoogleTest(&argc, argv);
+ } catch(...) {
+ std::cout << "Exception occurred" << std::endl;
+ }
+
+ try {
+ ret = RUN_ALL_TESTS();
+ } catch (const ::testing::internal::GoogleTestFailureException& e) {
+ ret = -1;
+ std::cout << "GoogleTestFailureException was thrown:" << e.what()
+ << std::endl;
+ }
+
+ return ret;
+}
diff --git a/test/unit_tests/test_vconf_compat.cc b/test/unit_tests/test_vconf_compat.cc
new file mode 100644
index 0000000..75bc074
--- /dev/null
+++ b/test/unit_tests/test_vconf_compat.cc
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdlib.h>
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <poll.h>
+
+#include "vconf.h"
+#include "proto.h"
+#include "test_fixture.h"
+#include "gio_mock.h"
+
+#include <iostream>
+#include <memory>
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+
+class Mocks : public ::testing::NiceMock<GioMock>{};
+
+GVariant* data__;
+class VconfCompatTest : public TestFixture {
+ public:
+ VconfCompatTest() : TestFixture(std::make_unique<Mocks>()) {}
+ virtual ~VconfCompatTest() {}
+
+ virtual void SetUp() {
+ list_ = vconf_keylist_new();
+ data__ = g_variant_new("s", "testvalue");
+ ASSERT_NE(list_, nullptr);
+ }
+
+ virtual void TearDown() {
+ g_variant_unref(data__);
+ vconf_keylist_free(list_);
+ }
+ keylist_t* list_;
+};
+
+TEST_F(VconfCompatTest, vconf_keylist_add_int) {
+ vconf_keylist_add_int(list_, "test", 7);
+
+ keynode_t* node;
+ vconf_keylist_lookup(list_, "test", &node);
+
+ int ret = vconf_keynode_get_int(node);
+ EXPECT_EQ(ret, 7);
+}
+
+TEST_F(VconfCompatTest, vconf_keylist_add_bool) {
+ vconf_keylist_add_bool(list_, "test", true);
+
+ keynode_t* node;
+ vconf_keylist_lookup(list_, "test", &node);
+
+ int ret = vconf_keynode_get_bool(node);
+ EXPECT_EQ(ret, 1);
+}
+
+TEST_F(VconfCompatTest, vconf_keylist_add_null) {
+ int len1 = vconf_keylist_add_null(list_, "test");
+ int len2 = vconf_keylist_add_null(list_, "test");
+ EXPECT_EQ(len1, len2);
+}
+
+TEST_F(VconfCompatTest, vconf_keylist_del) {
+ int len1 = vconf_keylist_add_bool(list_, "test", true);
+ int len2 = vconf_keylist_del(list_, "test");
+
+ EXPECT_EQ(len1, len2 + 1);
+}
+
+TEST_F(VconfCompatTest, vconf_keynode_get_name) {
+ vconf_keylist_add_bool(list_, "test", true);
+
+ keynode_t* node;
+ vconf_keylist_lookup(list_, "test", &node);
+
+ char* name = vconf_keynode_get_name(node);
+ EXPECT_STREQ(name, "test");
+}
+
+TEST_F(VconfCompatTest, vconf_keynode_get_type) {
+ vconf_keylist_add_bool(list_, "test", true);
+
+ keynode_t* node;
+ vconf_keylist_lookup(list_, "test", &node);
+
+ int type = vconf_keynode_get_type(node);
+ EXPECT_EQ(VCONF_TYPE_BOOL, type);
+}
+
+TEST_F(VconfCompatTest, vconf_keynode_get_dbl) {
+ vconf_keylist_add_dbl(list_, "test", 1.1);
+
+ keynode_t* node;
+ vconf_keylist_lookup(list_, "test", &node);
+ double ret = vconf_keynode_get_dbl(node);
+ EXPECT_EQ(ret, 1.1);
+}
+
+TEST_F(VconfCompatTest, vconf_keynode_get_str) {
+ vconf_keylist_add_str(list_, "test", "value");
+
+ keynode_t* node;
+ vconf_keylist_lookup(list_, "test", &node);
+ char* ret = vconf_keynode_get_str(node);
+ EXPECT_STREQ(ret, "value");
+}
+
+TEST_F(VconfCompatTest, vconf_keylist_rewind) {
+ vconf_keylist_add_str(list_, "test", "value");
+ vconf_keylist_add_str(list_, "test2", "value2");
+ vconf_keylist_add_str(list_, "test3", "value3");
+
+ keynode_t* node = vconf_keylist_nextnode(list_);
+ char* ret = vconf_keynode_get_str(node);
+ vconf_keylist_rewind(list_);
+ node = vconf_keylist_nextnode(list_);
+ char* ret2 = vconf_keynode_get_str(node);
+ EXPECT_STREQ(ret, ret2);
+}
+
+extern "C" int pthread_mutex_lock(pthread_mutex_t* mutex) {
+ return 0;
+}
+
+extern "C" int pthread_mutex_unlock(pthread_mutex_t* mutex) {
+ return 0;
+}
+
+typedef enum {
+ LOG_ID_INVALID = -1,
+ LOG_ID_MAIN,
+ LOG_ID_RADIO,
+ LOG_ID_SYSTEM,
+ LOG_ID_APPS,
+ LOG_ID_KMSG,
+ LOG_ID_SYSLOG,
+ LOG_ID_MAX
+} log_id_t;
+
+extern "C" int __dlog_print(
+ log_id_t log_id, int prio, const char* tag, const char* fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ printf("\n");
+
+ return 0;
+}
+
+void __vconf_callback_fn(keynode_t *node, void *user_data) {
+}
+
+extern "C" int connect(
+ int sock, const struct sockaddr *addr, socklen_t addrlen) {
+ return 1;
+}
+
+extern "C" ssize_t send(int sockfd, const void *buf, size_t len, int flags) {
+ return len;
+}
+
+
+GVariant* g_variant_new_from_data(const GVariantType* type,
+ gconstpointer data, gsize size, gboolean trusted, GDestroyNotify notify,
+ gpointer user_data) {
+ static int msgid = 0;
+ return g_variant_new("(qv)", MSG_GET,
+ g_variant_new("(uiuv)", msgid++, 0, 24,
+ data__));
+}
+
+extern "C" ssize_t recv(int sockfd, void *buf, size_t len, int flags) {
+ struct header* hdr = (struct header*)buf;
+ hdr->type = MSG_SINGLE;
+ hdr->mtype = MSG_GET;
+ hdr->total = 12;
+ hdr->len = 12;
+ return len;
+}
+
+extern "C" int poll(struct pollfd *fds, nfds_t nfds, int timeout) {
+ return 1;
+}
+
+extern "C" guint g_idle_add_full(gint priority, GSourceFunc function,
+ gpointer data, GDestroyNotify notify) {
+ function(data);
+ return 1;
+}
+
+TEST_F(VconfCompatTest, vconf_notify_key_changed) {
+ int ret = vconf_notify_key_changed("test", __vconf_callback_fn, nullptr);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_ignore_key_changed) {
+ int ret = vconf_ignore_key_changed("test", __vconf_callback_fn);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_set_int) {
+ int ret = vconf_set_int("key", 1);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_set_bool) {
+ int ret = vconf_set_bool("key_b", true);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_set_str) {
+ int ret = vconf_set_str("key_s", "str");
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_set_dbl) {
+ int ret = vconf_set_dbl("key_d", 0.5);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_get_int) {
+ int val;
+ if (data__ != nullptr)
+ g_variant_unref(data__);
+ data__ = g_variant_new("i", 777);
+ int ret = vconf_get_int("key", &val);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_get_bool) {
+ int val;
+ if (data__ != nullptr)
+ g_variant_unref(data__);
+ data__ = g_variant_new("b", true);
+ int ret = vconf_get_bool("key_b", &val);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_get_dbl) {
+ double val;
+ if (data__ != nullptr)
+ g_variant_unref(data__);
+ data__ = g_variant_new("d", true);
+ int ret = vconf_get_dbl("key_d", &val);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_get_str) {
+ if (data__ != nullptr)
+ g_variant_unref(data__);
+ data__ = g_variant_new("s", "test");
+ char* ret = vconf_get_str("key_s");
+ EXPECT_STREQ(ret, "test");
+}
+
+TEST_F(VconfCompatTest, vconf_set) {
+ vconf_keylist_add_str(list_, "test", "value");
+ int ret = vconf_set(list_);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_get) {
+ int ret = vconf_get(list_, "db/test", VCONF_GET_ALL);
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(VconfCompatTest, vconf_unset_negative) {
+ int ret = vconf_unset(nullptr);
+ EXPECT_EQ(ret, VCONF_ERROR_NOT_SUPPORTED);
+}
+
+TEST_F(VconfCompatTest, vconf_unset_recursive_negative) {
+ int ret = vconf_unset_recursive(nullptr);
+ EXPECT_EQ(ret, VCONF_ERROR_NOT_SUPPORTED);
+}
+
+TEST_F(VconfCompatTest, vconf_sync_key) {
+ int ret = vconf_sync_key("test");
+ EXPECT_EQ(ret, 0);
+}