[asterisk-scf-commits] asterisk-scf/integration/statereplicator.git branch "master" created.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Tue Sep 21 19:41:40 CDT 2010
branch "master" has been created
at 747d9ed0aa4f01ed06ee4b2d17d8a1311ac25cf9 (commit)
- Log -----------------------------------------------------------------
commit 747d9ed0aa4f01ed06ee4b2d17d8a1311ac25cf9
Author: Ken Hunt <ken.hunt at digium.com>
Date: Tue Sep 21 19:39:00 2010 -0500
Initial implementation of StateReplicator template class and tests.
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..69bf862
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,30 @@
+#
+# Asterisk Scalable Communications Framework
+#
+# Copyright (C) 2010 -- Digium, Inc.
+#
+# All rights reserved.
+#
+
+# State Replicator build system
+
+if(NOT integrated_build STREQUAL "true")
+
+ # Minimum we require is 2.6
+ cmake_minimum_required(VERSION 2.6)
+
+ # Include common Hydra build infrastructure. Make sure your submodules are pulled.
+ include(cmake/AsteriskSCF.cmake)
+
+ # This project is C++ based and requires a minimum of 3.4 of Ice.
+ hydra_project(SipChannelService 3.4 CXX)
+
+ # Pull in the slice definitions
+ #add_subdirectory(slice)
+
+endif()
+
+add_subdirectory(src)
+add_subdirectory(testslice)
+add_subdirectory(test)
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..670ed86
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Define the SIP Channel Service component
+
+hydra_component_init(StateReplicator CXX)
+
+hydra_component_add_file(StateReplicator StateReplicator.h)
+hydra_component_add_file(StateReplicator StateReplicator.cpp)
+
+hydra_component_build_library(StateReplicator)
+
+hydra_component_install(StateReplicator RUNTIME lib "State Replicator" StateReplicator)
+
diff --git a/src/StateReplicator.cpp b/src/StateReplicator.cpp
new file mode 100644
index 0000000..fc7f541
--- /dev/null
+++ b/src/StateReplicator.cpp
@@ -0,0 +1,22 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+#include <IceUtil/UUID.h>
+
+#include "StateReplicator.h"
+
+namespace AsteriskSCF
+{
+namespace StateReplication
+{
+ /*
+ * This .cpp is a temporary solution to get a CMakeProject that consists only of header files.
+ */
+
+};
+};
diff --git a/src/StateReplicator.h b/src/StateReplicator.h
new file mode 100644
index 0000000..d0a2464
--- /dev/null
+++ b/src/StateReplicator.h
@@ -0,0 +1,168 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+#pragma once
+
+#include <Ice/Ice.h>
+
+namespace AsteriskSCF
+{
+namespace StateReplication
+{
+
+/**
+ * Templatization of a state replicator.
+ * NOTE:
+ * - The state item type is assumed to have a public field named "key" which is of type "k".
+ * - The listeners should be notified on a worker thread.
+ */
+template<typename R, typename S, typename s, typename K, typename k, typename L>
+class StateReplicator : public R
+{
+// Types: R - Replicator, S - State Item Seq, s - state item, K - Key sequence, k - Key element type, L - Listener
+public:
+ /**
+ * Functor for forwarding setState() notices.
+ */
+ template<typename T, typename U> class SetStateNotice
+ {
+ // Types: T - Listener type, U - State Item seq.
+ public:
+ SetStateNotice(const U& stateSeq) : mStateSeq(stateSeq) {}
+ ~SetStateNotice() {}
+ void operator() (T x) {x->setStateNotice(mStateSeq);}
+ U mStateSeq;
+ };
+
+ /**
+ * Functor for forwarding removeState() notices.
+ */
+ template<typename T, typename V> class RemoveStateNotice
+ {
+ // Types: T - Listener type, V - Key Item seq.
+ public:
+ RemoveStateNotice(const V& keys) : mKeys(keys) {}
+ ~RemoveStateNotice() {}
+ void operator() (T x) {x->removeStateNotice(mKeys);}
+ V mKeys;
+ };
+
+ /**
+ * Functor to use as find_if predicate.
+ */
+ template<typename T> class IdentifyListener
+ {
+ public:
+ IdentifyListener(const T& listener) : mListener(listener) {}
+ ~IdentifyListener() {}
+ bool operator() (T x) {return (x->ice_getIdentity() == mListener->ice_getIdentity());}
+ T mListener;
+ };
+
+public:
+ StateReplicator() {};
+ virtual ~StateReplicator() {};
+
+ void addListener(const L& listener, const Ice::Current& = ::Ice::Current())
+ {
+ mListeners.push_back(listener);
+ }
+
+ void removeListener(const L& listener, const Ice::Current& = ::Ice::Current())
+ {
+ std::vector<L>::iterator it = std::find_if(mListeners.begin(), mListeners.end(), IdentifyListener<L>(listener));
+
+ if (it != mListeners.end())
+ {
+ mListeners.erase(it);
+ }
+ }
+
+ void clearListeners()
+ {
+ mListeners.clear();
+ }
+
+ void clearState()
+ {
+ K allIds;
+
+ for(std::map<k, s>::const_iterator it = mStateItemMap.begin(); it != mStateItemMap.end(); ++it)
+ {
+ allIds.push_back(it->first);
+ }
+
+ for_each(mListeners.begin(), mListeners.end(), RemoveStateNotice<L,K>(allIds));
+
+ mStateItemMap.clear();
+ }
+
+ void setState(const S& items, const Ice::Current& = ::Ice::Current())
+ {
+ for (S::const_iterator iter = items.begin();
+ iter != items.end(); ++iter)
+ {
+ std::map<k, s>::iterator mapItem = mStateItemMap.find((*iter)->key);
+
+ if (mapItem != mStateItemMap.end())
+ {
+ (*mapItem).second = (*iter);
+ }
+ else
+ {
+ mStateItemMap[(*iter)->key] = (*iter);
+ }
+ }
+
+ for_each( mListeners.begin(), mListeners.end(), SetStateNotice<L,S>(items) );
+ }
+
+ void removeState(const K& ids, const Ice::Current& = ::Ice::Current())
+ {
+ for (K::const_iterator iter = ids.begin(); iter != ids.end(); ++iter)
+ {
+ mStateItemMap.erase(*iter);
+ }
+
+ for_each(mListeners.begin(), mListeners.end(), RemoveStateNotice<L,K>(ids));
+ }
+
+ S getState(const K& itemKeys, const Ice::Current& = ::Ice::Current())
+ {
+ S results;
+
+ for(K::const_iterator it = itemKeys.begin(); it != itemKeys.end(); ++it)
+ {
+ results.push_back(mStateItemMap[(*it)]);
+ }
+ return results;
+ }
+
+ S getAllState(const Ice::Current& = ::Ice::Current())
+ {
+ S results;
+
+ for(std::map<k, s>::const_iterator it = mStateItemMap.begin(); it != mStateItemMap.end(); ++it)
+ {
+ results.push_back(it->second);
+ }
+ return results;
+ }
+
+ int getListenerCount()
+ {
+ return mListeners.size();
+ }
+
+private:
+ std::vector<L> mListeners;
+ std::map<k, s > mStateItemMap;
+};
+
+
+};
+};
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..5c7b3bc
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Create State Replicator Test project.
+
+hydra_component_init(StateReplicatorTest CXX)
+include_directories("../src")
+hydra_component_add_slice(StateReplicatorTest StateReplicatorTestIf)
+hydra_component_add_file(StateReplicatorTest TestStateReplicator.cpp)
+hydra_component_add_file(StateReplicatorTest SharedTestData.h)
+hydra_component_add_file(StateReplicatorTest MockStateReplicatorListener.h)
+
+hydra_component_add_boost_libraries(StateReplicatorTest unit_test_framework)
+
+hydra_component_build_standalone(StateReplicatorTest)
+hydra_component_install(StateReplicatorTest RUNTIME bin "StateReplicatorTest Component Test Driver." Test)
+
+boost_add_test(StateReplicatorTest)
diff --git a/test/MockStateReplicatorListener.h b/test/MockStateReplicatorListener.h
new file mode 100644
index 0000000..abaaeb6
--- /dev/null
+++ b/test/MockStateReplicatorListener.h
@@ -0,0 +1,55 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+#pragma once
+
+#include <Ice/Ice.h>
+#include "StateReplicatorTestIf.h"
+
+namespace AsteriskSCF
+{
+namespace StateReplicatorTest
+{
+
+class MockStateReplicatorListenerImpl : public AsteriskSCF::StateReplicatorTest::V1::TestStateReplicatorListener
+{
+public:
+ MockStateReplicatorListenerImpl() : mRemoveStateCalled(false), mSetStateCalled(true)
+ {
+ }
+
+ void removeStateNotice(const ::Ice::StringSeq& itemKeys, const ::Ice::Current& )
+ {
+ mItemKeys = itemKeys;
+ mRemoveStateCalled = true;
+ }
+
+ void setStateNotice(const ::AsteriskSCF::StateReplicatorTest::V1::TestStateItemSeq& items, const ::Ice::Current& )
+ {
+ mStateItems = items;
+ mSetStateCalled = true;
+ }
+
+ void reset()
+ {
+ mRemoveStateCalled = false;
+ mSetStateCalled = false;
+ mStateItems.clear();
+ mItemKeys.clear();
+ }
+
+public:
+ bool mRemoveStateCalled;
+ bool mSetStateCalled;
+ AsteriskSCF::StateReplicatorTest::V1::TestStateItemSeq mStateItems;
+ Ice::StringSeq mItemKeys;
+};
+typedef ::IceInternal::ProxyHandle<MockStateReplicatorListenerImpl> MockStateReplicatorListenerImplPrx;
+typedef ::IceInternal::Handle<MockStateReplicatorListenerImpl> MockStateReplicatorListenerImplPtr;
+
+} // StateReplicatorTest
+} // AsteriskSCF
diff --git a/test/SharedTestData.h b/test/SharedTestData.h
new file mode 100644
index 0000000..4c7bf48
--- /dev/null
+++ b/test/SharedTestData.h
@@ -0,0 +1,50 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+#pragma once
+
+#include <Ice/Ice.h>
+#include "StateReplicatorTestIf.h"
+#include "MockStateReplicatorListener.h"
+
+namespace AsteriskSCF
+{
+namespace StateReplicatorTest
+{
+ typedef AsteriskSCF::StateReplication::StateReplicator<AsteriskSCF::StateReplicatorTest::V1::TestStateReplicator, AsteriskSCF::StateReplicatorTest::V1::TestStateItemSeq, AsteriskSCF::StateReplicatorTest::V1::TestStateItemPtr, Ice::StringSeq, std::string, AsteriskSCF::StateReplicatorTest::V1::TestStateReplicatorListenerPrx> TestReplicatorImpl;
+ typedef IceUtil::Handle<TestReplicatorImpl> TestReplicatorImplPtr;
+
+/**
+ * Pseudo singleton for sharing data among test artifacts.
+ */
+class SharedTestData
+{
+public:
+ static SharedTestData instance;
+
+ // Communicator for outgoing stuff.
+ Ice::CommunicatorPtr communicator_out;
+
+ // Communicator for incoming stuff. This is where we add the test servants.
+ Ice::CommunicatorPtr communicator_in;
+
+ Ice::ObjectAdapterPtr adapter_in;
+ Ice::ObjectAdapterPtr adapter_out;
+
+ TestReplicatorImplPtr mTestReplicatorImplPtr;
+ AsteriskSCF::StateReplicatorTest::V1::TestStateReplicatorPrx mTestStateReplicatorPrx;
+
+ MockStateReplicatorListenerImplPtr mMockStateListener1Ptr;
+ MockStateReplicatorListenerImplPtr mMockStateListener2Ptr;
+
+ AsteriskSCF::StateReplicatorTest::V1::TestStateReplicatorListenerPrx mTestStateListener1Prx;
+ AsteriskSCF::StateReplicatorTest::V1::TestStateReplicatorListenerPrx mTestStateListener2Prx;
+
+};
+
+}; // StateReplicatorTest
+}; // AsteriskSCF
diff --git a/test/TestStateReplicator.cpp b/test/TestStateReplicator.cpp
new file mode 100644
index 0000000..b4afdce
--- /dev/null
+++ b/test/TestStateReplicator.cpp
@@ -0,0 +1,389 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE StateReplicatorComponentTestSuite
+#define BOOST_TEST_NO_MAIN
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/debug.hpp>
+
+#include <Ice/Ice.h>
+
+#include "StateReplicatorTestIf.h"
+#include "StateReplicator.h"
+#include "SharedTestData.h"
+
+using namespace std;
+using namespace AsteriskSCF::StateReplicatorTest::V1;
+using namespace AsteriskSCF::StateReplicatorTest;
+using namespace AsteriskSCF::StateReplication;
+
+/**
+ * Instantiate our shared data.
+ */
+SharedTestData SharedTestData::instance;
+
+/* Cache the command line arguments so that Ice can be initialized within the global fixture. */
+struct ArgCacheType
+{
+public:
+ int argc;
+ char **argv;
+};
+static ArgCacheType mCachedArgs;
+
+/**
+ * A global fixture for Ice initialization.
+ * Provides setup/teardown for the entire set of tests.
+ */
+struct GlobalIceFixture
+{
+ GlobalIceFixture()
+ {
+ BOOST_TEST_MESSAGE("Setting up State Replicator test fixture");
+
+ ::boost::debug::detect_memory_leaks(false);
+ ::boost::unit_test::unit_test_log.set_stream( std::cout );
+
+ int status = 0;
+ try
+ {
+ Ice::PropertiesPtr props = Ice::createProperties(mCachedArgs.argc, mCachedArgs.argv);
+ Ice::InitializationData initData;
+ initData.properties = props;
+
+ // NOTE: See the typedef at top of ShareTestData.h to see how the StateReplicator template is invoked.
+
+ // Set up incoming adapter. This is where we'll publish our proxies.
+ SharedTestData::instance.communicator_in = Ice::initialize(initData);
+
+ SharedTestData::instance.adapter_in = SharedTestData::instance.communicator_in->createObjectAdapterWithEndpoints("TestReplicatorAdapterIn", "default -p 10070");
+
+ string replicatorId("TestReplicator");
+ SharedTestData::instance.mTestReplicatorImplPtr = new TestReplicatorImpl();
+ SharedTestData::instance.adapter_in->add(SharedTestData::instance.mTestReplicatorImplPtr, SharedTestData::instance.communicator_in->stringToIdentity(replicatorId));
+
+ string listenerId1("Listener1");
+ SharedTestData::instance.mMockStateListener1Ptr = new MockStateReplicatorListenerImpl();
+ SharedTestData::instance.adapter_in->add(SharedTestData::instance.mMockStateListener1Ptr, SharedTestData::instance.communicator_in->stringToIdentity(listenerId1));
+
+ string listenerId2("Listener2");
+ SharedTestData::instance.mMockStateListener2Ptr = new MockStateReplicatorListenerImpl();
+ SharedTestData::instance.adapter_in->add(SharedTestData::instance.mMockStateListener2Ptr, SharedTestData::instance.communicator_in->stringToIdentity(listenerId2));
+
+ SharedTestData::instance.adapter_in->activate();
+
+ // Now that the adapter has been activated, get a local proxy to the replicator.
+ Ice::ObjectPrx replicatorObjectPrx = SharedTestData::instance.adapter_in->createDirectProxy(SharedTestData::instance.communicator_in->stringToIdentity(replicatorId));
+ SharedTestData::instance.mTestStateReplicatorPrx = TestStateReplicatorPrx::checkedCast(replicatorObjectPrx);
+
+ Ice::ObjectPrx listener1ObjectPrx = SharedTestData::instance.adapter_in->createDirectProxy(SharedTestData::instance.communicator_in->stringToIdentity(listenerId1));
+ SharedTestData::instance.mTestStateListener1Prx = TestStateReplicatorListenerPrx::checkedCast(listener1ObjectPrx);
+
+ Ice::ObjectPrx listener2ObjectPrx = SharedTestData::instance.adapter_in->createDirectProxy(SharedTestData::instance.communicator_in->stringToIdentity(listenerId2));
+ SharedTestData::instance.mTestStateListener2Prx = TestStateReplicatorListenerPrx::checkedCast(listener2ObjectPrx);
+
+ }
+ catch (const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = 1;
+ }
+ catch (const char* msg)
+ {
+ cerr << msg << endl;
+ status = 1;
+ }
+ } // end Fixture() constructor
+
+
+ ~GlobalIceFixture()
+ {
+ BOOST_TEST_MESSAGE("Tearing down service discovery test fixture");
+
+
+ if (SharedTestData::instance.communicator_in)
+ {
+ SharedTestData::instance.communicator_in->shutdown();
+ SharedTestData::instance.communicator_in = 0;
+ }
+ if (SharedTestData::instance.communicator_out)
+ {
+ SharedTestData::instance.communicator_out->shutdown();
+ SharedTestData::instance.communicator_out = 0;
+ }
+ }
+private:
+ int mGlob;
+};
+
+BOOST_GLOBAL_FIXTURE(GlobalIceFixture);
+
+/**
+ * Implement our own main to intercept the command line args.
+ * (A default main() is provided if we hadn't set BOOST_TEST_NO_MAIN at the top of file.)
+ * NOTE: Pass in --log_level=message to see the debug print statements.
+ */
+int BOOST_TEST_CALL_DECL main( int argc, char* argv[] )
+{
+ mCachedArgs.argc = argc;
+ mCachedArgs.argv = argv;
+ return ::boost::unit_test::unit_test_main( &init_unit_test, argc, argv );
+}
+
+struct PerTestFixture
+{
+public:
+ PerTestFixture()
+ {
+ try
+ {
+ SharedTestData::instance.mMockStateListener1Ptr->reset();
+ SharedTestData::instance.mMockStateListener2Ptr->reset();
+
+ SharedTestData::instance.mTestStateReplicatorPrx->addListener(SharedTestData::instance.mTestStateListener1Prx);
+ SharedTestData::instance.mTestStateReplicatorPrx->addListener(SharedTestData::instance.mTestStateListener2Prx);
+
+ mTestValues.clear();
+
+ TestStateItemFooPtr item1 = new TestStateItemFoo();
+ item1->key = "FooBabar";
+ item1->mFooCount = 12;
+ item1->mFooString = "Baileys";
+ mTestValues.push_back(item1);
+
+ TestStateItemBarPtr item2 = new TestStateItemBar();
+ item2->key = "BarMouse";
+ item2->mBarString = "Ringling";
+ mTestValues.push_back(item2);
+
+ TestStateItemFooPtr item3 = new TestStateItemFoo();
+ item3->key = "FooDumbo";
+ item3->mFooCount = 7;
+ item3->mFooString = "Barnum";
+ mTestValues.push_back(item3);
+
+ }
+ catch (...)
+ {
+ BOOST_TEST_MESSAGE("PerTestFixture failed to initialize.");
+
+ SharedTestData::instance.mTestReplicatorImplPtr->clearListeners();
+ SharedTestData::instance.mTestReplicatorImplPtr->clearState();
+ }
+ }
+
+ ~PerTestFixture()
+ {
+ try
+ {
+ SharedTestData::instance.mTestReplicatorImplPtr->clearListeners();
+ SharedTestData::instance.mTestReplicatorImplPtr->clearState();
+ }
+ catch (...)
+ {
+ BOOST_TEST_MESSAGE("PerTestFixture failed in shutdown.");
+ }
+ }
+
+public:
+ TestStateItemSeq mTestValues;
+};
+
+/**
+ * Test adding and removing a listener with the StateReplicator.
+ */
+BOOST_AUTO_TEST_CASE(AddRemoveListeners)
+{
+ bool addListenerSucceeded(true);
+ try
+ {
+ SharedTestData::instance.mTestStateReplicatorPrx->addListener(SharedTestData::instance.mTestStateListener1Prx);
+ SharedTestData::instance.mTestStateReplicatorPrx->addListener(SharedTestData::instance.mTestStateListener2Prx);
+ }
+ catch (...)
+ {
+ addListenerSucceeded = false;
+ BOOST_TEST_MESSAGE("Exception adding Listeners.");
+ }
+
+ BOOST_CHECK(addListenerSucceeded);
+ BOOST_CHECK(SharedTestData::instance.mTestReplicatorImplPtr->getListenerCount() == 2);
+
+ bool removeListenerSucceeded(true);
+ try
+ {
+ SharedTestData::instance.mTestStateReplicatorPrx->removeListener(SharedTestData::instance.mTestStateListener1Prx);
+ SharedTestData::instance.mTestStateReplicatorPrx->removeListener(SharedTestData::instance.mTestStateListener2Prx);
+ }
+ catch (...)
+ {
+ removeListenerSucceeded = false;
+ BOOST_TEST_MESSAGE("Exception removing Listener.");
+ }
+ BOOST_CHECK(removeListenerSucceeded);
+ BOOST_CHECK(SharedTestData::instance.mTestReplicatorImplPtr->getListenerCount() == 0);
+
+
+ BOOST_TEST_MESSAGE("Completed AddRemoveListeners test.");
+}
+
+/**
+ * Test forwarding the setState operation of the StateReplicator interface to listeners.
+ */
+BOOST_FIXTURE_TEST_CASE(PushData, PerTestFixture)
+{
+ try
+ {
+ SharedTestData::instance.mTestStateReplicatorPrx->setState(mTestValues);
+
+ }
+ catch(const IceUtil::Exception &ie)
+ {
+ bool IceException(false);
+ string msg = "Exception pushing state data.";
+ msg += ie.what();
+ BOOST_TEST_MESSAGE(msg);
+ BOOST_CHECK(IceException);
+ }
+ catch (...)
+ {
+ bool unknownException(false);
+ BOOST_CHECK(unknownException);
+ }
+
+ BOOST_CHECK(SharedTestData::instance.mMockStateListener1Ptr->mStateItems.size() == 3);
+ BOOST_CHECK(SharedTestData::instance.mMockStateListener2Ptr->mStateItems.size() == 3);
+
+ BOOST_CHECK(SharedTestData::instance.mMockStateListener1Ptr->mStateItems.front()->key == "FooBabar");
+
+ BOOST_TEST_MESSAGE("Completed PushData test.");
+
+}
+
+/**
+ * Test forwarding the removeState message to listeners.
+ */
+BOOST_FIXTURE_TEST_CASE(ForwardRemoveState, PerTestFixture)
+{
+ TestStateItemSeq retrievedValues;
+
+ try
+ {
+ SharedTestData::instance.mTestStateReplicatorPrx->setState(mTestValues);
+
+ Ice::StringSeq keys;
+ keys.push_back("FooBabar");
+ keys.push_back("FooDumbo");
+
+ SharedTestData::instance.mTestStateReplicatorPrx->removeState(keys);
+ }
+ catch(const IceUtil::Exception &ie)
+ {
+ bool IceException(false);
+ string msg = "Exception removing state data.";
+ msg += ie.what();
+ BOOST_TEST_MESSAGE(msg);
+ BOOST_CHECK(IceException);
+ }
+ catch (...)
+ {
+ bool unknownException(false);
+ BOOST_CHECK(unknownException);
+ }
+
+ BOOST_CHECK(SharedTestData::instance.mMockStateListener1Ptr->mItemKeys.size() == 2);
+ BOOST_CHECK(SharedTestData::instance.mMockStateListener2Ptr->mItemKeys.size() == 2);
+
+ BOOST_CHECK(SharedTestData::instance.mMockStateListener1Ptr->mItemKeys.front() == "FooBabar");
+
+ BOOST_TEST_MESSAGE("Completed RemoveState test.");
+
+}
+
+/**
+ * Test removing state. Also tests retrieving all the state.
+ */
+BOOST_FIXTURE_TEST_CASE(RemoveState, PerTestFixture)
+{
+ TestStateItemSeq retrievedValues;
+
+ try
+ {
+ // Set the basic 3 items of state.
+ SharedTestData::instance.mTestStateReplicatorPrx->setState(mTestValues);
+
+ // Try removing two of them.
+ Ice::StringSeq keys;
+ keys.push_back("FooBabar");
+ keys.push_back("FooDumbo");
+
+ SharedTestData::instance.mTestStateReplicatorPrx->removeState(keys);
+
+ retrievedValues = SharedTestData::instance.mTestStateReplicatorPrx->getAllState();
+ }
+ catch(const IceUtil::Exception &ie)
+ {
+ bool IceException(false);
+ string msg = "Exception removing state data.";
+ msg += ie.what();
+ BOOST_TEST_MESSAGE(msg);
+ BOOST_CHECK(IceException);
+ }
+ catch (...)
+ {
+ bool unknownException(false);
+ BOOST_CHECK(unknownException);
+ }
+
+ BOOST_CHECK(retrievedValues.size() == 1);
+ BOOST_CHECK(retrievedValues.size() == 1);
+
+ BOOST_CHECK(retrievedValues.front()->key == "BarMouse");
+
+ BOOST_TEST_MESSAGE("Completed RemoveState test.");
+}
+
+/**
+ * Test getting partial state based on keyed subset.
+ */
+BOOST_FIXTURE_TEST_CASE(GetSomeState, PerTestFixture)
+{
+ TestStateItemSeq retrievedValues;
+
+ try
+ {
+ SharedTestData::instance.mTestStateReplicatorPrx->setState(mTestValues);
+
+ Ice::StringSeq keys;
+ keys.push_back("FooBabar");
+ keys.push_back("FooDumbo");
+
+ retrievedValues = SharedTestData::instance.mTestStateReplicatorPrx->getState(keys);
+ }
+ catch(const IceUtil::Exception &ie)
+ {
+ bool IceException(false);
+ string msg = "Exception getting partial state data.";
+ msg += ie.what();
+ BOOST_TEST_MESSAGE(msg);
+ BOOST_CHECK(IceException);
+ }
+ catch (...)
+ {
+ bool unknownException(false);
+ BOOST_CHECK(unknownException);
+ }
+
+ BOOST_CHECK(retrievedValues.size() == 2);
+ BOOST_CHECK(retrievedValues.size() == 2);
+
+ BOOST_CHECK(retrievedValues.front()->key == "FooBabar");
+
+ BOOST_TEST_MESSAGE("Completed GetSomeState test.");
+}
\ No newline at end of file
diff --git a/testslice/CMakeLists.txt b/testslice/CMakeLists.txt
new file mode 100644
index 0000000..ec356d7
--- /dev/null
+++ b/testslice/CMakeLists.txt
@@ -0,0 +1,5 @@
+# Compile State Replicator Test Component's slice
+
+hydra_slice_include_directories("${CMAKE_SOURCE_DIR}/slice")
+hydra_compile_slice(StateReplicatorTestIf.ice lib "State Replicator Test Slice Types" Test)
+
diff --git a/testslice/StateReplicatorTestIf.ice b/testslice/StateReplicatorTestIf.ice
new file mode 100644
index 0000000..8b2a758
--- /dev/null
+++ b/testslice/StateReplicatorTestIf.ice
@@ -0,0 +1,48 @@
+#pragma once
+#include <Ice/BuiltinSequences.ice>
+
+module AsteriskSCF
+{
+module StateReplicatorTest
+{
+["suppress"]
+module V1
+{
+ class TestStateItem
+ {
+ string key;
+ };
+
+ sequence<TestStateItem> TestStateItemSeq;
+
+ interface TestStateReplicatorListener
+ {
+ void removeStateNotice(Ice::StringSeq itemKeys);
+ void setStateNotice(TestStateItemSeq items);
+ };
+
+ interface TestStateReplicator
+ {
+ void addListener(TestStateReplicatorListener *listener);
+ idempotent void removeListener(TestStateReplicatorListener *listener);
+ void setState (TestStateItemSeq items);
+ idempotent void removeState(Ice::StringSeq items);
+ TestStateItemSeq getState(Ice::StringSeq itemKeys);
+ TestStateItemSeq getAllState();
+ };
+
+ class TestStateItemFoo extends TestStateItem
+ {
+ string mFooString;
+ bool mIsFoo;
+ int mFooCount;
+ };
+
+ class TestStateItemBar extends TestStateItem
+ {
+ string mBarString;
+ };
+
+}; //module V1
+}; //module SIP
+}; //module Asterisk SCF
-----------------------------------------------------------------------
--
asterisk-scf/integration/statereplicator.git
More information about the asterisk-scf-commits
mailing list