diff options
Diffstat (limited to 'Swiften/FileTransfer/UnitTest')
-rw-r--r-- | Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp | 164 | ||||
-rw-r--r-- | Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp | 154 |
2 files changed, 318 insertions, 0 deletions
diff --git a/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp b/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp new file mode 100644 index 0000000..9052439 --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <vector> +#include <boost/bind.hpp> + +#include "Swiften/FileTransfer/IBBSendSession.h" +#include "Swiften/FileTransfer/ByteArrayReadBytestream.h" +#include "Swiften/Queries/IQRouter.h" +#include "Swiften/Client/DummyStanzaChannel.h" + +using namespace Swift; + +class IBBSendSessionTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(IBBSendSessionTest); + CPPUNIT_TEST(testStart); + CPPUNIT_TEST(testStart_ResponseStartsSending); + CPPUNIT_TEST(testResponseContinuesSending); + CPPUNIT_TEST(testRespondToAllFinishes); + CPPUNIT_TEST(testErrorResponseFinishesWithError); + CPPUNIT_TEST(testStopDuringSessionCloses); + CPPUNIT_TEST(testStopAfterFinishedDoesNotClose); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + bytestream = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(ByteArray("abcdefg"))); + } + + void tearDown() { + delete iqRouter; + delete stanzaChannel; + } + + void testStart() { + std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(1234); + + testling->start(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(0, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[0]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Open, ibb->getAction()); + CPPUNIT_ASSERT_EQUAL(1234, ibb->getBlockSize()); + CPPUNIT_ASSERT_EQUAL(String("myid"), ibb->getStreamID()); + } + + void testStart_ResponseStartsSending() { + std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + + stanzaChannel->onIQReceived(createIBBResult()); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); + CPPUNIT_ASSERT_EQUAL(ByteArray("abc"), ibb->getData()); + CPPUNIT_ASSERT_EQUAL(0, ibb->getSequenceNumber()); + CPPUNIT_ASSERT_EQUAL(String("myid"), ibb->getStreamID()); + } + + void testResponseContinuesSending() { + std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(2, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[2]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); + CPPUNIT_ASSERT_EQUAL(ByteArray("def"), ibb->getData()); + CPPUNIT_ASSERT_EQUAL(1, ibb->getSequenceNumber()); + CPPUNIT_ASSERT_EQUAL(String("myid"), ibb->getStreamID()); + } + + void testRespondToAllFinishes() { + std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(!error); + } + + void testErrorResponseFinishesWithError() { + std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getID())); + + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(error); + } + + void testStopDuringSessionCloses() { + std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + testling->stop(); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Close, ibb->getAction()); + CPPUNIT_ASSERT_EQUAL(String("myid"), ibb->getStreamID()); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(!error); + } + + void testStopAfterFinishedDoesNotClose() { + std::auto_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(16); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + CPPUNIT_ASSERT(finished); + + testling->stop(); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + private: + IQ::ref createIBBResult() { + return IQ::createResult(JID("baz@fum.com/dum"), stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getID(), boost::shared_ptr<IBB>()); + } + + private: + std::auto_ptr<IBBSendSession> createSession(const String& to) { + std::auto_ptr<IBBSendSession> session(new IBBSendSession("myid", JID(to), bytestream, iqRouter)); + session->onFinished.connect(boost::bind(&IBBSendSessionTest::handleFinished, this, _1)); + return session; + } + + void handleFinished(boost::optional<FileTransferError> error) { + finished = true; + this->error = error; + } + + private: + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + bool finished; + boost::optional<FileTransferError> error; + boost::shared_ptr<ByteArrayReadBytestream> bytestream; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(IBBSendSessionTest); diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp new file mode 100644 index 0000000..126f971 --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <boost/bind.hpp> + +#include "Swiften/FileTransfer/SOCKS5BytestreamServerSession.h" +#include "Swiften/FileTransfer/ByteArrayReadBytestream.h" +#include "Swiften/FileTransfer/SOCKS5BytestreamRegistry.h" +#include "Swiften/Network/DummyConnection.h" +#include "Swiften/EventLoop/DummyEventLoop.h" +#include "Swiften/Base/StartStopper.h" + +using namespace Swift; + +class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(SOCKS5BytestreamServerSessionTest); + CPPUNIT_TEST(testAuthenticate); + CPPUNIT_TEST(testAuthenticate_Chunked); + CPPUNIT_TEST(testRequest); + CPPUNIT_TEST(testRequest_UnknownBytestream); + CPPUNIT_TEST(testReceiveData); + CPPUNIT_TEST(testReceiveData_Chunked); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + receivedDataChunks = 0; + eventLoop = new DummyEventLoop(); + connection = boost::shared_ptr<DummyConnection>(new DummyConnection()); + connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); + stream1 = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(ByteArray("abcdefg"))); + } + + void tearDown() { + connection.reset(); + delete eventLoop; + } + + void testAuthenticate() { + std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + + receive(ByteArray("\x05\x02\x01\x02")); + + CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00", 2), receivedData); + } + + void testAuthenticate_Chunked() { + std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + + receive(ByteArray("\x05\x02\x01")); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedData.getSize())); + receive(ByteArray("\x01")); + CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00", 2), receivedData); + } + + void testRequest() { + std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + bytestreams.addBytestream("abcdef", stream1); + authenticate(); + + ByteArray hostname("abcdef"); + receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.getSize() + hostname + ByteArray("\x00\x00", 2)); + CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13), ByteArray(receivedData.getData(), 13)); + } + + void testRequest_UnknownBytestream() { + std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + authenticate(); + + ByteArray hostname("abcdef"); + receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.getSize() + hostname + ByteArray("\x00\x00", 2)); + CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x04\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13), receivedData); + } + + void testReceiveData() { + std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + bytestreams.addBytestream("abcdef", stream1); + authenticate(); + request("abcdef"); + eventLoop->processEvents(); + skipHeader("abcdef"); + + CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefg"), receivedData); + CPPUNIT_ASSERT_EQUAL(2, receivedDataChunks); + } + + void testReceiveData_Chunked() { + std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + testling->setChunkSize(3); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + bytestreams.addBytestream("abcdef", stream1); + authenticate(); + request("abcdef"); + eventLoop->processEvents(); + + skipHeader("abcdef"); + CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefg"), receivedData); + CPPUNIT_ASSERT_EQUAL(4, receivedDataChunks); + } + + private: + void receive(const ByteArray& data) { + connection->receive(data); + eventLoop->processEvents(); + } + + void authenticate() { + receive(ByteArray("\x05\x02\x01\x02")); + receivedData.clear(); + receivedDataChunks = 0; + } + + void request(const String& hostname) { + receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.getUTF8Size() + hostname + ByteArray("\x00\x00", 2)); + } + + void skipHeader(const String& hostname) { + int headerSize = 7 + hostname.getUTF8Size(); + receivedData = ByteArray(receivedData.getData() + headerSize, receivedData.getSize() - headerSize); + } + + + void handleDataWritten(const ByteArray& data) { + receivedData += data; + receivedDataChunks++; + } + + private: + SOCKS5BytestreamServerSession* createSession() { + SOCKS5BytestreamServerSession* session = new SOCKS5BytestreamServerSession(connection, &bytestreams); + return session; + } + + private: + DummyEventLoop* eventLoop; + SOCKS5BytestreamRegistry bytestreams; + boost::shared_ptr<DummyConnection> connection; + ByteArray receivedData; + int receivedDataChunks; + boost::shared_ptr<ByteArrayReadBytestream> stream1; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(SOCKS5BytestreamServerSessionTest); |