summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp')
-rw-r--r--Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp283
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);