From 9704031bf3ab9e96c504412b79c3c320b3d86d66 Mon Sep 17 00:00:00 2001 From: Lomtev Dmytro Date: Wed, 4 Oct 2017 16:45:34 +0300 Subject: [PATCH] SECIOTSRK-596 Test coverage increased. Minor refactoring. --- device_core/ctrl_app_lib/src/ctrl_app_support.cpp | 2 +- device_core/iotivity_lib/inc/iot_resource.h | 98 +++------ device_core/iotivity_lib/inc/iot_resource_server.h | 8 +- device_core/iotivity_lib/src/iot_resource.cpp | 136 ++++-------- .../iotivity_lib/src/iot_resource_server.cpp | 9 +- device_core/nmdaemon/hub_policy_resource.cpp | 239 ++++++++++----------- device_core/nmdaemon/hub_policy_resource.h | 66 +++--- device_core/nmdaemon/hub_report_resource.cpp | 89 ++------ device_core/nmdaemon/hub_report_resource.h | 35 ++- device_core/nmdaemon/main_thread.cpp | 2 - device_core/nmdaemon/policyhandler.h | 6 +- device_core/nmdaemon/policyhandlerres.cpp | 47 +--- device_core/nmdaemon/policyhandlerres.h | 12 +- device_core/nmdaemon/reporthandler.h | 4 + device_core/nmdaemon/reporthandler_res.cpp | 45 +--- device_core/nmdaemon/reporthandler_res.h | 11 +- device_core/utest/CMakeLists.txt | 2 +- device_core/utest/test_audit_trail_stub.cpp | 29 ++- device_core/utest/test_commandhandler.cpp | 17 +- device_core/utest/test_hub_policy_resource.cpp | 150 +++++++++++++ device_core/utest/test_hub_report_resource.cpp | 63 ++++++ device_core/utest/test_iotresourceclient.cpp | 90 ++++++++ device_core/utest/test_mq.cpp | 12 +- device_core/utest/test_policyhandlerres.cpp | 69 ++++++ device_core/utest/test_reporthandlerres.cpp | 67 ++++++ device_core/utest/test_sd-daemon-stub.cpp | 7 + 26 files changed, 773 insertions(+), 542 deletions(-) create mode 100644 device_core/utest/test_hub_policy_resource.cpp create mode 100644 device_core/utest/test_hub_report_resource.cpp create mode 100644 device_core/utest/test_iotresourceclient.cpp create mode 100644 device_core/utest/test_policyhandlerres.cpp create mode 100644 device_core/utest/test_reporthandlerres.cpp create mode 100644 device_core/utest/test_sd-daemon-stub.cpp diff --git a/device_core/ctrl_app_lib/src/ctrl_app_support.cpp b/device_core/ctrl_app_lib/src/ctrl_app_support.cpp index 11a4126..088bc23 100644 --- a/device_core/ctrl_app_lib/src/ctrl_app_support.cpp +++ b/device_core/ctrl_app_lib/src/ctrl_app_support.cpp @@ -181,7 +181,7 @@ NM_ErrorCode NM_init(NM_hContext* ctx) return EC_INTERNAL_ERROR; } } else { - LOG_E(TAG, "Config file \"%s\" not found.", g_ini_file.c_str()); + LOG_W(TAG, "Config file \"%s\" not found.", g_ini_file.c_str()); LOG_W(TAG, "Use \"%s\" as IoT cloud address", g_cloud_host.c_str()); LOG_W(TAG, "Use \"%s\" as DSM server address", g_dsm_uri.c_str()); } diff --git a/device_core/iotivity_lib/inc/iot_resource.h b/device_core/iotivity_lib/inc/iot_resource.h index adda38d..12e21bb 100644 --- a/device_core/iotivity_lib/inc/iot_resource.h +++ b/device_core/iotivity_lib/inc/iot_resource.h @@ -1,11 +1,8 @@ #ifndef __IOT_RESOURCE_H__ #define __IOT_RESOURCE_H__ -#include -#include -#include - -#include "OCApi.h" +#include +#include "iotivity.h" namespace NetworkManager { @@ -13,99 +10,64 @@ namespace NetworkManager /** * @brief The IotResource class provides abstraction of IoTivity resource model */ -class IotResource +class IotResourceClient { public: + /** * @brief Constructor - * @param uri [in] uri used to locate resource - * @param types [in] types to identify resource - * @param interfaces [in] supported interfaces + * @param resource [in] pointer to OCResource instance */ - IotResource(const std::string& uri, const std::vector& types, const std::vector& interfaces); - - IotResource(const IotResource& obj) = default; - - virtual ~IotResource(); - - IotResource& operator=(const IotResource& obj) = default; + IotResourceClient(IoTivity* iotivity, const std::string& resource_type, const std::string& sid = ""); /** - * @brief getRepresentation - resource representation getter - * @return representation of resource + * @brief Destructor */ - OC::OCRepresentation getRepresentation() { - return m_representation; + virtual ~IotResourceClient() + { } /** - * @brief setRepresentation - resource representation setter - * @param rep updated resource representation + * @brief Assignment operator + * @param resource [in] pointer to OCResource instance + * @return */ - virtual void setRepresentation(OC::OCRepresentation& rep) = 0; + IotResourceClient& operator=(OC::OCResource::Ptr resource); /** - * @brief sendRepresentation - sends representation as response on request - * @param request [in] request for representation - * @return error code or OC_STACK_OK + * @brief Returns underlying OCResource shared pointer + * @return */ - OCStackResult sendRepresentation(std::shared_ptr request); + OC::OCResource::Ptr resource() + { + return m_resource; + } /** - * @brief registerResource - registers resource to make it discoverable - * @return error code or OC_STACK_OK + * @brief Try to find resource + * @param on_cloud [in] if true search in IoT cloud account + * @return true if resource found */ - OCStackResult registerResource(); + bool findResource(bool on_cloud = true, bool retry = true); /** - * @brief entityHandler - resource users request handler (called by OCF) - * @param request [in] request for resource - * @return error code or OC_EH_OK + * @brief Returns validity of the resorce */ - virtual OCEntityHandlerResult entityHandler(std::shared_ptr request) = 0; - - static std::shared_ptr createResourceObject( - const std::string& host, - const std::string& uri, - OCConnectivityType connectivity_type, - bool is_observable, - const std::vector& types, - const std::vector& interfaces); - -// static OCStackResult get( -// const std::shared_ptr resource, -// OC::OCRepresentation& representation, -// const std::string& type = "", -// const std::string& interface = "", -// const OC::QueryParamsMap& query_params = OC::QueryParamsMap{}); + operator bool() const; /** * @brief post - perform POST request to the resource - * @param resource [in] pointer to the resource - * @param type [in] type of resource to use - * @param interface [in] selected resource interface * @param representation [in] representation which have to be posted * @param query_params [in] additional query parameters * @return error code or OC_STACK_OK */ - static OCStackResult post( - const std::shared_ptr resource, - const std::string& type, - const std::string& interface, - const OC::OCRepresentation& representation, - const OC::QueryParamsMap& query_params); - - /** - * @brief getHandle - retruns handle used for publishing of the resource on resource directory - * @return handle - */ - OCResourceHandle getHandle() { - return m_handle; - } + virtual OCStackResult post(const OC::OCRepresentation& representation, const OC::QueryParamsMap& query_params); protected: - OCResourceHandle m_handle; - OC::OCRepresentation m_representation; + OC::OCResource::Ptr m_resource; + IoTivity* m_iotivity; + std::string m_type; + std::string m_sid; }; } // namespace NetworkManager diff --git a/device_core/iotivity_lib/inc/iot_resource_server.h b/device_core/iotivity_lib/inc/iot_resource_server.h index 4cb7d8c..825f263 100644 --- a/device_core/iotivity_lib/inc/iot_resource_server.h +++ b/device_core/iotivity_lib/inc/iot_resource_server.h @@ -15,7 +15,11 @@ public: IotResourceServer(const std::string& uri, const std::string& type); - IotResourceServer(const std::string& uri, const std::string& type, const std::vector& interfaces); + IotResourceServer( + const std::string& uri, + const std::string& type, + const std::vector& interfaces, + uint8_t flags = OC_DISCOVERABLE); virtual ~IotResourceServer(); @@ -94,7 +98,7 @@ public: return m_handle; } -private: +protected: OCResourceHandle m_handle; }; diff --git a/device_core/iotivity_lib/src/iot_resource.cpp b/device_core/iotivity_lib/src/iot_resource.cpp index bab4010..d550a19 100644 --- a/device_core/iotivity_lib/src/iot_resource.cpp +++ b/device_core/iotivity_lib/src/iot_resource.cpp @@ -1,18 +1,14 @@ -#include #include -#include -#include #include -#include #include - -#include "OCPlatform.h" -#include "RDClient.h" - +#include #include "iot_resource.h" #include "resource_callbacks.h" +#include "logging.h" +#include "network_manager_tag.h" using namespace OC; +namespace PH = std::placeholders; namespace { @@ -24,124 +20,68 @@ const std::chrono::seconds DEFAULT_TIMEOUT{5}; namespace NetworkManager { -IotResource::IotResource(const std::string& _uri, const std::vector& _types, - const std::vector& _interfaces) - : m_handle(nullptr) +IotResourceClient::IotResourceClient(IoTivity* iotivity, const std::string& resource_type, const std::string& sid) + : m_resource(nullptr), m_iotivity(iotivity), m_type(resource_type), m_sid(sid) { - m_representation.setUri(_uri); - m_representation.setResourceTypes(_types); - m_representation.setResourceInterfaces(_interfaces); } -IotResource::~IotResource() +IotResourceClient& IotResourceClient::operator=(OC::OCResource::Ptr resource) { - OC::OCPlatform::unregisterResource(m_handle); + m_resource = resource; } -OCStackResult IotResource::sendRepresentation(std::shared_ptr _request) +bool IotResourceClient::findResource(bool on_cloud, bool retry) { - auto response = std::make_shared(); + LOG_D(TAG, "IotResourceClient: search for resource of type '%s'", m_type.c_str()); - response->setRequestHandle(_request->getRequestHandle()); - response->setResourceHandle(_request->getResourceHandle()); + if (nullptr == m_iotivity) { + LOG_E(TAG, "IotResourceClient: iotivity not initialized"); + return false; + } - QueryParamsMap qpm = _request->getQueryParameters(); - auto fr = qpm.find("if"); - if (fr != qpm.end()) { - response->setResourceRepresentation(getRepresentation(), fr->second); + if (m_sid.empty()) { + m_resource = m_iotivity->findResource(on_cloud ? m_iotivity->host() : "", m_type, OC_RSRVD_WELL_KNOWN_URI); } else { - response->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE); + m_resource = m_iotivity->findResource(on_cloud ? m_iotivity->host() : "", m_type, OC_RSRVD_WELL_KNOWN_URI, m_sid); } - response->setResponseResult(OC_EH_OK); - - return OCPlatform::sendResponse(response); -} - -OCStackResult IotResource::registerResource() -{ - auto interfaces = m_representation.getResourceInterfaces(); - std::string uri = m_representation.getUri(); - auto result = OCPlatform::registerResource( - m_handle, - uri, - m_representation.getResourceTypes()[0], - interfaces[0], - std::bind(&IotResource::entityHandler, this, std::placeholders::_1), - OC_DISCOVERABLE); - - if (interfaces.size() > 1u) { - auto it = interfaces.begin(); - while (++it != interfaces.end()) { - OCPlatform::bindInterfaceToResource(m_handle, *it); + if (!m_resource && retry) { + if (m_iotivity->isConnected()) { + try { + m_iotivity->signIn(); + this->findResource(on_cloud, false); + } catch (std::exception& e) { + LOG_E(TAG, "IoTivity error: %s", e.what()); + } } } - return result; + + return bool(m_resource); } -std::shared_ptr IotResource::createResourceObject(const std::string& _host, - const std::string& _uri, - OCConnectivityType _connectivity_type, - bool _is_observable, - const std::vector& _types, - const std::vector& _interfaces) +IotResourceClient::operator bool() const { - return OCPlatform::constructResourceObject(_host, _uri, _connectivity_type, _is_observable, _types, _interfaces); + return bool(m_resource); } -//OCStackResult IotResource::get(const std::shared_ptr _resource, OCRepresentation& _representation, const std::string& _type, const std::string& _interface, const QueryParamsMap& _query_params) -//{ -// OCStackResult res = OC_STACK_ERROR; - -// if(_resource) -// { -// std::mutex mtx; -// std::unique_lock lck(mtx); -// std::condition_variable cvar; -// res = _resource->get( _type, -// _interface, -// _query_params, -// [&](const HeaderOptions&, const OCRepresentation& _rep, const int _ecode) -// { -//// if(_ecode != 4) -//// res = static_cast(_ecode); -// _representation = _rep; -// res = static_cast(_ecode); -// cvar.notify_all(); -// } ); -// cvar.wait(lck); -// } - -// return res; -//} - -OCStackResult IotResource::post(const std::shared_ptr _resource, const std::string& _type, - const std::string& _interface, const OCRepresentation& _representation, const QueryParamsMap& _query_params) +OCStackResult IotResourceClient::post(const OCRepresentation& representation, const QueryParamsMap& query_params) { OCStackResult res = OC_STACK_ERROR; - if (_resource) { + if (m_resource) { std::mutex mtx; std::unique_lock lck(mtx); std::condition_variable cvar; bool fired = false; - res = _resource->post( - _representation, - _query_params, - [&](const HeaderOptions&, const OCRepresentation & _rep, const int _ecode) { - if (_ecode > 4) { - // Fail codes have numbers bigger than 4 - res = static_cast(_ecode); - } - - fired = true; - cvar.notify_all(); - }); + auto callback = std::make_shared(); - cvar.wait_for(lck, std::chrono::seconds(3), [&fired] { return fired; }); + res = m_resource->post( + representation, + query_params, + bind_callback(callback, PH::_1, PH::_2, PH::_3)); - if (!fired) { - res = OC_STACK_TIMEOUT; + if (callback->wait()) { + res = static_cast(callback->errorCode); } } diff --git a/device_core/iotivity_lib/src/iot_resource_server.cpp b/device_core/iotivity_lib/src/iot_resource_server.cpp index f38ef68..c533584 100644 --- a/device_core/iotivity_lib/src/iot_resource_server.cpp +++ b/device_core/iotivity_lib/src/iot_resource_server.cpp @@ -15,8 +15,11 @@ IotResourceServer::IotResourceServer(const std::string& uri, const std::string& { } -IotResourceServer::IotResourceServer(const std::string& uri, const std::string& type, - const std::vector& interfaces) +IotResourceServer::IotResourceServer( + const std::string& uri, + const std::string& type, + const std::vector& interfaces, + uint8_t flags) : m_handle(nullptr) { if (uri.empty() || type.empty() || interfaces.size() == 0) { @@ -31,7 +34,7 @@ IotResourceServer::IotResourceServer(const std::string& uri, const std::string& type, interfaces[0], std::bind(&IotResourceServer::entityHandler, this, PH::_1), - OC_DISCOVERABLE); + flags); if (result != OC_STACK_OK) { throw IoTInternalError("Failed to register resource of type: " + type, result); diff --git a/device_core/nmdaemon/hub_policy_resource.cpp b/device_core/nmdaemon/hub_policy_resource.cpp index fbb90e0..ddfd84d 100644 --- a/device_core/nmdaemon/hub_policy_resource.cpp +++ b/device_core/nmdaemon/hub_policy_resource.cpp @@ -9,16 +9,14 @@ */ #include -#include +#include +#include +#include #include "OCPlatform.h" #include "hub_policy_resource.h" #include -#include #include -#include -#include #include "logging.h" -#include using namespace OC; using namespace std; @@ -26,15 +24,38 @@ namespace PH = std::placeholders; #define TAG "nmdaemon" +namespace +{ +template class ContainerType, typename KeyType, typename ValueType> +ValueType getOrDefault(const ContainerType& o, const KeyType& key, const ValueType& def) +{ + auto it = o.find(key); + return it == o.cend() ? ValueType(def) : ValueType(it->second); +} + +} + +const std::string PolicyResource::HUB_POLICY_RESOURCE_URI{"/a/policy"}; +const std::string PolicyResource::HUB_POLICY_RESORCE_TYPE{"core.policy"}; PolicyResource::PolicyResource(PolicyHandler* handler, const std::string& hub_device_id, std::shared_ptr hub, std::shared_ptr proxy) - : resource_handle(nullptr), hub_did(hub_device_id), policy_handler(handler), hub(hub), proxy(proxy) + : NetworkManager::IotResourceServer( + HUB_POLICY_RESOURCE_URI, + HUB_POLICY_RESORCE_TYPE, + {DEFAULT_INTERFACE}, + OC_DISCOVERABLE | OC_OBSERVABLE) + , hub_did(hub_device_id) + , policy_handler(handler) + , hub(hub) + , proxy(proxy) { assert(policy_handler != nullptr); assert(hub != nullptr); assert(proxy != nullptr); + + policy_handler->setObserver(std::bind(&PolicyResource::proxyCallback, this, PH::_1, PH::_2, PH::_3, PH::_4)); } PolicyResource::~PolicyResource() @@ -42,154 +63,112 @@ PolicyResource::~PolicyResource() policy_handler->clearObserver(); } -void PolicyResource::registerResource() +OCEntityHandlerResult PolicyResource::getHandler(const OC::OCRepresentation& representation, const OC::QueryParamsMap& params, + OC::OCRepresentation& response_body) { - uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; - EntityHandler cb = std::bind(&PolicyResource::entityHandler, this, PH::_1); - std::string uri{"/a/policy"}; - OCStackResult result = OCPlatform::registerResource( - resource_handle, uri, "core.policy", - DEFAULT_INTERFACE, cb, resourceProperty); - - if (OC_STACK_OK != result) { - LOG_E(TAG, "Policy resource creation was unsuccessful"); - } else { - LOG_D(TAG, "Policy resource created"); + LOG_D(TAG, "IN > PolicyResource::getHandler"); + OCEntityHandlerResult result = OC_EH_OK; + std::string policy{"[]"}; + + try { + const std::string& did = params.at("did"); + + auto agent_iter = params.find("agent"); + const std::string agent = agent_iter == params.cend() ? "user" : agent_iter->second; + + const auto child = policies.find(did); + + if (child != policies.cend()) { + const auto policy_it = child->second.find(agent); + + if (policy_it != child->second.cend()) { + policy = policy_it->second; + } + } + + response_body.setValue("agent", agent); + response_body.setValue("policy", policy); + } catch (std::out_of_range&) { + result = OC_EH_BAD_REQ; } - policy_handler->setObserver(std::bind(&PolicyResource::observHandler, this, PH::_1, PH::_2, PH::_3, PH::_4)); + return result; } -OCResourceHandle PolicyResource::getHandle() +OCEntityHandlerResult PolicyResource::postHandler(const OC::OCRepresentation& representation, const OC::QueryParamsMap& params, + OC::OCRepresentation& response_body) { - return resource_handle; -} + LOG_D(TAG, "IN > PolicyResource::postHandler"); + OCEntityHandlerResult result = OC_EH_OK; -OCRepresentation PolicyResource::get(const std::string& did, const std::string& agent) -{ - LOG_D(TAG, "IN > PolicyResource::get(const QueryParamsMap& params)"); - std::string policy{"[]"}; + try { + const std::string& did = params.at("did"); + + auto agent_iter = params.find("agent"); + const std::string agent = agent_iter == params.cend() ? "user" : agent_iter->second; - const auto child = policies.find(did); - if (child != policies.cend()) { - const auto policy_it = child->second.find(agent); - if (policy_it != child->second.cend()) { - policy = policy_it->second; + OC::QueryParamsMap proxy_params{{"did", did}, {"agent", agent}}; + + if (bool(proxy)) { + proxy->addDefferedTask(&PolicyHandler::pass, policy_handler, representation, proxy_params); } + } catch (std::out_of_range&){ + result = OC_EH_BAD_REQ; } - OCRepresentation rep; - rep.setValue("agent", agent); - rep.setValue("policy", policy); - return rep; + return result; } -OCEntityHandlerResult PolicyResource::entityHandler(std::shared_ptr request) +OCEntityHandlerResult PolicyResource::observHandler(const OC::OCRepresentation& representation, + const OC::QueryParamsMap& params, const OC::ObservationInfo& obsInfo) { - OCEntityHandlerResult ehResult = OC_EH_ERROR; + OCEntityHandlerResult result = OC_EH_OK; try { + const std::string& did = params.at("did"); + unique_lock lock(obs_mutex); - if (request) { - std::string requestType = request->getRequestType(); - int requestFlag = request->getRequestHandlerFlag(); - QueryParamsMap queries = request->getQueryParameters(); - std::string& did = queries["did"]; - std::string& agent_id = queries["agent"]; - if (agent_id.empty()) { - agent_id = "user"; - } + if (ObserveAction::ObserveRegister == obsInfo.action) { - LOG_D(TAG, "Policy request: %s", requestType.c_str()); - NetworkManager::printRepresentation(request->getResourceRepresentation()); - - if (requestFlag & RequestHandlerFlag::RequestFlag) { - - auto pResponse = make_shared(); - pResponse->setRequestHandle(request->getRequestHandle()); - pResponse->setResourceHandle(request->getResourceHandle()); - - if (requestType == "GET") { - pResponse->setResponseResult(OC_EH_OK); - pResponse->setResourceRepresentation(get(did, agent_id)); - if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) { - ehResult = OC_EH_OK; - } - } else if (requestType == "PUT") { - if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) { - ehResult = OC_EH_OK; - } - } else if (requestType == "POST") { - const auto& rep = request->getResourceRepresentation(); - QueryParamsMap qp{{"did", did}, {"agent", agent_id}}; - - if (bool(proxy)) { - proxy->addDefferedTask(&PolicyHandler::pass, policy_handler, rep, qp); - } - - if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) { - ehResult = OC_EH_OK; - } - } else if (requestType == "DELETE") { - } - } + if (hub->isOwned(did.c_str())) { + observers[did] = obsInfo.obsId; + + LOG_D(TAG, "Client [%s]:%d?di=%s was registered with ID %d" + , obsInfo.address.c_str() + , int(obsInfo.port) + , did.c_str() + , int(obsInfo.obsId)); - if (requestFlag & RequestHandlerFlag::ObserverFlag) { - ObservationInfo observationInfo = request->getObservationInfo(); - unique_lock lock(obs_mutex); - - if (ObserveAction::ObserveRegister == observationInfo.action) { - - if (hub->isOwned(did.c_str())) { - observers[did] = observationInfo.obsId; - - LOG_D(TAG, "Client [%s]:%d?di=%s was registered to observe %s\nObserve ID %d" - , observationInfo.address.c_str() - , int(observationInfo.port) - , did.c_str() - , request->getResourceUri().c_str() - , int(observationInfo.obsId)); - - ehResult = OC_EH_OK; - } else { - LOG_D(TAG, "Client [%s]:%d?di=%s can't be registered for observation %s\nObserve ID %d" - , observationInfo.address.c_str() - , int(observationInfo.port) - , did.c_str() - , request->getResourceUri().c_str() - , int(observationInfo.obsId)); - - ehResult = OC_EH_RESOURCE_NOT_FOUND; - } - } else if (ObserveAction::ObserveUnregister == observationInfo.action) { - LOG_D(TAG, "Observe unregister request ID %d", int(observationInfo.obsId)); - auto it = observers.find(did); - - if (it != observers.end()) { - LOG_D(TAG, "Observer found. Unregister"); - observers.erase(it); - } else { - LOG_E(TAG, "Observer not found."); - } - - ehResult = OC_EH_OK; - } + } else { + LOG_D(TAG, "Client [%s]:%d?di=%s is not owned and can't be registered" + , obsInfo.address.c_str() + , int(obsInfo.port) + , did.c_str()); + + result = OC_EH_RESOURCE_NOT_FOUND; + } + } else if (ObserveAction::ObserveUnregister == obsInfo.action) { + LOG_D(TAG, "Observe unregister request ID %d", int(obsInfo.obsId)); + auto it = observers.find(did); + + if (it != observers.end()) { + LOG_D(TAG, "Observer found. Unregister"); + observers.erase(it); + } else { + LOG_E(TAG, "Observer not found."); } - } else { - LOG_E(TAG, "Invalid request"); } - } catch (std::exception& e) { - LOG_E(TAG, "entityHandler exception: %s", e.what()); - ehResult = OC_EH_ERROR; + } catch (std::out_of_range&){ + result = OC_EH_BAD_REQ; } - return ehResult; + return result; } -void PolicyResource::observHandler(const HeaderOptions& /*head_options*/, const OCRepresentation& rep, const int& ecode, +void PolicyResource::proxyCallback(const HeaderOptions& /*head_options*/, const OCRepresentation& rep, const int& ecode, const int& seq_number) { - LOG_D(TAG, "IN > PolicyResource::observHandler"); + LOG_D(TAG, "IN > PolicyResource::proxyCallback"); if (ecode == OC_STACK_OK) { std::string did; @@ -224,14 +203,14 @@ void PolicyResource::observHandler(const HeaderOptions& /*head_options*/, const rep.setValue("policy", policy); notify_response->setResourceRepresentation(rep); notify_response->setResponseResult(OC_EH_OK); - OCPlatform::notifyListOfObservers(resource_handle, obs, notify_response); + OCPlatform::notifyListOfObservers(m_handle, obs, notify_response); } if (seq_number == (MAX_SEQUENCE_NUMBER + 1)) { - forgetAbout(did); + policies.erase(did); } } } else { - LOG_E(TAG, "[RMI_THREADS] Observe error: %d", ecode); + LOG_E(TAG, "Policy proxyCallback error: %d", ecode); } } diff --git a/device_core/nmdaemon/hub_policy_resource.h b/device_core/nmdaemon/hub_policy_resource.h index e052434..4b64826 100644 --- a/device_core/nmdaemon/hub_policy_resource.h +++ b/device_core/nmdaemon/hub_policy_resource.h @@ -23,59 +23,53 @@ using namespace OC; using namespace NMD; -class PolicyResource +class PolicyResource : public NetworkManager::IotResourceServer { -private: - OCResourceHandle resource_handle; - std::map observers; - std::map> policies; - std::mutex obs_mutex; - std::string hub_did; - PolicyHandler* policy_handler; - std::shared_ptr hub; - std::shared_ptr proxy; - public: /** + * @brief Hub policy resource URI + */ + static const std::string HUB_POLICY_RESOURCE_URI; + /** + * @brief Type of hub policy resource + */ + static const std::string HUB_POLICY_RESORCE_TYPE; + + /** * Constructor */ PolicyResource(PolicyHandler* handler, const std::string& hub_device_id, std::shared_ptr hub, std::shared_ptr proxy); ~PolicyResource(); - /** - * Register resource to make IOTivity clients to find it - */ - void registerResource(); + OCEntityHandlerResult getHandler(const OC::OCRepresentation& representation, const OC::QueryParamsMap& params, + OC::OCRepresentation& response_body) override; - /** - * Getter for resource handle - * - * @return OCResourceHandle object (used to publish resource on IoT cloud) - */ - OCResourceHandle getHandle(); + OCEntityHandlerResult postHandler(const OC::OCRepresentation& representation, const OC::QueryParamsMap& params, + OC::OCRepresentation& response_body) override; - /** - * @brief get the updated representation. - * @param did [in] id of device which request representation - * @param agent [in] agent id - * @return representation object - */ - OCRepresentation get(const std::string& did, const std::string& agent); + OCEntityHandlerResult observHandler(const OC::OCRepresentation& representation, + const OC::QueryParamsMap& params, const OC::ObservationInfo& obsInfo) override; /** - * @brief forgetAbout remove record for specified device - * @param did [in] id of device which policies must be removed + * @brief Used to proxy policy updates from server to primitive devices + * @param head_options [in] additional request headers + * @param representation [in] request data + * @param ecode [in] error code + * @param seq_number [in] number of the request */ - void forgetAbout(const std::string& did) { - policies.erase(did); - } + void proxyCallback(const HeaderOptions& head_options, const OCRepresentation& representation, const int& ecode, + const int& seq_number); private: - OCEntityHandlerResult entityHandler(std::shared_ptr request); - void observHandler(const HeaderOptions& head_options, const OCRepresentation& rep, const int& ecode, - const int& seq_number); + std::map observers; + std::map> policies; + std::mutex obs_mutex; + std::string hub_did; + PolicyHandler* policy_handler; + std::shared_ptr hub; + std::shared_ptr proxy; }; diff --git a/device_core/nmdaemon/hub_report_resource.cpp b/device_core/nmdaemon/hub_report_resource.cpp index fccd9ce..476f4d6 100644 --- a/device_core/nmdaemon/hub_report_resource.cpp +++ b/device_core/nmdaemon/hub_report_resource.cpp @@ -8,14 +8,7 @@ * @author Mail to: Dmytro Lomtev, d.lomtev@samsung.com */ -#include -#include -#include "OCPlatform.h" #include "hub_report_resource.h" -#include -#include -#include "iotutils.h" -#include #include "logging.h" using namespace OC; @@ -24,76 +17,32 @@ namespace PH = std::placeholders; #define TAG "nmdaemon" -ReportResource::ReportResource(ReportHandler& handler, std::shared_ptr proxy) - : m_resourceHandle(nullptr), report_handler(handler), proxy(proxy) -{ -} - -void ReportResource::registerResource() -{ - EntityHandler cb = std::bind(&ReportResource::entityHandler, this, PH::_1); - std::string uri{"/a/report"}; - OCStackResult result = OCPlatform::registerResource( - m_resourceHandle, uri, "core.security", - DEFAULT_INTERFACE, cb, OC_DISCOVERABLE); +const std::string ReportResource::HUB_REPORT_RESOURCE_URI{"/a/report"}; +const std::string ReportResource::HUB_REPORT_RESORCE_TYPE{"core.security"}; - if (OC_STACK_OK != result) { - LOG_E(TAG, "Security Resource creation was unsuccessful"); - } else { - LOG_D(TAG, "Report resource created"); - } -} - -OCResourceHandle ReportResource::getHandle() +ReportResource::ReportResource(ReportHandler& handler, std::shared_ptr proxy) + : NetworkManager::IotResourceServer(HUB_REPORT_RESOURCE_URI, HUB_REPORT_RESORCE_TYPE) + , report_handler(handler) + , proxy(proxy) { - return m_resourceHandle; } -OCEntityHandlerResult ReportResource::entityHandler(std::shared_ptr request) +OCEntityHandlerResult ReportResource::postHandler(const OC::OCRepresentation& request_body, + const OC::QueryParamsMap& params, OCRepresentation& /*response_body*/) { - OCEntityHandlerResult ehResult = OC_EH_METHOD_NOT_ALLOWED; - LOG_D(TAG, "IN > ReportResource::entityHandler"); + OCEntityHandlerResult res = OC_EH_INTERNAL_SERVER_ERROR; - if (request) { - std::string requestType = request->getRequestType(); - int requestFlag = request->getRequestHandlerFlag(); - LOG_D(TAG, "Request type %s", requestType.c_str()); - NetworkManager::printRepresentation(request->getResourceRepresentation()); - - if (requestFlag & RequestHandlerFlag::RequestFlag) { - - auto pResponse = make_shared(); - pResponse->setRequestHandle(request->getRequestHandle()); - pResponse->setResourceHandle(request->getResourceHandle()); - - if (requestType == "POST") { - const auto& rep = request->getResourceRepresentation(); - const auto& query = request->getQueryParameters(); - - try { - if (proxy) { - LOG_D(TAG, "Proxy add action: report pass"); - proxy->addDefferedTask(&ReportHandler::pass, &report_handler, rep, query); - } - } catch (std::exception& e) { - LOG_E(TAG, "Proxy add action exception: %s", e.what()); - } - - ehResult = OC_EH_OK; - } - - pResponse->setResponseResult(ehResult); - pResponse->setResourceRepresentation(OCRepresentation{}); - OCStackResult sendResult = OCPlatform::sendResponse(pResponse); - - if (OC_STACK_OK != sendResult) { - LOG_E(TAG, "Send response error: %d", sendResult); - } + try { + if (proxy) { + LOG_D(TAG, "Proxy add action: report pass"); + proxy->addDefferedTask(&ReportHandler::pass, &report_handler, request_body, params); } - } else { - LOG_E(TAG, "Invalid request"); - ehResult = OC_EH_ERROR; + + res = OC_EH_OK; + } catch (std::exception& e) { + LOG_E(TAG, "Proxy add action exception: %s", e.what()); } - return ehResult; + return res; } + diff --git a/device_core/nmdaemon/hub_report_resource.h b/device_core/nmdaemon/hub_report_resource.h index f4a06a3..9e6f880 100644 --- a/device_core/nmdaemon/hub_report_resource.h +++ b/device_core/nmdaemon/hub_report_resource.h @@ -10,43 +10,38 @@ * @author Mail to: Dmytro Lomtev, d.lomtev@samsung.com */ -#include "OCApi.h" #include -#include +#include "iot_resource_server.h" #include "reporthandler.h" #include "proxythread.h" using namespace OC; -void sql_test(); - -class ReportResource +class ReportResource : public NetworkManager::IotResourceServer { -private: - OCResourceHandle m_resourceHandle; - OCRepresentation m_reportRep; - ReportHandler& report_handler; - std::shared_ptr proxy; public: + /** - * Constructor + * @brief Hub report resource URI */ - ReportResource(ReportHandler& handler, std::shared_ptr proxy); - + static const std::string HUB_REPORT_RESOURCE_URI; /** - * Register resource to make IOTivity clients to find it + * @brief Type of hub report resource */ - void registerResource(); + static const std::string HUB_REPORT_RESORCE_TYPE; /** - * Getter for resource handle - * - * @return OCResourceHandle object (used to publish resource on IoT cloud) + * Constructor */ - OCResourceHandle getHandle(); + ReportResource(ReportHandler& handler, std::shared_ptr proxy); + + OCEntityHandlerResult postHandler(const OC::OCRepresentation& representation, const OC::QueryParamsMap& params, + OC::OCRepresentation& response_body) override; private: - OCEntityHandlerResult entityHandler(std::shared_ptr request); + + ReportHandler& report_handler; + std::shared_ptr proxy; }; #endif //__HUB_REPORT_RESOURCE__ diff --git a/device_core/nmdaemon/main_thread.cpp b/device_core/nmdaemon/main_thread.cpp index ff3fe45..73a9323 100644 --- a/device_core/nmdaemon/main_thread.cpp +++ b/device_core/nmdaemon/main_thread.cpp @@ -142,10 +142,8 @@ void MainThread::routine() rhandles.push_back(hub->getHandle()); report_hub_resorce = std::make_shared(*report_handler, proxy_thread); - report_hub_resorce->registerResource(); policy_hub_resource = std::make_shared(policy_handler.get(), iotivity->getDeviceID(), hub, proxy_thread); - policy_hub_resource->registerResource(); } CommandHandler command_handler(iotivity, hub, report_handler, policy_handler, proxy_thread, g_working_mode, this); diff --git a/device_core/nmdaemon/policyhandler.h b/device_core/nmdaemon/policyhandler.h index a130c6d..29d6b5b 100644 --- a/device_core/nmdaemon/policyhandler.h +++ b/device_core/nmdaemon/policyhandler.h @@ -19,14 +19,14 @@ public: * @brief setObserver set proxy observe callback * @param handler */ - void setObserver(ObserverCallback&& handler) { - callback = std::move(handler); + virtual void setObserver(const ObserverCallback& handler) { + callback = handler; } /** * @brief clearObserver delete proxy observe callback */ - void clearObserver() { + virtual void clearObserver() { } /** diff --git a/device_core/nmdaemon/policyhandlerres.cpp b/device_core/nmdaemon/policyhandlerres.cpp index 067cafc..ae87cd3 100644 --- a/device_core/nmdaemon/policyhandlerres.cpp +++ b/device_core/nmdaemon/policyhandlerres.cpp @@ -15,57 +15,32 @@ using namespace NetworkManager; namespace PH = std::placeholders; PolicyHandlerRes::PolicyHandlerRes(NetworkManager::IoTivity* iotivity, const std::string& server_id) - : PolicyHandler(iotivity), sid(server_id) + : PolicyHandler(iotivity) + , NetworkManager::IotResourceClient(iotivity, POLICY_RESOURCE_TYPE, server_id) { } void PolicyHandlerRes::pass(const OCRepresentation& rep, const QueryParamsMap& params) { - if (disabled) { - return; - } - - if (!resource) { - LOG_D(TAG, "[RMI_THREADS] Search for policy resource"); - findResource(); - } - - if (bool(resource) - && OC_STACK_OK != IotResource::post(resource, POLICY_RESOURCE_TYPE, DEFAULT_INTERFACE, rep, params)) { - resource.reset(); + if (!disabled && (m_resource || init())) { + if (OC_STACK_OK != post(rep, params)) { + LOG_W(TAG, "Failed to send policy"); + m_resource.reset(); + } } } bool PolicyHandlerRes::init() { - return findResource(); -} - -bool PolicyHandlerRes::findResource() -{ - auto iotivity = NetworkManager::IoTivity::getInstance(); - - resource = iotivity->findResource(iotivity->host(), POLICY_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, sid); - - if (!resource) { - if (iotivity->isConnected()) { - - try { - iotivity->signIn(); - resource = iotivity->findResource(iotivity->host(), POLICY_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, sid); - } catch (std::exception& e) { - LOG_E(TAG, "IoTivity error: %s", e.what()); - } - } - } + findResource(); - if (resource) { + if (m_resource) { QueryParamsMap query{{"did", iotivity->getDeviceID()}}; - resource->observe(ObserveType::Observe, query, std::bind(&PolicyHandlerRes::observeCallback, this, PH::_1, PH::_2, + m_resource->observe(ObserveType::Observe, query, std::bind(&PolicyHandlerRes::observeCallback, this, PH::_1, PH::_2, PH::_3, PH::_4)); } else { LOG_D(TAG, "[RMI_THREADS] Policy resource not found"); } - return bool(resource); + return bool(m_resource); } diff --git a/device_core/nmdaemon/policyhandlerres.h b/device_core/nmdaemon/policyhandlerres.h index 618e257..70bccf9 100644 --- a/device_core/nmdaemon/policyhandlerres.h +++ b/device_core/nmdaemon/policyhandlerres.h @@ -2,9 +2,10 @@ #define POLICYHANDLERRES_H #include "iotivity.h" +#include "iot_resource.h" #include "policyhandler.h" -class PolicyHandlerRes: public PolicyHandler +class PolicyHandlerRes: public PolicyHandler, public NetworkManager::IotResourceClient { public: /** @@ -24,15 +25,6 @@ public: virtual ~PolicyHandlerRes() {}; -protected: - std::shared_ptr resource; - std::string sid; - - /** - * @brief findResource starting search of policy resource on server - * @return true on success - */ - bool findResource(); }; #endif // POLICYHANDLERRES_H diff --git a/device_core/nmdaemon/reporthandler.h b/device_core/nmdaemon/reporthandler.h index 821c6a3..0b7b3c7 100644 --- a/device_core/nmdaemon/reporthandler.h +++ b/device_core/nmdaemon/reporthandler.h @@ -9,6 +9,10 @@ public: ReportHandler() : disabled(false) {} + virtual ~ReportHandler() + { + } + /** * @brief pass sends report representation to server * @param rep representation to send diff --git a/device_core/nmdaemon/reporthandler_res.cpp b/device_core/nmdaemon/reporthandler_res.cpp index 5e2eb7a..ed2ff04 100644 --- a/device_core/nmdaemon/reporthandler_res.cpp +++ b/device_core/nmdaemon/reporthandler_res.cpp @@ -12,48 +12,17 @@ namespace const std::string REPORT_RESOURCE_TYPE{"core.security"}; } -ReportHandlerRes::ReportHandlerRes(NetworkManager::IoTivity* iotivity, const std::string& server_id) - : iotivity(iotivity), server_id(server_id) +ReportHandlerRes::ReportHandlerRes(IoTivity* iotivity, const std::string& server_id) + : ReportHandler() + , IotResourceClient(iotivity, REPORT_RESOURCE_TYPE, server_id) { } -void ReportHandlerRes::pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) +void ReportHandlerRes::pass(const OCRepresentation& rep, const QueryParamsMap& params) { - if (disabled) { - return; - } - std::unique_lock lock(handler_mutex); - OCStackResult result = OC_STACK_ERROR; - - if (!resource) { - findResource(); - } - - if (resource) { - result = IotResource::post(resource, REPORT_RESOURCE_TYPE, DEFAULT_INTERFACE, rep, params); - - if (OC_STACK_OK != result) { - resource.reset(); + if (!disabled && (m_resource || findResource())) { + if (OC_STACK_OK != post(rep, params)) { + m_resource.reset(); } } } - -void ReportHandlerRes::findResource() -{ - if (disabled) { - return; - } - resource = iotivity->findResource(iotivity->host(), REPORT_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, server_id); - - if (!resource) { - if (iotivity->isConnected()) { - try { - iotivity->signIn(); - resource = iotivity->findResource(iotivity->host(), REPORT_RESOURCE_TYPE, OC_RSRVD_WELL_KNOWN_URI, server_id); - } catch (std::exception& e) { - LOG_E(TAG, "IoTivity error: %s", e.what()); - } - } - } -} - diff --git a/device_core/nmdaemon/reporthandler_res.h b/device_core/nmdaemon/reporthandler_res.h index ae0ea3e..2ba172b 100644 --- a/device_core/nmdaemon/reporthandler_res.h +++ b/device_core/nmdaemon/reporthandler_res.h @@ -3,9 +3,10 @@ #include #include "iotivity.h" +#include "iot_resource.h" #include "reporthandler.h" -class ReportHandlerRes: public ReportHandler +class ReportHandlerRes: public ReportHandler, public NetworkManager::IotResourceClient { public: /** @@ -16,14 +17,6 @@ public: void pass(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params) override; -private: - - void findResource(); - - std::shared_ptr resource; - NetworkManager::IoTivity* iotivity; - std::string server_id; - std::mutex handler_mutex; }; #endif // REPORTHANDLERRES_H diff --git a/device_core/utest/CMakeLists.txt b/device_core/utest/CMakeLists.txt index a1da63d..13e8617 100644 --- a/device_core/utest/CMakeLists.txt +++ b/device_core/utest/CMakeLists.txt @@ -4,7 +4,7 @@ project(${ProjectId}) add_definitions(-D__MOCK_THIRDPARTY__) -if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "CCOV") +if (NOT ("${CMAKE_BUILD_TYPE}" STREQUAL "CCOV" OR "${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")) SET (CMAKE_BUILD_TYPE TEST) endif () diff --git a/device_core/utest/test_audit_trail_stub.cpp b/device_core/utest/test_audit_trail_stub.cpp index 99c121a..00b8edb 100644 --- a/device_core/utest/test_audit_trail_stub.cpp +++ b/device_core/utest/test_audit_trail_stub.cpp @@ -7,7 +7,7 @@ void testCb(const char* log, void* user_data) { } -TEST(AuditTrailStub, test_all) +TEST(Test_AuditTrailStub, test_all) { AuditTrailMock mock; audit_trail_set_implementation(&mock); @@ -59,4 +59,31 @@ TEST(AuditTrailStub, test_all) EXPECT_EQ(RESULT_CODE, audit_trail_remove_syscall_cb(handle, id)); EXPECT_EQ(RESULT_CODE, audit_trail_enable_syscall(handle, enable)); EXPECT_EQ(RESULT_CODE, audit_trail_is_enabled_syscall(handle, &enable)); + + AuditTrailDefaultImpl impl; + EXPECT_EQ(0, impl.audit_trail_create(&handle)); + EXPECT_EQ(&impl, handle); + EXPECT_EQ(0, impl.audit_trail_destroy()); + EXPECT_EQ(0, impl.audit_trail_foreach_dac(nullptr, nullptr)); + EXPECT_EQ(0, impl.audit_trail_clear_dac()); + EXPECT_EQ(0, impl.audit_trail_add_dac_cb(nullptr, nullptr, nullptr)); + EXPECT_EQ(0, impl.audit_trail_remove_dac_cb(1)); + EXPECT_EQ(0, impl.audit_trail_enable_dac(true)); + bool en; + EXPECT_EQ(0, impl.audit_trail_is_enabled_dac(&en)); + EXPECT_TRUE(en); + EXPECT_EQ(0, impl.audit_trail_foreach_mac(nullptr, nullptr)); + EXPECT_EQ(0, impl.audit_trail_clear_mac()); + EXPECT_EQ(0, impl.audit_trail_add_mac_cb(nullptr, nullptr, nullptr)); + EXPECT_EQ(0, impl.audit_trail_remove_mac_cb(1)); + EXPECT_EQ(0, impl.audit_trail_enable_mac(true)); + EXPECT_EQ(0, impl.audit_trail_is_enabled_mac(&en)); + EXPECT_TRUE(en); + EXPECT_EQ(0, impl.audit_trail_foreach_syscall(nullptr, nullptr)); + EXPECT_EQ(0, impl.audit_trail_clear_syscall()); + EXPECT_EQ(0, impl.audit_trail_add_syscall_cb(nullptr, nullptr, nullptr)); + EXPECT_EQ(0, impl.audit_trail_remove_syscall_cb(1)); + EXPECT_EQ(0, impl.audit_trail_enable_syscall(true)); + EXPECT_EQ(0, impl.audit_trail_is_enabled_syscall(&en)); + EXPECT_TRUE(en); } diff --git a/device_core/utest/test_commandhandler.cpp b/device_core/utest/test_commandhandler.cpp index b62f8b9..8bbc644 100644 --- a/device_core/utest/test_commandhandler.cpp +++ b/device_core/utest/test_commandhandler.cpp @@ -26,7 +26,6 @@ const std::string UNREG_TOPIC{"/srv/unreg"}; const std::string ACTION_UNREGISTER{"unregister"}; const std::string DEVICE_ID{"this-device-id"}; const std::string OTHER_DEVICE_ID{"unknown-device-id"}; -} class ReportHandlerStub: public ReportHandler { @@ -36,10 +35,10 @@ public: } }; -class PolicyHandlerMock : public PolicyHandler +class PolicyHandlerStub : public PolicyHandler { public: - PolicyHandlerMock(): PolicyHandler(nullptr) + PolicyHandlerStub(): PolicyHandler(nullptr) { } @@ -53,6 +52,8 @@ public: } }; +} + class MainThreadMock : public ThreadBase { public: @@ -81,7 +82,7 @@ TEST(Test_commandhandler, test_unOwnTask_standard) std::shared_ptr proxy = std::make_shared(); std::shared_ptr hub = nullptr; std::shared_ptr rh = std::make_shared(); - std::shared_ptr ph = std::make_shared(); + std::shared_ptr ph = std::make_shared(); proxy->start(); @@ -112,7 +113,7 @@ TEST(Test_commandhandler, test_uninstallTask) std::shared_ptr proxy = std::make_shared(); std::shared_ptr hub = std::make_shared(&iot, proxy.get(), std::string{""}); std::shared_ptr rh = std::make_shared(); - std::shared_ptr ph = std::make_shared(); + std::shared_ptr ph = std::make_shared(); ThreadBase mt; CommandHandler handler(&iot, hub, rh, ph, proxy, WorkingMode::Standard, &mt); @@ -137,7 +138,7 @@ TEST(Test_commandhandler, test_uninstall_wrong_params) std::shared_ptr proxy = std::make_shared(); std::shared_ptr hub = std::make_shared(&iot, proxy.get(), std::string{""}); std::shared_ptr rh = std::make_shared(); - std::shared_ptr ph = std::make_shared(); + std::shared_ptr ph = std::make_shared(); ThreadBase mt; CommandHandler handler(&iot, hub, rh, ph, proxy, WorkingMode::Standard, &mt); @@ -168,7 +169,7 @@ TEST(Test_commandhandler, test_uninstallTask_dpm_failure) std::shared_ptr proxy = std::make_shared(); std::shared_ptr hub = std::make_shared(&iot, proxy.get(), std::string{""}); std::shared_ptr rh = std::make_shared(); - std::shared_ptr ph = std::make_shared(); + std::shared_ptr ph = std::make_shared(); ThreadBase mt; CommandHandler handler(&iot, hub, rh, ph, proxy, WorkingMode::Standard, &mt); @@ -191,7 +192,7 @@ TEST(Test_commandhandler, test_unsupported_command) std::shared_ptr proxy = std::make_shared(); std::shared_ptr hub = std::make_shared(&iot, proxy.get(), std::string{""}); std::shared_ptr rh = std::make_shared(); - std::shared_ptr ph = std::make_shared(); + std::shared_ptr ph = std::make_shared(); ThreadBase mt; CommandHandler handler(&iot, hub, rh, ph, proxy, WorkingMode::Standard, &mt); diff --git a/device_core/utest/test_hub_policy_resource.cpp b/device_core/utest/test_hub_policy_resource.cpp new file mode 100644 index 0000000..b3a12b3 --- /dev/null +++ b/device_core/utest/test_hub_policy_resource.cpp @@ -0,0 +1,150 @@ +#include +#include "hub_policy_resource.h" + +using ::testing::Eq; +using ::testing::_; + +/** + * @brief ReportHandler Mocking class + */ +class PolicyHandlerMock: public PolicyHandler +{ +public: + PolicyHandlerMock(): PolicyHandler(nullptr) + { + } + + MOCK_METHOD1(setObserver, void(const ObserverCallback& handler)); + MOCK_METHOD0(clearObserver, void()); + MOCK_METHOD2(pass, void(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params)); + MOCK_METHOD0(init, bool()); +}; + +/** + * @brief TEST for PolicyResource::postHandler method normal call + * 1. Create objects and mocks + * 2. Set expectations + * 3. Call method with wrong parameters + * 4. Call method with parameters for user enforced policy case + * 5. Call method with parameters for agent enforced policy case + * 6. Check the result + * 7. Check that PolicyHandlerMock::pass called with expected arguments + */ +TEST(Test_PolicyResource, postHandler) +{ + const std::string THIS_DEVICE_ID{"this-device-id"}; + const std::string PRIMITIVE_DEVICE_ID{"primitive-device-id"}; + const std::string AGENT_ID{"microsoft agent"}; + OC::OCRepresentation policy; + + OC::QueryParamsMap wrong_params{}; + OC::QueryParamsMap user_eforced_policy{{"did", THIS_DEVICE_ID}}; + OC::QueryParamsMap user_eforced_policy_matcher{{"did", THIS_DEVICE_ID}, {"agent", "user"}}; + OC::QueryParamsMap agent_eforced_policy{{"did", THIS_DEVICE_ID}, {"agent", AGENT_ID}}; + + policy.setValue("policy", std::string{"[fake policy]"}); + + PolicyHandlerMock policyHandler; + ProxyThread executor; + HubResource hub(NetworkManager::IoTivity::getInstance(), &executor, ""); + ::testing::InSequence dummy; + + EXPECT_CALL(policyHandler, setObserver(_)).Times(1); + EXPECT_CALL(policyHandler, pass(Eq(policy), Eq(user_eforced_policy_matcher))).Times(1); + EXPECT_CALL(policyHandler, pass(Eq(policy), Eq(agent_eforced_policy))).Times(1); + EXPECT_CALL(policyHandler, clearObserver()).Times(1); + + executor.start(); + + // Test PolicyResource object creation + PolicyResource policyResource( + &policyHandler, + THIS_DEVICE_ID, + std::shared_ptr(&hub, [](HubResource*){}), + std::shared_ptr(&executor, [](ProxyThread*){})); + + OC::OCRepresentation response; + + // Call with parameters that does not contain "did" property results in BAD_REQ error + EXPECT_EQ(OC_EH_BAD_REQ, policyResource.postHandler(policy, wrong_params, response)); + EXPECT_EQ(response, OC::OCRepresentation{}); + // User enforced policy case + EXPECT_EQ(OC_EH_OK, policyResource.postHandler(policy, user_eforced_policy, response)); + EXPECT_EQ(response, OC::OCRepresentation{}); + // Agent enforced policy case + EXPECT_EQ(OC_EH_OK, policyResource.postHandler(policy, agent_eforced_policy, response)); + EXPECT_EQ(response, OC::OCRepresentation{}); + + executor.stop(); + executor.join(); +} + +/** + * @brief TEST for ReportResource::postHandler method normal call + * 1. Create objects and mocks + * 2. Set expectations + * 3. Call method + * 4. Check the result + * 5. Check that ReportHandlerMock::pass called + */ +TEST(Test_PolicyResource, getHandler) +{ + const std::string THIS_DEVICE_ID{"this-device-id"}; + const std::string PRIMITIVE_DEVICE_ID{"primitive-device-id"}; + const std::string AGENT_ID{"microsoft agent"}; + OC::OCRepresentation not_used; + OC::OCRepresentation policy; + OC::OCRepresentation policy_match; + OC::OCRepresentation policy_empty_match; + + OC::QueryParamsMap wrong_params{}; + OC::QueryParamsMap primitive_policy_request{{"did", PRIMITIVE_DEVICE_ID}, {"agent", AGENT_ID}}; + + policy.setValue("policy", std::string{"[fake policy]"}); + policy.setValue("duid", PRIMITIVE_DEVICE_ID); + policy.setValue("agent", AGENT_ID); + + policy_match.setValue("policy", std::string{"[fake policy]"}); + policy_match.setValue("agent", AGENT_ID); + + policy_empty_match.setValue("policy", std::string{"[]"}); + policy_empty_match.setValue("agent", AGENT_ID); + + PolicyHandlerMock policyHandler; + ProxyThread executor; + HubResource hub(NetworkManager::IoTivity::getInstance(), &executor, ""); + ::testing::InSequence dummy; + + EXPECT_CALL(policyHandler, setObserver(_)).Times(1); + EXPECT_CALL(policyHandler, clearObserver()).Times(1); + + executor.start(); + + // Test PolicyResource object creation + PolicyResource policyResource( + &policyHandler, + THIS_DEVICE_ID, + std::shared_ptr(&hub, [](HubResource*){}), + std::shared_ptr(&executor, [](ProxyThread*){})); + + OC::OCRepresentation response; + // Call with parameters that does not contain "did" property results in BAD_REQ error + EXPECT_EQ(OC_EH_BAD_REQ, policyResource.getHandler(not_used, wrong_params, response)); + EXPECT_EQ(response, OC::OCRepresentation{}); + + // Call with error flag + EXPECT_NO_THROW(policyResource.proxyCallback(HeaderOptions{}, policy, OC_STACK_ERROR, 1)); + // Check get empty policy + EXPECT_EQ(OC_EH_OK, policyResource.getHandler(not_used, primitive_policy_request, response)); + EXPECT_EQ(policy_empty_match, response); + + // Simulate policy update from the server + EXPECT_NO_THROW(policyResource.proxyCallback(HeaderOptions{}, policy, OC_STACK_OK, 1)); + // Check get good policy + EXPECT_EQ(OC_EH_OK, policyResource.getHandler(not_used, primitive_policy_request, response)); + EXPECT_EQ(policy_match, response); + + executor.stop(); + executor.join(); +} + diff --git a/device_core/utest/test_hub_report_resource.cpp b/device_core/utest/test_hub_report_resource.cpp new file mode 100644 index 0000000..9f8adbd --- /dev/null +++ b/device_core/utest/test_hub_report_resource.cpp @@ -0,0 +1,63 @@ +#include +#include "hub_report_resource.h" + +using ::testing::Eq; +using ::testing::_; + +/** + * @brief ReportHandler Mocking class + */ +class ReportHandlerMock: public ReportHandler +{ +public: + MOCK_METHOD2(pass, void(const OC::OCRepresentation& rep, const OC::QueryParamsMap& params)); +}; + +/** + * @brief TEST for ReportResource::postHandler method normal call + * 1. Create objects and mocks + * 2. Set expectations + * 3. Call method + * 4. Check the result + * 5. Check that ReportHandlerMock::pass called + */ +TEST(Test_ReportResource, postHandler) +{ + ReportHandlerMock reportHandler; + ProxyThread executor; + OC::OCRepresentation report; + report.setValue("report", std::string{"text of the report"}); + + EXPECT_CALL(reportHandler, pass(Eq(report), _)).Times(1); + executor.start(); + ReportResource reportResource(reportHandler, std::shared_ptr(&executor, [](ProxyThread*){})); + OC::OCRepresentation response; + + EXPECT_EQ(OC_EH_OK, reportResource.postHandler(report, OC::QueryParamsMap{}, response)); + EXPECT_EQ(response, OC::OCRepresentation{}); + + executor.stop(); + executor.join(); +} + +/** + * @brief TEST for ReportResource::postHandler method call when no proxy thread supplied + * 1. Create objects and mocks + * 2. Set expectations + * 3. Call method + * 4. Check the result + * 5. Check that ReportHandlerMock::pass is not called + */ +TEST(Test_ReportResource, postHandler_nullproxy) +{ + ReportHandlerMock reportHandler; + OC::OCRepresentation report; + report.setValue("report", std::string{"text of the report"}); + + EXPECT_CALL(reportHandler, pass(Eq(report), _)).Times(0); + ReportResource reportResource(reportHandler, std::shared_ptr()); + OC::OCRepresentation response; + + EXPECT_EQ(OC_EH_OK, reportResource.postHandler(report, OC::QueryParamsMap{}, response)); + EXPECT_EQ(response, OC::OCRepresentation{}); +} diff --git a/device_core/utest/test_iotresourceclient.cpp b/device_core/utest/test_iotresourceclient.cpp new file mode 100644 index 0000000..56c9f5f --- /dev/null +++ b/device_core/utest/test_iotresourceclient.cpp @@ -0,0 +1,90 @@ +#include "iotivity_mock.h" +#include "iot_resource.h" + +using namespace NetworkManager; +using ::testing::ReturnRef; +using ::testing::Return; +using ::testing::StrEq; +using ::testing::Eq; +using ::testing::_; +using ::testing::Matcher; + +namespace +{ +const std::string RESOURCE_SID{"resource-sid"}; +const std::string RESOURCE_TYPE{"resource.type"}; +const std::string RESOURCE_HOST{"coap://192.168.1.2:5000"}; +const std::string RESOURCE_URI{"/a/link"}; +} + +TEST(Test_IotResourceClient, findResource_no_iotivity) +{ + IotResourceClient with_no_iotivity(nullptr, RESOURCE_TYPE, RESOURCE_SID); + EXPECT_FALSE(with_no_iotivity.findResource()); +} + +TEST(Test_IotResourceClient, findResource_with_resignIn) +{ + IoTivityMock iotivity; + OC::OCResource::Ptr empty; + auto resource_stub = OC::OCPlatform::constructResourceObject( + RESOURCE_HOST, + RESOURCE_URI, + CT_DEFAULT, + true, + {RESOURCE_TYPE}, + {OC::DEFAULT_INTERFACE}); + + + EXPECT_CALL(iotivity, host()).WillRepeatedly(ReturnRef(RESOURCE_HOST)); + + { + ::testing::InSequence dummy; + + EXPECT_CALL(iotivity, findResource( + Matcher(StrEq(RESOURCE_HOST)), + StrEq(RESOURCE_TYPE), + StrEq(OC_RSRVD_WELL_KNOWN_URI), + Matcher(StrEq(RESOURCE_SID)))) + .WillOnce(Return(empty)); + EXPECT_CALL(iotivity, isConnected()).WillOnce(Return(true)); + EXPECT_CALL(iotivity, signIn()).Times(1); + EXPECT_CALL(iotivity, findResource( + Matcher(StrEq(RESOURCE_HOST)), + StrEq(RESOURCE_TYPE), + StrEq(OC_RSRVD_WELL_KNOWN_URI), + Matcher(Eq(RESOURCE_SID)))) + .WillOnce(Return(resource_stub)); + } + + IotResourceClient res(&iotivity, RESOURCE_TYPE, RESOURCE_SID); + + EXPECT_TRUE(res.findResource()); +} + +TEST(Test_IotResourceClient, findResource) +{ + IoTivityMock iotivity; + OC::OCResource::Ptr empty; + auto resource_stub = OC::OCPlatform::constructResourceObject( + RESOURCE_HOST, + RESOURCE_URI, + CT_DEFAULT, + true, + {RESOURCE_TYPE}, + {OC::DEFAULT_INTERFACE}); + + ::testing::InSequence dummy; + EXPECT_CALL(iotivity, host()).WillRepeatedly(ReturnRef(RESOURCE_HOST)); + EXPECT_CALL(iotivity, findResource( + Matcher(StrEq(RESOURCE_HOST)), + StrEq(RESOURCE_TYPE), + StrEq(OC_RSRVD_WELL_KNOWN_URI), + Matcher(Eq(CT_DEFAULT)))) + .WillOnce(Return(resource_stub)); + + IotResourceClient res(&iotivity, RESOURCE_TYPE); + + EXPECT_TRUE(res.findResource()); +} + diff --git a/device_core/utest/test_mq.cpp b/device_core/utest/test_mq.cpp index 9894cc2..c441c8e 100644 --- a/device_core/utest/test_mq.cpp +++ b/device_core/utest/test_mq.cpp @@ -91,8 +91,9 @@ static void subscribeCB(const HeaderOptions&, TEST_F(TestIotMQ, publishCorrect) { try { - std::string stringToPublish("test"); - std::string stringToPublish2("test2"); + const std::string stringToPublish("test"); + const std::string stringToPublish2("test2"); + const std::string test_topic("/topic1/test2"); OCRepresentation rep; rep["message"] = stringToPublish; @@ -100,18 +101,17 @@ TEST_F(TestIotMQ, publishCorrect) std::unique_lock notificationLock(notificationMtx); auto mqHandler = iot->getMqHandler(); - mqHandler->subscribe("/topic1/test2", &subscribeCB); - mqHandler->publish("/topic1/test2", rep); + mqHandler->subscribe(test_topic, &subscribeCB); + mqHandler->publish(test_topic, rep); notificationCV.wait_for( notificationLock, std::chrono::seconds(3)); - mqHandler->unsubscribe("/topic1/test2"); + mqHandler->unsubscribe(test_topic); notificationCV.wait_for(notificationLock, std::chrono::seconds(3)); rep["message"] = stringToPublish2; -// mqHandler->publish("/topic1/test2", rep); ASSERT_TRUE(firstCallbackFired); ASSERT_TRUE(lastCallbackFired); diff --git a/device_core/utest/test_policyhandlerres.cpp b/device_core/utest/test_policyhandlerres.cpp new file mode 100644 index 0000000..2b295eb --- /dev/null +++ b/device_core/utest/test_policyhandlerres.cpp @@ -0,0 +1,69 @@ +#include +#include +#include "iotivity_mock.h" +#include "policyhandlerres.h" + +using ::testing::ReturnRef; +using ::testing::Return; +using ::testing::StrEq; +using ::testing::Eq; +using ::testing::_; +using ::testing::Matcher; + +namespace +{ +const std::string RESOURCE_HOST{"coap://192.168.1.2:5000"}; +const std::string RESOURCE_URI{"/resource"}; +const std::string RESOURCE_TYPE{"core.policy"}; +const std::string DEVICE_ID{"this-device-id"}; +} + +class PolicyHandlerResMock: public PolicyHandlerRes +{ +public: + PolicyHandlerResMock(NetworkManager::IoTivity* iotivity, const std::string& server_id = "") + : PolicyHandlerRes(iotivity, server_id) + { + } + + MOCK_METHOD2(post, OCStackResult(const OC::OCRepresentation& representation, const OC::QueryParamsMap& query_params)); +}; + +TEST(Test_PolicyHandlerRes, pass) +{ + IoTivityMock iotivity; + PolicyHandlerResMock policyHandler(&iotivity); + OC::OCRepresentation test_rep; + test_rep.setValue("key", std::string{"value"}); + OC::QueryParamsMap test_params{{"param", "value"}}; + + auto resource_stub = OC::OCPlatform::constructResourceObject( + RESOURCE_HOST, + RESOURCE_URI, + CT_DEFAULT, + true, + {RESOURCE_TYPE}, + {OC::DEFAULT_INTERFACE}); + + EXPECT_CALL(iotivity, host()).WillOnce(ReturnRef(RESOURCE_HOST)); + EXPECT_CALL(iotivity, getDeviceID()).WillOnce(ReturnRef(DEVICE_ID)); + EXPECT_CALL(iotivity, findResource( + Matcher(StrEq(RESOURCE_HOST)), + Eq(RESOURCE_TYPE), + Eq(OC_RSRVD_WELL_KNOWN_URI), + Matcher(Eq(CT_DEFAULT)))) + .WillOnce(Return(resource_stub)); + EXPECT_CALL(policyHandler, post(Eq(test_rep), Eq(test_params))).WillOnce(Return(OC_STACK_OK)); + + policyHandler.pass(test_rep, test_params); +} + +TEST(Test_PolicyHandlerRes, create_without_iotivity) +{ + PolicyHandlerResMock policyHandler(nullptr); + OC::OCRepresentation test_rep; + test_rep.setValue("key", std::string{"value"}); + OC::QueryParamsMap test_params{{"param", "value"}}; + + EXPECT_NO_THROW(policyHandler.pass(test_rep, test_params)); +} diff --git a/device_core/utest/test_reporthandlerres.cpp b/device_core/utest/test_reporthandlerres.cpp new file mode 100644 index 0000000..59caac4 --- /dev/null +++ b/device_core/utest/test_reporthandlerres.cpp @@ -0,0 +1,67 @@ +#include +#include +#include "iotivity_mock.h" +#include "reporthandler_res.h" + +using ::testing::ReturnRef; +using ::testing::Return; +using ::testing::StrEq; +using ::testing::Eq; +using ::testing::_; +using ::testing::Matcher; + +namespace +{ +const std::string RESOURCE_HOST{"coap://192.168.1.2:5000"}; +const std::string RESOURCE_URI{"/resource"}; +const std::string RESOURCE_TYPE{"core.security"}; +} + +class ReportHandlerResMock: public ReportHandlerRes +{ +public: + ReportHandlerResMock(NetworkManager::IoTivity* iotivity, const std::string& server_id = "") + : ReportHandlerRes(iotivity, server_id) + { + } + + MOCK_METHOD2(post, OCStackResult(const OC::OCRepresentation& representation, const OC::QueryParamsMap& query_params)); +}; + +TEST(Test_ReportHandlerRes, pass) +{ + IoTivityMock iotivity; + ReportHandlerResMock reportHandler(&iotivity); + OC::OCRepresentation test_rep; + test_rep.setValue("key", std::string{"value"}); + OC::QueryParamsMap test_params{{"param", "value"}}; + + auto resource_stub = OC::OCPlatform::constructResourceObject( + RESOURCE_HOST, + RESOURCE_URI, + CT_DEFAULT, + true, + {RESOURCE_TYPE}, + {OC::DEFAULT_INTERFACE}); + + EXPECT_CALL(iotivity, host()).WillOnce(ReturnRef(RESOURCE_HOST)); + EXPECT_CALL(iotivity, findResource( + Matcher(StrEq(RESOURCE_HOST)), + Eq(RESOURCE_TYPE), + Eq(OC_RSRVD_WELL_KNOWN_URI), + Matcher(Eq(CT_DEFAULT)))) + .WillOnce(Return(resource_stub)); + EXPECT_CALL(reportHandler, post(Eq(test_rep), Eq(test_params))).WillOnce(Return(OC_STACK_OK)); + + reportHandler.pass(test_rep, test_params); +} + +TEST(Test_ReportHandlerRes, create_without_iotivity) +{ + ReportHandlerResMock reportHandler(nullptr); + OC::OCRepresentation test_rep; + test_rep.setValue("key", std::string{"value"}); + OC::QueryParamsMap test_params{{"param", "value"}}; + + EXPECT_NO_THROW(reportHandler.pass(test_rep, test_params)); +} diff --git a/device_core/utest/test_sd-daemon-stub.cpp b/device_core/utest/test_sd-daemon-stub.cpp new file mode 100644 index 0000000..a867722 --- /dev/null +++ b/device_core/utest/test_sd-daemon-stub.cpp @@ -0,0 +1,7 @@ +#include +#include "mock/sd-daemon.h" + +TEST(Test_sd_notify, all) +{ + EXPECT_EQ(0, sd_notify(0, nullptr)); +} -- 2.7.4