summaryrefslogtreecommitdiff
path: root/qpid/cpp/src/tests/ClusterMapTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/cpp/src/tests/ClusterMapTest.cpp')
-rw-r--r--qpid/cpp/src/tests/ClusterMapTest.cpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/qpid/cpp/src/tests/ClusterMapTest.cpp b/qpid/cpp/src/tests/ClusterMapTest.cpp
new file mode 100644
index 0000000000..344dd71eb5
--- /dev/null
+++ b/qpid/cpp/src/tests/ClusterMapTest.cpp
@@ -0,0 +1,191 @@
+/*
+ *
+ * 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/ClusterMap.h"
+#include "qpid/framing/ClusterMapBody.h"
+#include "qpid/framing/Buffer.h"
+#include "qpid/Url.h"
+#include <boost/assign.hpp>
+
+QPID_AUTO_TEST_SUITE(CluterMapTest)
+
+using namespace std;
+using namespace qpid;
+using namespace cluster;
+using namespace framing;
+
+MemberId id(int i) { return MemberId(i,i); }
+
+Url url(const char* host) { return Url(TcpAddress(host)); }
+
+QPID_AUTO_TEST_CASE(testNotice) {
+ ClusterMap m;
+ BOOST_CHECK(!m.urlNotice(id(0), url("0-ready"))); // id(0) member, no dump.
+ BOOST_CHECK(m.isMember(id(0)));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 0);
+ BOOST_CHECK_EQUAL(m.memberCount(), 1);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+
+ BOOST_CHECK_EQUAL(id(0), m.urlNotice(id(1), url("1-dump"))); // Newbie, needs dump
+ BOOST_CHECK(m.isMember(id(0)));
+ BOOST_CHECK(m.isDumpee(id(1)));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 1);
+ BOOST_CHECK_EQUAL(m.dumps(id(1)), 0);
+ BOOST_CHECK_EQUAL(m.memberCount(), 1);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 1);
+
+ BOOST_CHECK(!m.urlNotice(id(1), url("1-ready"))); // id(1) is ready.
+ BOOST_CHECK(m.isMember(id(0)));
+ BOOST_CHECK(m.isMember(id(1)));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 0);
+ BOOST_CHECK_EQUAL(m.dumps(id(1)), 0);
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+
+ BOOST_CHECK_EQUAL(id(0), m.urlNotice(id(2), url("2-dump"))); // id(2) needs dump
+ BOOST_CHECK(m.isDumpee(id(2)));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 1);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 1);
+
+ BOOST_CHECK_EQUAL(id(1), m.urlNotice(id(3), url("3-dump"))); // 0 busy, dump to id(1).
+ BOOST_CHECK(m.isDumpee(id(3)));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 1);
+ BOOST_CHECK_EQUAL(m.dumps(id(1)), 1);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 2);
+
+ BOOST_CHECK_EQUAL(id(0), m.urlNotice(id(4), url("4-dump"))); // Equally busy, 0 is first on list.
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 2);
+ BOOST_CHECK_EQUAL(m.dumps(id(1)), 1);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 3);
+
+ // My dumpees both complete
+ BOOST_CHECK(!m.urlNotice(id(2), url("2-ready")));
+ BOOST_CHECK(!m.urlNotice(id(4), url("4-ready")));
+ BOOST_CHECK(m.isMember(id(2)));
+ BOOST_CHECK(m.isMember(id(4)));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 0);
+ BOOST_CHECK_EQUAL(m.dumps(id(1)), 1);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 1);
+
+ // Final dumpee completes.
+ BOOST_CHECK(!m.urlNotice(id(3), url("3-ready")));
+ BOOST_CHECK(m.isMember(id(3)));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 0);
+ BOOST_CHECK_EQUAL(m.dumps(id(1)), 0);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+
+}
+
+QPID_AUTO_TEST_CASE(testLeave) {
+ ClusterMap m;
+ BOOST_CHECK(!m.urlNotice(id(0), url("0-ready")));
+ BOOST_CHECK_EQUAL(id(0), m.urlNotice(id(1), url("1-dump")));
+ BOOST_CHECK(!m.urlNotice(id(1), url("1-ready")));
+ BOOST_CHECK_EQUAL(id(0), m.urlNotice(id(2), url("2-dump")));
+ BOOST_CHECK(!m.urlNotice(id(2), url("2-ready")));
+ BOOST_CHECK_EQUAL(m.memberCount(), 3);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+
+ m.leave(id(1));
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+ BOOST_CHECK(m.isMember(id(0)));
+ BOOST_CHECK(m.isMember(id(2)));
+
+ BOOST_CHECK_EQUAL(id(0), m.urlNotice(id(4), url("4-dump")));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 1);
+ BOOST_CHECK(m.isDumpee(id(4)));
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 1);
+
+ m.dumpFailed(id(4)); // Dumper detected a failure.
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 0);
+ BOOST_CHECK(!m.isDumpee(id(4)));
+ BOOST_CHECK(!m.isMember(id(4)));
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+
+ m.leave(id(4)); // Dumpee leaves, no-op since we already know it failed.
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+
+ BOOST_CHECK_EQUAL(id(0), m.urlNotice(id(5), url("5-dump")));
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 1);
+ BOOST_CHECK(m.isDumpee(id(5)));
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 1);
+
+ m.leave(id(5)); // Dumpee detects failure and leaves cluster.
+ BOOST_CHECK_EQUAL(m.dumps(id(0)), 0);
+ BOOST_CHECK(!m.isDumpee(id(5)));
+ BOOST_CHECK(!m.isMember(id(5)));
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+
+ m.dumpFailed(id(5)); // Dumper reports failure - no op, we already know.
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 0);
+}
+
+QPID_AUTO_TEST_CASE(testToControl) {
+ ClusterMap m;
+ m.urlNotice(id(0), url("0"));
+ m.urlNotice(id(1), url("1dump"));
+ m.urlNotice(id(1), url("1"));
+ m.urlNotice(id(2), url("2dump"));
+ m.urlNotice(id(3), url("3dump"));
+ m.urlNotice(id(4), url("4dump"));
+
+ BOOST_CHECK_EQUAL(m.memberCount(), 2);
+ BOOST_CHECK_EQUAL(m.dumpeeCount(), 3);
+
+ ClusterMapBody b = m.toControl();
+
+ BOOST_CHECK_EQUAL(b.getMembers().count(), 2);
+ BOOST_CHECK_EQUAL(b.getMembers().getString(id(0).str()), url("0").str());
+ BOOST_CHECK_EQUAL(b.getMembers().getString(id(1).str()), url("1").str());
+
+ BOOST_CHECK_EQUAL(b.getDumpees().count(), 3);
+ BOOST_CHECK_EQUAL(b.getDumpees().getString(id(2).str()), url("2dump").str());
+ BOOST_CHECK_EQUAL(b.getDumpees().getString(id(3).str()), url("3dump").str());
+ BOOST_CHECK_EQUAL(b.getDumpees().getString(id(4).str()), url("4dump").str());
+
+ BOOST_CHECK_EQUAL(b.getDumps().count(), 3);
+ BOOST_CHECK_EQUAL(b.getDumps().getString(id(2).str()), id(0).str());
+ BOOST_CHECK_EQUAL(b.getDumps().getString(id(3).str()), id(1).str());
+ BOOST_CHECK_EQUAL(b.getDumps().getString(id(4).str()), id(0).str());
+
+ std::string s(b.size(), '\0');
+ Buffer buf(&s[0], s.size());
+ b.encode(buf);
+
+ ClusterMap m2;
+ m2.fromControl(b);
+ ClusterMapBody b2 = m2.toControl();
+ std::string s2(b2.size(), '\0');
+ Buffer buf2(&s2[0], s2.size());
+ b2.encode(buf2);
+
+ // Verify a round-trip encoding produces identical results.
+ BOOST_CHECK_EQUAL(s,s2);
+}
+
+QPID_AUTO_TEST_SUITE_END()