From fee242388c9f5efbb54aa6c646d3709225be2b84 Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Fri, 23 Jan 2015 16:32:02 +0100
Subject: [PATCH 01/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&)
{
- return std::shared_ptr(new EmptyData());
+ return std::make_shared();
}
-std::shared_ptr returnDataCallback(const FileDescriptor, std::shared_ptr&)
+std::shared_ptr returnDataCallback(const FileDescriptor, std::shared_ptr&)
{
- return std::shared_ptr(new SendData(1));
+ return std::make_shared(1);
}
-std::shared_ptr echoCallback(const FileDescriptor, std::shared_ptr& data)
+std::shared_ptr echoCallback(const FileDescriptor, std::shared_ptr& data)
{
- return data;
+ return std::make_shared(data->intVal);
}
-std::shared_ptr longEchoCallback(const FileDescriptor, std::shared_ptr& data)
+std::shared_ptr longEchoCallback(const FileDescriptor, std::shared_ptr& data)
{
std::this_thread::sleep_for(std::chrono::milliseconds(LONG_OPERATION_TIME));
- return data;
+ return std::make_shared(data->intVal);
}
FileDescriptor connect(Service& s, Client& c, bool isServiceGlib = false, bool isClientGlib = false)
@@ -182,7 +191,7 @@ FileDescriptor connectClientGSource(Service& s, Client& c)
void testEcho(Client& c, const MethodID methodID)
{
std::shared_ptr sentData(new SendData(34));
- std::shared_ptr recvData = c.callSync(methodID, sentData, TIMEOUT);
+ std::shared_ptr recvData = c.callSync(methodID, sentData, TIMEOUT);
BOOST_REQUIRE(recvData);
BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
}
@@ -190,7 +199,7 @@ void testEcho(Client& c, const MethodID methodID)
void testEcho(Service& s, const MethodID methodID, const FileDescriptor peerFD)
{
std::shared_ptr sentData(new SendData(56));
- std::shared_ptr recvData = s.callSync(methodID, peerFD, sentData, TIMEOUT);
+ std::shared_ptr recvData = s.callSync(methodID, peerFD, sentData, TIMEOUT);
BOOST_REQUIRE(recvData);
BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
}
@@ -210,12 +219,12 @@ BOOST_AUTO_TEST_CASE(ServiceAddRemoveMethod)
{
Service s(socketPath);
s.setMethodHandler(1, returnEmptyCallback);
- s.setMethodHandler(1, returnDataCallback);
+ s.setMethodHandler(1, returnDataCallback);
s.start();
- s.setMethodHandler(1, echoCallback);
- s.setMethodHandler(2, returnDataCallback);
+ s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(2, returnDataCallback);
Client c(socketPath);
connect(s, c);
@@ -232,12 +241,12 @@ BOOST_AUTO_TEST_CASE(ClientAddRemoveMethod)
Service s(socketPath);
Client c(socketPath);
c.setMethodHandler(1, returnEmptyCallback);
- c.setMethodHandler(1, returnDataCallback);
+ c.setMethodHandler(1, returnDataCallback);
FileDescriptor peerFD = connect(s, c);
- c.setMethodHandler(1, echoCallback);
- c.setMethodHandler(2, returnDataCallback);
+ c.setMethodHandler(1, echoCallback);
+ c.setMethodHandler(2, returnDataCallback);
testEcho(s, 1, peerFD);
@@ -251,7 +260,7 @@ BOOST_AUTO_TEST_CASE(ServiceStartStop)
{
Service s(socketPath);
- s.setMethodHandler(1, returnDataCallback);
+ s.setMethodHandler(1, returnDataCallback);
s.start();
s.stop();
@@ -266,7 +275,7 @@ BOOST_AUTO_TEST_CASE(ClientStartStop)
{
Service s(socketPath);
Client c(socketPath);
- c.setMethodHandler(1, returnDataCallback);
+ c.setMethodHandler(1, returnDataCallback);
c.start();
c.stop();
@@ -283,8 +292,8 @@ BOOST_AUTO_TEST_CASE(ClientStartStop)
BOOST_AUTO_TEST_CASE(SyncClientToServiceEcho)
{
Service s(socketPath);
- s.setMethodHandler(1, echoCallback);
- s.setMethodHandler(2, echoCallback);
+ s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(2, echoCallback);
Client c(socketPath);
connect(s, c);
@@ -296,9 +305,9 @@ BOOST_AUTO_TEST_CASE(SyncClientToServiceEcho)
BOOST_AUTO_TEST_CASE(Restart)
{
Service s(socketPath);
- s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
s.start();
- s.setMethodHandler(2, echoCallback);
+ s.setMethodHandler(2, echoCallback);
Client c(socketPath);
c.start();
@@ -322,11 +331,11 @@ BOOST_AUTO_TEST_CASE(SyncServiceToClientEcho)
{
Service s(socketPath);
Client c(socketPath);
- c.setMethodHandler(1, echoCallback);
+ c.setMethodHandler(1, echoCallback);
FileDescriptor peerFD = connect(s, c);
std::shared_ptr sentData(new SendData(56));
- std::shared_ptr recvData = s.callSync(1, peerFD, sentData);
+ std::shared_ptr recvData = s.callSync(1, peerFD, sentData);
BOOST_REQUIRE(recvData);
BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
}
@@ -334,49 +343,49 @@ BOOST_AUTO_TEST_CASE(SyncServiceToClientEcho)
BOOST_AUTO_TEST_CASE(AsyncClientToServiceEcho)
{
std::shared_ptr sentData(new SendData(34));
- ValueLatch recvDataLatch;
+ ValueLatch> recvDataLatch;
// Setup Service and Client
Service s(socketPath);
- s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
s.start();
Client c(socketPath);
c.start();
//Async call
- auto dataBack = [&recvDataLatch](ipc::Status status, std::shared_ptr& data) {
+ auto dataBack = [&recvDataLatch](ipc::Status status, std::shared_ptr& data) {
if (status == ipc::Status::OK) {
- recvDataLatch.set(*data);
+ recvDataLatch.set(data);
}
};
- c.callAsync(1, sentData, dataBack);
+ c.callAsync(1, sentData, dataBack);
// Wait for the response
- std::shared_ptr recvData(new SendData(recvDataLatch.get(TIMEOUT)));
+ std::shared_ptr recvData(recvDataLatch.get(TIMEOUT));
BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
}
BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho)
{
std::shared_ptr sentData(new SendData(56));
- ValueLatch recvDataLatch;
+ ValueLatch> recvDataLatch;
Service s(socketPath);
Client c(socketPath);
- c.setMethodHandler(1, echoCallback);
+ c.setMethodHandler(1, echoCallback);
FileDescriptor peerFD = connect(s, c);
// Async call
- auto dataBack = [&recvDataLatch](ipc::Status status, std::shared_ptr& data) {
+ auto dataBack = [&recvDataLatch](ipc::Status status, std::shared_ptr& data) {
if (status == ipc::Status::OK) {
- recvDataLatch.set(*data);
+ recvDataLatch.set(data);
}
};
- s.callAsync(1, peerFD, sentData, dataBack);
+ s.callAsync(1, peerFD, sentData, dataBack);
// Wait for the response
- std::shared_ptr recvData(new SendData(recvDataLatch.get(TIMEOUT)));
+ std::shared_ptr recvData(recvDataLatch.get(TIMEOUT));
BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
}
@@ -384,33 +393,33 @@ BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho)
BOOST_AUTO_TEST_CASE(SyncTimeout)
{
Service s(socketPath);
- s.setMethodHandler(1, longEchoCallback);
+ s.setMethodHandler(1, longEchoCallback);
Client c(socketPath);
connect(s, c);
std::shared_ptr sentData(new SendData(78));
- BOOST_REQUIRE_THROW((c.callSync(1, sentData, TIMEOUT)), IPCException);
+ BOOST_REQUIRE_THROW((c.callSync(1, sentData, TIMEOUT)), IPCException);
}
BOOST_AUTO_TEST_CASE(SerializationError)
{
Service s(socketPath);
- s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
Client c(socketPath);
connect(s, c);
std::shared_ptr throwingData(new ThrowOnAcceptData());
- BOOST_CHECK_THROW((c.callSync(1, throwingData)), IPCSerializationException);
+ BOOST_CHECK_THROW((c.callSync(1, throwingData)), IPCSerializationException);
}
BOOST_AUTO_TEST_CASE(ParseError)
{
Service s(socketPath);
- s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
s.start();
Client c(socketPath);
@@ -436,12 +445,12 @@ BOOST_AUTO_TEST_CASE(DisconnectedPeerError)
Client c(socketPath);
c.start();
- auto dataBack = [&retStatusLatch](ipc::Status status, std::shared_ptr&) {
+ auto dataBack = [&retStatusLatch](ipc::Status status, std::shared_ptr&) {
retStatusLatch.set(status);
};
std::shared_ptr sentData(new SendData(78));
- c.callAsync(1, sentData, dataBack);
+ c.callAsync(1, sentData, dataBack);
// Wait for the response
ipc::Status retStatus = retStatusLatch.get(TIMEOUT);
@@ -456,24 +465,24 @@ BOOST_AUTO_TEST_CASE(DisconnectedPeerError)
BOOST_AUTO_TEST_CASE(ReadTimeout)
{
Service s(socketPath);
- auto longEchoCallback = [](const FileDescriptor, std::shared_ptr& data) {
+ auto longEchoCallback = [](const FileDescriptor, std::shared_ptr& data) {
return std::shared_ptr(new LongSendData(data->intVal, LONG_OPERATION_TIME));
};
- s.setMethodHandler(1, longEchoCallback);
+ s.setMethodHandler(1, longEchoCallback);
Client c(socketPath);
connect(s, c);
// Test timeout on read
std::shared_ptr sentData(new SendData(334));
- BOOST_CHECK_THROW((c.callSync(1, sentData, TIMEOUT)), IPCException);
+ BOOST_CHECK_THROW((c.callSync(1, sentData, TIMEOUT)), IPCException);
}
BOOST_AUTO_TEST_CASE(WriteTimeout)
{
Service s(socketPath);
- s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
s.start();
Client c(socketPath);
@@ -481,77 +490,86 @@ BOOST_AUTO_TEST_CASE(WriteTimeout)
// Test echo with a minimal timeout
std::shared_ptr sentDataA(new LongSendData(34, SHORT_OPERATION_TIME));
- std::shared_ptr recvData = c.callSync(1, sentDataA, TIMEOUT);
+ std::shared_ptr recvData = c.callSync(1, sentDataA, TIMEOUT);
BOOST_REQUIRE(recvData);
BOOST_CHECK_EQUAL(recvData->intVal, sentDataA->intVal);
// Test timeout on write
std::shared_ptr sentDataB(new LongSendData(34, LONG_OPERATION_TIME));
- BOOST_CHECK_THROW((c.callSync(1, sentDataB, TIMEOUT)), IPCTimeoutException);
+ BOOST_CHECK_THROW((c.callSync(1, sentDataB, TIMEOUT)), IPCTimeoutException);
}
BOOST_AUTO_TEST_CASE(AddSignalInRuntime)
{
- utils::Latch latchA;
- utils::Latch latchB;
+ ValueLatch> recvDataLatchA;
+ ValueLatch> recvDataLatchB;
Service s(socketPath);
Client c(socketPath);
connect(s, c);
- auto handlerA = [&latchA](const FileDescriptor, std::shared_ptr&) {
- latchA.set();
+ auto handlerA = [&recvDataLatchA](const FileDescriptor, std::shared_ptr& data) {
+ recvDataLatchA.set(data);
};
- auto handlerB = [&latchB](const FileDescriptor, std::shared_ptr&) {
- latchB.set();
+ auto handlerB = [&recvDataLatchB](const FileDescriptor, std::shared_ptr& data) {
+ recvDataLatchB.set(data);
};
- c.setSignalHandler(1, handlerA);
- c.setSignalHandler(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));
- auto data = std::make_shared(1);
- s.signal(2, data);
- s.signal(1, data);
+ auto sendDataA = std::make_shared(1);
+ auto sendDataB = std::make_shared(2);
+ s.signal(2, sendDataB);
+ s.signal(1, sendDataA);
// Wait for the signals to arrive
- BOOST_CHECK(latchA.wait(TIMEOUT) && latchB.wait(TIMEOUT));
+ std::shared_ptr recvDataA(recvDataLatchA.get(TIMEOUT));
+ std::shared_ptr recvDataB(recvDataLatchB.get(TIMEOUT));
+ BOOST_CHECK_EQUAL(recvDataA->intVal, sendDataA->intVal);
+ BOOST_CHECK_EQUAL(recvDataB->intVal, sendDataB->intVal);
}
BOOST_AUTO_TEST_CASE(AddSignalOffline)
{
- utils::Latch latchA;
- utils::Latch latchB;
+ ValueLatch> recvDataLatchA;
+ ValueLatch> recvDataLatchB;
Service s(socketPath);
Client c(socketPath);
- auto handlerA = [&latchA](const FileDescriptor, std::shared_ptr&) {
- latchA.set();
+ auto handlerA = [&recvDataLatchA](const FileDescriptor, std::shared_ptr& data) {
+ recvDataLatchA.set(data);
};
- auto handlerB = [&latchB](const FileDescriptor, std::shared_ptr&) {
- latchB.set();
+ auto handlerB = [&recvDataLatchB](const FileDescriptor, std::shared_ptr& data) {
+ recvDataLatchB.set(data);
};
- c.setSignalHandler(1, handlerA);
- c.setSignalHandler(2, handlerB);
+ c.setSignalHandler(1, handlerA);
+ c.setSignalHandler(2, handlerB);
connect(s, c);
// Wait for the information about the signals to propagate
std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT));
- auto data = std::make_shared(1);
- s.signal(2, data);
- s.signal(1, data);
+
+ auto sendDataA = std::make_shared(1);
+ auto sendDataB = std::make_shared(2);
+ s.signal(2, sendDataB);
+ s.signal(1, sendDataA);
// Wait for the signals to arrive
- BOOST_CHECK(latchA.wait(TIMEOUT) && latchB.wait(TIMEOUT));
+ std::shared_ptr recvDataA(recvDataLatchA.get(TIMEOUT));
+ std::shared_ptr recvDataB(recvDataLatchB.get(TIMEOUT));
+ BOOST_CHECK_EQUAL(recvDataA->intVal, sendDataA->intVal);
+ BOOST_CHECK_EQUAL(recvDataB->intVal, sendDataB->intVal);
}
@@ -560,16 +578,16 @@ BOOST_AUTO_TEST_CASE(ServiceGSource)
utils::Latch l;
ScopedGlibLoop loop;
- auto signalHandler = [&l](const FileDescriptor, std::shared_ptr&) {
+ auto signalHandler = [&l](const FileDescriptor, std::shared_ptr&) {
l.set();
};
IPCGSource::Pointer serviceGSource;
Service s(socketPath);
- s.setMethodHandler(1, echoCallback);
+ s.setMethodHandler(1, echoCallback);
Client c(socketPath);
- s.setSignalHandler(2, signalHandler);
+ s.setSignalHandler(2, signalHandler);
connectServiceGSource(s, c);
@@ -587,7 +605,7 @@ BOOST_AUTO_TEST_CASE(ClientGSource)
utils::Latch l;
ScopedGlibLoop loop;
- auto signalHandler = [&l](const FileDescriptor, std::shared_ptr&) {
+ auto signalHandler = [&l](const FileDescriptor, std::shared_ptr&) {
l.set();
};
@@ -596,8 +614,8 @@ BOOST_AUTO_TEST_CASE(ClientGSource)
IPCGSource::Pointer clientGSource;
Client c(socketPath);
- c.setMethodHandler(1, echoCallback);
- c.setSignalHandler(2, signalHandler);
+ c.setMethodHandler(1, echoCallback);
+ c.setSignalHandler(2, signalHandler);
FileDescriptor peerFD = connectClientGSource(s, c);
@@ -616,7 +634,7 @@ BOOST_AUTO_TEST_CASE(ClientGSource)
// // Setup Service and many Clients
// Service s(socketPath);
-// s.setMethodHandler(1, echoCallback);
+// s.setMethodHandler(1, echoCallback);
// s.start();
// std::list clients;
@@ -632,7 +650,7 @@ BOOST_AUTO_TEST_CASE(ClientGSource)
// for (auto it = clients.begin(); it != clients.end(); ++it) {
// try {
// std::shared_ptr sentData(new SendData(generator()));
-// std::shared_ptr recvData = it->callSync(1, sentData);
+// std::shared_ptr recvData = it->callSync(1, sentData);
// BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal);
// } catch (...) {}
// }
--
2.7.4
From 849928b8d50b923e5ff5959de68bfc642da135fa Mon Sep 17 00:00:00 2001
From: Mateusz Malicki
Date: Mon, 26 Jan 2015 15:40:57 +0100
Subject: [PATCH 02/16] Add list and remove to ZoneProvision class
[Bug/Feature] Ability to list and remove provision
[Cause] N/A
[Solution] N/A
[Verification] Build, run tests
Change-Id: I3e3a566dd00298d4111fb9a3b5ec6d2351774ac7
---
server/zone-provision.cpp | 106 ++++++++++++++++++++++----
server/zone-provision.hpp | 42 ++++++----
server/zone.cpp | 28 +++----
server/zone.hpp | 22 +++---
tests/unit_tests/server/ut-zone-provision.cpp | 69 +++++++++++++++++
5 files changed, 214 insertions(+), 53 deletions(-)
diff --git a/server/zone-provision.cpp b/server/zone-provision.cpp
index 928d887..861a506 100644
--- a/server/zone-provision.cpp
+++ b/server/zone-provision.cpp
@@ -36,6 +36,7 @@
#include
#include
+#include
#include
namespace fs = boost::filesystem;
@@ -65,42 +66,53 @@ void ZoneProvision::saveProvisioningConfig()
config::saveToKVStore(mDbPath, mProvisioningConfig, mDbPrefix);
}
-void ZoneProvision::declareProvision(ZoneProvisioningConfig::Provision&& provision)
+std::string ZoneProvision::declareProvision(ZoneProvisioningConfig::Provision&& provision)
{
+ std::string id = getId(provision);
+ auto it = std::find_if(mProvisioningConfig.provisions.begin(),
+ mProvisioningConfig.provisions.end(),
+ [&](const ZoneProvisioningConfig::Provision& provision) {
+ return getId(provision) == id;
+ });
+ if (it != mProvisioningConfig.provisions.end()) {
+ LOGE("Can't add provision. It already exists: " << id);
+ throw UtilsException("Provision already exists");
+ }
mProvisioningConfig.provisions.push_back(std::move(provision));
saveProvisioningConfig();
+ return id;
}
-void ZoneProvision::declareFile(const int32_t& type,
- const std::string& path,
- const int32_t& flags,
- const int32_t& mode)
+std::string ZoneProvision::declareFile(const int32_t& type,
+ const std::string& path,
+ const int32_t& flags,
+ const int32_t& mode)
{
ZoneProvisioningConfig::Provision provision;
provision.set(ZoneProvisioningConfig::File({type, path, flags, mode}));
- declareProvision(std::move(provision));
+ return declareProvision(std::move(provision));
}
-void ZoneProvision::declareMount(const std::string& source,
- const std::string& target,
- const std::string& type,
- const int64_t& flags,
- const std::string& data)
+std::string ZoneProvision::declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t& flags,
+ const std::string& data)
{
ZoneProvisioningConfig::Provision provision;
provision.set(ZoneProvisioningConfig::Mount({source, target, type, flags, data}));
- declareProvision(std::move(provision));
+ return declareProvision(std::move(provision));
}
-void ZoneProvision::declareLink(const std::string& source,
- const std::string& target)
+std::string ZoneProvision::declareLink(const std::string& source,
+ const std::string& target)
{
ZoneProvisioningConfig::Provision provision;
provision.set(ZoneProvisioningConfig::Link({source, target}));
- declareProvision(std::move(provision));
+ return declareProvision(std::move(provision));
}
void ZoneProvision::start() noexcept
@@ -138,6 +150,31 @@ void ZoneProvision::stop() noexcept
});
}
+std::vector ZoneProvision::list() const
+{
+ std::vector items;
+ for (const auto& provision : mProvisioningConfig.provisions) {
+ items.push_back(getId(provision));
+ }
+ return items;
+}
+
+void ZoneProvision::remove(const std::string& item)
+{
+
+ const auto it = std::find_if(mProvisioningConfig.provisions.begin(),
+ mProvisioningConfig.provisions.end(),
+ [&](const ZoneProvisioningConfig::Provision& provision) {
+ return getId(provision) == item;
+ });
+ if (it == mProvisioningConfig.provisions.end()) {
+ throw UtilsException("Can't find provision");
+ }
+
+ mProvisioningConfig.provisions.erase(it);
+ LOGI("Provision removed: " << item);
+}
+
void ZoneProvision::file(const ZoneProvisioningConfig::File& config)
{
bool ret = false;
@@ -216,4 +253,43 @@ void ZoneProvision::link(const ZoneProvisioningConfig::Link& config)
throw UtilsException("Failed to hard link: path prefix is not valid");
}
+std::string ZoneProvision::getId(const ZoneProvisioningConfig::File& file) const
+{
+ //TODO output of type,flags and mode should be more user friendly
+ return "file " +
+ file.path + " " +
+ std::to_string(file.type) + " " +
+ std::to_string(file.flags) + " " +
+ std::to_string(file.mode);
+}
+
+std::string ZoneProvision::getId(const ZoneProvisioningConfig::Mount& mount) const
+{
+ //TODO output of flags should be more user friendly
+ return "mount " +
+ mount.source + " " +
+ mount.target + " " +
+ mount.type + " " +
+ std::to_string(mount.flags) + " " +
+ mount.data;
+}
+
+std::string ZoneProvision::getId(const ZoneProvisioningConfig::Link& link) const
+{
+ return "link " + link.source + " " + link.target;
+}
+
+std::string ZoneProvision::getId(const ZoneProvisioningConfig::Provision& provision) const
+{
+ using namespace vasum;
+ if (provision.is()) {
+ return getId(provision.as());
+ } else if (provision.is()) {
+ return getId(provision.as());
+ } else if (provision.is()) {
+ return getId(provision.as());
+ }
+ throw UtilsException("Unknown provision type");
+}
+
} // namespace vasum
diff --git a/server/zone-provision.hpp b/server/zone-provision.hpp
index f6933db..2f123ae 100644
--- a/server/zone-provision.hpp
+++ b/server/zone-provision.hpp
@@ -64,27 +64,39 @@ public:
/**
* Declare file, directory or pipe that will be created while zone startup
*/
- void declareFile(const int32_t& type,
- const std::string& path,
- const int32_t& flags,
- const int32_t& mode);
+ std::string declareFile(const int32_t& type,
+ const std::string& path,
+ const int32_t& flags,
+ const int32_t& mode);
/**
* Declare mount that will be created while zone startup
*/
- void declareMount(const std::string& source,
- const std::string& target,
- const std::string& type,
- const int64_t& flags,
- const std::string& data);
+ std::string declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t& flags,
+ const std::string& data);
/**
* Declare link that will be created while zone startup
*/
- void declareLink(const std::string& source,
- const std::string& target);
+ std::string declareLink(const std::string& source,
+ const std::string& target);
void start() noexcept;
void stop() noexcept;
+ /**
+ * List all provisioned resources
+ */
+ std::vector list() const;
+
+ /**
+ * Remove resource
+ *
+ * @param item resource to be removed (as in list())
+ */
+ void remove(const std::string& item);
+
private:
ZoneProvisioningConfig mProvisioningConfig;
std::string mRootPath;
@@ -94,14 +106,18 @@ private:
std::list mProvisioned;
void saveProvisioningConfig();
- void declareProvision(ZoneProvisioningConfig::Provision&& provision);
+ std::string declareProvision(ZoneProvisioningConfig::Provision&& provision);
void mount(const ZoneProvisioningConfig::Mount& config);
void umount(const ZoneProvisioningConfig::Mount& config);
void file(const ZoneProvisioningConfig::File& config);
void link(const ZoneProvisioningConfig::Link& config);
-};
+ std::string getId(const ZoneProvisioningConfig::File& file) const;
+ std::string getId(const ZoneProvisioningConfig::Mount& mount) const;
+ std::string getId(const ZoneProvisioningConfig::Link& link) const;
+ std::string getId(const ZoneProvisioningConfig::Provision& provision) const;
+};
} // namespace vasum
diff --git a/server/zone.cpp b/server/zone.cpp
index fbbd819..c3f6991 100644
--- a/server/zone.cpp
+++ b/server/zone.cpp
@@ -381,27 +381,27 @@ void Zone::proxyCallAsync(const std::string& busName,
}
}
-void Zone::declareFile(const int32_t& type,
- const std::string& path,
- const int32_t& flags,
- const int32_t& mode)
+std::string Zone::declareFile(const int32_t& type,
+ const std::string& path,
+ const int32_t& flags,
+ const int32_t& mode)
{
- mProvision->declareFile(type, path, flags, mode);
+ return mProvision->declareFile(type, path, flags, mode);
}
-void Zone::declareMount(const std::string& source,
- const std::string& target,
- const std::string& type,
- const int64_t& flags,
- const std::string& data)
+std::string Zone::declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t& flags,
+ const std::string& data)
{
- mProvision->declareMount(source, target, type, flags, data);
+ return mProvision->declareMount(source, target, type, flags, data);
}
-void Zone::declareLink(const std::string& source,
- const std::string& target)
+std::string Zone::declareLink(const std::string& source,
+ const std::string& target)
{
- mProvision->declareLink(source, target);
+ return mProvision->declareLink(source, target);
}
} // namespace vasum
diff --git a/server/zone.hpp b/server/zone.hpp
index 2eab7f3..8cd3535 100644
--- a/server/zone.hpp
+++ b/server/zone.hpp
@@ -230,23 +230,23 @@ public:
/**
* Declare file, directory or pipe that will be created while zone startup
*/
- void declareFile(const int32_t& type,
- const std::string& path,
- const int32_t& flags,
- const int32_t& mode);
+ std::string declareFile(const int32_t& type,
+ const std::string& path,
+ const int32_t& flags,
+ const int32_t& mode);
/**
* Declare mount that will be created while zone startup
*/
- void declareMount(const std::string& source,
- const std::string& target,
- const std::string& type,
- const int64_t& flags,
- const std::string& data);
+ std::string declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t& flags,
+ const std::string& data);
/**
* Declare link that will be created while zone startup
*/
- void declareLink(const std::string& source,
- const std::string& target);
+ std::string declareLink(const std::string& source,
+ const std::string& target);
/**
* Get zone root path
diff --git a/tests/unit_tests/server/ut-zone-provision.cpp b/tests/unit_tests/server/ut-zone-provision.cpp
index c488c09..9038fd4 100644
--- a/tests/unit_tests/server/ut-zone-provision.cpp
+++ b/tests/unit_tests/server/ut-zone-provision.cpp
@@ -89,6 +89,12 @@ struct Fixture {
}
};
+std::function expectedMessage(const std::string& message) {
+ return [=](const std::exception& e) {
+ return e.what() == message;
+ };
+}
+
} // namespace
@@ -257,6 +263,9 @@ BOOST_AUTO_TEST_CASE(DeclareMountTest)
ZoneProvision zoneProvision = create({});
zoneProvision.declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake");
zoneProvision.declareMount("/fake/path2", "/fake/path2", "tmpfs", 077, "fake");
+ BOOST_CHECK_EXCEPTION(zoneProvision.declareMount("/fake/path2", "/fake/path2", "tmpfs", 077, "fake"),
+ UtilsException,
+ expectedMessage("Provision already exists"));
ZoneProvisioningConfig config;
load(config);
@@ -338,4 +347,64 @@ BOOST_AUTO_TEST_CASE(ProvisionedAlreadyTest)
zoneProvision.stop();
}
+BOOST_AUTO_TEST_CASE(ListTest)
+{
+ std::vector expected;
+ ZoneProvision zoneProvision = create({});
+
+ zoneProvision.declareFile(1, "path", 0747, 0777);
+ zoneProvision.declareFile(2, "path", 0747, 0777);
+ expected.push_back("file path 1 " + std::to_string(0747) + " " + std::to_string(0777));
+ expected.push_back("file path 2 " + std::to_string(0747) + " " + std::to_string(0777));
+
+ zoneProvision.declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake1");
+ zoneProvision.declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake2");
+ expected.push_back("mount /fake/path1 /fake/path2 tmpfs " + std::to_string(077) + " fake1");
+ expected.push_back("mount /fake/path1 /fake/path2 tmpfs " + std::to_string(077) + " fake2");
+
+ zoneProvision.declareLink("/fake/path1", "/fake/path3");
+ zoneProvision.declareLink("/fake/path2", "/fake/path4");
+ expected.push_back("link /fake/path1 /fake/path3");
+ expected.push_back("link /fake/path2 /fake/path4");
+
+ const std::vector provisions = zoneProvision.list();
+ BOOST_REQUIRE_EQUAL(provisions.size(), expected.size());
+ auto provision = provisions.cbegin();
+ for (const auto& item : expected) {
+ BOOST_CHECK_EQUAL(item, *(provision++));
+ }
+}
+
+BOOST_AUTO_TEST_CASE(RemoveTest)
+{
+ std::vector expected;
+ ZoneProvision zoneProvision = create({});
+
+ zoneProvision.declareFile(1, "path", 0747, 0777);
+ zoneProvision.declareFile(2, "path", 0747, 0777);
+ expected.push_back("file path 2 " + std::to_string(0747) + " " + std::to_string(0777));
+
+ zoneProvision.declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake1");
+ zoneProvision.declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake2");
+ expected.push_back("mount /fake/path1 /fake/path2 tmpfs " + std::to_string(077) + " fake1");
+
+ zoneProvision.declareLink("/fake/path1", "/fake/path3");
+ zoneProvision.declareLink("/fake/path2", "/fake/path4");
+ expected.push_back("link /fake/path1 /fake/path3");
+
+ zoneProvision.remove("file path 1 " + std::to_string(0747) + " " + std::to_string(0777));
+ zoneProvision.remove("mount /fake/path1 /fake/path2 tmpfs " + std::to_string(077) + " fake2");
+ zoneProvision.remove("link /fake/path2 /fake/path4");
+ BOOST_CHECK_EXCEPTION(zoneProvision.remove("link /fake/path_fake /fake/path2"),
+ UtilsException,
+ expectedMessage("Can't find provision"));
+
+ const std::vector provisions = zoneProvision.list();
+ BOOST_REQUIRE_EQUAL(provisions.size(), expected.size());
+ auto provision = provisions.cbegin();
+ for (const auto& item : expected) {
+ BOOST_CHECK_EQUAL(item, *(provision++));
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
--
2.7.4
From 3680abcc3097cfdccc1245cd7ae5814e56ac236e Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Tue, 27 Jan 2015 16:13:03 +0100
Subject: [PATCH 03/16] Fix focus, defaultId, foregroundId logic
[Bug/Feature] Buggy focus logic. DefaultId, foregroundId does not work
after implementing dynamic zone adding and removing.
[Cause] N/A
[Solution] Update focus after remove, pause and stop zone.
DefaultId moved to dynamic config. ForegroundId removed
from config.
[Verification] Build, run tests, run daemon and check focus after
adding, pausing, removing zones, switching zones.
Change-Id: I325e501242b747802da07b103ccba4c20891138e
---
common/config.hpp | 1 +
server/configs/daemon.conf.in | 1 -
server/host-dbus-definitions.hpp | 2 +-
server/zones-manager-config.hpp | 20 +--
server/zones-manager.cpp | 181 ++++++++++++++-------
server/zones-manager.hpp | 5 +-
.../configs/ut-client/test-dbus-daemon.conf.in | 1 -
tests/unit_tests/server/configs/CMakeLists.txt | 4 -
.../server/configs/ut-server/buggy-daemon.conf.in | 1 -
.../server/configs/ut-server/test-daemon.conf.in | 1 -
.../configs/ut-zones-manager/buggy-daemon.conf.in | 1 -
.../ut-zones-manager/buggy-default-daemon.conf.in | 18 --
.../buggy-foreground-daemon.conf.in | 18 --
.../ut-zones-manager/empty-dbus-daemon.conf.in | 1 -
.../configs/ut-zones-manager/test-daemon.conf.in | 1 -
.../ut-zones-manager/test-dbus-daemon.conf.in | 1 -
tests/unit_tests/server/ut-zones-manager.cpp | 53 +++---
17 files changed, 159 insertions(+), 151 deletions(-)
delete mode 100644 tests/unit_tests/server/configs/ut-zones-manager/buggy-default-daemon.conf.in
delete mode 100644 tests/unit_tests/server/configs/ut-zones-manager/buggy-foreground-daemon.conf.in
diff --git a/common/config.hpp b/common/config.hpp
index 0721de4..753430e 100644
--- a/common/config.hpp
+++ b/common/config.hpp
@@ -55,6 +55,7 @@
#define final
#define override
#define thread_local __thread // use GCC extension instead of C++11
+#define steady_clock monotonic_clock
#endif // GCC_VERSION < 40700
#endif // GCC_VERSION
diff --git a/server/configs/daemon.conf.in b/server/configs/daemon.conf.in
index b7d9c87..ea2d457 100644
--- a/server/configs/daemon.conf.in
+++ b/server/configs/daemon.conf.in
@@ -6,7 +6,6 @@
"zoneTemplatePath" : "/etc/vasum/templates/template.conf",
"zoneNewConfigPrefix" : "/var/lib/vasum",
"runMountPointPrefix" : "/var/run/zones",
- "foregroundId" : "",
"defaultId" : "",
"lxcTemplatePrefix" : "/etc/vasum/lxc-templates",
"inputConfig" : {"enabled" : true,
diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp
index e17261c..ff13843 100644
--- a/server/host-dbus-definitions.hpp
+++ b/server/host-dbus-definitions.hpp
@@ -36,7 +36,7 @@ const std::string BUS_NAME = "org.tizen.vasum.host";
const std::string OBJECT_PATH = "/org/tizen/vasum/host";
const std::string INTERFACE = "org.tizen.vasum.host.manager";
-const std::string ERROR_ZONE_STOPPED = "org.tizen.vasum.host.Error.ZonesStopped";
+const std::string ERROR_ZONE_NOT_RUNNING = "org.tizen.vasum.host.Error.ZonesNotRunning";
const std::string METHOD_GET_ZONE_DBUSES = "GetZoneDbuses";
const std::string METHOD_GET_ZONE_ID_LIST = "GetZoneIds";
diff --git a/server/zones-manager-config.hpp b/server/zones-manager-config.hpp
index ab55762..19da74a 100644
--- a/server/zones-manager-config.hpp
+++ b/server/zones-manager-config.hpp
@@ -44,16 +44,6 @@ struct ZonesManagerConfig {
std::string dbPath;
/**
- * An ID of a currently focused/foreground zone.
- */
- std::string foregroundId;
-
- /**
- * An ID of default zone.
- */
- std::string defaultId;
-
- /**
* A path where the zones mount points reside.
*/
std::string zonesPath;
@@ -97,8 +87,6 @@ struct ZonesManagerConfig {
CONFIG_REGISTER
(
dbPath,
- foregroundId,
- defaultId,
zonesPath,
zoneImagePath,
zoneTemplatePath,
@@ -118,9 +106,15 @@ struct ZonesManagerDynamicConfig {
*/
std::vector zoneConfigs;
+ /**
+ * An ID of default zone.
+ */
+ std::string defaultId;
+
CONFIG_REGISTER
(
- zoneConfigs
+ zoneConfigs,
+ defaultId
)
};
diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp
index 99e87ee..fa6ec80 100644
--- a/server/zones-manager.cpp
+++ b/server/zones-manager.cpp
@@ -156,12 +156,7 @@ ZonesManager::ZonesManager(const std::string& configPath)
createZone(utils::createFilePath(mConfig.zoneNewConfigPrefix, zoneConfig));
}
- // check if default zone exists, throw ZoneOperationException if not found
- if (!mConfig.defaultId.empty() && mZones.find(mConfig.defaultId) == mZones.end()) {
- LOGE("Provided default zone ID " << mConfig.defaultId << " is invalid.");
- throw ZoneOperationException("Provided default zone ID " + mConfig.defaultId +
- " is invalid.");
- }
+ updateDefaultId();
LOGD("ZonesManager object instantiated");
@@ -198,6 +193,29 @@ void ZonesManager::saveDynamicConfig()
config::saveToKVStore(mConfig.dbPath, mDynamicConfig, DB_PREFIX);
}
+void ZonesManager::updateDefaultId()
+{
+ // TODO add an api to change defaultId
+ if (mZones.empty() && mDynamicConfig.defaultId.empty()) {
+ LOGT("Keep empty defaultId");
+ return;
+ }
+ if (mZones.find(mDynamicConfig.defaultId) != mZones.end()) {
+ LOGT("Keep " << mDynamicConfig.defaultId << " as defaultId");
+ return;
+ }
+
+ // update
+ if (mZones.empty()) {
+ mDynamicConfig.defaultId.clear();
+ LOGD("DefaultId cleared");
+ } else {
+ mDynamicConfig.defaultId = mZones.begin()->first;
+ LOGD("DefaultId changed to " << mDynamicConfig.defaultId);
+ }
+ saveDynamicConfig();
+}
+
void ZonesManager::createZone(const std::string& zoneConfigPath)
{
LOGT("Creating Zone " << zoneConfigPath);
@@ -251,7 +269,6 @@ void ZonesManager::destroyZone(const std::string& zoneId)
throw ZoneOperationException("No such zone");
}
- // TODO give back the focus
it->second->setDestroyOnExit();
mZones.erase(it);
@@ -264,14 +281,34 @@ void ZonesManager::destroyZone(const std::string& zoneId)
// update dynamic config
remove(mDynamicConfig.zoneConfigs, getConfigName(zoneId));
saveDynamicConfig();
+ updateDefaultId();
+
+ refocus();
}
void ZonesManager::focus(const std::string& zoneId)
{
Lock lock(mMutex);
+ if (zoneId == mActiveZoneId) {
+ // nothing to do
+ return;
+ }
+
+ if (zoneId.empty()) {
+ LOGI("Focus to: host");
+ // give back the focus to the host
+ // TODO switch to host vt
+ mActiveZoneId.clear();
+ return;
+ }
+
+ LOGI("Focus to: " << zoneId);
+
/* try to access the object first to throw immediately if it doesn't exist */
- ZoneMap::mapped_type& foregroundZone = mZones.at(zoneId);
+ auto& foregroundZone = mZones.at(zoneId);
+
+ assert(foregroundZone->isRunning());
if (!foregroundZone->activateVT()) {
LOGE("Failed to activate zones VT. Aborting focus.");
@@ -279,12 +316,44 @@ void ZonesManager::focus(const std::string& zoneId)
}
for (auto& zone : mZones) {
- LOGD(zone.second->getId() << ": being sent to background");
- zone.second->goBackground();
+ if (zone.first == zoneId) {
+ LOGD(zone.first << ": being sent to foreground");
+ zone.second->goForeground();
+ } else {
+ LOGD(zone.first << ": being sent to background");
+ zone.second->goBackground();
+ }
+ }
+ mActiveZoneId = zoneId;
+}
+
+void ZonesManager::refocus()
+{
+ Lock lock(mMutex);
+
+ // check if refocus is required
+ auto oldIter = mZones.find(mActiveZoneId);
+ if (oldIter != mZones.end() && oldIter->second->isRunning()) {
+ return;
+ }
+
+ // try to refocus to defaultId
+ auto iter = mZones.find(mDynamicConfig.defaultId);
+ if (iter != mZones.end() && iter->second->isRunning()) {
+ // focus to default
+ focus(iter->first);
+ } else {
+ // focus to any running or to host if not found
+ auto zoneIsRunning = [](const ZoneMap::value_type& pair) {
+ return pair.second->isRunning();
+ };
+ auto iter = std::find_if(mZones.begin(), mZones.end(), zoneIsRunning);
+ if (iter == mZones.end()) {
+ focus(std::string());
+ } else {
+ focus(iter->first);
+ }
}
- mConfig.foregroundId = foregroundZone->getId();
- LOGD(mConfig.foregroundId << ": being sent to foreground");
- foregroundZone->goForeground();
}
void ZonesManager::startAll()
@@ -293,30 +362,11 @@ void ZonesManager::startAll()
Lock lock(mMutex);
- bool isForegroundFound = false;
-
for (auto& zone : mZones) {
zone.second->start();
-
- if (zone.first == mConfig.foregroundId) {
- isForegroundFound = true;
- LOGI(zone.second->getId() << ": set as the foreground zone");
- zone.second->goForeground();
- }
}
- if (!isForegroundFound) {
- auto foregroundIterator = std::min_element(mZones.begin(), mZones.end(),
- [](ZoneMap::value_type &c1, ZoneMap::value_type &c2) {
- return c1.second->getPrivilege() < c2.second->getPrivilege();
- });
-
- if (foregroundIterator != mZones.end()) {
- mConfig.foregroundId = foregroundIterator->second->getId();
- LOGI(mConfig.foregroundId << ": no foreground zone configured, setting one with highest priority");
- foregroundIterator->second->goForeground();
- }
- }
+ refocus();
}
void ZonesManager::stopAll()
@@ -328,6 +378,8 @@ void ZonesManager::stopAll()
for (auto& zone : mZones) {
zone.second->stop();
}
+
+ refocus();
}
bool ZonesManager::isPaused(const std::string& zoneId)
@@ -359,13 +411,15 @@ std::string ZonesManager::getRunningForegroundZoneId() const
{
Lock lock(mMutex);
- for (auto& zone : mZones) {
- if (zone.first == mConfig.foregroundId &&
- zone.second->isRunning()) {
- return zone.first;
- }
+ if (!mActiveZoneId.empty() && !mZones.at(mActiveZoneId)->isRunning()) {
+ // Can zone change its state by itself?
+ // Maybe when it is shut down by itself? TODO check it
+ LOGW("Active zone " << mActiveZoneId << " is not running any more!");
+ assert(false);
+ return std::string();
}
- return std::string();
+
+ return mActiveZoneId;
}
std::string ZonesManager::getNextToForegroundZoneId()
@@ -378,22 +432,21 @@ std::string ZonesManager::getNextToForegroundZoneId()
}
for (auto it = mZones.begin(); it != mZones.end(); ++it) {
- if (it->first == mConfig.foregroundId &&
- it->second->isRunning()) {
+ if (it->first == mActiveZoneId && it->second->isRunning()) {
auto nextIt = std::next(it);
if (nextIt != mZones.end()) {
return nextIt->first;
}
}
}
- return mZones.begin()->first;
+ return mZones.begin()->first;//TODO fix - check isRunning
}
void ZonesManager::switchingSequenceMonitorNotify()
{
LOGI("switchingSequenceMonitorNotify() called");
- auto nextZoneId = getNextToForegroundZoneId();
+ std::string nextZoneId = getNextToForegroundZoneId();
if (!nextZoneId.empty()) {
focus(nextZoneId);
@@ -436,13 +489,15 @@ void ZonesManager::displayOffHandler(const std::string& /*caller*/)
// get config of currently set zone and switch if switchToDefaultAfterTimeout is true
Lock lock(mMutex);
- const std::string activeZoneName = getRunningForegroundZoneId();
- const auto& activeZone = mZones.find(activeZoneName);
+ auto activeZone = mZones.find(mActiveZoneId);
if (activeZone != mZones.end() &&
- activeZone->second->isSwitchToDefaultAfterTimeoutAllowed()) {
- LOGI("Switching to default zone " << mConfig.defaultId);
- focus(mConfig.defaultId);
+ activeZone->second->isSwitchToDefaultAfterTimeoutAllowed() &&
+ !mDynamicConfig.defaultId.empty() &&
+ mZones.at(mDynamicConfig.defaultId)->isRunning()) {
+
+ LOGI("Switching to default zone " << mDynamicConfig.defaultId);
+ focus(mDynamicConfig.defaultId);
}
}
@@ -630,11 +685,9 @@ void ZonesManager::handleGetActiveZoneIdCall(dbus::MethodResultBuilder::Pointer
Lock lock(mMutex);
- if (!mConfig.foregroundId.empty() && mZones[mConfig.foregroundId]->isRunning()){
- result->set(g_variant_new("(s)", mConfig.foregroundId.c_str()));
- } else {
- result->set(g_variant_new("(s)", ""));
- }
+ std::string id = getRunningForegroundZoneId();
+
+ result->set(g_variant_new("(s)", id.c_str()));
}
void ZonesManager::handleGetZoneInfoCall(const std::string& id,
@@ -651,7 +704,7 @@ void ZonesManager::handleGetZoneInfoCall(const std::string& id,
}
const auto& zone = mZones[id];
const char* state;
- //TODO: Use the lookup map.
+
if (zone->isRunning()) {
state = "RUNNING";
} else if (zone->isStopped()) {
@@ -752,10 +805,10 @@ void ZonesManager::handleSetActiveZoneCall(const std::string& id,
return;
}
- if (zone->second->isStopped()){
- LOGE("Could not activate a stopped zone");
- result->setError(api::host::ERROR_ZONE_STOPPED,
- "Could not activate a stopped zone");
+ if (!zone->second->isRunning()){
+ LOGE("Could not activate stopped or paused zone");
+ result->setError(api::host::ERROR_ZONE_NOT_RUNNING,
+ "Could not activate stopped or paused zone");
return;
}
@@ -891,6 +944,7 @@ void ZonesManager::handleCreateZoneCall(const std::string& id,
mDynamicConfig.zoneConfigs.push_back(newConfigName);
saveDynamicConfig();
+ updateDefaultId();
result->setVoid();
}
@@ -939,13 +993,19 @@ void ZonesManager::handleShutdownZoneCall(const std::string& id,
auto shutdown = [id, result, this] {
try {
- mZones[id]->stop();
+ ZoneMap::mapped_type zone;
+ {
+ Lock lock(mMutex);
+ zone = mZones.at(id);
+ }
+ zone->stop();
+ refocus();
+ result->setVoid();
} catch (ZoneOperationException& e) {
LOGE("Error during zone shutdown: " << e.what());
result->setError(api::ERROR_INTERNAL, "Failed to shutdown zone");
return;
}
- result->setVoid();
};
mWorker->addTask(shutdown);
@@ -1008,6 +1068,7 @@ void ZonesManager::handleLockZoneCall(const std::string& id,
LOGT("Lock zone");
try {
zone.suspend();
+ refocus();
} catch (ZoneOperationException& e) {
LOGE(e.what());
result->setError(api::ERROR_INTERNAL, e.what());
diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp
index 677b056..72dd952 100644
--- a/server/zones-manager.hpp
+++ b/server/zones-manager.hpp
@@ -117,11 +117,14 @@ private:
// to hold InputMonitor pointer to monitor if zone switching sequence is recognized
std::unique_ptr mSwitchingSequenceMonitor;
std::unique_ptr mProxyCallPolicy;
- typedef std::unordered_map> ZoneMap;
+ typedef std::unordered_map> ZoneMap;//TODO should keep order of insertions
ZoneMap mZones; // map of zones, id is the key
+ std::string mActiveZoneId;
bool mDetachOnExit;
void saveDynamicConfig();
+ void updateDefaultId();
+ void refocus();
void switchingSequenceMonitorNotify();
void generateNewConfig(const std::string& id,
const std::string& templatePath,
diff --git a/tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf.in b/tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf.in
index 544accc..e0af664 100644
--- a/tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf.in
+++ b/tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf.in
@@ -3,7 +3,6 @@
"zoneConfigs" : ["zones/console1-dbus.conf",
"zones/console2-dbus.conf",
"zones/console3-dbus.conf"],
- "foregroundId" : "ut-zones-manager-console1-dbus",
"defaultId" : "ut-zones-manager-console1-dbus",
"zonesPath" : "/tmp/ut-zones",
"zoneImagePath" : "",
diff --git a/tests/unit_tests/server/configs/CMakeLists.txt b/tests/unit_tests/server/configs/CMakeLists.txt
index 596c123..fac9d99 100644
--- a/tests/unit_tests/server/configs/CMakeLists.txt
+++ b/tests/unit_tests/server/configs/CMakeLists.txt
@@ -50,10 +50,6 @@ CONFIGURE_FILE(ut-zones-manager/test-daemon.conf.in
${CMAKE_BINARY_DIR}/ut-zones-manager/test-daemon.conf @ONLY)
CONFIGURE_FILE(ut-zones-manager/buggy-daemon.conf.in
${CMAKE_BINARY_DIR}/ut-zones-manager/buggy-daemon.conf @ONLY)
-CONFIGURE_FILE(ut-zones-manager/buggy-default-daemon.conf.in
- ${CMAKE_BINARY_DIR}/ut-zones-manager/buggy-default-daemon.conf @ONLY)
-CONFIGURE_FILE(ut-zones-manager/buggy-foreground-daemon.conf.in
- ${CMAKE_BINARY_DIR}/ut-zones-manager/buggy-foreground-daemon.conf @ONLY)
CONFIGURE_FILE(ut-zones-manager/test-dbus-daemon.conf.in
${CMAKE_BINARY_DIR}/ut-zones-manager/test-dbus-daemon.conf @ONLY)
CONFIGURE_FILE(ut-zones-manager/empty-dbus-daemon.conf.in
diff --git a/tests/unit_tests/server/configs/ut-server/buggy-daemon.conf.in b/tests/unit_tests/server/configs/ut-server/buggy-daemon.conf.in
index 9df74dc..bf274de 100644
--- a/tests/unit_tests/server/configs/ut-server/buggy-daemon.conf.in
+++ b/tests/unit_tests/server/configs/ut-server/buggy-daemon.conf.in
@@ -6,7 +6,6 @@
"zoneTemplatePath" : "no_need_for_templates_in_this_test",
"zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-server/",
"runMountPointPrefix" : "",
- "foregroundId" : "ut-server-zone1",
"defaultId" : "ut-server-zone1",
"lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
"inputConfig" : {"enabled" : false,
diff --git a/tests/unit_tests/server/configs/ut-server/test-daemon.conf.in b/tests/unit_tests/server/configs/ut-server/test-daemon.conf.in
index 697a468..e1a67e8 100644
--- a/tests/unit_tests/server/configs/ut-server/test-daemon.conf.in
+++ b/tests/unit_tests/server/configs/ut-server/test-daemon.conf.in
@@ -6,7 +6,6 @@
"zoneTemplatePath" : "no_need_for_templates_in_this_test",
"zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-server/",
"runMountPointPrefix" : "",
- "foregroundId" : "ut-server-zone1",
"defaultId" : "ut-server-zone1",
"lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
"inputConfig" : {"enabled" : false,
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/buggy-daemon.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/buggy-daemon.conf.in
index 754594f..d07ab4c 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/buggy-daemon.conf.in
+++ b/tests/unit_tests/server/configs/ut-zones-manager/buggy-daemon.conf.in
@@ -2,7 +2,6 @@
"dbPath" : "/tmp/ut-zones/vasum.db",
"zoneConfigs" : ["zones/console1.conf", "missing/file/path/missing.conf", "zones/console3.conf"],
"runMountPointPrefix" : "",
- "foregroundId" : "ut-zones-manager-console1",
"defaultId" : "ut-zones-manager-console1",
"zonesPath" : "/tmp/ut-zones",
"zoneImagePath" : "",
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/buggy-default-daemon.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/buggy-default-daemon.conf.in
deleted file mode 100644
index 3eb9e02..0000000
--- a/tests/unit_tests/server/configs/ut-zones-manager/buggy-default-daemon.conf.in
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "dbPath" : "/tmp/ut-zones/vasum.db",
- "zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
- "runMountPointPrefix" : "",
- "foregroundId" : "ut-zones-manager-console1",
- "defaultId" : "in_no_way_there_is_a_valid_id_here",
- "zonesPath" : "/tmp/ut-zones",
- "zoneImagePath" : "",
- "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
- "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
- "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
- "inputConfig" : {"enabled" : false,
- "device" : "/dev/doesnotexist",
- "code" : 139,
- "numberOfEvents" : 2,
- "timeWindowMs" : 500},
- "proxyCallRules" : []
-}
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/buggy-foreground-daemon.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/buggy-foreground-daemon.conf.in
deleted file mode 100644
index 6e02372..0000000
--- a/tests/unit_tests/server/configs/ut-zones-manager/buggy-foreground-daemon.conf.in
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "dbPath" : "/tmp/ut-zones/vasum.db",
- "zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
- "runMountPointPrefix" : "",
- "foregroundId" : "this_id_does_not_exist",
- "defaultId" : "ut-zones-manager-console1",
- "zonesPath" : "/tmp/ut-zones",
- "zoneImagePath" : "",
- "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
- "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
- "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
- "inputConfig" : {"enabled" : false,
- "device" : "/dev/doesnotexist",
- "code" : 139,
- "numberOfEvents" : 2,
- "timeWindowMs" : 500},
- "proxyCallRules" : []
-}
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/empty-dbus-daemon.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/empty-dbus-daemon.conf.in
index a80be26..943ade9 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/empty-dbus-daemon.conf.in
+++ b/tests/unit_tests/server/configs/ut-zones-manager/empty-dbus-daemon.conf.in
@@ -1,7 +1,6 @@
{
"dbPath" : "/tmp/ut-zones/vasum.db",
"zoneConfigs" : [],
- "foregroundId" : "",
"defaultId" : "",
"zonesPath" : "/tmp/ut-zones",
"zoneImagePath" : "",
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/test-daemon.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/test-daemon.conf.in
index 14cea0b..f3cddde 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/test-daemon.conf.in
+++ b/tests/unit_tests/server/configs/ut-zones-manager/test-daemon.conf.in
@@ -2,7 +2,6 @@
"dbPath" : "/tmp/ut-zones/vasum.db",
"zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
"runMountPointPrefix" : "",
- "foregroundId" : "ut-zones-manager-console1",
"defaultId" : "ut-zones-manager-console1",
"zonesPath" : "/tmp/ut-zones",
"zoneImagePath" : "",
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/test-dbus-daemon.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/test-dbus-daemon.conf.in
index 2a55718..fc47ff9 100644
--- a/tests/unit_tests/server/configs/ut-zones-manager/test-dbus-daemon.conf.in
+++ b/tests/unit_tests/server/configs/ut-zones-manager/test-dbus-daemon.conf.in
@@ -3,7 +3,6 @@
"zoneConfigs" : ["zones/console1-dbus.conf",
"zones/console2-dbus.conf",
"zones/console3-dbus.conf"],
- "foregroundId" : "ut-zones-manager-console1-dbus",
"defaultId" : "ut-zones-manager-console1-dbus",
"zonesPath" : "/tmp/ut-zones",
"zoneImagePath" : "",
diff --git a/tests/unit_tests/server/ut-zones-manager.cpp b/tests/unit_tests/server/ut-zones-manager.cpp
index 5925052..3929c77 100644
--- a/tests/unit_tests/server/ut-zones-manager.cpp
+++ b/tests/unit_tests/server/ut-zones-manager.cpp
@@ -65,11 +65,10 @@ const std::string TEST_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zon
const std::string TEST_DBUS_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/test-dbus-daemon.conf";
const std::string EMPTY_DBUS_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/empty-dbus-daemon.conf";
const std::string BUGGY_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/buggy-daemon.conf";
-const std::string BUGGY_FOREGROUND_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/buggy-foreground-daemon.conf";
-const std::string BUGGY_DEFAULTID_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/buggy-default-daemon.conf";
const std::string TEST_ZONE_CONF_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/zones/";
const std::string MISSING_CONFIG_PATH = "/this/is/a/missing/file/path/missing-daemon.conf";
const int EVENT_TIMEOUT = 5000;
+const int UNEXPECTED_EVENT_TIMEOUT = EVENT_TIMEOUT / 5;
const int TEST_DBUS_CONNECTION_ZONES_COUNT = 3;
const std::string PREFIX_CONSOLE_NAME = "ut-zones-manager-console";
const std::string TEST_APP_NAME = "testapp";
@@ -438,7 +437,8 @@ private:
std::mutex mMutex;
std::condition_variable mNameCondition;
- bool isHost() const {
+ bool isHost() const
+ {
return mId == HOST_ID;
}
@@ -452,12 +452,26 @@ private:
}
};
-std::function expectedMessage(const std::string& message) {
+std::function expectedMessage(const std::string& message)
+{
return [=](const std::exception& e) {
return e.what() == message;
};
}
+template
+bool spinWaitFor(int timeoutMs, Predicate pred)
+{
+ auto until = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeoutMs);
+ while (!pred()) {
+ if (std::chrono::steady_clock::now() >= until) {
+ return false;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
+ return true;
+}
+
struct Fixture {
vasum::utils::ScopedGlibLoop mLoop;
@@ -499,19 +513,6 @@ BOOST_AUTO_TEST_CASE(StartAllTest)
BOOST_CHECK(cm.getRunningForegroundZoneId() == "ut-zones-manager-console1");
}
-BOOST_AUTO_TEST_CASE(BuggyForegroundTest)
-{
- ZonesManager cm(BUGGY_FOREGROUND_CONFIG_PATH);
- cm.startAll();
- BOOST_CHECK(cm.getRunningForegroundZoneId() == "ut-zones-manager-console2");
-}
-
-BOOST_AUTO_TEST_CASE(BuggyDefaultTest)
-{
- BOOST_REQUIRE_THROW(ZonesManager cm(BUGGY_DEFAULTID_CONFIG_PATH),
- ZoneOperationException);
-}
-
BOOST_AUTO_TEST_CASE(StopAllTest)
{
ZonesManager cm(TEST_CONFIG_PATH);
@@ -626,9 +627,6 @@ BOOST_AUTO_TEST_CASE(DisplayOffTest)
client->setName(fake_power_manager_api::BUS_NAME);
}
- std::mutex Mutex;
- std::unique_lock Lock(Mutex);
- std::condition_variable Condition;
auto cond = [&cm]() -> bool {
return cm.getRunningForegroundZoneId() == "ut-zones-manager-console1-dbus";
};
@@ -645,7 +643,7 @@ BOOST_AUTO_TEST_CASE(DisplayOffTest)
nullptr);
// check if default zone has focus
- BOOST_CHECK(Condition.wait_for(Lock, std::chrono::milliseconds(EVENT_TIMEOUT), cond));
+ BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, cond));
}
}
@@ -761,9 +759,6 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefaultTest)
client->setName(fake_power_manager_api::BUS_NAME);
}
- std::mutex condMutex;
- std::unique_lock condLock(condMutex);
- std::condition_variable condition;
auto cond = [&cm]() -> bool {
return cm.getRunningForegroundZoneId() == "ut-zones-manager-console1-dbus";
};
@@ -779,7 +774,7 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefaultTest)
nullptr);
// check if default zone has focus
- BOOST_CHECK(condition.wait_for(condLock, std::chrono::milliseconds(EVENT_TIMEOUT), cond));
+ BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, cond));
// focus non-default zone with disabled switching
cm.focus("ut-zones-manager-console2-dbus");
@@ -791,7 +786,7 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefaultTest)
nullptr);
// now default zone should not be focused
- BOOST_CHECK(!condition.wait_for(condLock, std::chrono::milliseconds(EVENT_TIMEOUT), cond));
+ BOOST_CHECK(!spinWaitFor(UNEXPECTED_EVENT_TIMEOUT, cond));
}
}
@@ -1048,6 +1043,8 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest)
cm.startAll();
+ BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1);
+ cm.focus(zone3);
BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone3);
// destroy zone2
@@ -1058,7 +1055,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest)
// destroy zone3
dbus.callAsyncMethodDestroyZone(zone3, resultCallback);
BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
- //BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1);//TODO fix it
+ BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1);
// destroy zone1
dbus.callAsyncMethodDestroyZone(zone1, resultCallback);
@@ -1159,7 +1156,7 @@ BOOST_AUTO_TEST_CASE(LockUnlockZoneTest)
"ut-zones-manager-console2-dbus",
"ut-zones-manager-console3-dbus"};
- for (std::string& zoneId: zoneIds){
+ for (const std::string& zoneId: zoneIds){
dbus.callMethodLockZone(zoneId);
BOOST_CHECK(cm.isPaused(zoneId));
dbus.callMethodUnlockZone(zoneId);
--
2.7.4
From 5c9f567e6fc2b39e65f8dc616b4dae3fba117f1c Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Wed, 28 Jan 2015 13:31:50 +0100
Subject: [PATCH 04/16] Compile test of client C API
[Bug/Feature] N/A
[Cause] N/A
[Solution] N/A
[Verification] Build
Change-Id: I4c8d33904f9f23db70e8ffc0e6002bf2e3335ee8
---
client/vasum-client.h | 17 ++++++-----
tests/unit_tests/CMakeLists.txt | 3 ++
.../unit_tests/client/client-c-api-compile-test.c | 34 ++++++++++++++++++++++
3 files changed, 46 insertions(+), 8 deletions(-)
create mode 100644 tests/unit_tests/client/client-c-api-compile-test.c
diff --git a/client/vasum-client.h b/client/vasum-client.h
index eba04e6..bf15f25 100644
--- a/client/vasum-client.h
+++ b/client/vasum-client.h
@@ -80,6 +80,7 @@ finish:
#include
#include
+#include
#ifdef __cplusplus
extern "C"
@@ -109,12 +110,12 @@ typedef VsmString* VsmArrayString;
* Completion status of communication function.
*/
typedef enum {
- VSMCLIENT_CUSTOM_ERROR, ///< User specified error
- VSMCLIENT_IO_ERROR, ///< Input/Output error
- VSMCLIENT_OPERATION_FAILED, ///< Operation failed
- VSMCLIENT_INVALID_ARGUMENT, ///< Invalid argument
- VSMCLIENT_OTHER_ERROR, ///< Other error
- VSMCLIENT_SUCCESS ///< Success
+ VSMCLIENT_CUSTOM_ERROR, /**< User specified error */
+ VSMCLIENT_IO_ERROR, /**< Input/Output error */
+ VSMCLIENT_OPERATION_FAILED, /**< Operation failed */
+ VSMCLIENT_INVALID_ARGUMENT, /**< Invalid argument */
+ VSMCLIENT_OTHER_ERROR, /**< Other error */
+ VSMCLIENT_SUCCESS /**< Success */
} VsmStatus;
/**
@@ -653,7 +654,7 @@ VsmStatus vsm_declare_link(VsmClient client,
const char *target);
-/** @} */ // Host API
+/** @} Host API */
/**
@@ -722,7 +723,7 @@ VsmStatus vsm_add_notification_callback(VsmClient client,
*/
VsmStatus vsm_del_notification_callback(VsmClient client, VsmSubscriptionId subscriptionId);
-/** @} */ // Zone API
+/** @} Zone API */
#ifdef __cplusplus
}
diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt
index 8b66b09..96ab943 100644
--- a/tests/unit_tests/CMakeLists.txt
+++ b/tests/unit_tests/CMakeLists.txt
@@ -32,6 +32,9 @@ LIST(REMOVE_ITEM server_SRCS ${main_SRC})
SET(UT_SERVER_CODENAME "${PROJECT_NAME}-server-unit-tests")
ADD_EXECUTABLE(${UT_SERVER_CODENAME} ${project_SRCS} ${common_SRCS} ${server_SRCS} ${client_SRCS})
+## A fake target to test vasum-client C API
+ADD_EXECUTABLE("vasum-client-c-api-compile-test" client/client-c-api-compile-test.c)
+
## Link libraries ##############################################################
FIND_PACKAGE (Boost COMPONENTS unit_test_framework system filesystem regex)
diff --git a/tests/unit_tests/client/client-c-api-compile-test.c b/tests/unit_tests/client/client-c-api-compile-test.c
new file mode 100644
index 0000000..168b8cd
--- /dev/null
+++ b/tests/unit_tests/client/client-c-api-compile-test.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015 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 Compilation test of Vasum Client C API
+ *
+ * This API header is already included in vasum-client.cpp,
+ * although this test is required to:
+ * - detect missing includes
+ * - check if it is a pure C API (extern "C" does not guarantee it)
+ */
+
+#include "vasum-client.h"
+
+int main() {
+ return 0;
+}
--
2.7.4
From 8fe7189dc8d8789e7abd8f80fec3b0fe34a4c069 Mon Sep 17 00:00:00 2001
From: Jan Olszak
Date: Mon, 26 Jan 2015 14:33:01 +0100
Subject: [PATCH 05/16] IPC: Remote error handling
[Bug/Feature] Passing errors to callbacks
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run tests, run tests under valgrind
Change-Id: Icbe4df6671144fd34a3bf8b43c4360c2242a6d3e
---
common/ipc/client.hpp | 1 +
common/ipc/exception.hpp | 48 +++++++++--
common/ipc/internals/method-request.hpp | 12 +--
common/ipc/internals/processor.cpp | 115 ++++++++++++++++++---------
common/ipc/internals/processor.hpp | 136 +++++++++++++++++++++-----------
common/ipc/internals/request-queue.hpp | 28 +++++--
common/ipc/internals/result-builder.hpp | 78 ++++++++++++++++++
common/ipc/result.hpp | 74 +++++++++++++++++
common/ipc/service.hpp | 1 +
common/ipc/types.cpp | 33 --------
common/ipc/types.hpp | 20 -----
tests/unit_tests/ipc/ut-ipc.cpp | 49 +++++++++---
12 files changed, 428 insertions(+), 167 deletions(-)
create mode 100644 common/ipc/internals/result-builder.hpp
create mode 100644 common/ipc/result.hpp
diff --git a/common/ipc/client.hpp b/common/ipc/client.hpp
index eedf81b..1ee44bb 100644
--- a/common/ipc/client.hpp
+++ b/common/ipc/client.hpp
@@ -28,6 +28,7 @@
#include "ipc/internals/processor.hpp"
#include "ipc/ipc-gsource.hpp"
#include "ipc/types.hpp"
+#include "ipc/result.hpp"
#include "logger/logger.hpp"
#include
diff --git a/common/ipc/exception.hpp b/common/ipc/exception.hpp
index 794cf21..8e9a7df 100644
--- a/common/ipc/exception.hpp
+++ b/common/ipc/exception.hpp
@@ -29,35 +29,67 @@
#include "base-exception.hpp"
namespace vasum {
-
+namespace ipc {
/**
* Base class for exceptions in IPC
*/
struct IPCException: public VasumException {
- IPCException(const std::string& error) : VasumException(error) {}
+ IPCException(const std::string& message)
+ : VasumException(message) {}
};
struct IPCParsingException: public IPCException {
- IPCParsingException(const std::string& error) : IPCException(error) {}
+ IPCParsingException(const std::string& message = "Exception during reading/parsing data from the socket")
+ : IPCException(message) {}
};
struct IPCSerializationException: public IPCException {
- IPCSerializationException(const std::string& error) : IPCException(error) {}
+ IPCSerializationException(const std::string& message = "Exception during writing/serializing data to the socket")
+ : IPCException(message) {}
};
struct IPCPeerDisconnectedException: public IPCException {
- IPCPeerDisconnectedException(const std::string& error) : IPCException(error) {}
+ IPCPeerDisconnectedException(const std::string& message = "No such peer. Might got disconnected.")
+ : IPCException(message) {}
};
struct IPCNaughtyPeerException: public IPCException {
- IPCNaughtyPeerException(const std::string& error) : IPCException(error) {}
+ IPCNaughtyPeerException(const std::string& message = "Peer performed a forbidden action.")
+ : IPCException(message) {}
+};
+
+struct IPCRemovedPeerException: public IPCException {
+ IPCRemovedPeerException(const std::string& message = "Removing peer")
+ : IPCException(message) {}
+};
+
+struct IPCClosingException: public IPCException {
+ IPCClosingException(const std::string& message = "Closing IPC")
+ : IPCException(message) {}
};
struct IPCTimeoutException: public IPCException {
- IPCTimeoutException(const std::string& error) : IPCException(error) {}
+ IPCTimeoutException(const std::string& message)
+ : IPCException(message) {}
+};
+
+struct IPCUserException: public IPCException {
+ IPCUserException(const int code, const std::string& message)
+ : IPCException(message),
+ mCode(code)
+ {}
+
+ int getCode() const
+ {
+ return mCode;
+ }
+
+private:
+ int mCode;
};
-}
+} // namespace ipc
+} // namespace vasum
#endif // COMMON_IPC_EXCEPTION_HPP
diff --git a/common/ipc/internals/method-request.hpp b/common/ipc/internals/method-request.hpp
index 36d3d7a..8ed17c5 100644
--- a/common/ipc/internals/method-request.hpp
+++ b/common/ipc/internals/method-request.hpp
@@ -25,9 +25,12 @@
#ifndef COMMON_IPC_INTERNALS_METHOD_REQUEST_HPP
#define COMMON_IPC_INTERNALS_METHOD_REQUEST_HPP
+#include "ipc/internals/result-builder.hpp"
#include "ipc/types.hpp"
+#include "ipc/result.hpp"
#include "logger/logger-scope.hpp"
#include "config/manager.hpp"
+#include
namespace vasum {
namespace ipc {
@@ -49,7 +52,7 @@ public:
std::shared_ptr data;
SerializeCallback serialize;
ParseCallback parse;
- ResultHandler::type process;
+ ResultBuilderHandler process;
private:
MethodRequest(const MethodID methodID, const FileDescriptor peerFD)
@@ -82,10 +85,9 @@ std::shared_ptr MethodRequest::create(const MethodID methodID,
return data;
};
- request->process = [process](Status status, std::shared_ptr& data)->void {
- LOGS("Method process, status: " << toString(status));
- std::shared_ptr tmpData = std::static_pointer_cast(data);
- return process(status, tmpData);
+ request->process = [process](ResultBuilder & resultBuilder) {
+ LOGS("Method process");
+ process(resultBuilder.build());
};
return request;
diff --git a/common/ipc/internals/processor.cpp b/common/ipc/internals/processor.cpp
index bdc8a8d..58beca8 100644
--- a/common/ipc/internals/processor.cpp
+++ b/common/ipc/internals/processor.cpp
@@ -51,6 +51,7 @@ namespace ipc {
const MethodID Processor::RETURN_METHOD_ID = std::numeric_limits::max();
const MethodID Processor::REGISTER_SIGNAL_METHOD_ID = std::numeric_limits::max() - 1;
+const MethodID Processor::ERROR_METHOD_ID = std::numeric_limits::max() - 2;
Processor::Processor(const std::string& logName,
const PeerCallback& newPeerCallback,
@@ -66,8 +67,10 @@ Processor::Processor(const std::string& logName,
utils::signalBlock(SIGPIPE);
using namespace std::placeholders;
- setMethodHandlerInternal(REGISTER_SIGNAL_METHOD_ID,
- std::bind(&Processor::onNewSignals, this, _1, _2));
+ setSignalHandlerInternal(REGISTER_SIGNAL_METHOD_ID,
+ std::bind(&Processor::onNewSignals, this, _1, _2));
+
+ setSignalHandlerInternal(ERROR_METHOD_ID, std::bind(&Processor::onErrorSignal, this, _1, _2));
}
Processor::~Processor()
@@ -110,7 +113,7 @@ void Processor::stop()
{
Lock lock(mStateMutex);
auto request = std::make_shared(conditionPtr);
- mRequestQueue.push(Event::FINISH, request);
+ mRequestQueue.pushBack(Event::FINISH, request);
}
LOGD(mLogPrefix + "Waiting for the Processor to stop");
@@ -158,7 +161,7 @@ FileDescriptor Processor::addPeer(const std::shared_ptr& socketPtr)
FileDescriptor peerFD = socketPtr->getFD();
auto request = std::make_shared