diff options
Diffstat (limited to 'Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp')
| -rw-r--r-- | Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp | 282 | 
1 files changed, 282 insertions, 0 deletions
diff --git a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp new file mode 100644 index 0000000..7407f44 --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Elements/IBB.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/FileTransfer/ByteArrayWriteBytestream.h> +#include <Swiften/FileTransfer/IncomingJingleFileTransfer.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h> +#include <Swiften/Jingle/FakeJingleSession.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/Network/DummyConnectionFactory.h> +#include <Swiften/Network/PlatformNATTraversalWorker.h> +#include <Swiften/Queries/IQRouter.h> + +#include <iostream> + +using namespace Swift; +using namespace boost; + +class FakeRemoteJingleTransportCandidateSelector : public RemoteJingleTransportCandidateSelector { +		void addRemoteTransportCandidates(JingleTransportPayload::ref cand) { +			candidate = cand; +		} + +		void selectCandidate() { +		    boost::shared_ptr<JingleS5BTransportPayload> payload = make_shared<JingleS5BTransportPayload>(); +		    payload->setCandidateError(true); +		    payload->setSessionID(candidate->getSessionID()); +		    onRemoteTransportCandidateSelectFinished(payload); +		} + +		void setMinimumPriority(int) { + +		} + +		bool isActualCandidate(JingleTransportPayload::ref) { +			return false; +		} + +		int getPriority(JingleTransportPayload::ref) { +			return 0; +		} + +		JingleTransport::ref selectTransport(JingleTransportPayload::ref) { +			return JingleTransport::ref(); +		} + +private: +	JingleTransportPayload::ref candidate; +}; + +class FakeRemoteJingleTransportCandidateSelectorFactory : public RemoteJingleTransportCandidateSelectorFactory { +public: +	virtual ~FakeRemoteJingleTransportCandidateSelectorFactory() { + +	} + +	virtual RemoteJingleTransportCandidateSelector* createCandidateSelector() { +		return new FakeRemoteJingleTransportCandidateSelector(); +	} +}; + +class FakeLocalJingleTransportCandidateGenerator : public LocalJingleTransportCandidateGenerator { +public: +	virtual void generateLocalTransportCandidates(JingleTransportPayload::ref payload) { +		JingleS5BTransportPayload::ref payL = make_shared<JingleS5BTransportPayload>(); +		payL->setSessionID(payload->getSessionID()); +		onLocalTransportCandidatesGenerated(payL); +	} + +	void emitonLocalTransportCandidatesGenerated(JingleTransportPayload::ref payload) { +		onLocalTransportCandidatesGenerated(payload); +	} + +	virtual bool isActualCandidate(JingleTransportPayload::ref) { +		return false; +	} + +	virtual int getPriority(JingleTransportPayload::ref) { +		return 0; +	} + +	virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref) { +		return JingleTransport::ref(); +	} +}; + +class FakeLocalJingleTransportCandidateGeneratorFactory : public LocalJingleTransportCandidateGeneratorFactory { +public: +	virtual LocalJingleTransportCandidateGenerator* createCandidateGenerator() { +		return new FakeLocalJingleTransportCandidateGenerator(); +	} +}; + +class IncomingJingleFileTransferTest : public CppUnit::TestFixture { +		CPPUNIT_TEST_SUITE(IncomingJingleFileTransferTest); +		CPPUNIT_TEST(test_AcceptOnyIBBSendsSessionAccept); +		CPPUNIT_TEST(test_OnlyIBBTransferReceiveWorks); +		CPPUNIT_TEST(test_AcceptFailingS5BFallsBackToIBB); +		CPPUNIT_TEST_SUITE_END(); +public: +		shared_ptr<IncomingJingleFileTransfer> createTestling() { +			JID ourJID("our@jid.org/full"); +			return make_shared<IncomingJingleFileTransfer>(ourJID, shared_ptr<JingleSession>(fakeJingleSession), jingleContentPayload, fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, bytestreamRegistry, bytestreamProxy, timerFactory); +		} + +		IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { +			IQ::ref request = IQ::createRequest(IQ::Set, JID("foo@bar.com/baz"), id, ibb); +			request->setFrom(from); +			return request; +		} + +		void setUp() { +			eventLoop = new DummyEventLoop(); +			fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession"); +			jingleContentPayload = make_shared<JingleContentPayload>(); +			fakeRJTCSF = make_shared<FakeRemoteJingleTransportCandidateSelectorFactory>(); +			fakeLJTCF = make_shared<FakeLocalJingleTransportCandidateGeneratorFactory>(); +			stanzaChannel = new DummyStanzaChannel(); +			iqRouter = new IQRouter(stanzaChannel); +			bytestreamRegistry = new SOCKS5BytestreamRegistry(); +			timerFactory = new DummyTimerFactory(); +			connectionFactory = new DummyConnectionFactory(eventLoop); +			bytestreamProxy = new SOCKS5BytestreamProxy(connectionFactory, timerFactory); +		} + +		void tearDown() { +			delete bytestreamProxy; +			delete connectionFactory; +			delete timerFactory; +			delete bytestreamRegistry; +			delete iqRouter; +			delete stanzaChannel; +			delete eventLoop; +		} + +		// Tests whether IncomingJingleFileTransfer would accept a IBB only file transfer. +		void test_AcceptOnyIBBSendsSessionAccept() { +			//1. create your test incoming file transfer +			shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); +			desc->addOffer(StreamInitiationFileInfo()); +			jingleContentPayload->addDescription(desc); +			JingleIBBTransportPayload::ref tpRef = make_shared<JingleIBBTransportPayload>(); +			tpRef->setSessionID("mysession"); +			jingleContentPayload->addTransport(tpRef); + +			shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); + +			//2. do 'accept' on a dummy writebytestream (you'll have to look if there already is one) +			shared_ptr<ByteArrayWriteBytestream> byteStream = make_shared<ByteArrayWriteBytestream>(); +			fileTransfer->accept(byteStream); + +			// check whether accept has been called +			getCall<FakeJingleSession::AcceptCall>(0); +		} + +		void test_OnlyIBBTransferReceiveWorks() { +			//1. create your test incoming file transfer +			shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); +			desc->addOffer(StreamInitiationFileInfo()); +			jingleContentPayload->addDescription(desc); +			JingleIBBTransportPayload::ref tpRef = make_shared<JingleIBBTransportPayload>(); +			tpRef->setSessionID("mysession"); +			jingleContentPayload->addTransport(tpRef); + +			shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); + +			//2. do 'accept' on a dummy writebytestream (you'll have to look if there already is one) +			shared_ptr<ByteArrayWriteBytestream> byteStream = make_shared<ByteArrayWriteBytestream>(); +			fileTransfer->accept(byteStream); + +			// check whether accept has been called +			getCall<FakeJingleSession::AcceptCall>(0); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); +			CPPUNIT_ASSERT(createByteArray("abc") == byteStream->getData()); +		} + +		void test_AcceptFailingS5BFallsBackToIBB() { +			//1. create your test incoming file transfer +			addFileTransferDescription(); + +			// add SOCKS5BytestreamTransportPayload +			JingleS5BTransportPayload::ref payLoad = addJingleS5BPayload(); + +			shared_ptr<IncomingJingleFileTransfer> fileTransfer = createTestling(); + +			//2. do 'accept' on a dummy writebytestream (you'll have to look if there already is one) +			shared_ptr<ByteArrayWriteBytestream> byteStream = make_shared<ByteArrayWriteBytestream>(); +			fileTransfer->accept(byteStream); + +			// check whether accept has been called +			FakeJingleSession::AcceptCall acceptCall = getCall<FakeJingleSession::AcceptCall>(0); +			CPPUNIT_ASSERT_EQUAL(payLoad->getSessionID(), acceptCall.payload->getSessionID()); + +			// check for candidate error +			FakeJingleSession::InfoTransportCall infoTransportCall = getCall<FakeJingleSession::InfoTransportCall>(1); +			JingleS5BTransportPayload::ref s5bPayload = dynamic_pointer_cast<JingleS5BTransportPayload>(infoTransportCall.payload); +			CPPUNIT_ASSERT(s5bPayload->hasCandidateError()); + +			// indicate transport replace (Romeo) +			fakeJingleSession->onTransportReplaceReceived(getContentID(), addJingleIBBPayload()); + +			FakeJingleSession::AcceptTransportCall acceptTransportCall = getCall<FakeJingleSession::AcceptTransportCall>(2); + +			// send a bit of data +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); +			CPPUNIT_ASSERT(createByteArray("abc") == byteStream->getData()); +		} + +		void test_S5BTransferReceiveTest() { +			addFileTransferDescription(); +			JingleS5BTransportPayload::ref payLoad = addJingleS5BPayload(); +		} + +private: +	void addFileTransferDescription() { +		shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); +		desc->addOffer(StreamInitiationFileInfo()); +		jingleContentPayload->addDescription(desc); +	} + +	shared_ptr<JingleS5BTransportPayload> addJingleS5BPayload() { +		JingleS5BTransportPayload::ref payLoad = make_shared<JingleS5BTransportPayload>(); +		payLoad->setSessionID("mysession"); +		jingleContentPayload->addTransport(payLoad); +		return payLoad; +	} + +	shared_ptr<JingleIBBTransportPayload> addJingleIBBPayload() { +		JingleIBBTransportPayload::ref payLoad = make_shared<JingleIBBTransportPayload>(); +		payLoad->setSessionID("mysession"); +		jingleContentPayload->addTransport(payLoad); +		return payLoad; +	} +	 +	JingleContentID getContentID() const  { +		return JingleContentID(jingleContentPayload->getName(), jingleContentPayload->getCreator()); +	} + +	template <typename T> T getCall(int i) const { +		size_t index = static_cast<size_t>(i); +		CPPUNIT_ASSERT(index < fakeJingleSession->calledCommands.size()); +		T* cmd = boost::get<T>(&fakeJingleSession->calledCommands[index]); +		CPPUNIT_ASSERT(cmd); +		return *cmd; +	} + +private: +	EventLoop* eventLoop; +	FakeJingleSession* fakeJingleSession; +	shared_ptr<JingleContentPayload> jingleContentPayload; +	shared_ptr<FakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF; +	shared_ptr<FakeLocalJingleTransportCandidateGeneratorFactory> fakeLJTCF; +	DummyStanzaChannel* stanzaChannel; +	IQRouter* iqRouter; +	SOCKS5BytestreamRegistry* bytestreamRegistry; +	DummyConnectionFactory* connectionFactory; +	SOCKS5BytestreamProxy* bytestreamProxy; +	DummyTimerFactory* timerFactory; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(IncomingJingleFileTransferTest);  | 
 Swift