From 1d09d9ead06be72ee0c4026aa027cd90e6f1546b Mon Sep 17 00:00:00 2001 From: Tobias Markmann Date: Sun, 1 Mar 2015 22:00:49 +0100 Subject: Fix OutgoingJingleFileTransferTest and enable it again Test-Information: Unit tests pass. Change-Id: I793fb65fd2e760daddab0142abc33d4aa5b4fce5 diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp index 7ff1a08..aabbd2d 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp @@ -126,6 +126,9 @@ void OutgoingJingleFileTransfer::handleSessionTerminateReceived(boost::optional< if (state == Finished) { SWIFT_LOG(warning) << "Incorrect state: " << state << std::endl; return; } stopAll(); + if (state == WaitForTermination) { + waitForRemoteTermination->stop(); + } if (reason && reason->type == JinglePayload::Reason::Cancel) { setFinishedState(FileTransfer::State::Canceled, FileTransferError(FileTransferError::PeerError)); } diff --git a/Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h b/Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h new file mode 100644 index 0000000..324404d --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Swift { + +class DummyFileTransferTransporter : public FileTransferTransporter { +public: + enum Role { + Initiator, + Responder + }; + +public: + DummyFileTransferTransporter( + const JID& initiator, + const JID& responder, + Role role, + SOCKS5BytestreamRegistry* s5bRegistry, + SOCKS5BytestreamServerManager* /* s5bServerManager */, + SOCKS5BytestreamProxiesManager* /* s5bProxy */, + IDGenerator* /* idGenerator */, + ConnectionFactory*, + TimerFactory*, + CryptoProvider* cryptoProvider, + IQRouter* iqRouter, + const FileTransferOptions&) : initiator_(initiator), responder_(responder), role_(role), s5bRegistry_(s5bRegistry), crypto_(cryptoProvider), iqRouter_(iqRouter) { + + } + + void initialize() { + s5bSessionID_ = s5bRegistry_->generateSessionID(); + } + + virtual void startGeneratingLocalCandidates() { + std::vector candidates; + onLocalCandidatesGenerated(s5bSessionID_, candidates, getSOCKS5DstAddr()); + } + + virtual void stopGeneratingLocalCandidates() { + } + + virtual void addRemoteCandidates(const std::vector&, const std::string&) { + } + + virtual void startTryingRemoteCandidates() { + onRemoteCandidateSelectFinished(s5bSessionID_, boost::optional()); + } + + virtual void stopTryingRemoteCandidates() { + } + + virtual void startActivatingProxy(const JID& /* proxy */) { + } + + virtual void stopActivatingProxy() { + } + + virtual boost::shared_ptr createIBBSendSession(const std::string& sessionID, unsigned int blockSize, boost::shared_ptr stream) { + boost::shared_ptr ibbSession = boost::make_shared( + sessionID, initiator_, responder_, stream, iqRouter_); + ibbSession->setBlockSize(blockSize); + return boost::make_shared(ibbSession); + } + + virtual boost::shared_ptr createIBBReceiveSession(const std::string& sessionID, unsigned long long size, boost::shared_ptr stream) { + boost::shared_ptr ibbSession = boost::make_shared( + sessionID, initiator_, responder_, size, stream, iqRouter_); + return boost::make_shared(ibbSession); + } + + virtual boost::shared_ptr createRemoteCandidateSession( + boost::shared_ptr, const JingleS5BTransportPayload::Candidate& /* candidate */) { + return boost::shared_ptr(); + } + + virtual boost::shared_ptr createRemoteCandidateSession( + boost::shared_ptr, const JingleS5BTransportPayload::Candidate& /* candidate */) { + return boost::shared_ptr(); + } + + virtual boost::shared_ptr createLocalCandidateSession( + boost::shared_ptr, const JingleS5BTransportPayload::Candidate& /* candidate */) { + return boost::shared_ptr(); + } + + virtual boost::shared_ptr createLocalCandidateSession( + boost::shared_ptr, const JingleS5BTransportPayload::Candidate& /* candidate */) { + return boost::shared_ptr(); + } + +private: + std::string getSOCKS5DstAddr() const { + std::string result; + if (role_ == Initiator) { + result = getInitiatorCandidateSOCKS5DstAddr(); + } + else { + result = getResponderCandidateSOCKS5DstAddr(); + } + return result; + } + + std::string getInitiatorCandidateSOCKS5DstAddr() const { + return Hexify::hexify(crypto_->getSHA1Hash(createSafeByteArray(s5bSessionID_ + initiator_.toString() + responder_.toString()))); + } + + std::string getResponderCandidateSOCKS5DstAddr() const { + return Hexify::hexify(crypto_->getSHA1Hash(createSafeByteArray(s5bSessionID_ + responder_.toString() + initiator_.toString()))); + } + + +private: + JID initiator_; + JID responder_; + Role role_; + SOCKS5BytestreamRegistry* s5bRegistry_; + CryptoProvider* crypto_; + std::string s5bSessionID_; + IQRouter* iqRouter_; +}; + +class DummyFileTransferTransporterFactory : public FileTransferTransporterFactory { +public: + DummyFileTransferTransporterFactory( + SOCKS5BytestreamRegistry* s5bRegistry, + SOCKS5BytestreamServerManager* s5bServerManager, + SOCKS5BytestreamProxiesManager* s5bProxy, + IDGenerator* idGenerator, + ConnectionFactory* connectionFactory, + TimerFactory* timerFactory, + CryptoProvider* cryptoProvider, + IQRouter* iqRouter) : s5bRegistry_(s5bRegistry), s5bServerManager_(s5bServerManager), s5bProxy_(s5bProxy), idGenerator_(idGenerator), connectionFactory_(connectionFactory), timerFactory_(timerFactory), cryptoProvider_(cryptoProvider), iqRouter_(iqRouter) { + + } + + virtual ~DummyFileTransferTransporterFactory() { + } + + virtual FileTransferTransporter* createInitiatorTransporter(const JID& initiator, const JID& responder, const FileTransferOptions& options) { + DummyFileTransferTransporter* transporter = new DummyFileTransferTransporter( + initiator, + responder, + DummyFileTransferTransporter::Initiator, + s5bRegistry_, + s5bServerManager_, + s5bProxy_, + idGenerator_, + connectionFactory_, + timerFactory_, + cryptoProvider_, + iqRouter_, + options); + transporter->initialize(); + return transporter; + } + + virtual FileTransferTransporter* createResponderTransporter(const JID& /* initiator */, const JID& /* responder */, const std::string& /* s5bSessionID */, const FileTransferOptions& /* options */) { + return NULL; + } + +private: + SOCKS5BytestreamRegistry* s5bRegistry_; + SOCKS5BytestreamServerManager* s5bServerManager_; + SOCKS5BytestreamProxiesManager* s5bProxy_; + IDGenerator* idGenerator_; + ConnectionFactory* connectionFactory_; + TimerFactory* timerFactory_; + CryptoProvider* cryptoProvider_; + IQRouter* iqRouter_; +}; + +} diff --git a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp index 6c375bc..0186e0b 100644 --- a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp +++ b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2013 Isode Limited. + * Copyright (c) 2013-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -17,120 +17,44 @@ #include #include -#include -#include -#include +#include +#include +#include #include -#include -#include -#include - +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include -#include -#include - -#include +#include +#include +#include +#include +#include +#include #include -#if 0 using namespace Swift; -class OFakeRemoteJingleTransportCandidateSelector : public RemoteJingleTransportCandidateSelector { - void addRemoteTransportCandidates(JingleTransportPayload::ref cand) { - candidate = cand; - } - - void selectCandidate() { - JingleS5BTransportPayload::ref payload = boost::make_shared(); - 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: - void emitonLocalTransportCandidatesGenerated(const std::vector& candidates) { - onLocalTransportCandidatesGenerated(candidates); - } - - virtual bool isActualCandidate(JingleTransportPayload::ref) { - return false; - } - - virtual int getPriority(JingleTransportPayload::ref) { - return 0; - } - - virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref) { - return JingleTransport::ref(); - } - - virtual void start() SWIFTEN_OVERRIDE { - //JingleTransportPayload::ref payL = make_shared(); - //payL->setSessionID(payload->getSessionID()); - // JingleS5BTransportPayload::ref payL = boost::make_shared(); - - onLocalTransportCandidatesGenerated(std::vector()); - } - - virtual void stop() SWIFTEN_OVERRIDE {} -}; - -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_FallbackToIBBAfterFailingS5B); CPPUNIT_TEST(test_ReceiveSessionTerminateAfterSessionInitiate); CPPUNIT_TEST_SUITE_END(); @@ -147,12 +71,21 @@ public: boost::shared_ptr createTestling() { JID to("test@foo.com/bla"); - StreamInitiationFileInfo fileInfo; + JingleFileTransferFileInfo fileInfo; fileInfo.setDescription("some file"); fileInfo.setName("test.bin"); - fileInfo.setHash("asdjasdas"); + fileInfo.addHash(HashElement("sha-1", ByteArray())); fileInfo.setSize(1024 * 1024); - return boost::shared_ptr(new OutgoingJingleFileTransfer(boost::shared_ptr(fakeJingleSession), fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, idGen, JID(), to, stream, fileInfo, s5bRegistry, s5bProxy, crypto.get())); + return boost::shared_ptr(new OutgoingJingleFileTransfer( + to, + boost::shared_ptr(fakeJingleSession), + stream, + ftTransportFactory, + timerFactory, + idGen, + fileInfo, + FileTransferOptions().withAssistedAllowed(false).withDirectAllowed(false).withProxiedAllowed(false), + crypto.get())); } IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { @@ -165,15 +98,16 @@ public: crypto = boost::shared_ptr(PlatformCryptoProvider::create()); fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession"); jingleContentPayload = boost::make_shared(); - fakeRJTCSF = boost::make_shared(); - fakeLJTCF = boost::make_shared(); stanzaChannel = new DummyStanzaChannel(); iqRouter = new IQRouter(stanzaChannel); eventLoop = new DummyEventLoop(); timerFactory = new DummyTimerFactory(); connectionFactory = new DummyConnectionFactory(eventLoop); + serverConnectionFactory = new DummyConnectionServerFactory(eventLoop); s5bRegistry = new SOCKS5BytestreamRegistry(); - s5bProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory); + networkEnvironment = new PlatformNetworkEnvironment(); + natTraverser = new PlatformNATTraversalWorker(eventLoop); + bytestreamServerManager = new SOCKS5BytestreamServerManager(s5bRegistry, serverConnectionFactory, networkEnvironment, natTraverser); data.clear(); for (int n=0; n < 1024 * 1024; ++n) { @@ -183,9 +117,14 @@ public: stream = boost::make_shared(data); idGen = new IDGenerator(); + s5bProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory, resolver, iqRouter, "bar.com"); + ftTransportFactory = new DummyFileTransferTransporterFactory(s5bRegistry, bytestreamServerManager, s5bProxy, idGen, connectionFactory, timerFactory, crypto.get(), iqRouter); } void tearDown() { + delete ftTransportFactory; + delete bytestreamServerManager; + delete s5bProxy; delete idGen; delete s5bRegistry; delete connectionFactory; @@ -199,27 +138,42 @@ public: void test_SendSessionInitiateOnStart() { boost::shared_ptr transfer = createTestling(); transfer->start(); + FakeJingleSession::InitiateCall call = getCall(0); JingleFileTransferDescription::ref description = boost::dynamic_pointer_cast(call.description); CPPUNIT_ASSERT(description); - CPPUNIT_ASSERT_EQUAL(static_cast(1), description->getOffers().size()); - CPPUNIT_ASSERT(static_cast(1048576) == description->getOffers()[0].getSize()); + CPPUNIT_ASSERT(static_cast(1048576) == description->getFileInfo().getSize()); JingleS5BTransportPayload::ref transport = boost::dynamic_pointer_cast(call.payload); CPPUNIT_ASSERT(transport); } - void test_IBBStartsAfterSendingSessionAccept() { + void test_FallbackToIBBAfterFailingS5B() { boost::shared_ptr transfer = createTestling(); transfer->start(); FakeJingleSession::InitiateCall call = getCall(0); - // FIXME: we initiate with SOCSK5 now and not IBB, needs to be fixed. - /* - fakeJingleSession->onSessionAcceptReceived(call.id, call.description, call.payload); + + fakeJingleSession->handleSessionAcceptReceived(call.id, call.description, call.payload); + + // send candidate failure + JingleS5BTransportPayload::ref candidateFailurePayload = boost::make_shared(); + candidateFailurePayload->setCandidateError(true); + candidateFailurePayload->setSessionID(call.payload->getSessionID()); + fakeJingleSession->handleTransportInfoReceived(call.id, candidateFailurePayload); + + // no S5B candidates -> fallback to IBB + // call at position 1 is the candidate our candidate error + FakeJingleSession::ReplaceTransportCall replaceCall = getCall(2); + + // accept transport replace + fakeJingleSession->handleTransportAcceptReceived(replaceCall.id, replaceCall.payload); + IQ::ref iqOpenStanza = stanzaChannel->getStanzaAtIndex(0); CPPUNIT_ASSERT(iqOpenStanza); - */ + IBB::ref ibbOpen = iqOpenStanza->getPayload(); + CPPUNIT_ASSERT(ibbOpen); + CPPUNIT_ASSERT_EQUAL(IBB::Open, ibbOpen->getAction()); } void test_ReceiveSessionTerminateAfterSessionInitiate() { @@ -231,7 +185,7 @@ public: FTStatusHelper helper; helper.finishedCalled = false; transfer->onFinished.connect(bind(&FTStatusHelper::handleFileTransferFinished, &helper, _1)); - fakeJingleSession->onSessionTerminateReceived(JinglePayload::Reason(JinglePayload::Reason::Busy)); + fakeJingleSession->handleSessionTerminateReceived(JinglePayload::Reason(JinglePayload::Reason::Busy)); CPPUNIT_ASSERT_EQUAL(true, helper.finishedCalled); CPPUNIT_ASSERT(FileTransferError::PeerError == helper.error); } @@ -242,7 +196,7 @@ public: private: void addFileTransferDescription() { boost::shared_ptr desc = boost::make_shared(); - desc->addOffer(StreamInitiationFileInfo()); + desc->setFileInfo(JingleFileTransferFileInfo()); jingleContentPayload->addDescription(desc); } @@ -277,8 +231,8 @@ private: boost::shared_ptr stream; FakeJingleSession* fakeJingleSession; boost::shared_ptr jingleContentPayload; - boost::shared_ptr fakeRJTCSF; - boost::shared_ptr fakeLJTCF; + FileTransferTransporterFactory* ftTransportFactory; + SOCKS5BytestreamServerManager* bytestreamServerManager; DummyStanzaChannel* stanzaChannel; IQRouter* iqRouter; IDGenerator* idGen; @@ -287,8 +241,11 @@ private: SOCKS5BytestreamProxiesManager* s5bProxy; DummyTimerFactory* timerFactory; DummyConnectionFactory* connectionFactory; + DummyConnectionServerFactory* serverConnectionFactory; boost::shared_ptr crypto; + NetworkEnvironment* networkEnvironment; + NATTraverser* natTraverser; + DomainNameResolver* resolver; }; CPPUNIT_TEST_SUITE_REGISTRATION(OutgoingJingleFileTransferTest); -#endif diff --git a/Swiften/Jingle/FakeJingleSession.cpp b/Swiften/Jingle/FakeJingleSession.cpp index 3b94da7..864dd53 100644 --- a/Swiften/Jingle/FakeJingleSession.cpp +++ b/Swiften/Jingle/FakeJingleSession.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2014 Isode Limited. + * Copyright (c) 2014-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -61,4 +61,20 @@ void FakeJingleSession::handleTransportReplaceReceived(const JingleContentID& co notifyListeners(&JingleSessionListener::handleTransportReplaceReceived, contentID, transport); } +void FakeJingleSession::handleTransportAcceptReceived(const JingleContentID& contentID, JingleTransportPayload::ref transport) { + notifyListeners(&JingleSessionListener::handleTransportAcceptReceived, contentID, transport); +} + +void FakeJingleSession::handleTransportInfoReceived(const JingleContentID& contentID, JingleTransportPayload::ref transport) { + notifyListeners(&JingleSessionListener::handleTransportInfoReceived, contentID, transport); +} + +void FakeJingleSession::handleSessionTerminateReceived(boost::optional reason) { + notifyListeners(&JingleSessionListener::handleSessionTerminateReceived, reason); +} + +void FakeJingleSession::handleSessionAcceptReceived(const JingleContentID& contentID, boost::shared_ptr desc, boost::shared_ptr payload) { + notifyListeners(&JingleSessionListener::handleSessionAcceptReceived, contentID, desc, payload); +} + } diff --git a/Swiften/Jingle/FakeJingleSession.h b/Swiften/Jingle/FakeJingleSession.h index 19028ad..f250b1a 100644 --- a/Swiften/Jingle/FakeJingleSession.h +++ b/Swiften/Jingle/FakeJingleSession.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2013-2014 Isode Limited. + * Copyright (c) 2013-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -96,7 +96,15 @@ namespace Swift { virtual void sendTransportReject(const JingleContentID&, JingleTransportPayload::ref) SWIFTEN_OVERRIDE; virtual void sendTransportReplace(const JingleContentID&, JingleTransportPayload::ref) SWIFTEN_OVERRIDE; + void handleSessionTerminateReceived(boost::optional); + void handleSessionAcceptReceived(const JingleContentID&, boost::shared_ptr, boost::shared_ptr); + void handleSessionInfoReceived(boost::shared_ptr); + void handleTransportReplaceReceived(const JingleContentID&, JingleTransportPayload::ref); + void handleTransportAcceptReceived(const JingleContentID&, boost::shared_ptr); + void handleTransportInfoReceived(const JingleContentID&, boost::shared_ptr); + void handleTransportRejectReceived(const JingleContentID&, boost::shared_ptr); + void handleTransportInfoAcknowledged(const std::string& id); public: std::vector calledCommands; -- cgit v0.10.2-6-g49f6