[asterisk-scf-commits] asterisk-scf/integration/bridging.git branch "bridge-replication" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Wed Mar 2 07:51:46 CST 2011
branch "bridge-replication" has been updated
via 648a2edcda7992f8e4e7e72eb5c9f8ce4d0f4d20 (commit)
via 86832b8c359690a79b152dc657aea9c969379f44 (commit)
via a2b836e84227da376985070f22f8a6cc31ec459f (commit)
from 3a967cb0590297d35cf9fa290512d32bf2423799 (commit)
Summary of changes:
src/BridgeImpl.cpp | 42 +++---
src/ListenerManager.h | 7 +-
src/ServiceUtil.h | 3 +
src/SessionCollection.cpp | 33 +++--
src/SessionCollection.h | 19 ++-
src/SessionOperations.h | 8 +-
src/SessionWrapper.cpp | 3 -
test/CMakeLists.txt | 56 ++++---
test/TestBridging.cpp | 8 +
test/UnitTests.cpp | 390 +++++++++++++++++++++++++++++++++++++++++++++
10 files changed, 512 insertions(+), 57 deletions(-)
create mode 100644 test/UnitTests.cpp
- Log -----------------------------------------------------------------
commit 648a2edcda7992f8e4e7e72eb5c9f8ce4d0f4d20
Author: Brent Eagles <beagles at digium.com>
Date: Wed Mar 2 10:18:23 2011 -0330
- Added some additional comments.
- Added more unit tests.
- Fixed what would end up being a consistency bug in replaceSession.
- Fixed another unique/shared lock bug.
- Removed all "automagic" reaping from SessionCollection. It's entirely manual now.
- SessionCollection::getSessionSeq() now "eat's its own dogfood" and uses
visitSessions() with a SelectOperation + IfInOperation to select only those
sessions that are in an "active" state (i.e. not disconnected or marked as
"Done" for other reasons).
diff --git a/src/BridgeImpl.cpp b/src/BridgeImpl.cpp
index 7267165..61df06c 100644
--- a/src/BridgeImpl.cpp
+++ b/src/BridgeImpl.cpp
@@ -440,26 +440,31 @@ void BridgeImpl::replaceSession(const SessionPrx& oldSession, const SessionSeq&
statePreCheck();
SessionWrapperPtr session = mSessions->getSession(oldSession);
- if (session)
+ //
+ // If the session did not exist on this bridge, then this operation should not proceed.
+ //
+ if (!session)
{
- try
- {
- //
- // TODO: AMI.
- //
- oldSession->removeBridge(mSessionListenerPrx);
- }
- catch (const Ice::Exception& ex)
- {
- mLogger(Info) << ": removingthe bridge from " << oldSession << " threw "
- << ex.what();
- }
- session->disconnect();
- SessionSeq removed;
- removed.push_back(oldSession);
- mListeners->sessionsRemoved(removed);
- update();
+ throw SessionNotFound(oldSession);
+ }
+
+ try
+ {
+ //
+ // TODO: AMI.
+ //
+ oldSession->removeBridge(mSessionListenerPrx);
}
+ catch (const Ice::Exception& ex)
+ {
+ mLogger(Info) << ": removingthe bridge from " << oldSession << " threw "
+ << ex.what();
+ }
+ session->disconnect();
+ SessionSeq removed;
+ removed.push_back(oldSession);
+ mListeners->sessionsRemoved(removed);
+ update();
SessionSeq added;
for (SessionSeq::const_iterator i = newSessions.begin(); i != newSessions.end(); ++i)
@@ -590,7 +595,6 @@ void BridgeImpl::activate()
mActivated = true;
}
-
namespace
{
class ShutdownThread : public IceUtil::Thread
diff --git a/src/SessionCollection.cpp b/src/SessionCollection.cpp
index cf26a6d..4dac11f 100644
--- a/src/SessionCollection.cpp
+++ b/src/SessionCollection.cpp
@@ -15,6 +15,8 @@
*/
#include "SessionCollection.h"
+#include "SessionOperations.h"
+#include <set>
using namespace AsteriskSCF::System::Logging;
using namespace AsteriskSCF::SessionCommunications::V1;
@@ -23,7 +25,16 @@ using namespace AsteriskSCF::Bridge::V1;
using namespace AsteriskSCF;
using namespace std;
-SessionCollection::SessionCollection(const Ice::CommunicatorPtr& comm, const string& bridgeId, const ReplicatorSmartPrx& replicator,
+/**
+ *
+ * NOTE: The lack of reaping throughout is deliberate. Sessions that are in a terminal state are of some interest to the
+ * service internals. Reaping is consequently a manual process. The visitSessions method + various SessionOperations can
+ * be used to perform state-dependent queries.
+ *
+ **/
+
+SessionCollection::SessionCollection(const Ice::CommunicatorPtr& comm, const string& bridgeId,
+ const ReplicatorSmartPrx& replicator,
const Logger& logger) :
mCommunicator(comm),
mReplicator(replicator),
@@ -104,14 +115,17 @@ bool SessionCollection::hasSession(const SessionPrx& prx)
SessionSeq SessionCollection::getSessionSeq()
{
- SessionSeq result;
- boost::shared_lock<boost::shared_mutex> lock(mLock);
- reap();
- for (SessionMap::const_iterator i = mMap.begin(); i != mMap.end(); ++i)
- {
- result.push_back(i->second->getSession());
- }
- return result;
+ //
+ // TODO: Look at creating some private preinitialized criteria sets so we don't have to initialize this each time.
+ //
+ set<BridgedSessionState> states;
+ states.insert(BridgedSessionState::Added);
+ states.insert(BridgedSessionState::Connected);
+
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> active(states);
+ SelectOperation< IfInCriteria<set<BridgedSessionState>, StateMemberSelector>, SessionPrxSelector, SessionSeq>
+ selectIf(active);
+ return visitSessions(selectIf).results();
}
size_t SessionCollection::size()
@@ -122,7 +136,6 @@ size_t SessionCollection::size()
void SessionCollection::reap()
{
- boost::unique_lock<boost::shared_mutex> lock(mLock);
for (SessionMap::iterator i = mMap.begin(); i != mMap.end();)
{
if (i->second->isDestroyed())
diff --git a/src/SessionCollection.h b/src/SessionCollection.h
index 6090a8f..ea3aed0 100644
--- a/src/SessionCollection.h
+++ b/src/SessionCollection.h
@@ -83,22 +83,37 @@ public:
bool hasSession(const AsteriskSCF::SessionCommunications::V1::SessionPrx& session);
/**
- * Return a Bridge service compatible sequence of sessions.
+ * Return a Bridge service compatible sequence of sessions. This session sequence does not
+ * include sessions in the collection that are disconnected or awaiting reaping.
**/
AsteriskSCF::SessionCommunications::V1::SessionSeq getSessionSeq();
+ /**
+ *
+ * Applies the specified operation over the map of sessions.
+ *
+ **/
template <typename Func>
- void visitSessions(Func& op)
+ Func& visitSessions(Func& op)
{
boost::shared_lock<boost::shared_mutex> lock(mLock);
for (SessionMap::iterator i = mMap.begin(); i != mMap.end(); ++i)
{
op(i->second);
}
+ return op;
}
+ /**
+ * Return the total number of entries in the collection. Warning: may include sessions that are essentially "done
+ * with". If its desirable to exclude disconnected or "done" sessions, either call reap() beforehand or use the
+ * visitSessions method with a CountIfOperation with an IfInCriteria initialized with the proper values.
+ **/
size_t size();
+ /**
+ * Release session wrappers for sessions that have reached a terminal state.
+ **/
void reap();
void replicaUpdate(const AsteriskSCF::Bridge::V1::BridgedSessionPtr& bridgedSession);
diff --git a/test/UnitTests.cpp b/test/UnitTests.cpp
index 41eec40..c57517f 100644
--- a/test/UnitTests.cpp
+++ b/test/UnitTests.cpp
@@ -22,11 +22,13 @@
#include <AsteriskSCF/Media/MediaIf.h>
#include <AsteriskSCF/logger.h>
#include <Ice/Ice.h>
+#include <IceUtil/UUID.h>
#include <set>
#include <vector>
#include <algorithm>
#include "SessionOperations.h"
+#include "SessionCollection.h"
using namespace AsteriskSCF::System::Logging;
using namespace AsteriskSCF::SessionCommunications::V1;
@@ -34,6 +36,43 @@ using namespace AsteriskSCF::Bridge::V1;
using namespace AsteriskSCF::BridgeService;
using namespace std;
+class IceEnvironment
+{
+public:
+ IceEnvironment()
+ {
+ //
+ // NOTE: for the moment, the communicator is really a placeholder so doesn't require configuration.
+ //
+ Ice::StringSeq noArgs;
+ mCommunicator = Ice::initialize(noArgs);
+ }
+
+ Ice::CommunicatorPtr communicator()
+ {
+ return mCommunicator;
+ }
+
+ ~IceEnvironment()
+ {
+ try
+ {
+ mCommunicator->destroy();
+ }
+ catch (...)
+ {
+ std::cerr << "exception on destroy!" << std::endl;
+ }
+ }
+
+ Ice::Identity strToIdent(const std::string& s)
+ {
+ return mCommunicator->stringToIdentity(s);
+ }
+
+private:
+ Ice::CommunicatorPtr mCommunicator;
+};
class BridgeIdSelector
{
@@ -62,6 +101,7 @@ static BridgedSessionPtr createBridgedSession(const BridgedSessionState initialS
{
BridgedSessionPtr result(new BridgedSession);
result->currentState = initialState;
+ result->key = IceUtil::generateUUID();
return result;
}
@@ -72,6 +112,13 @@ static BridgedSessionPtr createBridgedSession(const BridgedSessionState initialS
return result;
}
+static BridgedSessionPtr createBridgedSession(const BridgedSessionState initialState, const SessionPrx& proxy)
+{
+ BridgedSessionPtr result(createBridgedSession(initialState));
+ result->session = proxy;
+ return result;
+}
+
BOOST_AUTO_TEST_SUITE(BridgeUnitTests)
class Fixture
@@ -300,5 +347,44 @@ BOOST_FIXTURE_TEST_CASE(testSelect, Fixture)
BOOST_CHECK(results[index++] == "b");
}
+BOOST_FIXTURE_TEST_CASE(testGetSeq, Fixture)
+{
+ IceEnvironment iceEnv;
+ AsteriskSCF::BridgeService::ReplicatorSmartPrx rep;
+ SessionCollectionPtr collection(new SessionCollection(iceEnv.communicator(), "test", rep, getLogger()));
+
+ SessionPrx dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo0:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Added, dummy));
+
+ dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo1:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Added, dummy));
+
+ dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo2:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Disconnected, dummy));
+
+ dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo3:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Connected, dummy));
+
+ dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo4:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Done, dummy));
+
+ dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo5:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Added, dummy));
+
+ dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo6:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Disconnected, dummy));
+
+ dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo7:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Done, dummy));
+
+ dummy = SessionPrx::uncheckedCast(iceEnv.communicator()->stringToProxy("foo8:default"));
+ collection->replicaUpdate(createBridgedSession(BridgedSessionState::Connected, dummy));
+
+ //
+ // getSessionSeq() should only return the sessions that are *not* disconnected or destroyed.
+ //
+ SessionSeq activeSessions(collection->getSessionSeq());
+ BOOST_CHECK(activeSessions.size() == 5);
+}
BOOST_AUTO_TEST_SUITE_END()
commit 86832b8c359690a79b152dc657aea9c969379f44
Author: Brent Eagles <beagles at digium.com>
Date: Tue Mar 1 18:47:02 2011 -0330
Added test for "Select" operations.
diff --git a/test/UnitTests.cpp b/test/UnitTests.cpp
index e4eea61..41eec40 100644
--- a/test/UnitTests.cpp
+++ b/test/UnitTests.cpp
@@ -34,6 +34,24 @@ using namespace AsteriskSCF::Bridge::V1;
using namespace AsteriskSCF::BridgeService;
using namespace std;
+
+class BridgeIdSelector
+{
+public:
+ BridgeIdSelector(const SessionWrapperPtr& wrapper) :
+ mWrapper(wrapper)
+ {
+ }
+
+ string select()
+ {
+ return mWrapper->getBridgedSession()->bridgeId;
+ }
+
+private:
+ SessionWrapperPtr mWrapper;
+};
+
/**
*
* These tests are "actual" unit tests for verifying that small bits of code within the
@@ -47,6 +65,13 @@ static BridgedSessionPtr createBridgedSession(const BridgedSessionState initialS
return result;
}
+static BridgedSessionPtr createBridgedSession(const BridgedSessionState initialState, const std::string& bridgeKey)
+{
+ BridgedSessionPtr result(createBridgedSession(initialState));
+ result->bridgeId = bridgeKey;
+ return result;
+}
+
BOOST_AUTO_TEST_SUITE(BridgeUnitTests)
class Fixture
@@ -171,4 +196,109 @@ BOOST_FIXTURE_TEST_CASE(testCountIf, Fixture)
BOOST_CHECK((testData.size() -4) == countNegNo.count());
}
+BOOST_FIXTURE_TEST_CASE(testSelect, Fixture)
+{
+ //
+ // Setup some test data.
+ //
+ AsteriskSCF::BridgeService::ReplicatorSmartPrx rep;
+ vector<SessionWrapperPtr> testData;
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Added, "a"), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Added, "b"), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Disconnected, "a"),
+ rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Connected, "c"), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Done, "a"), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Added, "b"), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Disconnected, "c"), rep,
+ getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Done, "a"), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Connected, "b"), rep, getLogger()));
+
+ //
+ // Now a variety of test criteria.
+ //
+ IfStateCriteria a(BridgedSessionState::Added);
+ SelectOperation<IfStateCriteria, BridgeIdSelector, vector<string> > selectIf(a);
+ selectIf = for_each(testData.begin(), testData.end(), selectIf);
+ vector<string> results = selectIf.results();
+ BOOST_CHECK(results.size() == 3);
+ int index = 0;
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "b");
+ BOOST_CHECK(results[index++] == "b");
+
+ Negate<IfStateCriteria> notA(a);
+ SelectOperation<Negate<IfStateCriteria>, BridgeIdSelector, vector<string> > selectNotIf(notA);
+ selectNotIf = for_each(testData.begin(), testData.end(), selectNotIf);
+ results = selectNotIf.results();
+ BOOST_CHECK((testData.size() -3) == results.size());
+ index = 0;
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "c");
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "c");
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "b");
+
+ set<BridgedSessionState> yesVals;
+ yesVals.insert(BridgedSessionState::Added);
+ yesVals.insert(BridgedSessionState::Connected);
+ set<BridgedSessionState> noVals;
+ noVals.insert(BridgedSessionState::Disconnected);
+ noVals.insert(BridgedSessionState::Done);
+
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> yes(yesVals);
+ SelectOperation<IfInCriteria<set<BridgedSessionState>, StateMemberSelector>, BridgeIdSelector,
+ vector<string> > selectYes(yes);
+ selectYes = for_each(testData.begin(), testData.end(), selectYes);
+ results = selectYes.results();
+ BOOST_CHECK(results.size() == 5);
+ index = 0;
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "b");
+ BOOST_CHECK(results[index++] == "c");
+ BOOST_CHECK(results[index++] == "b");
+ BOOST_CHECK(results[index++] == "b");
+
+
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> no(noVals);
+ SelectOperation<IfInCriteria<set<BridgedSessionState>, StateMemberSelector>, BridgeIdSelector,
+ vector<string> > selectNo(no);
+ selectNo = for_each(testData.begin(), testData.end(), selectNo);
+ results = selectNo.results();
+ BOOST_CHECK(results.size() == 4);
+ index = 0;
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "c");
+ BOOST_CHECK(results[index++] == "a");
+
+ Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > negYes(yes);
+ SelectOperation<Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> >,
+ BridgeIdSelector, vector<string> > selectNegYes(negYes);
+ selectNegYes = for_each(testData.begin(), testData.end(), selectNegYes);
+ results = selectNegYes.results();
+ BOOST_CHECK((testData.size() -5) == results.size());
+ index = 0;
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "c");
+ BOOST_CHECK(results[index++] == "a");
+
+ Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > negNo(no);
+ SelectOperation<Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > ,
+ BridgeIdSelector, vector<string> > selectNegNo(negNo);
+ selectNegNo = for_each(testData.begin(), testData.end(), selectNegNo);
+ results = selectNegNo.results();
+ BOOST_CHECK((testData.size() -4) == results.size());
+ index = 0;
+ BOOST_CHECK(results[index++] == "a");
+ BOOST_CHECK(results[index++] == "b");
+ BOOST_CHECK(results[index++] == "c");
+ BOOST_CHECK(results[index++] == "b");
+ BOOST_CHECK(results[index++] == "b");
+}
+
+
BOOST_AUTO_TEST_SUITE_END()
commit a2b836e84227da376985070f22f8a6cc31ec459f
Author: Brent Eagles <beagles at digium.com>
Date: Tue Mar 1 17:17:22 2011 -0330
- fix a unique/shared mutex bug ListenerManager
- add a unit test driver for some small but key code in the bridge service.
diff --git a/src/ListenerManager.h b/src/ListenerManager.h
index e0e8700..c6ef841 100644
--- a/src/ListenerManager.h
+++ b/src/ListenerManager.h
@@ -61,6 +61,11 @@ class ListenerManagerT : public IceUtil::Shared
}
private:
+ //
+ // NOTE: Currently uses the monitor semantics provided by the Ice threading library. This should be switched to
+ // use a mechanism implemented in Boost if there is something equivalent. (Not indicated as something that needs
+ // to be done, as it really isn't a priority)
+ //
IceUtil::Monitor<IceUtil::Mutex> mMonitor;
typename IceUtil::Handle<ListenerManagerT> mMgr;
bool mStopped;
@@ -182,7 +187,7 @@ protected:
bool init()
{
- boost::shared_lock<boost::shared_mutex> lock(mLock);
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
if(mInitialized)
{
return mInitialized;
diff --git a/src/ServiceUtil.h b/src/ServiceUtil.h
index 333d9d2..36610b9 100644
--- a/src/ServiceUtil.h
+++ b/src/ServiceUtil.h
@@ -77,6 +77,9 @@ public:
private:
+ //
+ // TODO: boost?
+ //
IceUtil::Mutex mLock;
Ice::CommunicatorPtr mCommunicator;
std::string mProxyString;
diff --git a/src/SessionOperations.h b/src/SessionOperations.h
index 9648553..d08d9cd 100644
--- a/src/SessionOperations.h
+++ b/src/SessionOperations.h
@@ -139,7 +139,8 @@ class CountIfOperation : public std::unary_function<SessionWrapperPtr, void>
{
public:
CountIfOperation(const Crit& crit) :
- mCriteria(crit)
+ mCriteria(crit),
+ mCount(0)
{
}
@@ -151,7 +152,10 @@ public:
}
}
- size_t count() const;
+ size_t count() const
+ {
+ return mCount;
+ }
private:
Crit mCriteria;
size_t mCount;
diff --git a/src/SessionWrapper.cpp b/src/SessionWrapper.cpp
index aa75ace..67d03ba 100644
--- a/src/SessionWrapper.cpp
+++ b/src/SessionWrapper.cpp
@@ -116,9 +116,6 @@ void SessionWrapper::update(const BridgedSessionPtr& update)
void SessionWrapper::pushUpdate()
{
- // XXX this might be redundnant.
- mLogger(Debug) << ": replicating and update for " << mSession->key;
-
boost::unique_lock<boost::shared_mutex> lock(mLock);
++mSession->serial;
ReplicatedStateItemSeq seq;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 80e2a80..4b34369 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -2,24 +2,24 @@ asterisk_scf_slice_include_directories(${API_SLICE_DIR})
if(NOT integrated_build STREQUAL "true")
add_subdirectory(channel_driver/local_slice)
endif()
-asterisk_scf_component_init(bridging_unit_test CXX)
+asterisk_scf_component_init(bridge_component_test CXX)
include_directories("../src")
include_directories(${utils_dir}/SmartProxy/include)
-asterisk_scf_component_add_slice(bridging_unit_test CommandsIf)
-asterisk_scf_component_add_file(bridging_unit_test TestBridging.cpp)
-asterisk_scf_component_add_file(bridging_unit_test SessionListenerI.h)
-asterisk_scf_component_add_file(bridging_unit_test SessionListenerI.cpp)
-asterisk_scf_component_add_file(bridging_unit_test BridgeListenerI.h)
-asterisk_scf_component_add_file(bridging_unit_test BridgeListenerI.cpp)
-asterisk_scf_component_add_file(bridging_unit_test BridgeManagerListenerI.h)
-asterisk_scf_component_add_file(bridging_unit_test BridgeManagerListenerI.cpp)
-asterisk_scf_component_add_file(bridging_unit_test TestCommandDriver.cpp)
-asterisk_scf_component_add_file(bridging_unit_test TestCommandDriver.h)
-asterisk_scf_component_add_slice(bridging_unit_test ../src/BridgeReplicatorIf.ice)
+asterisk_scf_component_add_slice(bridge_component_test CommandsIf)
+asterisk_scf_component_add_file(bridge_component_test TestBridging.cpp)
+asterisk_scf_component_add_file(bridge_component_test SessionListenerI.h)
+asterisk_scf_component_add_file(bridge_component_test SessionListenerI.cpp)
+asterisk_scf_component_add_file(bridge_component_test BridgeListenerI.h)
+asterisk_scf_component_add_file(bridge_component_test BridgeListenerI.cpp)
+asterisk_scf_component_add_file(bridge_component_test BridgeManagerListenerI.h)
+asterisk_scf_component_add_file(bridge_component_test BridgeManagerListenerI.cpp)
+asterisk_scf_component_add_file(bridge_component_test TestCommandDriver.cpp)
+asterisk_scf_component_add_file(bridge_component_test TestCommandDriver.h)
+asterisk_scf_component_add_slice(bridge_component_test ../src/BridgeReplicatorIf.ice)
-asterisk_scf_component_add_ice_libraries(bridging_unit_test IceStorm)
-asterisk_scf_component_add_ice_libraries(bridging_unit_test IceBox)
-asterisk_scf_component_add_boost_libraries(bridging_unit_test unit_test_framework thread)
+asterisk_scf_component_add_ice_libraries(bridge_component_test IceStorm)
+asterisk_scf_component_add_ice_libraries(bridge_component_test IceBox)
+asterisk_scf_component_add_boost_libraries(bridge_component_test unit_test_framework thread)
if(NOT logger_dir)
message(FATAL_ERROR "The logger directory could not be found ${logger_dir}")
@@ -29,12 +29,28 @@ include_directories(${API_INCLUDE_DIR})
if(integrated_build STREQUAL "true")
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../test_channel/local_slice/generated)
endif()
-asterisk_scf_component_build_icebox(bridging_unit_test)
-target_link_libraries(bridging_unit_test logging-client)
-target_link_libraries(bridging_unit_test asterisk-scf-api)
-target_link_libraries(bridging_unit_test test-channel-api)
+asterisk_scf_component_build_icebox(bridge_component_test)
+target_link_libraries(bridge_component_test logging-client)
+target_link_libraries(bridge_component_test asterisk-scf-api)
+target_link_libraries(bridge_component_test test-channel-api)
# component tests only work for integrated builds
if(integrated_build STREQUAL "true")
- icebox_add_test(bridging_unit_test ../config/test_bridging.conf)
+ icebox_add_test(bridge_component_test ../config/test_bridging.conf)
endif()
+
+asterisk_scf_component_init(bridge_unit_tests CXX)
+asterisk_scf_component_add_slice(bridge_unit_tests ../src/BridgeReplicatorIf.ice)
+asterisk_scf_component_add_file(bridge_unit_tests ../src/SessionCollection.cpp)
+asterisk_scf_component_add_file(bridge_unit_tests ../src/SessionOperations.cpp)
+asterisk_scf_component_add_file(bridge_unit_tests ../src/SessionWrapper.cpp)
+asterisk_scf_component_add_file(bridge_unit_tests ../src/MediaSplicer.cpp)
+asterisk_scf_component_add_file(bridge_unit_tests UnitTests.cpp)
+asterisk_scf_component_add_ice_libraries(bridge_component_test Ice)
+asterisk_scf_component_add_boost_libraries(bridge_unit_tests unit_test_framework thread)
+asterisk_scf_component_build_standalone(bridge_unit_tests)
+
+target_link_libraries(bridge_unit_tests logging-client)
+target_link_libraries(bridge_unit_tests asterisk-scf-api)
+
+
diff --git a/test/TestBridging.cpp b/test/TestBridging.cpp
index 3fc4510..e1ba7b2 100644
--- a/test/TestBridging.cpp
+++ b/test/TestBridging.cpp
@@ -50,6 +50,11 @@ public:
mArgs(args),
mArgv(0)
{
+ //
+ // TODO: stl ensures that a std::vector's memory organization is compatible with
+ // casting to C pointers, so this should be converted to take advantage of that.
+ // (see the other test suites).
+ //
const char* fakeName = "BRIDGE_TEST_SERVICE";
mArgc = args.size() + 1;
mArgv = new char*[mArgc];
@@ -109,6 +114,9 @@ typedef IceUtil::Handle<TestEnvironment> TestEnvironmentPtr;
//
TestEnvironmentPtr globalTestEnvironment;
+//
+// Simple helper for initializing Ice and ensuring proper cleanup in the context of a test case.
+//
class IceEnvironment
{
public:
diff --git a/test/UnitTests.cpp b/test/UnitTests.cpp
new file mode 100644
index 0000000..e4eea61
--- /dev/null
+++ b/test/UnitTests.cpp
@@ -0,0 +1,174 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#define BOOST_TEST_MODULE "Bridge internals unit test"
+#include <boost/test/unit_test.hpp>
+#include <boost/bind.hpp>
+#include <boost/test/debug.hpp>
+#include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
+#include <AsteriskSCF/Media/MediaIf.h>
+#include <AsteriskSCF/logger.h>
+#include <Ice/Ice.h>
+#include <set>
+#include <vector>
+#include <algorithm>
+
+#include "SessionOperations.h"
+
+using namespace AsteriskSCF::System::Logging;
+using namespace AsteriskSCF::SessionCommunications::V1;
+using namespace AsteriskSCF::Bridge::V1;
+using namespace AsteriskSCF::BridgeService;
+using namespace std;
+
+/**
+ *
+ * These tests are "actual" unit tests for verifying that small bits of code within the
+ * bridging service are working properly.
+ *
+ **/
+static BridgedSessionPtr createBridgedSession(const BridgedSessionState initialState)
+{
+ BridgedSessionPtr result(new BridgedSession);
+ result->currentState = initialState;
+ return result;
+}
+
+BOOST_AUTO_TEST_SUITE(BridgeUnitTests)
+
+class Fixture
+{
+public:
+ Fixture() :
+ mLogger(getLoggerFactory().getLogger("AsteriskSCF.BridgeUnitTests"))
+ {
+ }
+
+ ~Fixture()
+ {
+ }
+
+ Logger getLogger()
+ {
+ return mLogger;
+ }
+private:
+ Logger mLogger;
+};
+
+BOOST_FIXTURE_TEST_CASE(testIfState, Fixture)
+{
+ BridgedSessionPtr letter(createBridgedSession(BridgedSessionState::Added));
+ SessionWrapperPtr wrapper(new SessionWrapper(letter, AsteriskSCF::BridgeService::ReplicatorSmartPrx(), getLogger()));
+ IfStateCriteria a(BridgedSessionState::Added);
+ IfStateCriteria b(BridgedSessionState::Connected);
+ BOOST_CHECK(a(wrapper));
+ BOOST_CHECK(!b(wrapper));
+}
+
+BOOST_FIXTURE_TEST_CASE(testIfInCrriteria, Fixture)
+{
+ BridgedSessionPtr letter(createBridgedSession(BridgedSessionState::Added));
+ SessionWrapperPtr wrapper(new SessionWrapper(letter, AsteriskSCF::BridgeService::ReplicatorSmartPrx(), getLogger()));
+ set<BridgedSessionState> yesVals;
+ yesVals.insert(BridgedSessionState::Added);
+ yesVals.insert(BridgedSessionState::Connected);
+ set<BridgedSessionState> noVals;
+ noVals.insert(BridgedSessionState::Disconnected);
+ noVals.insert(BridgedSessionState::Done);
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> yes(yesVals);
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> no(noVals);
+ BOOST_CHECK(yes(wrapper));
+ BOOST_CHECK(!no(wrapper));
+}
+
+BOOST_FIXTURE_TEST_CASE(testNegation, Fixture)
+{
+ BridgedSessionPtr letter(createBridgedSession(BridgedSessionState::Added));
+ SessionWrapperPtr wrapper(new SessionWrapper(letter, AsteriskSCF::BridgeService::ReplicatorSmartPrx(), getLogger()));
+ set<BridgedSessionState> yesVals;
+ yesVals.insert(BridgedSessionState::Added);
+ yesVals.insert(BridgedSessionState::Connected);
+ set<BridgedSessionState> noVals;
+ noVals.insert(BridgedSessionState::Disconnected);
+ noVals.insert(BridgedSessionState::Done);
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> yes(yesVals);
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> no(noVals);
+ Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > negYes(yes);
+ Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > negNo(no);
+
+ BOOST_CHECK(!negYes(wrapper));
+ BOOST_CHECK(negNo(wrapper));
+}
+
+BOOST_FIXTURE_TEST_CASE(testCountIf, Fixture)
+{
+ //
+ // Setup some test data.
+ //
+ AsteriskSCF::BridgeService::ReplicatorSmartPrx rep;
+ vector<SessionWrapperPtr> testData;
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Added), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Added), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Disconnected), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Connected), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Done), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Added), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Disconnected), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Done), rep, getLogger()));
+ testData.push_back(new SessionWrapper(createBridgedSession(BridgedSessionState::Connected), rep, getLogger()));
+
+ //
+ // Now a variety of test criteria.
+ //
+ IfStateCriteria a(BridgedSessionState::Added);
+ CountIfOperation<IfStateCriteria> countIf(a);
+ countIf = for_each(testData.begin(), testData.end(), countIf);
+ BOOST_CHECK(countIf.count() == 3);
+
+ Negate<IfStateCriteria> notA(a);
+ CountIfOperation<Negate<IfStateCriteria> > countNotIf(notA);
+ countNotIf = for_each(testData.begin(), testData.end(), countNotIf);
+ BOOST_CHECK((testData.size() -3) == countNotIf.count());
+
+ set<BridgedSessionState> yesVals;
+ yesVals.insert(BridgedSessionState::Added);
+ yesVals.insert(BridgedSessionState::Connected);
+ set<BridgedSessionState> noVals;
+ noVals.insert(BridgedSessionState::Disconnected);
+ noVals.insert(BridgedSessionState::Done);
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> yes(yesVals);
+ CountIfOperation<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > countYes(yes);
+ countYes = for_each(testData.begin(), testData.end(), countYes);
+ BOOST_CHECK(countYes.count() == 5);
+
+ IfInCriteria<set<BridgedSessionState>, StateMemberSelector> no(noVals);
+ CountIfOperation<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > countNo(no);
+ countNo = for_each(testData.begin(), testData.end(), countNo);
+ BOOST_CHECK(countNo.count() == 4);
+
+ Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > negYes(yes);
+ CountIfOperation<Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > > countNegYes(negYes);
+ countNegYes = for_each(testData.begin(), testData.end(), countNegYes);
+ BOOST_CHECK((testData.size() -5) == countNegYes.count());
+
+ Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > negNo(no);
+ CountIfOperation<Negate<IfInCriteria<set<BridgedSessionState>, StateMemberSelector> > > countNegNo(negNo);
+ countNegNo = for_each(testData.begin(), testData.end(), countNegNo);
+ BOOST_CHECK((testData.size() -4) == countNegNo.count());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
-----------------------------------------------------------------------
--
asterisk-scf/integration/bridging.git
More information about the asterisk-scf-commits
mailing list