summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/FileTransfer/UnitTest')
-rw-r--r--Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h194
-rw-r--r--Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp195
2 files changed, 270 insertions, 119 deletions
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 <string>
+
+#include <Swiften/Base/API.h>
+#include <Swiften/StringCodecs/Hexify.h>
+#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/FileTransfer/FileTransferTransporter.h>
+#include <Swiften/FileTransfer/FileTransferTransporterFactory.h>
+#include <Swiften/FileTransfer/IBBReceiveSession.h>
+#include <Swiften/FileTransfer/IBBReceiveTransportSession.h>
+#include <Swiften/FileTransfer/IBBSendTransportSession.h>
+#include <Swiften/FileTransfer/IBBSendSession.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
+#include <Swiften/FileTransfer/TransportSession.h>
+#include <Swiften/JID/JID.h>
+
+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<JingleS5BTransportPayload::Candidate> candidates;
+ onLocalCandidatesGenerated(s5bSessionID_, candidates, getSOCKS5DstAddr());
+ }
+
+ virtual void stopGeneratingLocalCandidates() {
+ }
+
+ virtual void addRemoteCandidates(const std::vector<JingleS5BTransportPayload::Candidate>&, const std::string&) {
+ }
+
+ virtual void startTryingRemoteCandidates() {
+ onRemoteCandidateSelectFinished(s5bSessionID_, boost::optional<JingleS5BTransportPayload::Candidate>());
+ }
+
+ virtual void stopTryingRemoteCandidates() {
+ }
+
+ virtual void startActivatingProxy(const JID& /* proxy */) {
+ }
+
+ virtual void stopActivatingProxy() {
+ }
+
+ virtual boost::shared_ptr<TransportSession> createIBBSendSession(const std::string& sessionID, unsigned int blockSize, boost::shared_ptr<ReadBytestream> stream) {
+ boost::shared_ptr<IBBSendSession> ibbSession = boost::make_shared<IBBSendSession>(
+ sessionID, initiator_, responder_, stream, iqRouter_);
+ ibbSession->setBlockSize(blockSize);
+ return boost::make_shared<IBBSendTransportSession>(ibbSession);
+ }
+
+ virtual boost::shared_ptr<TransportSession> createIBBReceiveSession(const std::string& sessionID, unsigned long long size, boost::shared_ptr<WriteBytestream> stream) {
+ boost::shared_ptr<IBBReceiveSession> ibbSession = boost::make_shared<IBBReceiveSession>(
+ sessionID, initiator_, responder_, size, stream, iqRouter_);
+ return boost::make_shared<IBBReceiveTransportSession>(ibbSession);
+ }
+
+ virtual boost::shared_ptr<TransportSession> createRemoteCandidateSession(
+ boost::shared_ptr<ReadBytestream>, const JingleS5BTransportPayload::Candidate& /* candidate */) {
+ return boost::shared_ptr<TransportSession>();
+ }
+
+ virtual boost::shared_ptr<TransportSession> createRemoteCandidateSession(
+ boost::shared_ptr<WriteBytestream>, const JingleS5BTransportPayload::Candidate& /* candidate */) {
+ return boost::shared_ptr<TransportSession>();
+ }
+
+ virtual boost::shared_ptr<TransportSession> createLocalCandidateSession(
+ boost::shared_ptr<ReadBytestream>, const JingleS5BTransportPayload::Candidate& /* candidate */) {
+ return boost::shared_ptr<TransportSession>();
+ }
+
+ virtual boost::shared_ptr<TransportSession> createLocalCandidateSession(
+ boost::shared_ptr<WriteBytestream>, const JingleS5BTransportPayload::Candidate& /* candidate */) {
+ return boost::shared_ptr<TransportSession>();
+ }
+
+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 <boost/optional.hpp>
#include <boost/smart_ptr/make_shared.hpp>
-#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h>
-#include <Swiften/Jingle/FakeJingleSession.h>
-#include <Swiften/Queries/IQRouter.h>
+#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/IDGenerator.h>
+#include <Swiften/Base/Override.h>
#include <Swiften/Client/DummyStanzaChannel.h>
-#include <Swiften/FileTransfer/ByteArrayReadBytestream.h>
-#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
-#include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
-
+#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/Crypto/PlatformCryptoProvider.h>
+#include <Swiften/Elements/IBB.h>
+#include <Swiften/Elements/JingleFileTransferDescription.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/Override.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/FileTransfer/ByteArrayReadBytestream.h>
+#include <Swiften/FileTransfer/DefaultFileTransferTransporterFactory.h>
+#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h>
+#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
+#include <Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h>
+#include <Swiften/Jingle/FakeJingleSession.h>
#include <Swiften/Network/ConnectionFactory.h>
+#include <Swiften/Network/DummyConnection.h>
#include <Swiften/Network/DummyConnectionFactory.h>
-#include <Swiften/Crypto/CryptoProvider.h>
-#include <Swiften/Crypto/PlatformCryptoProvider.h>
-
-#include <Swiften/Base/Log.h>
+#include <Swiften/Network/DummyConnectionServer.h>
+#include <Swiften/Network/DummyConnectionServerFactory.h>
+#include <Swiften/Network/DummyTimerFactory.h>
+#include <Swiften/Network/PlatformNATTraversalWorker.h>
+#include <Swiften/Network/PlatformNetworkEnvironment.h>
+#include <Swiften/Queries/IQRouter.h>
#include <iostream>
-#if 0
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:
- void emitonLocalTransportCandidatesGenerated(const std::vector<JingleS5BTransportPayload::Candidate>& 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<JingleTransportPayload>();
- //payL->setSessionID(payload->getSessionID());
- // JingleS5BTransportPayload::ref payL = boost::make_shared<JingleS5BTransportPayload>();
-
- onLocalTransportCandidatesGenerated(std::vector<JingleS5BTransportPayload::Candidate>());
- }
-
- 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<OutgoingJingleFileTransfer> 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<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(boost::shared_ptr<JingleSession>(fakeJingleSession), fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, idGen, JID(), to, stream, fileInfo, s5bRegistry, s5bProxy, crypto.get()));
+ return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(
+ to,
+ boost::shared_ptr<JingleSession>(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<CryptoProvider>(PlatformCryptoProvider::create());
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);
+ 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<ByteArrayReadBytestream>(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<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());
+ CPPUNIT_ASSERT(static_cast<size_t>(1048576) == description->getFileInfo().getSize());
JingleS5BTransportPayload::ref transport = boost::dynamic_pointer_cast<JingleS5BTransportPayload>(call.payload);
CPPUNIT_ASSERT(transport);
}
- void test_IBBStartsAfterSendingSessionAccept() {
+ void test_FallbackToIBBAfterFailingS5B() {
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);
+
+ fakeJingleSession->handleSessionAcceptReceived(call.id, call.description, call.payload);
+
+ // send candidate failure
+ JingleS5BTransportPayload::ref candidateFailurePayload = boost::make_shared<JingleS5BTransportPayload>();
+ 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<FakeJingleSession::ReplaceTransportCall>(2);
+
+ // accept transport replace
+ fakeJingleSession->handleTransportAcceptReceived(replaceCall.id, replaceCall.payload);
+
IQ::ref iqOpenStanza = stanzaChannel->getStanzaAtIndex<IQ>(0);
CPPUNIT_ASSERT(iqOpenStanza);
- */
+ IBB::ref ibbOpen = iqOpenStanza->getPayload<IBB>();
+ 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<JingleFileTransferDescription> desc = boost::make_shared<JingleFileTransferDescription>();
- desc->addOffer(StreamInitiationFileInfo());
+ desc->setFileInfo(JingleFileTransferFileInfo());
jingleContentPayload->addDescription(desc);
}
@@ -277,8 +231,8 @@ private:
boost::shared_ptr<ByteArrayReadBytestream> stream;
FakeJingleSession* fakeJingleSession;
boost::shared_ptr<JingleContentPayload> jingleContentPayload;
- boost::shared_ptr<OFakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF;
- boost::shared_ptr<OFakeLocalJingleTransportCandidateGeneratorFactory> 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<CryptoProvider> crypto;
+ NetworkEnvironment* networkEnvironment;
+ NATTraverser* natTraverser;
+ DomainNameResolver* resolver;
};
CPPUNIT_TEST_SUITE_REGISTRATION(OutgoingJingleFileTransferTest);
-#endif