From 467ce343680c60bb9d7a368f06ef3b3ca428a7e9 Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Fri, 9 Jan 2015 15:13:36 +0100
Subject: [PATCH 01/16] Improve config tests
[Bug/Feature] N/A
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run tests
Change-Id: I6fc7974d3379d4a96aa712e3e00b8798e6d90181
---
tests/unit_tests/config/testconfig-example.hpp | 12 ++++
tests/unit_tests/config/ut-configuration.cpp | 96 ++++++++++++++++++++++----
tests/unit_tests/config/ut-dynvisit.cpp | 17 ++---
tests/unit_tests/config/ut-kvstore.cpp | 16 ++---
4 files changed, 112 insertions(+), 29 deletions(-)
diff --git a/tests/unit_tests/config/testconfig-example.hpp b/tests/unit_tests/config/testconfig-example.hpp
index 35e846e..c8563d0 100644
--- a/tests/unit_tests/config/testconfig-example.hpp
+++ b/tests/unit_tests/config/testconfig-example.hpp
@@ -122,6 +122,18 @@ struct TestConfig {
)
};
+struct PartialTestConfig {
+ // a subset of TestConfig fields
+ std::string stringVal;
+ std::vector intVector;
+
+ CONFIG_REGISTER
+ (
+ stringVal,
+ intVector
+ )
+};
+
/**
* JSON string used in ConfigSuite test cases
* For the purpose of these tests the order of this string
diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp
index bbf9ed9..e014f68 100644
--- a/tests/unit_tests/config/ut-configuration.cpp
+++ b/tests/unit_tests/config/ut-configuration.cpp
@@ -27,19 +27,30 @@
#include "ut.hpp"
#include "testconfig-example.hpp"
#include "config/manager.hpp"
+#include "utils/scoped-dir.hpp"
#include
#include
#include
-#include
-namespace fs = boost::filesystem;
+namespace {
+
using namespace config;
-BOOST_AUTO_TEST_SUITE(ConfigurationSuite)
+const std::string UT_PATH = "/tmp/ut-config/";
+const std::string DB_PATH = UT_PATH + "kvstore.db3";
+const std::string DB_PREFIX = "ut";
// Floating point tolerance as a number of rounding errors
const int TOLERANCE = 1;
+struct Fixture {
+ vasum::utils::ScopedDir mUTDirGuard;
+ Fixture() : mUTDirGuard(UT_PATH) {}
+};
+
+} // namespace
+
+BOOST_FIXTURE_TEST_SUITE(ConfigurationSuite, Fixture)
BOOST_AUTO_TEST_CASE(FromStringTest)
{
@@ -249,17 +260,12 @@ BOOST_AUTO_TEST_CASE(FromToKVStoreTest)
TestConfig config;
loadFromJsonString(jsonTestString, config);
- std::string dbPath = fs::unique_path("/tmp/kvstore-%%%%.db3").string();
-
- saveToKVStore(dbPath, config, "prefix");
+ saveToKVStore(DB_PATH, config, DB_PREFIX);
TestConfig outConfig;
- loadFromKVStore(dbPath, outConfig, "prefix");
+ loadFromKVStore(DB_PATH, outConfig, DB_PREFIX);
std::string out = saveToJsonString(outConfig);
BOOST_CHECK_EQUAL(out, jsonTestString);
-
- fs::remove(dbPath);
- fs::remove(dbPath + "-journal");
}
BOOST_AUTO_TEST_CASE(FromToFDTest)
@@ -267,7 +273,7 @@ BOOST_AUTO_TEST_CASE(FromToFDTest)
TestConfig config;
loadFromJsonString(jsonTestString, config);
// Setup fd
- std::string fifoPath = fs::unique_path("/tmp/fdstore-%%%%").string();
+ std::string fifoPath = UT_PATH + "fdstore";
BOOST_CHECK(::mkfifo(fifoPath.c_str(), S_IWUSR | S_IRUSR) >= 0);
int fd = ::open(fifoPath.c_str(), O_RDWR);
BOOST_REQUIRE(fd >= 0);
@@ -281,7 +287,73 @@ BOOST_AUTO_TEST_CASE(FromToFDTest)
// Cleanup
BOOST_CHECK(::close(fd) >= 0);
- fs::remove(fifoPath);
+}
+
+BOOST_AUTO_TEST_CASE(FromKVWithDefaultsTest)
+{
+ TestConfig config;
+ loadFromJsonString(jsonTestString, config);
+
+ // nothing in db
+ TestConfig outConfig1;
+ loadFromKVStoreWithJson(DB_PATH, jsonTestString, outConfig1, DB_PREFIX);
+
+ std::string out1 = saveToJsonString(outConfig1);
+ BOOST_CHECK_EQUAL(out1, jsonTestString);
+
+ // all in db
+ saveToKVStore(DB_PATH, config, DB_PREFIX);
+ TestConfig outConfig2;
+ outConfig2.union1.set(0);
+ outConfig2.union2.set(0);
+ std::string emptyConfig = saveToJsonString(outConfig2);
+ loadFromKVStoreWithJson(DB_PATH, emptyConfig, outConfig2, DB_PREFIX);
+
+ std::string out2 = saveToJsonString(outConfig2);
+ BOOST_CHECK_EQUAL(out2, jsonTestString);
+}
+
+BOOST_AUTO_TEST_CASE(PartialConfigTest)
+{
+ // check if partial config is fully supported
+ TestConfig config;
+ loadFromJsonString(jsonTestString, config);
+
+ // from string
+ {
+ PartialTestConfig partialConfig;
+ loadFromJsonString(jsonTestString, partialConfig);
+
+ BOOST_CHECK_EQUAL(config.stringVal, partialConfig.stringVal);
+ BOOST_CHECK(config.intVector == partialConfig.intVector);
+ }
+
+ // from kv
+ {
+ PartialTestConfig partialConfig;
+ saveToKVStore(DB_PATH, config, DB_PREFIX);
+ loadFromKVStore(DB_PATH, partialConfig, DB_PREFIX);
+
+ BOOST_CHECK_EQUAL(config.stringVal, partialConfig.stringVal);
+ BOOST_CHECK(config.intVector == partialConfig.intVector);
+ }
+
+ // from kv with defaults
+ {
+ PartialTestConfig partialConfig;
+ loadFromKVStoreWithJson(DB_PATH, jsonTestString, partialConfig, DB_PREFIX);
+
+ BOOST_CHECK_EQUAL(config.stringVal, partialConfig.stringVal);
+ BOOST_CHECK(config.intVector == partialConfig.intVector);
+ }
+
+ // save to kv
+ {
+ PartialTestConfig partialConfig;
+ partialConfig.stringVal = "partial";
+ partialConfig.intVector = {7};
+ config::saveToKVStore(DB_PATH, partialConfig, DB_PREFIX);
+ }
}
BOOST_AUTO_TEST_CASE(ConfigUnionTest)
diff --git a/tests/unit_tests/config/ut-dynvisit.cpp b/tests/unit_tests/config/ut-dynvisit.cpp
index dd782f3..2050def 100644
--- a/tests/unit_tests/config/ut-dynvisit.cpp
+++ b/tests/unit_tests/config/ut-dynvisit.cpp
@@ -26,31 +26,32 @@
#include "config.hpp"
#include "ut.hpp"
#include "testconfig-example.hpp"
+#include "utils/scoped-dir.hpp"
#include "config/manager.hpp"
-#include
#include "config/from-kvjson-visitor.hpp"
+namespace {
using namespace config;
-namespace fs = boost::filesystem;
+
+const std::string UT_PATH = "/tmp/ut-config/";
struct Fixture {
+ vasum::utils::ScopedDir mUTDirGuard;
std::string dbPath;
std::string dbPrefix;
Fixture()
- : dbPath(fs::unique_path("/tmp/kvstore-%%%%.db3").string())
+ : mUTDirGuard(UT_PATH)
+ , dbPath(UT_PATH + "kvstore.db3")
, dbPrefix("conf")
{
- fs::remove(dbPath);
- }
- ~Fixture()
- {
- fs::remove(dbPath);
}
};
+} // namespace
+
BOOST_FIXTURE_TEST_SUITE(DynVisitSuite, Fixture)
void checkJsonConfig(const TestConfig& cfg, const std::string& json)
diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp
index ba95452..9855457 100644
--- a/tests/unit_tests/config/ut-kvstore.cpp
+++ b/tests/unit_tests/config/ut-kvstore.cpp
@@ -28,6 +28,7 @@
#include "config/kvstore.hpp"
#include "config/exception.hpp"
+#include "utils/scoped-dir.hpp"
#include
#include
@@ -38,19 +39,18 @@ namespace fs = boost::filesystem;
namespace {
+const std::string UT_PATH = "/tmp/ut-config/";
+
struct Fixture {
+ vasum::utils::ScopedDir mUTDirGuard;
std::string dbPath;
KVStore c;
Fixture()
- : dbPath(fs::unique_path("/tmp/kvstore-%%%%.db3").string()),
- c(dbPath)
- {
- }
- ~Fixture()
+ : mUTDirGuard(UT_PATH)
+ , dbPath(UT_PATH + "kvstore.db3")
+ , c(dbPath)
{
- fs::remove(dbPath);
- fs::remove(dbPath + "-journal");
}
};
@@ -97,7 +97,6 @@ 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));
@@ -105,7 +104,6 @@ BOOST_AUTO_TEST_CASE(SimpleConstructorDestructorTest)
BOOST_CHECK(fs::exists(dbPath));
BOOST_REQUIRE_NO_THROW(conPtr.reset());
BOOST_CHECK(fs::exists(dbPath));
- fs::remove(dbPath);
}
BOOST_AUTO_TEST_CASE(EscapedCharactersTest)
--
2.7.4
From 8d508112b8644e21a065307b3bff7a4c93162234 Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Thu, 22 Jan 2015 12:51:04 +0100
Subject: [PATCH 02/16] Fix LxcZoneSuite/StartStopTest
[Bug/Feature] Test was failing
[Cause] N/A
[Solution] N/A
[Verification] Build, run tests
Change-Id: Ia87dbd173cfe58f216adac1141a15d854e91159c
---
tests/unit_tests/lxc/ut-zone.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/unit_tests/lxc/ut-zone.cpp b/tests/unit_tests/lxc/ut-zone.cpp
index b80e261..6840e31 100644
--- a/tests/unit_tests/lxc/ut-zone.cpp
+++ b/tests/unit_tests/lxc/ut-zone.cpp
@@ -138,8 +138,11 @@ BOOST_AUTO_TEST_CASE(StartStopTest)
};
BOOST_CHECK(lxc.start(argv));
BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING);
+ waitForInit();
+#ifndef USE_EXEC // TODO improve shutdown implementation
BOOST_CHECK(!lxc.shutdown(1));
BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING);
+#endif
BOOST_CHECK(lxc.stop());
BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED);
--
2.7.4
From ca9543ec62d3c1295677758be5df99cad79085e0 Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Thu, 22 Jan 2015 09:34:38 +0100
Subject: [PATCH 03/16] Provisioning uses dynamic configuration
[Bug/Feature] N/A
[Cause] N/A
[Solution] N/A
[Verification] Build, run tests
Change-Id: If1762b8d0993a98048d2f9310981c53f2a913124
---
server/configs/templates/template.conf | 1 +
server/zone-provision-config.hpp | 8 +-
server/zone-provision.cpp | 98 +++++------
server/zone-provision.hpp | 38 ++--
server/zone.cpp | 11 +-
server/zone.hpp | 2 +
server/zones-manager.cpp | 3 +-
server/zones-manager.hpp | 2 +-
.../configs/ut-client/zones/console1-dbus.conf.in | 1 +
.../configs/ut-client/zones/console2-dbus.conf.in | 1 +
.../configs/ut-client/zones/console3-dbus.conf.in | 1 +
tests/unit_tests/server/configs/CMakeLists.txt | 5 +
.../server/configs/ut-server/zones/zone1.conf | 1 +
.../server/configs/ut-server/zones/zone2.conf | 1 +
.../server/configs/ut-server/zones/zone3.conf | 1 +
.../server/configs/ut-zone-admin/zones/buggy.conf | 1 +
.../configs/ut-zone-admin/zones/missing.conf | 1 +
.../ut-zone-admin/zones/test-no-shutdown.conf | 1 +
.../server/configs/ut-zone-admin/zones/test.conf | 1 +
.../server/configs/ut-zone-provision/test.conf | 3 +
.../server/configs/ut-zone/zones/buggy.conf | 1 +
.../server/configs/ut-zone/zones/test-dbus.conf.in | 1 +
.../server/configs/ut-zone/zones/test.conf | 1 +
.../ut-zones-manager/templates/template.conf.in | 1 +
.../ut-zones-manager/zones/console1-dbus.conf.in | 1 +
.../configs/ut-zones-manager/zones/console1.conf | 1 +
.../ut-zones-manager/zones/console2-dbus.conf.in | 1 +
.../configs/ut-zones-manager/zones/console2.conf | 1 +
.../ut-zones-manager/zones/console3-dbus.conf.in | 1 +
.../configs/ut-zones-manager/zones/console3.conf | 1 +
tests/unit_tests/server/ut-zone-provision.cpp | 196 ++++++++++++---------
tests/unit_tests/server/ut-zone.cpp | 2 +
32 files changed, 225 insertions(+), 164 deletions(-)
create mode 100644 tests/unit_tests/server/configs/ut-zone-provision/test.conf
diff --git a/server/configs/templates/template.conf b/server/configs/templates/template.conf
index e011a64..9690a87 100644
--- a/server/configs/templates/template.conf
+++ b/server/configs/templates/template.conf
@@ -11,6 +11,7 @@
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : true,
"runMountPoint" : "~NAME~/run",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : [ "/tmp/",
diff --git a/server/zone-provision-config.hpp b/server/zone-provision-config.hpp
index 5a9f5ff..93fe1a0 100644
--- a/server/zone-provision-config.hpp
+++ b/server/zone-provision-config.hpp
@@ -34,7 +34,7 @@
namespace vasum {
-struct ZoneProvisioning
+struct ZoneProvisioningConfig
{
struct File
@@ -83,7 +83,7 @@ struct ZoneProvisioning
)
};
- struct Unit
+ struct Provision
{
CONFIG_DECLARE_UNION
(
@@ -93,11 +93,11 @@ struct ZoneProvisioning
)
};
- std::vector units;
+ std::vector provisions;
CONFIG_REGISTER
(
- units
+ provisions
)
};
diff --git a/server/zone-provision.cpp b/server/zone-provision.cpp
index c04a32a..928d887 100644
--- a/server/zone-provision.cpp
+++ b/server/zone-provision.cpp
@@ -42,29 +42,17 @@ namespace fs = boost::filesystem;
namespace vasum {
-namespace {
-
-const std::string ZONE_PROVISION_FILE = "provision.conf";
-
-void declareUnit(const std::string& file, ZoneProvisioning::Unit&& unit)
-{
- // TODO: Add to the dynamic configuration
- ZoneProvisioning config;
- if (fs::exists(file)) {
- config::loadFromJsonFile(file, config);
- }
- config.units.push_back(std::move(unit));
- config::saveToJsonFile(file, config);
-}
-
-} // namespace
-
-ZoneProvision::ZoneProvision(const std::string& zonePath,
+ZoneProvision::ZoneProvision(const std::string& rootPath,
+ const std::string& configPath,
+ const std::string& dbPath,
+ const std::string& dbPrefix,
const std::vector& validLinkPrefixes)
+ : mRootPath(rootPath)
+ , mDbPath(dbPath)
+ , mDbPrefix(dbPrefix)
+ , mValidLinkPrefixes(validLinkPrefixes)
{
- mProvisionFile = (fs::path(zonePath) / fs::path(ZONE_PROVISION_FILE)).string();
- mRootPath = (zonePath / fs::path("rootfs")).string();
- mValidLinkPrefixes = validLinkPrefixes;
+ config::loadFromKVStoreWithJsonFile(dbPath, configPath, mProvisioningConfig, dbPrefix);
}
ZoneProvision::~ZoneProvision()
@@ -72,21 +60,26 @@ ZoneProvision::~ZoneProvision()
stop();
}
-std::string ZoneProvision::getRootPath() const
+void ZoneProvision::saveProvisioningConfig()
{
- return mRootPath;
+ config::saveToKVStore(mDbPath, mProvisioningConfig, mDbPrefix);
}
+void ZoneProvision::declareProvision(ZoneProvisioningConfig::Provision&& provision)
+{
+ mProvisioningConfig.provisions.push_back(std::move(provision));
+ saveProvisioningConfig();
+}
void ZoneProvision::declareFile(const int32_t& type,
const std::string& path,
const int32_t& flags,
const int32_t& mode)
{
- ZoneProvisioning::Unit unit;
- unit.set(ZoneProvisioning::File({type, path, flags, mode}));
+ ZoneProvisioningConfig::Provision provision;
+ provision.set(ZoneProvisioningConfig::File({type, path, flags, mode}));
- declareUnit(mProvisionFile, std::move(unit));
+ declareProvision(std::move(provision));
}
void ZoneProvision::declareMount(const std::string& source,
@@ -95,49 +88,46 @@ void ZoneProvision::declareMount(const std::string& source,
const int64_t& flags,
const std::string& data)
{
- ZoneProvisioning::Unit unit;
- unit.set(ZoneProvisioning::Mount({source, target, type, flags, data}));
+ ZoneProvisioningConfig::Provision provision;
+ provision.set(ZoneProvisioningConfig::Mount({source, target, type, flags, data}));
- declareUnit(mProvisionFile, std::move(unit));
+ declareProvision(std::move(provision));
}
void ZoneProvision::declareLink(const std::string& source,
const std::string& target)
{
- ZoneProvisioning::Unit unit;
- unit.set(ZoneProvisioning::Link({source, target}));
+ ZoneProvisioningConfig::Provision provision;
+ provision.set(ZoneProvisioningConfig::Link({source, target}));
- declareUnit(mProvisionFile, std::move(unit));
+ declareProvision(std::move(provision));
}
void ZoneProvision::start() noexcept
{
- if (fs::exists(mProvisionFile)) {
- config::loadFromJsonFile(mProvisionFile, mProvisioningConfig);
- for (const auto& unit : mProvisioningConfig.units) {
- try {
- if (unit.is()) {
- file(unit.as());
- } else if (unit.is()) {
- mount(unit.as());
- } else if (unit.is()) {
- link(unit.as());
- }
- // mProvisioned must be FILO
- mProvisioned.push_front(unit);
- } catch (const std::exception& ex) {
- LOGE("Provsion error: " << ex.what());
+ for (const auto& provision : mProvisioningConfig.provisions) {
+ try {
+ if (provision.is()) {
+ file(provision.as());
+ } else if (provision.is()) {
+ mount(provision.as());
+ } else if (provision.is()) {
+ link(provision.as());
}
+ // mProvisioned must be FILO
+ mProvisioned.push_front(provision);
+ } catch (const std::exception& ex) {
+ LOGE("Provsion error: " << ex.what());
}
}
}
void ZoneProvision::stop() noexcept
{
- mProvisioned.remove_if([this](const ZoneProvisioning::Unit& unit) -> bool {
+ mProvisioned.remove_if([this](const ZoneProvisioningConfig::Provision& provision) -> bool {
try {
- if (unit.is()) {
- umount(unit.as());
+ if (provision.is()) {
+ umount(provision.as());
}
// leaves files, links, fifo, untouched
return true;
@@ -148,7 +138,7 @@ void ZoneProvision::stop() noexcept
});
}
-void ZoneProvision::file(const ZoneProvisioning::File& config)
+void ZoneProvision::file(const ZoneProvisioningConfig::File& config)
{
bool ret = false;
const fs::path hostPath = fs::path(mRootPath) / fs::path(config.path);
@@ -183,7 +173,7 @@ void ZoneProvision::file(const ZoneProvisioning::File& config)
}
}
-void ZoneProvision::mount(const ZoneProvisioning::Mount& config)
+void ZoneProvision::mount(const ZoneProvisioningConfig::Mount& config)
{
const fs::path hostPath = fs::path(mRootPath) / fs::path(config.target);
bool ret = utils::mount(config.source,
@@ -196,7 +186,7 @@ void ZoneProvision::mount(const ZoneProvisioning::Mount& config)
}
}
-void ZoneProvision::umount(const ZoneProvisioning::Mount& config)
+void ZoneProvision::umount(const ZoneProvisioningConfig::Mount& config)
{
const fs::path hostPath = fs::path(mRootPath) / fs::path(config.target);
bool ret = utils::umount(hostPath.string());
@@ -205,7 +195,7 @@ void ZoneProvision::umount(const ZoneProvisioning::Mount& config)
}
}
-void ZoneProvision::link(const ZoneProvisioning::Link& config)
+void ZoneProvision::link(const ZoneProvisioningConfig::Link& config)
{
const std::string srcHostPath = fs::path(config.source).normalize().string();
for (const std::string& prefix : mValidLinkPrefixes) {
diff --git a/server/zone-provision.hpp b/server/zone-provision.hpp
index 5585c1f..f6933db 100644
--- a/server/zone-provision.hpp
+++ b/server/zone-provision.hpp
@@ -44,12 +44,23 @@ class ZoneProvision {
public:
/**
* ZoneProvision constructor
- * @param zonePath directory where zones are defined (lxc configs, rootfs etc)
+ * @param rootPath zone root path
+ * @param configPath path to config with defaults
+ * @param dbPath path to database
+ * @param dbPrefix database prefix
+ * @param validLinkPrefixes valid link prefixes
*/
- ZoneProvision(const std::string& zonePath,
+ ZoneProvision(const std::string& rootPath,
+ const std::string& configPath,
+ const std::string& dbPath,
+ const std::string& dbPrefix,
const std::vector& validLinkPrefixes);
~ZoneProvision();
+ ZoneProvision(const ZoneProvision&) = delete;
+ ZoneProvision& operator=(const ZoneProvision&) = delete;
+ ZoneProvision(ZoneProvision&&) = default;
+
/**
* Declare file, directory or pipe that will be created while zone startup
*/
@@ -71,25 +82,24 @@ public:
void declareLink(const std::string& source,
const std::string& target);
- /**
- * Get zone root path
- */
- std::string getRootPath() const;
-
void start() noexcept;
void stop() noexcept;
private:
- ZoneProvisioning mProvisioningConfig;
+ ZoneProvisioningConfig mProvisioningConfig;
std::string mRootPath;
- std::string mProvisionFile;
+ std::string mDbPath;
+ std::string mDbPrefix;
std::vector mValidLinkPrefixes;
- std::list mProvisioned;
+ std::list mProvisioned;
+
+ void saveProvisioningConfig();
+ void declareProvision(ZoneProvisioningConfig::Provision&& provision);
- void mount(const ZoneProvisioning::Mount& config);
- void umount(const ZoneProvisioning::Mount& config);
- void file(const ZoneProvisioning::File& config);
- void link(const ZoneProvisioning::Link& config);
+ void mount(const ZoneProvisioningConfig::Mount& config);
+ void umount(const ZoneProvisioningConfig::Mount& config);
+ void file(const ZoneProvisioningConfig::File& config);
+ void link(const ZoneProvisioningConfig::Link& config);
};
diff --git a/server/zone.cpp b/server/zone.cpp
index f35a360..fbbd819 100644
--- a/server/zone.cpp
+++ b/server/zone.cpp
@@ -48,12 +48,14 @@ typedef std::lock_guard Lock;
// TODO: move constants to the config file when default values are implemented there
const int RECONNECT_RETRIES = 15;
const int RECONNECT_DELAY = 1 * 1000;
+const std::string DB_PREFIX = "zone.";
} // namespace
Zone::Zone(const utils::Worker::Pointer& worker,
const std::string& zonesPath,
const std::string& zoneConfigPath,
+ const std::string& dbPath,
const std::string& lxcTemplatePrefix,
const std::string& baseRunMountPointPath)
: mWorker(worker)
@@ -72,8 +74,12 @@ Zone::Zone(const utils::Worker::Pointer& worker,
}
mAdmin.reset(new ZoneAdmin(zonesPath, lxcTemplatePrefix, mConfig));
+
const fs::path zonePath = fs::path(zonesPath) / mAdmin->getId();
- mProvision.reset(new ZoneProvision(zonePath.string(), mConfig.validLinkPrefixes));
+ mRootPath = (zonePath / fs::path("rootfs")).string();
+ const std::string dbPrefix = DB_PREFIX + mAdmin->getId();
+
+ mProvision.reset(new ZoneProvision(mRootPath, zoneConfigPath, dbPath, dbPrefix, mConfig.validLinkPrefixes));
}
Zone::~Zone()
@@ -185,10 +191,9 @@ int Zone::getVT() const
std::string Zone::getRootPath() const
{
- return mProvision->getRootPath();
+ return mRootPath;
}
-
bool Zone::activateVT()
{
Lock lock(mReconnectMutex);
diff --git a/server/zone.hpp b/server/zone.hpp
index 7eb34cf..2eab7f3 100644
--- a/server/zone.hpp
+++ b/server/zone.hpp
@@ -55,6 +55,7 @@ public:
Zone(const utils::Worker::Pointer& worker,
const std::string& zonesPath,
const std::string& zoneConfigPath,
+ const std::string& dbPath,
const std::string& lxcTemplatePrefix,
const std::string& baseRunMountPointPath);
Zone(Zone&&) = default;
@@ -269,6 +270,7 @@ private:
DbusStateChangedCallback mDbusStateChangedCallback;
std::string mDbusAddress;
std::string mRunMountPoint;
+ std::string mRootPath;
void onNameLostCallback();
void reconnectHandler();
diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp
index f65f9e3..99e87ee 100644
--- a/server/zones-manager.cpp
+++ b/server/zones-manager.cpp
@@ -204,6 +204,7 @@ void ZonesManager::createZone(const std::string& zoneConfigPath)
std::unique_ptr zone(new Zone(mWorker->createSubWorker(),
mConfig.zonesPath,
zoneConfigPath,
+ mConfig.dbPath,
mConfig.lxcTemplatePrefix,
mConfig.runMountPointPrefix));
const std::string id = zone->getId();
@@ -254,7 +255,7 @@ void ZonesManager::destroyZone(const std::string& zoneId)
it->second->setDestroyOnExit();
mZones.erase(it);
- if (mZones.size() == 0) {
+ if (mZones.empty()) {
if (!utils::removeFile(utils::createFilePath(mConfig.zonesPath, ENABLED_FILE_NAME))) {
LOGE("Failed to remove enabled file.");
}
diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp
index e074fc9..677b056 100644
--- a/server/zones-manager.hpp
+++ b/server/zones-manager.hpp
@@ -50,7 +50,7 @@ public:
/**
* Create new zone.
*
- * @param zoneConfig config of new zone
+ * @param zoneConfigPath config of new zone
*/
void createZone(const std::string& zoneConfigPath);
diff --git a/tests/unit_tests/client/configs/ut-client/zones/console1-dbus.conf.in b/tests/unit_tests/client/configs/ut-client/zones/console1-dbus.conf.in
index 46fb716..097480d 100644
--- a/tests/unit_tests/client/configs/ut-client/zones/console1-dbus.conf.in
+++ b/tests/unit_tests/client/configs/ut-client/zones/console1-dbus.conf.in
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console1-dbus",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*", "/etc/secret2" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/client/configs/ut-client/zones/console2-dbus.conf.in b/tests/unit_tests/client/configs/ut-client/zones/console2-dbus.conf.in
index 260d01f..440772b 100644
--- a/tests/unit_tests/client/configs/ut-client/zones/console2-dbus.conf.in
+++ b/tests/unit_tests/client/configs/ut-client/zones/console2-dbus.conf.in
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console2-dbus",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/client/configs/ut-client/zones/console3-dbus.conf.in b/tests/unit_tests/client/configs/ut-client/zones/console3-dbus.conf.in
index e20ffe9..2f28ee1 100644
--- a/tests/unit_tests/client/configs/ut-client/zones/console3-dbus.conf.in
+++ b/tests/unit_tests/client/configs/ut-client/zones/console3-dbus.conf.in
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console3-dbus",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/CMakeLists.txt b/tests/unit_tests/server/configs/CMakeLists.txt
index 4a9edbe..596c123 100644
--- a/tests/unit_tests/server/configs/CMakeLists.txt
+++ b/tests/unit_tests/server/configs/CMakeLists.txt
@@ -28,6 +28,8 @@ FILE(GLOB manager_zone_CONF ut-zones-manager/zones/*.conf)
FILE(GLOB zone_CONF ut-zone/*.conf)
FILE(GLOB zone_zone_CONF ut-zone/zones/*.conf)
+FILE(GLOB zone_provision_CONF ut-zone-provision/*.conf)
+
FILE(GLOB admin_zone_CONF ut-zone-admin/zones/*.conf)
FILE(GLOB connection_CONF ut-zone-connection/*.conf)
@@ -97,6 +99,9 @@ INSTALL(FILES ${zone_zone_CONF}
INSTALL(FILES ${zone_zone_CONF_GEN}
DESTINATION ${VSM_TEST_CONFIG_INSTALL_DIR}/server/ut-zone/zones)
+INSTALL(FILES ${zone_provision_CONF}
+ DESTINATION ${VSM_TEST_CONFIG_INSTALL_DIR}/server/ut-zone-provision)
+
INSTALL(FILES ${admin_zone_CONF}
DESTINATION ${VSM_TEST_CONFIG_INSTALL_DIR}/server/ut-zone-admin/zones)
diff --git a/tests/unit_tests/server/configs/ut-server/zones/zone1.conf b/tests/unit_tests/server/configs/ut-server/zones/zone1.conf
index 2c2ccde..432adc6 100644
--- a/tests/unit_tests/server/configs/ut-server/zones/zone1.conf
+++ b/tests/unit_tests/server/configs/ut-server/zones/zone1.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-server/zones/zone2.conf b/tests/unit_tests/server/configs/ut-server/zones/zone2.conf
index 1d500a7..2126b8f 100644
--- a/tests/unit_tests/server/configs/ut-server/zones/zone2.conf
+++ b/tests/unit_tests/server/configs/ut-server/zones/zone2.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-server/zones/zone3.conf b/tests/unit_tests/server/configs/ut-server/zones/zone3.conf
index a9856c7..dfc4a04 100644
--- a/tests/unit_tests/server/configs/ut-server/zones/zone3.conf
+++ b/tests/unit_tests/server/configs/ut-server/zones/zone3.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zone-admin/zones/buggy.conf b/tests/unit_tests/server/configs/ut-zone-admin/zones/buggy.conf
index e96dca8..fa7bd6b 100644
--- a/tests/unit_tests/server/configs/ut-zone-admin/zones/buggy.conf
+++ b/tests/unit_tests/server/configs/ut-zone-admin/zones/buggy.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zone-admin/zones/missing.conf b/tests/unit_tests/server/configs/ut-zone-admin/zones/missing.conf
index 9a5ec68..5cb9524 100644
--- a/tests/unit_tests/server/configs/ut-zone-admin/zones/missing.conf
+++ b/tests/unit_tests/server/configs/ut-zone-admin/zones/missing.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zone-admin/zones/test-no-shutdown.conf b/tests/unit_tests/server/configs/ut-zone-admin/zones/test-no-shutdown.conf
index be05697..7ab5df7 100644
--- a/tests/unit_tests/server/configs/ut-zone-admin/zones/test-no-shutdown.conf
+++ b/tests/unit_tests/server/configs/ut-zone-admin/zones/test-no-shutdown.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zone-admin/zones/test.conf b/tests/unit_tests/server/configs/ut-zone-admin/zones/test.conf
index 45213d7..215fa4f 100644
--- a/tests/unit_tests/server/configs/ut-zone-admin/zones/test.conf
+++ b/tests/unit_tests/server/configs/ut-zone-admin/zones/test.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zone-provision/test.conf b/tests/unit_tests/server/configs/ut-zone-provision/test.conf
new file mode 100644
index 0000000..504b486
--- /dev/null
+++ b/tests/unit_tests/server/configs/ut-zone-provision/test.conf
@@ -0,0 +1,3 @@
+{
+ "provisions" : []
+}
diff --git a/tests/unit_tests/server/configs/ut-zone/zones/buggy.conf b/tests/unit_tests/server/configs/ut-zone/zones/buggy.conf
index eaf0811..d29993c 100644
--- a/tests/unit_tests/server/configs/ut-zone/zones/buggy.conf
+++ b/tests/unit_tests/server/configs/ut-zone/zones/buggy.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zone/zones/test-dbus.conf.in b/tests/unit_tests/server/configs/ut-zone/zones/test-dbus.conf.in
index e4a18fa..77a4180 100644
--- a/tests/unit_tests/server/configs/ut-zone/zones/test-dbus.conf.in
+++ b/tests/unit_tests/server/configs/ut-zone/zones/test-dbus.conf.in
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zone-test-dbus",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zone/zones/test.conf b/tests/unit_tests/server/configs/ut-zone/zones/test.conf
index 4386c8c..9887e1c 100644
--- a/tests/unit_tests/server/configs/ut-zone/zones/test.conf
+++ b/tests/unit_tests/server/configs/ut-zone/zones/test.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [],
"permittedToRecv" : [],
"validLinkPrefixes" : [ "/tmp" ]
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/templates/template.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/templates/template.conf.in
index 7c2f5e4..28879db 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/templates/template.conf.in
+++ b/tests/unit_tests/server/configs/ut-zones-manager/templates/template.conf.in
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/~NAME~",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/zones/console1-dbus.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/zones/console1-dbus.conf.in
index 46fb716..097480d 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/zones/console1-dbus.conf.in
+++ b/tests/unit_tests/server/configs/ut-zones-manager/zones/console1-dbus.conf.in
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console1-dbus",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*", "/etc/secret2" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/zones/console1.conf b/tests/unit_tests/server/configs/ut-zones-manager/zones/console1.conf
index 41071ad..1fd4061 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/zones/console1.conf
+++ b/tests/unit_tests/server/configs/ut-zones-manager/zones/console1.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/zones/console2-dbus.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/zones/console2-dbus.conf.in
index 260d01f..440772b 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/zones/console2-dbus.conf.in
+++ b/tests/unit_tests/server/configs/ut-zones-manager/zones/console2-dbus.conf.in
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console2-dbus",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/zones/console2.conf b/tests/unit_tests/server/configs/ut-zones-manager/zones/console2.conf
index f152092..3c37313 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/zones/console2.conf
+++ b/tests/unit_tests/server/configs/ut-zones-manager/zones/console2.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/zones/console3-dbus.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/zones/console3-dbus.conf.in
index e20ffe9..2f28ee1 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/zones/console3-dbus.conf.in
+++ b/tests/unit_tests/server/configs/ut-zones-manager/zones/console3-dbus.conf.in
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console3-dbus",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/zones/console3.conf b/tests/unit_tests/server/configs/ut-zones-manager/zones/console3.conf
index 4979dd2..8e54fe6 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/zones/console3.conf
+++ b/tests/unit_tests/server/configs/ut-zones-manager/zones/console3.conf
@@ -11,6 +11,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
+ "provisions" : [],
"permittedToSend" : [ "/tmp/.*" ],
"permittedToRecv" : [ "/tmp/.*" ],
"validLinkPrefixes" : []
diff --git a/tests/unit_tests/server/ut-zone-provision.cpp b/tests/unit_tests/server/ut-zone-provision.cpp
index 8d1738f..c488c09 100644
--- a/tests/unit_tests/server/ut-zone-provision.cpp
+++ b/tests/unit_tests/server/ut-zone-provision.cpp
@@ -28,6 +28,7 @@
#include "utils/scoped-dir.hpp"
#include "utils/exception.hpp"
+#include "utils/fs.hpp"
#include "config/manager.hpp"
#include "zone-provision.hpp"
#include "zone-provision-config.hpp"
@@ -47,13 +48,15 @@ namespace fs = boost::filesystem;
namespace {
-const std::string PROVISON_CONFIG_FILE = "provision.conf";
+const std::string TEST_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zone-provision/test.conf";
const std::string ZONE = "ut-zone-provision-test";
const fs::path ZONES_PATH = "/tmp/ut-zones";
const fs::path LXC_TEMPLATES_PATH = VSM_TEST_LXC_TEMPLATES_INSTALL_DIR;
const fs::path ZONE_PATH = ZONES_PATH / fs::path(ZONE);
-const fs::path PROVISION_FILE_PATH = ZONE_PATH / fs::path(PROVISON_CONFIG_FILE);
-const fs::path ROOTFS_PATH = ZONE_PATH / fs::path("rootfs");
+const fs::path SOME_FILE_PATH = ZONE_PATH / "file.txt";
+const fs::path ROOTFS_PATH = ZONE_PATH / "rootfs";
+const fs::path DB_PATH = ZONES_PATH / "vasum.db";
+const std::string DB_PREFIX = "zone";
struct Fixture {
utils::ScopedDir mZonesPathGuard;
@@ -63,6 +66,26 @@ struct Fixture {
: mZonesPathGuard(ZONES_PATH.string())
, mRootfsPath(ROOTFS_PATH.string())
{
+ BOOST_REQUIRE(utils::saveFileContent(SOME_FILE_PATH.string(), "text"));
+ }
+
+ ZoneProvision create(const std::vector& validLinkPrefixes)
+ {
+ return ZoneProvision(ROOTFS_PATH.string(),
+ TEST_CONFIG_PATH,
+ DB_PATH.string(),
+ DB_PREFIX,
+ validLinkPrefixes);
+ }
+
+ void load(ZoneProvisioningConfig& config)
+ {
+ config::loadFromKVStoreWithJsonFile(DB_PATH.string(), TEST_CONFIG_PATH, config, DB_PREFIX);
+ }
+
+ void save(const ZoneProvisioningConfig& config)
+ {
+ config::saveToKVStore(DB_PATH.string(), config, DB_PREFIX);
}
};
@@ -78,22 +101,22 @@ BOOST_AUTO_TEST_CASE(DestructorTest)
{
utils::ScopedDir provisionfs(mountSource.string());
- ZoneProvisioning config;
- ZoneProvisioning::Unit unit;
- unit.set(ZoneProvisioning::File({VSMFILE_DIRECTORY,
+ ZoneProvisioningConfig config;
+ ZoneProvisioningConfig::Provision provision;
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_DIRECTORY,
mountTarget.string(),
0,
0777}));
- config.units.push_back(unit);
- unit.set(ZoneProvisioning::Mount({mountSource.string(),
+ config.provisions.push_back(provision);
+ provision.set(ZoneProvisioningConfig::Mount({mountSource.string(),
mountTarget.string(),
"",
MS_BIND,
""}));
- config.units.push_back(unit);
+ config.provisions.push_back(provision);
+ save(config);
- config::saveToJsonFile(PROVISION_FILE_PATH.string(), config);
- ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+ ZoneProvision zoneProvision = create({});
zoneProvision.start();
}
BOOST_CHECK(!fs::exists(mountSource));
@@ -103,35 +126,35 @@ BOOST_AUTO_TEST_CASE(FileTest)
{
//TODO: Test Fifo
const fs::path regularFile = fs::path("/opt/usr/data/ut-regular-file");
- const fs::path copyFile = PROVISION_FILE_PATH;
+ const fs::path copyFile = SOME_FILE_PATH;
- ZoneProvisioning config;
- ZoneProvisioning::Unit unit;
- unit.set(ZoneProvisioning::File({VSMFILE_DIRECTORY,
+ ZoneProvisioningConfig config;
+ ZoneProvisioningConfig::Provision provision;
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_DIRECTORY,
regularFile.parent_path().string(),
0,
0777}));
- config.units.push_back(unit);
+ config.provisions.push_back(provision);
- unit.set(ZoneProvisioning::File({VSMFILE_REGULAR,
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_REGULAR,
regularFile.string(),
O_CREAT,
0777}));
- config.units.push_back(unit);
+ config.provisions.push_back(provision);
- unit.set(ZoneProvisioning::File({VSMFILE_DIRECTORY,
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_DIRECTORY,
copyFile.parent_path().string(),
0,
0777}));
- config.units.push_back(unit);
- unit.set(ZoneProvisioning::File({VSMFILE_REGULAR,
+ config.provisions.push_back(provision);
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_REGULAR,
copyFile.string(),
0,
0777}));
- config.units.push_back(unit);
- config::saveToJsonFile(PROVISION_FILE_PATH.string(), config);
+ config.provisions.push_back(provision);
+ save(config);
- ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+ ZoneProvision zoneProvision = create({});
zoneProvision.start();
BOOST_CHECK(fs::exists(ROOTFS_PATH / regularFile.parent_path()));
@@ -152,27 +175,27 @@ BOOST_AUTO_TEST_CASE(MountTest)
utils::ScopedDir provisionfs(mountSource.string());
- ZoneProvisioning config;
- ZoneProvisioning::Unit unit;
- unit.set(ZoneProvisioning::File({VSMFILE_DIRECTORY,
+ ZoneProvisioningConfig config;
+ ZoneProvisioningConfig::Provision provision;
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_DIRECTORY,
mountTarget.string(),
0,
0777}));
- config.units.push_back(unit);
- unit.set(ZoneProvisioning::Mount({mountSource.string(),
+ config.provisions.push_back(provision);
+ provision.set(ZoneProvisioningConfig::Mount({mountSource.string(),
mountTarget.string(),
"",
MS_BIND,
""}));
- config.units.push_back(unit);
- unit.set(ZoneProvisioning::File({VSMFILE_REGULAR,
+ config.provisions.push_back(provision);
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_REGULAR,
(mountTarget / sharedFile).string(),
O_CREAT,
0777}));
- config.units.push_back(unit);
- config::saveToJsonFile(PROVISION_FILE_PATH.string(), config);
+ config.provisions.push_back(provision);
+ save(config);
- ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+ ZoneProvision zoneProvision = create({});
zoneProvision.start();
BOOST_CHECK(fs::exists(ROOTFS_PATH / mountTarget));
@@ -184,17 +207,17 @@ BOOST_AUTO_TEST_CASE(MountTest)
BOOST_AUTO_TEST_CASE(LinkTest)
{
- const fs::path linkFile = fs::path("/ut-from-host-provision.conf");
+ const fs::path linkFile = fs::path("/ut-from-host-file.txt");
- ZoneProvisioning config;
- ZoneProvisioning::Unit unit;
+ ZoneProvisioningConfig config;
+ ZoneProvisioningConfig::Provision provision;
- unit.set(ZoneProvisioning::Link({PROVISION_FILE_PATH.string(),
+ provision.set(ZoneProvisioningConfig::Link({SOME_FILE_PATH.string(),
linkFile.string()}));
- config.units.push_back(unit);
- config::saveToJsonFile(PROVISION_FILE_PATH.string(), config);
+ config.provisions.push_back(provision);
+ save(config);
{
- ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+ ZoneProvision zoneProvision = create({});
zoneProvision.start();
BOOST_CHECK(!fs::exists(ROOTFS_PATH / linkFile));
@@ -202,7 +225,7 @@ BOOST_AUTO_TEST_CASE(LinkTest)
zoneProvision.stop();
}
{
- ZoneProvision zoneProvision(ZONE_PATH.string(), {"/tmp/"});
+ ZoneProvision zoneProvision = create({"/tmp/"});
zoneProvision.start();
BOOST_CHECK(fs::exists(ROOTFS_PATH / linkFile));
@@ -213,82 +236,81 @@ BOOST_AUTO_TEST_CASE(LinkTest)
BOOST_AUTO_TEST_CASE(DeclareFileTest)
{
- ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+ ZoneProvision zoneProvision = create({});
zoneProvision.declareFile(1, "path", 0747, 0777);
zoneProvision.declareFile(2, "path", 0747, 0777);
- ZoneProvisioning config;
- BOOST_REQUIRE_NO_THROW(loadFromJsonFile(PROVISION_FILE_PATH.string(), config));
- BOOST_REQUIRE_EQUAL(config.units.size(), 2);
- BOOST_REQUIRE(config.units[0].is());
- BOOST_REQUIRE(config.units[1].is());
- const ZoneProvisioning::File& unit = config.units[0].as();
- BOOST_CHECK_EQUAL(unit.type, 1);
- BOOST_CHECK_EQUAL(unit.path, "path");
- BOOST_CHECK_EQUAL(unit.flags, 0747);
- BOOST_CHECK_EQUAL(unit.mode, 0777);
+ ZoneProvisioningConfig config;
+ load(config);
+ BOOST_REQUIRE_EQUAL(config.provisions.size(), 2);
+ BOOST_REQUIRE(config.provisions[0].is());
+ BOOST_REQUIRE(config.provisions[1].is());
+ const ZoneProvisioningConfig::File& provision = config.provisions[0].as();
+ BOOST_CHECK_EQUAL(provision.type, 1);
+ BOOST_CHECK_EQUAL(provision.path, "path");
+ BOOST_CHECK_EQUAL(provision.flags, 0747);
+ BOOST_CHECK_EQUAL(provision.mode, 0777);
}
BOOST_AUTO_TEST_CASE(DeclareMountTest)
{
- ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+ ZoneProvision zoneProvision = create({});
zoneProvision.declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake");
zoneProvision.declareMount("/fake/path2", "/fake/path2", "tmpfs", 077, "fake");
- ZoneProvisioning config;
- BOOST_REQUIRE_NO_THROW(loadFromJsonFile(PROVISION_FILE_PATH.string(), config));
- BOOST_REQUIRE_EQUAL(config.units.size(), 2);
- BOOST_REQUIRE(config.units[0].is());
- BOOST_REQUIRE(config.units[1].is());
- const ZoneProvisioning::Mount& unit = config.units[0].as();
- BOOST_CHECK_EQUAL(unit.source, "/fake/path1");
- BOOST_CHECK_EQUAL(unit.target, "/fake/path2");
- BOOST_CHECK_EQUAL(unit.type, "tmpfs");
- BOOST_CHECK_EQUAL(unit.flags, 077);
- BOOST_CHECK_EQUAL(unit.data, "fake");
+ ZoneProvisioningConfig config;
+ load(config);
+ BOOST_REQUIRE_EQUAL(config.provisions.size(), 2);
+ BOOST_REQUIRE(config.provisions[0].is());
+ BOOST_REQUIRE(config.provisions[1].is());
+ const ZoneProvisioningConfig::Mount& provision = config.provisions[0].as();
+ BOOST_CHECK_EQUAL(provision.source, "/fake/path1");
+ BOOST_CHECK_EQUAL(provision.target, "/fake/path2");
+ BOOST_CHECK_EQUAL(provision.type, "tmpfs");
+ BOOST_CHECK_EQUAL(provision.flags, 077);
+ BOOST_CHECK_EQUAL(provision.data, "fake");
}
BOOST_AUTO_TEST_CASE(DeclareLinkTest)
{
- ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+ ZoneProvision zoneProvision = create({});
zoneProvision.declareLink("/fake/path1", "/fake/path2");
zoneProvision.declareLink("/fake/path2", "/fake/path2");
- ZoneProvisioning config;
- BOOST_REQUIRE_NO_THROW(loadFromJsonFile(PROVISION_FILE_PATH.string(), config));
- BOOST_REQUIRE_EQUAL(config.units.size(), 2);
- BOOST_REQUIRE(config.units[0].is());
- BOOST_REQUIRE(config.units[1].is());
- const ZoneProvisioning::Link& unit = config.units[0].as();
- BOOST_CHECK_EQUAL(unit.source, "/fake/path1");
- BOOST_CHECK_EQUAL(unit.target, "/fake/path2");
+ ZoneProvisioningConfig config;
+ load(config);
+ BOOST_REQUIRE_EQUAL(config.provisions.size(), 2);
+ BOOST_REQUIRE(config.provisions[0].is());
+ BOOST_REQUIRE(config.provisions[1].is());
+ const ZoneProvisioningConfig::Link& provision = config.provisions[0].as();
+ BOOST_CHECK_EQUAL(provision.source, "/fake/path1");
+ BOOST_CHECK_EQUAL(provision.target, "/fake/path2");
}
BOOST_AUTO_TEST_CASE(ProvisionedAlreadyTest)
{
- const fs::path dir = fs::path("/opt/usr/data/ut-from-host-provision");
- const fs::path linkFile = fs::path("/ut-from-host-provision.conf");
+ const fs::path dir = fs::path("/opt/usr/data/ut-from-host");
+ const fs::path linkFile = fs::path("/ut-from-host-file.txt");
const fs::path regularFile = fs::path("/opt/usr/data/ut-regular-file");
- ZoneProvisioning config;
- ZoneProvisioning::Unit unit;
- unit.set(ZoneProvisioning::File({VSMFILE_DIRECTORY,
+ ZoneProvisioningConfig config;
+ ZoneProvisioningConfig::Provision provision;
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_DIRECTORY,
dir.string(),
0,
0777}));
- config.units.push_back(unit);
- unit.set(ZoneProvisioning::Link({PROVISION_FILE_PATH.string(),
+ config.provisions.push_back(provision);
+ provision.set(ZoneProvisioningConfig::Link({SOME_FILE_PATH.string(),
linkFile.string()}));
- config.units.push_back(unit);
- unit.set(ZoneProvisioning::File({VSMFILE_REGULAR,
+ config.provisions.push_back(provision);
+ provision.set(ZoneProvisioningConfig::File({VSMFILE_REGULAR,
regularFile.string(),
O_CREAT,
0777}));
- config.units.push_back(unit);
-
- config::saveToJsonFile(PROVISION_FILE_PATH.string(), config);
+ config.provisions.push_back(provision);
+ save(config);
- ZoneProvision zoneProvision(ZONE_PATH.string(), {"/tmp/"});
+ ZoneProvision zoneProvision = create({"/tmp/"});
zoneProvision.start();
BOOST_CHECK(fs::exists(ROOTFS_PATH / dir));
diff --git a/tests/unit_tests/server/ut-zone.cpp b/tests/unit_tests/server/ut-zone.cpp
index 80e73da..783fbf8 100644
--- a/tests/unit_tests/server/ut-zone.cpp
+++ b/tests/unit_tests/server/ut-zone.cpp
@@ -51,6 +51,7 @@ const std::string BUGGY_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zo
const std::string MISSING_CONFIG_PATH = "/this/is/a/missing/file/path/config.conf";
const std::string ZONES_PATH = "/tmp/ut-zones";
const std::string LXC_TEMPLATES_PATH = VSM_TEST_LXC_TEMPLATES_INSTALL_DIR;
+const std::string DB_PATH = ZONES_PATH + "/vasum.db";
struct Fixture {
utils::ScopedGlibLoop mLoop;
@@ -66,6 +67,7 @@ struct Fixture {
return std::unique_ptr(new Zone(utils::Worker::create(),
ZONES_PATH,
configPath,
+ DB_PATH,
LXC_TEMPLATES_PATH,
""));
}
--
2.7.4
From ca9d04423d356228266a2480231e77b624cf5876 Mon Sep 17 00:00:00 2001
From: Jan Olszak
Date: Tue, 20 Jan 2015 16:15:39 +0100
Subject: [PATCH 04/16] IPC: Support older glib
[Bug/Feature] Replaced new calls with older equivalents
Fixed SIGSEGV bug
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run tests, run tests under valgrind
Change-Id: I572321fb4055f8f5b033b755c883c3e4b00bfcda
---
common/ipc/client.cpp | 62 ++++++++++--
common/ipc/client.hpp | 31 +++---
common/ipc/internals/add-peer-request.hpp | 2 +-
common/ipc/internals/finish-request.hpp | 2 +-
common/ipc/internals/method-request.hpp | 2 +-
common/ipc/internals/processor.cpp | 12 +--
common/ipc/internals/processor.hpp | 17 ++--
common/ipc/internals/remove-peer-request.hpp | 2 +-
common/ipc/internals/request-queue.hpp | 2 +-
common/ipc/internals/signal-request.hpp | 2 +-
common/ipc/ipc-gsource.cpp | 141 ++++++++++++++------------
common/ipc/ipc-gsource.hpp | 58 +++++------
common/ipc/service.cpp | 109 +++++++++++++-------
common/ipc/service.hpp | 31 +++---
common/ipc/types.cpp | 2 +-
common/ipc/types.hpp | 2 +-
tests/unit_tests/ipc/ut-ipc.cpp | 142 ++++++++-------------------
17 files changed, 327 insertions(+), 292 deletions(-)
diff --git a/common/ipc/client.cpp b/common/ipc/client.cpp
index 16f77e6..1b7ae56 100644
--- a/common/ipc/client.cpp
+++ b/common/ipc/client.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
@@ -36,6 +36,8 @@ Client::Client(const std::string& socketPath)
mSocketPath(socketPath)
{
LOGS("Client Constructor");
+ setNewPeerCallback(nullptr);
+ setRemovedPeerCallback(nullptr);
}
Client::~Client()
@@ -52,10 +54,14 @@ void Client::start(const bool usesExternalPolling)
{
LOGS("Client start");
// Initialize the connection with the server
+ if (usesExternalPolling) {
+ startPoll();
+ }
+ mProcessor.start(usesExternalPolling);
+
LOGD("Connecting to " + mSocketPath);
auto socketPtr = std::make_shared(Socket::connectSocket(mSocketPath));
mServiceFD = mProcessor.addPeer(socketPtr);
- mProcessor.start(usesExternalPolling);
}
bool Client::isStarted()
@@ -65,21 +71,41 @@ bool Client::isStarted()
void Client::stop()
{
- LOGS("Client Destructor");
+ LOGS("Client stop");
mProcessor.stop();
+
+ if (mIPCGSourcePtr) {
+ stopPoll();
+ }
}
-std::vector Client::getFDs()
+void Client::startPoll()
{
- std::vector fds;
- fds.push_back(mProcessor.getEventFD());
- fds.push_back(mServiceFD);
+ LOGS("Client startPoll");
+ using namespace std::placeholders;
+ mIPCGSourcePtr = IPCGSource::create(std::bind(&Client::handle, this, _1, _2));
+ mIPCGSourcePtr->addFD(mProcessor.getEventFD());
+ mIPCGSourcePtr->attach();
+}
+
+void Client::stopPoll()
+{
+ LOGS("Client stopPoll");
- return fds;
+ mIPCGSourcePtr->removeFD(mProcessor.getEventFD());
+ mIPCGSourcePtr->detach();
+ mIPCGSourcePtr.reset();
}
void Client::handle(const FileDescriptor fd, const short pollEvent)
{
+ LOGS("Client handle");
+
+ if (!isStarted()) {
+ LOGW("Client stopped");
+ return;
+ }
+
if (fd == mProcessor.getEventFD() && (pollEvent & POLLIN)) {
mProcessor.handleEvent();
return;
@@ -97,13 +123,29 @@ void Client::handle(const FileDescriptor fd, const short pollEvent)
void Client::setNewPeerCallback(const PeerCallback& newPeerCallback)
{
LOGS("Client setNewPeerCallback");
- mProcessor.setNewPeerCallback(newPeerCallback);
+ auto callback = [newPeerCallback, this](FileDescriptor fd) {
+ if (mIPCGSourcePtr) {
+ mIPCGSourcePtr->addFD(fd);
+ }
+ if (newPeerCallback) {
+ newPeerCallback(fd);
+ }
+ };
+ mProcessor.setNewPeerCallback(callback);
}
void Client::setRemovedPeerCallback(const PeerCallback& removedPeerCallback)
{
LOGS("Client setRemovedPeerCallback");
- mProcessor.setRemovedPeerCallback(removedPeerCallback);
+ auto callback = [removedPeerCallback, this](FileDescriptor fd) {
+ if (mIPCGSourcePtr) {
+ mIPCGSourcePtr->removeFD(fd);
+ }
+ if (removedPeerCallback) {
+ removedPeerCallback(fd);
+ }
+ };
+ mProcessor.setRemovedPeerCallback(callback);
}
void Client::removeMethod(const MethodID methodID)
diff --git a/common/ipc/client.hpp b/common/ipc/client.hpp
index 7b86198..eedf81b 100644
--- a/common/ipc/client.hpp
+++ b/common/ipc/client.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
@@ -26,6 +26,7 @@
#define COMMON_IPC_CLIENT_HPP
#include "ipc/internals/processor.hpp"
+#include "ipc/ipc-gsource.hpp"
#include "ipc/types.hpp"
#include "logger/logger.hpp"
@@ -72,13 +73,6 @@ public:
void stop();
/**
- * Used with an external polling loop
- *
- * @return vector of internal file descriptors
- */
- std::vector getFDs();
-
- /**
* Used with an external polling loop.
* Handles one event from the file descriptor.
*
@@ -111,7 +105,7 @@ public:
* @param method method handling implementation
*/
template
- void addMethodHandler(const MethodID methodID,
+ void setMethodHandler(const MethodID methodID,
const typename MethodHandler::type& method);
/**
@@ -124,7 +118,7 @@ public:
* @tparam ReceivedDataType data type to serialize
*/
template
- void addSignalHandler(const MethodID methodID,
+ void setSignalHandler(const MethodID methodID,
const typename SignalHandler::type& signal);
/**
@@ -175,25 +169,30 @@ public:
const std::shared_ptr& data);
private:
+
+ void startPoll();
+ void stopPoll();
+
FileDescriptor mServiceFD;
Processor mProcessor;
std::string mSocketPath;
+ IPCGSource::Pointer mIPCGSourcePtr;
};
template
-void Client::addMethodHandler(const MethodID methodID,
+void Client::setMethodHandler(const MethodID methodID,
const typename MethodHandler::type& method)
{
- LOGS("Client addMethodHandler, methodID: " << methodID);
- mProcessor.addMethodHandler(methodID, method);
+ LOGS("Client setMethodHandler, methodID: " << methodID);
+ mProcessor.setMethodHandler(methodID, method);
}
template
-void Client::addSignalHandler(const MethodID methodID,
+void Client::setSignalHandler(const MethodID methodID,
const typename SignalHandler::type& handler)
{
- LOGS("Client addSignalHandler, methodID: " << methodID);
- mProcessor.addSignalHandler(methodID, handler);
+ LOGS("Client setSignalHandler, methodID: " << methodID);
+ mProcessor.setSignalHandler(methodID, handler);
}
template
diff --git a/common/ipc/internals/add-peer-request.hpp b/common/ipc/internals/add-peer-request.hpp
index 05c5524..3409ba5 100644
--- a/common/ipc/internals/add-peer-request.hpp
+++ b/common/ipc/internals/add-peer-request.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
diff --git a/common/ipc/internals/finish-request.hpp b/common/ipc/internals/finish-request.hpp
index 3019475..3fd4a4f 100644
--- a/common/ipc/internals/finish-request.hpp
+++ b/common/ipc/internals/finish-request.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
diff --git a/common/ipc/internals/method-request.hpp b/common/ipc/internals/method-request.hpp
index f9860f7..36d3d7a 100644
--- a/common/ipc/internals/method-request.hpp
+++ b/common/ipc/internals/method-request.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
diff --git a/common/ipc/internals/processor.cpp b/common/ipc/internals/processor.cpp
index 05c97aa..bdc8a8d 100644
--- a/common/ipc/internals/processor.cpp
+++ b/common/ipc/internals/processor.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
@@ -66,7 +66,7 @@ Processor::Processor(const std::string& logName,
utils::signalBlock(SIGPIPE);
using namespace std::placeholders;
- addMethodHandlerInternal(REGISTER_SIGNAL_METHOD_ID,
+ setMethodHandlerInternal(REGISTER_SIGNAL_METHOD_ID,
std::bind(&Processor::onNewSignals, this, _1, _2));
}
@@ -94,6 +94,7 @@ void Processor::start(bool usesExternalPolling)
if (!isStarted()) {
LOGI(mLogPrefix + "Processor start");
mIsRunning = true;
+ mUsesExternalPolling = usesExternalPolling;
if (!usesExternalPolling) {
mThread = std::thread(&Processor::run, this);
}
@@ -228,7 +229,6 @@ void Processor::removePeerInternal(const FileDescriptor peerFD, Status status)
mRemovedPeerCallback(peerFD);
}
-
resetPolling();
}
@@ -236,8 +236,7 @@ void Processor::resetPolling()
{
LOGS(mLogPrefix + "Processor resetPolling");
- if (!isStarted()) {
- LOGW(mLogPrefix + "Processor not started! Polling not reset!");
+ if (mUsesExternalPolling) {
return;
}
@@ -681,7 +680,7 @@ bool Processor::onFinishRequest(FinishRequest& request)
break;
}
case Event::REMOVE_PEER: {
- request.get()->conditionPtr->notify_all();
+ onRemovePeerRequest(*request.get());
break;
}
case Event::SIGNAL:
@@ -692,6 +691,7 @@ bool Processor::onFinishRequest(FinishRequest& request)
}
mIsRunning = false;
+
request.conditionPtr->notify_all();
return true;
}
diff --git a/common/ipc/internals/processor.hpp b/common/ipc/internals/processor.hpp
index 157f39c..40dd4c0 100644
--- a/common/ipc/internals/processor.hpp
+++ b/common/ipc/internals/processor.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
@@ -190,7 +190,7 @@ public:
* @tparam ReceivedDataType data type to receive
*/
template
- void addMethodHandler(const MethodID methodID,
+ void setMethodHandler(const MethodID methodID,
const typename MethodHandler::type& process);
/**
@@ -208,7 +208,7 @@ public:
* @tparam ReceivedDataType data type to receive
*/
template
- void addSignalHandler(const MethodID methodID,
+ void setSignalHandler(const MethodID methodID,
const typename SignalHandler::type& process);
/**
@@ -360,6 +360,7 @@ private:
RequestQueue mRequestQueue;
bool mIsRunning;
+ bool mUsesExternalPolling;
std::unordered_map> mMethodsCallbacks;
std::unordered_map> mSignalsCallbacks;
@@ -381,7 +382,7 @@ private:
std::thread mThread;
template
- void addMethodHandlerInternal(const MethodID methodID,
+ void setMethodHandlerInternal(const MethodID methodID,
const typename MethodHandler::type& process);
template
@@ -420,7 +421,7 @@ private:
};
template
-void Processor::addMethodHandlerInternal(const MethodID methodID,
+void Processor::setMethodHandlerInternal(const MethodID methodID,
const typename MethodHandler::type& method)
{
MethodHandlers methodCall;
@@ -447,7 +448,7 @@ void Processor::addMethodHandlerInternal(const MethodID methodID,
}
template
-void Processor::addMethodHandler(const MethodID methodID,
+void Processor::setMethodHandler(const MethodID methodID,
const typename MethodHandler::type& method)
{
if (methodID == RETURN_METHOD_ID || methodID == REGISTER_SIGNAL_METHOD_ID) {
@@ -463,13 +464,13 @@ void Processor::addMethodHandler(const MethodID methodID,
throw IPCException("MethodID used by a signal: " + std::to_string(methodID));
}
- addMethodHandlerInternal(methodID, method);
+ setMethodHandlerInternal(methodID, method);
}
}
template
-void Processor::addSignalHandler(const MethodID methodID,
+void Processor::setSignalHandler(const MethodID methodID,
const typename SignalHandler::type& handler)
{
if (methodID == RETURN_METHOD_ID || methodID == REGISTER_SIGNAL_METHOD_ID) {
diff --git a/common/ipc/internals/remove-peer-request.hpp b/common/ipc/internals/remove-peer-request.hpp
index ec01ac4..4ec07cb 100644
--- a/common/ipc/internals/remove-peer-request.hpp
+++ b/common/ipc/internals/remove-peer-request.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
diff --git a/common/ipc/internals/request-queue.hpp b/common/ipc/internals/request-queue.hpp
index 35b5120..82ba606 100644
--- a/common/ipc/internals/request-queue.hpp
+++ b/common/ipc/internals/request-queue.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
diff --git a/common/ipc/internals/signal-request.hpp b/common/ipc/internals/signal-request.hpp
index 4cf62c2..ad80d91 100644
--- a/common/ipc/internals/signal-request.hpp
+++ b/common/ipc/internals/signal-request.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
diff --git a/common/ipc/ipc-gsource.cpp b/common/ipc/ipc-gsource.cpp
index 5a4e137..1769414 100644
--- a/common/ipc/ipc-gsource.cpp
+++ b/common/ipc/ipc-gsource.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
@@ -26,10 +26,9 @@
#include "config.hpp"
#include "ipc/ipc-gsource.hpp"
-
-#if GLIB_CHECK_VERSION(2,36,0)
-
+#include "utils/callback-wrapper.hpp"
#include "logger/logger.hpp"
+
#include
namespace vasum {
@@ -37,33 +36,26 @@ namespace ipc {
namespace {
+gushort conditions = static_cast(G_IO_IN |
+ G_IO_ERR |
+ G_IO_HUP);
-GIOCondition conditions = static_cast(G_IO_IN |
- G_IO_ERR |
- G_IO_HUP);
}
-
-IPCGSource::IPCGSource(const std::vector fds,
- const HandlerCallback& handlerCallback)
+IPCGSource::IPCGSource(const HandlerCallback& handlerCallback)
: mHandlerCallback(handlerCallback)
{
- LOGS("IPCGSource constructor");
-
- for (const FileDescriptor fd : fds) {
- addFD(fd);
- }
+ LOGT("IPCGSource Constructor");
}
IPCGSource::~IPCGSource()
{
- LOGS("~IPCGSource");
+ LOGT("IPCGSource Destructor");
}
-IPCGSource::Pointer IPCGSource::create(const std::vector& fds,
- const HandlerCallback& handlerCallback)
+IPCGSource::Pointer IPCGSource::create(const HandlerCallback& handlerCallback)
{
- LOGS("Creating IPCGSource");
+ LOGT("Creating IPCGSource");
static GSourceFuncs funcs = { &IPCGSource::prepare,
&IPCGSource::check,
@@ -79,64 +71,96 @@ IPCGSource::Pointer IPCGSource::create(const std::vector& fds,
// Fill additional data
IPCGSource* source = reinterpret_cast(gSource);
- new(source)IPCGSource(fds, handlerCallback);
+ new(source) IPCGSource(handlerCallback);
auto deleter = [](IPCGSource * ptr) {
LOGD("Deleter");
-
- if (!g_source_is_destroyed(&(ptr->mGSource))) {
- // This way finalize method will be run in glib loop's thread
- g_source_destroy(&(ptr->mGSource));
- }
+ g_source_unref(&ptr->mGSource);
};
- return std::shared_ptr(source, deleter);
+ Pointer ipcGSourcePtr(source, deleter);
+
+ g_source_set_callback(gSource,
+ &IPCGSource::onHandlerCall,
+ utils::createCallbackWrapper(Pointer(ipcGSourcePtr), ipcGSourcePtr->mGuard.spawn()),
+ &utils::deleteCallbackWrapper);
+
+ return ipcGSourcePtr;
}
void IPCGSource::addFD(const FileDescriptor fd)
{
+ LOGI("Adding to glib FD: " << fd);
+ Lock lock(mStateMutex);
- if (!&mGSource) {
- // In case it's called as a callback but the IPCGSource is destroyed
- return;
- }
- LOGS("Adding fd to glib");
-
- gpointer tag = g_source_add_unix_fd(&mGSource,
- fd,
- conditions);
- FDInfo fdInfo(tag, fd);
- mFDInfos.push_back(std::move(fdInfo));
+ mGPollFDs.push_back({fd, conditions, 0});
+ g_source_add_poll(&mGSource, &mGPollFDs.back());
}
void IPCGSource::removeFD(const FileDescriptor fd)
{
- if (!&mGSource) {
- // In case it's called as a callback but the IPCGSource is destroyed
- return;
- }
+ Lock lock(mStateMutex);
+
+ auto it = std::find_if(mGPollFDs.begin(), mGPollFDs.end(), [fd](GPollFD gPollFD) {
+ return gPollFD.fd = fd;
+ });
- LOGS("Removing fd from glib");
- auto it = std::find(mFDInfos.begin(), mFDInfos.end(), fd);
- if (it == mFDInfos.end()) {
+ if (it == mGPollFDs.end()) {
LOGE("No such fd");
return;
}
- g_source_remove_unix_fd(&mGSource, it->tag);
- mFDInfos.erase(it);
+ g_source_remove_poll(&mGSource, &(*it));
+ mGPollFDs.erase(it);
+ LOGI("Removed from glib FD: " << fd);
}
guint IPCGSource::attach(GMainContext* context)
{
- LOGS("Attaching to GMainContext");
+ LOGT("Attaching to GMainContext");
guint ret = g_source_attach(&mGSource, context);
- g_source_unref(&mGSource);
return ret;
}
+void IPCGSource::detach()
+{
+ LOGT("Detaching");
+ Lock lock(mStateMutex);
+
+ for (GPollFD gPollFD : mGPollFDs) {
+ g_source_remove_poll(&mGSource, &gPollFD);
+ }
+
+ mGPollFDs.clear();
+ if (!g_source_is_destroyed(&mGSource)) {
+ LOGD("Destroying");
+ // This way finalize method will be run in glib loop's thread
+ g_source_destroy(&mGSource);
+ }
+}
+
+void IPCGSource::callHandler()
+{
+ Lock lock(mStateMutex);
+
+ for (const GPollFD& gPollFD : mGPollFDs) {
+ if (gPollFD.revents & conditions) {
+ mHandlerCallback(gPollFD.fd, gPollFD.revents);
+ }
+ }
+}
+
+gboolean IPCGSource::onHandlerCall(gpointer userData)
+{
+ const auto& source = utils::getCallbackFromPointer(userData);
+ if (source) {
+ source->callHandler();
+ }
+ return TRUE;
+}
+
gboolean IPCGSource::prepare(GSource* gSource, gint* timeout)
{
- if (!gSource) {
+ if (!gSource || g_source_is_destroyed(gSource)) {
return FALSE;
}
@@ -149,7 +173,7 @@ gboolean IPCGSource::prepare(GSource* gSource, gint* timeout)
gboolean IPCGSource::check(GSource* gSource)
{
- if (!gSource) {
+ if (!gSource || g_source_is_destroyed(gSource)) {
return FALSE;
}
@@ -157,21 +181,16 @@ gboolean IPCGSource::check(GSource* gSource)
}
gboolean IPCGSource::dispatch(GSource* gSource,
- GSourceFunc /*callback*/,
- gpointer /*userData*/)
+ GSourceFunc callback,
+ gpointer userData)
{
if (!gSource || g_source_is_destroyed(gSource)) {
// Remove the GSource from the GMainContext
return FALSE;
}
- IPCGSource* source = reinterpret_cast(gSource);
-
- for (const FDInfo fdInfo : source->mFDInfos) {
- GIOCondition cond = g_source_query_unix_fd(gSource, fdInfo.tag);
- if (conditions & cond) {
- source->mHandlerCallback(fdInfo.fd, cond);
- }
+ if (callback) {
+ callback(userData);
}
return TRUE;
@@ -179,8 +198,6 @@ gboolean IPCGSource::dispatch(GSource* gSource,
void IPCGSource::finalize(GSource* gSource)
{
- LOGS("IPCGSource Finalize");
-
if (gSource) {
IPCGSource* source = reinterpret_cast(gSource);
source->~IPCGSource();
@@ -189,5 +206,3 @@ void IPCGSource::finalize(GSource* gSource)
} // namespace ipc
} // namespace vasum
-
-#endif // GLIB_CHECK_VERSION
diff --git a/common/ipc/ipc-gsource.hpp b/common/ipc/ipc-gsource.hpp
index bb9a096..87057db 100644
--- a/common/ipc/ipc-gsource.hpp
+++ b/common/ipc/ipc-gsource.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
@@ -26,12 +26,12 @@
#define COMMON_IPC_IPC_GSOURCE_HPP
#include
-#if GLIB_CHECK_VERSION(2,36,0)
-
-#include "ipc/service.hpp"
#include "ipc/types.hpp"
+#include "utils/callback-guard.hpp"
#include
+#include
+#include
namespace vasum {
@@ -82,18 +82,32 @@ public:
guint attach(GMainContext* context = nullptr);
/**
+ * After this method quits handlerCallback will not be called
+ */
+ void detach();
+
+ /**
* Creates the IPCGSource class in the memory allocated by glib.
* Calls IPCGSource's constructor
*
- * @param fds initial set of file descriptors
* @param handlerCallback event handling callback
*
* @return pointer to the IPCGSource
*/
- static Pointer create(const std::vector& fds,
- const HandlerCallback& handlerCallback);
+ static Pointer create(const HandlerCallback& handlerCallback);
+
+ /**
+ * Callback for the dispatch function
+ */
+ static gboolean onHandlerCall(gpointer userData);
+
+ /**
+ * Locks the internal state mutex and calls the handler callback for each fd
+ */
+ void callHandler();
private:
+ typedef std::unique_lock Lock;
/**
* GSourceFuncs' callback
@@ -117,38 +131,18 @@ private:
*/
static void finalize(GSource* source);
-
-
// Called only from IPCGSource::create
- IPCGSource(const std::vector fds,
- const HandlerCallback& handlerCallback);
-
- struct FDInfo {
- FDInfo(gpointer tag, FileDescriptor fd)
- : tag(tag), fd(fd) {}
-
- bool operator==(const gpointer t)
- {
- return t == tag;
- }
-
- bool operator==(const FileDescriptor f)
- {
- return f == fd;
- }
-
- gpointer tag;
- FileDescriptor fd;
- };
+ IPCGSource(const HandlerCallback& handlerCallback);
GSource mGSource;
HandlerCallback mHandlerCallback;
- std::vector mFDInfos;
+ std::list mGPollFDs;
+ utils::CallbackGuard mGuard;
+ std::recursive_mutex mStateMutex;
+
};
} // namespace ipc
} // namespace vasum
-#endif // GLIB_CHECK_VERSION
-
#endif // COMMON_IPC_IPC_GSOURCE_HPP
diff --git a/common/ipc/service.cpp b/common/ipc/service.cpp
index b96bcd4..9bf721b 100644
--- a/common/ipc/service.cpp
+++ b/common/ipc/service.cpp
@@ -1,26 +1,26 @@
-// /*
-// * 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 IPC handling class
-// */
+/*
+* Copyright (c) 2015 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 IPC handling class
+ */
#include "config.hpp"
@@ -36,11 +36,13 @@ namespace ipc {
Service::Service(const std::string& socketPath,
const PeerCallback& addPeerCallback,
const PeerCallback& removePeerCallback)
- : mProcessor("[SERVICE] ", addPeerCallback, removePeerCallback),
+ : mProcessor("[SERVICE] "),
mAcceptor(socketPath, std::bind(&Processor::addPeer, &mProcessor, _1))
{
LOGS("Service Constructor");
+ setNewPeerCallback(addPeerCallback);
+ setRemovedPeerCallback(removePeerCallback);
}
Service::~Service()
@@ -56,6 +58,9 @@ Service::~Service()
void Service::start(const bool usesExternalPolling)
{
LOGS("Service start");
+ if (usesExternalPolling) {
+ startPoll();
+ }
mProcessor.start(usesExternalPolling);
// There can be an incoming connection from mAcceptor before mProcessor is listening,
@@ -75,20 +80,43 @@ void Service::stop()
LOGS("Service stop");
mAcceptor.stop();
mProcessor.stop();
+
+ if (mIPCGSourcePtr) {
+ stopPoll();
+ }
+}
+
+void Service::startPoll()
+{
+ LOGS("Service startPoll");
+
+ mIPCGSourcePtr = IPCGSource::create(std::bind(&Service::handle, this, _1, _2));
+ mIPCGSourcePtr->addFD(mAcceptor.getEventFD());
+ mIPCGSourcePtr->addFD(mAcceptor.getConnectionFD());
+ mIPCGSourcePtr->addFD(mProcessor.getEventFD());
+ mIPCGSourcePtr->attach();
}
-std::vector Service::getFDs()
+void Service::stopPoll()
{
- std::vector fds;
- fds.push_back(mAcceptor.getEventFD());
- fds.push_back(mAcceptor.getConnectionFD());
- fds.push_back(mProcessor.getEventFD());
+ LOGS("Service stopPoll");
- return fds;
+ mIPCGSourcePtr->removeFD(mAcceptor.getEventFD());
+ mIPCGSourcePtr->removeFD(mAcceptor.getConnectionFD());
+ mIPCGSourcePtr->removeFD(mProcessor.getEventFD());
+ mIPCGSourcePtr->detach();
+ mIPCGSourcePtr.reset();
}
void Service::handle(const FileDescriptor fd, const short pollEvent)
{
+ LOGS("Service handle");
+
+ if (!isStarted()) {
+ LOGW("Service stopped");
+ return;
+ }
+
if (fd == mProcessor.getEventFD() && (pollEvent & POLLIN)) {
mProcessor.handleEvent();
return;
@@ -111,17 +139,32 @@ void Service::handle(const FileDescriptor fd, const short pollEvent)
}
}
-
void Service::setNewPeerCallback(const PeerCallback& newPeerCallback)
{
LOGS("Service setNewPeerCallback");
- mProcessor.setNewPeerCallback(newPeerCallback);
+ auto callback = [newPeerCallback, this](FileDescriptor fd) {
+ if (mIPCGSourcePtr) {
+ mIPCGSourcePtr->addFD(fd);
+ }
+ if (newPeerCallback) {
+ newPeerCallback(fd);
+ }
+ };
+ mProcessor.setNewPeerCallback(callback);
}
void Service::setRemovedPeerCallback(const PeerCallback& removedPeerCallback)
{
LOGS("Service setRemovedPeerCallback");
- mProcessor.setRemovedPeerCallback(removedPeerCallback);
+ auto callback = [removedPeerCallback, this](FileDescriptor fd) {
+ if (mIPCGSourcePtr) {
+ mIPCGSourcePtr->removeFD(fd);
+ }
+ if (removedPeerCallback) {
+ removedPeerCallback(fd);
+ }
+ };
+ mProcessor.setRemovedPeerCallback(callback);
}
void Service::removeMethod(const MethodID methodID)
diff --git a/common/ipc/service.hpp b/common/ipc/service.hpp
index 9392a42..34b73fd 100644
--- a/common/ipc/service.hpp
+++ b/common/ipc/service.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
@@ -27,6 +27,7 @@
#include "ipc/internals/processor.hpp"
#include "ipc/internals/acceptor.hpp"
+#include "ipc/ipc-gsource.hpp"
#include "ipc/types.hpp"
#include "logger/logger.hpp"
@@ -77,13 +78,6 @@ public:
void stop();
/**
- * Used with an external polling loop
- *
- * @return vector of internal file descriptors
- */
- std::vector getFDs();
-
- /**
* Used with an external polling loop.
* Handles one event from the file descriptor.
*
@@ -116,7 +110,7 @@ public:
* @param method method handling implementation
*/
template
- void addMethodHandler(const MethodID methodID,
+ void setMethodHandler(const MethodID methodID,
const typename MethodHandler::type& method);
/**
@@ -129,7 +123,7 @@ public:
* @tparam ReceivedDataType data type to serialize
*/
template
- void addSignalHandler(const MethodID methodID,
+ void setSignalHandler(const MethodID methodID,
const typename SignalHandler::type& handler);
/**
@@ -180,26 +174,31 @@ public:
void signal(const MethodID methodID,
const std::shared_ptr& data);
private:
+
+ void startPoll();
+ void stopPoll();
+
typedef std::lock_guard Lock;
Processor mProcessor;
Acceptor mAcceptor;
+ IPCGSource::Pointer mIPCGSourcePtr;
};
template
-void Service::addMethodHandler(const MethodID methodID,
+void Service::setMethodHandler(const MethodID methodID,
const typename MethodHandler::type& method)
{
- LOGS("Service addMethodHandler, methodID " << methodID);
- mProcessor.addMethodHandler(methodID, method);
+ LOGS("Service setMethodHandler, methodID " << methodID);
+ mProcessor.setMethodHandler(methodID, method);
}
template
-void Service::addSignalHandler(const MethodID methodID,
+void Service::setSignalHandler(const MethodID methodID,
const typename SignalHandler::type& handler)
{
- LOGS("Service addSignalHandler, methodID " << methodID);
- mProcessor.addSignalHandler(methodID, handler);
+ LOGS("Service setSignalHandler, methodID " << methodID);
+ mProcessor.setSignalHandler(methodID, handler);
}
template
diff --git a/common/ipc/types.cpp b/common/ipc/types.cpp
index ba4c1c4..5d7dab6 100644
--- a/common/ipc/types.cpp
+++ b/common/ipc/types.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
diff --git a/common/ipc/types.hpp b/common/ipc/types.hpp
index 10b87df..6186f65 100644
--- a/common/ipc/types.hpp
+++ b/common/ipc/types.hpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Jan Olszak
*
diff --git a/tests/unit_tests/ipc/ut-ipc.cpp b/tests/unit_tests/ipc/ut-ipc.cpp
index c14b2a0..a15027c 100644
--- a/tests/unit_tests/ipc/ut-ipc.cpp
+++ b/tests/unit_tests/ipc/ut-ipc.cpp
@@ -33,7 +33,6 @@
#include "ipc/service.hpp"
#include "ipc/client.hpp"
-#include "ipc/ipc-gsource.hpp"
#include "ipc/types.hpp"
#include "utils/glib-loop.hpp"
#include "utils/latch.hpp"
@@ -148,7 +147,7 @@ std::shared_ptr longEchoCallback(const FileDescriptor, std::shared_ptr
return data;
}
-FileDescriptor connect(Service& s, Client& c)
+FileDescriptor connect(Service& s, Client& c, bool isServiceGlib = false, bool isClientGlib = false)
{
// Connects the Client to the Service and returns Clients FileDescriptor
ValueLatch peerFDLatch;
@@ -159,10 +158,10 @@ FileDescriptor connect(Service& s, Client& c)
s.setNewPeerCallback(newPeerCallback);
if (!s.isStarted()) {
- s.start();
+ s.start(isServiceGlib);
}
- c.start();
+ c.start(isClientGlib);
FileDescriptor peerFD = peerFDLatch.get(TIMEOUT);
s.setNewPeerCallback(nullptr);
@@ -170,66 +169,16 @@ FileDescriptor connect(Service& s, Client& c)
return peerFD;
}
-#if GLIB_CHECK_VERSION(2,36,0)
-
-std::pair connectServiceGSource(Service& s, Client& c)
+FileDescriptor connectServiceGSource(Service& s, Client& c)
{
- ValueLatch peerFDLatch;
- IPCGSource::Pointer ipcGSourcePtr = IPCGSource::create(s.getFDs(), std::bind(&Service::handle, &s, _1, _2));
-
- auto newPeerCallback = [&peerFDLatch, ipcGSourcePtr](const FileDescriptor newFD) {
- if (ipcGSourcePtr) {
- //TODO: Remove this if
- ipcGSourcePtr->addFD(newFD);
- }
- peerFDLatch.set(newFD);
- };
-
-
- s.setNewPeerCallback(newPeerCallback);
- s.setRemovedPeerCallback(std::bind(&IPCGSource::removeFD, ipcGSourcePtr, _1));
- s.start(true);
- // Service starts to process
- ipcGSourcePtr->attach();
-
- c.start();
-
- FileDescriptor peerFD = peerFDLatch.get(TIMEOUT);
- s.setNewPeerCallback(nullptr);
- BOOST_REQUIRE_NE(peerFD, 0);
- return std::make_pair(peerFD, ipcGSourcePtr);
+ return connect(s, c, true, false);
}
-std::pair connectClientGSource(Service& s, Client& c)
+FileDescriptor connectClientGSource(Service& s, Client& c)
{
- // Connects the Client to the Service and returns Clients FileDescriptor
- ValueLatch peerFDLatch;
- auto newPeerCallback = [&peerFDLatch](const FileDescriptor newFD) {
- peerFDLatch.set(newFD);
- };
- s.setNewPeerCallback(newPeerCallback);
-
- if (!s.isStarted()) {
- // Service starts to process
- s.start();
- }
-
-
- c.start(true);
- IPCGSource::Pointer ipcGSourcePtr = IPCGSource::create(c.getFDs(),
- std::bind(&Client::handle, &c, _1, _2));
-
- ipcGSourcePtr->attach();
-
- FileDescriptor peerFD = peerFDLatch.get(TIMEOUT);
- s.setNewPeerCallback(nullptr);
- BOOST_REQUIRE_NE(peerFD, 0);
- return std::make_pair(peerFD, ipcGSourcePtr);
+ return connect(s, c, false, true);
}
-#endif // GLIB_CHECK_VERSION
-
-
void testEcho(Client& c, const MethodID methodID)
{
std::shared_ptr sentData(new SendData(34));
@@ -260,13 +209,13 @@ BOOST_AUTO_TEST_CASE(ConstructorDestructor)
BOOST_AUTO_TEST_CASE(ServiceAddRemoveMethod)
{
Service s(socketPath);
- s.addMethodHandler(1, returnEmptyCallback);
- s.addMethodHandler(1, returnDataCallback);
+ s.setMethodHandler(1, returnEmptyCallback);
+ s.setMethodHandler(1, returnDataCallback);
s.start();
- s.addMethodHandler(1, echoCallback);
- s.addMethodHandler(2, returnDataCallback);
+ s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(2, returnDataCallback);
Client c(socketPath);
connect(s, c);
@@ -282,13 +231,13 @@ BOOST_AUTO_TEST_CASE(ClientAddRemoveMethod)
{
Service s(socketPath);
Client c(socketPath);
- c.addMethodHandler(1, returnEmptyCallback);
- c.addMethodHandler(1, returnDataCallback);
+ c.setMethodHandler(1, returnEmptyCallback);
+ c.setMethodHandler(1, returnDataCallback);
FileDescriptor peerFD = connect(s, c);
- c.addMethodHandler(1, echoCallback);
- c.addMethodHandler(2, returnDataCallback);
+ c.setMethodHandler(1, echoCallback);
+ c.setMethodHandler(2, returnDataCallback);
testEcho(s, 1, peerFD);
@@ -302,7 +251,7 @@ BOOST_AUTO_TEST_CASE(ServiceStartStop)
{
Service s(socketPath);
- s.addMethodHandler(1, returnDataCallback);
+ s.setMethodHandler(1, returnDataCallback);
s.start();
s.stop();
@@ -317,7 +266,7 @@ BOOST_AUTO_TEST_CASE(ClientStartStop)
{
Service s(socketPath);
Client c(socketPath);
- c.addMethodHandler(1, returnDataCallback);
+ c.setMethodHandler(1, returnDataCallback);
c.start();
c.stop();
@@ -334,8 +283,8 @@ BOOST_AUTO_TEST_CASE(ClientStartStop)
BOOST_AUTO_TEST_CASE(SyncClientToServiceEcho)
{
Service s(socketPath);
- s.addMethodHandler(1, echoCallback);
- s.addMethodHandler(2, echoCallback);
+ s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(2, echoCallback);
Client c(socketPath);
connect(s, c);
@@ -347,9 +296,9 @@ BOOST_AUTO_TEST_CASE(SyncClientToServiceEcho)
BOOST_AUTO_TEST_CASE(Restart)
{
Service s(socketPath);
- s.addMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
s.start();
- s.addMethodHandler(2, echoCallback);
+ s.setMethodHandler(2, echoCallback);
Client c(socketPath);
c.start();
@@ -373,7 +322,7 @@ BOOST_AUTO_TEST_CASE(SyncServiceToClientEcho)
{
Service s(socketPath);
Client c(socketPath);
- c.addMethodHandler(1, echoCallback);
+ c.setMethodHandler(1, echoCallback);
FileDescriptor peerFD = connect(s, c);
std::shared_ptr sentData(new SendData(56));
@@ -389,7 +338,7 @@ BOOST_AUTO_TEST_CASE(AsyncClientToServiceEcho)
// Setup Service and Client
Service s(socketPath);
- s.addMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
s.start();
Client c(socketPath);
c.start();
@@ -414,7 +363,7 @@ BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho)
Service s(socketPath);
Client c(socketPath);
- c.addMethodHandler(1, echoCallback);
+ c.setMethodHandler(1, echoCallback);
FileDescriptor peerFD = connect(s, c);
// Async call
@@ -435,7 +384,7 @@ BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho)
BOOST_AUTO_TEST_CASE(SyncTimeout)
{
Service s(socketPath);
- s.addMethodHandler(1, longEchoCallback);
+ s.setMethodHandler(1, longEchoCallback);
Client c(socketPath);
connect(s, c);
@@ -447,7 +396,7 @@ BOOST_AUTO_TEST_CASE(SyncTimeout)
BOOST_AUTO_TEST_CASE(SerializationError)
{
Service s(socketPath);
- s.addMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
Client c(socketPath);
connect(s, c);
@@ -461,7 +410,7 @@ BOOST_AUTO_TEST_CASE(SerializationError)
BOOST_AUTO_TEST_CASE(ParseError)
{
Service s(socketPath);
- s.addMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
s.start();
Client c(socketPath);
@@ -481,7 +430,7 @@ BOOST_AUTO_TEST_CASE(DisconnectedPeerError)
};
// Method will throw during serialization and disconnect automatically
- s.addMethodHandler(1, method);
+ s.setMethodHandler(1, method);
s.start();
Client c(socketPath);
@@ -510,7 +459,7 @@ BOOST_AUTO_TEST_CASE(ReadTimeout)
auto longEchoCallback = [](const FileDescriptor, std::shared_ptr& data) {
return std::shared_ptr(new LongSendData(data->intVal, LONG_OPERATION_TIME));
};
- s.addMethodHandler(1, longEchoCallback);
+ s.setMethodHandler(1, longEchoCallback);
Client c(socketPath);
connect(s, c);
@@ -524,7 +473,7 @@ BOOST_AUTO_TEST_CASE(ReadTimeout)
BOOST_AUTO_TEST_CASE(WriteTimeout)
{
Service s(socketPath);
- s.addMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
s.start();
Client c(socketPath);
@@ -559,8 +508,8 @@ BOOST_AUTO_TEST_CASE(AddSignalInRuntime)
latchB.set();
};
- c.addSignalHandler(1, handlerA);
- c.addSignalHandler(2, handlerB);
+ c.setSignalHandler(1, handlerA);
+ c.setSignalHandler(2, handlerB);
// Wait for the signals to propagate to the Service
std::this_thread::sleep_for(std::chrono::milliseconds(2 * TIMEOUT));
@@ -590,8 +539,8 @@ BOOST_AUTO_TEST_CASE(AddSignalOffline)
latchB.set();
};
- c.addSignalHandler(1, handlerA);
- c.addSignalHandler(2, handlerB);
+ c.setSignalHandler(1, handlerA);
+ c.setSignalHandler(2, handlerB);
connect(s, c);
@@ -606,9 +555,6 @@ BOOST_AUTO_TEST_CASE(AddSignalOffline)
}
-#if GLIB_CHECK_VERSION(2,36,0)
-
-// FIXME This test causes segfault, however it should work in GDB.
BOOST_AUTO_TEST_CASE(ServiceGSource)
{
utils::Latch l;
@@ -620,13 +566,12 @@ BOOST_AUTO_TEST_CASE(ServiceGSource)
IPCGSource::Pointer serviceGSource;
Service s(socketPath);
- s.addMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
Client c(socketPath);
- s.addSignalHandler(2, signalHandler);
+ s.setSignalHandler(2, signalHandler);
- auto ret = connectServiceGSource(s, c);
- serviceGSource = ret.second;
+ connectServiceGSource(s, c);
testEcho(c, 1);
@@ -636,6 +581,7 @@ BOOST_AUTO_TEST_CASE(ServiceGSource)
BOOST_CHECK(l.wait(TIMEOUT));
}
+
BOOST_AUTO_TEST_CASE(ClientGSource)
{
utils::Latch l;
@@ -650,12 +596,10 @@ BOOST_AUTO_TEST_CASE(ClientGSource)
IPCGSource::Pointer clientGSource;
Client c(socketPath);
- c.addMethodHandler(1, echoCallback);
- c.addSignalHandler(2, signalHandler);
+ c.setMethodHandler(1, echoCallback);
+ c.setSignalHandler(2, signalHandler);
- auto ret = connectClientGSource(s, c);
- FileDescriptor peerFD = ret.first;
- clientGSource = ret.second;
+ FileDescriptor peerFD = connectClientGSource(s, c);
testEcho(s, 1, peerFD);
@@ -665,8 +609,6 @@ BOOST_AUTO_TEST_CASE(ClientGSource)
BOOST_CHECK(l.wait(TIMEOUT));
}
-#endif // GLIB_CHECK_VERSION
-
// BOOST_AUTO_TEST_CASE(ConnectionLimitTest)
// {
// unsigned oldLimit = ipc::getMaxFDNumber();
@@ -674,7 +616,7 @@ BOOST_AUTO_TEST_CASE(ClientGSource)
// // Setup Service and many Clients
// Service s(socketPath);
-// s.addMethodHandler(1, echoCallback);
+// s.setMethodHandler(1, echoCallback);
// s.start();
// std::list clients;
--
2.7.4
From fee242388c9f5efbb54aa6c646d3709225be2b84 Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Fri, 23 Jan 2015 16:32:02 +0100
Subject: [PATCH 05/16] Fix ut threading, ut refactor
[Bug/Feature] N/A
[Cause] N/A
[Solution] N/A
[Verification] Build, run tests
Change-Id: I9eca161ee3752f29611395dccc73e9ba8e614e6d
---
common/ipc/internals/processor.hpp | 1 +
tests/unit_tests/config/ut-kvstore.cpp | 38 ++++++-
tests/unit_tests/dbus/ut-connection.cpp | 28 +++--
tests/unit_tests/ipc/ut-ipc.cpp | 182 ++++++++++++++++++--------------
4 files changed, 152 insertions(+), 97 deletions(-)
diff --git a/common/ipc/internals/processor.hpp b/common/ipc/internals/processor.hpp
index 40dd4c0..c3bcc6b 100644
--- a/common/ipc/internals/processor.hpp
+++ b/common/ipc/internals/processor.hpp
@@ -548,6 +548,7 @@ std::shared_ptr Processor::callSync(const MethodID methodID,
Status returnStatus = ipc::Status::UNDEFINED;
auto process = [&result, &mutex, &cv, &returnStatus](Status status, std::shared_ptr returnedData) {
+ std::unique_lock lock(mutex);
returnStatus = status;
result = returnedData;
cv.notify_all();
diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp
index 9855457..af2fa29 100644
--- a/tests/unit_tests/config/ut-kvstore.cpp
+++ b/tests/unit_tests/config/ut-kvstore.cpp
@@ -29,12 +29,15 @@
#include "config/kvstore.hpp"
#include "config/exception.hpp"
#include "utils/scoped-dir.hpp"
+#include "utils/latch.hpp"
#include
#include
+#include
#include
using namespace config;
+using namespace vasum::utils;
namespace fs = boost::filesystem;
namespace {
@@ -171,19 +174,19 @@ BOOST_AUTO_TEST_CASE(SingleValueTest)
namespace {
template
-void setVector(Fixture& f, std::vector vec)
+void setVector(Fixture& f, const 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_NO_THROW(storedVec = f.c.get>(KEY))
BOOST_CHECK_EQUAL_COLLECTIONS(storedVec.begin(), storedVec.end(), vec.begin(), vec.end());
}
template
void testVectorOfValues(Fixture& f,
- std::vector a,
- std::vector b,
- std::vector c)
+ const std::vector& a,
+ const std::vector& b,
+ const std::vector& c)
{
// Set
setVector(f, a);
@@ -221,6 +224,31 @@ BOOST_AUTO_TEST_CASE(ClearTest)
BOOST_CHECK_THROW(c.get(KEY), ConfigException);
}
+BOOST_AUTO_TEST_CASE(TransactionTest)
+{
+ auto t1 = c.getTransaction();
+ BOOST_CHECK_EQUAL(t1.use_count(), 1);
+
+ auto t2 = c.getTransaction();
+ BOOST_CHECK_EQUAL(t1.use_count(), 2);
+ BOOST_CHECK_EQUAL(t2.use_count(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionTwoThreadsTest)
+{
+ Latch latch;
+ auto trans1 = c.getTransaction();
+ std::thread thread([&]{
+ auto trans2 = c.getTransaction();
+ latch.set();
+ });
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ BOOST_CHECK(latch.empty());
+ trans1.reset();
+ latch.wait();
+ thread.join();
+}
+
BOOST_AUTO_TEST_CASE(KeyTest)
{
BOOST_CHECK_EQUAL(key(), "");
diff --git a/tests/unit_tests/dbus/ut-connection.cpp b/tests/unit_tests/dbus/ut-connection.cpp
index 96175ee..94b02b7 100644
--- a/tests/unit_tests/dbus/ut-connection.cpp
+++ b/tests/unit_tests/dbus/ut-connection.cpp
@@ -414,8 +414,9 @@ BOOST_AUTO_TEST_CASE(MethodAsyncCallTest)
conn1->registerObject(TESTAPI_OBJECT_PATH, TESTAPI_DEFINITION, handler);
auto asyncResult1 = [&](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
- BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT));
- callDone.set();
+ if (g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT)) {
+ callDone.set();
+ }
};
conn2->callMethodAsync(TESTAPI_BUS_NAME,
TESTAPI_OBJECT_PATH,
@@ -429,8 +430,9 @@ BOOST_AUTO_TEST_CASE(MethodAsyncCallTest)
auto asyncResult2 = [&](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
const gchar* ret = NULL;
g_variant_get(asyncMethodCallResult.get(), "(&s)", &ret);
- BOOST_CHECK_EQUAL("resp: arg", ret);
- callDone.set();
+ if (ret == std::string("resp: arg")) {
+ callDone.set();
+ }
};
conn2->callMethodAsync(TESTAPI_BUS_NAME,
TESTAPI_OBJECT_PATH,
@@ -442,8 +444,12 @@ BOOST_AUTO_TEST_CASE(MethodAsyncCallTest)
BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
auto asyncResult3 = [&](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
- BOOST_CHECK_THROW(asyncMethodCallResult.get(), DbusCustomException);
- callDone.set();
+ try {
+ asyncMethodCallResult.get();
+ } catch (DbusCustomException&) {
+ //expected
+ callDone.set();
+ }
};
conn2->callMethodAsync(TESTAPI_BUS_NAME,
TESTAPI_OBJECT_PATH,
@@ -494,8 +500,9 @@ BOOST_AUTO_TEST_CASE(MethodAsyncCallAsyncHandlerTest)
auto asyncResult = [&](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
const gchar* ret = NULL;
g_variant_get(asyncMethodCallResult.get(), "(&s)", &ret);
- BOOST_CHECK_EQUAL("resp: arg", ret);
- callDone.set();
+ if (ret == std::string("resp: arg")) {
+ callDone.set();
+ }
};
conn2->callMethodAsync(TESTAPI_BUS_NAME,
TESTAPI_OBJECT_PATH,
@@ -583,8 +590,9 @@ BOOST_AUTO_TEST_CASE(DbusApiNotifyTest)
DbusTestClient client;
auto onNotify = [&](const std::string& message) {
- BOOST_CHECK_EQUAL("notification", message);
- notified.set();
+ if (message == "notification") {
+ notified.set();
+ }
};
client.setNotifyCallback(onNotify);
server.notifyClients("notification");
diff --git a/tests/unit_tests/ipc/ut-ipc.cpp b/tests/unit_tests/ipc/ut-ipc.cpp
index a15027c..e5609f7 100644
--- a/tests/unit_tests/ipc/ut-ipc.cpp
+++ b/tests/unit_tests/ipc/ut-ipc.cpp
@@ -25,7 +25,6 @@
// TODO: Test connection limit
// TODO: Refactor tests - function for setting up env
-// TODO: Callback wrapper that waits till the callback is called
#include "config.hpp"
@@ -80,7 +79,17 @@ struct Fixture {
struct SendData {
int intVal;
- SendData(int i = 0): intVal(i) {}
+ SendData(int i): intVal(i) {}
+
+ CONFIG_REGISTER
+ (
+ intVal
+ )
+};
+
+struct RecvData {
+ int intVal;
+ RecvData(): intVal(-1) {}
CONFIG_REGISTER
(
@@ -128,23 +137,23 @@ struct ThrowOnAcceptData {
std::shared_ptr returnEmptyCallback(const FileDescriptor, std::shared_ptr