diff options
author | Alan Conway <aconway@apache.org> | 2009-02-12 15:27:11 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2009-02-12 15:27:11 +0000 |
commit | 0727c97b2c2ac20557692c85b5caffbfa03b6011 (patch) | |
tree | 222cc46220e92399c93e81111565f373fdcfba6e | |
parent | c1ee4f022ef7ad902b66bbd9b31f2a68db5a3a24 (diff) | |
download | qpid-python-0727c97b2c2ac20557692c85b5caffbfa03b6011.tar.gz |
Allow passing extra argv arguments to ClusterFixture.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@743779 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | qpid/cpp/src/tests/ClusterFixture.cpp | 62 | ||||
-rw-r--r-- | qpid/cpp/src/tests/ClusterFixture.h | 33 | ||||
-rw-r--r-- | qpid/cpp/src/tests/ForkedBroker.cpp | 84 | ||||
-rw-r--r-- | qpid/cpp/src/tests/ForkedBroker.h | 70 | ||||
-rw-r--r-- | qpid/cpp/src/tests/Makefile.am | 3 | ||||
-rw-r--r-- | qpid/cpp/src/tests/cluster.mk | 2 |
6 files changed, 146 insertions, 108 deletions
diff --git a/qpid/cpp/src/tests/ClusterFixture.cpp b/qpid/cpp/src/tests/ClusterFixture.cpp index 76c7cd7e2b..4a373e3811 100644 --- a/qpid/cpp/src/tests/ClusterFixture.cpp +++ b/qpid/cpp/src/tests/ClusterFixture.cpp @@ -36,6 +36,7 @@ #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> +#include <boost/assign.hpp> #include <string> #include <iostream> @@ -55,29 +56,34 @@ using qpid::sys::TIME_SEC; using qpid::broker::Broker; using boost::shared_ptr; using qpid::cluster::Cluster; - +using boost::assign::list_of; #include "ClusterFixture.h" -ClusterFixture::ClusterFixture(size_t n, int localIndex_) : name(Uuid(true).str()), localIndex(localIndex_) { +ClusterFixture::ClusterFixture(size_t n, int localIndex_, const Args& args_) + : name(Uuid(true).str()), localIndex(localIndex_), userArgs(args_) +{ add(n); } +ClusterFixture::Args ClusterFixture::makeArgs(const std::string& prefix) { + Args args = list_of<string>("qpidd " __FILE__) + ("--no-module-dir") + ("--load-module=../.libs/cluster.so") + ("--cluster-name")(name) + ("--auth=no") + ("--no-data-dir") + ("--log-prefix")(prefix); + args.insert(args.end(), userArgs.begin(), userArgs.end()); + return args; +} + void ClusterFixture::add() { if (size() != size_t(localIndex)) { // fork a broker process. std::ostringstream os; os << "fork" << size(); std::string prefix = os.str(); - const char* argv[] = { - "qpidd " __FILE__ , - "--no-module-dir", - "--load-module=../.libs/cluster.so", - "--cluster-name", name.c_str(), - "--auth=no", "--no-data-dir", - "--log-prefix", prefix.c_str(), - }; - size_t argc = sizeof(argv)/sizeof(argv[0]); - forkedBrokers.push_back(shared_ptr<ForkedBroker>(new ForkedBroker(argc, argv))); + forkedBrokers.push_back(shared_ptr<ForkedBroker>(new ForkedBroker(makeArgs(prefix)))); push_back(forkedBrokers.back()->getPort()); } else { // Run in this process @@ -96,21 +102,31 @@ Broker::Options parseOpts(size_t argc, const char* argv[]) { } void ClusterFixture::addLocal() { - assert(int(size()) == localIndex || localIndex == -1); - localIndex = size(); - const char* argv[] = { - "qpidd " __FILE__ , - "--load-module=../.libs/cluster.so", - "--cluster-name", name.c_str(), - "--auth=no", "--no-data-dir" - }; - size_t argc = sizeof(argv)/sizeof(argv[0]); + assert(int(size()) == localIndex); ostringstream os; os << "local" << localIndex; + string prefix = os.str(); + Args args(makeArgs(prefix)); + vector<const char*> argv(args.size()); + transform(args.begin(), args.end(), argv.begin(), boost::bind(&string::c_str, _1)); qpid::log::Logger::instance().setPrefix(os.str()); - localBroker.reset(new BrokerFixture(parseOpts(argc, argv))); + localBroker.reset(new BrokerFixture(parseOpts(argv.size(), &argv[0]))); push_back(localBroker->getPort()); forkedBrokers.push_back(shared_ptr<ForkedBroker>()); } +bool ClusterFixture::hasLocal() const { return localIndex >= 0 && size_t(localIndex) < size(); } + +/** Kill a forked broker with sig, or shutdown localBroker if n==0. */ +void ClusterFixture::kill(size_t n, int sig) { + if (n == size_t(localIndex)) + localBroker->broker->shutdown(); + else + forkedBrokers[n]->kill(sig); +} - +/** Kill a broker and suppressing errors from closing connection c. */ +void ClusterFixture::killWithSilencer(size_t n, client::Connection& c, int sig) { + ScopedSuppressLogging sl; + kill(n,sig); + try { c.close(); } catch(...) {} +} diff --git a/qpid/cpp/src/tests/ClusterFixture.h b/qpid/cpp/src/tests/ClusterFixture.h index 1617ce5e5b..d1acfaa9cb 100644 --- a/qpid/cpp/src/tests/ClusterFixture.h +++ b/qpid/cpp/src/tests/ClusterFixture.h @@ -67,37 +67,32 @@ using qpid::cluster::Cluster; * process, all others are forked as children. */ class ClusterFixture : public vector<uint16_t> { - string name; - std::auto_ptr<BrokerFixture> localBroker; - int localIndex; - std::vector<shared_ptr<ForkedBroker> > forkedBrokers; - public: + typedef std::vector<std::string> Args; /** @param localIndex can be -1 meaning don't automatically start a local broker. * A local broker can be started with addLocal(). */ - ClusterFixture(size_t n, int localIndex=0); + ClusterFixture(size_t n, int localIndex=0, const Args& args=Args()); void add(size_t n) { for (size_t i=0; i < n; ++i) add(); } void add(); // Add a broker. - void addLocal(); // Add a local broker. void setup(); - bool hasLocal() const { return localIndex >= 0 && size_t(localIndex) < size(); } + bool hasLocal() const; /** Kill a forked broker with sig, or shutdown localBroker if n==0. */ - void kill(size_t n, int sig=SIGINT) { - if (n == size_t(localIndex)) - localBroker->broker->shutdown(); - else - forkedBrokers[n]->kill(sig); - } + void kill(size_t n, int sig=SIGINT); /** Kill a broker and suppressing errors from closing connection c. */ - void killWithSilencer(size_t n, client::Connection& c, int sig=SIGINT) { - ScopedSuppressLogging sl; - kill(n,sig); - try { c.close(); } catch(...) {} - } + void killWithSilencer(size_t n, client::Connection& c, int sig=SIGINT); + + private: + void addLocal(); // Add a local broker. + Args makeArgs(const std::string& prefix); + string name; + std::auto_ptr<BrokerFixture> localBroker; + int localIndex; + std::vector<shared_ptr<ForkedBroker> > forkedBrokers; + Args userArgs; }; diff --git a/qpid/cpp/src/tests/ForkedBroker.cpp b/qpid/cpp/src/tests/ForkedBroker.cpp new file mode 100644 index 0000000000..2b90068549 --- /dev/null +++ b/qpid/cpp/src/tests/ForkedBroker.cpp @@ -0,0 +1,84 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 "ForkedBroker.h" +#include <boost/bind.hpp> +#include <algorithm> + +ForkedBroker::ForkedBroker(const Args& args) { init(args); } + +ForkedBroker::ForkedBroker(int argc, const char* const argv[]) { init(Args(argv, argc+argv)); } + +ForkedBroker::~ForkedBroker() { + try { kill(); } catch(const std::exception& e) { + QPID_LOG(error, QPID_MSG("Killing forked broker: " << e.what())); + } +} + +void ForkedBroker::kill(int sig) { + if (pid == 0) return; + int savePid = pid; + pid = 0; // Reset pid here in case of an exception. + using qpid::ErrnoException; + if (::kill(savePid, sig) < 0) + throw ErrnoException("kill failed"); + int status; + if (::waitpid(savePid, &status, 0) < 0) + throw ErrnoException("wait for forked process failed"); + if (WEXITSTATUS(status) != 0) + throw qpid::Exception(QPID_MSG("Forked broker exited with: " << WEXITSTATUS(status))); +} + + +void ForkedBroker::init(const Args& userArgs) { + using qpid::ErrnoException; + port = 0; + int pipeFds[2]; + if(::pipe(pipeFds) < 0) throw ErrnoException("Can't create pipe"); + pid = ::fork(); + if (pid < 0) throw ErrnoException("Fork failed"); + if (pid) { // parent + ::close(pipeFds[1]); + FILE* f = ::fdopen(pipeFds[0], "r"); + if (!f) throw ErrnoException("fopen failed"); + if (::fscanf(f, "%d", &port) != 1) { + if (ferror(f)) throw ErrnoException("Error reading port number from child."); + else throw qpid::Exception("EOF reading port number from child."); + } + ::close(pipeFds[0]); + } + else { // child + ::close(pipeFds[0]); + // FIXME aconway 2009-02-12: + int fd = ::dup2(pipeFds[1], 1); // pipe stdout to the parent. + if (fd < 0) throw ErrnoException("dup2 failed"); + const char* prog = "../qpidd"; + Args args(userArgs); + args.push_back("--port=0"); + if (!::getenv("QPID_TRACE") && !::getenv("QPID_LOG_ENABLE")) + args.push_back("--log-enable=error+"); // Keep quiet except for errors. + std::vector<const char*> argv(args.size()); + std::transform(args.begin(), args.end(), argv.begin(), boost::bind(&std::string::c_str, _1)); + argv.push_back(0); + execv(prog, const_cast<char* const*>(&argv[0])); + throw ErrnoException("execv failed"); + } +} diff --git a/qpid/cpp/src/tests/ForkedBroker.h b/qpid/cpp/src/tests/ForkedBroker.h index 5d75c9364d..6f97fbdc09 100644 --- a/qpid/cpp/src/tests/ForkedBroker.h +++ b/qpid/cpp/src/tests/ForkedBroker.h @@ -46,76 +46,18 @@ */ class ForkedBroker { public: - ForkedBroker(std::vector<const char*> argv) { init(argv); } + typedef std::vector<std::string> Args; - ForkedBroker(int argc, const char* const argv[]) { - std::vector<const char*> args(argv, argv+argc); - init(args); - } - - ~ForkedBroker() { - try { kill(); } catch(const std::exception& e) { - QPID_LOG(error, QPID_MSG("Killing forked broker: " << e.what())); - } - } - - void kill(int sig=SIGINT) { - if (pid == 0) return; - int savePid = pid; - pid = 0; // Reset pid here in case of an exception. - using qpid::ErrnoException; - if (::kill(savePid, sig) < 0) - throw ErrnoException("kill failed"); - int status; - if (::waitpid(savePid, &status, 0) < 0) - throw ErrnoException("wait for forked process failed"); - if (WEXITSTATUS(status) != 0) - throw qpid::Exception(QPID_MSG("Forked broker exited with: " << WEXITSTATUS(status))); - } + ForkedBroker(const Args& argv); + ForkedBroker(int argc, const char* const argv[]); + ~ForkedBroker(); + void kill(int sig=SIGINT); uint16_t getPort() { return port; } pid_t getPID() { return pid; } private: - - template <class F> struct OnExit { - F fn; - OnExit(F f) : fn(f) {} - ~OnExit() { fn(); } - }; - - void init(const std::vector<const char*>& args) { - using qpid::ErrnoException; - port = 0; - int pipeFds[2]; - if(::pipe(pipeFds) < 0) throw ErrnoException("Can't create pipe"); - pid = ::fork(); - if (pid < 0) throw ErrnoException("Fork failed"); - if (pid) { // parent - ::close(pipeFds[1]); - FILE* f = ::fdopen(pipeFds[0], "r"); - if (!f) throw ErrnoException("fopen failed"); - if (::fscanf(f, "%d", &port) != 1) { - if (ferror(f)) throw ErrnoException("Error reading port number from child."); - else throw qpid::Exception("EOF reading port number from child."); - } - ::close(pipeFds[0]); - } - else { // child - ::close(pipeFds[0]); - int fd = ::dup2(pipeFds[1], 1); // pipe stdout to the parent. - if (fd < 0) throw ErrnoException("dup2 failed"); - const char* prog = "../qpidd"; - std::vector<const char*> args2(args); - args2.push_back("--port=0"); - args2.push_back("--mgmt-enable=no"); // TODO aconway 2008-07-16: why does mgmt cause problems? - if (!::getenv("QPID_TRACE") && !::getenv("QPID_LOG_ENABLE")) - args2.push_back("--log-enable=error+"); // Keep quiet except for errors. - args2.push_back(0); - execv(prog, const_cast<char* const*>(&args2[0])); - throw ErrnoException("execv failed"); - } - } + void init(const Args& args); pid_t pid; int port; diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am index 4ab290722c..108f8e26c3 100644 --- a/qpid/cpp/src/tests/Makefile.am +++ b/qpid/cpp/src/tests/Makefile.am @@ -87,6 +87,7 @@ unit_test_SOURCES= unit_test.cpp unit_test.h \ MessageBuilderTest.cpp \ ConnectionOptions.h \ ForkedBroker.h \ + ForkedBroker.cpp \ ManagementTest.cpp \ MessageReplayTracker.cpp \ ConsoleTest.cpp \ @@ -161,7 +162,7 @@ header_test_SOURCES=header_test.cpp TestOptions.h ConnectionOptions.h header_test_LDADD=$(lib_client) check_PROGRAMS+=failover_soak -failover_soak_SOURCES=failover_soak.cpp ForkedBroker.h +failover_soak_SOURCES=failover_soak.cpp ForkedBroker.h ForkedBroker.cpp failover_soak_LDADD=$(lib_client) check_PROGRAMS+=declare_queues diff --git a/qpid/cpp/src/tests/cluster.mk b/qpid/cpp/src/tests/cluster.mk index 995148fb54..0427a1783b 100644 --- a/qpid/cpp/src/tests/cluster.mk +++ b/qpid/cpp/src/tests/cluster.mk @@ -33,7 +33,7 @@ TESTS+=ais_check EXTRA_DIST+=ais_check start_cluster stop_cluster restart_cluster cluster_python_tests cluster_python_tests_failing.txt check_PROGRAMS+=cluster_test -cluster_test_SOURCES=unit_test.cpp cluster_test.cpp ClusterFixture.cpp ClusterFixture.h +cluster_test_SOURCES=unit_test.cpp cluster_test.cpp ClusterFixture.cpp ClusterFixture.h ForkedBroker.h ForkedBroker.cpp cluster_test_LDADD=$(lib_client) ../cluster.la -lboost_unit_test_framework unit_test_LDADD+=../cluster.la |