diff options
author | Alan Conway <aconway@apache.org> | 2009-11-17 18:09:01 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2009-11-17 18:09:01 +0000 |
commit | ef7728a725272b88c3cd2f81f81ee60ed00cde90 (patch) | |
tree | 5083904bb1324c93cf399c6c8b04ee4f0cb03549 /cpp/src/tests | |
parent | 74c1740d54360bb4b091b5486c69f0f945d27abd (diff) | |
download | qpid-python-ef7728a725272b88c3cd2f81f81ee60ed00cde90.tar.gz |
cluster::InitialStatusMap and unit tests, support for improved cluster join protocol.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@881420 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/tests')
-rw-r--r-- | cpp/src/tests/InitialStatusMap.cpp | 141 | ||||
-rw-r--r-- | cpp/src/tests/cluster.mk | 5 | ||||
-rw-r--r-- | cpp/src/tests/cluster_test.cpp | 5 | ||||
-rw-r--r-- | cpp/src/tests/test_tools.h | 14 |
4 files changed, 156 insertions, 9 deletions
diff --git a/cpp/src/tests/InitialStatusMap.cpp b/cpp/src/tests/InitialStatusMap.cpp new file mode 100644 index 0000000000..7709b1fbfc --- /dev/null +++ b/cpp/src/tests/InitialStatusMap.cpp @@ -0,0 +1,141 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * 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. + * + */ + + +#include "unit_test.h" +#include "test_tools.h" +#include "qpid/cluster/InitialStatusMap.h" +#include <boost/assign.hpp> + +using namespace std; +using namespace qpid::cluster; +using namespace qpid::framing; +using namespace boost::assign; + +namespace qpid { +namespace tests { + +QPID_AUTO_TEST_SUITE(InitialStatusMapTestSuite) + +typedef InitialStatusMap::Status Status; + +Status activeStatus() { return Status(ProtocolVersion(), true, false, FieldTable()); } +Status newcomerStatus() { return Status(ProtocolVersion(), false, false, FieldTable()); } + +QPID_AUTO_TEST_CASE(testFirstInCluster) { + // Single member is first in cluster. + InitialStatusMap map(MemberId(0)); + BOOST_CHECK(!map.isComplete()); + MemberSet members = list_of(MemberId(0)); + map.configChange(members); + BOOST_CHECK(!map.isComplete()); + map.received(MemberId(0), newcomerStatus()); + BOOST_CHECK(map.isComplete()); + BOOST_CHECK(map.getElders().empty()); + BOOST_CHECK(!map.isUpdateNeeded()); +} + +QPID_AUTO_TEST_CASE(testJoinExistingCluster) { + // Single member 0 joins existing cluster 1,2 + InitialStatusMap map(MemberId(0)); + MemberSet members = list_of(MemberId(0))(MemberId(1))(MemberId(2)); + map.configChange(members); + BOOST_CHECK(map.isResendNeeded()); + BOOST_CHECK(!map.isComplete()); + map.received(MemberId(0), newcomerStatus()); + map.received(MemberId(1), activeStatus()); + BOOST_CHECK(!map.isComplete()); + map.received(MemberId(2), activeStatus()); + BOOST_CHECK(map.isComplete()); + BOOST_CHECK_EQUAL(map.getElders(), list_of<MemberId>(1)(2)); + BOOST_CHECK(map.isUpdateNeeded()); +} + +QPID_AUTO_TEST_CASE(testMultipleFirstInCluster) { + // Multiple members 0,1,2 join at same time. + InitialStatusMap map(MemberId(1)); // self is 1 + MemberSet members = list_of(MemberId(0))(MemberId(1))(MemberId(2)); + map.configChange(members); + BOOST_CHECK(map.isResendNeeded()); + + // All new members + map.received(MemberId(0), newcomerStatus()); + map.received(MemberId(1), newcomerStatus()); + map.received(MemberId(2), newcomerStatus()); + BOOST_CHECK(!map.isResendNeeded()); + BOOST_CHECK(map.isComplete()); + BOOST_CHECK_EQUAL(map.getElders(), list_of(MemberId(2))); + BOOST_CHECK(!map.isUpdateNeeded()); +} + +QPID_AUTO_TEST_CASE(testMultipleJoinExisting) { + // Multiple members 1,2,3 join existing cluster containing 0. + InitialStatusMap map(MemberId(2)); // self is 2 + MemberSet members = list_of(MemberId(0))(MemberId(1))(MemberId(2))(MemberId(3)); + map.configChange(members); + BOOST_CHECK(map.isResendNeeded()); + + map.received(MemberId(1), newcomerStatus()); + map.received(MemberId(2), newcomerStatus()); + map.received(MemberId(3), newcomerStatus()); + map.received(MemberId(0), activeStatus()); + BOOST_CHECK(!map.isResendNeeded()); + BOOST_CHECK(map.isComplete()); + BOOST_CHECK_EQUAL(map.getElders(), list_of(MemberId(0))(MemberId(3))); + BOOST_CHECK(map.isUpdateNeeded()); +} + +QPID_AUTO_TEST_CASE(testMembersLeave) { + // Test that map completes if members leave rather than send status. + InitialStatusMap map(MemberId(0)); + map.configChange(list_of(MemberId(0))(MemberId(1))(MemberId(2))); + map.received(MemberId(0), newcomerStatus()); + map.received(MemberId(1), activeStatus()); + BOOST_CHECK(!map.isComplete()); + map.configChange(list_of(MemberId(0))(MemberId(1))); // 2 left + BOOST_CHECK(map.isComplete()); + BOOST_CHECK_EQUAL(map.getElders(), list_of(MemberId(1))); +} + +QPID_AUTO_TEST_CASE(testInteveningConfig) { + // Multiple config changes arrives before we complete the map. + InitialStatusMap map(MemberId(0)); + + map.configChange(list_of<MemberId>(0)(1)); + BOOST_CHECK(map.isResendNeeded()); + map.received(MemberId(0), newcomerStatus()); + BOOST_CHECK(!map.isComplete()); + BOOST_CHECK(!map.isResendNeeded()); + // New member 2 joins before we receive 1 + map.configChange(list_of<MemberId>(0)(1)(2)); + BOOST_CHECK(!map.isComplete()); + BOOST_CHECK(map.isResendNeeded()); + map.received(1, activeStatus()); + map.received(2, newcomerStatus()); + // We should not be complete as we haven't received 0 since new member joined + BOOST_CHECK(!map.isComplete()); + BOOST_CHECK(!map.isResendNeeded()); + + map.received(0, newcomerStatus()); + BOOST_CHECK(map.isComplete()); + BOOST_CHECK_EQUAL(map.getElders(), list_of<MemberId>(1)); +} + +QPID_AUTO_TEST_SUITE_END() + +}} // namespace qpid::tests diff --git a/cpp/src/tests/cluster.mk b/cpp/src/tests/cluster.mk index 961d65f319..f33f87ee62 100644 --- a/cpp/src/tests/cluster.mk +++ b/cpp/src/tests/cluster.mk @@ -75,9 +75,10 @@ cluster_test_SOURCES = \ ForkedBroker.h \ ForkedBroker.cpp \ PartialFailure.cpp \ - ClusterFailover.cpp + ClusterFailover.cpp \ + InitialStatusMap.cpp -cluster_test_LDADD=$(lib_client) $(lib_broker) -lboost_unit_test_framework +cluster_test_LDADD=$(lib_client) $(lib_broker) ../cluster.la -lboost_unit_test_framework qpidtest_SCRIPTS += run_cluster_tests cluster_tests.py run_long_cluster_tests long_cluster_tests.py testlib.py cluster_tests.fail diff --git a/cpp/src/tests/cluster_test.cpp b/cpp/src/tests/cluster_test.cpp index eb6d98eced..c2683727cf 100644 --- a/cpp/src/tests/cluster_test.cpp +++ b/cpp/src/tests/cluster_test.cpp @@ -54,11 +54,6 @@ #include <algorithm> #include <iterator> -namespace std { // ostream operators in std:: namespace -template <class T> -ostream& operator<<(ostream& o, const std::set<T>& s) { return seqPrint(o, s); } -} - using namespace std; using namespace qpid; using namespace qpid::cluster; diff --git a/cpp/src/tests/test_tools.h b/cpp/src/tests/test_tools.h index 832c04af04..4174751173 100644 --- a/cpp/src/tests/test_tools.h +++ b/cpp/src/tests/test_tools.h @@ -26,6 +26,7 @@ #include <boost/regex.hpp> #include <boost/assign/list_of.hpp> #include <vector> +#include <set> #include <ostream> // Print a sequence @@ -43,14 +44,17 @@ bool seqEqual(const T& a, const U& b) { return (i == a.end()) && (j == b.end()); } -// ostream and == operators so we can compare vectors and boost::assign::list_of -// with BOOST_CHECK_EQUALS +// ostream and == operators so we can compare vectors and sets with +// boost::assign::list_of with BOOST_CHECK_EQUALS namespace std { // In namespace std so boost can find them. template <class T> ostream& operator<<(ostream& o, const vector<T>& v) { return seqPrint(o, v); } template <class T> +ostream& operator<<(ostream& o, const set<T>& v) { return seqPrint(o, v); } + +template <class T> ostream& operator<<(ostream& o, const boost::assign_detail::generic_list<T>& l) { return seqPrint(o, l); } template <class T> @@ -58,6 +62,12 @@ bool operator == (const vector<T>& a, const boost::assign_detail::generic_list<T template <class T> bool operator == (const boost::assign_detail::generic_list<T>& b, const vector<T>& a) { return seqEqual(a, b); } + +template <class T> +bool operator == (const set<T>& a, const boost::assign_detail::generic_list<T>& b) { return seqEqual(a, b); } + +template <class T> +bool operator == (const boost::assign_detail::generic_list<T>& b, const set<T>& a) { return seqEqual(a, b); } } namespace qpid { |