diff options
author | Alan Conway <aconway@apache.org> | 2006-12-20 15:11:37 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2006-12-20 15:11:37 +0000 |
commit | b6a25edfe049db4d4a7c109f2464fb4e4f16e600 (patch) | |
tree | 7793c3a8149eb0e8de308fe4a87df050bf46bc66 /cpp/tests | |
parent | fc6d79eb365027d1fdda43ae0081f72dd45b7896 (diff) | |
download | qpid-python-b6a25edfe049db4d4a7c109f2464fb4e4f16e600.tar.gz |
Adding files for EventChannel implementation.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@489110 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/tests')
-rw-r--r-- | cpp/tests/AcceptorTest.cpp | 95 | ||||
-rw-r--r-- | cpp/tests/EventChannelConnectionTest.cpp | 109 | ||||
-rw-r--r-- | cpp/tests/MockSessionHandler.h | 113 | ||||
-rwxr-xr-x | cpp/tests/run-system-tests | 38 |
4 files changed, 355 insertions, 0 deletions
diff --git a/cpp/tests/AcceptorTest.cpp b/cpp/tests/AcceptorTest.cpp new file mode 100644 index 0000000000..394dfea463 --- /dev/null +++ b/cpp/tests/AcceptorTest.cpp @@ -0,0 +1,95 @@ +/* + * + * 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 <iostream> +#include <boost/bind.hpp> + +#include "sys/Thread.h" +#include "sys/Acceptor.h" +#include "sys/Socket.h" +#include "framing/Buffer.h" +#include "qpid_test_plugin.h" + +#include "MockSessionHandler.h" + +using namespace qpid::sys; +using namespace qpid::framing; +using namespace std; + +const char hello[] = "hello"; +const size_t size = sizeof(hello); + + +class AcceptorTest : public CppUnit::TestCase, private Runnable +{ + CPPUNIT_TEST_SUITE(AcceptorTest); + CPPUNIT_TEST(testAccept); + CPPUNIT_TEST_SUITE_END(); + + private: + MockSessionHandlerFactory factory; + Acceptor::shared_ptr acceptor; + + public: + + void run() { + acceptor->run(factory); + } + + void setUp() { + acceptor = Acceptor::create(0, 10, 3); + } + + void tearDown() { + acceptor.reset(); + } + + void testAccept() + { + int port = acceptor->getPort(); + CPPUNIT_ASSERT(port > 0); + Thread runThread(*this); + // Connect to the acceptor + Socket client = Socket::createTcp(); + client.connect("localhost", port); + factory.waitForHandler(); + CPPUNIT_ASSERT(factory.handler != 0); + // Send a protocol initiation. + Buffer buf(1024); + ProtocolInitiation(4,2).encode(buf); + buf.flip(); + client.send(buf.start(), buf.available()); + + // Verify session handler got the protocol init. + ProtocolInitiation init = factory.handler->waitForProtocolInit(); + CPPUNIT_ASSERT_EQUAL(int(4), int(init.getMajor())); + CPPUNIT_ASSERT_EQUAL(int(2), int(init.getMinor())); + + acceptor->shutdown(); + runThread.join(); + factory.handler->waitForClosed(); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(AcceptorTest); + diff --git a/cpp/tests/EventChannelConnectionTest.cpp b/cpp/tests/EventChannelConnectionTest.cpp new file mode 100644 index 0000000000..a6b309d771 --- /dev/null +++ b/cpp/tests/EventChannelConnectionTest.cpp @@ -0,0 +1,109 @@ +/* + * + * 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 <iostream> +#include <boost/bind.hpp> +#include "framing/AMQHeartbeatBody.h" +#include "framing/AMQFrame.h" +#include "sys/posix/EventChannelConnection.h" +#include "sys/SessionHandler.h" +#include "sys/SessionHandlerFactory.h" +#include "sys/Socket.h" +#include "qpid_test_plugin.h" +#include "MockSessionHandler.h" + +using namespace qpid::sys; +using namespace qpid::framing; +using namespace std; + +class EventChannelConnectionTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(EventChannelConnectionTest); + CPPUNIT_TEST(testSendReceive); + CPPUNIT_TEST(testCloseExternal); + CPPUNIT_TEST(testCloseException); + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp() { + threads = EventChannelThreads::create(); + CPPUNIT_ASSERT_EQUAL(0, ::pipe(pipe)); + connection.reset( + new EventChannelConnection(threads, factory, pipe[0], pipe[1])); + CPPUNIT_ASSERT(factory.handler != 0); + } + + void tearDown() { + threads->shutdown(); + threads->join(); + } + + void testSendReceive() + { + // Send a protocol initiation. + Buffer buf(1024); + ProtocolInitiation(4,2).encode(buf); + buf.flip(); + ssize_t n = write(pipe[1], buf.start(), buf.available()); + CPPUNIT_ASSERT_EQUAL(ssize_t(buf.available()), n); + + // Verify session handler got the protocol init. + ProtocolInitiation init = factory.handler->waitForProtocolInit(); + CPPUNIT_ASSERT_EQUAL(int(4), int(init.getMajor())); + CPPUNIT_ASSERT_EQUAL(int(2), int(init.getMinor())); + + // Send a heartbeat frame, verify connection got it. + connection->send(new AMQFrame(42, new AMQHeartbeatBody())); + AMQFrame frame = factory.handler->waitForFrame(); + CPPUNIT_ASSERT_EQUAL(u_int16_t(42), frame.getChannel()); + CPPUNIT_ASSERT_EQUAL(u_int8_t(HEARTBEAT_BODY), + frame.getBody()->type()); + threads->shutdown(); + } + + // Make sure the handler is closed if the connection is closed. + void testCloseExternal() { + connection->close(); + factory.handler->waitForClosed(); + } + + // Make sure the handler is closed if the connection closes or fails. + // TODO aconway 2006-12-18: logs exception message in test output. + void testCloseException() { + ::close(pipe[0]); + ::close(pipe[1]); + // TODO aconway 2006-12-18: Shouldn't this be failing? + connection->send(new AMQFrame(42, new AMQHeartbeatBody())); + factory.handler->waitForClosed(); + } + + private: + EventChannelThreads::shared_ptr threads; + int pipe[2]; + std::auto_ptr<EventChannelConnection> connection; + MockSessionHandlerFactory factory; +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(EventChannelConnectionTest); + diff --git a/cpp/tests/MockSessionHandler.h b/cpp/tests/MockSessionHandler.h new file mode 100644 index 0000000000..aace780ac9 --- /dev/null +++ b/cpp/tests/MockSessionHandler.h @@ -0,0 +1,113 @@ +#ifndef _tests_MockSessionHandler_h +#define _tests_MockSessionHandler_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 "sys/SessionHandler.h" +#include "sys/SessionHandlerFactory.h" +#include "sys/Monitor.h" +#include "framing/ProtocolInitiation.h" + +struct MockSessionHandler : public qpid::sys::SessionHandler { + + MockSessionHandler() : state(START) {} + + ~MockSessionHandler() {} + + void initiated(qpid::framing::ProtocolInitiation* pi) { + qpid::sys::Monitor::ScopedLock l(monitor); + init = *pi; + setState(GOT_INIT); + } + + void received(qpid::framing::AMQFrame* framep) { + qpid::sys::Monitor::ScopedLock l(monitor); + frame = *framep; + setState(GOT_FRAME); + } + + qpid::framing::ProtocolInitiation waitForProtocolInit() { + waitFor(GOT_INIT); + return init; + } + + qpid::framing::AMQFrame waitForFrame() { + waitFor(GOT_FRAME); + return frame; + } + + void waitForClosed() { + waitFor(CLOSED); + } + + void closed() { + qpid::sys::Monitor::ScopedLock l(monitor); + setState(CLOSED); + } + + void idleOut() {} + void idleIn() {} + + private: + typedef enum { START, GOT_INIT, GOT_FRAME, CLOSED } State; + + void setState(State s) { + state = s; + monitor.notify(); + } + + void waitFor(State s) { + qpid::sys::Monitor::ScopedLock l(monitor); + qpid::sys::Time deadline = qpid::sys::now() + 10*qpid::sys::TIME_SEC; + while (state != s) + CPPUNIT_ASSERT(monitor.wait(deadline)); + } + + qpid::sys::Monitor monitor; + State state; + qpid::framing::ProtocolInitiation init; + qpid::framing::AMQFrame frame; +}; + + +struct MockSessionHandlerFactory : public qpid::sys::SessionHandlerFactory { + MockSessionHandlerFactory() : handler(0) {} + + qpid::sys::SessionHandler* create(qpid::sys::SessionContext*) { + qpid::sys::Monitor::ScopedLock lock(monitor); + handler = new MockSessionHandler(); + monitor.notifyAll(); + return handler; + } + + void waitForHandler() { + qpid::sys::Monitor::ScopedLock lock(monitor); + qpid::sys::Time deadline = + qpid::sys::now() + 500 * qpid::sys::TIME_SEC; + while (handler == 0) + CPPUNIT_ASSERT(monitor.wait(deadline)); + } + + MockSessionHandler* handler; + qpid::sys::Monitor monitor; +}; + + + +#endif /*!_tests_MockSessionHandler_h*/ diff --git a/cpp/tests/run-system-tests b/cpp/tests/run-system-tests new file mode 100755 index 0000000000..5aa0f9a409 --- /dev/null +++ b/cpp/tests/run-system-tests @@ -0,0 +1,38 @@ +#!/bin/sh + +set -e +log=`pwd`/qpidd.log +# Start the daemon, recording its PID. +../src/qpidd > $log 2>&1 & pid=$! + +# Arrange to kill the daemon upon any type of termination. +trap 'status=$?; kill $pid; exit $status' 0 +trap '(exit $?); exit $?' 1 2 13 15 + +# Run C++ client tests. +run_test() { + test="$*" + echo -n "Running: $test ... " + if $test >test.out 2>&1 ; then + echo " Passed" ; + else + echo " FAILED. Output:"; + cat test.out + FAILED=yes + fi + rm -f test.out +} + +run_test ./client_test +run_test ./topictest -l2 -m2 -b1 + +# Run the python tests. +if test -d ../../python ; then + cd ../../python && ./run-tests -v -I cpp_failing.txt +else + echo Warning: python tests not found. +fi + +# TODO aconway 2006-12-13: run the other client tests. + +rm -f $log |