From: i.metelytsia Date: Fri, 21 Sep 2018 09:11:11 +0000 (+0300) Subject: Commit summary: X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen;p=platform%2Fcore%2Fsecurity%2Fsuspicious-activity-monitor.git Commit summary: - Test coverage was improved Change-Id: I7c6d6e2dcd6f4812506bb6126406c9875ed66aab --- diff --git a/daemon/application_service.cpp b/daemon/application_service.cpp index e79134f..3589b04 100644 --- a/daemon/application_service.cpp +++ b/daemon/application_service.cpp @@ -94,7 +94,6 @@ int ApplicationService::uninstall(const std::string& package_name) { int res = -1; device_policy_manager_h handle = dpm_manager_create(); - if (handle) { res = dpm_application_uninstall_package(handle, package_name.c_str()); LOG_D(TAG, "dpm_application_uninstall_package returned %d", res); @@ -180,12 +179,6 @@ std::vector ApplicationService::get_processes_ids_by_path(const std::string return pids; } -int ApplicationService::device_power_off() -{ - sync(); - return reboot(RB_POWER_OFF); -} - std::string ApplicationService::find_this_executable() { std::string exe; diff --git a/daemon/application_service.h b/daemon/application_service.h index 5adf758..16e6df4 100644 --- a/daemon/application_service.h +++ b/daemon/application_service.h @@ -89,13 +89,6 @@ public: static std::vector get_processes_ids_by_path(const std::string& path); /** - * @brief Power off the device - * @details This API can be used to power off the device - * @return 0 if success - */ - static int device_power_off(); - - /** * @brief Returns path of current executable * @return Thie axecutable path as string */ diff --git a/daemon/dbus/dbuslistener.cpp b/daemon/dbus/dbuslistener.cpp index 6bad766..979e93a 100644 --- a/daemon/dbus/dbuslistener.cpp +++ b/daemon/dbus/dbuslistener.cpp @@ -62,7 +62,7 @@ DBusListener::DBusListener(AllowedPredicate&& allowed) : m_connection(nullptr), if (dbus_bus_request_name(m_connection, "com.samsung.sam.sink", DBUS_NAME_FLAG_REPLACE_EXISTING , nullptr) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { LOG_E(TAG, "dbus_bus_request_name failed!"); - dbus_connection_close(m_connection); + dbus_connection_unref(m_connection); throw std::runtime_error("dbus_bus_request_name failed!"); } @@ -73,11 +73,6 @@ DBusListener::DBusListener(AllowedPredicate&& allowed) : m_connection(nullptr), DBusListener::~DBusListener() { dbus_connection_unref(m_connection); - /* - You may not close a shared connection. - Connections created with dbus_connection_open() or dbus_bus_get() are shared. - */ - //dbus_connection_close(m_connection); } bool DBusListener::addHandler(const std::string& type, DBusHandler* handler) diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt index 8785933..7f9e67a 100644 --- a/utest/CMakeLists.txt +++ b/utest/CMakeLists.txt @@ -2,7 +2,7 @@ project(utest) add_definitions(-D__MOCK_THIRDPARTY__ -DUNIT_TESTS) -file(GLOB SRCS *.cpp ../daemon/*.cpp ../daemon/dpm/*.cpp ../daemon/audit/*.cpp mock/*.cpp) +file(GLOB SRCS *.cpp ../daemon/*.cpp ../daemon/dpm/*.cpp ../daemon/audit/*.cpp ../daemon/dbus/*.cpp mock/*.cpp) file(GLOB DAEMON_MAIN ../daemon/main.cpp) file(GLOB DAEMON_MAIN_THREAD ../daemon/main_thread.cpp) @@ -14,12 +14,12 @@ list(REMOVE_ITEM SRCS ${DAEMON_DBUS_THREAD}) add_executable (${PROJECT_NAME} ${SRCS}) -pkg_check_modules(UTEST_DEPS REQUIRED boost libcurl dpm dlog audit-trail capi-system-info systemd capi-appfw-app-control) +pkg_check_modules(UTEST_DEPS REQUIRED boost libcurl dpm dlog audit-trail capi-system-info systemd capi-appfw-app-control dbus-1) add_dependencies(${PROJECT_NAME} communication) include_directories(SYSTEM ${UTEST_DEPS_INCLUDE_DIRS}) -include_directories(../common/inc ../communication/inc ../daemon ../daemon/dpm ../daemon/audit mock) +include_directories(../common/inc ../communication/inc ../daemon ../daemon/dpm ../daemon/audit ../daemon/dbus mock) target_compile_definitions(${PROJECT_NAME} PRIVATE CONFIG_FILE_PATH=${DAEMON_CONFIG_DIR}/${DAEMON_CONFIG_FILE}) @@ -31,7 +31,8 @@ target_link_libraries(${PROJECT_NAME} boost_system dlog curl - capi-appfw-app-control) + capi-appfw-app-control + dbus-1) install(TARGETS ${PROJECT_NAME} DESTINATION ${BIN_DIR}) install(FILES tests.manifest DESTINATION ${MANIFESTDIR}) diff --git a/utest/mock/app_control_mock.h b/utest/mock/app_control_mock.h new file mode 100644 index 0000000..d6ca90a --- /dev/null +++ b/utest/mock/app_control_mock.h @@ -0,0 +1,41 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 APPCONTROLMOCK_H +#define APPCONTROLMOCK_H + +#include +#include "app_control_stub.h" + +class AppControlMock: public IAppControl +{ +public: + AppControlMock(): IAppControl() + { + } + + MOCK_METHOD1(app_control_create, int(app_control_h*)); + MOCK_METHOD0(app_control_destroy, int()); + + MOCK_METHOD1(app_control_set_operation, int(const char*)); + MOCK_METHOD1(app_control_set_app_id, int(const char*)); + MOCK_METHOD2(app_control_add_extra_data, int(const char*, const char*)); + + MOCK_METHOD2(app_control_send_launch_request, int(app_control_reply_cb, void*)); +}; + +#endif // APPCONTROLMOCK_H diff --git a/utest/mock/app_control_stub.cpp b/utest/mock/app_control_stub.cpp new file mode 100644 index 0000000..4c6946d --- /dev/null +++ b/utest/mock/app_control_stub.cpp @@ -0,0 +1,81 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include "app_control_stub.h" + +namespace +{ +static IAppControl* app_control = nullptr; + +void app_control_set_implementation(IAppControl* impl) +{ + app_control = impl; +} + +IAppControl* app_control_from_handle(app_control_h handle) +{ + assert(handle); + IAppControl** p = reinterpret_cast(handle); + assert(*p); + return *p; +} +} + +IAppControl::IAppControl() +{ + app_control_set_implementation(this); +} +IAppControl::~IAppControl() +{ + app_control_set_implementation(nullptr); +} + +int app_control_create(app_control_h* handle) +{ + assert(app_control); + int ret = app_control->app_control_create(handle); + *handle = (app_control_h)&app_control; + return ret; +} +int app_control_destroy(app_control_h handle) +{ + assert(handle); + IAppControl** p = reinterpret_cast(handle); + if (p != nullptr && *p != nullptr && *p == app_control) { + (*p)->app_control_destroy(); + } + return 0; +} + +int app_control_set_operation(app_control_h handle, const char* operation) +{ + return app_control_from_handle(handle)->app_control_set_operation(operation); +} +int app_control_set_app_id(app_control_h handle, const char* app_id) +{ + return app_control_from_handle(handle)->app_control_set_app_id(app_id); +} +int app_control_add_extra_data(app_control_h handle, const char* key, const char* value) +{ + return app_control_from_handle(handle)->app_control_add_extra_data(key, value); +} + +int app_control_send_launch_request(app_control_h handle, app_control_reply_cb callback, void* user_data) +{ + return app_control_from_handle(handle)->app_control_send_launch_request(callback, user_data); +} diff --git a/utest/mock/app_control_stub.h b/utest/mock/app_control_stub.h new file mode 100644 index 0000000..5b56dc3 --- /dev/null +++ b/utest/mock/app_control_stub.h @@ -0,0 +1,39 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 APPCONTROLSTUB_H +#define APPCONTROLSTUB_H + +#include + +class IAppControl +{ +public: + IAppControl(); + virtual ~IAppControl(); + + virtual int app_control_create(app_control_h* handle) = 0; + virtual int app_control_destroy() = 0; + + virtual int app_control_set_operation(const char* operation) = 0; + virtual int app_control_set_app_id(const char* app_id) = 0; + virtual int app_control_add_extra_data(const char* key, const char* value) = 0; + + virtual int app_control_send_launch_request(app_control_reply_cb callback, void* user_data) = 0; +}; + +#endif // APPCONTROLSTUB_H diff --git a/utest/mock/dbus_mock.h b/utest/mock/dbus_mock.h new file mode 100644 index 0000000..e699f5a --- /dev/null +++ b/utest/mock/dbus_mock.h @@ -0,0 +1,63 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 DBUSMOCK_H +#define DBUSMOCK_H + +#include +#include "dbus_stub.h" + +class DBusConnectionMock : public IDBusConnection +{ +public: + DBusConnectionMock() + { + } + + MOCK_METHOD2(dbus_bus_get, void*(DBusBusType, DBusError*)); + MOCK_METHOD3(dbus_bus_request_name, int(const char*, unsigned int, DBusError*)); + MOCK_METHOD2(dbus_bus_add_match, void(const char*, DBusError*)); + MOCK_METHOD1(dbus_connection_read_write, dbus_bool_t(int)); + MOCK_METHOD0(dbus_connection_pop_message, void*()); + MOCK_METHOD0(dbus_connection_flush, void()); + MOCK_METHOD0(dbus_connection_unref, void()); +}; + +class DBusMessageMock : public IDBusMessage +{ +public: + DBusMessageMock() + { + } + + MOCK_METHOD2(dbus_message_is_signal, dbus_bool_t(const char*, const char*)); + MOCK_METHOD1(dbus_message_iter_init, dbus_bool_t(DBusMessageIter*)); + MOCK_METHOD0(dbus_message_unref, void()); +}; + +class DBusMessageIterMock : public IDBusMessageIter +{ +public: + DBusMessageIterMock() + { + } + + MOCK_METHOD0(dbus_message_iter_get_arg_type, int()); + MOCK_METHOD1(dbus_message_iter_get_basic, void(void*)); +}; + +#endif // DBUSMOCK_H diff --git a/utest/mock/dbus_stub.cpp b/utest/mock/dbus_stub.cpp new file mode 100644 index 0000000..6cac430 --- /dev/null +++ b/utest/mock/dbus_stub.cpp @@ -0,0 +1,147 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include "dbus_stub.h" + +namespace +{ +static IDBusConnection* dbus_connection = nullptr; +static IDBusMessage* dbus_message = nullptr; +static IDBusMessageIter* dbus_message_iter = nullptr; + +void dbus_connection_set_implementation(IDBusConnection* impl) +{ + dbus_connection = impl; +} + +IDBusConnection* get_dbus_connection(DBusConnection* connection) +{ + assert(connection); + return reinterpret_cast(connection); +} + +void dbus_message_set_implementation(IDBusMessage* impl) +{ + dbus_message = impl; +} + +IDBusMessage* get_dbus_message(DBusMessage* message) +{ + assert(message); + return reinterpret_cast(message); +} + +void dbus_message_iter_set_implementation(IDBusMessageIter* impl) +{ + dbus_message_iter = impl; +} + +IDBusMessageIter* get_dbus_message_iter(DBusMessageIter* iter) +{ + assert(dbus_message_iter); + return dbus_message_iter; +} +} + +IDBusConnection::IDBusConnection() +{ + dbus_connection_set_implementation(this); +} +IDBusConnection::~IDBusConnection() +{ + dbus_connection_set_implementation(nullptr); +} + +DBusConnection* dbus_bus_get(DBusBusType type, DBusError* error) +{ + assert(dbus_connection); + return (DBusConnection*)(dbus_connection->dbus_bus_get(type, error)); +} + +int dbus_bus_request_name(DBusConnection* connection, const char* name, unsigned int flags, DBusError* error) +{ + return get_dbus_connection(connection)->dbus_bus_request_name(name, flags, error); +} + +void dbus_bus_add_match(DBusConnection* connection, const char* rule, DBusError* error) +{ + get_dbus_connection(connection)->dbus_bus_add_match(rule, error); +} + +dbus_bool_t dbus_connection_read_write(DBusConnection* connection, int timeout_milliseconds) +{ + return get_dbus_connection(connection)->dbus_connection_read_write(timeout_milliseconds); +} + +DBusMessage* dbus_connection_pop_message(DBusConnection* connection) +{ + return (DBusMessage*)get_dbus_connection(connection)->dbus_connection_pop_message(); +} + +void dbus_connection_flush(DBusConnection* connection) +{ + get_dbus_connection(connection)->dbus_connection_flush(); +} + +void dbus_connection_unref(DBusConnection* connection) +{ + get_dbus_connection(connection)->dbus_connection_unref(); +} + +IDBusMessage::IDBusMessage() +{ + dbus_message_set_implementation(this); +} +IDBusMessage::~IDBusMessage() +{ + dbus_message_set_implementation(nullptr); +} + +dbus_bool_t dbus_message_is_signal(DBusMessage* message, const char* iface, const char* signal_name) +{ + return get_dbus_message(message)->dbus_message_is_signal(iface, signal_name); +} + +dbus_bool_t dbus_message_iter_init(DBusMessage* message, DBusMessageIter* iter) +{ + return get_dbus_message(message)->dbus_message_iter_init(iter); +} + +void dbus_message_unref(DBusMessage* message) +{ + get_dbus_message(message)->dbus_message_unref(); +} + +IDBusMessageIter::IDBusMessageIter() +{ + dbus_message_iter_set_implementation(this); +} +IDBusMessageIter::~IDBusMessageIter() +{ + dbus_message_iter_set_implementation(nullptr); +} + +int dbus_message_iter_get_arg_type(DBusMessageIter* iter) +{ + return get_dbus_message_iter(iter)->dbus_message_iter_get_arg_type(); +} + +void dbus_message_iter_get_basic(DBusMessageIter* iter, void* value) +{ + get_dbus_message_iter(iter)->dbus_message_iter_get_basic(value); +} diff --git a/utest/mock/dbus_stub.h b/utest/mock/dbus_stub.h new file mode 100644 index 0000000..72cad84 --- /dev/null +++ b/utest/mock/dbus_stub.h @@ -0,0 +1,60 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 DBUSSTUB_H +#define DBUSSTUB_H + +#include + +class IDBusConnection +{ +public: + IDBusConnection(); + virtual ~IDBusConnection(); + + virtual void* dbus_bus_get(DBusBusType type, DBusError* error) = 0; + virtual int dbus_bus_request_name(const char* name, unsigned int flags, DBusError* error) = 0; + virtual void dbus_bus_add_match(const char* rule, DBusError* error) = 0; + virtual dbus_bool_t dbus_connection_read_write(int timeout_milliseconds) = 0; + virtual void* dbus_connection_pop_message() = 0; + virtual void dbus_connection_flush() = 0; + virtual void dbus_connection_unref() = 0; +}; + +class IDBusMessage +{ +public: + IDBusMessage(); + virtual ~IDBusMessage(); + + virtual dbus_bool_t dbus_message_is_signal(const char* iface, const char* signal_name) = 0; + virtual dbus_bool_t dbus_message_iter_init(DBusMessageIter* iter) = 0; + virtual void dbus_message_unref() = 0; +}; + +class IDBusMessageIter +{ +public: + IDBusMessageIter(); + ~IDBusMessageIter(); + + virtual int dbus_message_iter_get_arg_type() = 0; + virtual void dbus_message_iter_get_basic(void* value) = 0; +}; + + +#endif // DBUSSTUB_H diff --git a/utest/mock/sys_mock.h b/utest/mock/sys_mock.h index 45f4a60..192cccb 100644 --- a/utest/mock/sys_mock.h +++ b/utest/mock/sys_mock.h @@ -31,6 +31,8 @@ public: MOCK_METHOD1(uname, int(struct utsname*)); + MOCK_METHOD2(kill, int(pid_t, int)); + MOCK_METHOD2(system_info_get_platform_string, int(const char*, char**)); MOCK_METHOD2(system_info_get_value_string, int(system_info_key_e, char**)); }; diff --git a/utest/mock/sys_stub.cpp b/utest/mock/sys_stub.cpp index cff4e57..ef580c6 100644 --- a/utest/mock/sys_stub.cpp +++ b/utest/mock/sys_stub.cpp @@ -50,6 +50,11 @@ int __attribute__ ((visibility ("protected"))) uname(struct utsname* buf) return SysI::instance()->uname(buf); } +int __attribute__ ((visibility ("protected"))) kill(pid_t pid, int sig) +{ + return SysI::instance()->kill(pid, sig); +} + int system_info_get_platform_string(const char* key, char** value) { return SysI::instance()->system_info_get_platform_string(key, value); diff --git a/utest/mock/sys_stub.h b/utest/mock/sys_stub.h index d974d7e..f8d8ef6 100644 --- a/utest/mock/sys_stub.h +++ b/utest/mock/sys_stub.h @@ -18,6 +18,8 @@ #ifndef SYSSTUB_H #define SYSSTUB_H +#include +#include #include #include @@ -33,6 +35,8 @@ public: virtual int uname(struct utsname* buf) = 0; + virtual int kill(pid_t pid, int sig) = 0; + virtual int system_info_get_platform_string(const char* key, char** value) = 0; virtual int system_info_get_value_string(system_info_key_e key, char** value) = 0; diff --git a/utest/test_applicationservice.cpp b/utest/test_applicationservice.cpp new file mode 100644 index 0000000..e7ef861 --- /dev/null +++ b/utest/test_applicationservice.cpp @@ -0,0 +1,117 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include "application_service.h" +#include "app_control_mock.h" +#include "device_policy_manager_mock.h" +#include "sys_mock.h" + +using ::testing::_; +using ::testing::A; +using ::testing::DoAll; +using ::testing::SaveArg; +using ::testing::Eq; +using ::testing::StrEq; +using ::testing::TypedEq; +using ::testing::Return; + +namespace +{ +const std::string APP_ID{"test_app"}; +const std::string EX_DATA_KEY{"ex_data_key"}; +const std::string EX_DATA_VAL{"ex_data_val"}; +} + +/** + * @brief Test for ApplicationService::launch + */ +TEST(TestApplicationService, test_launch_failed) +{ + AppControlMock app_ctrl; + EXPECT_CALL(app_ctrl, app_control_create(_)).WillOnce(Return(-1)); + ASSERT_EQ(-1, agent::ApplicationService::launch(APP_ID, EX_DATA_KEY, EX_DATA_VAL)); +} + +/** + * @brief Test for ApplicationService::launch + */ +TEST(TestApplicationService, test_launch_success) +{ + AppControlMock app_ctrl; + EXPECT_CALL(app_ctrl, app_control_create(_)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_set_operation(_)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_set_app_id(StrEq(APP_ID))).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_add_extra_data(StrEq(EX_DATA_KEY), StrEq(EX_DATA_VAL))).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_send_launch_request(_, _)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_destroy()).WillOnce(Return(0)); + ASSERT_EQ(0, agent::ApplicationService::launch(APP_ID, EX_DATA_KEY, EX_DATA_VAL)); +} + +/** + * @brief Test for ApplicationService::install + */ +TEST(TestApplicationService, test_install_failed) +{ + DPMMock dpmm; + EXPECT_CALL(dpmm, dpm_manager_create()).WillOnce(Return(nullptr)); + ASSERT_EQ(-1, agent::ApplicationService::install(APP_ID)); +} + +/** + * @brief Test for ApplicationService::install + */ +TEST(TestApplicationService, test_install_success) +{ + DPMMock dpmm; + EXPECT_CALL(dpmm, dpm_manager_create()).WillOnce(Return(&dpmm)); + EXPECT_CALL(dpmm, dpm_application_install_package(StrEq(APP_ID))).WillOnce(Return(0)); + EXPECT_CALL(dpmm, dpm_manager_destroy()).Times(1); + ASSERT_EQ(0, agent::ApplicationService::install(APP_ID)); +} + +/** + * @brief Test for ApplicationService::uninstall + */ +TEST(TestApplicationService, test_uninstall_failed) +{ + DPMMock dpmm; + EXPECT_CALL(dpmm, dpm_manager_create()).WillOnce(Return(nullptr)); + ASSERT_EQ(-1, agent::ApplicationService::uninstall(APP_ID)); +} + +/** + * @brief Test for ApplicationService::uninstall + */ +TEST(TestApplicationService, test_uninstall_success) +{ + DPMMock dpmm; + EXPECT_CALL(dpmm, dpm_manager_create()).WillOnce(Return(&dpmm)); + EXPECT_CALL(dpmm, dpm_application_uninstall_package(StrEq(APP_ID))).WillOnce(Return(0)); + EXPECT_CALL(dpmm, dpm_manager_destroy()).Times(1); + ASSERT_EQ(0, agent::ApplicationService::uninstall(APP_ID)); +} + +/** + * @brief Test for ApplicationService::kill_process + */ +TEST(TestApplicationService, test_kill_process) +{ + SysMock sys; + EXPECT_CALL(sys, kill(Eq(1234), Eq(SIGKILL))).WillOnce(Return(0)); + EXPECT_EQ(0, agent::ApplicationService::kill_process(1234)); +} diff --git a/utest/test_auditdeleteallrules.cpp b/utest/test_auditdeleteallrules.cpp new file mode 100644 index 0000000..feed475 --- /dev/null +++ b/utest/test_auditdeleteallrules.cpp @@ -0,0 +1,91 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include "auditdeleteallrules.h" +#include "restservicemock.h" +#include "audit_trail_mock.h" +#include "settings.h" + +using ::testing::_; +using ::testing::A; +using ::testing::DoAll; +using ::testing::SaveArg; +using ::testing::Eq; +using ::testing::TypedEq; +using ::testing::Return; +using ::testing::Invoke; + +namespace +{ +const std::string TEST_DUID{"device-id"}; +const std::chrono::milliseconds TEST_KEEPALIVE{1}; +const std::string TEST_EVENT_TYPE{"rule"}; +const std::string TEST_EVENT_URI{"test-uri"}; +const std::string TEST_EVENT_CURI{"test-curi"}; +const std::string TEST_RESP_CONTENT{R"#({"type":"status-rule","data":{"rules":[]}})#"}; +} + +/** + * @brief TEST that event not confirmed when device is locked + */ +TEST(TestAuditDeleteAllRules, test_accept_when_locked) +{ + RestServiceMock rest; + Json::Value event_msg; + agent::Settings::instance().setLock(true); + event_msg["type"] = TEST_EVENT_TYPE; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditDeleteAllRules handler(conn); + communication::Event event(event_msg, conn); + + EXPECT_NO_THROW(handler.accept(event)); + agent::Settings::instance().setLock(false); +} + +/** + * @brief TEST for normal accept sequence + */ +TEST(TestAuditDeleteAllRules, test_accept) +{ + RestServiceMock rest; + Json::Value event_msg; + AuditTrailMock audit; + event_msg["type"] = TEST_EVENT_TYPE; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + Json::Reader reader; + Json::Value response; + reader.parse(TEST_RESP_CONTENT, response); + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditDeleteAllRules handler(conn); + communication::Event event(event_msg, conn); + + EXPECT_CALL(audit, audit_trail_create(_)) + .WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit, audit_trail_foreach_rule(_, _)) + .WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + //EXPECT_CALL(audit, audit_trail_remove_rule(_)) + //.WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), TypedEq(response))) + .Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} diff --git a/utest/test_auditrequestrulehandler.cpp b/utest/test_auditrequestrulehandler.cpp new file mode 100644 index 0000000..4b26e43 --- /dev/null +++ b/utest/test_auditrequestrulehandler.cpp @@ -0,0 +1,119 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include +#include "auditrequestrulehandler.h" +#include "restservicemock.h" +#include "audit_trail_mock.h" +#include "settings.h" + +using ::testing::_; +using ::testing::A; +using ::testing::DoAll; +using ::testing::SaveArg; +using ::testing::Eq; +using ::testing::TypedEq; +using ::testing::Return; +using ::testing::Throw; + +namespace +{ +const std::string TEST_DUID{"device-id"}; +const std::chrono::milliseconds TEST_KEEPALIVE{1}; +const std::string TEST_EVENT_URI{"test-uri"}; +const std::string TEST_EVENT_CURI{"test-curi"}; +const std::string REQUEST_KEY{"request-existing-rules"}; +const std::string ENFORCE_KEY{"response-existing-rules"}; +const std::string RESPONSE_KEY{"state-rule"}; +const std::string REQUEST_CONTENT{R"#({"type":"request-existing-rules"})#"}; +const std::string ENFORCE_CONTENT{R"#({"type":"response-existing-rules","data":[{"key":"test","syscall":[1]}]})#"}; +const std::string RESPONSE_CONTENT{R"#({"type":"state-rule","data":[{"condition":[],"key":"test","syscall":[1]}]})#"}; +} + +/** + * @brief TEST for normal request sequence + */ +TEST(TestAuditRequestRuleHandler, test_request) +{ + RestServiceMock rest; + Json::Reader reader; + Json::Value request; + reader.parse(REQUEST_CONTENT, request); + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditRequestRuleHandler handler(conn); + + EXPECT_CALL(rest, sendData(_, TypedEq(request))) + .WillOnce(Throw(std::runtime_error("sendData failed!"))) + .WillOnce(Return()); + + ASSERT_NO_THROW(handler.request()); +} + +/** + * @brief TEST that event not confirmed when device is locked + */ +TEST(TestAuditRequestRuleHandler, test_accept_when_locked) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditRequestRuleHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + + agent::Settings::instance().setLock(true); + EXPECT_NO_THROW(handler.accept(event)); + agent::Settings::instance().setLock(false); +} + +/** + * @brief TEST for normal accept sequence + */ +TEST(TestAuditRequestRuleHandler, test_accept) +{ + AuditTrailMock audit_trail; + AuditRuleMock audit_rule; + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditRequestRuleHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + Json::Reader reader; + Json::Value response; + reader.parse(RESPONSE_CONTENT, response); + + EXPECT_CALL(audit_trail, audit_trail_create(_)).WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_rule, audit_rule_create(_)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_rule, audit_rule_add_condition(_, _, _)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_rule, audit_rule_add_systemcall(_)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_trail, audit_trail_add_rule(_)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_rule, audit_rule_destroy()).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_trail, audit_trail_foreach_rule(_, _)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(ENFORCE_CONTENT)); + EXPECT_CALL(rest, sendData(_, TypedEq(response))).Times(1); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), A())).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} diff --git a/utest/test_auditrewriterulehandler.cpp b/utest/test_auditrewriterulehandler.cpp new file mode 100644 index 0000000..aa91e23 --- /dev/null +++ b/utest/test_auditrewriterulehandler.cpp @@ -0,0 +1,95 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include "auditrewriterulehandler.h" +#include "restservicemock.h" +#include "audit_trail_mock.h" +#include "settings.h" + +using ::testing::_; +using ::testing::A; +using ::testing::DoAll; +using ::testing::SaveArg; +using ::testing::Eq; +using ::testing::TypedEq; +using ::testing::Return; + +namespace +{ +const std::string TEST_DUID{"device-id"}; +const std::chrono::milliseconds TEST_KEEPALIVE{1}; +const std::string TEST_EVENT_URI{"test-uri"}; +const std::string TEST_EVENT_CURI{"test-curi"}; +const std::string ENFORCE_KEY{"rewrite-rule"}; +const std::string RESPONSE_KEY{"status-rule"}; +const std::string ENFORCE_CONTENT{R"#({"type":"rewrite-rule","data":[{"new":{"key":"test","syscall":[1]}}]})#"}; +const std::string RESPONSE_CONTENT{R"#({"data":{"result":[{"new":{"key":"test","syscall":[1]},"status":0}],"rules":[{"condition":[],"key":"test","syscall":[1]}]},"type":"status-rule"})#"}; +} + +/** + * @brief TEST that event not confirmed when device is locked + */ +TEST(TestAuditRewriteRuleHandler, test_accept_when_locked) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditRewriteRuleHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + + agent::Settings::instance().setLock(true); + EXPECT_NO_THROW(handler.accept(event)); + agent::Settings::instance().setLock(false); +} + +/** + * @brief TEST for normal accept sequence + */ +TEST(TestAuditRewriteRuleHandler, test_accept) +{ + AuditTrailMock audit_trail; + AuditRuleMock audit_rule; + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditRewriteRuleHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + Json::Reader reader; + Json::Value response; + reader.parse(RESPONSE_CONTENT, response); + + EXPECT_CALL(audit_trail, audit_trail_create(_)).WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_trail, audit_trail_foreach_rule(_, _)).WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_rule, audit_rule_create(_)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_rule, audit_rule_add_condition(_, _, _)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_rule, audit_rule_add_systemcall(_)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_trail, audit_trail_add_rule(_)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_rule, audit_rule_destroy()).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(ENFORCE_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), TypedEq(response))).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} diff --git a/utest/test_auditrewriterulesethandler.cpp b/utest/test_auditrewriterulesethandler.cpp new file mode 100644 index 0000000..23914ed --- /dev/null +++ b/utest/test_auditrewriterulesethandler.cpp @@ -0,0 +1,90 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include "auditrewriterulesethandler.h" +#include "restservicemock.h" +#include "audit_trail_mock.h" +#include "settings.h" + +using ::testing::_; +using ::testing::A; +using ::testing::DoAll; +using ::testing::SaveArg; +using ::testing::Eq; +using ::testing::TypedEq; +using ::testing::Return; + +namespace +{ +const std::string TEST_DUID{"device-id"}; +const std::chrono::milliseconds TEST_KEEPALIVE{1}; +const std::string TEST_EVENT_URI{"test-uri"}; +const std::string TEST_EVENT_CURI{"test-curi"}; +const std::string ENFORCE_KEY{"rewrite-profile"}; +const std::string RESPONSE_KEY{"status-profile"}; +const std::string ENFORCE_CONTENT{R"#({"type":"rewrite-profile", "data":["profile"]})#"}; +const std::string RESPONSE_CONTENT{R"#({"type":"status-profile","data":{"result":[{"name":"profile","status":0}],"rules":[]}})#"}; +} + +/** + * @brief TEST that event not confirmed when device is locked + */ +TEST(TestAuditRewriteRulesetHandler, test_accept_when_locked) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditRewriteRulesetHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + + agent::Settings::instance().setLock(true); + EXPECT_NO_THROW(handler.accept(event)); + agent::Settings::instance().setLock(false); +} + +/** + * @brief TEST for normal accept sequence + */ +TEST(TestAuditRewriteRulesetHandler, test_accept) +{ + AuditTrailMock audit_trail; + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditRewriteRulesetHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + Json::Reader reader; + Json::Value response; + reader.parse(RESPONSE_CONTENT, response); + + EXPECT_CALL(audit_trail, audit_trail_create(_)).WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_trail, audit_trail_foreach_rule(_, _)).WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit_trail, audit_trail_load_ruleset(_)).WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(ENFORCE_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), TypedEq(response))).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} diff --git a/utest/test_auditupdaterulesethandler.cpp b/utest/test_auditupdaterulesethandler.cpp new file mode 100644 index 0000000..7bbcfa6 --- /dev/null +++ b/utest/test_auditupdaterulesethandler.cpp @@ -0,0 +1,149 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include "auditupdaterulesethandler.h" +#include "restservicemock.h" +#include "audit_trail_mock.h" +#include "settings.h" + +using ::testing::_; +using ::testing::A; +using ::testing::DoAll; +using ::testing::SaveArg; +using ::testing::Eq; +using ::testing::TypedEq; +using ::testing::Return; + +namespace +{ +const std::string TEST_DUID{"device-id"}; +const std::chrono::milliseconds TEST_KEEPALIVE{1}; +const std::string TEST_EVENT_TYPE{"rule"}; +const std::string TEST_EVENT_URI{"test-uri"}; +const std::string TEST_EVENT_CURI{"test-curi"}; +const std::string TEST_UPDATE_CONTENT{R"#({"type":"update-profile", "data":["profile"]})#"}; +const std::string TEST_RESP_CONTENT{R"#({"type":"status-profile","data":{"result":[{"name":"profile","status":0}],"rules":[]}})#"}; +const std::string TEST_EMPTY_CONTENT{""}; +const std::string TEST_RESP_EMPTY_CONTENT{R"#({"type":"status-profile","data":null})#"}; +const std::string TEST_MALFORMED_CONTENT{"!@#$%^&*()_"}; +} + +/** + * @brief TEST that event not confirmed when device is locked + */ +TEST(TestAuditUpdateRulesetHandler, test_accept_when_locked) +{ + RestServiceMock rest; + Json::Value event_msg; + agent::Settings::instance().setLock(true); + event_msg["type"] = TEST_EVENT_TYPE; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditUpdateRulesetHandler handler(conn); + communication::Event event(event_msg, conn); + + EXPECT_NO_THROW(handler.accept(event)); + agent::Settings::instance().setLock(false); +} + +/** + * @brief TEST for normal accept sequence + */ +TEST(TestAuditUpdateRulesetHandler, test_accept) +{ + RestServiceMock rest; + Json::Value event_msg; + AuditTrailMock audit; + event_msg["type"] = TEST_EVENT_TYPE; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + Json::Reader reader; + Json::Value response; + reader.parse(TEST_RESP_CONTENT, response); + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditUpdateRulesetHandler handler(conn); + communication::Event event(event_msg, conn); + + EXPECT_CALL(audit, audit_trail_create(_)) + .WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit, audit_trail_load_ruleset(_)) + .WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(audit, audit_trail_foreach_rule(_, _)) + .WillOnce(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))) + .WillOnce(Return(TEST_UPDATE_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), TypedEq(response))) + .Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} + +/** + * @brief TEST work when event content is empty + */ +TEST(TestAuditUpdateRulesetHandler, test_empty_content) +{ + RestServiceMock rest; + Json::Value event_msg; + AuditTrailMock audit; + event_msg["type"] = TEST_EVENT_TYPE; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + Json::Reader reader; + Json::Value response; + reader.parse(TEST_RESP_EMPTY_CONTENT, response); + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditUpdateRulesetHandler handler(conn); + communication::Event event(event_msg, conn); + + EXPECT_CALL(audit, audit_trail_create(_)) + .WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))) + .WillOnce(Return(TEST_EMPTY_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), TypedEq(response))) + .Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} + +/** + * @brief TEST malformed JSON is recieved + */ +TEST(TestAuditUpdateRulesetHandler, test_exception_in_accept) +{ + RestServiceMock rest; + Json::Value event_msg, result; + AuditTrailMock audit; + event_msg["type"] = TEST_EVENT_TYPE; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::AuditUpdateRulesetHandler handler(conn); + communication::Event event(event_msg, conn); + + EXPECT_CALL(audit, audit_trail_create(_)) + .WillRepeatedly(Return(AUDIT_TRAIL_ERROR_NONE)); + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))) + .WillOnce(Return(TEST_MALFORMED_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), A())) + .WillOnce(SaveArg<2>(&result)); + + ASSERT_NO_THROW(handler.accept(event)); +} diff --git a/utest/test_dbuslistener.cpp b/utest/test_dbuslistener.cpp new file mode 100644 index 0000000..44f80d9 --- /dev/null +++ b/utest/test_dbuslistener.cpp @@ -0,0 +1,94 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include "dbuslistener.h" +#include "dbushandler.h" +#include "dbus_mock.h" + +using ::testing::_; +using ::testing::Eq; +using ::testing::Return; + +/** + * @brief Test for failed CTOR + */ +TEST(TestDBusListener, test_ctor_failed_1) +{ + DBusConnectionMock conn; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(nullptr)); + + std::shared_ptr listener = nullptr; + EXPECT_ANY_THROW(listener = std::make_shared([](){return true;})); +} + +/** + * @brief Test for failed CTOR + */ +TEST(TestDBusListener, test_ctor_failed_2) +{ + DBusConnectionMock conn; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(-1)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + + std::shared_ptr listener = nullptr; + EXPECT_ANY_THROW(listener = std::make_shared([](){return true;})); +} + +/** + * @brief Test CTOR for normal sequence + */ +TEST(TestDBusListener, test_ctor_success) +{ + DBusConnectionMock conn; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + + std::shared_ptr listener = nullptr; + EXPECT_NO_THROW(listener = std::make_shared([](){return true;})); +} + +/** + * @brief Test loop for normal sequence + */ +TEST(TestDBusListener, test_loop) +{ + DBusConnectionMock conn; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillOnce(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +} diff --git a/utest/test_killprocesshandler.cpp b/utest/test_killprocesshandler.cpp new file mode 100644 index 0000000..326f7b8 --- /dev/null +++ b/utest/test_killprocesshandler.cpp @@ -0,0 +1,175 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include "dbuslistener.h" +#include "dbushandler.h" +#include "killprocesshandler.h" +#include "settings.h" +#include "dbus_mock.h" +#include "sys_mock.h" + +using ::testing::_; +using ::testing::Eq; +using ::testing::StrEq; +using ::testing::Return; +using ::testing::DoAll; +using ::testing::Invoke; + +namespace +{ +const int PID = 1234; +const char* TEST_SIGNAL = "{\"type\":\"kill_process\",\"data\":{\"pid\":1234}}"; +const char* TEST_SIGNAL_EMPTY_DATA = "{\"type\":\"kill_process\",\"data\":{}}"; +const char* TEST_SIGNAL_INCORRECT_PID = "{\"type\":\"kill_process\",\"data\":{\"pid\":\"1234\"}}"; +} + +/** + * @brief Test signal when device is locked + */ +TEST(TestKillProcessHandler, test_process_locked) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL);})); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::KillProcessHandler handler{listener}; + + agent::Settings::instance().setLock(true); + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); + + agent::Settings::instance().setLock(false); +} + +/** + * @brief Test signal with empty data + */ +TEST(TestKillProcessHandler, test_process_empty_data) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL_EMPTY_DATA);})); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::KillProcessHandler handler{listener}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +} + +/** + * @brief Test signal with invalid pid + */ +TEST(TestKillProcessHandler, test_process_invalid_pid) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL_INCORRECT_PID);})); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::KillProcessHandler handler{listener}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +} + +/** + * @brief Test signal for normal sequence + */ +TEST(TestKillProcessHandler, test_process) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + SysMock sys; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL);})); + EXPECT_CALL(sys, kill(Eq(PID), Eq(SIGKILL))).WillOnce(Return(0)); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::KillProcessHandler handler{listener}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +} diff --git a/utest/test_notificationhandler.cpp b/utest/test_notificationhandler.cpp new file mode 100644 index 0000000..09d16c4 --- /dev/null +++ b/utest/test_notificationhandler.cpp @@ -0,0 +1,207 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include "notificationhandler.h" +#include "restservicemock.h" +#include "app_control_mock.h" +#include "settings.h" + +using ::testing::_; +using ::testing::A; +using ::testing::DoAll; +using ::testing::SaveArg; +using ::testing::Eq; +using ::testing::StrEq; +using ::testing::TypedEq; +using ::testing::Return; + +namespace +{ +const std::string TEST_DUID{"device-id"}; +const std::chrono::milliseconds TEST_KEEPALIVE{1}; +const std::string TEST_EVENT_URI{"test-uri"}; +const std::string TEST_EVENT_CURI{"test-curi"}; +const std::string ENFORCE_KEY{"notify_user"}; +const std::string EMPTY_CONTENT{""}; +const std::string NOTIFICATION_SERVICE{"org.example.samnotificationservice"}; +const std::string UNINSTALL_APP_EMPTY_CONTENT{R"#({"type":"notify-user","data":{"action":"uninstall_application"}})#"}; +const std::string UNINSTALL_APP_CONTENT{R"#({"type":"notify-user","data":{"action":"uninstall_application","subject":"org.example.photostealware"}})#"}; +const std::string UNINSTALL_APP_EX_DATA_KEY{ENFORCE_KEY}; +const std::string UNINSTALL_APP_EX_DATA_VAL{"{\"title\":\"SAM notification\",\"body\":\"Stealware process was detected [photostealware]. Remove it?\",\"buttons\":[{\"action\":{\"data\":{\"app_id\":\"org.example.photostealware\"},\"type\":\"uninstall_application\"},\"caption\":\"YES\"},{\"caption\":\"NO\"}]}"}; +const std::string KILL_PROCESS_EMPTY_CONTENT{R"#({"type":"notify-user","data":{"action":"kill_process"}})#"}; +const std::string KILL_PROCESS_CONTENT{R"#({"type":"notify-user","data":{"action":"kill_process","pid":1234,"path":"/usr/app/xmrstack"}})#"}; +const std::string KILL_PROCESS_EX_DATA_KEY{ENFORCE_KEY}; +const std::string KILL_PROCESS_EX_DATA_VAL{""}; +const std::string UNKNOWN_ACTION_CONTENT{R"#({"type":"notify-user","data":{"action":"undef"}})#"}; +} + +/** + * @brief TEST that event not confirmed when device is locked + */ +TEST(TestNotificationHandler, test_accept_when_locked) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::NotificationHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + + agent::Settings::instance().setLock(true); + EXPECT_NO_THROW(handler.accept(event)); + agent::Settings::instance().setLock(false); +} + +/** + * @brief TEST for empty content + */ +TEST(TestNotificationHandler, test_accept_empty_content) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::NotificationHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(EMPTY_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), A())).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} + +/** + * @brief TEST for uninstall application with empty subject + */ +TEST(TestNotificationHandler, test_accept_uninstall_application_empty_content) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::NotificationHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(UNINSTALL_APP_EMPTY_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), A())).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} + +/** + * @brief TEST for uninstall application + */ +TEST(TestNotificationHandler, test_accept_uninstall_application) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::NotificationHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + AppControlMock app_ctrl; + + EXPECT_CALL(app_ctrl, app_control_create(_)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_set_operation(_)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_set_app_id(StrEq(NOTIFICATION_SERVICE))).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_add_extra_data(StrEq(UNINSTALL_APP_EX_DATA_KEY), _)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_send_launch_request(_, _)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_destroy()).WillOnce(Return(0)); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(UNINSTALL_APP_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), A())).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} + +/** + * @brief TEST for kill process with empty content + */ +TEST(TestNotificationHandler, test_accept_kill_process_empty_content) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::NotificationHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(KILL_PROCESS_EMPTY_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), A())).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} + +/** + * @brief TEST for kill process + */ +TEST(TestNotificationHandler, test_accept_kill_process) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::NotificationHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + AppControlMock app_ctrl; + + EXPECT_CALL(app_ctrl, app_control_create(_)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_set_operation(_)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_set_app_id(StrEq(NOTIFICATION_SERVICE))).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_add_extra_data(StrEq(KILL_PROCESS_EX_DATA_KEY), _)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_send_launch_request(_, _)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_destroy()).WillOnce(Return(0)); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(KILL_PROCESS_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), A())).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} + +/** + * @brief TEST for unknown action + */ +TEST(TestNotificationHandler, test_accept_unknown_action) +{ + RestServiceMock rest; + communication::Connection conn(TEST_DUID, TEST_KEEPALIVE, &rest, [](){return true;}); + agent::NotificationHandler handler(conn); + Json::Value event_msg; + event_msg["uri"] = TEST_EVENT_URI; + event_msg["curi"] = TEST_EVENT_CURI; + event_msg["type"] = ENFORCE_KEY; + communication::Event event(event_msg, conn); + + EXPECT_CALL(rest, doGet(_, Eq(TEST_EVENT_URI))).WillOnce(Return(UNKNOWN_ACTION_CONTENT)); + EXPECT_CALL(rest, doPost(_, Eq(TEST_EVENT_CURI), A())).Times(1); + + ASSERT_NO_THROW(handler.accept(event)); +} diff --git a/utest/test_notifyuserhandler.cpp b/utest/test_notifyuserhandler.cpp new file mode 100644 index 0000000..d3dd1fe --- /dev/null +++ b/utest/test_notifyuserhandler.cpp @@ -0,0 +1,150 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include "dbuslistener.h" +#include "dbushandler.h" +#include "notifyuserhandler.h" +#include "settings.h" +#include "dbus_mock.h" +#include "app_control_mock.h" + +using ::testing::_; +using ::testing::Eq; +using ::testing::StrEq; +using ::testing::Return; +using ::testing::DoAll; +using ::testing::Invoke; + +namespace +{ +const std::string APP_ID{"org.example.samnotificationservice"}; +const std::string EX_DATA_KEY{"notify_user"}; +const std::string EX_DATA_VAL{"{\"title\":\"TITLE\"}\n"}; +const char* TEST_SIGNAL = "{\"type\":\"notify_user\",\"data\":{\"title\":\"TITLE\"}}"; +const char* TEST_SIGNAL_EMPTY_DATA = "{\"type\":\"notify_user\",\"data\":{}}"; +} + +/** + * @brief Test signal when device is locked + */ +TEST(TestNotifyUserHandler, test_process_locked) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL);})); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::NotifyUserHandler handler{listener}; + + agent::Settings::instance().setLock(true); + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); + + agent::Settings::instance().setLock(false); +} + +/** + * @brief Test signal with empty data + */ +TEST(TestNotifyUserHandler, test_process_empty_data) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL_EMPTY_DATA);})); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::NotifyUserHandler handler{listener}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +} + +/** + * @brief Test signal for normal sequence + */ +TEST(TestNotifyUserHandler, test_process) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + AppControlMock app_ctrl; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL);})); + EXPECT_CALL(app_ctrl, app_control_create(_)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_set_operation(_)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_set_app_id(StrEq(APP_ID))).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_add_extra_data(StrEq(EX_DATA_KEY), StrEq(EX_DATA_VAL))).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_send_launch_request(_, _)).WillOnce(Return(0)); + EXPECT_CALL(app_ctrl, app_control_destroy()).WillOnce(Return(0)); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::NotifyUserHandler handler{listener}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +} diff --git a/utest/test_uninstallhandler.cpp b/utest/test_uninstallhandler.cpp new file mode 100644 index 0000000..7ce144b --- /dev/null +++ b/utest/test_uninstallhandler.cpp @@ -0,0 +1,177 @@ +/** + * Samsung Ukraine R&D Center (SRK under a contract between) + * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include "dbuslistener.h" +#include "dbushandler.h" +#include "uninstallhandler.h" +#include "settings.h" +#include "dbus_mock.h" +#include "device_policy_manager_mock.h" + +using ::testing::_; +using ::testing::Eq; +using ::testing::StrEq; +using ::testing::Return; +using ::testing::DoAll; +using ::testing::Invoke; + +namespace +{ +const std::string APP_ID = "org.example.photostealware"; +const char* TEST_SIGNAL = "{\"type\":\"uninstall_application\",\"data\":{\"app_id\":\"org.example.photostealware\"}}"; +const char* TEST_SIGNAL_EMPTY_DATA = "{\"type\":\"uninstall_application\"}"; +const char* TEST_SIGNAL_INCORRECT_APP_ID = "{\"type\":\"uninstall_application\",\"data\":{\"app_id\":0}}"; +} + +/** + * @brief Test signal when device is locked + */ +TEST(TestUninstallHandler, test_process_locked) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL);})); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::UninstallHandler handler{listener}; + + agent::Settings::instance().setLock(true); + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); + + agent::Settings::instance().setLock(false); +} + +/** + * @brief Test signal with empty data + */ +TEST(TestUninstallHandler, test_process_empty_data) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL_EMPTY_DATA);})); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::UninstallHandler handler{listener}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +} + +/** + * @brief Test signal with invalid application id + */ +TEST(TestUninstallHandler, test_process_invalid_app_id) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL_INCORRECT_APP_ID);})); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::UninstallHandler handler{listener}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +} + +/** + * @brief Test signal for normal sequence + */ +TEST(TestUninstallHandler, test_process) +{ + DBusConnectionMock conn; + DBusMessageMock msg; + DBusMessageIterMock iter; + DPMMock dpm; + EXPECT_CALL(conn, dbus_bus_get(_, _)).WillOnce(Return(&conn)); + EXPECT_CALL(conn, dbus_bus_request_name(_, _, _)).WillOnce(Return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)); + EXPECT_CALL(conn, dbus_bus_add_match(_, _)).Times(1); + EXPECT_CALL(conn, dbus_connection_flush()).Times(1); + EXPECT_CALL(conn, dbus_connection_read_write(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(conn, dbus_connection_pop_message()).WillOnce(Return(&msg)).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(conn, dbus_connection_unref()).Times(1); + EXPECT_CALL(msg, dbus_message_is_signal(_, _)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_iter_init(_)).WillOnce(Return(true)); + EXPECT_CALL(msg, dbus_message_unref()).Times(1); + EXPECT_CALL(iter, dbus_message_iter_get_arg_type()).WillOnce(Return(DBUS_TYPE_STRING)); + EXPECT_CALL(iter, dbus_message_iter_get_basic(_)).WillOnce(Invoke([](void* value) {*(char**)value = strdup(TEST_SIGNAL);})); + EXPECT_CALL(dpm, dpm_manager_create()).WillOnce(Return(&dpm)); + EXPECT_CALL(dpm, dpm_application_uninstall_package(StrEq(APP_ID))).WillOnce(Return(0)); + EXPECT_CALL(dpm, dpm_manager_destroy()).Times(1); + + bool allowed = true; + dbus::DBusListener listener{[&allowed](){return allowed;}}; + dbus::UninstallHandler handler{listener}; + + std::thread t(&dbus::DBusListener::loop, &listener); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + allowed = false; + t.join(); +}