diff options
Diffstat (limited to 'Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp')
-rw-r--r-- | Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp new file mode 100644 index 0000000..582c3e5 --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp @@ -0,0 +1,283 @@ +/* + * 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/bind.hpp> +#include <boost/optional.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h> +#include <Swiften/Jingle/FakeJingleSession.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/FileTransfer/ByteArrayReadBytestream.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> +#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h> + +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Elements/IBB.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/Network/PlatformNATTraversalWorker.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/Network/DummyConnection.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/DummyConnectionFactory.h> + +#include <Swiften/Base/Log.h> + +#include <iostream> + +using namespace Swift; + +class OFakeRemoteJingleTransportCandidateSelector : public RemoteJingleTransportCandidateSelector { + void addRemoteTransportCandidates(JingleTransportPayload::ref cand) { + candidate = cand; + } + + void selectCandidate() { + JingleS5BTransportPayload::ref payload = boost::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 OFakeRemoteJingleTransportCandidateSelectorFactory : public RemoteJingleTransportCandidateSelectorFactory { +public: + virtual ~OFakeRemoteJingleTransportCandidateSelectorFactory() { + + } + + virtual RemoteJingleTransportCandidateSelector* createCandidateSelector() { + return new OFakeRemoteJingleTransportCandidateSelector(); + } +}; + +class OFakeLocalJingleTransportCandidateGenerator : public LocalJingleTransportCandidateGenerator { +public: + virtual void generateLocalTransportCandidates(JingleTransportPayload::ref /* payload */) { + //JingleTransportPayload::ref payL = make_shared<JingleTransportPayload>(); + //payL->setSessionID(payload->getSessionID()); + JingleS5BTransportPayload::ref payL = boost::make_shared<JingleS5BTransportPayload>(); + + 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 OFakeLocalJingleTransportCandidateGeneratorFactory : public LocalJingleTransportCandidateGeneratorFactory { +public: + virtual LocalJingleTransportCandidateGenerator* createCandidateGenerator() { + return new OFakeLocalJingleTransportCandidateGenerator(); + } +}; + +class OutgoingJingleFileTransferTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(OutgoingJingleFileTransferTest); + CPPUNIT_TEST(test_SendSessionInitiateOnStart); + CPPUNIT_TEST(test_IBBStartsAfterSendingSessionAccept); + CPPUNIT_TEST(test_ReceiveSessionTerminateAfterSessionInitiate); + CPPUNIT_TEST_SUITE_END(); + + class FTStatusHelper { + public: + bool finishedCalled; + FileTransferError::Type error; + void handleFileTransferFinished(boost::optional<FileTransferError> error) { + finishedCalled = true; + if (error.is_initialized()) this->error = error.get().getType(); + } + }; +public: + + boost::shared_ptr<OutgoingJingleFileTransfer> createTestling() { + JID to("test@foo.com/bla"); + StreamInitiationFileInfo fileInfo; + fileInfo.setDescription("some file"); + fileInfo.setName("test.bin"); + fileInfo.setHash("asdjasdas"); + fileInfo.setSize(1024 * 1024); + return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(boost::shared_ptr<JingleSession>(fakeJingleSession), fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, idGen, to, stream, fileInfo, s5bRegistry, s5bProxy)); + } + + 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() { + fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession"); + jingleContentPayload = boost::make_shared<JingleContentPayload>(); + fakeRJTCSF = boost::make_shared<OFakeRemoteJingleTransportCandidateSelectorFactory>(); + fakeLJTCF = boost::make_shared<OFakeLocalJingleTransportCandidateGeneratorFactory>(); + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + eventLoop = new DummyEventLoop(); + timerFactory = new DummyTimerFactory(); + connectionFactory = new DummyConnectionFactory(eventLoop); + s5bRegistry = new SOCKS5BytestreamRegistry(); + s5bProxy = new SOCKS5BytestreamProxy(connectionFactory, timerFactory); + + data.clear(); + for (int n=0; n < 1024 * 1024; ++n) { + data.push_back(34); + } + + stream = boost::make_shared<ByteArrayReadBytestream>(data); + + idGen = new IDGenerator(); + } + + void tearDown() { + delete idGen; + delete s5bRegistry; + delete connectionFactory; + delete timerFactory; + delete eventLoop; + delete iqRouter; + delete stanzaChannel; + } + + + void test_SendSessionInitiateOnStart() { + boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); + transfer->start(); + FakeJingleSession::InitiateCall call = getCall<FakeJingleSession::InitiateCall>(0); + JingleFileTransferDescription::ref description = boost::dynamic_pointer_cast<JingleFileTransferDescription>(call.description); + CPPUNIT_ASSERT(description); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), description->getOffers().size()); + CPPUNIT_ASSERT(static_cast<size_t>(1048576) == description->getOffers()[0].getSize()); + + JingleS5BTransportPayload::ref transport = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(call.payload); + CPPUNIT_ASSERT(transport); + } + + void test_IBBStartsAfterSendingSessionAccept() { + boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); + transfer->start(); + + FakeJingleSession::InitiateCall call = getCall<FakeJingleSession::InitiateCall>(0); + // FIXME: we initiate with SOCSK5 now and not IBB, needs to be fixed. + /* + fakeJingleSession->onSessionAcceptReceived(call.id, call.description, call.payload); + IQ::ref iqOpenStanza = stanzaChannel->getStanzaAtIndex<IQ>(0); + CPPUNIT_ASSERT(iqOpenStanza); + */ + } + + void test_ReceiveSessionTerminateAfterSessionInitiate() { + boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(); + transfer->start(); + + getCall<FakeJingleSession::InitiateCall>(0); + + FTStatusHelper helper; + helper.finishedCalled = false; + transfer->onFinished.connect(bind(&FTStatusHelper::handleFileTransferFinished, &helper, _1)); + fakeJingleSession->onSessionTerminateReceived(JinglePayload::Reason(JinglePayload::Reason::Busy)); + CPPUNIT_ASSERT_EQUAL(true, helper.finishedCalled); + CPPUNIT_ASSERT(FileTransferError::PeerError == helper.error); + } + + +//TODO: some more testcases + +private: + void addFileTransferDescription() { + boost::shared_ptr<JingleFileTransferDescription> desc = boost::make_shared<JingleFileTransferDescription>(); + desc->addOffer(StreamInitiationFileInfo()); + jingleContentPayload->addDescription(desc); + } + + boost::shared_ptr<JingleS5BTransportPayload> addJingleS5BPayload() { + JingleS5BTransportPayload::ref payLoad = boost::make_shared<JingleS5BTransportPayload>(); + payLoad->setSessionID("mysession"); + jingleContentPayload->addTransport(payLoad); + return payLoad; + } + + boost::shared_ptr<JingleIBBTransportPayload> addJingleIBBPayload() { + JingleIBBTransportPayload::ref payLoad = boost::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: + std::vector<unsigned char> data; + boost::shared_ptr<ByteArrayReadBytestream> stream; + FakeJingleSession* fakeJingleSession; + boost::shared_ptr<JingleContentPayload> jingleContentPayload; + boost::shared_ptr<OFakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF; + boost::shared_ptr<OFakeLocalJingleTransportCandidateGeneratorFactory> fakeLJTCF; + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + IDGenerator* idGen; + EventLoop *eventLoop; + SOCKS5BytestreamRegistry* s5bRegistry; + SOCKS5BytestreamProxy* s5bProxy; + DummyTimerFactory* timerFactory; + DummyConnectionFactory* connectionFactory; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(OutgoingJingleFileTransferTest); |