From 014f4e74208a68f9edae11e0b3f58c1f1ac794e0 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Wed, 23 Jul 2014 16:18:43 +0200 Subject: [PATCH 01/16] Release version 0.1.1 Change-Id: I0fdb371060d86446141700c60958d165cbf44d88 --- packaging/security-containers.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index 7d7b0a1..f6a77e1 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -7,7 +7,7 @@ %define input_event_group video Name: security-containers -Version: 0.1.0 +Version: 0.1.1 Release: 0 Source0: %{name}-%{version}.tar.gz License: Apache-2.0 @@ -16,7 +16,7 @@ Summary: Daemon for managing containers BuildRequires: cmake BuildRequires: boost-devel BuildRequires: libvirt-devel -BuildRequires: libjson-devel +BuildRequires: libjson-devel >= 0.10.0 BuildRequires: libcap-ng-devel BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(libsystemd-journal) -- 2.7.4 From e785e1bbacccf70374ab14cda57b7059d07cdbff Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Thu, 24 Jul 2014 10:22:03 +0200 Subject: [PATCH 02/16] Fix dependency problem in spec [Bug/Feature] Build break [Cause] Dependency version not match [Solution] N/A [Verification] Build with gbs Change-Id: I0b1a93d293364edea18b15b58cb61fa998674960 --- packaging/security-containers.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index f6a77e1..e639a98 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -16,7 +16,7 @@ Summary: Daemon for managing containers BuildRequires: cmake BuildRequires: boost-devel BuildRequires: libvirt-devel -BuildRequires: libjson-devel >= 0.10.0 +BuildRequires: libjson-devel >= 0.10 BuildRequires: libcap-ng-devel BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(libsystemd-journal) -- 2.7.4 From e9617fa11ae5172e3b2cb9338fdcd23476a291be Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Wed, 23 Jul 2014 12:56:47 +0200 Subject: [PATCH 03/16] Dbus API for sharing containers DBuses [Bug/Feature] New method on host dbus interface for getting list of containers dbus addresses and new signals when containers dbus become available or unavailable. [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Ib37d47c8e2ffbdca58828c542d7b474e068ca138 --- server/container.cpp | 61 +++++++++--- server/container.hpp | 16 ++++ server/containers-manager.cpp | 25 +++++ server/containers-manager.hpp | 3 + server/host-connection.cpp | 23 +++++ server/host-connection.hpp | 17 +++- server/host-dbus-definitions.hpp | 10 ++ tests/unit_tests/server/ut-containers-manager.cpp | 108 +++++++++++++++++++++- 8 files changed, 246 insertions(+), 17 deletions(-) diff --git a/server/container.cpp b/server/container.cpp index 0b61d65..4284fec 100644 --- a/server/container.cpp +++ b/server/container.cpp @@ -82,7 +82,7 @@ Container::~Container() // condition on the mReconnectThread. { Lock lock(mReconnectMutex); - mConnection.reset(); + disconnect(); } if (mReconnectThread.joinable()) { @@ -117,7 +117,28 @@ void Container::start() mConnectionTransport.reset(new ContainerConnectionTransport(mRunMountPoint)); mNetworkAdmin->start(); mAdmin->start(); - mConnection.reset(new ContainerConnection(mConnectionTransport->acquireAddress(), + connect(); + + // Send to the background only after we're connected, + // otherwise it'd take ages. + LOGD(getId() << ": DBUS connected, sending to the background"); + goBackground(); +} + +void Container::stop() +{ + Lock lock(mReconnectMutex); + disconnect(); + mAdmin->stop(); + mNetworkAdmin->stop(); + mConnectionTransport.reset(); +} + +void Container::connect() +{ + // assume called under reconnect lock + mDbusAddress = mConnectionTransport->acquireAddress(); + mConnection.reset(new ContainerConnection(mDbusAddress, std::bind(&Container::onNameLostCallback, this))); if (mNotifyCallback) { mConnection->setNotifyActiveContainerCallback(mNotifyCallback); @@ -131,20 +152,28 @@ void Container::start() if (mProxyCallCallback) { mConnection->setProxyCallCallback(mProxyCallCallback); } + if (mDbusStateChangedCallback) { + mDbusStateChangedCallback(mDbusAddress); + } +} - // Send to the background only after we're connected, - // otherwise it'd take ages. - LOGD(getId() << ": DBUS connected, sending to the background"); - goBackground(); +void Container::disconnect() +{ + // assume called under reconnect lock + if (mConnection) { + mConnection.reset(); + mDbusAddress.clear(); + if (mDbusStateChangedCallback) { + // notify about invalid dbusAddress for this container + mDbusStateChangedCallback(std::string()); + } + } } -void Container::stop() +std::string Container::getDbusAddress() { Lock lock(mReconnectMutex); - mConnection.reset(); - mAdmin->stop(); - mNetworkAdmin->stop(); - mConnectionTransport.reset(); + return mDbusAddress; } void Container::goForeground() @@ -204,7 +233,7 @@ void Container::reconnectHandler() { { Lock lock(mReconnectMutex); - mConnection.reset(); + disconnect(); } for (int i = 0; i < RECONNECT_RETRIES; ++i) { @@ -219,8 +248,7 @@ void Container::reconnectHandler() try { LOGT(getId() << ": Reconnect try " << i + 1); - mConnection.reset(new ContainerConnection(mConnectionTransport->acquireAddress(), - std::bind(&Container::onNameLostCallback, this))); + connect(); LOGI(getId() << ": Reconnected"); return; } catch (SecurityContainersException&) { @@ -283,6 +311,11 @@ void Container::setProxyCallCallback(const ProxyCallCallback& callback) } } +void Container::setDbusStateChangedCallback(const DbusStateChangedCallback& callback) +{ + mDbusStateChangedCallback = callback; +} + void Container::proxyCallAsync(const std::string& busName, const std::string& objectPath, const std::string& interface, diff --git a/server/container.hpp b/server/container.hpp index dff5d23..c29b860 100644 --- a/server/container.hpp +++ b/server/container.hpp @@ -54,6 +54,8 @@ public: typedef ContainerConnection::FileMoveRequestCallback FileMoveRequestCallback; typedef ContainerConnection::ProxyCallCallback ProxyCallCallback; + typedef std::function DbusStateChangedCallback; + /** * Returns a vector of regexps defining files permitted to be * send to other containers using file move functionality @@ -166,6 +168,11 @@ public: void setFileMoveRequestCallback(const FileMoveRequestCallback& callback); /** + * Register dbus state changed callback + */ + void setDbusStateChangedCallback(const DbusStateChangedCallback& callback); + + /** * Make a proxy call */ void proxyCallAsync(const std::string& busName, @@ -175,6 +182,11 @@ public: GVariant* parameters, const dbus::DbusConnection::AsyncMethodCallCallback& callback); + /** + * Get a dbus address + */ + std::string getDbusAddress(); + private: ContainerConfig mConfig; std::vector mPermittedToSend; @@ -189,10 +201,14 @@ private: DisplayOffCallback mDisplayOffCallback; FileMoveRequestCallback mFileMoveCallback; ProxyCallCallback mProxyCallCallback; + DbusStateChangedCallback mDbusStateChangedCallback; + std::string mDbusAddress; std::string mRunMountPoint; void onNameLostCallback(); void reconnectHandler(); + void connect(); + void disconnect(); }; diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index 7bd22b3..dc6e637 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -75,6 +75,9 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet mHostConnection.setProxyCallCallback(bind(&ContainersManager::handleProxyCall, this, HOST_ID, _1, _2, _3, _4, _5, _6, _7)); + mHostConnection.setGetContainerDbusesCallback(bind( + &ContainersManager::handleGetContainerDbuses, this, _1)); + for (auto& containerConfig : mConfig.containerConfigs) { std::string containerConfigPath; @@ -105,6 +108,9 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet c->setProxyCallCallback(bind(&ContainersManager::handleProxyCall, this, id, _1, _2, _3, _4, _5, _6, _7)); + c->setDbusStateChangedCallback(bind(&ContainersManager::handleDbusStateChanged, + this, id, _1)); + mContainers.insert(ContainerMap::value_type(id, std::move(c))); } @@ -391,5 +397,24 @@ void ContainersManager::handleProxyCall(const std::string& caller, asyncResultCallback); } +void ContainersManager::handleGetContainerDbuses(dbus::MethodResultBuilder::Pointer result) +{ + std::vector entries; + for (auto& container : mContainers) { + GVariant* containerId = g_variant_new_string(container.first.c_str()); + GVariant* dbusAddress = g_variant_new_string(container.second->getDbusAddress().c_str()); + GVariant* entry = g_variant_new_dict_entry(containerId, dbusAddress); + entries.push_back(entry); + } + GVariant* dict = g_variant_new_array(G_VARIANT_TYPE("{ss}"), entries.data(), entries.size()); + result->set(g_variant_new("(*)", dict)); +} + +void ContainersManager::handleDbusStateChanged(const std::string& containerId, + const std::string& dbusAddress) +{ + mHostConnection.signalContainerDbusState(containerId, dbusAddress); +} + } // namespace security_containers diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp index 4354fdd..8a5c823 100644 --- a/server/containers-manager.hpp +++ b/server/containers-manager.hpp @@ -103,6 +103,9 @@ private: GVariant* parameters, dbus::MethodResultBuilder::Pointer result); + void handleGetContainerDbuses(dbus::MethodResultBuilder::Pointer result); + void handleDbusStateChanged(const std::string& containerId, const std::string& dbusAddress); + }; diff --git a/server/host-connection.cpp b/server/host-connection.cpp index 2821202..88ce5a4 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -115,6 +115,11 @@ void HostConnection::setProxyCallCallback(const ProxyCallCallback& callback) mProxyCallCallback = callback; } +void HostConnection::setGetContainerDbusesCallback(const GetContainerDbusesCallback& callback) +{ + mGetContainerDbusesCallback = callback; +} + void HostConnection::onMessageCall(const std::string& objectPath, const std::string& interface, const std::string& methodName, @@ -125,6 +130,13 @@ void HostConnection::onMessageCall(const std::string& objectPath, return; } + if (methodName == hostapi::METHOD_GET_CONTAINER_DBUSES) { + if (mGetContainerDbusesCallback) { + mGetContainerDbusesCallback(result); + } + return; + } + if (methodName == hostapi::METHOD_PROXY_CALL) { const gchar* target = NULL; const gchar* targetBusName = NULL; @@ -151,6 +163,7 @@ void HostConnection::onMessageCall(const std::string& objectPath, args.get(), result); } + return; } } @@ -170,5 +183,15 @@ void HostConnection::proxyCallAsync(const std::string& busName, callback); } +void HostConnection::signalContainerDbusState(const std::string& containerId, + const std::string& dbusAddress) +{ + GVariant* parameters = g_variant_new("(ss)", containerId.c_str(), dbusAddress.c_str()); + mDbusConnection->emitSignal(hostapi::OBJECT_PATH, + hostapi::INTERFACE, + hostapi::SIGNAL_CONTAINER_DBUS_STATE, + parameters); +} + } // namespace security_containers diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 88cb480..3d9c493 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -49,7 +49,11 @@ public: const std::string& targetInterface, const std::string& targetMethod, GVariant* parameters, - dbus::MethodResultBuilder::Pointer result)> ProxyCallCallback; + dbus::MethodResultBuilder::Pointer result + )> ProxyCallCallback; + + typedef std::function GetContainerDbusesCallback; /** * Register proxy call callback @@ -57,6 +61,16 @@ public: void setProxyCallCallback(const ProxyCallCallback& callback); /** + * Register get container dbuses callback + */ + void setGetContainerDbusesCallback(const GetContainerDbusesCallback& callback); + + /** + * Send signal describing dbus address state change + */ + void signalContainerDbusState(const std::string& containerId, const std::string& dbusAddress); + + /** * Make a proxy call */ void proxyCallAsync(const std::string& busName, @@ -73,6 +87,7 @@ private: bool mNameAcquired; bool mNameLost; ProxyCallCallback mProxyCallCallback; + GetContainerDbusesCallback mGetContainerDbusesCallback; void onNameAcquired(); void onNameLost(); diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index f41da38..4594433 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -37,6 +37,9 @@ const std::string OBJECT_PATH = "/org/tizen/containers/hos const std::string INTERFACE = "org.tizen.containers.host.manager"; const std::string METHOD_PROXY_CALL = "ProxyCall"; +const std::string METHOD_GET_CONTAINER_DBUSES = "GetContainerDbuses"; + +const std::string SIGNAL_CONTAINER_DBUS_STATE = "ContainerDbusState"; const std::string DEFINITION = "" @@ -50,6 +53,13 @@ const std::string DEFINITION = " " " " " " + " " + " " + " " + " " + " " + " " + " " " " ""; diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index 64659ef..43bc15a 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -75,10 +75,14 @@ const std::string FILE_CONTENT = "File content\n" class DbusAccessory { public: + static const int HOST_ID = 0; + typedef std::function TestApiMethodCallback; + typedef std::map Dbuses; + DbusAccessory(int id) : mId(id), mClient(DbusConnection::create(acquireAddress())), @@ -122,7 +126,7 @@ public: void signalSubscribe(const DbusConnection::SignalCallback& callback) { - mClient->signalSubscribe(callback, api::BUS_NAME); + mClient->signalSubscribe(callback, isHost() ? hostapi::BUS_NAME : api::BUS_NAME); } void emitSignal(const std::string& objectPath, @@ -218,6 +222,28 @@ public: g_variant_get(result.get(), "(v)", &unpackedResult); return GVariantPtr(unpackedResult, g_variant_unref); } + + Dbuses callMethodGetContainerDbuses() { + assert(isHost()); + Dbuses dbuses; + GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME, + hostapi::OBJECT_PATH, + hostapi::INTERFACE, + hostapi::METHOD_GET_CONTAINER_DBUSES, + NULL, + "(a{ss})"); + GVariant* array = NULL; + g_variant_get(result.get(), "(*)", &array); + dbus::GVariantPtr autounref(array, g_variant_unref); + size_t count = g_variant_n_children(array); + for (size_t n = 0; n < count; ++n) { + const char* containerId = NULL; + const char* dbusAddress = NULL; + g_variant_get_child(array, n, "{&s&s}", &containerId, &dbusAddress); + dbuses.insert(Dbuses::value_type(containerId, dbusAddress)); + } + return dbuses; + } private: const int mId; DbusConnection::Pointer mClient; @@ -227,7 +253,7 @@ private: std::condition_variable mNameCondition; bool isHost() const { - return mId == 0; + return mId == HOST_ID; } std::string acquireAddress() const @@ -644,5 +670,83 @@ BOOST_AUTO_TEST_CASE(ProxyCallTest) expectedMessage("Proxy call forbidden")); } +namespace { + const DbusAccessory::Dbuses EXPECTED_DBUSES_STOPPED = { + {"ut-containers-manager-console1-dbus", ""}, + {"ut-containers-manager-console2-dbus", ""}, + {"ut-containers-manager-console3-dbus", ""}}; + + const DbusAccessory::Dbuses EXPECTED_DBUSES_STARTED = { + {"ut-containers-manager-console1-dbus", + "unix:path=/tmp/ut-containers-manager/console1-dbus/dbus/system_bus_socket"}, + {"ut-containers-manager-console2-dbus", + "unix:path=/tmp/ut-containers-manager/console2-dbus/dbus/system_bus_socket"}, + {"ut-containers-manager-console3-dbus", + "unix:path=/tmp/ut-containers-manager/console3-dbus/dbus/system_bus_socket"}}; +} // namespace + +BOOST_AUTO_TEST_CASE(GetContainerDbusesTest) +{ + DbusAccessory host(DbusAccessory::HOST_ID); + + ContainersManager cm(TEST_DBUS_CONFIG_PATH); + + BOOST_CHECK(EXPECTED_DBUSES_STOPPED == host.callMethodGetContainerDbuses()); + + cm.startAll(); + + BOOST_CHECK(EXPECTED_DBUSES_STARTED == host.callMethodGetContainerDbuses()); + + cm.stopAll(); + + BOOST_CHECK(EXPECTED_DBUSES_STOPPED == host.callMethodGetContainerDbuses()); +} + +BOOST_AUTO_TEST_CASE(ContainerDbusesSignalsTest) +{ + DbusAccessory host(DbusAccessory::HOST_ID); + + Latch signalLatch; + DbusAccessory::Dbuses collectedDbuses; + + auto onSignal = [&] (const std::string& /*senderBusName*/, + const std::string& objectPath, + const std::string& interface, + const std::string& signalName, + GVariant* parameters) { + if (objectPath == hostapi::OBJECT_PATH && + interface == hostapi::INTERFACE && + signalName == hostapi::SIGNAL_CONTAINER_DBUS_STATE) { + + const gchar* containerId = NULL; + const gchar* dbusAddress = NULL; + g_variant_get(parameters, "(&s&s)", &containerId, &dbusAddress); + + collectedDbuses.insert(DbusAccessory::Dbuses::value_type(containerId, dbusAddress)); + signalLatch.set(); + } + }; + + host.signalSubscribe(onSignal); + + { + ContainersManager cm(TEST_DBUS_CONFIG_PATH); + + BOOST_CHECK(signalLatch.empty()); + BOOST_CHECK(collectedDbuses.empty()); + + cm.startAll(); + + BOOST_CHECK(signalLatch.waitForN(TEST_DBUS_CONNECTION_CONTAINERS_COUNT, EVENT_TIMEOUT)); + BOOST_CHECK(signalLatch.empty()); + BOOST_CHECK(EXPECTED_DBUSES_STARTED == collectedDbuses); + collectedDbuses.clear(); + } + + BOOST_CHECK(signalLatch.waitForN(TEST_DBUS_CONNECTION_CONTAINERS_COUNT, EVENT_TIMEOUT)); + BOOST_CHECK(signalLatch.empty()); + BOOST_CHECK(EXPECTED_DBUSES_STOPPED == collectedDbuses); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From a5c612deb7685dae1fd5aececd81db28d159dd4e Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Tue, 22 Jul 2014 17:25:20 +0200 Subject: [PATCH 04/16] API for obtaining container's IDs [Bug/Feature] D-Bus API for getting the ID of the active container D-Bus API for getting the IDs of all containers [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I03081e3dc5e275f9c0d5c6b5a6cacfef38c5adff --- server/containers-manager.cpp | 28 ++++++++ server/containers-manager.hpp | 2 + server/host-connection.cpp | 31 +++++++-- server/host-connection.hpp | 16 +++++ server/host-dbus-definitions.hpp | 8 +++ tests/unit_tests/server/ut-containers-manager.cpp | 80 ++++++++++++++++++++++- 6 files changed, 158 insertions(+), 7 deletions(-) diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index dc6e637..b2c4222 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -78,6 +78,12 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet mHostConnection.setGetContainerDbusesCallback(bind( &ContainersManager::handleGetContainerDbuses, this, _1)); + mHostConnection.setGetContainerIdsCallback(bind(&ContainersManager::handleGetContainerIdsCall, + this, _1)); + + mHostConnection.setGetActiveContainerIdCallback(bind(&ContainersManager::handleGetActiveContainerIdCall, + this, _1)); + for (auto& containerConfig : mConfig.containerConfigs) { std::string containerConfigPath; @@ -416,5 +422,27 @@ void ContainersManager::handleDbusStateChanged(const std::string& containerId, mHostConnection.signalContainerDbusState(containerId, dbusAddress); } +void ContainersManager::handleGetContainerIdsCall(dbus::MethodResultBuilder::Pointer result) +{ + std::vector containerIds; + for(auto& container: mContainers){ + containerIds.push_back(g_variant_new_string(container.first.c_str())); + } + + GVariant* array = g_variant_new_array(G_VARIANT_TYPE("s"), + containerIds.data(), + containerIds.size()); + result->set(g_variant_new("(*)", array)); +} + +void ContainersManager::handleGetActiveContainerIdCall(dbus::MethodResultBuilder::Pointer result) +{ + LOGI("GetActiveContainerId call"); + if (mContainers[mConfig.foregroundId]->isRunning()){ + result->set(g_variant_new("(s)", mConfig.foregroundId.c_str())); + } else { + result->set(g_variant_new("(s)", "")); + } +} } // namespace security_containers diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp index 8a5c823..b685028 100644 --- a/server/containers-manager.hpp +++ b/server/containers-manager.hpp @@ -105,6 +105,8 @@ private: void handleGetContainerDbuses(dbus::MethodResultBuilder::Pointer result); void handleDbusStateChanged(const std::string& containerId, const std::string& dbusAddress); + void handleGetContainerIdsCall(dbus::MethodResultBuilder::Pointer result); + void handleGetActiveContainerIdCall(dbus::MethodResultBuilder::Pointer result); }; diff --git a/server/host-connection.cpp b/server/host-connection.cpp index 88ce5a4..0d96039 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -65,12 +65,7 @@ HostConnection::HostConnection() mDbusConnection->registerObject(hostapi::OBJECT_PATH, hostapi::DEFINITION, std::bind(&HostConnection::onMessageCall, - this, - _1, - _2, - _3, - _4, - _5)); + this, _1, _2, _3, _4, _5)); LOGD("Connected"); } @@ -120,6 +115,16 @@ void HostConnection::setGetContainerDbusesCallback(const GetContainerDbusesCallb mGetContainerDbusesCallback = callback; } +void HostConnection::setGetContainerIdsCallback(const GetContainerIdsCallback& callback) +{ + mGetContainerIdsCallback = callback; +} + +void HostConnection::setGetActiveContainerIdCallback(const GetActiveContainerIdCallback& callback) +{ + mGetActiveContainerIdCallback = callback; +} + void HostConnection::onMessageCall(const std::string& objectPath, const std::string& interface, const std::string& methodName, @@ -165,6 +170,20 @@ void HostConnection::onMessageCall(const std::string& objectPath, } return; } + + if (methodName == hostapi::METHOD_GET_CONTAINER_ID_LIST){ + if (mGetContainerIdsCallback){ + mGetContainerIdsCallback(result); + } + return; + } + + if (methodName == hostapi::METHOD_GET_ACTIVE_CONTAINER_ID){ + if (mGetActiveContainerIdCallback){ + mGetActiveContainerIdCallback(result); + } + return; + } } void HostConnection::proxyCallAsync(const std::string& busName, diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 3d9c493..962fbb9 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -54,6 +54,10 @@ public: typedef std::function GetContainerDbusesCallback; + typedef std::function GetContainerIdsCallback; + typedef std::function GetActiveContainerIdCallback; + /** * Register proxy call callback @@ -71,6 +75,16 @@ public: void signalContainerDbusState(const std::string& containerId, const std::string& dbusAddress); /** + * Register a callback called to get a list of domain ids + */ + void setGetContainerIdsCallback(const GetContainerIdsCallback& callback); + + /** + * Register a callback called to get the active container id + */ + void setGetActiveContainerIdCallback(const GetContainerIdsCallback& callback); + + /** * Make a proxy call */ void proxyCallAsync(const std::string& busName, @@ -88,6 +102,8 @@ private: bool mNameLost; ProxyCallCallback mProxyCallCallback; GetContainerDbusesCallback mGetContainerDbusesCallback; + GetContainerIdsCallback mGetContainerIdsCallback; + GetActiveContainerIdCallback mGetActiveContainerIdCallback; void onNameAcquired(); void onNameLost(); diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index 4594433..ef30e1a 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -38,6 +38,8 @@ const std::string INTERFACE = "org.tizen.containers.host const std::string METHOD_PROXY_CALL = "ProxyCall"; const std::string METHOD_GET_CONTAINER_DBUSES = "GetContainerDbuses"; +const std::string METHOD_GET_CONTAINER_ID_LIST = "GetContainerIds"; +const std::string METHOD_GET_ACTIVE_CONTAINER_ID = "GetActiveContainerId"; const std::string SIGNAL_CONTAINER_DBUS_STATE = "ContainerDbusState"; @@ -56,6 +58,12 @@ const std::string DEFINITION = " " " " " " + " " + " " + " " + " " + " " + " " " " " " " " diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index 43bc15a..d4708e3 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -223,7 +223,8 @@ public: return GVariantPtr(unpackedResult, g_variant_unref); } - Dbuses callMethodGetContainerDbuses() { + Dbuses callMethodGetContainerDbuses() + { assert(isHost()); Dbuses dbuses; GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME, @@ -244,6 +245,47 @@ public: } return dbuses; } + + std::vector callMethodGetContainerIds() + { + assert(isHost()); + GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME, + hostapi::OBJECT_PATH, + hostapi::INTERFACE, + hostapi::METHOD_GET_CONTAINER_ID_LIST, + NULL, + "(as)"); + + GVariant* array = NULL; + g_variant_get(result.get(), "(*)", &array); + + size_t arraySize = g_variant_n_children(array); + std::vector containerIds; + for (size_t i = 0; i < arraySize; ++i) { + const char* id = NULL; + g_variant_get_child(array, i, "&s", &id); + containerIds.push_back(id); + } + + g_variant_unref(array); + return containerIds; + } + + std::string callMethodGetActiveContainerId() + { + assert(isHost()); + GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME, + hostapi::OBJECT_PATH, + hostapi::INTERFACE, + hostapi::METHOD_GET_ACTIVE_CONTAINER_ID, + NULL, + "(s)"); + + const char* containerId = NULL; + g_variant_get(result.get(), "(&s)", &containerId); + return containerId; + } + private: const int mId; DbusConnection::Pointer mClient; @@ -749,4 +791,40 @@ BOOST_AUTO_TEST_CASE(ContainerDbusesSignalsTest) } +BOOST_AUTO_TEST_CASE(GetContainerIdsTest) +{ + ContainersManager cm(TEST_DBUS_CONFIG_PATH); + + DbusAccessory dbus(DbusAccessory::HOST_ID); + + std::vector containerIds = {"ut-containers-manager-console1-dbus", + "ut-containers-manager-console2-dbus", + "ut-containers-manager-console3-dbus"}; + std::vector returnedIds = dbus.callMethodGetContainerIds(); + + BOOST_CHECK(std::is_permutation(returnedIds.begin(), + returnedIds.end(), + containerIds.begin())); +} + +BOOST_AUTO_TEST_CASE(GetActiveContainerIdTest) +{ + ContainersManager cm(TEST_DBUS_CONFIG_PATH); + cm.startAll(); + + DbusAccessory dbus(DbusAccessory::HOST_ID); + + std::vector containerIds = {"ut-containers-manager-console1-dbus", + "ut-containers-manager-console2-dbus", + "ut-containers-manager-console3-dbus"}; + + for (std::string& containerId: containerIds){ + cm.focus(containerId); + BOOST_CHECK(dbus.callMethodGetActiveContainerId() == containerId); + } + + cm.stopAll(); + BOOST_CHECK(dbus.callMethodGetActiveContainerId() == ""); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From d880b2a8fda680e6970d2916f06c19b19ac1fed4 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Mon, 28 Jul 2014 11:06:13 +0200 Subject: [PATCH 05/16] Fix invalid use of glib loop in unit tests [Bug/Feature] Memleak in unit tests [Cause] Glib loop was started twice [Solution] N/A [Verification] Build, install, run tests under valgrind Change-Id: I7407a0211e141143b3828cf1784f3a2a5ac3f5b3 --- server/container-admin.hpp | 1 - tests/unit_tests/server/ut-input-monitor.cpp | 15 ++++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/server/container-admin.hpp b/server/container-admin.hpp index a1e0baf..3831a3a 100644 --- a/server/container-admin.hpp +++ b/server/container-admin.hpp @@ -35,7 +35,6 @@ #include #include -#include #include #include #include diff --git a/tests/unit_tests/server/ut-input-monitor.cpp b/tests/unit_tests/server/ut-input-monitor.cpp index a0bd9dd..13f1d51 100644 --- a/tests/unit_tests/server/ut-input-monitor.cpp +++ b/tests/unit_tests/server/ut-input-monitor.cpp @@ -40,7 +40,6 @@ #include #include -#include #include #include #include @@ -114,9 +113,8 @@ BOOST_AUTO_TEST_CASE(Config_deviceFilePathNotExisting) InputMonitorException); } -void sendNEvents(unsigned int noOfEventsToSend) +void sendNEvents(Fixture& f, unsigned int noOfEventsToSend) { - Fixture f; Latch eventLatch; std::unique_ptr inputMonitor; @@ -150,17 +148,16 @@ void sendNEvents(unsigned int noOfEventsToSend) BOOST_AUTO_TEST_CASE(Event_oneAtATime) { - sendNEvents(1); + sendNEvents(*this, 1); } BOOST_AUTO_TEST_CASE(Event_tenAtATime) { - sendNEvents(10); + sendNEvents(*this, 10); } -void sendNEventsWithPauses(unsigned int noOfEventsToSend) +void sendNEventsWithPauses(Fixture& f, unsigned int noOfEventsToSend) { - Fixture f; Latch eventLatch; std::unique_ptr inputMonitor; @@ -199,12 +196,12 @@ void sendNEventsWithPauses(unsigned int noOfEventsToSend) BOOST_AUTO_TEST_CASE(Event_oneAtATimeWithPauses) { - sendNEventsWithPauses(1); + sendNEventsWithPauses(*this, 1); } BOOST_AUTO_TEST_CASE(Event_tenAtATimeWithPauses) { - sendNEventsWithPauses(10); + sendNEventsWithPauses(*this, 10); } -- 2.7.4 From 35339dc228673f4454360b9107718078aa8d0c10 Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Fri, 25 Jul 2014 10:42:26 +0200 Subject: [PATCH 06/16] Setting the active container through D-Bus [Bug/Feature] D-Bus API for setting the active container [Cause] N/A [Solution] Added the new API Added a common part of dbus definitions [Verification] Build, install, run tests Change-Id: I4be877c17751b6334e8d424ff64de8d884699ede --- server/common-dbus-definitions.hpp | 43 +++++++ server/container-connection.cpp | 22 ++-- server/container-dbus-definitions.hpp | 7 +- server/containers-manager.cpp | 55 ++++++--- server/containers-manager.hpp | 3 +- server/host-connection.cpp | 41 ++++--- server/host-connection.hpp | 14 ++- server/host-dbus-definitions.hpp | 30 +++-- .../unit_tests/server/ut-container-connection.cpp | 17 +-- tests/unit_tests/server/ut-containers-manager.cpp | 123 ++++++++++++++------- 10 files changed, 244 insertions(+), 111 deletions(-) create mode 100644 server/common-dbus-definitions.hpp diff --git a/server/common-dbus-definitions.hpp b/server/common-dbus-definitions.hpp new file mode 100644 index 0000000..8821b34 --- /dev/null +++ b/server/common-dbus-definitions.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak + * + * 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 + */ + +/** + * @file + * @author Jan Olszak (j.olszak@samsung.com) + * @brief Common dbus api definitions + */ + +#ifndef SERVER_COMMON_DBUS_DEFINITIONS_HPP +#define SERVER_COMMON_DBUS_DEFINITIONS_HPP + +#include + + +namespace security_containers { +namespace api { +const std::string ERROR_FORBIDDEN = "org.tizen.containers.Error.Forbidden"; +const std::string ERROR_FORWARDED = "org.tizen.containers.Error.Forwarded"; +const std::string ERROR_UNKNOWN_ID = "org.tizen.containers.Error.UnknownId"; + +const std::string METHOD_PROXY_CALL = "ProxyCall"; + +} // namespace api +} // namespace security_containers + + +#endif // SERVER_COMMON_DBUS_DEFINITIONS_HPP diff --git a/server/container-connection.cpp b/server/container-connection.cpp index f71a5a6..0e96bb2 100644 --- a/server/container-connection.cpp +++ b/server/container-connection.cpp @@ -59,19 +59,19 @@ ContainerConnection::ContainerConnection(const std::string& address, const OnNam mDbusConnection = dbus::DbusConnection::create(address); LOGT("Setting DBUS name"); - mDbusConnection->setName(api::BUS_NAME, + mDbusConnection->setName(api::container::BUS_NAME, std::bind(&ContainerConnection::onNameAcquired, this), std::bind(&ContainerConnection::onNameLost, this)); if (!waitForNameAndSetCallback(NAME_ACQUIRED_TIMEOUT, callback)) { - LOGE("Could not acquire dbus name: " << api::BUS_NAME); - throw ContainerConnectionException("Could not acquire dbus name: " + api::BUS_NAME); + LOGE("Could not acquire dbus name: " << api::container::BUS_NAME); + throw ContainerConnectionException("Could not acquire dbus name: " + api::container::BUS_NAME); } LOGT("Registering DBUS interface"); using namespace std::placeholders; - mDbusConnection->registerObject(api::OBJECT_PATH, - api::DEFINITION, + mDbusConnection->registerObject(api::container::OBJECT_PATH, + api::container::DEFINITION, std::bind(&ContainerConnection::onMessageCall, this, _1, @@ -157,11 +157,11 @@ void ContainerConnection::onMessageCall(const std::string& objectPath, GVariant* parameters, dbus::MethodResultBuilder::Pointer result) { - if (objectPath != api::OBJECT_PATH || interface != api::INTERFACE) { + if (objectPath != api::container::OBJECT_PATH || interface != api::container::INTERFACE) { return; } - if (methodName == api::METHOD_NOTIFY_ACTIVE_CONTAINER) { + if (methodName == api::container::METHOD_NOTIFY_ACTIVE_CONTAINER) { const gchar* application = NULL; const gchar* message = NULL; g_variant_get(parameters, "(&s&s)", &application, &message); @@ -171,7 +171,7 @@ void ContainerConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::METHOD_FILE_MOVE_REQUEST) { + if (methodName == api::container::METHOD_FILE_MOVE_REQUEST) { const gchar* destination = NULL; const gchar* path = NULL; g_variant_get(parameters, "(&s&s)", &destination, &path); @@ -234,9 +234,9 @@ void ContainerConnection::sendNotification(const std::string& container, container.c_str(), application.c_str(), message.c_str()); - mDbusConnection->emitSignal(api::OBJECT_PATH, - api::INTERFACE, - api::SIGNAL_NOTIFICATION, + mDbusConnection->emitSignal(api::container::OBJECT_PATH, + api::container::INTERFACE, + api::container::SIGNAL_NOTIFICATION, parameters); } diff --git a/server/container-dbus-definitions.hpp b/server/container-dbus-definitions.hpp index fe72e4d..0e280d4 100644 --- a/server/container-dbus-definitions.hpp +++ b/server/container-dbus-definitions.hpp @@ -25,12 +25,12 @@ #ifndef SERVER_CONTAINER_DBUS_DEFINITIONS_HPP #define SERVER_CONTAINER_DBUS_DEFINITIONS_HPP -#include +#include "common-dbus-definitions.hpp" namespace security_containers { namespace api { - +namespace container { const std::string BUS_NAME = "org.tizen.containers.domain"; const std::string OBJECT_PATH = "/org/tizen/containers/domain"; @@ -38,7 +38,6 @@ const std::string INTERFACE = "org.tizen.containers.doma const std::string METHOD_NOTIFY_ACTIVE_CONTAINER = "NotifyActiveContainer"; const std::string METHOD_FILE_MOVE_REQUEST = "FileMoveRequest"; -const std::string METHOD_PROXY_CALL = "ProxyCall"; const std::string SIGNAL_NOTIFICATION = "Notification"; const std::string FILE_MOVE_DESTINATION_NOT_FOUND = "FILE_MOVE_DESTINATION_NOT_FOUND"; @@ -78,7 +77,7 @@ const std::string DEFINITION = " " ""; - +} // namespace container } // namespace api } // namespace security_containers diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index b2c4222..012a8f7 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -24,6 +24,8 @@ #include "config.hpp" +#include "host-dbus-definitions.hpp" +#include "common-dbus-definitions.hpp" #include "container-dbus-definitions.hpp" #include "containers-manager.hpp" #include "container-admin.hpp" @@ -58,9 +60,6 @@ bool regexMatchVector(const std::string& str, const std::vector& v } const std::string HOST_ID = "host"; -const std::string DBUS_ERROR_NAME_FORBIDDEN = "org.tizen.containers.Error.Forbidden"; -const std::string DBUS_ERROR_NAME_FORWARDED = "org.tizen.containers.Error.Forwarded"; -const std::string DBUS_ERROR_NAME_UNKNOWN_TARGET = "org.tizen.containers.Error.UnknownTarget"; } // namespace @@ -84,6 +83,9 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet mHostConnection.setGetActiveContainerIdCallback(bind(&ContainersManager::handleGetActiveContainerIdCall, this, _1)); + mHostConnection.setSetActiveContainerCallback(bind(&ContainersManager::handleSetActiveContainerCall, + this, _1, _2)); + for (auto& containerConfig : mConfig.containerConfigs) { std::string containerConfigPath; @@ -138,7 +140,6 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet } } - ContainersManager::~ContainersManager() { LOGD("Destroying ContainersManager object..."); @@ -154,7 +155,6 @@ ContainersManager::~ContainersManager() LOGD("ContainersManager object destroyed"); } - void ContainersManager::focus(const std::string& containerId) { /* try to access the object first to throw immediately if it doesn't exist */ @@ -169,7 +169,6 @@ void ContainersManager::focus(const std::string& containerId) foregroundContainer->goForeground(); } - void ContainersManager::startAll() { LOGI("Starting all containers"); @@ -198,7 +197,6 @@ void ContainersManager::startAll() } } - void ContainersManager::stopAll() { LOGI("Stopping all containers"); @@ -208,7 +206,6 @@ void ContainersManager::stopAll() } } - std::string ContainersManager::getRunningForegroundContainerId() { for (auto& container : mContainers) { @@ -304,26 +301,26 @@ void ContainersManager::handleContainerMoveFileRequest(const std::string& srcCon ContainerMap::const_iterator dstIter = mContainers.find(dstContainerId); if (dstIter == mContainers.end()) { LOGE("Destination container '" << dstContainerId << "' not found"); - result->set(g_variant_new("(s)", api::FILE_MOVE_DESTINATION_NOT_FOUND.c_str())); + result->set(g_variant_new("(s)", api::container::FILE_MOVE_DESTINATION_NOT_FOUND.c_str())); return; } Container& dstContanier = *dstIter->second; if (srcContainerId == dstContainerId) { LOGE("Cannot send a file to yourself"); - result->set(g_variant_new("(s)", api::FILE_MOVE_WRONG_DESTINATION.c_str())); + result->set(g_variant_new("(s)", api::container::FILE_MOVE_WRONG_DESTINATION.c_str())); return; } if (!regexMatchVector(path, srcContainer.getPermittedToSend())) { LOGE("Source container has no permissions to send the file: " << path); - result->set(g_variant_new("(s)", api::FILE_MOVE_NO_PERMISSIONS_SEND.c_str())); + result->set(g_variant_new("(s)", api::container::FILE_MOVE_NO_PERMISSIONS_SEND.c_str())); return; } if (!regexMatchVector(path, dstContanier.getPermittedToRecv())) { LOGE("Destination container has no permissions to receive the file: " << path); - result->set(g_variant_new("(s)", api::FILE_MOVE_NO_PERMISSIONS_RECEIVE.c_str())); + result->set(g_variant_new("(s)", api::container::FILE_MOVE_NO_PERMISSIONS_RECEIVE.c_str())); return; } @@ -333,11 +330,11 @@ void ContainersManager::handleContainerMoveFileRequest(const std::string& srcCon if (!utils::moveFile(srcPath, dstPath)) { LOGE("Failed to move the file: " << path); - result->set(g_variant_new("(s)", api::FILE_MOVE_FAILED.c_str())); + result->set(g_variant_new("(s)", api::container::FILE_MOVE_FAILED.c_str())); } else { - result->set(g_variant_new("(s)", api::FILE_MOVE_SUCCEEDED.c_str())); + result->set(g_variant_new("(s)", api::container::FILE_MOVE_SUCCEEDED.c_str())); try { - dstContanier.sendNotification(srcContainerId, path, api::FILE_MOVE_SUCCEEDED); + dstContanier.sendNotification(srcContainerId, path, api::container::FILE_MOVE_SUCCEEDED); } catch (ServerException&) { LOGE("Notification to '" << dstContainerId << "' has not been sent"); } @@ -361,7 +358,7 @@ void ContainersManager::handleProxyCall(const std::string& caller, targetMethod)) { LOGW("Forbidden proxy call; " << caller << " -> " << target << "; " << targetBusName << "; " << targetObjectPath << "; " << targetInterface << "; " << targetMethod); - result->setError(DBUS_ERROR_NAME_FORBIDDEN, "Proxy call forbidden"); + result->setError(api::ERROR_FORBIDDEN, "Proxy call forbidden"); return; } @@ -373,7 +370,7 @@ void ContainersManager::handleProxyCall(const std::string& caller, GVariant* targetResult = asyncMethodCallResult.get(); result->set(g_variant_new("(v)", targetResult)); } catch (dbus::DbusException& e) { - result->setError(DBUS_ERROR_NAME_FORWARDED, e.what()); + result->setError(api::ERROR_FORWARDED, e.what()); } }; @@ -390,7 +387,7 @@ void ContainersManager::handleProxyCall(const std::string& caller, ContainerMap::const_iterator targetIter = mContainers.find(target); if (targetIter == mContainers.end()) { LOGE("Target container '" << target << "' not found"); - result->setError(DBUS_ERROR_NAME_UNKNOWN_TARGET, "Unknown proxy call target"); + result->setError(api::ERROR_UNKNOWN_ID, "Unknown proxy call target"); return; } @@ -445,4 +442,26 @@ void ContainersManager::handleGetActiveContainerIdCall(dbus::MethodResultBuilder } } +void ContainersManager::handleSetActiveContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result) +{ + LOGI("SetActiveContainer call; Id=" << id ); + auto container = mContainers.find(id); + if (container == mContainers.end()){ + LOGE("No container with id=" << id ); + result->setError(api::ERROR_UNKNOWN_ID, "No such container id"); + return; + } + + if (container->second->isStopped()){ + LOGE("Could not activate a stopped container"); + result->setError(api::host::ERROR_CONTAINER_STOPPED, + "Could not activate a stopped container"); + return; + } + + focus(id); + result->setVoid(); +} + } // namespace security_containers diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp index b685028..33767a9 100644 --- a/server/containers-manager.hpp +++ b/server/containers-manager.hpp @@ -102,11 +102,12 @@ private: const std::string& targetMethod, GVariant* parameters, dbus::MethodResultBuilder::Pointer result); - void handleGetContainerDbuses(dbus::MethodResultBuilder::Pointer result); void handleDbusStateChanged(const std::string& containerId, const std::string& dbusAddress); void handleGetContainerIdsCall(dbus::MethodResultBuilder::Pointer result); void handleGetActiveContainerIdCall(dbus::MethodResultBuilder::Pointer result); + void handleSetActiveContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result); }; diff --git a/server/host-connection.cpp b/server/host-connection.cpp index 0d96039..83ba8f8 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -51,19 +51,19 @@ HostConnection::HostConnection() mDbusConnection = dbus::DbusConnection::createSystem(); LOGT("Setting DBUS name"); - mDbusConnection->setName(hostapi::BUS_NAME, + mDbusConnection->setName(api::host::BUS_NAME, std::bind(&HostConnection::onNameAcquired, this), std::bind(&HostConnection::onNameLost, this)); if (!waitForName(NAME_ACQUIRED_TIMEOUT)) { - LOGE("Could not acquire dbus name: " << hostapi::BUS_NAME); - throw HostConnectionException("Could not acquire dbus name: " + hostapi::BUS_NAME); + LOGE("Could not acquire dbus name: " << api::host::BUS_NAME); + throw HostConnectionException("Could not acquire dbus name: " + api::host::BUS_NAME); } LOGT("Registering DBUS interface"); using namespace std::placeholders; - mDbusConnection->registerObject(hostapi::OBJECT_PATH, - hostapi::DEFINITION, + mDbusConnection->registerObject(api::host::OBJECT_PATH, + api::host::DEFINITION, std::bind(&HostConnection::onMessageCall, this, _1, _2, _3, _4, _5)); @@ -125,24 +125,39 @@ void HostConnection::setGetActiveContainerIdCallback(const GetActiveContainerIdC mGetActiveContainerIdCallback = callback; } +void HostConnection::setSetActiveContainerCallback(const SetActiveContainerCallback& callback) +{ + mSetActiveContainerCallback = callback; +} + void HostConnection::onMessageCall(const std::string& objectPath, const std::string& interface, const std::string& methodName, GVariant* parameters, dbus::MethodResultBuilder::Pointer result) { - if (objectPath != hostapi::OBJECT_PATH || interface != hostapi::INTERFACE) { + if (objectPath != api::host::OBJECT_PATH || interface != api::host::INTERFACE) { + return; + } + + if (methodName == api::host::METHOD_SET_ACTIVE_CONTAINER) { + const gchar* id = NULL; + g_variant_get(parameters, "(&s)", &id); + + if (mSetActiveContainerCallback) { + mSetActiveContainerCallback(id, result); + } return; } - if (methodName == hostapi::METHOD_GET_CONTAINER_DBUSES) { + if (methodName == api::host::METHOD_GET_CONTAINER_DBUSES) { if (mGetContainerDbusesCallback) { mGetContainerDbusesCallback(result); } return; } - if (methodName == hostapi::METHOD_PROXY_CALL) { + if (methodName == api::METHOD_PROXY_CALL) { const gchar* target = NULL; const gchar* targetBusName = NULL; const gchar* targetObjectPath = NULL; @@ -171,14 +186,14 @@ void HostConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == hostapi::METHOD_GET_CONTAINER_ID_LIST){ + if (methodName == api::host::METHOD_GET_CONTAINER_ID_LIST){ if (mGetContainerIdsCallback){ mGetContainerIdsCallback(result); } return; } - if (methodName == hostapi::METHOD_GET_ACTIVE_CONTAINER_ID){ + if (methodName == api::host::METHOD_GET_ACTIVE_CONTAINER_ID){ if (mGetActiveContainerIdCallback){ mGetActiveContainerIdCallback(result); } @@ -206,9 +221,9 @@ void HostConnection::signalContainerDbusState(const std::string& containerId, const std::string& dbusAddress) { GVariant* parameters = g_variant_new("(ss)", containerId.c_str(), dbusAddress.c_str()); - mDbusConnection->emitSignal(hostapi::OBJECT_PATH, - hostapi::INTERFACE, - hostapi::SIGNAL_CONTAINER_DBUS_STATE, + mDbusConnection->emitSignal(api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::SIGNAL_CONTAINER_DBUS_STATE, parameters); } diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 962fbb9..bc9015d 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -51,13 +51,15 @@ public: GVariant* parameters, dbus::MethodResultBuilder::Pointer result )> ProxyCallCallback; - typedef std::function GetContainerDbusesCallback; - typedef std::function GetContainerIdsCallback; + typedef std::function GetContainerIdsCallback; typedef std::function GetActiveContainerIdCallback; - + typedef std::function SetActiveContainerCallback; /** * Register proxy call callback @@ -85,6 +87,11 @@ public: void setGetActiveContainerIdCallback(const GetContainerIdsCallback& callback); /** + * Register a callback called to set the active container + */ + void setSetActiveContainerCallback(const SetActiveContainerCallback& callback); + + /** * Make a proxy call */ void proxyCallAsync(const std::string& busName, @@ -104,6 +111,7 @@ private: GetContainerDbusesCallback mGetContainerDbusesCallback; GetContainerIdsCallback mGetContainerIdsCallback; GetActiveContainerIdCallback mGetActiveContainerIdCallback; + SetActiveContainerCallback mSetActiveContainerCallback; void onNameAcquired(); void onNameLost(); diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index ef30e1a..12e8d4a 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -25,23 +25,26 @@ #ifndef SERVER_HOST_DBUS_DEFINITIONS_HPP #define SERVER_HOST_DBUS_DEFINITIONS_HPP -#include +#include "common-dbus-definitions.hpp" namespace security_containers { -namespace hostapi { +namespace api { +namespace host { +const std::string BUS_NAME = "org.tizen.containers.host"; +const std::string OBJECT_PATH = "/org/tizen/containers/host"; +const std::string INTERFACE = "org.tizen.containers.host.manager"; -const std::string BUS_NAME = "org.tizen.containers.host"; -const std::string OBJECT_PATH = "/org/tizen/containers/host"; -const std::string INTERFACE = "org.tizen.containers.host.manager"; +const std::string ERROR_CONTAINER_STOPPED = "org.tizen.containers.host.Error.ContainersStopped"; -const std::string METHOD_PROXY_CALL = "ProxyCall"; -const std::string METHOD_GET_CONTAINER_DBUSES = "GetContainerDbuses"; -const std::string METHOD_GET_CONTAINER_ID_LIST = "GetContainerIds"; -const std::string METHOD_GET_ACTIVE_CONTAINER_ID = "GetActiveContainerId"; +const std::string METHOD_GET_CONTAINER_DBUSES = "GetContainerDbuses"; +const std::string METHOD_GET_CONTAINER_ID_LIST = "GetContainerIds"; +const std::string METHOD_GET_ACTIVE_CONTAINER_ID = "GetActiveContainerId"; +const std::string METHOD_SET_ACTIVE_CONTAINER = "SetActiveContainer"; + +const std::string SIGNAL_CONTAINER_DBUS_STATE = "ContainerDbusState"; -const std::string SIGNAL_CONTAINER_DBUS_STATE = "ContainerDbusState"; const std::string DEFINITION = "" @@ -64,6 +67,9 @@ const std::string DEFINITION = " " " " " " + " " + " " + " " " " " " " " @@ -71,8 +77,8 @@ const std::string DEFINITION = " " ""; - -} // namespace hostapi +} // namespace host +} // namespace api } // namespace security_containers diff --git a/tests/unit_tests/server/ut-container-connection.cpp b/tests/unit_tests/server/ut-container-connection.cpp index 9f7b680..29dd310 100644 --- a/tests/unit_tests/server/ut-container-connection.cpp +++ b/tests/unit_tests/server/ut-container-connection.cpp @@ -28,6 +28,7 @@ #include "container-connection.hpp" #include "container-connection-transport.hpp" +#include "host-dbus-definitions.hpp" #include "container-dbus-definitions.hpp" // TODO: Switch to real power-manager dbus defs when they will be implemented in power-manager #include "fake-power-manager-dbus-definitions.hpp" @@ -152,10 +153,10 @@ BOOST_AUTO_TEST_CASE(NotifyActiveContainerApiTest) connection->setNotifyActiveContainerCallback(callback); DbusConnection::Pointer client = DbusConnection::create(dbus.acquireAddress()); - client->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_NOTIFY_ACTIVE_CONTAINER, + client->callMethod(api::container::BUS_NAME, + api::container::OBJECT_PATH, + api::container::INTERFACE, + api::container::METHOD_NOTIFY_ACTIVE_CONTAINER, g_variant_new("(ss)", "testapp", "testmessage"), "()"); BOOST_CHECK(notifyCalled.wait(EVENT_TIMEOUT)); @@ -178,9 +179,9 @@ BOOST_AUTO_TEST_CASE(SignalNotificationApiTest) const std::string& interface, const std::string& signalName, GVariant* parameters) { - if (objectPath == api::OBJECT_PATH && - interface == api::INTERFACE && - signalName == api::SIGNAL_NOTIFICATION && + if (objectPath == api::container::OBJECT_PATH && + interface == api::container::INTERFACE && + signalName == api::container::SIGNAL_NOTIFICATION && g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { const gchar* container = NULL; @@ -194,7 +195,7 @@ BOOST_AUTO_TEST_CASE(SignalNotificationApiTest) } } }; - client->signalSubscribe(handler, api::BUS_NAME); + client->signalSubscribe(handler, api::container::BUS_NAME); connection->sendNotification("testcontainer", "testapp", "testmessage"); diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index d4708e3..b3ce809 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -72,6 +72,7 @@ const std::string TEST_MESSAGE = "testmessage"; const std::string FILE_CONTENT = "File content\n" "Line 1\n" "Line 2\n"; +const std::string NON_EXISTANT_CONTAINER_ID = "NON_EXISTANT_CONTAINER_ID"; class DbusAccessory { public: @@ -126,7 +127,7 @@ public: void signalSubscribe(const DbusConnection::SignalCallback& callback) { - mClient->signalSubscribe(callback, isHost() ? hostapi::BUS_NAME : api::BUS_NAME); + mClient->signalSubscribe(callback, isHost() ? api::host::BUS_NAME : api::container::BUS_NAME); } void emitSignal(const std::string& objectPath, @@ -140,10 +141,10 @@ public: void callMethodNotify() { GVariant* parameters = g_variant_new("(ss)", TEST_APP_NAME.c_str(), TEST_MESSAGE.c_str()); - mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_NOTIFY_ACTIVE_CONTAINER, + mClient->callMethod(api::container::BUS_NAME, + api::container::OBJECT_PATH, + api::container::INTERFACE, + api::container::METHOD_NOTIFY_ACTIVE_CONTAINER, parameters, "()"); } @@ -151,10 +152,10 @@ public: std::string callMethodMove(const std::string& dest, const std::string& path) { GVariant* parameters = g_variant_new("(ss)", dest.c_str(), path.c_str()); - GVariantPtr result = mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_FILE_MOVE_REQUEST, + GVariantPtr result = mClient->callMethod(api::container::BUS_NAME, + api::container::OBJECT_PATH, + api::container::INTERFACE, + api::container::METHOD_FILE_MOVE_REQUEST, parameters, "(s)"); @@ -212,10 +213,13 @@ public: interface.c_str(), method.c_str(), parameters); - GVariantPtr result = mClient->callMethod(isHost() ? hostapi::BUS_NAME : api::BUS_NAME, - isHost() ? hostapi::OBJECT_PATH : api::OBJECT_PATH, - isHost() ? hostapi::INTERFACE : api::INTERFACE, - isHost() ? hostapi::METHOD_PROXY_CALL : api::METHOD_PROXY_CALL, + GVariantPtr result = mClient->callMethod(isHost() ? api::host::BUS_NAME : + api::container::BUS_NAME, + isHost() ? api::host::OBJECT_PATH : + api::container::OBJECT_PATH, + isHost() ? api::host::INTERFACE : + api::container::INTERFACE, + api::METHOD_PROXY_CALL, packedParameters, "(v)"); GVariant* unpackedResult = NULL; @@ -227,10 +231,10 @@ public: { assert(isHost()); Dbuses dbuses; - GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME, - hostapi::OBJECT_PATH, - hostapi::INTERFACE, - hostapi::METHOD_GET_CONTAINER_DBUSES, + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_GET_CONTAINER_DBUSES, NULL, "(a{ss})"); GVariant* array = NULL; @@ -249,10 +253,10 @@ public: std::vector callMethodGetContainerIds() { assert(isHost()); - GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME, - hostapi::OBJECT_PATH, - hostapi::INTERFACE, - hostapi::METHOD_GET_CONTAINER_ID_LIST, + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_GET_CONTAINER_ID_LIST, NULL, "(as)"); @@ -274,10 +278,10 @@ public: std::string callMethodGetActiveContainerId() { assert(isHost()); - GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME, - hostapi::OBJECT_PATH, - hostapi::INTERFACE, - hostapi::METHOD_GET_ACTIVE_CONTAINER_ID, + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_GET_ACTIVE_CONTAINER_ID, NULL, "(s)"); @@ -286,6 +290,19 @@ public: return containerId; } + void callMethodSetActiveContainer(const std::string& id) + { + assert(isHost()); + GVariant* parameters = g_variant_new("(s)", id.c_str()); + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_SET_ACTIVE_CONTAINER, + parameters, + "()"); + + } + private: const int mId; DbusConnection::Pointer mClient; @@ -413,9 +430,9 @@ BOOST_AUTO_TEST_CASE(NotifyActiveContainerTest) const std::string& signalName, GVariant* parameters) { - if (objectPath == api::OBJECT_PATH && - interface == api::INTERFACE && - signalName == api::SIGNAL_NOTIFICATION && + if (objectPath == api::container::OBJECT_PATH && + interface == api::container::INTERFACE && + signalName == api::container::SIGNAL_NOTIFICATION && g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { const gchar* container = NULL; @@ -516,9 +533,9 @@ BOOST_AUTO_TEST_CASE(MoveFileTest) const std::string& signalName, GVariant* parameters) { - if (objectPath == api::OBJECT_PATH && - interface == api::INTERFACE && - signalName == api::SIGNAL_NOTIFICATION && + if (objectPath == api::container::OBJECT_PATH && + interface == api::container::INTERFACE && + signalName == api::container::SIGNAL_NOTIFICATION && g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { const gchar* source = NULL; @@ -547,27 +564,27 @@ BOOST_AUTO_TEST_CASE(MoveFileTest) // sending to a non existing container BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(BUGGY_CONTAINER, NO_PATH), - api::FILE_MOVE_DESTINATION_NOT_FOUND); + api::container::FILE_MOVE_DESTINATION_NOT_FOUND); BOOST_CHECK(notificationLatch.empty()); // sending to self BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER1, NO_PATH), - api::FILE_MOVE_WRONG_DESTINATION); + api::container::FILE_MOVE_WRONG_DESTINATION); BOOST_CHECK(notificationLatch.empty()); // no permission to send BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER2, "/etc/secret1"), - api::FILE_MOVE_NO_PERMISSIONS_SEND); + api::container::FILE_MOVE_NO_PERMISSIONS_SEND); BOOST_CHECK(notificationLatch.empty()); // no permission to receive BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER2, "/etc/secret2"), - api::FILE_MOVE_NO_PERMISSIONS_RECEIVE); + api::container::FILE_MOVE_NO_PERMISSIONS_RECEIVE); BOOST_CHECK(notificationLatch.empty()); // non existing file BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER2, BUGGY_PATH), - api::FILE_MOVE_FAILED); + api::container::FILE_MOVE_FAILED); BOOST_CHECK(notificationLatch.empty()); // a working scenario @@ -580,12 +597,12 @@ BOOST_AUTO_TEST_CASE(MoveFileTest) BOOST_REQUIRE(utils::saveFileContent(CONTAINER1PATH + "/file", FILE_CONTENT)); BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER2, TMP + "/file"), - api::FILE_MOVE_SUCCEEDED); + api::container::FILE_MOVE_SUCCEEDED); BOOST_CHECK(notificationLatch.wait(EVENT_TIMEOUT)); BOOST_CHECK(notificationLatch.empty()); BOOST_CHECK_EQUAL(notificationSource, CONTAINER1); BOOST_CHECK_EQUAL(notificationPath, TMP + "/file"); - BOOST_CHECK_EQUAL(notificationRetcode, api::FILE_MOVE_SUCCEEDED); + BOOST_CHECK_EQUAL(notificationRetcode, api::container::FILE_MOVE_SUCCEEDED); BOOST_CHECK(!fs::exists(CONTAINER1PATH + "/file")); BOOST_CHECK_EQUAL(utils::readFileContent(CONTAINER2PATH + "/file"), FILE_CONTENT); @@ -756,9 +773,9 @@ BOOST_AUTO_TEST_CASE(ContainerDbusesSignalsTest) const std::string& interface, const std::string& signalName, GVariant* parameters) { - if (objectPath == hostapi::OBJECT_PATH && - interface == hostapi::INTERFACE && - signalName == hostapi::SIGNAL_CONTAINER_DBUS_STATE) { + if (objectPath == api::host::OBJECT_PATH && + interface == api::host::INTERFACE && + signalName == api::host::SIGNAL_CONTAINER_DBUS_STATE) { const gchar* containerId = NULL; const gchar* dbusAddress = NULL; @@ -827,4 +844,28 @@ BOOST_AUTO_TEST_CASE(GetActiveContainerIdTest) BOOST_CHECK(dbus.callMethodGetActiveContainerId() == ""); } +BOOST_AUTO_TEST_CASE(SetActiveContainerTest) +{ + ContainersManager cm(TEST_DBUS_CONFIG_PATH); + cm.startAll(); + + DbusAccessory dbus(DbusAccessory::HOST_ID); + + std::vector containerIds = {"ut-containers-manager-console1-dbus", + "ut-containers-manager-console2-dbus", + "ut-containers-manager-console3-dbus"}; + + for (std::string& containerId: containerIds){ + BOOST_REQUIRE_NO_THROW(dbus.callMethodSetActiveContainer(containerId)); + BOOST_CHECK(dbus.callMethodGetActiveContainerId() == containerId); + } + + BOOST_REQUIRE_THROW(dbus.callMethodSetActiveContainer(NON_EXISTANT_CONTAINER_ID), + DbusException); + + cm.stopAll(); + BOOST_REQUIRE_THROW(dbus.callMethodSetActiveContainer("ut-containers-manager-console1-dbus"), + DbusException); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From d4af3ccd9e4b36bcce46bbadb07f65519f3369e5 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Tue, 29 Jul 2014 12:33:10 +0200 Subject: [PATCH 07/16] Fix client library installation [Bug/Feature] Missing so versioning [Cause] N/A [Solution] N/A [Verification] Build, install Change-Id: I4f5c3715b177506c6c6e967512acf969944fa246 --- client/CMakeLists.txt | 17 ++++++++++------- client/security-containers.pc.in | 6 ++++-- packaging/security-containers.spec | 11 +++++++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 8d45be5..8a34575 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -21,10 +21,14 @@ MESSAGE(STATUS "Generating makefile for the Client...") FILE(GLOB project_SRCS *.cpp *.hpp) FILE(GLOB_RECURSE common_SRCS ${COMMON_FOLDER}/*.cpp ${COMMON_FOLDER}/*.hpp) +SET(_LIB_VERSION_ "0.0.1") +SET(_LIB_SOVERSION_ "0") +SET(PC_FILE "${PROJECT_NAME}.pc") ## Setup target ################################################################ -SET(CLIENT_CODENAME "${PROJECT_NAME}-client") -ADD_LIBRARY(${CLIENT_CODENAME} SHARED ${project_SRCS}) +ADD_LIBRARY(${PROJECT_NAME} SHARED ${project_SRCS}) +SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY SOVERSION ${_LIB_SOVERSION_}) +SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY VERSION ${_LIB_VERSION_}) ## Link libraries ############################################################## @@ -32,17 +36,16 @@ INCLUDE_DIRECTORIES(${COMMON_FOLDER}) ## Generate the pc file ######################################################## -CONFIGURE_FILE(security-containers.pc.in - ${CMAKE_BINARY_DIR}/security-containers.pc @ONLY) +CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY) ## Install ##################################################################### -INSTALL(FILES ${CMAKE_BINARY_DIR}/security-containers.pc +INSTALL(FILES ${CMAKE_BINARY_DIR}/${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) -INSTALL(TARGETS ${CLIENT_CODENAME} +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries) INSTALL(FILES security-containers-client.h - DESTINATION ${INCLUDE_INSTALL_DIR}/security-containers) + DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME}) diff --git a/client/security-containers.pc.in b/client/security-containers.pc.in index 16a4330..186218e 100644 --- a/client/security-containers.pc.in +++ b/client/security-containers.pc.in @@ -1,10 +1,12 @@ +# Package Information for pkg-config + prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} libdir=@LIB_INSTALL_DIR@ includedir=${prefix}/include Name: security-containers -Description: Security Containers Package -Version: @PACKAGE_VERSION@ +Description: Security Containers library +Version: @_LIB_VERSION_@ Libs: -L${libdir} -lsecurity-containers-client Cflags: -I${includedir}/security-containers diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index e639a98..af4751c 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -113,7 +113,13 @@ Library interface to the security-containers daemon %files client %manifest packaging/libsecurity-containers-client.manifest -%attr(644,root,root) %{_libdir}/libsecurity-containers-client.so +%defattr(644,root,root,755) +%attr(755,root,root) %{_libdir}/libsecurity-containers.so.0.0.1 +%{_libdir}/libsecurity-containers.so.0 + +%post client -p /sbin/ldconfig + +%postun client -p /sbin/ldconfig ## Devel Package ############################################################### @@ -129,8 +135,9 @@ Development package including the header files for the client library %files devel %manifest packaging/security-containers.manifest %defattr(644,root,root,755) +%{_libdir}/libsecurity-containers.so %{_includedir}/security-containers -%{_libdir}/pkgconfig/* +%{_libdir}/pkgconfig/*.pc ## Container Support Package ################################################### -- 2.7.4 From 907f1db9a197eab354dce2fff1007e6b235ff985 Mon Sep 17 00:00:00 2001 From: Jacek Pielaszkiewicz Date: Mon, 21 Jul 2014 17:09:35 +0200 Subject: [PATCH 08/16] Extract common/log, common/dbus, common/config directories and create from them libraries. [Bug/Feature] N/A [Cause] N/A [Solution] 1. The following directories have been extracted (removed): - common/log - common/dbus - common/config 2. In place of the removed source code, security-containers is link with the following libraries: - libLogger - libSimpleDbus - libConfig [Verification] Build, install, run tests Change-Id: I9d0b1627638b401bb88e442dd9681a7943fe0b5d Signed-off-by: Jacek Pielaszkiewicz --- common/config/exception.hpp | 51 --- common/config/fields.hpp | 77 ---- common/config/from-json-visitor.hpp | 143 -------- common/config/is-visitable.hpp | 55 --- common/config/manager.hpp | 77 ---- common/config/to-json-visitor.hpp | 124 ------- common/dbus/connection.cpp | 391 --------------------- common/dbus/connection.hpp | 204 ----------- common/dbus/exception.hpp | 81 ----- common/libvirt/connection.cpp | 2 +- common/libvirt/domain.cpp | 2 +- common/libvirt/helpers.cpp | 2 +- common/libvirt/network.cpp | 2 +- common/log/backend-journal.cpp | 72 ---- common/log/backend-journal.hpp | 52 --- common/log/backend-null.hpp | 53 --- common/log/backend-stderr.cpp | 65 ---- common/log/backend-stderr.hpp | 52 --- common/log/backend.hpp | 55 --- common/log/ccolor.cpp | 44 --- common/log/ccolor.hpp | 56 --- common/log/formatter.cpp | 124 ------- common/log/formatter.hpp | 52 --- common/log/level.cpp | 70 ---- common/log/level.hpp | 58 --- common/log/logger.cpp | 86 ----- common/log/logger.hpp | 87 ----- common/utils/callback-guard.cpp | 2 +- common/utils/environment.cpp | 2 +- common/utils/fs.cpp | 2 +- container-daemon/CMakeLists.txt | 3 +- container-daemon/daemon-connection.cpp | 2 +- container-daemon/daemon.cpp | 2 +- container-daemon/main.cpp | 8 +- container-daemon/runner.cpp | 2 +- packaging/security-containers.spec | 3 + server/CMakeLists.txt | 2 +- server/container-admin.cpp | 2 +- server/container-connection-transport.cpp | 2 +- server/container-connection.cpp | 2 +- server/container.cpp | 3 +- server/containers-manager.cpp | 3 +- server/host-connection.cpp | 2 +- server/input-monitor.cpp | 2 +- server/main.cpp | 8 +- server/network-admin.cpp | 2 +- server/server.cpp | 3 +- tests/unit_tests/CMakeLists.txt | 2 +- tests/unit_tests/config/ut-configuration.cpp | 3 +- tests/unit_tests/dbus/test-server.cpp | 2 +- tests/unit_tests/dbus/ut-connection.cpp | 4 +- tests/unit_tests/log/ut-logger.cpp | 10 +- .../unit_tests/server/ut-container-connection.cpp | 2 +- tests/unit_tests/server/ut-container.cpp | 2 +- tests/unit_tests/server/ut-containers-manager.cpp | 6 +- tests/unit_tests/server/ut-server.cpp | 2 +- tests/unit_tests/ut.cpp | 6 +- tests/unit_tests/utils/scoped-daemon.cpp | 2 +- 58 files changed, 56 insertions(+), 2179 deletions(-) delete mode 100644 common/config/exception.hpp delete mode 100644 common/config/fields.hpp delete mode 100644 common/config/from-json-visitor.hpp delete mode 100644 common/config/is-visitable.hpp delete mode 100644 common/config/manager.hpp delete mode 100644 common/config/to-json-visitor.hpp delete mode 100644 common/dbus/connection.cpp delete mode 100644 common/dbus/connection.hpp delete mode 100644 common/dbus/exception.hpp delete mode 100644 common/log/backend-journal.cpp delete mode 100644 common/log/backend-journal.hpp delete mode 100644 common/log/backend-null.hpp delete mode 100644 common/log/backend-stderr.cpp delete mode 100644 common/log/backend-stderr.hpp delete mode 100644 common/log/backend.hpp delete mode 100644 common/log/ccolor.cpp delete mode 100644 common/log/ccolor.hpp delete mode 100644 common/log/formatter.cpp delete mode 100644 common/log/formatter.hpp delete mode 100644 common/log/level.cpp delete mode 100644 common/log/level.hpp delete mode 100644 common/log/logger.cpp delete mode 100644 common/log/logger.hpp diff --git a/common/config/exception.hpp b/common/config/exception.hpp deleted file mode 100644 index aa644b1..0000000 --- a/common/config/exception.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Lukasz Pawelczyk - * - * 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 - */ - -/** - * @file - * @author Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com) - * @brief Exceptions for the configuration - */ - - -#ifndef COMMON_CONFIG_EXCEPTION_HPP -#define COMMON_CONFIG_EXCEPTION_HPP - -#include "base-exception.hpp" - - -namespace security_containers { -namespace config { - - -/** - * Base class for exceptions in configuration. - * Error occured during a config file parsing, - * e.g. syntax error - */ -struct ConfigException: public SecurityContainersException { - - ConfigException(const std::string& error = "") : SecurityContainersException(error) {} -}; - - -} // namespace config -} // namespace security_containers - - -#endif // COMMON_CONFIG_EXCEPTION_HPP diff --git a/common/config/fields.hpp b/common/config/fields.hpp deleted file mode 100644 index db0f26f..0000000 --- a/common/config/fields.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * - * 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 - */ - -/** - * @file - * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Macros for registering configuration fields - */ - -#ifndef COMMON_CONFIG_FIELDS_HPP -#define COMMON_CONFIG_FIELDS_HPP - -#include -#include - -#if BOOST_PP_VARIADICS != 1 -#error variadic macros not supported -#endif - -/** - * Use this macro to register config fields. - * - * Example: - * struct Foo - * { - * std::string bar; - * std::vector tab; - * - * // SubConfigA must also register config fields - * SubConfigA sub_a; - * - * // SubConfigB must also register config fields - * std::vector tab_sub; - * - * CONFIG_REGISTER - * ( - * bar, - * tab, - * sub_a - * ) - * }; - */ -#define CONFIG_REGISTER(...) \ - template \ - void accept(Visitor v) { \ - GENERATE_ELEMENTS__(__VA_ARGS__) \ - } \ - template \ - void accept(Visitor v) const { \ - GENERATE_ELEMENTS__(__VA_ARGS__) \ - } \ - -#define GENERATE_ELEMENTS__(...) \ - BOOST_PP_LIST_FOR_EACH(GENERATE_ELEMENT__, \ - _, \ - BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)) \ - -#define GENERATE_ELEMENT__(r, _, element) \ - v.visit(#element, element); \ - - -#endif // COMMON_CONFIG_FIELDS_HPP diff --git a/common/config/from-json-visitor.hpp b/common/config/from-json-visitor.hpp deleted file mode 100644 index fad9986..0000000 --- a/common/config/from-json-visitor.hpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * - * 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 - */ - -/** - * @file - * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief JSON visitor - */ - -#ifndef COMMON_CONFIG_FROM_JSON_VISITOR_HPP -#define COMMON_CONFIG_FROM_JSON_VISITOR_HPP - -#include "config/is-visitable.hpp" -#include "config/exception.hpp" - -#include -#include -#include - -namespace security_containers { -namespace config { - -class FromJsonVisitor { -public: - explicit FromJsonVisitor(const std::string& jsonString) - : mObject(nullptr) - { - mObject = json_tokener_parse(jsonString.c_str()); - if (mObject == nullptr) { - throw ConfigException("Json parsing error"); - } - } - - FromJsonVisitor(const FromJsonVisitor& visitor) - : mObject(json_object_get(visitor.mObject)) - { - } - - ~FromJsonVisitor() - { - json_object_put(mObject); - } - - template - void visit(const std::string& name, T& value) - { - json_object* object = nullptr; - if (!json_object_object_get_ex(mObject, name.c_str(), &object)) { - throw ConfigException("Missing field '" + name + "' in json"); - } - fromJsonObject(object, value); - } - -private: - json_object* mObject; - - FromJsonVisitor& operator=(const FromJsonVisitor&) = delete; - - explicit FromJsonVisitor(json_object* object) - : mObject(json_object_get(object)) - { - } - - static void checkType(json_object* object, json_type type) - { - if (type != json_object_get_type(object)) { - throw ConfigException("Invalid field type"); - } - } - - static void fromJsonObject(json_object* object, int& value) - { - checkType(object, json_type_int); - std::int64_t value64 = json_object_get_int64(object); - if (value64 > INT32_MAX || value64 < INT32_MIN) { - throw ConfigException("Value out of range"); - } - value = static_cast(value64); - } - - static void fromJsonObject(json_object* object, std::int64_t& value) - { - checkType(object, json_type_int); - value = json_object_get_int64(object); - } - - static void fromJsonObject(json_object* object, bool& value) - { - checkType(object, json_type_boolean); - value = json_object_get_boolean(object); - } - - static void fromJsonObject(json_object* object, double& value) - { - checkType(object, json_type_double); - value = json_object_get_double(object); - } - - static void fromJsonObject(json_object* object, std::string& value) - { - checkType(object, json_type_string); - value = json_object_get_string(object); - } - - template - static void fromJsonObject(json_object* object, std::vector& value) - { - checkType(object, json_type_array); - int length = json_object_array_length(object); - value.resize(static_cast(length)); - for (int i = 0; i < length; ++i) { - fromJsonObject(json_object_array_get_idx(object, i), value[static_cast(i)]); - } - } - - template::value>::type> - static void fromJsonObject(json_object* object, T& value) - { - checkType(object, json_type_object); - FromJsonVisitor visitor(object); - value.accept(visitor); - } -}; - -} // namespace config -} // namespace security_containers - -#endif // COMMON_CONFIG_FROM_JSON_VISITOR_HPP diff --git a/common/config/is-visitable.hpp b/common/config/is-visitable.hpp deleted file mode 100644 index 0a405c5..0000000 --- a/common/config/is-visitable.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * - * 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 - */ - -/** - * @file - * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Internal configuration helper - */ - -#ifndef COMMON_CONFIG_IS_VISITABLE_HPP -#define COMMON_CONFIG_IS_VISITABLE_HPP - -#include - -namespace security_containers { -namespace config { - -template -struct isVisitableHelper__ { - struct Visitor {}; - - template static std::true_type - test(decltype(std::declval().template accept(Visitor()))*); - - template static std::false_type - test(...); - - static constexpr bool value = std::is_same(0)), std::true_type>::value; -}; - -/** - * Helper for compile-time checking against existance of template method 'accept'. - */ -template -struct isVisitable : public std::integral_constant::value> {}; - -} // namespace config -} // namespace security_containers - -#endif // COMMON_CONFIG_IS_VISITABLE_HPP diff --git a/common/config/manager.hpp b/common/config/manager.hpp deleted file mode 100644 index 8761267..0000000 --- a/common/config/manager.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * - * 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 - */ - -/** - * @file - * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Configuration management functions - */ - -#ifndef COMMON_CONFIG_MANAGER_HPP -#define COMMON_CONFIG_MANAGER_HPP - -#include "config/to-json-visitor.hpp" -#include "config/from-json-visitor.hpp" -#include "config/is-visitable.hpp" -#include "utils/fs.hpp" - -namespace security_containers { -namespace config { - -template -void loadFromString(const std::string& jsonString, Config& config) -{ - static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); - - FromJsonVisitor visitor(jsonString); - config.accept(visitor); -} - -template -std::string saveToString(const Config& config) -{ - static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); - - ToJsonVisitor visitor; - config.accept(visitor); - return visitor.toString(); -} - -template -void loadFromFile(const std::string& filename, Config& config) -{ - std::string content; - if (!utils::readFileContent(filename, content)) { - throw ConfigException("Could not load " + filename); - } - loadFromString(content, config); -} - -template -void saveToFile(const std::string& filename, const Config& config) -{ - const std::string content = saveToString(config); - if (!utils::saveFileContent(filename, content)) { - throw ConfigException("Could not save " + filename); - } -} - -} // namespace config -} // namespace security_containers - -#endif // COMMON_CONFIG_MANAGER_HPP diff --git a/common/config/to-json-visitor.hpp b/common/config/to-json-visitor.hpp deleted file mode 100644 index 477b1ef..0000000 --- a/common/config/to-json-visitor.hpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * - * 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 - */ - -/** - * @file - * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief JSON visitor - */ - -#ifndef COMMON_CONFIG_TO_JSON_VISITOR_HPP -#define COMMON_CONFIG_TO_JSON_VISITOR_HPP - -#include "config/is-visitable.hpp" - -#include -#include -#include - -namespace security_containers { -namespace config { - -class ToJsonVisitor { - -public: - ToJsonVisitor() - : mObject(json_object_new_object()) - { - } - - ToJsonVisitor(const ToJsonVisitor& visitor) - : mObject(json_object_get(visitor.mObject)) - { - } - - ~ToJsonVisitor() - { - json_object_put(mObject); - } - - std::string toString() const - { - return json_object_to_json_string(mObject); - } - - template - void visit(const std::string& name, const T& value) - { - json_object_object_add(mObject, name.c_str(), toJsonObject(value)); - } -private: - json_object* mObject; - - ToJsonVisitor& operator=(const ToJsonVisitor&) = delete; - - json_object* detach() - { - json_object* ret = mObject; - mObject = nullptr; - return ret; - } - - static json_object* toJsonObject(int value) - { - return json_object_new_int(value); - } - - static json_object* toJsonObject(std::int64_t value) - { - return json_object_new_int64(value); - } - - static json_object* toJsonObject(bool value) - { - return json_object_new_boolean(value); - } - - static json_object* toJsonObject(double value) - { - return json_object_new_double(value); - } - - static json_object* toJsonObject(const std::string& value) - { - return json_object_new_string(value.c_str()); - } - - template - static json_object* toJsonObject(const std::vector& value) - { - json_object* array = json_object_new_array(); - for (const T& v : value) { - json_object_array_add(array, toJsonObject(v)); - } - return array; - } - - template::value>::type> - static json_object* toJsonObject(const T& value) - { - ToJsonVisitor visitor; - value.accept(visitor); - return visitor.detach(); - } -}; - -} // namespace config -} // namespace security_containers - -#endif // COMMON_CONFIG_TO_JSON_VISITOR_HPP diff --git a/common/dbus/connection.cpp b/common/dbus/connection.cpp deleted file mode 100644 index ef6fc46..0000000 --- a/common/dbus/connection.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Piotr Bartosiewicz - * - * 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 - */ - -/** - * @file - * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Dbus connection class - */ - -#include "config.hpp" -#include "dbus/connection.hpp" -#include "dbus/exception.hpp" -#include "utils/callback-wrapper.hpp" -#include "utils/scoped-gerror.hpp" -#include "log/logger.hpp" - -using namespace security_containers::utils; - -namespace security_containers { -namespace dbus { - - -namespace { - -const std::string SYSTEM_BUS_ADDRESS = "unix:path=/var/run/dbus/system_bus_socket"; -const std::string INTROSPECT_INTERFACE = "org.freedesktop.DBus.Introspectable"; -const std::string INTROSPECT_METHOD = "Introspect"; - -const int CALL_METHOD_TIMEOUT_MS = 1000; - -class MethodResultBuilderImpl : public MethodResultBuilder { -public: - MethodResultBuilderImpl(GDBusMethodInvocation* invocation) - : mInvocation(invocation), mResultSet(false) {} - ~MethodResultBuilderImpl() - { - if (!mResultSet) { - setError("org.freedesktop.DBus.Error.UnknownMethod", "Not implemented"); - } - } - void set(GVariant* parameters) - { - g_dbus_method_invocation_return_value(mInvocation, parameters); - mResultSet = true; - } - void setVoid() - { - set(NULL); - } - void setError(const std::string& name, const std::string& message) - { - g_dbus_method_invocation_return_dbus_error(mInvocation, name.c_str(), message.c_str()); - mResultSet = true; - } -private: - GDBusMethodInvocation* mInvocation; - bool mResultSet; -}; - -void throwDbusException(const ScopedGError& e) -{ - if (e->domain == g_io_error_quark()) { - if (e->code == G_IO_ERROR_DBUS_ERROR) { - throw DbusCustomException(e->message); - } else { - throw DbusIOException(e->message); - } - } else if (e->domain == g_dbus_error_quark()) { - throw DbusOperationException(e->message); - } else if (e->domain == g_markup_error_quark()) { - throw DbusInvalidArgumentException(e->message); - } else { - throw DbusException(e->message); - } -} - -class AsyncMethodCallResultImpl : public AsyncMethodCallResult { -public: - AsyncMethodCallResultImpl(GVariant* result, const ScopedGError& error) - : mResult(result), mError(error) {} - ~AsyncMethodCallResultImpl() - { - if (mResult) { - g_variant_unref(mResult); - } - } - GVariant* get() - { - if (mError) { - throwDbusException(mError); - } - return mResult; - } -private: - GVariant* mResult; - const ScopedGError& mError; -}; - -} // namespace - -DbusConnection::Pointer DbusConnection::create(const std::string& address) -{ - return Pointer(new DbusConnection(address)); -} - -DbusConnection::Pointer DbusConnection::createSystem() -{ - return create(SYSTEM_BUS_ADDRESS); -} - -DbusConnection::DbusConnection(const std::string& address) - : mConnection(NULL) - , mNameId(0) -{ - ScopedGError error; - const GDBusConnectionFlags flags = - static_cast(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | - G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION); - // TODO: this is possible deadlock if the dbus - // socket exists but there is no dbus-daemon - mConnection = g_dbus_connection_new_for_address_sync(address.c_str(), - flags, - NULL, - NULL, - &error); - if (error) { - error.strip(); - LOGE("Could not connect to " << address << "; " << error); - throwDbusException(error); - } -} - -DbusConnection::~DbusConnection() -{ - if (mNameId) { - g_bus_unown_name(mNameId); - } - g_object_unref(mConnection); - LOGT("Connection deleted"); -} - -void DbusConnection::setName(const std::string& name, - const VoidCallback& onNameAcquired, - const VoidCallback& onNameLost) -{ - mNameId = g_bus_own_name_on_connection(mConnection, - name.c_str(), - G_BUS_NAME_OWNER_FLAGS_NONE, - &DbusConnection::onNameAcquired, - &DbusConnection::onNameLost, - utils::createCallbackWrapper( - NameCallbacks(onNameAcquired, onNameLost), - mGuard.spawn()), - &utils::deleteCallbackWrapper); -} - -void DbusConnection::onNameAcquired(GDBusConnection*, const gchar* name, gpointer userData) -{ - LOGD("Name acquired " << name); - const NameCallbacks& callbacks = utils::getCallbackFromPointer(userData); - if (callbacks.nameAcquired) { - callbacks.nameAcquired(); - } -} - -void DbusConnection::onNameLost(GDBusConnection*, const gchar* name, gpointer userData) -{ - LOGD("Name lost " << name); - const NameCallbacks& callbacks = utils::getCallbackFromPointer(userData); - if (callbacks.nameLost) { - callbacks.nameLost(); - } -} - -void DbusConnection::emitSignal(const std::string& objectPath, - const std::string& interface, - const std::string& name, - GVariant* parameters) -{ - ScopedGError error; - g_dbus_connection_emit_signal(mConnection, - NULL, - objectPath.c_str(), - interface.c_str(), - name.c_str(), - parameters, - &error); - if (error) { - error.strip(); - LOGE("Emit signal failed; " << error); - throwDbusException(error); - } -} - -void DbusConnection::signalSubscribe(const SignalCallback& callback, - const std::string& senderBusName) -{ - g_dbus_connection_signal_subscribe(mConnection, - senderBusName.empty() ? NULL : senderBusName.c_str(), - NULL, - NULL, - NULL, - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - &DbusConnection::onSignal, - utils::createCallbackWrapper(callback, mGuard.spawn()), - &utils::deleteCallbackWrapper); -} - -void DbusConnection::onSignal(GDBusConnection*, - const gchar* sender, - const gchar* object, - const gchar* interface, - const gchar* name, - GVariant* parameters, - gpointer userData) -{ - const SignalCallback& callback = utils::getCallbackFromPointer(userData); - - LOGD("Signal: " << sender << "; " << object << "; " << interface << "; " << name); - - if (callback) { - callback(sender, object, interface, name, parameters); - } -} - -std::string DbusConnection::introspect(const std::string& busName, const std::string& objectPath) -{ - GVariantPtr result = DbusConnection::callMethod(busName, - objectPath, - INTROSPECT_INTERFACE, - INTROSPECT_METHOD, - NULL, - "(s)"); - const gchar* xml; - g_variant_get(result.get(), "(&s)", &xml); - return xml; -} - -void DbusConnection::registerObject(const std::string& objectPath, - const std::string& objectDefinitionXml, - const MethodCallCallback& callback) -{ - ScopedGError error; - GDBusNodeInfo* nodeInfo = g_dbus_node_info_new_for_xml(objectDefinitionXml.c_str(), &error); - if (nodeInfo != NULL && (nodeInfo->interfaces == NULL || - nodeInfo->interfaces[0] == NULL || - nodeInfo->interfaces[1] != NULL)) { - g_dbus_node_info_unref(nodeInfo); - g_set_error(&error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Expected exactly one interface"); - } - if (error) { - error.strip(); - LOGE("Invalid xml; " << error); - throwDbusException(error); - } - GDBusInterfaceInfo* interfaceInfo = nodeInfo->interfaces[0]; - - GDBusInterfaceVTable vtable; - vtable.method_call = &DbusConnection::onMethodCall; - vtable.get_property = NULL; - vtable.set_property = NULL; - - g_dbus_connection_register_object(mConnection, - objectPath.c_str(), - interfaceInfo, - &vtable, - utils::createCallbackWrapper(callback, mGuard.spawn()), - &utils::deleteCallbackWrapper, - &error); - g_dbus_node_info_unref(nodeInfo); - if (error) { - error.strip(); - LOGE("Register object failed; " << error); - throwDbusException(error); - } -} - -void DbusConnection::onMethodCall(GDBusConnection*, - const gchar*, - const gchar* objectPath, - const gchar* interface, - const gchar* method, - GVariant* parameters, - GDBusMethodInvocation* invocation, - gpointer userData) -{ - const MethodCallCallback& callback = utils::getCallbackFromPointer(userData); - - LOGD("MethodCall: " << objectPath << "; " << interface << "; " << method); - - MethodResultBuilder::Pointer resultBuilder(new MethodResultBuilderImpl(invocation)); - if (callback) { - callback(objectPath, interface, method, parameters, resultBuilder); - } -} - -GVariantPtr DbusConnection::callMethod(const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters, - const std::string& replyType) -{ - ScopedGError error; - GVariant* result = g_dbus_connection_call_sync(mConnection, - busName.c_str(), - objectPath.c_str(), - interface.c_str(), - method.c_str(), - parameters, - replyType.empty() ? NULL - : G_VARIANT_TYPE(replyType.c_str()), - G_DBUS_CALL_FLAGS_NONE, - CALL_METHOD_TIMEOUT_MS, - NULL, - &error); - if (error) { - error.strip(); - LOGE("Call method failed; " << error); - throwDbusException(error); - } - return GVariantPtr(result, g_variant_unref); -} - -void DbusConnection::callMethodAsync(const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters, - const std::string& replyType, - const AsyncMethodCallCallback& callback) -{ - g_dbus_connection_call(mConnection, - busName.c_str(), - objectPath.c_str(), - interface.c_str(), - method.c_str(), - parameters, - replyType.empty() ? NULL - : G_VARIANT_TYPE(replyType.c_str()), - G_DBUS_CALL_FLAGS_NONE, - CALL_METHOD_TIMEOUT_MS, - NULL, - &DbusConnection::onAsyncReady, - utils::createCallbackWrapper(callback, mGuard.spawn())); -} - -void DbusConnection::onAsyncReady(GObject* source, - GAsyncResult* asyncResult, - gpointer userData) -{ - std::unique_ptr - autoDeleteCallback(userData, &utils::deleteCallbackWrapper); - GDBusConnection* connection = reinterpret_cast(source); - const AsyncMethodCallCallback& callback = - utils::getCallbackFromPointer(userData); - - ScopedGError error; - GVariant* result = g_dbus_connection_call_finish(connection, asyncResult, &error); - if (error) { - error.strip(); - LOGE("Call method failed; " << error); - } - AsyncMethodCallResultImpl asyncMethodCallResult(result, error); - if (callback) { - callback(asyncMethodCallResult); - } -} - - -} // namespace dbus -} // namespace security_containers diff --git a/common/dbus/connection.hpp b/common/dbus/connection.hpp deleted file mode 100644 index 9ac87de..0000000 --- a/common/dbus/connection.hpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Piotr Bartosiewicz - * - * 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 - */ - -/** - * @file - * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Dbus connection class - */ - -#ifndef COMMON_DBUS_CONNECTION_HPP -#define COMMON_DBUS_CONNECTION_HPP - -#include "utils/callback-guard.hpp" - -#include -#include -#include -#include - - -namespace security_containers { -namespace dbus { - - -typedef std::unique_ptr GVariantPtr; - -/** - * An interface used to set a result to a method call. - */ -class MethodResultBuilder { -public: - typedef std::shared_ptr Pointer; - - virtual ~MethodResultBuilder() {} - virtual void set(GVariant* parameters) = 0; - virtual void setVoid() = 0; - virtual void setError(const std::string& name, const std::string& message) = 0; -}; - -/** - * An interface used to get result from async response. - */ -class AsyncMethodCallResult { -public: - virtual ~AsyncMethodCallResult() {} - virtual GVariant* get() = 0; // throws DbusException on error -}; - -/** - * Dbus connection. - * Provides a functionality that allows to call dbus methods, - * register dbus interfaces, etc. - * - * TODO divide to interface and implementation header - */ -class DbusConnection { -public: - typedef std::unique_ptr Pointer; - - typedef std::function VoidCallback; - - typedef std::function MethodCallCallback; - - typedef std::function SignalCallback; - - typedef std::function AsyncMethodCallCallback; - - /** - * Creates a connection to the dbus with given address. - */ - static Pointer create(const std::string& address); - - /** - * Creates a connection to the system dbus. - */ - static Pointer createSystem(); - - ~DbusConnection(); - - /** - * Sets a name to the dbus connection. - * It allows other client to call methods using this name. - */ - void setName(const std::string& name, - const VoidCallback& onNameAcquired, - const VoidCallback& onNameLost); - - /** - * Emits dbus signal. - */ - void emitSignal(const std::string& objectPath, - const std::string& interface, - const std::string& name, - GVariant* parameters); - - /** - * Subscribes to a signal. - * Empty sender means subscribe to all signals - */ - void signalSubscribe(const SignalCallback& callback, const std::string& senderBusName); - - /** - * Registers an object with given definition. - * Api calls will be handled by given callback. - */ - void registerObject(const std::string& objectPath, - const std::string& objectDefinitionXml, - const MethodCallCallback& callback); - - /** - * Call a dbus method - */ - GVariantPtr callMethod(const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters, - const std::string& replyType); - - /** - * Async call a dbus method - */ - void callMethodAsync(const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters, - const std::string& replyType, - const AsyncMethodCallCallback& callback); - - /** - * Returns an xml with meta description of specified dbus object. - */ - std::string introspect(const std::string& busName, const std::string& objectPath); - -private: - struct NameCallbacks { - VoidCallback nameAcquired; - VoidCallback nameLost; - - NameCallbacks(const VoidCallback& acquired, const VoidCallback& lost) - : nameAcquired(acquired), nameLost(lost) {} - }; - - utils::CallbackGuard mGuard; - GDBusConnection* mConnection; - guint mNameId; - - DbusConnection(const std::string& address); - - static void onNameAcquired(GDBusConnection* connection, const gchar* name, gpointer userData); - static void onNameLost(GDBusConnection* connection, const gchar* name, gpointer userData); - static void onSignal(GDBusConnection* connection, - const gchar* sender, - const gchar* object, - const gchar* interface, - const gchar* name, - GVariant* parameters, - gpointer userData); - static void onMethodCall(GDBusConnection* connection, - const gchar* sender, - const gchar* objectPath, - const gchar* interface, - const gchar* method, - GVariant* parameters, - GDBusMethodInvocation* invocation, - gpointer userData); - static void onAsyncReady(GObject* source, - GAsyncResult* asyncResult, - gpointer userData); -}; - - -} // namespace dbus -} // namespace security_containers - - -#endif // COMMON_DBUS_CONNECTION_HPP diff --git a/common/dbus/exception.hpp b/common/dbus/exception.hpp deleted file mode 100644 index 32cf87c..0000000 --- a/common/dbus/exception.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Piotr Bartosiewicz - * - * 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 - */ - -/** - * @file - * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Dbus exceptions - */ - - -#ifndef COMMON_DBUS_EXCEPTION_HPP -#define COMMON_DBUS_EXCEPTION_HPP - -#include "base-exception.hpp" - - -namespace security_containers { -namespace dbus { - - -/** - * Base class for dbus exceptions - */ -struct DbusException: public SecurityContainersException { - - DbusException(const std::string& error = "") : SecurityContainersException(error) {} -}; - -/** - * Dbus IO exception (connection failed, connection lost, etc) - */ -struct DbusIOException: public DbusException { - - DbusIOException(const std::string& error = "") : DbusException(error) {} -}; - -/** - * Dbus operation failed exception - */ -struct DbusOperationException: public DbusException { - - DbusOperationException(const std::string& error = "") : DbusException(error) {} -}; - -/** - * Dbus custom exception triggered by user logic - */ -struct DbusCustomException: public DbusException { - - DbusCustomException(const std::string& error = "") : DbusException(error) {} -}; - -/** - * Dbus invalid argument exception - */ -struct DbusInvalidArgumentException: public DbusException { - - DbusInvalidArgumentException(const std::string& error = "") : DbusException(error) {} -}; - - -} // namespace dbus -} // namespace security_containers - - -#endif // COMMON_DBUS_EXCEPTION_HPP diff --git a/common/libvirt/connection.cpp b/common/libvirt/connection.cpp index 12c906d..2fdaaa9 100644 --- a/common/libvirt/connection.cpp +++ b/common/libvirt/connection.cpp @@ -23,7 +23,7 @@ */ #include "config.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "libvirt/helpers.hpp" #include "libvirt/connection.hpp" #include "libvirt/exception.hpp" diff --git a/common/libvirt/domain.cpp b/common/libvirt/domain.cpp index 8b6bb98..d9e4217 100644 --- a/common/libvirt/domain.cpp +++ b/common/libvirt/domain.cpp @@ -23,7 +23,7 @@ */ #include "config.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "libvirt/domain.hpp" #include "libvirt/helpers.hpp" #include "libvirt/exception.hpp" diff --git a/common/libvirt/helpers.cpp b/common/libvirt/helpers.cpp index 7948a6a..8b096bb 100644 --- a/common/libvirt/helpers.cpp +++ b/common/libvirt/helpers.cpp @@ -24,7 +24,7 @@ #include "config.hpp" #include "libvirt/helpers.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include #include diff --git a/common/libvirt/network.cpp b/common/libvirt/network.cpp index 5384d9f..486ae63 100644 --- a/common/libvirt/network.cpp +++ b/common/libvirt/network.cpp @@ -24,7 +24,7 @@ #include "config.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "libvirt/network.hpp" #include "libvirt/helpers.hpp" #include "libvirt/exception.hpp" diff --git a/common/log/backend-journal.cpp b/common/log/backend-journal.cpp deleted file mode 100644 index 859d546..0000000 --- a/common/log/backend-journal.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Dariusz Michaluk - * - * 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 - */ - -/** - * @file - * @author Dariusz Michaluk (d.michaluk@samsung.com) - * @brief Systemd journal backend for logger - */ - -#include "config.hpp" -#include "log/backend-journal.hpp" - -#define SD_JOURNAL_SUPPRESS_LOCATION -#include - -namespace security_containers { -namespace log { - -namespace { - -inline int toJournalPriority(LogLevel logLevel) -{ - switch (logLevel) { - case LogLevel::ERROR: - return LOG_ERR; // 3 - case LogLevel::WARN: - return LOG_WARNING; // 4 - case LogLevel::INFO: - return LOG_INFO; // 6 - case LogLevel::DEBUG: - return LOG_DEBUG; // 7 - case LogLevel::TRACE: - return LOG_DEBUG; // 7 - default: - return LOG_DEBUG; - } -} - -} // namespace - -void SystemdJournalBackend::log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) -{ - sd_journal_send("PRIORITY=%d", toJournalPriority(logLevel), - "CODE_FILE=%s", file.c_str(), - "CODE_LINE=%d", line, - "CODE_FUNC=%s", func.c_str(), - "MESSAGE=%s", message.c_str(), - NULL); -} - -} // namespace log -} // namespace security_containers - diff --git a/common/log/backend-journal.hpp b/common/log/backend-journal.hpp deleted file mode 100644 index f040d9a..0000000 --- a/common/log/backend-journal.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Dariusz Michaluk - * - * 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 - */ - -/** - * @file - * @author Dariusz Michaluk (d.michaluk@samsung.com) - * @brief Systemd journal backend for logger - */ - -#ifndef COMMON_LOG_BACKEND_JOURNAL_HPP -#define COMMON_LOG_BACKEND_JOURNAL_HPP - -#include "log/backend.hpp" - - -namespace security_containers { -namespace log { - - -/** - systemd journal logging backend - */ -class SystemdJournalBackend : public LogBackend { -public: - void log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) override; -}; - - -} // namespace log -} // namespace security_containers - - -#endif // COMMON_LOG_BACKEND_JOURNAL_HPP diff --git a/common/log/backend-null.hpp b/common/log/backend-null.hpp deleted file mode 100644 index 7a26344..0000000 --- a/common/log/backend-null.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Pawel Broda - * - * 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 - */ - -/** - * @file - * @author Pawel Broda (p.broda@partner.samsung.com) - * @brief Null backend for logger - */ - - -#ifndef COMMON_LOG_BACKEND_NULL_HPP -#define COMMON_LOG_BACKEND_NULL_HPP - -#include "log/backend.hpp" - - -namespace security_containers { -namespace log { - - -/** - Null logging backend - */ -class NullLogger : public LogBackend { -public: - void log(LogLevel /*logLevel*/, - const std::string& /*file*/, - const unsigned int& /*line*/, - const std::string& /*func*/, - const std::string& /*message*/) override {} -}; - - -} // namespace log -} // namespace security_containers - - -#endif // COMMON_LOG_BACKEND_NULL_HPP diff --git a/common/log/backend-stderr.cpp b/common/log/backend-stderr.cpp deleted file mode 100644 index 471106c..0000000 --- a/common/log/backend-stderr.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Pawel Broda - * - * 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 - */ - -/** - * @file - * @author Pawel Broda (p.broda@partner.samsung.com) - * @brief Stderr backend for logger - */ - -#include "config.hpp" -#include "log/backend-stderr.hpp" -#include "log/formatter.hpp" - -#include - -namespace security_containers { -namespace log { - -void StderrBackend::log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) -{ - typedef boost::char_separator charSeparator; - typedef boost::tokenizer tokenizer; - - // example log string - // 06:52:35.123 [ERROR] src/util/fs.cpp:43 readFileContent: /file/file.txt is missing - - const std::string logColor = LogFormatter::getConsoleColor(logLevel); - const std::string defaultColor = LogFormatter::getDefaultConsoleColor(); - const std::string header = LogFormatter::getHeader(logLevel, file, line, func); - tokenizer tokens(message, charSeparator("\n")); - for (const auto& messageLine : tokens) { - if (!messageLine.empty()) { - fprintf(stderr, - "%s%s%s%s\n", - logColor.c_str(), - header.c_str(), - messageLine.c_str(), - defaultColor.c_str()); - } - } -} - - -} // namespace log -} // namespace security_containers - diff --git a/common/log/backend-stderr.hpp b/common/log/backend-stderr.hpp deleted file mode 100644 index c60d523..0000000 --- a/common/log/backend-stderr.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Pawel Broda - * - * 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 - */ - -/** - * @file - * @author Pawel Broda (p.broda@partner.samsung.com) - * @brief Stderr backend for logger - */ - -#ifndef COMMON_LOG_BACKEND_STDERR_HPP -#define COMMON_LOG_BACKEND_STDERR_HPP - -#include "log/backend.hpp" - - -namespace security_containers { -namespace log { - - -/** - Stderr logging backend - */ -class StderrBackend : public LogBackend { -public: - void log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) override; -}; - - -} // namespace log -} // namespace security_containers - - -#endif // COMMON_LOG_BACKEND_STDERR_HPP diff --git a/common/log/backend.hpp b/common/log/backend.hpp deleted file mode 100644 index adad533..0000000 --- a/common/log/backend.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Pawel Broda - * - * 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 - */ - -/** - * @file - * @author Pawel Broda (p.broda@partner.samsung.com) - * @brief Logging backend - */ - - -#ifndef COMMON_LOG_BACKEND_HPP -#define COMMON_LOG_BACKEND_HPP - -#include "log/level.hpp" - -#include - -namespace security_containers { -namespace log { - - -/** - Abstract class for logger - */ -class LogBackend { -public: - virtual void log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) = 0; - virtual ~LogBackend() {} -}; - - -} // namespace log -} // namespace security_containers - - -#endif // COMMON_LOG_BACKEND_HPP diff --git a/common/log/ccolor.cpp b/common/log/ccolor.cpp deleted file mode 100644 index 128f11f..0000000 --- a/common/log/ccolor.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Dariusz Michaluk - * - * 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 - */ - -/** - * @file - * @author Dariusz Michaluk (d.michaluk@samsung.com) - * @brief Console color for StderrBackend logger - */ - -#include "config.hpp" -#include "log/ccolor.hpp" - -#include - -namespace security_containers { -namespace log { - -std::string getConsoleEscapeSequence(Attributes attr, Color color) -{ - char command[10]; - - // Command is the control command to the terminal - snprintf(command, sizeof(command), "%c[%d;%dm", 0x1B, attr, color); - return std::string(command); -} - -} // namespace log -} // namespace security_containers - diff --git a/common/log/ccolor.hpp b/common/log/ccolor.hpp deleted file mode 100644 index dc37458..0000000 --- a/common/log/ccolor.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Dariusz Michaluk - * - * 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 - */ - -/** - * @file - * @author Dariusz Michaluk (d.michaluk@samsung.com) - * @brief Console color for StderrBackend logger - */ - -#ifndef COMMON_LOG_CCOLOR_HPP -#define COMMON_LOG_CCOLOR_HPP - -#include - -namespace security_containers { -namespace log { - -enum class Color : unsigned int { - DEFAULT = 0, - BLACK = 90, - RED = 91, - GREEN = 92, - YELLOW = 93, - BLUE = 94, - MAGENTA = 95, - CYAN = 96, - WHITE = 97 -}; - -enum class Attributes : unsigned int { - DEFAULT = 0, - BOLD = 1 -}; - -std::string getConsoleEscapeSequence(Attributes attr, Color color); - -} // namespace log -} // namespace security_containers - -#endif // COMMON_LOG_CCOLOR_HPP - diff --git a/common/log/formatter.cpp b/common/log/formatter.cpp deleted file mode 100644 index 100a8eb..0000000 --- a/common/log/formatter.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Dariusz Michaluk - * - * 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 - */ - -/** - * @file - * @author Dariusz Michaluk (d.michaluk@samsung.com) - * @brief Helper formatter for logger - */ - -#include "config.hpp" -#include "log/formatter.hpp" -#include "log/ccolor.hpp" - -#include -#include -#include -#include -#include -#include - -namespace security_containers { -namespace log { - -namespace { - -const int TIME_COLUMN_LENGTH = 12; -const int SEVERITY_COLUMN_LENGTH = 8; -const int THREAD_COLUMN_LENGTH = 3; -const int FILE_COLUMN_LENGTH = 60; - -std::atomic gNextThreadId(1); -thread_local unsigned int gThisThreadId(0); - -} // namespace - -unsigned int LogFormatter::getCurrentThread(void) -{ - unsigned int id = gThisThreadId; - if (id == 0) { - gThisThreadId = id = gNextThreadId++; - } - - return id; -} - -std::string LogFormatter::getCurrentTime(void) -{ - char time[TIME_COLUMN_LENGTH + 1]; - struct timeval tv; - gettimeofday(&tv, NULL); - struct tm* tm = localtime(&tv.tv_sec); - snprintf(time, - sizeof(time), - "%02d:%02d:%02d.%03d", - tm->tm_hour, - tm->tm_min, - tm->tm_sec, - int(tv.tv_usec / 1000)); - - return std::string(time); -} - -std::string LogFormatter::getConsoleColor(LogLevel logLevel) -{ - switch (logLevel) { - case LogLevel::ERROR: - return getConsoleEscapeSequence(Attributes::BOLD, Color::RED); - case LogLevel::WARN: - return getConsoleEscapeSequence(Attributes::BOLD, Color::YELLOW); - case LogLevel::INFO: - return getConsoleEscapeSequence(Attributes::BOLD, Color::BLUE); - case LogLevel::DEBUG: - return getConsoleEscapeSequence(Attributes::DEFAULT, Color::GREEN); - case LogLevel::TRACE: - return getConsoleEscapeSequence(Attributes::DEFAULT, Color::BLACK); - default: - return getConsoleEscapeSequence(Attributes::DEFAULT, Color::DEFAULT); - } -} - -std::string LogFormatter::getDefaultConsoleColor(void) -{ - return getConsoleEscapeSequence(Attributes::DEFAULT, Color::DEFAULT); -} - -std::string LogFormatter::stripProjectDir(const std::string& file) -{ - const std::string SOURCE_DIR = PROJECT_SOURCE_DIR "/"; - // it will work until someone use in cmake FILE(GLOB ... RELATIVE ...) - assert(0 == file.compare(0, SOURCE_DIR.size(), SOURCE_DIR)); - return file.substr(SOURCE_DIR.size()); -} - -std::string LogFormatter::getHeader(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func) -{ - std::ostringstream logLine; - logLine << getCurrentTime() << ' ' - << std::left << std::setw(SEVERITY_COLUMN_LENGTH) << '[' + toString(logLevel) + ']' - << std::right << std::setw(THREAD_COLUMN_LENGTH) << getCurrentThread() << ": " - << std::left << std::setw(FILE_COLUMN_LENGTH) - << file + ':' + std::to_string(line) + ' ' + func + ':'; - return logLine.str(); -} - -} // namespace log -} // namespace security_containers diff --git a/common/log/formatter.hpp b/common/log/formatter.hpp deleted file mode 100644 index 7f83ebe..0000000 --- a/common/log/formatter.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Dariusz Michaluk - * - * 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 - */ - -/** - * @file - * @author Dariusz Michaluk (d.michaluk@samsung.com) - * @brief Helper formatter for logger - */ - -#ifndef COMMON_LOG_FORMATTER_HPP -#define COMMON_LOG_FORMATTER_HPP - -#include "log/level.hpp" - -#include - -namespace security_containers { -namespace log { - -class LogFormatter { -public: - static unsigned int getCurrentThread(void); - static std::string getCurrentTime(void); - static std::string getConsoleColor(LogLevel logLevel); - static std::string getDefaultConsoleColor(void); - static std::string stripProjectDir(const std::string& file); - static std::string getHeader(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func); -}; - -} // namespace log -} // namespace security_containers - -#endif // COMMON_LOG_FORMATTER_HPP - diff --git a/common/log/level.cpp b/common/log/level.cpp deleted file mode 100644 index 3897726..0000000 --- a/common/log/level.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Jan Olszak - * - * 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 - */ - -/** - * @file - * @author Jan Olszak (j.olszak@samsung.com) - * @brief Functions to handle LogLevel - */ - -#include "config.hpp" - -#include "log/level.hpp" - -#include -#include - -namespace security_containers { -namespace log { - -LogLevel parseLogLevel(const std::string& level) -{ - if (boost::iequals(level, "ERROR")) { - return LogLevel::ERROR; - } else if (boost::iequals(level, "WARN")) { - return LogLevel::WARN; - } else if (boost::iequals(level, "INFO")) { - return LogLevel::INFO; - } else if (boost::iequals(level, "DEBUG")) { - return LogLevel::DEBUG; - } else if (boost::iequals(level, "TRACE")) { - return LogLevel::TRACE; - } else { - throw std::runtime_error("Invalid LogLevel to parse"); - } -} - -std::string toString(const LogLevel logLevel) -{ - switch (logLevel) { - case LogLevel::ERROR: - return "ERROR"; - case LogLevel::WARN: - return "WARN"; - case LogLevel::INFO: - return "INFO"; - case LogLevel::DEBUG: - return "DEBUG"; - case LogLevel::TRACE: - return "TRACE"; - default: - return "UNKNOWN"; - } -} -} // namespace log -} // namespace security_containers diff --git a/common/log/level.hpp b/common/log/level.hpp deleted file mode 100644 index 6a54cda..0000000 --- a/common/log/level.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Dariusz Michaluk (d.michaluk@samsung.com) - * - * 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 - */ - -/** - * @file - * @author Dariusz Michaluk (d.michaluk@samsung.com) - * @brief LogLevel - */ - -#ifndef COMMON_LOG_LEVEL_HPP -#define COMMON_LOG_LEVEL_HPP - -#include - - -namespace security_containers { -namespace log { - -enum class LogLevel { - TRACE, - DEBUG, - INFO, - WARN, - ERROR -}; - -/** - * @param logLevel LogLevel - * @return std::sting representation of the LogLevel value - */ -std::string toString(const LogLevel logLevel); - -/** - * @param level string representation of log level - * @return parsed LogLevel value - */ -LogLevel parseLogLevel(const std::string& level); - - -} // namespace log -} // namespace security_containers - -#endif // COMMON_LOG_LEVEL_HPP diff --git a/common/log/logger.cpp b/common/log/logger.cpp deleted file mode 100644 index 83298ed..0000000 --- a/common/log/logger.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Pawel Broda - * - * 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 - */ - -/** - * @file - * @author Pawel Broda (p.broda@partner.samsung.com) - * @brief Logger - */ - -#include "config.hpp" -#include "log/logger.hpp" -#include "log/formatter.hpp" -#include "log/backend-null.hpp" - -#include -#include - -namespace security_containers { -namespace log { - - -namespace { - -volatile LogLevel gLogLevel = LogLevel::DEBUG; -std::unique_ptr gLogBackendPtr(new NullLogger()); -std::mutex gLogMutex; - -} // namespace - -Logger::Logger(LogLevel logLevel, - const std::string& file, - const unsigned int line, - const std::string& func) - : mLogLevel(logLevel), - mFile(LogFormatter::stripProjectDir(file)), - mLine(line), - mFunc(func) -{ - -} - -void Logger::logMessage(const std::string& message) -{ - std::unique_lock lock(gLogMutex); - gLogBackendPtr->log(mLogLevel, mFile, mLine, mFunc, message); -} - -void Logger::setLogLevel(const LogLevel level) -{ - gLogLevel = level; -} - -void Logger::setLogLevel(const std::string& level) -{ - gLogLevel = parseLogLevel(level); -} - -LogLevel Logger::getLogLevel(void) -{ - return gLogLevel; -} - -void Logger::setLogBackend(LogBackend* pBackend) -{ - std::unique_lock lock(gLogMutex); - gLogBackendPtr.reset(pBackend); -} - -} // namespace log -} // namespace security_containers - diff --git a/common/log/logger.hpp b/common/log/logger.hpp deleted file mode 100644 index 45c5f26..0000000 --- a/common/log/logger.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Jan Olszak - * - * 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 - */ - -/** - * @file - * @author Jan Olszak (j.olszak@samsung.com) - * @brief Logger - */ - - -#ifndef COMMON_LOG_LOGGER_HPP -#define COMMON_LOG_LOGGER_HPP - -#include "log/level.hpp" - -#include -#include - - -namespace security_containers { -namespace log { - -class LogBackend; - -class Logger { -public: - Logger(LogLevel logLevel, - const std::string& file, - const unsigned int line, - const std::string& func); - - void logMessage(const std::string& message); - - static void setLogLevel(const LogLevel level); - static void setLogLevel(const std::string& level); - static LogLevel getLogLevel(void); - static void setLogBackend(LogBackend* pBackend); - -private: - LogLevel mLogLevel; - std::string mFile; - unsigned int mLine; - std::string mFunc; -}; - -} // namespace log -} // namespace security_containers - - -#define LOG(SEVERITY, MESSAGE) \ - do { \ - if (security_containers::log::Logger::getLogLevel() <= \ - security_containers::log::LogLevel::SEVERITY) { \ - std::ostringstream messageStream__; \ - messageStream__ << MESSAGE; \ - security_containers::log::Logger logger(security_containers::log::LogLevel::SEVERITY, \ - __FILE__, \ - __LINE__, \ - __func__); \ - logger.logMessage(messageStream__.str()); \ - } \ - } while(0) - -#define LOGE(MESSAGE) LOG(ERROR, MESSAGE) -#define LOGW(MESSAGE) LOG(WARN, MESSAGE) -#define LOGI(MESSAGE) LOG(INFO, MESSAGE) -#define LOGD(MESSAGE) LOG(DEBUG, MESSAGE) -#define LOGT(MESSAGE) LOG(TRACE, MESSAGE) - - -#endif // COMMON_LOG_LOGGER_HPP - diff --git a/common/utils/callback-guard.cpp b/common/utils/callback-guard.cpp index 3a35098..d8ee57c 100644 --- a/common/utils/callback-guard.cpp +++ b/common/utils/callback-guard.cpp @@ -24,7 +24,7 @@ #include "config.hpp" #include "utils/callback-guard.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include #include diff --git a/common/utils/environment.cpp b/common/utils/environment.cpp index b74983d..70ef27c 100644 --- a/common/utils/environment.cpp +++ b/common/utils/environment.cpp @@ -25,7 +25,7 @@ #include "config.hpp" #include "utils/environment.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include #include diff --git a/common/utils/fs.cpp b/common/utils/fs.cpp index 354e726..d663831 100644 --- a/common/utils/fs.cpp +++ b/common/utils/fs.cpp @@ -23,7 +23,7 @@ */ #include "config.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "utils/fs.hpp" #include "utils/paths.hpp" #include "utils/exception.hpp" diff --git a/container-daemon/CMakeLists.txt b/container-daemon/CMakeLists.txt index 238af6f..c264a38 100644 --- a/container-daemon/CMakeLists.txt +++ b/container-daemon/CMakeLists.txt @@ -31,7 +31,8 @@ ADD_EXECUTABLE(${CONTAINER_DAEMON_CODENAME} ${project_SRCS} ${common_SRCS}) ## Link libraries ############################################################## FIND_PACKAGE (Boost COMPONENTS program_options system filesystem) -PKG_CHECK_MODULES(CONTAINER_DAEMON_DEPS REQUIRED gio-2.0 libsystemd-journal libcap-ng) +PKG_CHECK_MODULES(CONTAINER_DAEMON_DEPS REQUIRED gio-2.0 libsystemd-journal libcap-ng + libLogger libSimpleDbus libConfig) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${CONTAINER_DAEMON_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) TARGET_LINK_LIBRARIES(${CONTAINER_DAEMON_CODENAME} ${CONTAINER_DAEMON_DEPS_LIBRARIES} ${Boost_LIBRARIES}) diff --git a/container-daemon/daemon-connection.cpp b/container-daemon/daemon-connection.cpp index 0eb6636..7f4d6b7 100644 --- a/container-daemon/daemon-connection.cpp +++ b/container-daemon/daemon-connection.cpp @@ -28,7 +28,7 @@ #include "daemon-dbus-definitions.hpp" #include "exception.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" namespace security_containers { diff --git a/container-daemon/daemon.cpp b/container-daemon/daemon.cpp index d79762f..6848a09 100644 --- a/container-daemon/daemon.cpp +++ b/container-daemon/daemon.cpp @@ -26,7 +26,7 @@ #include "daemon.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" namespace security_containers { diff --git a/container-daemon/main.cpp b/container-daemon/main.cpp index 8dcdbad..fde059a 100644 --- a/container-daemon/main.cpp +++ b/container-daemon/main.cpp @@ -33,15 +33,15 @@ #include "exception.hpp" #include "runner.hpp" -#include "log/logger.hpp" -#include "log/backend-stderr.hpp" -#include "log/backend-journal.hpp" +#include "logger/logger.hpp" +#include "logger/backend-stderr.hpp" +#include "logger/backend-journal.hpp" #include "utils/typeinfo.hpp" #include #include -using namespace security_containers::log; +using namespace logger; using namespace security_containers; namespace po = boost::program_options; diff --git a/container-daemon/runner.cpp b/container-daemon/runner.cpp index 13d3f21..7b5c93f 100644 --- a/container-daemon/runner.cpp +++ b/container-daemon/runner.cpp @@ -27,7 +27,7 @@ #include "runner.hpp" #include "daemon.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "utils/glib-loop.hpp" #include "utils/latch.hpp" diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index af4751c..f7a1bdb 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -18,6 +18,9 @@ BuildRequires: boost-devel BuildRequires: libvirt-devel BuildRequires: libjson-devel >= 0.10 BuildRequires: libcap-ng-devel +BuildRequires: pkgconfig(libConfig) +BuildRequires: pkgconfig(libLogger) +BuildRequires: pkgconfig(libSimpleDbus) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(libsystemd-journal) BuildRequires: pkgconfig(libvirt-glib-1.0) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 1e639cd..3293307 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -30,7 +30,7 @@ ADD_EXECUTABLE(${SERVER_CODENAME} ${project_SRCS} ${common_SRCS}) ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS program_options system filesystem regex) PKG_CHECK_MODULES(SERVER_DEPS REQUIRED libvirt libvirt-glib-1.0 json gio-2.0 libsystemd-journal - libcap-ng) + libcap-ng libLogger libSimpleDbus libConfig) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) diff --git a/server/container-admin.cpp b/server/container-admin.cpp index b624817..805e9c1 100644 --- a/server/container-admin.cpp +++ b/server/container-admin.cpp @@ -28,7 +28,7 @@ #include "exception.hpp" #include "libvirt/helpers.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "utils/fs.hpp" #include "utils/latch.hpp" #include "utils/callback-wrapper.hpp" diff --git a/server/container-connection-transport.cpp b/server/container-connection-transport.cpp index 9b8848d..b5bcfb5 100644 --- a/server/container-connection-transport.cpp +++ b/server/container-connection-transport.cpp @@ -29,7 +29,7 @@ #include "utils/file-wait.hpp" #include "utils/fs.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include #include diff --git a/server/container-connection.cpp b/server/container-connection.cpp index 0e96bb2..d3098aa 100644 --- a/server/container-connection.cpp +++ b/server/container-connection.cpp @@ -30,7 +30,7 @@ // TODO: Switch to real power-manager dbus defs when they will be implemented in power-manager #include "fake-power-manager-dbus-definitions.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" namespace security_containers { diff --git a/server/container.cpp b/server/container.cpp index 4284fec..6fcaf77 100644 --- a/server/container.cpp +++ b/server/container.cpp @@ -25,8 +25,9 @@ #include "config.hpp" #include "container.hpp" +#include "base-exception.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "utils/paths.hpp" #include "config/manager.hpp" diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index 012a8f7..90a6cfc 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -32,9 +32,10 @@ #include "exception.hpp" #include "utils/paths.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "config/manager.hpp" #include "dbus/exception.hpp" +#include "utils/fs.hpp" #include #include diff --git a/server/host-connection.cpp b/server/host-connection.cpp index 83ba8f8..ae32de2 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -28,7 +28,7 @@ #include "host-dbus-definitions.hpp" #include "exception.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" namespace security_containers { diff --git a/server/input-monitor.cpp b/server/input-monitor.cpp index 13025a5..76dff29 100644 --- a/server/input-monitor.cpp +++ b/server/input-monitor.cpp @@ -28,7 +28,7 @@ #include "input-monitor.hpp" #include "exception.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "utils/exception.hpp" #include "utils/fs.hpp" #include "utils/callback-wrapper.hpp" diff --git a/server/main.cpp b/server/main.cpp index d84a850..bf3da84 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -33,15 +33,15 @@ #include "exception.hpp" #include "server.hpp" -#include "log/logger.hpp" -#include "log/backend-stderr.hpp" -#include "log/backend-journal.hpp" +#include "logger/logger.hpp" +#include "logger/backend-stderr.hpp" +#include "logger/backend-journal.hpp" #include "utils/typeinfo.hpp" #include #include -using namespace security_containers::log; +using namespace logger; using namespace security_containers; namespace po = boost::program_options; diff --git a/server/network-admin.cpp b/server/network-admin.cpp index 38f9b07..763dec0 100644 --- a/server/network-admin.cpp +++ b/server/network-admin.cpp @@ -28,7 +28,7 @@ #include "exception.hpp" #include "libvirt/helpers.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "utils/fs.hpp" #include diff --git a/server/server.cpp b/server/server.cpp index c2fae7d..5c3420d 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -29,9 +29,10 @@ #include "exception.hpp" #include "config/manager.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include "utils/glib-loop.hpp" #include "utils/environment.hpp" +#include "utils/fs.hpp" #include #include diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 30d309b..a82075c 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -35,7 +35,7 @@ ADD_EXECUTABLE(${UT_SERVER_CODENAME} ${project_SRCS} ${common_SRCS} ${server_SRC FIND_PACKAGE (Boost COMPONENTS unit_test_framework system filesystem regex) PKG_CHECK_MODULES(UT_SERVER_DEPS REQUIRED libvirt libvirt-glib-1.0 json gio-2.0 - libsystemd-journal libcap-ng) + libsystemd-journal libcap-ng libLogger libSimpleDbus libConfig) INCLUDE_DIRECTORIES(${COMMON_FOLDER} ${SERVER_FOLDER} ${UNIT_TESTS_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${UT_SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) TARGET_LINK_LIBRARIES(${UT_SERVER_CODENAME} ${UT_SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES}) diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp index 5417e5f..7d304db 100644 --- a/tests/unit_tests/config/ut-configuration.cpp +++ b/tests/unit_tests/config/ut-configuration.cpp @@ -28,8 +28,7 @@ #include "config/fields.hpp" #include "config/manager.hpp" -using namespace security_containers; -using namespace security_containers::config; +using namespace config; BOOST_AUTO_TEST_SUITE(ConfigurationSuite) diff --git a/tests/unit_tests/dbus/test-server.cpp b/tests/unit_tests/dbus/test-server.cpp index 3a77390..bdbda8b 100644 --- a/tests/unit_tests/dbus/test-server.cpp +++ b/tests/unit_tests/dbus/test-server.cpp @@ -29,7 +29,7 @@ #include "dbus/connection.hpp" #include "dbus/exception.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" namespace security_containers { diff --git a/tests/unit_tests/dbus/ut-connection.cpp b/tests/unit_tests/dbus/ut-connection.cpp index 21be1e8..18d4f7b 100644 --- a/tests/unit_tests/dbus/ut-connection.cpp +++ b/tests/unit_tests/dbus/ut-connection.cpp @@ -35,7 +35,7 @@ #include "utils/file-wait.hpp" #include "utils/latch.hpp" #include "utils/fs.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include #include @@ -47,7 +47,7 @@ BOOST_AUTO_TEST_SUITE(DbusSuite) using namespace security_containers; using namespace security_containers::utils; -using namespace security_containers::dbus; +using namespace dbus; namespace { diff --git a/tests/unit_tests/log/ut-logger.cpp b/tests/unit_tests/log/ut-logger.cpp index b4aeb5d..e574505 100644 --- a/tests/unit_tests/log/ut-logger.cpp +++ b/tests/unit_tests/log/ut-logger.cpp @@ -25,16 +25,16 @@ #include "config.hpp" #include "ut.hpp" -#include "log/logger.hpp" -#include "log/formatter.hpp" -#include "log/backend.hpp" -#include "log/backend-stderr.hpp" +#include "logger/logger.hpp" +#include "logger/formatter.hpp" +#include "logger/backend.hpp" +#include "logger/backend-stderr.hpp" #include BOOST_AUTO_TEST_SUITE(LogSuite) -using namespace security_containers::log; +using namespace logger; namespace { diff --git a/tests/unit_tests/server/ut-container-connection.cpp b/tests/unit_tests/server/ut-container-connection.cpp index 29dd310..1a2d153 100644 --- a/tests/unit_tests/server/ut-container-connection.cpp +++ b/tests/unit_tests/server/ut-container-connection.cpp @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_SUITE(ContainerConnectionSuite) using namespace security_containers; using namespace security_containers::utils; -using namespace security_containers::dbus; +using namespace dbus; namespace { diff --git a/tests/unit_tests/server/ut-container.cpp b/tests/unit_tests/server/ut-container.cpp index 7b65c95..e636276 100644 --- a/tests/unit_tests/server/ut-container.cpp +++ b/tests/unit_tests/server/ut-container.cpp @@ -40,7 +40,7 @@ using namespace security_containers; -using namespace security_containers::config; +using namespace config; namespace { diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index b3ce809..e8dc5de 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -52,9 +52,9 @@ #include using namespace security_containers; -using namespace security_containers::config; +using namespace config; using namespace security_containers::utils; -using namespace security_containers::dbus; +using namespace dbus; namespace { @@ -332,7 +332,7 @@ std::function expectedMessage(const std::string& me } struct Fixture { - utils::ScopedGlibLoop mLoop; + security_containers::utils::ScopedGlibLoop mLoop; }; } // namespace diff --git a/tests/unit_tests/server/ut-server.cpp b/tests/unit_tests/server/ut-server.cpp index d7393b7..74bcede 100644 --- a/tests/unit_tests/server/ut-server.cpp +++ b/tests/unit_tests/server/ut-server.cpp @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_SUITE(ServerSuite) using namespace security_containers; -using namespace security_containers::config; +using namespace config; const std::string TEST_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-server/test-daemon.conf"; const std::string BUGGY_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-server/buggy-daemon.conf"; diff --git a/tests/unit_tests/ut.cpp b/tests/unit_tests/ut.cpp index de98558..194dc9e 100644 --- a/tests/unit_tests/ut.cpp +++ b/tests/unit_tests/ut.cpp @@ -25,14 +25,14 @@ #include "config.hpp" -#include "log/logger.hpp" -#include "log/backend-stderr.hpp" +#include "logger/logger.hpp" +#include "logger/backend-stderr.hpp" #include using namespace boost::unit_test; -using namespace security_containers::log; +using namespace logger; test_suite* init_unit_test_suite(int /*argc*/, char** /*argv*/) { diff --git a/tests/unit_tests/utils/scoped-daemon.cpp b/tests/unit_tests/utils/scoped-daemon.cpp index 077e19a..21fea83 100644 --- a/tests/unit_tests/utils/scoped-daemon.cpp +++ b/tests/unit_tests/utils/scoped-daemon.cpp @@ -26,7 +26,7 @@ #include "utils/scoped-daemon.hpp" -#include "log/logger.hpp" +#include "logger/logger.hpp" #include #include -- 2.7.4 From 33c6ad7cbdfe563979889b201f3397f7e38ed60b Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Tue, 5 Aug 2014 18:00:00 +0200 Subject: [PATCH 09/16] Tests of the dynamic configuration in libConfig [Bug/Feature] Dynamic configuration stored in a database [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I112701773ec555bca0521871e2066d84d727a00b --- packaging/security-containers.spec | 1 + tests/unit_tests/config/ut-kvstore.cpp | 178 +++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 tests/unit_tests/config/ut-kvstore.cpp diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index f7a1bdb..30914b0 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -24,6 +24,7 @@ BuildRequires: pkgconfig(libSimpleDbus) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(libsystemd-journal) BuildRequires: pkgconfig(libvirt-glib-1.0) +BuildRequires: pkgconfig(sqlite3) Requires: libvirt-daemon >= 1.2.4 Requires(post): libcap-tools diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp new file mode 100644 index 0000000..26abf76 --- /dev/null +++ b/tests/unit_tests/config/ut-kvstore.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak + * + * 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 + */ + + +/** + * @file + * @author Jan Olszak (j.olszak@samsung.com) + * @brief Unit test of KVStore class + */ + +#include "config.hpp" +#include "ut.hpp" + +#include "config/kvstore.hpp" +#include "config/exception.hpp" + +#include +#include + +using namespace config; +namespace fs = boost::filesystem; + +namespace { + +struct Fixture { + std::string dbPath; + KVStore c; + + Fixture() + : dbPath(fs::unique_path("/tmp/kvstore-%%%%.db3").string()), + c(dbPath) + { + } + ~Fixture() + { + fs::remove(dbPath); + } +}; +} // namespace + +BOOST_FIXTURE_TEST_SUITE(KVStoreSuite, Fixture) + +const std::string KEY = "KEY"; + +BOOST_AUTO_TEST_CASE(SimpleConstructorDestructorTest) +{ + const std::string dbPath = fs::unique_path("/tmp/kvstore-%%%%.db3").string(); + std::unique_ptr conPtr; + BOOST_REQUIRE_NO_THROW(conPtr.reset(new KVStore(dbPath))); + BOOST_CHECK(fs::exists(dbPath)); + BOOST_REQUIRE_NO_THROW(conPtr.reset(new KVStore(dbPath))); + BOOST_CHECK(fs::exists(dbPath)); + BOOST_REQUIRE_NO_THROW(conPtr.reset()); + BOOST_CHECK(fs::exists(dbPath)); + fs::remove(dbPath); +} + +BOOST_AUTO_TEST_CASE(SingleValueTest) +{ + // Set + BOOST_CHECK_NO_THROW(c.set(KEY, "A")); + BOOST_CHECK_EQUAL(c.get(KEY), "A"); + + // Update + BOOST_CHECK_NO_THROW(c.set(KEY, "B")); + BOOST_CHECK_EQUAL(c.get(KEY), "B"); + BOOST_CHECK_EQUAL(c.count(KEY), 1); + + // Remove + BOOST_CHECK_NO_THROW(c.remove(KEY)); + BOOST_CHECK_EQUAL(c.count(KEY), 0); + BOOST_CHECK_THROW(c.get(KEY), ConfigException); +} + +BOOST_AUTO_TEST_CASE(EscapedCharactersTest) +{ + // '*' ?' '[' ']' are escaped + // They shouldn't influence the internal implementation + std::string HARD_KEY = "[" + KEY; + BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A")); + BOOST_CHECK_NO_THROW(c.set(KEY, "B")); + BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1); + BOOST_CHECK_EQUAL(c.count(KEY), 1); + BOOST_CHECK_EQUAL(c.size(), 2); + BOOST_CHECK_NO_THROW(c.clear()); + + HARD_KEY = "]" + KEY; + BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A")); + BOOST_CHECK_NO_THROW(c.set(KEY, "B")); + BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1); + BOOST_CHECK_EQUAL(c.count(KEY), 1); + BOOST_CHECK_EQUAL(c.size(), 2); + BOOST_CHECK_NO_THROW(c.clear()); + + HARD_KEY = "?" + KEY; + BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A")); + BOOST_CHECK_NO_THROW(c.set(KEY, "B")); + BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1); + BOOST_CHECK_EQUAL(c.count(KEY), 1); + BOOST_CHECK_EQUAL(c.size(), 2); + BOOST_CHECK_NO_THROW(c.clear()); + + HARD_KEY = "*" + KEY; + BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A")); + BOOST_CHECK_NO_THROW(c.set(KEY, "B")); + BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1); + BOOST_CHECK_EQUAL(c.count(KEY), 1); + BOOST_CHECK_EQUAL(c.size(), 2); +} + +BOOST_AUTO_TEST_CASE(VectorOfValuesTest) +{ + std::vector AB = {"A", "B"}; + std::vector AC = {"A", "C"}; + std::vector ABC = {"A", "B", "C"}; + + // Set + BOOST_CHECK_NO_THROW(c.set(KEY, AB)); + BOOST_CHECK(c.list(KEY) == AB); + BOOST_CHECK_EQUAL(c.count(KEY), 2); + BOOST_CHECK_EQUAL(c.size(), 2); + + + // Update + BOOST_CHECK_NO_THROW(c.set(KEY, AC)); + BOOST_CHECK(c.list(KEY) == AC); + BOOST_CHECK_EQUAL(c.count(KEY), 2); + BOOST_CHECK_EQUAL(c.size(), 2); + + // Update + BOOST_CHECK_NO_THROW(c.set(KEY, ABC)); + BOOST_CHECK(c.list(KEY) == ABC); + BOOST_CHECK_EQUAL(c.count(KEY), 3); + BOOST_CHECK_EQUAL(c.size(), 3); + + // Update + BOOST_CHECK_NO_THROW(c.set(KEY, AC)); + BOOST_CHECK(c.list(KEY) == AC); + BOOST_CHECK_EQUAL(c.count(KEY), 2); + BOOST_CHECK_EQUAL(c.size(), 2); + + // Remove + BOOST_CHECK_NO_THROW(c.remove(KEY)); + BOOST_CHECK_EQUAL(c.count(KEY), 0); + BOOST_CHECK_EQUAL(c.size(), 0); + BOOST_CHECK_THROW(c.list(KEY), ConfigException); + BOOST_CHECK_THROW(c.get(KEY), ConfigException); +} + +BOOST_AUTO_TEST_CASE(ClearTest) +{ + BOOST_CHECK_NO_THROW(c.clear()); + + BOOST_CHECK_NO_THROW(c.set(KEY, {"A", "B"})); + BOOST_CHECK_NO_THROW(c.clear()); + BOOST_CHECK_EQUAL(c.size(), 0); + + BOOST_CHECK_NO_THROW(c.remove(KEY)); + BOOST_CHECK_THROW(c.list(KEY), ConfigException); + BOOST_CHECK_THROW(c.get(KEY), ConfigException); +} + +BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 75ea538d1b5d0b9b5cbeff208f5d43cea89aaa75 Mon Sep 17 00:00:00 2001 From: Jacek Pielaszkiewicz Date: Fri, 27 Jun 2014 13:12:34 +0200 Subject: [PATCH 10/16] Add libvirt network filter support to security-containers [Feature] libvirt network filters implementation [Cause] N/A [Solution] - It was assumed that network filters are defined per container. - A new parameter networkFilterConfig has been added to the container config file. - Unit test have been updated due to a new configuration parameter in the container confg file. - "Network integration" tests for security-containers have been implemented. The tests assume that in the environment are two containers (Buisness and Private). Both of them are mutually isolated and both have the Internet access. [Verification] Build, install, run tests Signed-off-by: Jacek Pielaszkiewicz Change-Id: Ibc08d85c1a362119fb71d80f66184a5c67b5c721 --- common/libvirt/network-filter.cpp | 81 ++++++ common/libvirt/network-filter.hpp | 67 +++++ common/libvirt/network.hpp | 1 - server/configs/containers/business.conf | 1 + server/configs/containers/private.conf | 1 + server/configs/libvirt-config/business-network.xml | 5 +- .../configs/libvirt-config/business-nwfilter.xml | 8 + server/configs/libvirt-config/business.xml | 1 + server/configs/libvirt-config/private-network.xml | 5 +- server/configs/libvirt-config/private-nwfilter.xml | 8 + server/configs/libvirt-config/private.xml | 1 + server/container-config.hpp | 7 + server/container.cpp | 2 + server/network-admin.cpp | 2 + server/network-admin.hpp | 2 + tests/integration_tests/CMakeLists.txt | 1 + tests/integration_tests/__init__.py | 1 + .../integration_tests/network_tests/CMakeLists.txt | 26 ++ tests/integration_tests/network_tests/__init__.py | 4 + .../network_tests/network_common.py | 297 +++++++++++++++++++++ .../network_tests/network_tests.py | 65 +++++ tests/integration_tests/sc_int_tests.py | 4 +- tests/unit_tests/libvirt/network.cpp | 23 ++ .../ut-container-admin/containers/buggy.conf.in | 1 + .../ut-container-admin/containers/missing.conf | 1 + .../containers/test-no-shutdown.conf.in | 1 + .../ut-container-admin/containers/test.conf.in | 1 + .../configs/ut-container/containers/buggy.conf | 1 + .../configs/ut-container/containers/test-dbus.conf | 1 + .../configs/ut-container/containers/test.conf | 1 + .../ut-container/libvirt-config/network-filter.xml | 4 + .../ut-container/libvirt-config/test-dbus.xml.in | 1 + .../configs/ut-container/libvirt-config/test.xml | 1 + .../containers/console1-dbus.conf | 1 + .../ut-containers-manager/containers/console1.conf | 1 + .../containers/console2-dbus.conf | 1 + .../ut-containers-manager/containers/console2.conf | 1 + .../containers/console3-dbus.conf | 1 + .../ut-containers-manager/containers/console3.conf | 1 + .../libvirt-config/console1.xml | 1 + .../libvirt-config/console2.xml | 1 + .../libvirt-config/console3.xml | 1 + .../libvirt-config/network1-filter.xml | 3 + .../libvirt-config/network2-filter.xml | 3 + .../libvirt-config/network3-filter.xml | 3 + .../ut-network-admin/containers/buggy.conf.in | 1 + .../ut-network-admin/containers/missing.conf | 1 + .../ut-network-admin/containers/test.conf.in | 1 + .../libvirt-config/buggy-network-filter.xml | 1 + .../libvirt-config/network-filter.xml | 4 + .../configs/ut-server/containers/container1.conf | 1 + .../configs/ut-server/containers/container2.conf | 1 + .../configs/ut-server/containers/container3.conf | 1 + .../ut-server/libvirt-config/container1.xml | 1 + .../ut-server/libvirt-config/container2.xml | 1 + .../ut-server/libvirt-config/container3.xml | 1 + .../ut-server/libvirt-config/network1-filter.xml | 3 + .../ut-server/libvirt-config/network2-filter.xml | 3 + .../ut-server/libvirt-config/network3-filter.xml | 3 + 59 files changed, 661 insertions(+), 6 deletions(-) create mode 100644 common/libvirt/network-filter.cpp create mode 100644 common/libvirt/network-filter.hpp create mode 100644 server/configs/libvirt-config/business-nwfilter.xml create mode 100644 server/configs/libvirt-config/private-nwfilter.xml create mode 100644 tests/integration_tests/network_tests/CMakeLists.txt create mode 100644 tests/integration_tests/network_tests/__init__.py create mode 100755 tests/integration_tests/network_tests/network_common.py create mode 100644 tests/integration_tests/network_tests/network_tests.py create mode 100644 tests/unit_tests/server/configs/ut-container/libvirt-config/network-filter.xml create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network1-filter.xml create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network2-filter.xml create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network3-filter.xml create mode 100644 tests/unit_tests/server/configs/ut-network-admin/libvirt-config/buggy-network-filter.xml create mode 100644 tests/unit_tests/server/configs/ut-network-admin/libvirt-config/network-filter.xml create mode 100644 tests/unit_tests/server/configs/ut-server/libvirt-config/network1-filter.xml create mode 100644 tests/unit_tests/server/configs/ut-server/libvirt-config/network2-filter.xml create mode 100644 tests/unit_tests/server/configs/ut-server/libvirt-config/network3-filter.xml diff --git a/common/libvirt/network-filter.cpp b/common/libvirt/network-filter.cpp new file mode 100644 index 0000000..94fd96d --- /dev/null +++ b/common/libvirt/network-filter.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak + * + * 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 + */ + +/** + * @file + * @author Jan Olszak (j.olszak@samsung.com) + * @brief Implementation of the class wrapping libvirt network + */ + +#include "config.hpp" + +#include "logger/logger.hpp" +#include "libvirt/network-filter.hpp" +#include "libvirt/helpers.hpp" +#include "libvirt/exception.hpp" + + +namespace security_containers { +namespace libvirt { + +LibvirtNWFilter::LibvirtNWFilter(const std::string& configXML) + : mCon(LIBVIRT_LXC_ADDRESS), mNetFilter(nullptr), + mDetachOnExit(false) +{ + mNetFilter = virNWFilterDefineXML(mCon.get(), configXML.c_str()); + + if (mNetFilter == nullptr) { + LOGE("Error while definig a network filter:\n" + << libvirtFormatError()); + throw LibvirtOperationException(); + } +} + +LibvirtNWFilter::~LibvirtNWFilter() +{ + if (!mDetachOnExit) + { + if (virNWFilterUndefine(mNetFilter) < 0) { + LOGE("Error while undefining the network filter:\n" + << libvirtFormatError()); + } + } + + if (virNWFilterFree(mNetFilter) < 0) { + LOGE("Error while destroying the network filter object:\n" + << libvirtFormatError()); + } +} + +void LibvirtNWFilter::setDetachOnExit() +{ + mDetachOnExit = true; +} + +virNWFilterPtr LibvirtNWFilter::get() +{ + return mNetFilter; +} + +LibvirtNWFilter::operator bool() const +{ + return mNetFilter != nullptr; +} + +} // namespace libvirt +} // namespace security_containers diff --git a/common/libvirt/network-filter.hpp b/common/libvirt/network-filter.hpp new file mode 100644 index 0000000..ad6d8c4 --- /dev/null +++ b/common/libvirt/network-filter.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak + * + * 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 + */ + +/** + * @file + * @author Jan Olszak (j.olszak@samsung.com) + * @brief Declaration of the class wrapping libvirt network + */ + +#ifndef COMMON_LIBVIRT_NETWORK_FILTER_HPP +#define COMMON_LIBVIRT_NETWORK_FILTER_HPP + +#include "libvirt/connection.hpp" + +#include + + +namespace security_containers { +namespace libvirt { + +class LibvirtNWFilter { + +public: + LibvirtNWFilter(const std::string& configXML); + ~LibvirtNWFilter(); + + /** + * @return The libvirt network pointer + */ + virNWFilterPtr get(); + + /** + * @return libvirt network pointer is not NULL + */ + operator bool() const; + + /** + * Set whether container should be detached on exit. + */ + void setDetachOnExit(); + +private: + LibvirtConnection mCon; + virNWFilterPtr mNetFilter; + bool mDetachOnExit; +}; + +} // namespace libvirt +} // namespace security_containers + + +#endif // COMMON_LIBVIRT_NETWORK_FILTER_HPP diff --git a/common/libvirt/network.hpp b/common/libvirt/network.hpp index 92a73da..26e3b0a 100644 --- a/common/libvirt/network.hpp +++ b/common/libvirt/network.hpp @@ -55,7 +55,6 @@ private: virNetworkPtr mNet; }; - } // namespace libvirt } // namespace security_containers diff --git a/server/configs/containers/business.conf b/server/configs/containers/business.conf index f16ccb4..1b711b4 100644 --- a/server/configs/containers/business.conf +++ b/server/configs/containers/business.conf @@ -5,6 +5,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/business.xml", "networkConfig" : "../libvirt-config/business-network.xml", + "networkFilterConfig" : "../libvirt-config/business-nwfilter.xml", "runMountPoint" : "business/run", "permittedToSend" : [ "/tmp/.*" ], "permittedToRecv" : [ "/tmp/.*" ] diff --git a/server/configs/containers/private.conf b/server/configs/containers/private.conf index cde88c3..a981caf 100644 --- a/server/configs/containers/private.conf +++ b/server/configs/containers/private.conf @@ -5,6 +5,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/private.xml", "networkConfig" : "../libvirt-config/private-network.xml", + "networkFilterConfig" : "../libvirt-config/private-nwfilter.xml", "runMountPoint" : "private/run", "permittedToSend" : [ "/tmp/.*" ], "permittedToRecv" : [ "/tmp/.*" ] diff --git a/server/configs/libvirt-config/business-network.xml b/server/configs/libvirt-config/business-network.xml index 1cc7eeb..beb5c80 100644 --- a/server/configs/libvirt-config/business-network.xml +++ b/server/configs/libvirt-config/business-network.xml @@ -3,9 +3,10 @@ cc0951f9-3397-4272-ae05-66c19229accf - + + - + diff --git a/server/configs/libvirt-config/business-nwfilter.xml b/server/configs/libvirt-config/business-nwfilter.xml new file mode 100644 index 0000000..ea7453e --- /dev/null +++ b/server/configs/libvirt-config/business-nwfilter.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/server/configs/libvirt-config/business.xml b/server/configs/libvirt-config/business.xml index deaf000..c2539e9 100644 --- a/server/configs/libvirt-config/business.xml +++ b/server/configs/libvirt-config/business.xml @@ -99,6 +99,7 @@ + diff --git a/server/configs/libvirt-config/private-network.xml b/server/configs/libvirt-config/private-network.xml index 76add2c..f917b52 100644 --- a/server/configs/libvirt-config/private-network.xml +++ b/server/configs/libvirt-config/private-network.xml @@ -3,9 +3,10 @@ 5b25f83d-ccb6-45f0-9d5c-c05199c261bd - + + - + diff --git a/server/configs/libvirt-config/private-nwfilter.xml b/server/configs/libvirt-config/private-nwfilter.xml new file mode 100644 index 0000000..f3bd8ca --- /dev/null +++ b/server/configs/libvirt-config/private-nwfilter.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/server/configs/libvirt-config/private.xml b/server/configs/libvirt-config/private.xml index 532cd76..d6ce465 100644 --- a/server/configs/libvirt-config/private.xml +++ b/server/configs/libvirt-config/private.xml @@ -99,6 +99,7 @@ + diff --git a/server/container-config.hpp b/server/container-config.hpp index f5f202e..e679abb 100644 --- a/server/container-config.hpp +++ b/server/container-config.hpp @@ -60,6 +60,12 @@ struct ContainerConfig { std::string networkConfig; /** + * + * Container's libvirt (XML) network filter config file. + */ + std::string networkFilterConfig; + + /** * Container's CFS quota in us when it's in the foreground */ std::int64_t cpuQuotaForeground; @@ -92,6 +98,7 @@ struct ContainerConfig { switchToDefaultAfterTimeout, config, networkConfig, + networkFilterConfig, cpuQuotaForeground, cpuQuotaBackground, runMountPoint, diff --git a/server/container.cpp b/server/container.cpp index 6fcaf77..62b2c65a 100644 --- a/server/container.cpp +++ b/server/container.cpp @@ -66,6 +66,8 @@ Container::Container(const std::string& containerConfigPath, const std::string baseConfigPath = utils::dirName(containerConfigPath); mConfig.config = fs::absolute(mConfig.config, baseConfigPath).string(); mConfig.networkConfig = fs::absolute(mConfig.networkConfig, baseConfigPath).string(); + mConfig.networkFilterConfig = fs::absolute(mConfig.networkFilterConfig, + baseConfigPath).string(); if (!mConfig.runMountPoint.empty()) { mRunMountPoint = fs::absolute(mConfig.runMountPoint, baseRunMountPointPath).string(); } diff --git a/server/network-admin.cpp b/server/network-admin.cpp index 763dec0..6553d62 100644 --- a/server/network-admin.cpp +++ b/server/network-admin.cpp @@ -57,6 +57,7 @@ std::string getNetworkName(virNetworkPtr net) NetworkAdmin::NetworkAdmin(const ContainerConfig& config) : mConfig(config), + mNWFilter(utils::readFileContent(mConfig.networkFilterConfig)), mNetwork(utils::readFileContent(mConfig.networkConfig)), mId(getNetworkName(mNetwork.get())), mDetachOnExit(false) @@ -143,6 +144,7 @@ bool NetworkAdmin::isActive() void NetworkAdmin::setDetachOnExit() { mDetachOnExit = true; + mNWFilter.setDetachOnExit(); } diff --git a/server/network-admin.hpp b/server/network-admin.hpp index 8ddb883..0ec3a74 100644 --- a/server/network-admin.hpp +++ b/server/network-admin.hpp @@ -28,6 +28,7 @@ #include "container-config.hpp" +#include "libvirt/network-filter.hpp" #include "libvirt/network.hpp" @@ -69,6 +70,7 @@ public: private: const ContainerConfig& mConfig; + libvirt::LibvirtNWFilter mNWFilter; libvirt::LibvirtNetwork mNetwork; const std::string mId; bool mDetachOnExit; diff --git a/tests/integration_tests/CMakeLists.txt b/tests/integration_tests/CMakeLists.txt index 3f96c47..c0289c3 100644 --- a/tests/integration_tests/CMakeLists.txt +++ b/tests/integration_tests/CMakeLists.txt @@ -38,3 +38,4 @@ INSTALL(PROGRAMS ${main_SCRIPT} DESTINATION ${SCRIPT_INSTALL_DIR}) ## Subdirectories ############################################################## ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(image_tests) +ADD_SUBDIRECTORY(network_tests) diff --git a/tests/integration_tests/__init__.py b/tests/integration_tests/__init__.py index 731d042..634cfe6 100644 --- a/tests/integration_tests/__init__.py +++ b/tests/integration_tests/__init__.py @@ -1,3 +1,4 @@ __all__ = ["common", + "network_tests", "image_tests" ] diff --git a/tests/integration_tests/network_tests/CMakeLists.txt b/tests/integration_tests/network_tests/CMakeLists.txt new file mode 100644 index 0000000..374c8c1 --- /dev/null +++ b/tests/integration_tests/network_tests/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2014 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. +# +# +# @file CMakeLists.txt +# @author Jacek Pielaszkiewicz (j.pielaszkie@samsung.com) +# + +MESSAGE(STATUS "Including network tests to Integration Tests...") + +SET(TEST_NETWORK_DEST_DIR "${TEST_DEST_DIR}/network_tests") + +FILE(GLOB net_test_SCRIPTS *.py) + +INSTALL(FILES ${net_test_SCRIPTS} DESTINATION ${TEST_NETWORK_DEST_DIR}) diff --git a/tests/integration_tests/network_tests/__init__.py b/tests/integration_tests/network_tests/__init__.py new file mode 100644 index 0000000..a41c5d7 --- /dev/null +++ b/tests/integration_tests/network_tests/__init__.py @@ -0,0 +1,4 @@ +__all__ = ["network_common", + "network_tests" + ] + diff --git a/tests/integration_tests/network_tests/network_common.py b/tests/integration_tests/network_tests/network_common.py new file mode 100755 index 0000000..2b64920 --- /dev/null +++ b/tests/integration_tests/network_tests/network_common.py @@ -0,0 +1,297 @@ +#Copyright (c) 2014 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. +# +# @file network_common.py.in +# @author Jacek Pielaszkiewicz (j.pielaszkie@samsung.com) +# + +from sc_integration_tests.common import sc_test_utils +import subprocess +import string +import sys +import os + +# Debug command on/off +DEBUG_COMMAND=False + +# Test urls +TEST_URL_INTERNET=["www.samsung.com", "www.google.com", "www.oracle.com"] + +# Path to test container +TEST_CONTAINER_PATH="/opt/usr/containers/private" + +# Device Ethernet device +ETHERNET_DEVICE="usb0" +ETHERNET_DEVICE_DETECT=False + +# Test containers +CONTAINER_T1="business" +CONTAINER_T2="private" + +containers=[CONTAINER_T1, CONTAINER_T2] + +# Null device +OUTPUT_TO_NULL_DEVICE=" >/dev/null 2>&1 " + +# Ping timeout +PING_TIME_OUT=3 + +# The calss store test cases results +class TestNetworkInfo: + testName = "" + testItemType = [] + testItemName = [] + testItemStatus = [] + testItemResult = [] + testItemDescription = [] + + def __init__(self, tn): + self.testName = tn + +# ---------------------------------------------------------- +# Functions print info/error/warning message +# +def LOG_INFO(arg): + print("[Info] " + arg) + +def LOG_ERROR(arg): + print("[Error] " + arg) + +def LOG_WARNING(arg): + print("[Warning] " + arg) + +def LOG_DEBUG(arg): + print("[Debug] " + arg) + +# ---------------------------------------------------------- +# The function tests mandatory user privileges +# +def test_run_user(): + if(os.getegid() != 0 or os.geteuid() != 0): + return 1 + return 0 + +# ---------------------------------------------------------- +# The function runs os command +# +def runCommand(cmd, blockDebug=False): + null_device_str = OUTPUT_TO_NULL_DEVICE + if(DEBUG_COMMAND): + null_device_str = "" + + run_cmd = "( " + cmd + " ) " + null_device_str + + rc=0 + try: + out=sc_test_utils.launchProc(run_cmd) + except Exception: + rc=1 + + if(DEBUG_COMMAND and not blockDebug): + LOG_DEBUG("[DEBUG CMD] RC = " + str(rc) + "; CMD = " + run_cmd) + + return rc + +# ---------------------------------------------------------- +# The function runs os command and read output +# +def runCommandAndReadOutput(cmd): + proc=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + while(True): + # Return code + rcode=proc.poll() + + # Get line + ret=proc.stdout.readline() + ret=ret.translate(None, "\n") + + # Ignore empty lines + if(ret != ""): + yield ret + + # Test return code + if(rcode is not None): + break + +# ---------------------------------------------------------- +# The function checks whether test container image is present in system +# +def test_guest_image(): + rc = runCommand("/usr/bin/chroot " + TEST_CONTAINER_PATH + " /bin/true") + if( rc != 0 ): + return 1 + return 0 + +# ---------------------------------------------------------- +# The functions gets active ethernet device +# +def getActiveEthernetDevice(): + cmd=["/usr/sbin/ip -o link | /usr/bin/awk \' /ether/ { split( $2, list, \":\" ); print list[1] }\'"] + iter = runCommandAndReadOutput(cmd) + for val in iter: + ETHERNET_DEVICE=val + + if(ETHERNET_DEVICE == ""): + return 1 + + return 0 + +# ---------------------------------------------------------- +# The function checks whether mandatory tools are present in +# the system +# +def test_mandatory_toos(): + + tools =["/usr/bin/ping"] + root_tools=[TEST_CONTAINER_PATH] + + for i in range(len(tools)): + rc = runCommand("/usr/bin/ls " + root_tools[i] + tools[i]) + if( rc != 0 ): + if( root_tools[i] != "" ): + LOG_ERROR("No " + tools[i] + " command in guest") + else: + LOG_ERROR("No " + tools[i] + " command in host") + return 1 + return 0 + +def virshCmd(args): + return runCommand("/usr/bin/virsh -c lxc:/// " + args) + +# ---------------------------------------------------------- +# The function tests single test case result +# +def test_result(expected_result, result): + if((expected_result >= 0 and result == expected_result) or (expected_result < 0 and result != 0)): + return 0 + return 1 + +# ---------------------------------------------------------- +# The function performs single internet access test +# +def internetAccessTest(container): + count=0 + for item in TEST_URL_INTERNET: + LOG_INFO(" Test for URL : " + item); + rc = virshCmd("lxc-enter-namespace " + container + \ + " --noseclabel -- /usr/bin/ping -c 3 -W " + \ + str(PING_TIME_OUT) + " " + item) + if(rc != 0): + count = count + 1 + + if(count != 0): + return 1 + + return 0; + +# ---------------------------------------------------------- +# The function performs single internet access test +# +def networkVisibiltyTest(container, dest_ip): + return virshCmd("lxc-enter-namespace " + container + \ + " --noseclabel -- /usr/bin/ping -c 3 -W " + \ + str(PING_TIME_OUT) + " " + dest_ip) + +def printInternetAccessTestStatus(container, testInfo1): + + text = " Internet access for container: " + container + \ + "; TCS = " + testInfo1.testItemResult[len(testInfo1.testItemResult)-1] + + if(testInfo1.testItemResult[len(testInfo1.testItemResult)-1] == "Success"): + LOG_INFO(text) + else: + LOG_ERROR(text) + +def networkVisibiltyTestStatus(src, dest, ip, testInfo2): + + text = " Container access: " + src + \ + " -> " + dest + \ + " [" + ip + "]" + \ + "; TCS = " + testInfo2.testItemResult[len(testInfo2.testItemResult)-1] + + if(testInfo2.testItemResult[len(testInfo2.testItemResult)-1] == "Success"): + LOG_INFO(text) + else: + LOG_ERROR(text) + +# ---------------------------------------------------------- +# The function performs test case for two containers - Business and Private. +# Both containers are mutually isolated and have access to the Internet. +# +def twoNetworks(): + ltestInfo = TestNetworkInfo("Two networks tests") + + # 0. Test data + containers_list = [CONTAINER_T1, CONTAINER_T2] + dest_containers_list = [CONTAINER_T2, CONTAINER_T1] + test_ip_list = [["192.168.101.2"], ["192.168.102.2"]] + test_1_expected_res = [ 0, 0] + test_2_expected_res = [-1, -1] + + # 1. Enable internet access for both networks + LOG_INFO(" - Setup device") + + # 2. Internet access + LOG_INFO(" - Two containers environment network test case execution") + LOG_INFO(" - Internet access test") + for i in range(len(containers_list)): + + # - Test case info + ltestInfo.testItemType.append("[Two nets] Internet access") + ltestInfo.testItemName.append(containers_list[i]) + ltestInfo.testItemDescription.append("Internet access test for : " + containers_list[i]) + + # - Perform test + rc = internetAccessTest(containers_list[i]) + + # - Test status store + if(test_result(test_1_expected_res[i], rc) == 0): + ltestInfo.testItemStatus.append(0) + ltestInfo.testItemResult.append("Success") + else: + ltestInfo.testItemStatus.append(1) + ltestInfo.testItemResult.append("Error") + + # - Print status + printInternetAccessTestStatus(containers_list[i], ltestInfo) + + # 3. Mutual containers visibility + LOG_INFO(" - Containers isolation") + for i in range(len(containers_list)): + # Interate over destynation ips + dest_ips = test_ip_list[i] + + for j in range(len(dest_ips)): + # - Test case info + ltestInfo.testItemType.append("[Two nets] Visibility") + ltestInfo.testItemName.append(containers_list[i] + "->" + dest_containers_list[i]) + ltestInfo.testItemDescription.append("Container access for : " + containers_list[i]) + + # Perform test + rc = networkVisibiltyTest(containers_list[i], dest_ips[j]) + + # - Test status store + if(test_result(test_2_expected_res[i], rc) == 0): + ltestInfo.testItemStatus.append(0) + ltestInfo.testItemResult.append("Success") + else: + ltestInfo.testItemStatus.append(1) + ltestInfo.testItemResult.append("Error") + + # - Print status + networkVisibiltyTestStatus(containers_list[i], dest_containers_list[i], dest_ips[j], ltestInfo) + + LOG_INFO(" - Clean environment") + + return ltestInfo diff --git a/tests/integration_tests/network_tests/network_tests.py b/tests/integration_tests/network_tests/network_tests.py new file mode 100644 index 0000000..bd118a2 --- /dev/null +++ b/tests/integration_tests/network_tests/network_tests.py @@ -0,0 +1,65 @@ +#Copyright (c) 2014 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. +# +# @file network_tests.py +# @author Jacek Pielaszkiewicz (j.pielaszkie@samsung.com) +# + +'''! Module used to test network in containers + +@author: Jacek Pielaszkiewicz (j.pielaszkie@samsung.com) +''' +import unittest +from sc_integration_tests.common import sc_test_utils +from network_common import * + +class NetworkTestCase(unittest.TestCase): + '''! Test case to check network configuration + ''' + def setUp(self): + # Function setup host machine to perform tests + # + # 1. Check user permisions + if(test_run_user() == 1): + self.assertTrue(False, "ROOT user is required to run the test") + return + + # 2. Test container images + if(test_guest_image() == 1): + self.assertTrue(False, "No test container in path :" + TEST_CONTAINER_PATH) + return + + # 3. Test mandatory tools + if(test_mandatory_toos() == 1): + self.assertTrue(False, "No mandatory tools on host or in guest") + return + + # 4. Ethernet device obtaning + if(ETHERNET_DEVICE_DETECT and getActiveEthernetDevice() == 1): + self.assertTrue(False, "Cannot obtain ethernet device") + return + + def test_01twoNetworks(self): + '''! Checks networks configuration + ''' + print("\n") + ret=twoNetworks() + for item in ret.testItemStatus: + self.assertTrue(item == 0) + +def main(): + unittest.main(verbosity=2) + +if __name__ == "__main__": + main() diff --git a/tests/integration_tests/sc_int_tests.py b/tests/integration_tests/sc_int_tests.py index 42e2812..60d1ed3 100644 --- a/tests/integration_tests/sc_int_tests.py +++ b/tests/integration_tests/sc_int_tests.py @@ -5,12 +5,14 @@ Security-containers integration tests launcher. Launches all integration tests. ''' import unittest +from sc_integration_tests.network_tests import * from sc_integration_tests.image_tests import * # add tests here... test_groups = [ - image_tests + image_tests, + network_tests ] diff --git a/tests/unit_tests/libvirt/network.cpp b/tests/unit_tests/libvirt/network.cpp index 09adcc8..b158ecd 100644 --- a/tests/unit_tests/libvirt/network.cpp +++ b/tests/unit_tests/libvirt/network.cpp @@ -26,6 +26,7 @@ #include "config.hpp" #include "ut.hpp" +#include "libvirt/network-filter.hpp" #include "libvirt/network.hpp" #include "libvirt/exception.hpp" @@ -56,12 +57,27 @@ const std::string CORRECT_CONFIG_XML = "" " " ""; +const std::string CORRECT_CONFIG_FILTER_XML = "" + " " + " " + " " + " " + " " + " " + ""; + const std::string BUGGY_CONFIG_XML = "<>"; +const std::string BUGGY_CONFIG_FILTER_XML = "<> nwFilterPtr; + BOOST_REQUIRE_NO_THROW(nwFilterPtr.reset(new LibvirtNWFilter(CORRECT_CONFIG_FILTER_XML))); + BOOST_REQUIRE_NO_THROW(nwFilterPtr.reset()); + std::unique_ptr netPtr; BOOST_REQUIRE_NO_THROW(netPtr.reset(new LibvirtNetwork(CORRECT_CONFIG_XML))); BOOST_REQUIRE_NO_THROW(netPtr.reset()); @@ -69,17 +85,24 @@ BOOST_AUTO_TEST_CASE(ConstructorDestructorTest) BOOST_AUTO_TEST_CASE(BuggyConfigTest) { + BOOST_REQUIRE_THROW(LibvirtNWFilter filter(BUGGY_CONFIG_FILTER_XML), LibvirtOperationException); BOOST_REQUIRE_THROW(LibvirtNetwork net(BUGGY_CONFIG_XML), LibvirtOperationException); } BOOST_AUTO_TEST_CASE(DefinitionTest) { + LibvirtNWFilter filter(CORRECT_CONFIG_FILTER_XML); + BOOST_CHECK(filter.get() != NULL); + LibvirtNetwork net(CORRECT_CONFIG_XML); BOOST_CHECK(net.get() != NULL); } BOOST_AUTO_TEST_CASE(BoolTest) { + LibvirtNWFilter filter(CORRECT_CONFIG_FILTER_XML); + BOOST_CHECK(filter); + LibvirtNetwork net(CORRECT_CONFIG_XML); BOOST_CHECK(net); } diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in index 341052b..9ebef78 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/buggy.xml", "networkConfig" : "", + "networkFilterConfig" : "", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf b/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf index 7ac04e9..1943228 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "/this/is/a/missing/file/path/missing.xml", "networkConfig" : "", + "networkFilterConfig" : "", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in index 8f4da35..2360ac6 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/test-no-shutdown.xml", "networkConfig" : "", + "networkFilterConfig" : "", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in index badc3da..52da12a 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/test.xml", "networkConfig" : "", + "networkFilterConfig" : "", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-container/containers/buggy.conf b/tests/unit_tests/server/configs/ut-container/containers/buggy.conf index 0dc866a..5f59a89 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/buggy.conf +++ b/tests/unit_tests/server/configs/ut-container/containers/buggy.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "/missing/file/path/libvirt.xml", "networkConfig" : "../libvirt-config/network.xml", + "networkFilterConfig" : "../libvirt-config/network-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf b/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf index bf35f07..f646f80 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf +++ b/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/test-dbus.xml", "networkConfig" : "../libvirt-config/network.xml", + "networkFilterConfig" : "../libvirt-config/network-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "/tmp/ut-container", diff --git a/tests/unit_tests/server/configs/ut-container/containers/test.conf b/tests/unit_tests/server/configs/ut-container/containers/test.conf index dc81e44..cfd08c4 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/test.conf +++ b/tests/unit_tests/server/configs/ut-container/containers/test.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/test.xml", "networkConfig" : "../libvirt-config/network.xml", + "networkFilterConfig" : "../libvirt-config/network-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-container/libvirt-config/network-filter.xml b/tests/unit_tests/server/configs/ut-container/libvirt-config/network-filter.xml new file mode 100644 index 0000000..fa1490e --- /dev/null +++ b/tests/unit_tests/server/configs/ut-container/libvirt-config/network-filter.xml @@ -0,0 +1,4 @@ + + 37ec6a98-a8f2-4033-8146-a71deb1f0008 + + diff --git a/tests/unit_tests/server/configs/ut-container/libvirt-config/test-dbus.xml.in b/tests/unit_tests/server/configs/ut-container/libvirt-config/test-dbus.xml.in index 555a9c6..d927f11 100644 --- a/tests/unit_tests/server/configs/ut-container/libvirt-config/test-dbus.xml.in +++ b/tests/unit_tests/server/configs/ut-container/libvirt-config/test-dbus.xml.in @@ -16,6 +16,7 @@ + diff --git a/tests/unit_tests/server/configs/ut-container/libvirt-config/test.xml b/tests/unit_tests/server/configs/ut-container/libvirt-config/test.xml index 4205758..a6bab81 100644 --- a/tests/unit_tests/server/configs/ut-container/libvirt-config/test.xml +++ b/tests/unit_tests/server/configs/ut-container/libvirt-config/test.xml @@ -12,6 +12,7 @@ + diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf index ef49f19..af3380b 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/console1-dbus.xml", "networkConfig" : "../libvirt-config/network1.xml", + "networkFilterConfig" : "../libvirt-config/network1-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "/tmp/ut-containers-manager/console1-dbus", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf index b26e02e..e7bcf3f 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/console1.xml", "networkConfig" : "../libvirt-config/network1.xml", + "networkFilterConfig" : "../libvirt-config/network1-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf index 76c5e49..0db0a8a 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : false, "config" : "../libvirt-config/console2-dbus.xml", "networkConfig" : "../libvirt-config/network2.xml", + "networkFilterConfig" : "../libvirt-config/network2-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "/tmp/ut-containers-manager/console2-dbus", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf index f609a85..9e0b7c5 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/console2.xml", "networkConfig" : "../libvirt-config/network2.xml", + "networkFilterConfig" : "../libvirt-config/network2-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf index 592cbfa..14a8a60 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/console3-dbus.xml", "networkConfig" : "../libvirt-config/network3.xml", + "networkFilterConfig" : "../libvirt-config/network3-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "/tmp/ut-containers-manager/console3-dbus", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf index e249df7..6ace25e 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/console3.xml", "networkConfig" : "../libvirt-config/network3.xml", + "networkFilterConfig" : "../libvirt-config/network3-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console1.xml b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console1.xml index 9ca7f5e..81ded84 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console1.xml +++ b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console1.xml @@ -12,6 +12,7 @@ + diff --git a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console2.xml b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console2.xml index ca8400a..90abf67 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console2.xml +++ b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console2.xml @@ -12,6 +12,7 @@ + diff --git a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console3.xml b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console3.xml index d3224ff..3c08bb2 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console3.xml +++ b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/console3.xml @@ -12,6 +12,7 @@ + diff --git a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network1-filter.xml b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network1-filter.xml new file mode 100644 index 0000000..df0befd --- /dev/null +++ b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network1-filter.xml @@ -0,0 +1,3 @@ + + 37ec6a98-a8f2-4033-8146-a71deb1f0003 + diff --git a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network2-filter.xml b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network2-filter.xml new file mode 100644 index 0000000..68d7dab --- /dev/null +++ b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network2-filter.xml @@ -0,0 +1,3 @@ + + 37ec6a98-a8f2-4033-8146-a71deb1f0002 + diff --git a/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network3-filter.xml b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network3-filter.xml new file mode 100644 index 0000000..5e44805 --- /dev/null +++ b/tests/unit_tests/server/configs/ut-containers-manager/libvirt-config/network3-filter.xml @@ -0,0 +1,3 @@ + + 37ec6a98-a8f2-4033-8146-a71deb1f0004 + diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in b/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in index 2b88e29..48d0ef8 100644 --- a/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in +++ b/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "", "networkConfig" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-network-admin/libvirt-config/buggy-network.xml", + "networkFilterConfig" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-network-admin/libvirt-config/buggy-network-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf b/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf index ca580a1..b60814d 100644 --- a/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf +++ b/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "", "networkConfig" : "", + "networkFilterConfig" : "", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in b/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in index 547c6cd..1dce4ea 100644 --- a/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in +++ b/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "", "networkConfig" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-network-admin/libvirt-config/network.xml", + "networkFilterConfig" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-network-admin/libvirt-config/network-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-network-admin/libvirt-config/buggy-network-filter.xml b/tests/unit_tests/server/configs/ut-network-admin/libvirt-config/buggy-network-filter.xml new file mode 100644 index 0000000..de0f81e --- /dev/null +++ b/tests/unit_tests/server/configs/ut-network-admin/libvirt-config/buggy-network-filter.xml @@ -0,0 +1 @@ +<> diff --git a/tests/unit_tests/server/configs/ut-network-admin/libvirt-config/network-filter.xml b/tests/unit_tests/server/configs/ut-network-admin/libvirt-config/network-filter.xml new file mode 100644 index 0000000..658c129 --- /dev/null +++ b/tests/unit_tests/server/configs/ut-network-admin/libvirt-config/network-filter.xml @@ -0,0 +1,4 @@ + + 37ec6a98-a8f2-4033-8146-a71deb1f0001 + + diff --git a/tests/unit_tests/server/configs/ut-server/containers/container1.conf b/tests/unit_tests/server/configs/ut-server/containers/container1.conf index f93690a..b0f523f 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container1.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container1.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/container1.xml", "networkConfig" : "../libvirt-config/network1.xml", + "networkFilterConfig" : "../libvirt-config/network1-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-server/containers/container2.conf b/tests/unit_tests/server/configs/ut-server/containers/container2.conf index f519018..8a1fde1 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container2.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container2.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/container2.xml", "networkConfig" : "../libvirt-config/network2.xml", + "networkFilterConfig" : "../libvirt-config/network2-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-server/containers/container3.conf b/tests/unit_tests/server/configs/ut-server/containers/container3.conf index 3c5989e..be23c63 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container3.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container3.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/container3.xml", "networkConfig" : "../libvirt-config/network3.xml", + "networkFilterConfig" : "../libvirt-config/network3-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "", diff --git a/tests/unit_tests/server/configs/ut-server/libvirt-config/container1.xml b/tests/unit_tests/server/configs/ut-server/libvirt-config/container1.xml index 8571df7..913168b 100644 --- a/tests/unit_tests/server/configs/ut-server/libvirt-config/container1.xml +++ b/tests/unit_tests/server/configs/ut-server/libvirt-config/container1.xml @@ -12,6 +12,7 @@ + diff --git a/tests/unit_tests/server/configs/ut-server/libvirt-config/container2.xml b/tests/unit_tests/server/configs/ut-server/libvirt-config/container2.xml index 23f7a76..904765e 100644 --- a/tests/unit_tests/server/configs/ut-server/libvirt-config/container2.xml +++ b/tests/unit_tests/server/configs/ut-server/libvirt-config/container2.xml @@ -12,6 +12,7 @@ + diff --git a/tests/unit_tests/server/configs/ut-server/libvirt-config/container3.xml b/tests/unit_tests/server/configs/ut-server/libvirt-config/container3.xml index 59ea557..569c592 100644 --- a/tests/unit_tests/server/configs/ut-server/libvirt-config/container3.xml +++ b/tests/unit_tests/server/configs/ut-server/libvirt-config/container3.xml @@ -12,6 +12,7 @@ + diff --git a/tests/unit_tests/server/configs/ut-server/libvirt-config/network1-filter.xml b/tests/unit_tests/server/configs/ut-server/libvirt-config/network1-filter.xml new file mode 100644 index 0000000..b1dc861 --- /dev/null +++ b/tests/unit_tests/server/configs/ut-server/libvirt-config/network1-filter.xml @@ -0,0 +1,3 @@ + + 37ec6a98-a8f2-4033-8146-a71deb1f0006 + diff --git a/tests/unit_tests/server/configs/ut-server/libvirt-config/network2-filter.xml b/tests/unit_tests/server/configs/ut-server/libvirt-config/network2-filter.xml new file mode 100644 index 0000000..45911ce --- /dev/null +++ b/tests/unit_tests/server/configs/ut-server/libvirt-config/network2-filter.xml @@ -0,0 +1,3 @@ + + 37ec6a98-a8f2-4033-8146-a71deb1f0005 + diff --git a/tests/unit_tests/server/configs/ut-server/libvirt-config/network3-filter.xml b/tests/unit_tests/server/configs/ut-server/libvirt-config/network3-filter.xml new file mode 100644 index 0000000..84416fb --- /dev/null +++ b/tests/unit_tests/server/configs/ut-server/libvirt-config/network3-filter.xml @@ -0,0 +1,3 @@ + + 37ec6a98-a8f2-4033-8146-a71deb1f0007 + -- 2.7.4 From 8309d8ec42b525919e65bc661734a7e008d5b8c9 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Mon, 4 Aug 2014 15:33:25 +0200 Subject: [PATCH 11/16] Client library with C interface [Feature] security-containers's client with c interface. [Cause] N/A [Solution] N/A [Verification] Build, install, run test suite Client Change-Id: Ic968e876806ce44751c95a9161ba8f497427aee8 --- client/CMakeLists.txt | 22 +- client/exception.hpp | 47 ---- client/main.cpp | 27 --- client/security-containers-client-impl.cpp | 236 +++++++++++++++++++++ client/security-containers-client-impl.hpp | 116 ++++++++++ client/security-containers-client.cpp | 137 ++++++++++++ client/security-containers-client.h | 145 ++++++++++++- tests/unit_tests/CMakeLists.txt | 6 +- tests/unit_tests/client/configs/CMakeLists.txt | 44 ++++ .../ut-client/containers/console1-dbus.conf | 11 + .../ut-client/containers/console2-dbus.conf | 11 + .../ut-client/containers/console3-dbus.conf | 11 + .../ut-client/libvirt-config/console1-dbus.xml.in | 15 ++ .../ut-client/libvirt-config/console2-dbus.xml.in | 15 ++ .../ut-client/libvirt-config/console3-dbus.xml.in | 15 ++ .../configs/ut-client/libvirt-config/network1.xml | 4 + .../configs/ut-client/libvirt-config/network2.xml | 4 + .../configs/ut-client/libvirt-config/network3.xml | 4 + .../client/configs/ut-client/test-dbus-daemon.conf | 20 ++ tests/unit_tests/client/ut-client.cpp | 119 +++++++++++ 20 files changed, 924 insertions(+), 85 deletions(-) delete mode 100644 client/exception.hpp delete mode 100644 client/main.cpp create mode 100644 client/security-containers-client-impl.cpp create mode 100644 client/security-containers-client-impl.hpp create mode 100644 client/security-containers-client.cpp create mode 100644 tests/unit_tests/client/configs/CMakeLists.txt create mode 100644 tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf create mode 100644 tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf create mode 100644 tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/console1-dbus.xml.in create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/console2-dbus.xml.in create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/console3-dbus.xml.in create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/network1.xml create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/network2.xml create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/network3.xml create mode 100644 tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf create mode 100644 tests/unit_tests/client/ut-client.cpp diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 8a34575..48cefea 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -14,26 +14,38 @@ # # # @file CMakeLists.txt -# @author Jan Olszak (j.olszak@samsung.com) +# @author Mateusz Malicki (m.malicki2@samsung.com) # MESSAGE(STATUS "Generating makefile for the Client...") -FILE(GLOB project_SRCS *.cpp *.hpp) -FILE(GLOB_RECURSE common_SRCS ${COMMON_FOLDER}/*.cpp ${COMMON_FOLDER}/*.hpp) +FILE(GLOB project_SRCS *.cpp *.hpp *.h) +FILE(GLOB common_SRCS ${COMMON_FOLDER}/utils/callback-guard.hpp + ${COMMON_FOLDER}/utils/callback-guard.cpp + ${COMMON_FOLDER}/utils/glib-loop.cpp + ${COMMON_FOLDER}/utils/glib-loop.hpp) SET(_LIB_VERSION_ "0.0.1") SET(_LIB_SOVERSION_ "0") SET(PC_FILE "${PROJECT_NAME}.pc") +## Set the default ELF image symbol visibility to hidden. Using this feature +## can very substantially improve linking and load times of shared object +## libraries, produce more optimized code, provide near-perfect API export +## and prevent symbol clashes +ADD_DEFINITIONS(-fvisibility=hidden) + ## Setup target ################################################################ -ADD_LIBRARY(${PROJECT_NAME} SHARED ${project_SRCS}) +ADD_LIBRARY(${PROJECT_NAME} SHARED ${project_SRCS} ${common_SRCS}) SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY SOVERSION ${_LIB_SOVERSION_}) SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY VERSION ${_LIB_VERSION_}) ## Link libraries ############################################################## +PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libSimpleDbus libLogger) +INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) - +INCLUDE_DIRECTORIES(${SERVER_FOLDER}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_DEPS_LIBRARIES}) ## Generate the pc file ######################################################## CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY) diff --git a/client/exception.hpp b/client/exception.hpp deleted file mode 100644 index b4420e8..0000000 --- a/client/exception.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Lukasz Pawelczyk - * - * 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 - */ - -/** - * @file - * @author Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com) - * @brief Exceptions for the client - */ - - -#ifndef CLIENT_EXCEPTION_HPP -#define CLIENT_EXCEPTION_HPP - -#include "base-exception.hpp" - - -namespace security_containers { - - -/** - * @brief Base class for exceptions in Security Containers Client - */ -struct ClientException: public SecurityContainersException { - - ClientException(const std::string& error = "") : SecurityContainersException(error) {} -}; - - -} - - -#endif // CLIENT_EXCEPTION_HPP diff --git a/client/main.cpp b/client/main.cpp deleted file mode 100644 index 1c02567..0000000 --- a/client/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Jan Olszak - * - * 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 - */ - -/** - * @file - * @author Jan Olszak (j.olszak@samsung.com) - * @brief Main file for the Security Containers Client - */ - -#include "config.hpp" - -#include "exception.hpp" diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp new file mode 100644 index 0000000..87c30f8 --- /dev/null +++ b/client/security-containers-client-impl.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * 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 + */ + + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief This file contains security-containers-server's client implementation + */ + +#include +#include "security-containers-client-impl.hpp" +#include +#include +#include +#include + +#include +#include +#include + +using namespace std; +using namespace dbus; +using namespace security_containers; +using namespace security_containers::utils; + +namespace { + +const string SCCLIENT_SUCCESS_MSG; +const string SCCLIENT_EXCEPTION_MSG = "unspecified exception"; + +const DbusInterfaceInfo hostDbusInterfaceInfo(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE); + +unique_ptr loop; + +void toDict(GVariant* in, ScArrayString* keys, ScArrayString* values) +{ + assert(in); + assert(keys); + assert(values); + + typedef char* key_type; + typedef char* value_type; + + GVariantIter iter; + value_type value; + key_type key; + gsize size = g_variant_n_children(in); + key_type* outk = (key_type*)calloc(size + 1, sizeof(key_type)); + value_type* outv = (value_type*)calloc(size + 1, sizeof(value_type)); + + g_variant_iter_init(&iter, in); + for (int i = 0; g_variant_iter_loop(&iter, "{ss}", &key, &value); i++) { + outk[i] = strdup(key); + outv[i] = strdup(value); + } + *keys = outk; + *values = outv; +} + +ScStatus toStatus(const std::exception& ex) +{ + if (typeid(DbusCustomException) == typeid(ex)) { + return SCCLIENT_DBUS_CUSTOM_EXCEPTION; + } else if (typeid(DbusIOException) == typeid(ex)) { + return SCCLIENT_DBUS_IO_EXCEPTION; + } else if (typeid(DbusOperationException) == typeid(ex)) { + return SCCLIENT_DBUS_OPERATION_EXCEPTION; + } else if (typeid(DbusInvalidArgumentException) == typeid(ex)) { + return SCCLIENT_DBUS_INVALID_ARGUMENT_EXCEPTION; + } else if (typeid(DbusException) == typeid(ex)) { + return SCCLIENT_DBUS_EXCEPTION; + } + return SCCLIENT_RUNTIME_EXCEPTION; +} + +} //namespace + +ScStatus Client::sc_start() noexcept +{ + try { + if (!loop) { + loop.reset(new ScopedGlibLoop()); + } + } catch (const exception& ex) { + return toStatus(ex); + } catch (...) { + return SCCLIENT_EXCEPTION; + } + + return SCCLIENT_SUCCESS; +} + +ScStatus Client::sc_stop() noexcept +{ + try { + if (loop) { + loop.reset(); + } + } catch (const exception& ex) { + return toStatus(ex); + } catch (...) { + return SCCLIENT_EXCEPTION; + } + return SCCLIENT_SUCCESS; +} + +Client::Status::Status(ScStatus status) + : mScStatus(status) +{ + switch (status) { + case SCCLIENT_EXCEPTION: + mMsg = SCCLIENT_EXCEPTION_MSG; + break; + case SCCLIENT_SUCCESS: + mMsg = SCCLIENT_SUCCESS_MSG; + break; + default: + assert(!"Logic error. You must specify a message."); + mMsg = std::string(); + } +} + +Client::Status::Status(ScStatus status, const std::string& msg) + : mScStatus(status), mMsg(msg) +{ +} + +Client::Client() noexcept + : mStatus(SCCLIENT_SUCCESS) +{ +} + +Client::~Client() noexcept +{ +} + +ScStatus Client::createSystem() noexcept +{ + try { + mConnection = DbusConnection::createSystem(); + mStatus = Status(SCCLIENT_SUCCESS); + } catch (const exception& ex) { + mStatus = Status(toStatus(ex), ex.what()); + } catch (...) { + mStatus = Status(SCCLIENT_EXCEPTION); + } + return sc_get_status(); +} + +ScStatus Client::create(const string& address) noexcept +{ + try { + mConnection = DbusConnection::create(address); + mStatus = Status(SCCLIENT_SUCCESS); + } catch (const exception& ex) { + mStatus = Status(toStatus(ex), ex.what()); + } catch (...) { + mStatus = Status(SCCLIENT_EXCEPTION); + } + return sc_get_status(); +} + +ScStatus Client::callMethod(const DbusInterfaceInfo& info, + const string& method, + GVariant* args_in, + const string& args_spec_out, + GVariant** args_out) +{ + try { + GVariantPtr ret = mConnection->callMethod(info.busName, + info.objectPath, + info.interface, + method, + args_in, + args_spec_out); + if (args_out != NULL) { + *args_out = ret.release(); + } + mStatus = Status(SCCLIENT_SUCCESS); + } catch (const exception& ex) { + mStatus = Status(toStatus(ex), ex.what()); + } catch (...) { + mStatus = Status(SCCLIENT_EXCEPTION); + } + return sc_get_status(); +} + +const char* Client::sc_get_status_message() noexcept +{ + return mStatus.mMsg.c_str(); +} + +ScStatus Client::sc_get_status() noexcept +{ + return mStatus.mScStatus; +} + +ScStatus Client::sc_get_container_dbuses(ScArrayString* keys, ScArrayString* values) noexcept +{ + assert(keys); + assert(values); + + GVariant* out; + ScStatus ret = callMethod(hostDbusInterfaceInfo, + api::host::METHOD_GET_CONTAINER_DBUSES, + NULL, + "(a{ss})", + &out); + if (ret != SCCLIENT_SUCCESS) { + return ret; + } + GVariant* unpacked; + g_variant_get(out, "(*)", &unpacked); + toDict(unpacked, keys, values); + g_variant_unref(unpacked); + g_variant_unref(out); + return ret; +} diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp new file mode 100644 index 0000000..f823cd1 --- /dev/null +++ b/client/security-containers-client-impl.hpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * 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 + */ + + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief This file contains security-containers-server's client definition + */ + +#ifndef SECURITY_CONTAINERS_CLIENT_IMPL_HPP +#define SECURITY_CONTAINERS_CLIENT_IMPL_HPP + +#include "security-containers-client.h" +#include +#include + +/** + * Structure which defines the dbus interface. + */ +struct DbusInterfaceInfo { + DbusInterfaceInfo(const std::string& busName, + const std::string& objectPath, + const std::string& interface) + : busName(busName), + objectPath(objectPath), + interface(interface) {} + const std::string busName; + const std::string objectPath; + const std::string interface; +}; + +/** + * security-containers's client definition. + * + * Client uses dbus API. + */ +class Client { +private: + struct Status { + Status(ScStatus status); + Status(ScStatus status, const std::string& msg); + ScStatus mScStatus; + std::string mMsg; + }; + + dbus::DbusConnection::Pointer mConnection; + Status mStatus; + + ScStatus callMethod(const DbusInterfaceInfo& info, + const std::string& method, + GVariant* args_in, + const std::string& args_spec_out = std::string(), + GVariant** args_out = NULL); + +public: + Client() noexcept; + ~Client() noexcept; + + /** + * Create client with system dbus address. + * + * @return Status of this function call. + */ + ScStatus createSystem() noexcept; + + /** + * Create client. + * + * @param address Dbus socket address. + * @return Status of this function call. + */ + ScStatus create(const std::string& address) noexcept; + + /** + * @see ::sc_get_status_message + */ + const char* sc_get_status_message() noexcept; + + /** + * @see ::sc_get_status + */ + ScStatus sc_get_status() noexcept; + + /** + * @see ::sc_get_container_dbuses + */ + ScStatus sc_get_container_dbuses(ScArrayString* keys, ScArrayString* values) noexcept; + + /** + * @see ::sc_start + */ + static ScStatus sc_start() noexcept; + + /** + * @see ::sc_stop + */ + static ScStatus sc_stop() noexcept; +}; + +#endif /* SECURITY_CONTAINERS_CLIENT_IMPL_HPP */ diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp new file mode 100644 index 0000000..572f166 --- /dev/null +++ b/client/security-containers-client.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * 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 + */ + + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief This file contains the public API for Security Containers Client + */ + +#include +#include "security-containers-client.h" +#include "security-containers-client-impl.hpp" + +#include +#include + +#ifndef API +#define API __attribute__((visibility("default"))) +#endif // API + +using namespace std; + +namespace { + +typedef Client* ClientPtr; + +ClientPtr getClient(ScClient client) +{ + assert(client); + return reinterpret_cast(client); +} + +} // namespace + +/* external */ +API ScStatus sc_start() +{ + return Client::sc_start(); +} + +API ScStatus sc_stop() +{ + return Client::sc_stop(); +} + +API ScStatus sc_get_client(ScClient* client, ScClientType type, ...) +{ + const char* address = NULL; + va_list vl; + va_start(vl, type); + if (type == SCCLIENT_CUSTOM_TYPE) { + address = va_arg(vl, const char*); + assert(address); + } + va_end(vl); + + assert(client); + Client* clientPtr = new(nothrow) Client(); + *client = reinterpret_cast(clientPtr); + if (clientPtr == NULL) { + return SCCLIENT_NOT_ENOUGH_MEMORY; + } + + ScStatus status; + switch (type) { + case SCCLIENT_CUSTOM_TYPE: + status = clientPtr->create(address); + break; + case SCCLIENT_SYSTEM_TYPE: + status = clientPtr->createSystem(); + break; + default: + assert(!"Logic error. No such ScClient type"); + status = SCCLIENT_EXCEPTION; + } + return status; +} + +API int sc_is_failed(ScStatus status) +{ + return status != SCCLIENT_SUCCESS ? 1 : 0; +} + +API void sc_array_string_free(ScArrayString astring) +{ + if (!astring) { + return; + } + for (char** ptr = astring; *ptr; ++ptr) { + sc_string_free(*ptr); + } + free(astring); +} + +API void sc_string_free(ScString string) +{ + free(string); +} + + +API void sc_client_free(ScClient client) +{ + if (client != NULL) { + delete getClient(client); + } +} + +API const char* sc_get_status_message(ScClient client) +{ + return getClient(client)->sc_get_status_message(); +} + +API ScStatus sc_get_status(ScClient client) +{ + return getClient(client)->sc_get_status(); +} + +API ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArrayString* values) +{ + return getClient(client)->sc_get_container_dbuses(keys, values); +} diff --git a/client/security-containers-client.h b/client/security-containers-client.h index b17b763..692df31 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved * - * Contact: Jan Olszak + * Contact: Mateusz Malicki * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,149 @@ /** - * @file security-containers-client.h - * @author Jan Olszak (j.olszak@samsung.com) + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) * @brief This file contains the public API for Security Containers Client */ #ifndef SECURITY_CONTAINERS_CLIENT_H #define SECURITY_CONTAINERS_CLIENT_H -#endif /*SECURITY_CONTAINERS_CLIENT_H*/ +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * security-containers-server's client + */ +typedef void* ScClient; + +/** + * String type. + * + * NULL-terminated string. + */ +typedef char* ScString; + +/** + * Array of strings type. + * + * Array are NULL-terminated. + */ +typedef ScString* ScArrayString; + +/** + * Completion status of communication function. + */ +typedef enum { + SCCLIENT_DBUS_CUSTOM_EXCEPTION, + SCCLIENT_DBUS_IO_EXCEPTION, + SCCLIENT_DBUS_OPERATION_EXCEPTION, + SCCLIENT_DBUS_INVALID_ARGUMENT_EXCEPTION, + SCCLIENT_DBUS_EXCEPTION, + SCCLIENT_NOT_ENOUGH_MEMORY, + SCCLIENT_RUNTIME_EXCEPTION, + SCCLIENT_EXCEPTION, + SCCLIENT_SUCCESS +} ScStatus; + +typedef enum { + SCCLIENT_SYSTEM_TYPE, + SCCLIENT_CUSTOM_TYPE +} ScClientType; + +/** + * Initialize communication resources. + */ +ScStatus sc_start(); + +/** + * Release communication resources. + * + * @return Status of this function call. + */ +ScStatus sc_stop(); + +/** + * Create a security-containers-server's client. + * + * After calling this function a connection to security-containers-server is established. + * + * @param[out] client security-containers-server's client who will be returned. + * Client can be broken. To check this you must call sc_is_failed(). + * Broken client can't be used to communicate with security-containers-server. + * @param[in] type Type of client. + * @param[in] @optional address Dbus socket address (significant only for type SCCLIENT_CUSTOM_TYPE). + * @return Status of this function call. + */ +ScStatus sc_get_client(ScClient* client, ScClientType type, /* const char* address */ ...); + +/** + * Release client resources. + * + * @param client security-containers-server's client. + */ +void sc_client_free(ScClient client); + +/** + * Get status message of the last security-containers-server communication. + * + * @param client security-containers-server's client. + * @return Last status message from security-containers-server communication. + */ +const char* sc_get_status_message(ScClient client); + +/** + * Get status code of last security-containers-server communication. + * + * @param client security-containers-server's client. + * @return Status of this function call. + */ +ScStatus sc_get_status(ScClient client); + +/** + * Check if security-containers-server communication function fail. + * + * @param status Value returned by security-containers-server communication function. + * @return 0 if succeeded otherwise 1. + */ +int sc_is_failed(ScStatus status); + +/** + * Release ScArrayString. + * + * @param astring ScArrayString. + */ +void sc_array_string_free(ScArrayString astring); + +/** + * Release ScString. + * + * @param string ScString. + */ +void sc_string_free(ScString string); + + +/************************************************************************************************* + * + * org.tizen.containers.host.manager interface + * + ************************************************************************************************/ + +/** + * Get dbus address of each container. + * + * @param[in] client security-containers-server's client. + * @param[out] keys Array of containers name. + * @param[out] values Array of containers dbus address. + * @return Status of this function call. + * @post keys[i] corresponds to values[i]. + */ +ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArrayString* values); + +#ifdef __cplusplus +} +#endif + +#endif /* SECRITY_CONTAINERS_CLIENT_H */ diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index a82075c..3bb265d 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -21,6 +21,7 @@ MESSAGE(STATUS "Generating makefile for the Unit Tests...") FILE(GLOB_RECURSE project_SRCS *.cpp *.hpp) FILE(GLOB_RECURSE common_SRCS ${COMMON_FOLDER}/*.cpp ${COMMON_FOLDER}/*.hpp) FILE(GLOB server_SRCS ${SERVER_FOLDER}/*.cpp ${SERVER_FOLDER}/*.hpp) +FILE(GLOB client_SRCS ${CLIENT_FOLDER}/*.cpp ${CLIENT_FOLDER}/*.h) FILE(GLOB main_SRC ${SERVER_FOLDER}/main.cpp) LIST(REMOVE_ITEM server_SRCS ${main_SRC}) @@ -28,7 +29,7 @@ LIST(REMOVE_ITEM server_SRCS ${main_SRC}) ## Setup target ################################################################ SET(UT_SERVER_CODENAME "${PROJECT_NAME}-server-unit-tests") -ADD_EXECUTABLE(${UT_SERVER_CODENAME} ${project_SRCS} ${common_SRCS} ${server_SRCS}) +ADD_EXECUTABLE(${UT_SERVER_CODENAME} ${project_SRCS} ${common_SRCS} ${server_SRCS} ${client_SRCS}) ## Link libraries ############################################################## @@ -36,7 +37,7 @@ FIND_PACKAGE (Boost COMPONENTS unit_test_framework system filesystem regex) PKG_CHECK_MODULES(UT_SERVER_DEPS REQUIRED libvirt libvirt-glib-1.0 json gio-2.0 libsystemd-journal libcap-ng libLogger libSimpleDbus libConfig) -INCLUDE_DIRECTORIES(${COMMON_FOLDER} ${SERVER_FOLDER} ${UNIT_TESTS_FOLDER}) +INCLUDE_DIRECTORIES(${COMMON_FOLDER} ${SERVER_FOLDER} ${UNIT_TESTS_FOLDER} ${CLIENT_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${UT_SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) TARGET_LINK_LIBRARIES(${UT_SERVER_CODENAME} ${UT_SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES}) @@ -48,6 +49,7 @@ ADD_DEFINITIONS(-DSC_TEST_CONFIG_INSTALL_DIR="${SC_TEST_CONFIG_INSTALL_DIR}") ADD_SUBDIRECTORY(dbus/configs) ADD_SUBDIRECTORY(server/configs) ADD_SUBDIRECTORY(utils/configs) +ADD_SUBDIRECTORY(client/configs) ## Install ##################################################################### diff --git a/tests/unit_tests/client/configs/CMakeLists.txt b/tests/unit_tests/client/configs/CMakeLists.txt new file mode 100644 index 0000000..112d979 --- /dev/null +++ b/tests/unit_tests/client/configs/CMakeLists.txt @@ -0,0 +1,44 @@ +# Copyright (c) 2014 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. +# +# +# @file CMakeLists.txt +# @author Mateusz Malicki (m.malicki2@samsung.com) +# + +MESSAGE(STATUS "Installing configs for the Client Unit Tests to " ${SC_CONFIG_INSTALL_DIR}) + +FILE(GLOB client_manager_CONF ut-client/*.conf) +FILE(GLOB client_container_CONF ut-client/containers/*.conf) +FILE(GLOB client_admin_CONF ut-client/libvirt-config/*.xml) + +## Generate #################################################################### +CONFIGURE_FILE(ut-client/libvirt-config/console1-dbus.xml.in + ${CMAKE_BINARY_DIR}/ut-client/libvirt-config/console1-dbus.xml @ONLY) +CONFIGURE_FILE(ut-client/libvirt-config/console2-dbus.xml.in + ${CMAKE_BINARY_DIR}/ut-client/libvirt-config/console2-dbus.xml @ONLY) +CONFIGURE_FILE(ut-client/libvirt-config/console3-dbus.xml.in + ${CMAKE_BINARY_DIR}/ut-client/libvirt-config/console3-dbus.xml @ONLY) +FILE(GLOB client_admin_CONF_GEN ${CMAKE_BINARY_DIR}/ut-client/libvirt-config/*.xml) + + +## Install ##################################################################### +INSTALL(FILES ${client_manager_CONF} + DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/client/ut-client) +INSTALL(FILES ${client_container_CONF} + DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/client/ut-client/containers) +INSTALL(FILES ${client_admin_CONF} + DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/client/ut-client/libvirt-config) +INSTALL(FILES ${client_admin_CONF_GEN} + DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/client/ut-client/libvirt-config) diff --git a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf new file mode 100644 index 0000000..ef49f19 --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf @@ -0,0 +1,11 @@ +{ + "privilege" : 20, + "switchToDefaultAfterTimeout" : true, + "config" : "../libvirt-config/console1-dbus.xml", + "networkConfig" : "../libvirt-config/network1.xml", + "cpuQuotaForeground" : -1, + "cpuQuotaBackground" : 1000, + "runMountPoint" : "/tmp/ut-containers-manager/console1-dbus", + "permittedToSend" : [ "/tmp/.*", "/etc/secret2" ], + "permittedToRecv" : [ "/tmp/.*" ] +} diff --git a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf new file mode 100644 index 0000000..76c5e49 --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf @@ -0,0 +1,11 @@ +{ + "privilege" : 20, + "switchToDefaultAfterTimeout" : false, + "config" : "../libvirt-config/console2-dbus.xml", + "networkConfig" : "../libvirt-config/network2.xml", + "cpuQuotaForeground" : -1, + "cpuQuotaBackground" : 1000, + "runMountPoint" : "/tmp/ut-containers-manager/console2-dbus", + "permittedToSend" : [ "/tmp/.*" ], + "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ] +} diff --git a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf new file mode 100644 index 0000000..592cbfa --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf @@ -0,0 +1,11 @@ +{ + "privilege" : 20, + "switchToDefaultAfterTimeout" : true, + "config" : "../libvirt-config/console3-dbus.xml", + "networkConfig" : "../libvirt-config/network3.xml", + "cpuQuotaForeground" : -1, + "cpuQuotaBackground" : 1000, + "runMountPoint" : "/tmp/ut-containers-manager/console3-dbus", + "permittedToSend" : [ "/tmp/.*" ], + "permittedToRecv" : [ "/tmp/.*" ] +} diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/console1-dbus.xml.in b/tests/unit_tests/client/configs/ut-client/libvirt-config/console1-dbus.xml.in new file mode 100644 index 0000000..3bce659 --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/console1-dbus.xml.in @@ -0,0 +1,15 @@ + + ut-containers-manager-console1-dbus + 58184009-b278-4d01-975d-708393690084 + 102400 + + exe + /usr/bin/dbus-daemon + --nofork + --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf + --address=unix:path=/tmp/ut-containers-manager/console1-dbus/dbus/system_bus_socket + + + + + diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/console2-dbus.xml.in b/tests/unit_tests/client/configs/ut-client/libvirt-config/console2-dbus.xml.in new file mode 100644 index 0000000..f98c9bd --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/console2-dbus.xml.in @@ -0,0 +1,15 @@ + + ut-containers-manager-console2-dbus + 3d18323e-4ada-4a1b-a907-836701891306 + 102400 + + exe + /usr/bin/dbus-daemon + --nofork + --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf + --address=unix:path=/tmp/ut-containers-manager/console2-dbus/dbus/system_bus_socket + + + + + diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/console3-dbus.xml.in b/tests/unit_tests/client/configs/ut-client/libvirt-config/console3-dbus.xml.in new file mode 100644 index 0000000..8175bcf --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/console3-dbus.xml.in @@ -0,0 +1,15 @@ + + ut-containers-manager-console3-dbus + 71cb8511-7474-4e90-865a-3360b7f77254 + 102400 + + exe + /usr/bin/dbus-daemon + --nofork + --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf + --address=unix:path=/tmp/ut-containers-manager/console3-dbus/dbus/system_bus_socket + + + + + diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/network1.xml b/tests/unit_tests/client/configs/ut-client/libvirt-config/network1.xml new file mode 100644 index 0000000..23a5edd --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/network1.xml @@ -0,0 +1,4 @@ + + test-network-1 + 372720ef-258b-4b27-baf6-d08341b15353 + diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/network2.xml b/tests/unit_tests/client/configs/ut-client/libvirt-config/network2.xml new file mode 100644 index 0000000..c3b4f04 --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/network2.xml @@ -0,0 +1,4 @@ + + test-network-2 + 95b9c647-ed3f-4586-886e-0a7b24e683a8 + diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/network3.xml b/tests/unit_tests/client/configs/ut-client/libvirt-config/network3.xml new file mode 100644 index 0000000..7b3f730 --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/network3.xml @@ -0,0 +1,4 @@ + + test-network-3 + 962b061d-7f3e-410b-8990-3f1267d77656 + diff --git a/tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf b/tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf new file mode 100644 index 0000000..2a6ad35 --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf @@ -0,0 +1,20 @@ +{ + "containerConfigs" : ["containers/console1-dbus.conf", + "containers/console2-dbus.conf", + "containers/console3-dbus.conf"], + "foregroundId" : "ut-containers-manager-console1-dbus", + "defaultId" : "ut-containers-manager-console1-dbus", + "containersPath" : "/tmp", + "runMountPointPrefix" : "", + "inputConfig" : {"enabled" : false, + "device" : "/dev/doesnotexist", + "code" : 139, + "numberOfEvents" : 2, + "timeWindowMs" : 500}, + "proxyCallRules" : [{"caller" : "*", + "target" : "*", + "targetBusName" : "org.tizen.containers.tests", + "targetObjectPath" : "*", + "targetInterface" : "*", + "targetMethod" : "*"}] +} diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp new file mode 100644 index 0000000..1755874 --- /dev/null +++ b/tests/unit_tests/client/ut-client.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * 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 + */ + + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Unit tests of the client C API + */ + +#include +#include "ut.hpp" +#include + +#include "containers-manager.hpp" + +#include +#include +#include +#include + +using namespace security_containers; + +namespace { + +const std::string TEST_DBUS_CONFIG_PATH = + SC_TEST_CONFIG_INSTALL_DIR "/client/ut-client/test-dbus-daemon.conf"; + +struct Fixture { + Fixture() { sc_start(); }; + ~Fixture() { sc_stop(); }; +}; + +const std::map EXPECTED_DBUSES_STARTED = { + {"ut-containers-manager-console1-dbus", + "unix:path=/tmp/ut-containers-manager/console1-dbus/dbus/system_bus_socket"}, + {"ut-containers-manager-console2-dbus", + "unix:path=/tmp/ut-containers-manager/console2-dbus/dbus/system_bus_socket"}, + {"ut-containers-manager-console3-dbus", + "unix:path=/tmp/ut-containers-manager/console3-dbus/dbus/system_bus_socket"}}; + +void convertDictToMap(ScArrayString keys, + ScArrayString values, + std::map& ret) +{ + char** iKeys; + char** iValues; + for (iKeys = keys, iValues = values; *iKeys && *iValues; iKeys++, iValues++) { + ret.insert(std::make_pair(*iKeys, *iValues)); + } +} + +int getArrayStringLength(ScArrayString astring, int max_len = -1) +{ + int i = 0; + for (i = 0; astring[i]; i++) { + if (i == max_len) { + return max_len; + } + } + return i; +} + +} // namespace + +BOOST_FIXTURE_TEST_SUITE(Client, Fixture) + +BOOST_AUTO_TEST_CASE(NotRunningServerTest) +{ + ScClient client; + ScStatus status = sc_get_client(&client, + SCCLIENT_CUSTOM_TYPE, + EXPECTED_DBUSES_STARTED.begin()->second.c_str()); + BOOST_CHECK(sc_is_failed(status)); + sc_client_free(client); +} + +BOOST_AUTO_TEST_CASE(GetContainerDbusesTest) +{ + std::unique_ptr cm; + BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); + cm->startAll(); + ScClient client; + ScStatus status = sc_get_client(&client, SCCLIENT_SYSTEM_TYPE); + BOOST_REQUIRE(!sc_is_failed(status)); + ScArrayString keys, values; + status = sc_get_container_dbuses(client, &keys, &values); + BOOST_REQUIRE(!sc_is_failed(status)); + + BOOST_CHECK_EQUAL(getArrayStringLength(keys, EXPECTED_DBUSES_STARTED.size() + 1), + EXPECTED_DBUSES_STARTED.size()); + BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_DBUSES_STARTED.size() + 1), + EXPECTED_DBUSES_STARTED.size()); + + std::map containers; + convertDictToMap(keys, values, containers); + BOOST_CHECK(containers == EXPECTED_DBUSES_STARTED); + sc_array_string_free(keys); + sc_array_string_free(values); + sc_client_free(client); + BOOST_WARN_NO_THROW(cm.reset()); +} + +BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 8143c86bcc993789507ad56c96dd1773c2a11dc2 Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Mon, 11 Aug 2014 12:52:27 +0200 Subject: [PATCH 12/16] Tests of storing non-string types in KVStore [Bug/Feature] Types serializable to iostreams can be stored. [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I4395d697620f6b8ea9e558edf620e35f797c6178 --- tests/unit_tests/config/ut-kvstore.cpp | 151 ++++++++++++++++++++++----------- 1 file changed, 102 insertions(+), 49 deletions(-) diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp index 26abf76..a1e5591 100644 --- a/tests/unit_tests/config/ut-kvstore.cpp +++ b/tests/unit_tests/config/ut-kvstore.cpp @@ -29,6 +29,7 @@ #include "config/kvstore.hpp" #include "config/exception.hpp" +#include #include #include @@ -51,6 +52,42 @@ struct Fixture { fs::remove(dbPath); } }; + +class TestClass { +public: + TestClass(int v): value(v) {} + TestClass(): value(0) {} + friend std::ostream& operator<< (std::ostream& out, const TestClass& cPoint); + friend std::istream& operator>> (std::istream& in, TestClass& cPoint); + friend bool operator== (const TestClass& lhs, const TestClass& rhs); + friend bool operator!= (const TestClass& lhs, const TestClass& rhs); + +private: + int value ; +}; + +bool operator==(const TestClass& lhs, const TestClass& rhs) +{ + return lhs.value == rhs.value; +} + +bool operator!=(const TestClass& lhs, const TestClass& rhs) +{ + return lhs.value != rhs.value; +} + +std::ostream& operator<< (std::ostream& out, const TestClass& tc) +{ + out << tc.value;; + return out; +} + +std::istream& operator>> (std::istream& in, TestClass& tc) +{ + in >> tc.value; + return in; +} + } // namespace BOOST_FIXTURE_TEST_SUITE(KVStoreSuite, Fixture) @@ -70,23 +107,6 @@ BOOST_AUTO_TEST_CASE(SimpleConstructorDestructorTest) fs::remove(dbPath); } -BOOST_AUTO_TEST_CASE(SingleValueTest) -{ - // Set - BOOST_CHECK_NO_THROW(c.set(KEY, "A")); - BOOST_CHECK_EQUAL(c.get(KEY), "A"); - - // Update - BOOST_CHECK_NO_THROW(c.set(KEY, "B")); - BOOST_CHECK_EQUAL(c.get(KEY), "B"); - BOOST_CHECK_EQUAL(c.count(KEY), 1); - - // Remove - BOOST_CHECK_NO_THROW(c.remove(KEY)); - BOOST_CHECK_EQUAL(c.count(KEY), 0); - BOOST_CHECK_THROW(c.get(KEY), ConfigException); -} - BOOST_AUTO_TEST_CASE(EscapedCharactersTest) { // '*' ?' '[' ']' are escaped @@ -123,55 +143,88 @@ BOOST_AUTO_TEST_CASE(EscapedCharactersTest) BOOST_CHECK_EQUAL(c.size(), 2); } -BOOST_AUTO_TEST_CASE(VectorOfValuesTest) +namespace { +template +void testSingleValue(Fixture& f, const A& a, const B& b) { - std::vector AB = {"A", "B"}; - std::vector AC = {"A", "C"}; - std::vector ABC = {"A", "B", "C"}; - // Set - BOOST_CHECK_NO_THROW(c.set(KEY, AB)); - BOOST_CHECK(c.list(KEY) == AB); - BOOST_CHECK_EQUAL(c.count(KEY), 2); - BOOST_CHECK_EQUAL(c.size(), 2); - + BOOST_CHECK_NO_THROW(f.c.set(KEY, a)); + BOOST_CHECK_EQUAL(f.c.get(KEY), a); // Update - BOOST_CHECK_NO_THROW(c.set(KEY, AC)); - BOOST_CHECK(c.list(KEY) == AC); - BOOST_CHECK_EQUAL(c.count(KEY), 2); - BOOST_CHECK_EQUAL(c.size(), 2); + BOOST_CHECK_NO_THROW(f.c.set(KEY, b)); + BOOST_CHECK_EQUAL(f.c.get(KEY), b); + BOOST_CHECK_EQUAL(f.c.count(KEY), 1); - // Update - BOOST_CHECK_NO_THROW(c.set(KEY, ABC)); - BOOST_CHECK(c.list(KEY) == ABC); - BOOST_CHECK_EQUAL(c.count(KEY), 3); - BOOST_CHECK_EQUAL(c.size(), 3); + // Remove + BOOST_CHECK_NO_THROW(f.c.remove(KEY)); + BOOST_CHECK_EQUAL(f.c.count(KEY), 0); + BOOST_CHECK_THROW(f.c.get(KEY), ConfigException); +} +} // namespace - // Update - BOOST_CHECK_NO_THROW(c.set(KEY, AC)); - BOOST_CHECK(c.list(KEY) == AC); - BOOST_CHECK_EQUAL(c.count(KEY), 2); - BOOST_CHECK_EQUAL(c.size(), 2); + +BOOST_AUTO_TEST_CASE(SingleValueTest) +{ + testSingleValue(*this, "A", "B"); + testSingleValue(*this, 1, 2); + testSingleValue(*this, 1.1, 2.2); + testSingleValue(*this, 2, "A"); + testSingleValue(*this, INT64_MAX, INT64_MAX - 2); + testSingleValue(*this, 11, 22); +} + +namespace { +template +void setVector(Fixture& f, std::vector vec) +{ + std::vector storedVec; + BOOST_CHECK_NO_THROW(f.c.set(KEY, vec)); + BOOST_CHECK_NO_THROW(storedVec = f.c.get >(KEY)) + BOOST_CHECK_EQUAL_COLLECTIONS(storedVec.begin(), storedVec.end(), vec.begin(), vec.end()); + BOOST_CHECK_EQUAL(f.c.count(KEY), vec.size()); + BOOST_CHECK_EQUAL(f.c.size(), vec.size()); +} + +template +void testVectorOfValues(Fixture& f, + std::vector a, + std::vector b, + std::vector c) +{ + // Set + setVector(f, a); + setVector(f, b); + setVector(f, c); // Remove - BOOST_CHECK_NO_THROW(c.remove(KEY)); - BOOST_CHECK_EQUAL(c.count(KEY), 0); - BOOST_CHECK_EQUAL(c.size(), 0); - BOOST_CHECK_THROW(c.list(KEY), ConfigException); - BOOST_CHECK_THROW(c.get(KEY), ConfigException); + BOOST_CHECK_NO_THROW(f.c.remove(KEY)); + BOOST_CHECK_EQUAL(f.c.count(KEY), 0); + BOOST_CHECK_EQUAL(f.c.size(), 0); + BOOST_CHECK_THROW(f.c.get >(KEY), ConfigException); + BOOST_CHECK_THROW(f.c.get(KEY), ConfigException); +} +} // namespace + +BOOST_AUTO_TEST_CASE(VectorOfValuesTest) +{ + testVectorOfValues(*this, {"A", "B"}, {"A", "C"}, {"A", "B", "C"}); + testVectorOfValues(*this, {1, 2}, {1, 3}, {1, 2, 3}); + testVectorOfValues(*this, {INT64_MAX, 2}, {1, 3}, {INT64_MAX, 2, INT64_MAX}); + testVectorOfValues(*this, {1.1, 2.2}, {1.1, 3.3}, {1.1, 2.2, 3.3}); + testVectorOfValues(*this, {1, 2}, {1, 3}, {1, 2, 3}); } BOOST_AUTO_TEST_CASE(ClearTest) { BOOST_CHECK_NO_THROW(c.clear()); - - BOOST_CHECK_NO_THROW(c.set(KEY, {"A", "B"})); + std::vector vec = {"A", "B"}; + BOOST_CHECK_NO_THROW(c.set(KEY, vec)); BOOST_CHECK_NO_THROW(c.clear()); BOOST_CHECK_EQUAL(c.size(), 0); BOOST_CHECK_NO_THROW(c.remove(KEY)); - BOOST_CHECK_THROW(c.list(KEY), ConfigException); + BOOST_CHECK_THROW(c.get>(KEY), ConfigException); BOOST_CHECK_THROW(c.get(KEY), ConfigException); } -- 2.7.4 From 206d66b951ce02f6ce30c1eed355c8699cd20de8 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Tue, 19 Aug 2014 14:34:01 +0200 Subject: [PATCH 13/16] [Unit tests] Handle segmentation faults [Bug/Feature] No message was printed when unit tests was terminated by some signal. [Cause] N/A [Solution] N/A [Verification] Build, install, run good and crashing tests. Change-Id: Ib8a8abae09e3dfa2d2badd8c78f87440eb834c4c --- tests/scripts/sc_launch_test.py | 10 ++++++++-- tests/scripts/sc_test_parser.py | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/scripts/sc_launch_test.py b/tests/scripts/sc_launch_test.py index 81d6d62..6bdbcfe 100755 --- a/tests/scripts/sc_launch_test.py +++ b/tests/scripts/sc_launch_test.py @@ -42,7 +42,9 @@ def launchTest(cmd=[], externalToolCmd=[], parsing=True): if parsing: parser = Parser() - p = subprocess.Popen(" ".join(externalToolCmd + cmd + _defLaunchArgs), + command = " ".join(externalToolCmd + cmd + _defLaunchArgs) + log.info("Invoking `" + command + "`") + p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) @@ -51,10 +53,14 @@ def launchTest(cmd=[], externalToolCmd=[], parsing=True): domResult = minidom.parseString(testResult) log.XMLSummary(domResult) log.failedTestSummary(cmd[0]) + if p.returncode < 0: + log.terminatedBySignal(" ".join(cmd), -p.returncode) else: # Launching process without coloring does not require report in XML form # Avoid providing --report_format=XML, redirect std* by default to system's std* - p = subprocess.Popen(" ".join(externalToolCmd + cmd + _defLaunchArgs[1:]), + command = " ".join(externalToolCmd + cmd + _defLaunchArgs[1:]) + log.info("Invoking `" + command + "`") + p = subprocess.Popen(command, shell=True) p.wait() diff --git a/tests/scripts/sc_test_parser.py b/tests/scripts/sc_test_parser.py index 8d4b289..5299814 100644 --- a/tests/scripts/sc_test_parser.py +++ b/tests/scripts/sc_test_parser.py @@ -82,6 +82,14 @@ class Logger(object): for test in self.__failedTests: self.error(self.__indentChar + commandPrefix + test) + def terminatedBySignal(self, bin, signum): + self.error("\n=========== FAILED ===========\n") + signame = {2:"SIGINT", 9:"SIGKILL", 11:"SIGSEGV", 15:"SIGTERM"} + siginfo = signame.get(signum, 'signal ' + str(signum)) + self.error('Terminated by ' + siginfo) + if signum == 11: # SIGSEGV + self.error("\nUse following command to launch debugger:") + self.error(self.__indentChar + "sc_launch_test.py --gdb " + bin) class Parser(object): -- 2.7.4 From 51a73747a270ef176596365e5e5958aaeed87645 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 14 Aug 2014 18:03:51 +0200 Subject: [PATCH 14/16] Client library functions [Feature] Add more functions to the client library. [Cause] N/A [Solution] N/A [Verification] Build, install, run test suite Client Change-Id: Ided49f0363c5bb94669c272fda745510cd21d985 --- client/security-containers-client-impl.cpp | 165 +++++++++++++++++++++ client/security-containers-client-impl.hpp | 33 +++++ client/security-containers-client.cpp | 33 +++++ client/security-containers-client.h | 77 ++++++++++ .../ut-client/containers/console1-dbus.conf | 1 + .../ut-client/containers/console2-dbus.conf | 1 + .../ut-client/containers/console3-dbus.conf | 1 + .../ut-client/libvirt-config/network1-filter.xml | 3 + .../ut-client/libvirt-config/network2-filter.xml | 3 + .../ut-client/libvirt-config/network3-filter.xml | 3 + tests/unit_tests/client/ut-client.cpp | 120 +++++++++++++++ 11 files changed, 440 insertions(+) create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/network1-filter.xml create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/network2-filter.xml create mode 100644 tests/unit_tests/client/configs/ut-client/libvirt-config/network3-filter.xml diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index 87c30f8..17315b0 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,11 @@ const string SCCLIENT_EXCEPTION_MSG = "unspecified exception"; const DbusInterfaceInfo hostDbusInterfaceInfo(api::host::BUS_NAME, api::host::OBJECT_PATH, api::host::INTERFACE); +const DbusInterfaceInfo domainDbusInterfaceInfo(api::container::BUS_NAME, + api::container::OBJECT_PATH, + api::container::INTERFACE); + +template struct fake_dependency: public std::false_type {}; unique_ptr loop; @@ -75,6 +81,45 @@ void toDict(GVariant* in, ScArrayString* keys, ScArrayString* values) *values = outv; } +template +void toBasic(GVariant* in, T str) +{ + static_assert(fake_dependency::value, "Must use specialization"); + assert(!"Must use specialization"); +} + +template<> +void toBasic(GVariant* in, char** str) +{ + assert(in); + assert(str); + + gsize length; + const gchar* src = g_variant_get_string(in, &length); + char* buf = strndup(src, length); + *str = buf; +} + +template +void toArray(GVariant* in, T** scArray) +{ + assert(in); + assert(scArray); + + gsize size = g_variant_n_children(in); + T* ids = (T*)calloc(size + 1, sizeof(T)); + + GVariantIter iter; + GVariant* child; + + g_variant_iter_init(&iter, in); + for (int i = 0; (child = g_variant_iter_next_value(&iter)); i++) { + toBasic(child, &ids[i]); + g_variant_unref(child); + } + *scArray = ids; +} + ScStatus toStatus(const std::exception& ex) { if (typeid(DbusCustomException) == typeid(ex)) { @@ -203,6 +248,33 @@ ScStatus Client::callMethod(const DbusInterfaceInfo& info, return sc_get_status(); } +ScStatus Client::signalSubscribe(const DbusInterfaceInfo& info, + const string& name, + SignalCallback signalCallback) +{ + auto onSignal = [=](const std::string& /*senderBusName*/, + const std::string & objectPath, + const std::string & interface, + const std::string & signalName, + GVariant * parameters) { + if (objectPath == info.objectPath && + interface == info.interface && + signalName == name) { + + signalCallback(parameters); + } + }; + try { + mConnection->signalSubscribe(onSignal, info.busName); + mStatus = Status(SCCLIENT_SUCCESS); + } catch (const std::exception& ex) { + mStatus = Status(toStatus(ex), ex.what()); + } catch (...) { + mStatus = Status(SCCLIENT_EXCEPTION); + } + return sc_get_status(); +} + const char* Client::sc_get_status_message() noexcept { return mStatus.mMsg.c_str(); @@ -234,3 +306,96 @@ ScStatus Client::sc_get_container_dbuses(ScArrayString* keys, ScArrayString* val g_variant_unref(out); return ret; } + +ScStatus Client::sc_get_container_ids(ScArrayString* array) noexcept +{ + assert(array); + + GVariant* out; + ScStatus ret = callMethod(hostDbusInterfaceInfo, + api::host::METHOD_GET_CONTAINER_ID_LIST, + NULL, + "(as)", + &out); + if (ret != SCCLIENT_SUCCESS) { + return ret; + } + GVariant* unpacked; + g_variant_get(out, "(*)", &unpacked); + toArray(unpacked, array); + g_variant_unref(unpacked); + g_variant_unref(out); + return ret; +} + +ScStatus Client::sc_get_active_container_id(ScString* id) noexcept +{ + assert(id); + + GVariant* out; + ScStatus ret = callMethod(hostDbusInterfaceInfo, + api::host::METHOD_GET_ACTIVE_CONTAINER_ID, + NULL, + "(s)", + &out); + if (ret != SCCLIENT_SUCCESS) { + return ret; + } + GVariant* unpacked; + g_variant_get(out, "(*)", &unpacked); + toBasic(unpacked, id); + g_variant_unref(unpacked); + g_variant_unref(out); + return ret; +} + +ScStatus Client::sc_set_active_container(const char* id) noexcept +{ + assert(id); + + GVariant* args_in = g_variant_new("(s)", id); + return callMethod(hostDbusInterfaceInfo, api::host::METHOD_SET_ACTIVE_CONTAINER, args_in); +} + +ScStatus Client::sc_container_dbus_state(ScContainerDbusStateCallback containerDbusStateCallback) + noexcept +{ + assert(containerDbusStateCallback); + + auto onSigal = [ = ](GVariant * parameters) { + const char* container; + const char* dbusAddress; + g_variant_get(parameters, "(&s&s)", &container, &dbusAddress); + containerDbusStateCallback(container, dbusAddress); + }; + + return signalSubscribe(hostDbusInterfaceInfo, + api::host::SIGNAL_CONTAINER_DBUS_STATE, + onSigal); +} + +ScStatus Client::sc_notify_active_container(const char* application, const char* message) noexcept +{ + assert(application); + assert(message); + + GVariant* args_in = g_variant_new("(ss)", application, message); + return callMethod(domainDbusInterfaceInfo, + api::container::METHOD_NOTIFY_ACTIVE_CONTAINER, + args_in); +} + +ScStatus Client::sc_notification(ScNotificationCallback notificationCallback) noexcept +{ + assert(notificationCallback); + + auto onSigal = [ = ](GVariant * parameters) { + const char* container; + const char* application; + const char* message; + g_variant_get(parameters, "(&s&s&s)", &container, &application, &message); + notificationCallback(container, application, message); + }; + + return signalSubscribe(domainDbusInterfaceInfo, api::container::SIGNAL_NOTIFICATION, onSigal); +} diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp index f823cd1..aafcae0 100644 --- a/client/security-containers-client-impl.hpp +++ b/client/security-containers-client-impl.hpp @@ -52,6 +52,7 @@ struct DbusInterfaceInfo { */ class Client { private: + typedef std::function SignalCallback; struct Status { Status(ScStatus status); Status(ScStatus status, const std::string& msg); @@ -67,6 +68,9 @@ private: GVariant* args_in, const std::string& args_spec_out = std::string(), GVariant** args_out = NULL); + ScStatus signalSubscribe(const DbusInterfaceInfo& info, + const std::string& name, + SignalCallback signalCallback); public: Client() noexcept; @@ -103,6 +107,35 @@ public: ScStatus sc_get_container_dbuses(ScArrayString* keys, ScArrayString* values) noexcept; /** + * @see ::sc_get_container_ids + */ + ScStatus sc_get_container_ids(ScArrayString* array) noexcept; + + /** + * @see ::sc_get_active_container_id + */ + ScStatus sc_get_active_container_id(ScString* id) noexcept; + + /** + * @see ::sc_set_active_container + */ + ScStatus sc_set_active_container(const char* id) noexcept; + + /** + * @see ::sc_container_dbus_state + */ + ScStatus sc_container_dbus_state(ScContainerDbusStateCallback containerDbusStateCallback) noexcept; + + /** + * @see ::sc_notify_active_container + */ + ScStatus sc_notify_active_container(const char* application, const char* message) noexcept; + + /** + * @see ::sc_notification + */ + ScStatus sc_notification(ScNotificationCallback notificationCallback) noexcept; + /** * @see ::sc_start */ static ScStatus sc_start() noexcept; diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index 572f166..12a3d6d 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -135,3 +135,36 @@ API ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArr { return getClient(client)->sc_get_container_dbuses(keys, values); } + +API ScStatus sc_get_container_ids(ScClient client, ScArrayString* array) +{ + return getClient(client)->sc_get_container_ids(array); +} + +API ScStatus sc_get_active_container_id(ScClient client, ScString* id) +{ + return getClient(client)->sc_get_active_container_id(id); +} + +API ScStatus sc_set_active_container(ScClient client, const char* id) +{ + return getClient(client)->sc_set_active_container(id); +} + +API ScStatus sc_container_dbus_state(ScClient client, + ScContainerDbusStateCallback containerDbusStateCallback) +{ + return getClient(client)->sc_container_dbus_state(containerDbusStateCallback); +} + +API ScStatus sc_notify_active_container(ScClient client, + const char* application, + const char* message) +{ + return getClient(client)->sc_notify_active_container(application, message); +} + +API ScStatus sc_notification(ScClient client, ScNotificationCallback notificationCallback) +{ + return getClient(client)->sc_notification(notificationCallback); +} diff --git a/client/security-containers-client.h b/client/security-containers-client.h index 692df31..01ca12c 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -149,6 +149,11 @@ void sc_string_free(ScString string); ************************************************************************************************/ /** + * Dbus state change callback function signature. + */ +typedef void (*ScContainerDbusStateCallback)(const char* containerId, const char* dbusAddress); + +/** * Get dbus address of each container. * * @param[in] client security-containers-server's client. @@ -159,6 +164,78 @@ void sc_string_free(ScString string); */ ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArrayString* values); +/** + * Get containers name. + * + * @param[in] client security-containers-server's client. + * @param[out] array Array of containers name. + * @return Status of this function call. + */ +ScStatus sc_get_container_ids(ScClient client, ScArrayString* array); + +/** + * Get active container name. + * + * @param[in] client security-containers-server's client. + * @param[out] id Active container name. + * @return Status of this function call. + */ +ScStatus sc_get_active_container_id(ScClient client, ScString* id); + +/** + * Set active container. + * + * @param client security-containers-server's client. + * @param id Container name. + * @return Status of this function call. + */ +ScStatus sc_set_active_container(ScClient client, const char* id); + +/** + * Register dbus state change callback function. + * + * The callback function will be invoked on a different thread + * + * @param client security-containers-server's client. + * @param containerDbusStateCallback Callback function. + * @return Status of this function call. + */ +ScStatus sc_container_dbus_state(ScClient client, + ScContainerDbusStateCallback containerDbusStateCallback); + + +/************************************************************************************************* + * + * org.tizen.containers.domain.manager interface + * + ************************************************************************************************/ + +/** + * Notification callback function signature. + */ +typedef void (*ScNotificationCallback)(const char* container, + const char* application, + const char* message); +/** + * Send message to active container. + * + * @param client security-containers-server's client. + * @param application Application name. + * @param message Message. + * @return Status of this function call. + */ +ScStatus sc_notify_active_container(ScClient client, const char* application, const char* message); + +/** + * Register notification callback function. + * + * The callback function will be invoked on a different thread. + * + * @param client security-containers-server's client. + * @param notificationCallback Callback function. + * @return Status of this function call. + */ +ScStatus sc_notification(ScClient client, ScNotificationCallback notificationCallback); #ifdef __cplusplus } #endif diff --git a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf index ef49f19..af3380b 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf +++ b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/console1-dbus.xml", "networkConfig" : "../libvirt-config/network1.xml", + "networkFilterConfig" : "../libvirt-config/network1-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "/tmp/ut-containers-manager/console1-dbus", diff --git a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf index 76c5e49..0db0a8a 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf +++ b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : false, "config" : "../libvirt-config/console2-dbus.xml", "networkConfig" : "../libvirt-config/network2.xml", + "networkFilterConfig" : "../libvirt-config/network2-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "/tmp/ut-containers-manager/console2-dbus", diff --git a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf index 592cbfa..14a8a60 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf +++ b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf @@ -3,6 +3,7 @@ "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/console3-dbus.xml", "networkConfig" : "../libvirt-config/network3.xml", + "networkFilterConfig" : "../libvirt-config/network3-filter.xml", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "runMountPoint" : "/tmp/ut-containers-manager/console3-dbus", diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/network1-filter.xml b/tests/unit_tests/client/configs/ut-client/libvirt-config/network1-filter.xml new file mode 100644 index 0000000..bf39965 --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/network1-filter.xml @@ -0,0 +1,3 @@ + + abc79a77-0209-41a2-ab82-f767dfa5897e + diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/network2-filter.xml b/tests/unit_tests/client/configs/ut-client/libvirt-config/network2-filter.xml new file mode 100644 index 0000000..f33c816 --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/network2-filter.xml @@ -0,0 +1,3 @@ + + 703f53eb-c602-4383-9de9-62bbe843ba31 + diff --git a/tests/unit_tests/client/configs/ut-client/libvirt-config/network3-filter.xml b/tests/unit_tests/client/configs/ut-client/libvirt-config/network3-filter.xml new file mode 100644 index 0000000..04310bd --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/libvirt-config/network3-filter.xml @@ -0,0 +1,3 @@ + + 40943fcc-faec-4bfe-9e89-104945164d35 + diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 1755874..cab82e1 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -27,14 +27,19 @@ #include "ut.hpp" #include +#include "utils/latch.hpp" #include "containers-manager.hpp" #include #include #include #include +#include +#include +#include using namespace security_containers; +using namespace security_containers::utils; namespace { @@ -46,6 +51,7 @@ struct Fixture { ~Fixture() { sc_stop(); }; }; +const int EVENT_TIMEOUT = 5000; ///< ms const std::map EXPECTED_DBUSES_STARTED = { {"ut-containers-manager-console1-dbus", "unix:path=/tmp/ut-containers-manager/console1-dbus/dbus/system_bus_socket"}, @@ -65,6 +71,13 @@ void convertDictToMap(ScArrayString keys, } } +void convertArrayToSet(ScArrayString values, std::set& ret) +{ + for (char** iValues = values; *iValues; iValues++) { + ret.insert(*iValues); + } +} + int getArrayStringLength(ScArrayString astring, int max_len = -1) { int i = 0; @@ -76,6 +89,15 @@ int getArrayStringLength(ScArrayString astring, int max_len = -1) return i; } +Latch signalReceivedLatch; +std::vector< std::tuple > receivedSignalMsg; + +void NotificationTestCallback(const char* container, const char* application, const char* message) +{ + receivedSignalMsg.push_back(std::make_tuple(container, application, message)); + signalReceivedLatch.set(); +} + } // namespace BOOST_FIXTURE_TEST_SUITE(Client, Fixture) @@ -116,4 +138,102 @@ BOOST_AUTO_TEST_CASE(GetContainerDbusesTest) BOOST_WARN_NO_THROW(cm.reset()); } +BOOST_AUTO_TEST_CASE(GetContainerIdsTest) +{ + std::unique_ptr cm; + BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); + cm->startAll(); + ScClient client; + ScStatus status = sc_get_client(&client, SCCLIENT_SYSTEM_TYPE); + BOOST_REQUIRE(!sc_is_failed(status)); + ScArrayString values; + status = sc_get_container_ids(client, &values); + BOOST_REQUIRE(!sc_is_failed(status)); + BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_DBUSES_STARTED.size() + 1), + EXPECTED_DBUSES_STARTED.size()); + + std::set containers; + convertArrayToSet(values, containers); + + for (const auto& container : containers) { + BOOST_CHECK(EXPECTED_DBUSES_STARTED.find(container) != EXPECTED_DBUSES_STARTED.cend()); + } + sc_array_string_free(values); + sc_client_free(client); + + BOOST_WARN_NO_THROW(cm.reset()); +} + +BOOST_AUTO_TEST_CASE(GetActiveContainerIdTest) +{ + std::unique_ptr cm; + BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); + cm->startAll(); + + ScClient client; + ScStatus status = sc_get_client(&client, SCCLIENT_SYSTEM_TYPE); + BOOST_REQUIRE(!sc_is_failed(status)); + ScString container; + status = sc_get_active_container_id(client, &container); + BOOST_REQUIRE(!sc_is_failed(status)); + + BOOST_CHECK_EQUAL(container, cm->getRunningForegroundContainerId()); + + sc_string_free(container); + sc_client_free(client); + + BOOST_WARN_NO_THROW(cm.reset()); +} + +BOOST_AUTO_TEST_CASE(SetActiveContainerTest) +{ + std::string newActiveContainerId = "ut-containers-manager-console2-dbus"; + + std::unique_ptr cm; + BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); + cm->startAll(); + BOOST_REQUIRE_NE(newActiveContainerId, cm->getRunningForegroundContainerId()); + + ScClient client; + ScStatus status = sc_get_client(&client, SCCLIENT_SYSTEM_TYPE); + BOOST_REQUIRE(!sc_is_failed(status)); + status = sc_set_active_container(client, newActiveContainerId.c_str()); + BOOST_REQUIRE(!sc_is_failed(status)); + BOOST_CHECK_EQUAL(newActiveContainerId, cm->getRunningForegroundContainerId()); + sc_client_free(client); + BOOST_WARN_NO_THROW(cm.reset()); +} + +BOOST_AUTO_TEST_CASE(NotificationTest) +{ + std::string activeContainerId = "ut-containers-manager-console1-dbus"; + std::unique_ptr cm; + BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); + cm->startAll(); + + std::map clients; + for (const auto& it : EXPECTED_DBUSES_STARTED) { + ScClient client; + ScStatus status = sc_get_client(&client, SCCLIENT_CUSTOM_TYPE, it.second.c_str()); + BOOST_REQUIRE(!sc_is_failed(status)); + clients[it.first] = client; + } + for (auto& client : clients) { + ScStatus status = sc_notification(client.second, NotificationTestCallback); + BOOST_REQUIRE(!sc_is_failed(status)); + } + for (auto& client : clients) { + ScStatus status = sc_notify_active_container(client.second, "app", "msg"); + BOOST_REQUIRE(!sc_is_failed(status)); + } + + BOOST_CHECK(signalReceivedLatch.waitForN(clients.size() - 1, EVENT_TIMEOUT)); + BOOST_CHECK(signalReceivedLatch.empty()); + + for (auto& client : clients) { + sc_client_free(client.second); + } + BOOST_WARN_NO_THROW(cm.reset()); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 8f1989c65cb93980c22d6af3787a5f637f37bb0f Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Wed, 20 Aug 2014 12:50:45 +0200 Subject: [PATCH 15/16] Tests of a function for key creation [Bug/Feature] Tests of key creation [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I4c7fbaec78dbba6f847e3c9275d62c3e4a4ef098 --- server/container.hpp | 1 + tests/unit_tests/config/ut-kvstore.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/server/container.hpp b/server/container.hpp index c29b860..f2d67c0 100644 --- a/server/container.hpp +++ b/server/container.hpp @@ -32,6 +32,7 @@ #include "container-connection-transport.hpp" #include "network-admin.hpp" + #include #include #include diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp index a1e5591..66efc2b 100644 --- a/tests/unit_tests/config/ut-kvstore.cpp +++ b/tests/unit_tests/config/ut-kvstore.cpp @@ -228,4 +228,17 @@ BOOST_AUTO_TEST_CASE(ClearTest) BOOST_CHECK_THROW(c.get(KEY), ConfigException); } +BOOST_AUTO_TEST_CASE(KeyTest) +{ + BOOST_CHECK_EQUAL(key(), ""); + BOOST_CHECK_EQUAL(key<>(), ""); + BOOST_CHECK_EQUAL(key(""), ""); + BOOST_CHECK_EQUAL(key("KEY"), "KEY"); + BOOST_CHECK_EQUAL(key<>("KEY"), "KEY"); + BOOST_CHECK_EQUAL(key("KEY", "A"), "KEY.A"); + BOOST_CHECK_EQUAL(key("KEY", 1, 2.2), "KEY.1.2.2"); + BOOST_CHECK_EQUAL(key("KEY", 1, "B"), "KEY.1.B"); + BOOST_CHECK_EQUAL(key<'_'>("KEY", 1, 2.2), "KEY_1_2.2"); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From d9a52d5c3fe981b305080feb6386080902ae2a27 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Thu, 21 Aug 2014 18:02:49 +0200 Subject: [PATCH 16/16] Client library cleanup [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Idd5feb3fe6ec78a9c3ad3ffbb5f26efda0abbaec --- client/security-containers-client-impl.cpp | 110 ++++++++---------------- client/security-containers-client-impl.hpp | 16 ++-- client/security-containers-client.cpp | 73 ++++++---------- client/security-containers-client.h | 131 ++++++++++++++--------------- common/utils/glib-loop.cpp | 11 +++ tests/scripts/sc_test_parser.py | 11 ++- tests/unit_tests/client/ut-client.cpp | 106 ++++++++++------------- 7 files changed, 198 insertions(+), 260 deletions(-) diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index 17315b0..9e0a54a 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include @@ -42,19 +41,14 @@ using namespace security_containers::utils; namespace { -const string SCCLIENT_SUCCESS_MSG; -const string SCCLIENT_EXCEPTION_MSG = "unspecified exception"; +const DbusInterfaceInfo HOST_INTERFACE(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE); +const DbusInterfaceInfo CONTAINER_INTERFACE(api::container::BUS_NAME, + api::container::OBJECT_PATH, + api::container::INTERFACE); -const DbusInterfaceInfo hostDbusInterfaceInfo(api::host::BUS_NAME, - api::host::OBJECT_PATH, - api::host::INTERFACE); -const DbusInterfaceInfo domainDbusInterfaceInfo(api::container::BUS_NAME, - api::container::OBJECT_PATH, - api::container::INTERFACE); - -template struct fake_dependency: public std::false_type {}; - -unique_ptr loop; +unique_ptr gGlibLoop; void toDict(GVariant* in, ScArrayString* keys, ScArrayString* values) { @@ -81,14 +75,6 @@ void toDict(GVariant* in, ScArrayString* keys, ScArrayString* values) *values = outv; } -template -void toBasic(GVariant* in, T str) -{ - static_assert(fake_dependency::value, "Must use specialization"); - assert(!"Must use specialization"); -} - -template<> void toBasic(GVariant* in, char** str) { assert(in); @@ -123,64 +109,47 @@ void toArray(GVariant* in, T** scArray) ScStatus toStatus(const std::exception& ex) { if (typeid(DbusCustomException) == typeid(ex)) { - return SCCLIENT_DBUS_CUSTOM_EXCEPTION; + return SCCLIENT_CUSTOM_ERROR; } else if (typeid(DbusIOException) == typeid(ex)) { - return SCCLIENT_DBUS_IO_EXCEPTION; + return SCCLIENT_IO_ERROR; } else if (typeid(DbusOperationException) == typeid(ex)) { - return SCCLIENT_DBUS_OPERATION_EXCEPTION; + return SCCLIENT_OPERATION_FAILED; } else if (typeid(DbusInvalidArgumentException) == typeid(ex)) { - return SCCLIENT_DBUS_INVALID_ARGUMENT_EXCEPTION; + return SCCLIENT_INVALID_ARGUMENT; } else if (typeid(DbusException) == typeid(ex)) { - return SCCLIENT_DBUS_EXCEPTION; + return SCCLIENT_OTHER_ERROR; } - return SCCLIENT_RUNTIME_EXCEPTION; + return SCCLIENT_OTHER_ERROR; } } //namespace -ScStatus Client::sc_start() noexcept +ScStatus Client::sc_start_glib_loop() noexcept { try { - if (!loop) { - loop.reset(new ScopedGlibLoop()); + if (!gGlibLoop) { + gGlibLoop.reset(new ScopedGlibLoop()); } - } catch (const exception& ex) { - return toStatus(ex); - } catch (...) { - return SCCLIENT_EXCEPTION; + } catch (const exception&) { + return SCCLIENT_OTHER_ERROR; } return SCCLIENT_SUCCESS; } -ScStatus Client::sc_stop() noexcept +ScStatus Client::sc_stop_glib_loop() noexcept { try { - if (loop) { - loop.reset(); - } - } catch (const exception& ex) { - return toStatus(ex); - } catch (...) { - return SCCLIENT_EXCEPTION; + gGlibLoop.reset(); + } catch (const exception&) { + return SCCLIENT_OTHER_ERROR; } return SCCLIENT_SUCCESS; } -Client::Status::Status(ScStatus status) - : mScStatus(status) +Client::Status::Status() + : mScStatus(SCCLIENT_SUCCESS), mMsg() { - switch (status) { - case SCCLIENT_EXCEPTION: - mMsg = SCCLIENT_EXCEPTION_MSG; - break; - case SCCLIENT_SUCCESS: - mMsg = SCCLIENT_SUCCESS_MSG; - break; - default: - assert(!"Logic error. You must specify a message."); - mMsg = std::string(); - } } Client::Status::Status(ScStatus status, const std::string& msg) @@ -189,7 +158,6 @@ Client::Status::Status(ScStatus status, const std::string& msg) } Client::Client() noexcept - : mStatus(SCCLIENT_SUCCESS) { } @@ -201,11 +169,9 @@ ScStatus Client::createSystem() noexcept { try { mConnection = DbusConnection::createSystem(); - mStatus = Status(SCCLIENT_SUCCESS); + mStatus = Status(); } catch (const exception& ex) { mStatus = Status(toStatus(ex), ex.what()); - } catch (...) { - mStatus = Status(SCCLIENT_EXCEPTION); } return sc_get_status(); } @@ -214,11 +180,9 @@ ScStatus Client::create(const string& address) noexcept { try { mConnection = DbusConnection::create(address); - mStatus = Status(SCCLIENT_SUCCESS); + mStatus = Status(); } catch (const exception& ex) { mStatus = Status(toStatus(ex), ex.what()); - } catch (...) { - mStatus = Status(SCCLIENT_EXCEPTION); } return sc_get_status(); } @@ -239,11 +203,9 @@ ScStatus Client::callMethod(const DbusInterfaceInfo& info, if (args_out != NULL) { *args_out = ret.release(); } - mStatus = Status(SCCLIENT_SUCCESS); + mStatus = Status(); } catch (const exception& ex) { mStatus = Status(toStatus(ex), ex.what()); - } catch (...) { - mStatus = Status(SCCLIENT_EXCEPTION); } return sc_get_status(); } @@ -266,11 +228,9 @@ ScStatus Client::signalSubscribe(const DbusInterfaceInfo& info, }; try { mConnection->signalSubscribe(onSignal, info.busName); - mStatus = Status(SCCLIENT_SUCCESS); + mStatus = Status(); } catch (const std::exception& ex) { mStatus = Status(toStatus(ex), ex.what()); - } catch (...) { - mStatus = Status(SCCLIENT_EXCEPTION); } return sc_get_status(); } @@ -291,7 +251,7 @@ ScStatus Client::sc_get_container_dbuses(ScArrayString* keys, ScArrayString* val assert(values); GVariant* out; - ScStatus ret = callMethod(hostDbusInterfaceInfo, + ScStatus ret = callMethod(HOST_INTERFACE, api::host::METHOD_GET_CONTAINER_DBUSES, NULL, "(a{ss})", @@ -312,7 +272,7 @@ ScStatus Client::sc_get_container_ids(ScArrayString* array) noexcept assert(array); GVariant* out; - ScStatus ret = callMethod(hostDbusInterfaceInfo, + ScStatus ret = callMethod(HOST_INTERFACE, api::host::METHOD_GET_CONTAINER_ID_LIST, NULL, "(as)", @@ -333,7 +293,7 @@ ScStatus Client::sc_get_active_container_id(ScString* id) noexcept assert(id); GVariant* out; - ScStatus ret = callMethod(hostDbusInterfaceInfo, + ScStatus ret = callMethod(HOST_INTERFACE, api::host::METHOD_GET_ACTIVE_CONTAINER_ID, NULL, "(s)", @@ -354,7 +314,7 @@ ScStatus Client::sc_set_active_container(const char* id) noexcept assert(id); GVariant* args_in = g_variant_new("(s)", id); - return callMethod(hostDbusInterfaceInfo, api::host::METHOD_SET_ACTIVE_CONTAINER, args_in); + return callMethod(HOST_INTERFACE, api::host::METHOD_SET_ACTIVE_CONTAINER, args_in); } ScStatus Client::sc_container_dbus_state(ScContainerDbusStateCallback containerDbusStateCallback) @@ -369,7 +329,7 @@ ScStatus Client::sc_container_dbus_state(ScContainerDbusStateCallback containerD containerDbusStateCallback(container, dbusAddress); }; - return signalSubscribe(hostDbusInterfaceInfo, + return signalSubscribe(HOST_INTERFACE, api::host::SIGNAL_CONTAINER_DBUS_STATE, onSigal); } @@ -380,7 +340,7 @@ ScStatus Client::sc_notify_active_container(const char* application, const char* assert(message); GVariant* args_in = g_variant_new("(ss)", application, message); - return callMethod(domainDbusInterfaceInfo, + return callMethod(CONTAINER_INTERFACE, api::container::METHOD_NOTIFY_ACTIVE_CONTAINER, args_in); } @@ -397,5 +357,5 @@ ScStatus Client::sc_notification(ScNotificationCallback notificationCallback) no notificationCallback(container, application, message); }; - return signalSubscribe(domainDbusInterfaceInfo, api::container::SIGNAL_NOTIFICATION, onSigal); + return signalSubscribe(CONTAINER_INTERFACE, api::container::SIGNAL_NOTIFICATION, onSigal); } diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp index aafcae0..d6c9c0d 100644 --- a/client/security-containers-client-impl.hpp +++ b/client/security-containers-client-impl.hpp @@ -54,7 +54,7 @@ class Client { private: typedef std::function SignalCallback; struct Status { - Status(ScStatus status); + Status(); Status(ScStatus status, const std::string& msg); ScStatus mScStatus; std::string mMsg; @@ -79,15 +79,15 @@ public: /** * Create client with system dbus address. * - * @return Status of this function call. + * @return status of this function call */ ScStatus createSystem() noexcept; /** * Create client. * - * @param address Dbus socket address. - * @return Status of this function call. + * @param address Dbus socket address + * @return status of this function call */ ScStatus create(const std::string& address) noexcept; @@ -136,14 +136,14 @@ public: */ ScStatus sc_notification(ScNotificationCallback notificationCallback) noexcept; /** - * @see ::sc_start + * @see ::sc_start_glib_loop */ - static ScStatus sc_start() noexcept; + static ScStatus sc_start_glib_loop() noexcept; /** - * @see ::sc_stop + * @see ::sc_stop_glib_loop */ - static ScStatus sc_stop() noexcept; + static ScStatus sc_stop_glib_loop() noexcept; }; #endif /* SECURITY_CONTAINERS_CLIENT_IMPL_HPP */ diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index 12a3d6d..f0b3f63 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -27,7 +27,6 @@ #include "security-containers-client.h" #include "security-containers-client-impl.hpp" -#include #include #ifndef API @@ -38,63 +37,39 @@ using namespace std; namespace { -typedef Client* ClientPtr; - -ClientPtr getClient(ScClient client) +Client& getClient(ScClient client) { assert(client); - return reinterpret_cast(client); + return *reinterpret_cast(client); } } // namespace /* external */ -API ScStatus sc_start() +API ScStatus sc_start_glib_loop() { - return Client::sc_start(); + return Client::sc_start_glib_loop(); } -API ScStatus sc_stop() +API ScStatus sc_stop_glib_loop() { - return Client::sc_stop(); + return Client::sc_stop_glib_loop(); } -API ScStatus sc_get_client(ScClient* client, ScClientType type, ...) +API ScClient sc_client_create() { - const char* address = NULL; - va_list vl; - va_start(vl, type); - if (type == SCCLIENT_CUSTOM_TYPE) { - address = va_arg(vl, const char*); - assert(address); - } - va_end(vl); - - assert(client); Client* clientPtr = new(nothrow) Client(); - *client = reinterpret_cast(clientPtr); - if (clientPtr == NULL) { - return SCCLIENT_NOT_ENOUGH_MEMORY; - } + return reinterpret_cast(clientPtr); +} - ScStatus status; - switch (type) { - case SCCLIENT_CUSTOM_TYPE: - status = clientPtr->create(address); - break; - case SCCLIENT_SYSTEM_TYPE: - status = clientPtr->createSystem(); - break; - default: - assert(!"Logic error. No such ScClient type"); - status = SCCLIENT_EXCEPTION; - } - return status; +API ScStatus sc_connect(ScClient client) +{ + return getClient(client).createSystem(); } -API int sc_is_failed(ScStatus status) +API ScStatus sc_connect_custom(ScClient client, const char* address) { - return status != SCCLIENT_SUCCESS ? 1 : 0; + return getClient(client).create(address); } API void sc_array_string_free(ScArrayString astring) @@ -117,54 +92,54 @@ API void sc_string_free(ScString string) API void sc_client_free(ScClient client) { if (client != NULL) { - delete getClient(client); + delete &getClient(client); } } API const char* sc_get_status_message(ScClient client) { - return getClient(client)->sc_get_status_message(); + return getClient(client).sc_get_status_message(); } API ScStatus sc_get_status(ScClient client) { - return getClient(client)->sc_get_status(); + return getClient(client).sc_get_status(); } API ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArrayString* values) { - return getClient(client)->sc_get_container_dbuses(keys, values); + return getClient(client).sc_get_container_dbuses(keys, values); } API ScStatus sc_get_container_ids(ScClient client, ScArrayString* array) { - return getClient(client)->sc_get_container_ids(array); + return getClient(client).sc_get_container_ids(array); } API ScStatus sc_get_active_container_id(ScClient client, ScString* id) { - return getClient(client)->sc_get_active_container_id(id); + return getClient(client).sc_get_active_container_id(id); } API ScStatus sc_set_active_container(ScClient client, const char* id) { - return getClient(client)->sc_set_active_container(id); + return getClient(client).sc_set_active_container(id); } API ScStatus sc_container_dbus_state(ScClient client, ScContainerDbusStateCallback containerDbusStateCallback) { - return getClient(client)->sc_container_dbus_state(containerDbusStateCallback); + return getClient(client).sc_container_dbus_state(containerDbusStateCallback); } API ScStatus sc_notify_active_container(ScClient client, const char* application, const char* message) { - return getClient(client)->sc_notify_active_container(application, message); + return getClient(client).sc_notify_active_container(application, message); } API ScStatus sc_notification(ScClient client, ScNotificationCallback notificationCallback) { - return getClient(client)->sc_notification(notificationCallback); + return getClient(client).sc_notification(notificationCallback); } diff --git a/client/security-containers-client.h b/client/security-containers-client.h index 01ca12c..aeb69fb 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -54,90 +54,89 @@ typedef ScString* ScArrayString; * Completion status of communication function. */ typedef enum { - SCCLIENT_DBUS_CUSTOM_EXCEPTION, - SCCLIENT_DBUS_IO_EXCEPTION, - SCCLIENT_DBUS_OPERATION_EXCEPTION, - SCCLIENT_DBUS_INVALID_ARGUMENT_EXCEPTION, - SCCLIENT_DBUS_EXCEPTION, - SCCLIENT_NOT_ENOUGH_MEMORY, - SCCLIENT_RUNTIME_EXCEPTION, - SCCLIENT_EXCEPTION, - SCCLIENT_SUCCESS + SCCLIENT_CUSTOM_ERROR, ///< User specified error + SCCLIENT_IO_ERROR, ///< Input/Output error + SCCLIENT_OPERATION_FAILED, ///< Operation failed + SCCLIENT_INVALID_ARGUMENT, ///< Invalid argument + SCCLIENT_OTHER_ERROR, ///< Other error + SCCLIENT_SUCCESS ///< Success } ScStatus; -typedef enum { - SCCLIENT_SYSTEM_TYPE, - SCCLIENT_CUSTOM_TYPE -} ScClientType; - /** - * Initialize communication resources. + * Start glib loop. + * + * Do not call this function if the application creates glib loop itself. + * Otherwise call it before any other function from this library. + * + * @return status of this function call */ -ScStatus sc_start(); +ScStatus sc_start_glib_loop(); /** - * Release communication resources. + * Stop glib loop. * - * @return Status of this function call. + * @return status of this function call */ -ScStatus sc_stop(); +ScStatus sc_stop_glib_loop(); /** - * Create a security-containers-server's client. + * Create a new security-containers-server's client. * - * After calling this function a connection to security-containers-server is established. - * - * @param[out] client security-containers-server's client who will be returned. - * Client can be broken. To check this you must call sc_is_failed(). - * Broken client can't be used to communicate with security-containers-server. - * @param[in] type Type of client. - * @param[in] @optional address Dbus socket address (significant only for type SCCLIENT_CUSTOM_TYPE). - * @return Status of this function call. + * @return created client */ -ScStatus sc_get_client(ScClient* client, ScClientType type, /* const char* address */ ...); +ScClient sc_client_create(); /** * Release client resources. * - * @param client security-containers-server's client. + * @param client security-containers-server's client */ void sc_client_free(ScClient client); /** + * Get status code of last security-containers-server communication. + * + * @param client security-containers-server's client + * @return status of this function call + */ +ScStatus sc_get_status(ScClient client); + +/** * Get status message of the last security-containers-server communication. * - * @param client security-containers-server's client. - * @return Last status message from security-containers-server communication. + * @param client security-containers-server's client + * @return last status message from security-containers-server communication */ const char* sc_get_status_message(ScClient client); /** - * Get status code of last security-containers-server communication. + * Connect client to the security-containers-server. * - * @param client security-containers-server's client. - * @return Status of this function call. + * @param client security-containers-server's client + * @return status of this function call */ -ScStatus sc_get_status(ScClient client); +ScStatus sc_connect(ScClient client); /** - * Check if security-containers-server communication function fail. + * Connect client to the security-containers-server via custom address. * - * @param status Value returned by security-containers-server communication function. - * @return 0 if succeeded otherwise 1. + * @param client security-containers-server's client + * @param address dbus address + * @return status of this function call */ -int sc_is_failed(ScStatus status); +ScStatus sc_connect_custom(ScClient client, const char* address); /** * Release ScArrayString. * - * @param astring ScArrayString. + * @param astring ScArrayString */ void sc_array_string_free(ScArrayString astring); /** * Release ScString. * - * @param string ScString. + * @param string ScString */ void sc_string_free(ScString string); @@ -156,38 +155,38 @@ typedef void (*ScContainerDbusStateCallback)(const char* containerId, const char /** * Get dbus address of each container. * - * @param[in] client security-containers-server's client. - * @param[out] keys Array of containers name. - * @param[out] values Array of containers dbus address. - * @return Status of this function call. - * @post keys[i] corresponds to values[i]. + * @param[in] client security-containers-server's client + * @param[out] keys array of containers name + * @param[out] values array of containers dbus address + * @return status of this function call + * @post keys[i] corresponds to values[i] */ ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArrayString* values); /** * Get containers name. * - * @param[in] client security-containers-server's client. - * @param[out] array Array of containers name. - * @return Status of this function call. + * @param[in] client security-containers-server's client + * @param[out] array array of containers name + * @return status of this function call */ ScStatus sc_get_container_ids(ScClient client, ScArrayString* array); /** * Get active container name. * - * @param[in] client security-containers-server's client. - * @param[out] id Active container name. - * @return Status of this function call. + * @param[in] client security-containers-server's client + * @param[out] id active container name + * @return status of this function call */ ScStatus sc_get_active_container_id(ScClient client, ScString* id); /** * Set active container. * - * @param client security-containers-server's client. - * @param id Container name. - * @return Status of this function call. + * @param client security-containers-server's client + * @param id container name + * @return status of this function call */ ScStatus sc_set_active_container(ScClient client, const char* id); @@ -196,9 +195,9 @@ ScStatus sc_set_active_container(ScClient client, const char* id); * * The callback function will be invoked on a different thread * - * @param client security-containers-server's client. - * @param containerDbusStateCallback Callback function. - * @return Status of this function call. + * @param client security-containers-server's client + * @param containerDbusStateCallback callback function + * @return status of this function call */ ScStatus sc_container_dbus_state(ScClient client, ScContainerDbusStateCallback containerDbusStateCallback); @@ -219,10 +218,10 @@ typedef void (*ScNotificationCallback)(const char* container, /** * Send message to active container. * - * @param client security-containers-server's client. - * @param application Application name. - * @param message Message. - * @return Status of this function call. + * @param client security-containers-server's client + * @param application application name + * @param message message + * @return status of this function call */ ScStatus sc_notify_active_container(ScClient client, const char* application, const char* message); @@ -231,9 +230,9 @@ ScStatus sc_notify_active_container(ScClient client, const char* application, co * * The callback function will be invoked on a different thread. * - * @param client security-containers-server's client. - * @param notificationCallback Callback function. - * @return Status of this function call. + * @param client security-containers-server's client + * @param notificationCallback callback function + * @return status of this function call */ ScStatus sc_notification(ScClient client, ScNotificationCallback notificationCallback); #ifdef __cplusplus diff --git a/common/utils/glib-loop.cpp b/common/utils/glib-loop.cpp index a735e1e..3d76928 100644 --- a/common/utils/glib-loop.cpp +++ b/common/utils/glib-loop.cpp @@ -26,15 +26,25 @@ #include "utils/glib-loop.hpp" #include "utils/callback-wrapper.hpp" +#include +#include #include namespace security_containers { namespace utils { +namespace { +std::atomic_bool gLoopPresent(false); +} + ScopedGlibLoop::ScopedGlibLoop() : mLoop(g_main_loop_new(NULL, FALSE), g_main_loop_unref) { + if (gLoopPresent.exchange(true)) { + // only one loop per process + assert(0 && "Loop is already running"); + } #if !GLIB_CHECK_VERSION(2,36,0) g_type_init(); #endif @@ -52,6 +62,7 @@ ScopedGlibLoop::~ScopedGlibLoop() //stop loop and wait g_main_loop_quit(mLoop.get()); mLoopThread.join(); + gLoopPresent = false; } void Glib::addTimerEvent(const unsigned int intervalMs, diff --git a/tests/scripts/sc_test_parser.py b/tests/scripts/sc_test_parser.py index 5299814..b8ec404 100644 --- a/tests/scripts/sc_test_parser.py +++ b/tests/scripts/sc_test_parser.py @@ -84,10 +84,17 @@ class Logger(object): def terminatedBySignal(self, bin, signum): self.error("\n=========== FAILED ===========\n") - signame = {2:"SIGINT", 9:"SIGKILL", 11:"SIGSEGV", 15:"SIGTERM"} + signame = { 2: "SIGINT (Interrupt)", + 3: "SIGQUIT (Quit)", + 5: "SIGTRAP (Trace trap)", + 6: "SIGABRT (Abort)", + 8: "SIGFPE (Floating-point exception)", + 9: "SIGKILL (Kill)", + 11: "SIGSEGV (Segmentation fault)", + 15: "SIGTERM (Termination)"} siginfo = signame.get(signum, 'signal ' + str(signum)) self.error('Terminated by ' + siginfo) - if signum == 11: # SIGSEGV + if signum in [5, 6, 8, 11]: self.error("\nUse following command to launch debugger:") self.error(self.__indentChar + "sc_launch_test.py --gdb " + bin) diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index cab82e1..dc6045a 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -46,9 +46,19 @@ namespace { const std::string TEST_DBUS_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/client/ut-client/test-dbus-daemon.conf"; +struct Loop { + Loop() { sc_start_glib_loop(); }; + ~Loop() { sc_stop_glib_loop(); }; +}; + struct Fixture { - Fixture() { sc_start(); }; - ~Fixture() { sc_stop(); }; + Loop loop; + ContainersManager cm; + + Fixture(): cm(TEST_DBUS_CONFIG_PATH) + { + cm.startAll(); + }; }; const int EVENT_TIMEOUT = 5000; ///< ms @@ -64,8 +74,8 @@ void convertDictToMap(ScArrayString keys, ScArrayString values, std::map& ret) { - char** iKeys; - char** iValues; + ScArrayString iKeys; + ScArrayString iValues; for (iKeys = keys, iValues = values; *iKeys && *iValues; iKeys++, iValues++) { ret.insert(std::make_pair(*iKeys, *iValues)); } @@ -73,7 +83,7 @@ void convertDictToMap(ScArrayString keys, void convertArrayToSet(ScArrayString values, std::set& ret) { - for (char** iValues = values; *iValues; iValues++) { + for (ScArrayString iValues = values; *iValues; iValues++) { ret.insert(*iValues); } } @@ -104,25 +114,23 @@ BOOST_FIXTURE_TEST_SUITE(Client, Fixture) BOOST_AUTO_TEST_CASE(NotRunningServerTest) { - ScClient client; - ScStatus status = sc_get_client(&client, - SCCLIENT_CUSTOM_TYPE, - EXPECTED_DBUSES_STARTED.begin()->second.c_str()); - BOOST_CHECK(sc_is_failed(status)); + cm.stopAll(); + + ScClient client = sc_client_create(); + ScStatus status = sc_connect_custom(client, + EXPECTED_DBUSES_STARTED.begin()->second.c_str()); + BOOST_CHECK_EQUAL(SCCLIENT_IO_ERROR, status); sc_client_free(client); } BOOST_AUTO_TEST_CASE(GetContainerDbusesTest) { - std::unique_ptr cm; - BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); - cm->startAll(); - ScClient client; - ScStatus status = sc_get_client(&client, SCCLIENT_SYSTEM_TYPE); - BOOST_REQUIRE(!sc_is_failed(status)); + ScClient client = sc_client_create(); + ScStatus status = sc_connect(client); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); ScArrayString keys, values; status = sc_get_container_dbuses(client, &keys, &values); - BOOST_REQUIRE(!sc_is_failed(status)); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(getArrayStringLength(keys, EXPECTED_DBUSES_STARTED.size() + 1), EXPECTED_DBUSES_STARTED.size()); @@ -135,20 +143,16 @@ BOOST_AUTO_TEST_CASE(GetContainerDbusesTest) sc_array_string_free(keys); sc_array_string_free(values); sc_client_free(client); - BOOST_WARN_NO_THROW(cm.reset()); } BOOST_AUTO_TEST_CASE(GetContainerIdsTest) { - std::unique_ptr cm; - BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); - cm->startAll(); - ScClient client; - ScStatus status = sc_get_client(&client, SCCLIENT_SYSTEM_TYPE); - BOOST_REQUIRE(!sc_is_failed(status)); + ScClient client = sc_client_create(); + ScStatus status = sc_connect(client); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); ScArrayString values; status = sc_get_container_ids(client, &values); - BOOST_REQUIRE(!sc_is_failed(status)); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_DBUSES_STARTED.size() + 1), EXPECTED_DBUSES_STARTED.size()); @@ -160,71 +164,54 @@ BOOST_AUTO_TEST_CASE(GetContainerIdsTest) } sc_array_string_free(values); sc_client_free(client); - - BOOST_WARN_NO_THROW(cm.reset()); } BOOST_AUTO_TEST_CASE(GetActiveContainerIdTest) { - std::unique_ptr cm; - BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); - cm->startAll(); - - ScClient client; - ScStatus status = sc_get_client(&client, SCCLIENT_SYSTEM_TYPE); - BOOST_REQUIRE(!sc_is_failed(status)); + ScClient client = sc_client_create(); + ScStatus status = sc_connect(client); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); ScString container; status = sc_get_active_container_id(client, &container); - BOOST_REQUIRE(!sc_is_failed(status)); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); - BOOST_CHECK_EQUAL(container, cm->getRunningForegroundContainerId()); + BOOST_CHECK_EQUAL(container, cm.getRunningForegroundContainerId()); sc_string_free(container); sc_client_free(client); - - BOOST_WARN_NO_THROW(cm.reset()); } BOOST_AUTO_TEST_CASE(SetActiveContainerTest) { - std::string newActiveContainerId = "ut-containers-manager-console2-dbus"; + const std::string newActiveContainerId = "ut-containers-manager-console2-dbus"; - std::unique_ptr cm; - BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); - cm->startAll(); - BOOST_REQUIRE_NE(newActiveContainerId, cm->getRunningForegroundContainerId()); + BOOST_REQUIRE_NE(newActiveContainerId, cm.getRunningForegroundContainerId()); - ScClient client; - ScStatus status = sc_get_client(&client, SCCLIENT_SYSTEM_TYPE); - BOOST_REQUIRE(!sc_is_failed(status)); + ScClient client = sc_client_create(); + ScStatus status = sc_connect(client); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); status = sc_set_active_container(client, newActiveContainerId.c_str()); - BOOST_REQUIRE(!sc_is_failed(status)); - BOOST_CHECK_EQUAL(newActiveContainerId, cm->getRunningForegroundContainerId()); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + BOOST_CHECK_EQUAL(newActiveContainerId, cm.getRunningForegroundContainerId()); sc_client_free(client); - BOOST_WARN_NO_THROW(cm.reset()); } BOOST_AUTO_TEST_CASE(NotificationTest) { - std::string activeContainerId = "ut-containers-manager-console1-dbus"; - std::unique_ptr cm; - BOOST_REQUIRE_NO_THROW(cm.reset(new ContainersManager(TEST_DBUS_CONFIG_PATH))); - cm->startAll(); - std::map clients; for (const auto& it : EXPECTED_DBUSES_STARTED) { - ScClient client; - ScStatus status = sc_get_client(&client, SCCLIENT_CUSTOM_TYPE, it.second.c_str()); - BOOST_REQUIRE(!sc_is_failed(status)); + ScClient client = sc_client_create(); + ScStatus status = sc_connect_custom(client, it.second.c_str()); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); clients[it.first] = client; } for (auto& client : clients) { ScStatus status = sc_notification(client.second, NotificationTestCallback); - BOOST_REQUIRE(!sc_is_failed(status)); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); } for (auto& client : clients) { ScStatus status = sc_notify_active_container(client.second, "app", "msg"); - BOOST_REQUIRE(!sc_is_failed(status)); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); } BOOST_CHECK(signalReceivedLatch.waitForN(clients.size() - 1, EVENT_TIMEOUT)); @@ -233,7 +220,6 @@ BOOST_AUTO_TEST_CASE(NotificationTest) for (auto& client : clients) { sc_client_free(client.second); } - BOOST_WARN_NO_THROW(cm.reset()); } BOOST_AUTO_TEST_SUITE_END() -- 2.7.4