diff options
author | Alan Conway <aconway@apache.org> | 2007-06-26 02:11:55 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2007-06-26 02:11:55 +0000 |
commit | e6566439f627e375f12f77044819bbb37b585348 (patch) | |
tree | 18c52172d536b53df57e82a274a31bcfabc35f7b /cpp/src/tests | |
parent | 87c376ebc8fe6af86dc8aef8dcec03510ff5dcc0 (diff) | |
download | qpid-python-e6566439f627e375f12f77044819bbb37b585348.tar.gz |
2007-06-25 <aconway@redhat.com>
Cluster class implementing cluster membership map.
* src/qpid/cluster/Cluster.cpp: Cluster membership implementation.
* src/qpid/cluster/Cpg.cpp: Support for boost::function callbacks.
* src/tests/Url.cpp: Implements AMQP-95 URL format.
* xml/cluster.xml: Cluster join method.
Build/packaging
* README: Remove mention of openais till clustering is functional.
For now it is optional and we depend on an unpackaged version.
* configure.ac: Check openais has cpg_local_get().
* Makefile.am: Added cluster.xml to EXTRA_DIST.
* src/generate.sh: add cluster.xml to codegen.
* src/tests/Makefile.am:
- Generate individual "sudo -u ais" wrappers for openais tests.
- Drop "unit" directory, all unit tests in "tests" directory
Minor changes:
* src/qpid/sys/posix/Socket.cpp:
* src/qpid/sys/posix/PosixAcceptor.cpp:
* src/qpid/sys/posix/EventChannelAcceptor.cpp:
* src/qpid/sys/apr/APRAcceptor.cpp:
* src/qpid/sys/Acceptor.h (getHost): Added getHost()
* src/tests/.valgrind.supp-default: Suppress benign valgrind
warning in libcpg.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@550658 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/tests')
-rw-r--r-- | cpp/src/tests/.valgrind.supp-default | 9 | ||||
-rw-r--r-- | cpp/src/tests/Cluster.cpp | 72 | ||||
-rw-r--r-- | cpp/src/tests/Cluster.h | 83 | ||||
-rw-r--r-- | cpp/src/tests/Cpg.cpp (renamed from cpp/src/tests/unit/Cpg.cpp) | 80 | ||||
-rw-r--r-- | cpp/src/tests/Makefile.am | 53 | ||||
-rw-r--r-- | cpp/src/tests/Url.cpp (renamed from cpp/src/tests/unit/Url.cpp) | 1 | ||||
-rwxr-xr-x | cpp/src/tests/ais_unit_tests | 2 | ||||
-rw-r--r-- | cpp/src/tests/cluster.mk | 38 | ||||
-rw-r--r-- | cpp/src/tests/logging.cpp (renamed from cpp/src/tests/unit/logging.cpp) | 1 | ||||
-rwxr-xr-x | cpp/src/tests/run_test | 6 | ||||
-rw-r--r-- | cpp/src/tests/test_tools.h (renamed from cpp/src/tests/unit/test_tools.h) | 5 |
11 files changed, 272 insertions, 78 deletions
diff --git a/cpp/src/tests/.valgrind.supp-default b/cpp/src/tests/.valgrind.supp-default index 8b13789179..21fa58db45 100644 --- a/cpp/src/tests/.valgrind.supp-default +++ b/cpp/src/tests/.valgrind.supp-default @@ -1 +1,10 @@ +{ + Benign error in libcpg. + + Memcheck:Param + socketcall.sendmsg(msg.msg_iov[i]) + obj:*/libpthread-2.5.so + obj:*/libcpg.so.2.0.0 +} + diff --git a/cpp/src/tests/Cluster.cpp b/cpp/src/tests/Cluster.cpp new file mode 100644 index 0000000000..ed50cc5d7b --- /dev/null +++ b/cpp/src/tests/Cluster.cpp @@ -0,0 +1,72 @@ +/* + * + * 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. + * + */ + +#define BOOST_AUTO_TEST_MAIN // Must come before #include<boost/test/*> +#include <boost/test/auto_unit_test.hpp> +#include "test_tools.h" +#include "Cluster.h" +#include "qpid/framing/ChannelOkBody.h" +#include "qpid/framing/BasicGetOkBody.h" + + + +static const ProtocolVersion VER; + +/** Verify membership ind a cluster with one member. */ +BOOST_AUTO_TEST_CASE(clusterOne) { + VectorFrameHandler received; + Cluster cluster("Test", "amqp:one:1", received, VER); + AMQFrame frame(VER, 1, new ChannelOkBody(VER)); + + cluster.handle(frame); + BOOST_REQUIRE(received.waitFor(1)); + BOOST_CHECK_EQUAL(1u, cluster.size()); + Cluster::MemberList members = cluster.getMembers(); + BOOST_CHECK_EQUAL(1u, members.size()); + BOOST_REQUIRE_EQUAL(members.front()->url, "amqp:one:1"); + BOOST_CHECK_EQUAL(1u, received.size()); + BOOST_CHECK_TYPEID_EQUAL(ChannelOkBody, *received[0].getBody()); +} + +/** Fork a process to verify membership in a cluster with two members */ +BOOST_AUTO_TEST_CASE(clusterTwo) { + VectorFrameHandler received; + pid_t pid=fork(); + BOOST_REQUIRE(pid >= 0); + if (pid) { // Parent + TestCluster cluster("Test", "amqp::1", received, VER); + BOOST_REQUIRE(cluster.waitFor(2)); + + // Exchange frames with child. + AMQFrame frame(VER, 1, new ChannelOkBody(VER)); + cluster.handle(frame); + BOOST_REQUIRE(received.waitFor(2)); + BOOST_CHECK_TYPEID_EQUAL(ChannelOkBody, *received[0].getBody()); + BOOST_CHECK_TYPEID_EQUAL(BasicGetOkBody, *received[1].getBody()); + + // Wait for child to exit. + int status; + BOOST_CHECK_EQUAL(::wait(&status), pid); + BOOST_CHECK_EQUAL(0, status); + BOOST_CHECK(cluster.waitFor(1)); + BOOST_CHECK_EQUAL(1u, cluster.size()); + } + else { // Child + BOOST_REQUIRE(execl("Cluster_child", "Cluster_child", NULL)); + } +} diff --git a/cpp/src/tests/Cluster.h b/cpp/src/tests/Cluster.h new file mode 100644 index 0000000000..7ca5445e10 --- /dev/null +++ b/cpp/src/tests/Cluster.h @@ -0,0 +1,83 @@ +#ifndef CLUSTER_H +#define CLUSTER_H + +/* + * + * 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 "qpid/cluster/Cluster.h" +#include "qpid/framing/AMQFrame.h" +#include "qpid/framing/ChannelOkBody.h" +#include "qpid/framing/BasicGetOkBody.h" +#include "qpid/log/Logger.h" +#include <iostream> +#include <vector> + +/** + * Definitions for the Cluster.cpp and Cluster_child.cpp child program. + */ + +// using namespace in header file is bad manners, but this is strictly for +// the tests. +using namespace std; +using namespace qpid; +using namespace qpid::cluster; +using namespace qpid::framing; +using namespace qpid::sys; + +struct TestCluster : public Cluster { + TestCluster(const std::string& name, + const std::string& url, + framing::FrameHandler& next, + framing::ProtocolVersion ver) : Cluster(name,url,next, ver) {} + + /** Wait for the cluster to be of expected size (exactly) */ + bool waitFor(size_t n) { + Mutex::ScopedLock l(lock); + AbsTime deadline(now(),2*TIME_SEC); + while(size() != n && lock.wait(deadline)) + ; + return size() == n; + } +}; + +struct VectorFrameHandler : + public std::vector<AMQFrame>, public FrameHandler, public Monitor + +{ + void handle(AMQFrame& f) { + ScopedLock l(*this); + push_back(f); + notifyAll(); + } + + /** Wait for vector to reach size n exactly */ + bool waitFor(size_t n) { + ScopedLock l(*this); + AbsTime deadline(now(), 1*TIME_SEC); + while (size() != n && wait(deadline)) + ; + return size() == n; + } +}; + + +// namespace + + + +#endif /*!CLUSTER_H*/ diff --git a/cpp/src/tests/unit/Cpg.cpp b/cpp/src/tests/Cpg.cpp index 74c6532338..97b829ea63 100644 --- a/cpp/src/tests/unit/Cpg.cpp +++ b/cpp/src/tests/Cpg.cpp @@ -17,8 +17,11 @@ */ #define BOOST_AUTO_TEST_MAIN // Must come before #include<boost/test/*> +#include <boost/test/auto_unit_test.hpp> #include "test_tools.h" #include "qpid/cluster/Cpg.h" +#include "qpid/framing/AMQBody.h" +#include <boost/bind.hpp> #include <string> #include <iostream> #include <iterator> @@ -27,6 +30,7 @@ using namespace std; using namespace qpid::cluster; +using namespace qpid::framing; // For debugging: op << for CPG types. @@ -47,51 +51,57 @@ ostream& operator<<(ostream& o, const pair<T*, int>& array) { return o; } -const string testGroup("foo"); -vector<string> delivered; -vector<int> configChanges; +struct Callback { + Callback(const string group_) : group(group_) {} + string group; + vector<string> delivered; + vector<int> configChanges; -void testDeliver ( - cpg_handle_t /*handle*/, - struct cpg_name *group, - uint32_t /*nodeid*/, - uint32_t /*pid*/, - void* msg, - int msg_len) -{ - BOOST_CHECK_EQUAL(testGroup, Cpg::str(*group)); - delivered.push_back(string((char*)msg,msg_len)); -} + void deliver ( + cpg_handle_t /*handle*/, + struct cpg_name *grp, + uint32_t /*nodeid*/, + uint32_t /*pid*/, + void* msg, + int msg_len) + { + BOOST_CHECK_EQUAL(group, Cpg::str(*grp)); + delivered.push_back(string((char*)msg,msg_len)); + } -void testConfigChange( - cpg_handle_t /*handle*/, - struct cpg_name *group, - struct cpg_address */*members*/, int nMembers, - struct cpg_address */*left*/, int /*nLeft*/, - struct cpg_address */*joined*/, int /*nJoined*/ -) -{ - BOOST_CHECK_EQUAL(testGroup, Cpg::str(*group)); - configChanges.push_back(nMembers); -} + void configChange( + cpg_handle_t /*handle*/, + struct cpg_name *grp, + struct cpg_address */*members*/, int nMembers, + struct cpg_address */*left*/, int /*nLeft*/, + struct cpg_address */*joined*/, int /*nJoined*/ + ) + { + BOOST_CHECK_EQUAL(group, Cpg::str(*grp)); + configChanges.push_back(nMembers); + } +}; -BOOST_AUTO_TEST_CASE(basic) { +BOOST_AUTO_TEST_CASE(Cpg_basic) { // Verify basic functionality of cpg. This will catch any // openais configuration or permission errors. - // - Cpg cpg(&testDeliver, &testConfigChange); + // Cpg::Name group("foo"); + Callback cb(group.str()); + Cpg::DeliverFn deliver=boost::bind(&Callback::deliver, &cb, _1, _2, _3, _4, _5, _6); + Cpg::ConfigChangeFn reconfig=boost::bind<void>(&Callback::configChange, &cb, _1, _2, _3, _4, _5, _6, _7, _8); + Cpg cpg(deliver, reconfig); cpg.join(group); iovec iov = { (void*)"Hello!", 6 }; cpg.mcast(group, &iov, 1); cpg.leave(group); + cpg.dispatchSome(); - cpg.dispatch(CPG_DISPATCH_ONE); // Wait for at least one. - cpg.dispatch(CPG_DISPATCH_ALL); - BOOST_REQUIRE_EQUAL(1u, delivered.size()); - BOOST_CHECK_EQUAL("Hello!", delivered.front()); - BOOST_REQUIRE_EQUAL(2u, configChanges.size()); - BOOST_CHECK_EQUAL(1, configChanges[0]); - BOOST_CHECK_EQUAL(0, configChanges[1]); + BOOST_REQUIRE_EQUAL(1u, cb.delivered.size()); + BOOST_CHECK_EQUAL("Hello!", cb.delivered.front()); + BOOST_REQUIRE_EQUAL(2u, cb.configChanges.size()); + BOOST_CHECK_EQUAL(1, cb.configChanges[0]); + BOOST_CHECK_EQUAL(0, cb.configChanges[1]); } + diff --git a/cpp/src/tests/Makefile.am b/cpp/src/tests/Makefile.am index 76d675ee12..ab772ea744 100644 --- a/cpp/src/tests/Makefile.am +++ b/cpp/src/tests/Makefile.am @@ -1,25 +1,34 @@ AM_CXXFLAGS = $(WARNING_CFLAGS) $(CPPUNIT_CXXFLAGS) $(APR_CXXFLAGS) INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../gen -I$(top_builddir)/src/gen +abs_builddir=@abs_builddir@ +extra_libs = $(CPPUNIT_LIBS) +lib_client = $(abs_builddir)/../libqpidclient.la +lib_common = $(abs_builddir)/../libqpidcommon.la +lib_broker = $(abs_builddir)/../libqpidbroker.la + # -# Unit test programs. +# Initialize variables that are incremented with += # -UNIT_TESTS= +check_PROGRAMS= +unit_progs= +unit_wrappers= -UNIT_TESTS+=logging -logging_SOURCES=unit/logging.cpp unit/test_tools.h -logging_LDADD=-lboost_unit_test_framework -lboost_regex $(lib_common) +# +# Unit test programs. +# +unit_progs+=logging +logging_SOURCES=logging.cpp test_tools.h +logging_LDADD=-lboost_unit_test_framework -lboost_regex $(lib_common) -UNIT_TESTS+=Url -Url_SOURCES=unit/Url.cpp unit/test_tools.h -Url_LDADD=-lboost_unit_test_framework $(lib_common) +unit_progs+=Url +Url_SOURCES=Url.cpp test_tools.h +Url_LDADD=-lboost_unit_test_framework $(lib_common) -if CLUSTER include cluster.mk -endif # NB: CppUnit test libraries below will be migrated to boost test programs. -# UNIT_TESTS+= ... +# # Unit tests broker_unit_tests = \ @@ -74,7 +83,7 @@ testprogs = \ topic_publisher -check_PROGRAMS = $(UNIT_TESTS) $(AIS_UNIT_TESTS) $(testprogs) interop_runner +check_PROGRAMS += $(unit_progs) $(testprogs) interop_runner # FIXME aconway 2007-05-30: TESTS_ENVIRONMENT should have ./run_test # as below to run valgrind on all test programs. @@ -83,13 +92,12 @@ check_PROGRAMS = $(UNIT_TESTS) $(AIS_UNIT_TESTS) $(testprogs) interop_runner #TESTS_ENVIRONMENT = VALGRIND=$(VALGRIND) srcdir=$(srcdir) ./run_test TESTS_ENVIRONMENT = VALGRIND=$(VALGRIND) srcdir=$(srcdir) -SYSTEM_TESTS = client_test quick_topictest -TESTS = $(UNIT_TESTS) run-unit-tests $(RUN_AIS_TESTS) start_broker $(SYSTEM_TESTS) python_tests kill_broker daemon_test +system_tests = client_test quick_topictest +TESTS = dummy_test $(unit_progs) $(unit_wrappers) run-unit-tests start_broker $(system_tests) python_tests kill_broker daemon_test EXTRA_DIST = \ test_env run_test \ run-unit-tests start_broker python_tests kill_broker daemon_test \ - ais_unit_tests \ quick_topictest \ topictest \ .valgrind.supp-default \ @@ -106,12 +114,6 @@ check_LTLIBRARIES += libdlclose_noop.la libdlclose_noop_la_LDFLAGS = -module -rpath /home/aconway/svn/qpid/cpp/tests libdlclose_noop_la_SOURCES = dlclose_noop.c -abs_builddir = @abs_builddir@ -extra_libs = $(CPPUNIT_LIBS) -lib_client = $(abs_builddir)/../libqpidclient.la -lib_common = $(abs_builddir)/../libqpidcommon.la -lib_broker = $(abs_builddir)/../libqpidbroker.la - gen.mk: Makefile.am ( \ for i in $(testprogs); do \ @@ -131,11 +133,14 @@ gen.mk: Makefile.am > $@-t mv $@-t $@ -check: .valgrindrc .valgrind.supp - check-unit: $(MAKE) check TESTS=$(UNIT_TESTS) run-unit-tests +# Dummy test to force necessary test files to be generated. +dummy_test: .valgrind.supp .valgrindrc + { echo "#!/bin/sh"; echo "# Dummy test, does nothing. "; } > $@ + chmod a+x $@ + # Create a copy so that can be modified without risk of committing the changes. .valgrindrc: .valgrindrc-default cp $^ $@ @@ -147,7 +152,7 @@ check-unit: # ltmain invocations, one may corrupt the temporaries of the other. .NOTPARALLEL: -CLEANFILES=valgrind.out qpidd.log .valgrindrc .valgrind.supp +CLEANFILES=valgrind.out qpidd.log .valgrindrc .valgrind.supp dummy_test $(unit_wrappers) MAINTAINERCLEANFILES=gen.mk interop_runner_SOURCES = \ diff --git a/cpp/src/tests/unit/Url.cpp b/cpp/src/tests/Url.cpp index a8b415e641..09aabb80b3 100644 --- a/cpp/src/tests/unit/Url.cpp +++ b/cpp/src/tests/Url.cpp @@ -17,6 +17,7 @@ */ #define BOOST_AUTO_TEST_MAIN // Must come before #include<boost/test/*> +#include <boost/test/auto_unit_test.hpp> #include "test_tools.h" #include "qpid/Url.h" #include <boost/assign.hpp> diff --git a/cpp/src/tests/ais_unit_tests b/cpp/src/tests/ais_unit_tests deleted file mode 100755 index 9758891891..0000000000 --- a/cpp/src/tests/ais_unit_tests +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -make check-ais diff --git a/cpp/src/tests/cluster.mk b/cpp/src/tests/cluster.mk index 489eec748e..fd8f789363 100644 --- a/cpp/src/tests/cluster.mk +++ b/cpp/src/tests/cluster.mk @@ -1,23 +1,35 @@ -#-*-Makefile-*- +if CLUSTER # Cluster tests makefile fragment, to be included in Makefile.am # lib_cluster = $(abs_builddir)/../libqpidcluster.la -# -# AIS_UNIT_TESTS must be called with gid=ais. They are run -# separately under sudo -u ais. -# -AIS_UNIT_TESTS= -AIS_UNIT_TESTS+=Cpg -Cpg_SOURCES=unit/Cpg.cpp -Cpg_LDADD=-lboost_unit_test_framework $(lib_cluster) - -RUN_AIS_TESTS=ais_unit_tests # Run ais unit tests via check-ais. +# NOTE: Programs using the openais library must be run with gid=ais +# Such programs are built as *.ais, with a wrapper script *.sh that +# runs the program under sudo -u ais. +# +# Rule to generate wrappers. # The chmod is a horrible hack to allow libtools annoying wrapers to # relink the executable when run as user ais. -check-ais: $(AIS_UNIT_TESTS) +.ais.sh: + echo sudo -u ais env VALGRIND=$(VALGRIND) srcdir=$(srcdir) $(srcdir)/run_test ./$< >$@; chmod a+x $@ chmod a+rwx . .libs - sudo -u ais $(MAKE) check TESTS=$(AIS_UNIT_TESTS) +# Cluster tests. +# +check_PROGRAMS+=Cpg.ais +Cpg_ais_SOURCES=Cpg.cpp +Cpg_ais_LDADD=$(lib_cluster) -lboost_unit_test_framework +unit_wrappers+=Cpg.sh + +check_PROGRAMS+=Cluster.ais +Cluster_ais_SOURCES=Cluster.cpp Cluster.h +Cluster_ais_LDADD=$(lib_cluster) -lboost_unit_test_framework +unit_wrappers+=Cluster.sh + +check_PROGRAMS+=Cluster_child +Cluster_child_SOURCES=Cluster_child.cpp Cluster.h +Cluster_child_LDADD=$(lib_cluster) -lboost_test_exec_monitor + +endif diff --git a/cpp/src/tests/unit/logging.cpp b/cpp/src/tests/logging.cpp index c80bf7b337..ebe8f4d6e8 100644 --- a/cpp/src/tests/unit/logging.cpp +++ b/cpp/src/tests/logging.cpp @@ -17,6 +17,7 @@ */ #define BOOST_AUTO_TEST_MAIN // Must come before #include<boost/test/*> +#include <boost/test/auto_unit_test.hpp> #include "test_tools.h" #include "qpid/log/Logger.h" #include "qpid/log/Options.h" diff --git a/cpp/src/tests/run_test b/cpp/src/tests/run_test index ef608e55ca..bfd6991481 100755 --- a/cpp/src/tests/run_test +++ b/cpp/src/tests/run_test @@ -22,7 +22,7 @@ vg_check() grep -E '^==[0-9]+== ERROR SUMMARY:' $VG_LOG > /dev/null || \ vg_failed "No valgrind ERROR SUMMARY line in $$vg_failed." # Ensure that the number of errors is 0. - grep -E '^==[0-9]+== ERROR SUMMARY: [^0] ' $VG_LOG > /dev/null && \ + grep -E '^==[0-9]+== ERROR SUMMARY: [^0]' $VG_LOG > /dev/null && \ vg_failed "Valgrind reported errors in $vg_out; see above." # Check for leaks. grep -E '^==[0-9]+== +.* lost: [^0]' $VG_LOG && \ @@ -41,14 +41,14 @@ if grep -l "^# Generated by .*libtool" "$1" >/dev/null 2>&1; then # This is a libtool "executable". Valgrind it if VALGRIND specified. test -n "$VALGRIND" && VALGRIND="$VALGRIND --log-file-exactly=$VG_LOG --" # Hide output unless there's an error. - libtool --mode=execute $VALGRIND "$@" >$TEST_LOG 2>&1 || { + libtool --mode=execute "$VALGRIND" "$@" >$TEST_LOG 2>&1 || { ERROR=$? cat $TEST_LOG } test -n "$VALGRIND" && vg_check else # This is a non-libtool shell script, just execute it. - "$@" + exec "$@" fi if test -z "$ERROR"; then diff --git a/cpp/src/tests/unit/test_tools.h b/cpp/src/tests/test_tools.h index faa198af9a..e564b9a473 100644 --- a/cpp/src/tests/unit/test_tools.h +++ b/cpp/src/tests/test_tools.h @@ -19,7 +19,7 @@ * */ -#include <boost/test/auto_unit_test.hpp> +#include <boost/test/test_tools.hpp> #include <boost/assign/list_of.hpp> #include <boost/regex.hpp> #include <vector> @@ -49,5 +49,8 @@ inline bool regexPredicate(const std::string& re, const std::string& text) { #define BOOST_CHECK_REGEX(re, text) \ BOOST_CHECK_PREDICATE(regexPredicate, (re)(text)) +/** Check if types of two objects (as given by typeinfo::name()) match. */ +#define BOOST_CHECK_TYPEID_EQUAL(a,b) BOOST_CHECK_EQUAL(typeid(a).name(),typeid(b).name()) + #endif /*!TEST_TOOLS_H*/ |