diff options
Diffstat (limited to 'Swiften/FileTransfer/UnitTest')
8 files changed, 1385 insertions, 1385 deletions
diff --git a/Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h b/Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h index d08b5c3..70d25a5 100644 --- a/Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h +++ b/Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h @@ -21,36 +21,36 @@ #include <Swiften/FileTransfer/FileTransferManager.h> namespace Swift { - class S5BProxyRequest; - class FileTransferOptions; - - class DummyFileTransferManager : public FileTransferManager { - public: - DummyFileTransferManager() : FileTransferManager() { - } - - virtual OutgoingFileTransfer::ref createOutgoingFileTransfer( - const JID&, - const boost::filesystem::path&, - const std::string&, - boost::shared_ptr<ReadBytestream>, - const FileTransferOptions&) SWIFTEN_OVERRIDE { - return OutgoingFileTransfer::ref(); - } - - virtual OutgoingFileTransfer::ref createOutgoingFileTransfer( - const JID&, - const std::string&, - const std::string&, - const boost::uintmax_t, - const boost::posix_time::ptime&, - boost::shared_ptr<ReadBytestream>, - const FileTransferOptions&) SWIFTEN_OVERRIDE { - return OutgoingFileTransfer::ref(); - } - - virtual void addS5BProxy(boost::shared_ptr<S5BProxyRequest>) { - } - - }; + class S5BProxyRequest; + class FileTransferOptions; + + class DummyFileTransferManager : public FileTransferManager { + public: + DummyFileTransferManager() : FileTransferManager() { + } + + virtual OutgoingFileTransfer::ref createOutgoingFileTransfer( + const JID&, + const boost::filesystem::path&, + const std::string&, + boost::shared_ptr<ReadBytestream>, + const FileTransferOptions&) SWIFTEN_OVERRIDE { + return OutgoingFileTransfer::ref(); + } + + virtual OutgoingFileTransfer::ref createOutgoingFileTransfer( + const JID&, + const std::string&, + const std::string&, + const boost::uintmax_t, + const boost::posix_time::ptime&, + boost::shared_ptr<ReadBytestream>, + const FileTransferOptions&) SWIFTEN_OVERRIDE { + return OutgoingFileTransfer::ref(); + } + + virtual void addS5BProxy(boost::shared_ptr<S5BProxyRequest>) { + } + + }; } diff --git a/Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h b/Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h index 00a931f..59fc40a 100644 --- a/Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h +++ b/Swiften/FileTransfer/UnitTest/DummyFileTransferTransporterFactory.h @@ -28,175 +28,175 @@ namespace Swift { class DummyFileTransferTransporter : public FileTransferTransporter { public: - enum Role { - Initiator, - Responder - }; + 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& ftOptions) : initiator_(initiator), responder_(responder), role_(role), s5bRegistry_(s5bRegistry), crypto_(cryptoProvider), iqRouter_(iqRouter), ftOptions_(ftOptions) { - - } - - void initialize() { - s5bSessionID_ = s5bRegistry_->generateSessionID(); - } - - virtual void startGeneratingLocalCandidates() { - std::vector<JingleS5BTransportPayload::Candidate> candidates; - if (ftOptions_.isDirectAllowed()) { - JingleS5BTransportPayload::Candidate candidate; - candidate.cid = "123"; - candidate.priority = 1235; - candidates.push_back(candidate); - } - 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>(); - } + 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& ftOptions) : initiator_(initiator), responder_(responder), role_(role), s5bRegistry_(s5bRegistry), crypto_(cryptoProvider), iqRouter_(iqRouter), ftOptions_(ftOptions) { + + } + + void initialize() { + s5bSessionID_ = s5bRegistry_->generateSessionID(); + } + + virtual void startGeneratingLocalCandidates() { + std::vector<JingleS5BTransportPayload::Candidate> candidates; + if (ftOptions_.isDirectAllowed()) { + JingleS5BTransportPayload::Candidate candidate; + candidate.cid = "123"; + candidate.priority = 1235; + candidates.push_back(candidate); + } + 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()))); - } + 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_; - FileTransferOptions ftOptions_; + JID initiator_; + JID responder_; + Role role_; + SOCKS5BytestreamRegistry* s5bRegistry_; + CryptoProvider* crypto_; + std::string s5bSessionID_; + IQRouter* iqRouter_; + FileTransferOptions ftOptions_; }; 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; - } + 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_; + SOCKS5BytestreamRegistry* s5bRegistry_; + SOCKS5BytestreamServerManager* s5bServerManager_; + SOCKS5BytestreamProxiesManager* s5bProxy_; + IDGenerator* idGenerator_; + ConnectionFactory* connectionFactory_; + TimerFactory* timerFactory_; + CryptoProvider* cryptoProvider_; + IQRouter* iqRouter_; }; } diff --git a/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp b/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp index 2678758..d78f4f0 100644 --- a/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp @@ -22,166 +22,166 @@ using namespace Swift; class IBBReceiveSessionTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(IBBReceiveSessionTest); - CPPUNIT_TEST(testOpen); - CPPUNIT_TEST(testReceiveData); - CPPUNIT_TEST(testReceiveMultipleData); - CPPUNIT_TEST(testReceiveDataForOtherSession); - CPPUNIT_TEST(testReceiveDataOutOfOrder); - CPPUNIT_TEST(testReceiveLastData); - CPPUNIT_TEST(testReceiveClose); - CPPUNIT_TEST(testStopWhileActive); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - stanzaChannel = new DummyStanzaChannel(); - iqRouter = new IQRouter(stanzaChannel); - finished = false; - bytestream = boost::make_shared<ByteArrayWriteBytestream>(); - } + CPPUNIT_TEST_SUITE(IBBReceiveSessionTest); + CPPUNIT_TEST(testOpen); + CPPUNIT_TEST(testReceiveData); + CPPUNIT_TEST(testReceiveMultipleData); + CPPUNIT_TEST(testReceiveDataForOtherSession); + CPPUNIT_TEST(testReceiveDataOutOfOrder); + CPPUNIT_TEST(testReceiveLastData); + CPPUNIT_TEST(testReceiveClose); + CPPUNIT_TEST(testStopWhileActive); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + finished = false; + bytestream = boost::make_shared<ByteArrayWriteBytestream>(); + } - void tearDown() { - delete iqRouter; - delete stanzaChannel; - } - - void testOpen() { - boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); - testling->start(); - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + void tearDown() { + delete iqRouter; + delete stanzaChannel; + } + + void testOpen() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); - CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(0, "id-open")); - CPPUNIT_ASSERT(!finished); - - testling->stop(); - } + CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(0, "id-open")); + CPPUNIT_ASSERT(!finished); + + testling->stop(); + } - void testReceiveData() { - boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); - testling->start(); - 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(stanzaChannel->isResultAtIndex(1, "id-a")); - CPPUNIT_ASSERT(createByteArray("abc") == bytestream->getData()); - CPPUNIT_ASSERT(!finished); - - testling->stop(); - } - - void testReceiveMultipleData() { - boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); - testling->start(); - 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")); - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 1, createByteArray("def")), "foo@bar.com/baz", "id-b")); - - CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(2, "id-b")); - CPPUNIT_ASSERT(createByteArray("abcdef") == bytestream->getData()); - CPPUNIT_ASSERT(!finished); - - testling->stop(); - } - - void testReceiveDataForOtherSession() { - boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); - testling->start(); - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); - - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("othersession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); - - CPPUNIT_ASSERT(stanzaChannel->isErrorAtIndex(1, "id-a")); - - testling->stop(); - } - - void testReceiveDataOutOfOrder() { - boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); - testling->start(); - 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")); - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("def")), "foo@bar.com/baz", "id-b")); - - CPPUNIT_ASSERT(stanzaChannel->isErrorAtIndex(2, "id-b")); - CPPUNIT_ASSERT(finished); - CPPUNIT_ASSERT(error); - - testling->stop(); - } - - void testReceiveLastData() { - boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession", 6)); - testling->start(); - 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")); - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 1, createByteArray("def")), "foo@bar.com/baz", "id-b")); - - CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(2, "id-b")); - CPPUNIT_ASSERT(createByteArray("abcdef") == bytestream->getData()); - CPPUNIT_ASSERT(finished); - CPPUNIT_ASSERT(!error); - - testling->stop(); - } - - void testReceiveClose() { - boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); - testling->start(); - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); - - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBClose("mysession"), "foo@bar.com/baz", "id-close")); + void testReceiveData() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + 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(stanzaChannel->isResultAtIndex(1, "id-a")); + CPPUNIT_ASSERT(createByteArray("abc") == bytestream->getData()); + CPPUNIT_ASSERT(!finished); + + testling->stop(); + } + + void testReceiveMultipleData() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + 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")); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 1, createByteArray("def")), "foo@bar.com/baz", "id-b")); + + CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(2, "id-b")); + CPPUNIT_ASSERT(createByteArray("abcdef") == bytestream->getData()); + CPPUNIT_ASSERT(!finished); + + testling->stop(); + } + + void testReceiveDataForOtherSession() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("othersession", 0, createByteArray("abc")), "foo@bar.com/baz", "id-a")); + + CPPUNIT_ASSERT(stanzaChannel->isErrorAtIndex(1, "id-a")); + + testling->stop(); + } + + void testReceiveDataOutOfOrder() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + 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")); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, createByteArray("def")), "foo@bar.com/baz", "id-b")); + + CPPUNIT_ASSERT(stanzaChannel->isErrorAtIndex(2, "id-b")); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(error); + + testling->stop(); + } + + void testReceiveLastData() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession", 6)); + testling->start(); + 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")); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 1, createByteArray("def")), "foo@bar.com/baz", "id-b")); + + CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(2, "id-b")); + CPPUNIT_ASSERT(createByteArray("abcdef") == bytestream->getData()); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(!error); + + testling->stop(); + } + + void testReceiveClose() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBClose("mysession"), "foo@bar.com/baz", "id-close")); - CPPUNIT_ASSERT(finished); - CPPUNIT_ASSERT(error); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(error); - testling->stop(); - } + testling->stop(); + } - void testStopWhileActive() { - boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); - testling->start(); - stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + void testStopWhileActive() { + boost::shared_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); + testling->start(); + stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); - testling->stop(); + testling->stop(); - CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); - IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); - CPPUNIT_ASSERT_EQUAL(IBB::Close, ibb->getAction()); - CPPUNIT_ASSERT_EQUAL(std::string("mysession"), ibb->getStreamID()); - CPPUNIT_ASSERT(finished); - CPPUNIT_ASSERT(!error); - } + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Close, ibb->getAction()); + CPPUNIT_ASSERT_EQUAL(std::string("mysession"), ibb->getStreamID()); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(!error); + } - private: - IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { - IQ::ref request = IQ::createRequest(IQ::Set, JID("baz@fum.com/dum"), id, ibb); - request->setFrom(from); - return request; - } + private: + IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { + IQ::ref request = IQ::createRequest(IQ::Set, JID("baz@fum.com/dum"), id, ibb); + request->setFrom(from); + return request; + } - IBBReceiveSession* createSession(const std::string& from, const std::string& id, size_t size = 0x1000) { - IBBReceiveSession* session = new IBBReceiveSession(id, JID(from), JID(), size, bytestream, iqRouter); - session->onFinished.connect(boost::bind(&IBBReceiveSessionTest::handleFinished, this, _1)); - return session; - } + IBBReceiveSession* createSession(const std::string& from, const std::string& id, size_t size = 0x1000) { + IBBReceiveSession* session = new IBBReceiveSession(id, JID(from), JID(), size, bytestream, iqRouter); + session->onFinished.connect(boost::bind(&IBBReceiveSessionTest::handleFinished, this, _1)); + return session; + } - void handleFinished(boost::optional<FileTransferError> error) { - finished = true; - this->error = error; - } + void handleFinished(boost::optional<FileTransferError> error) { + finished = true; + this->error = error; + } - private: - DummyStanzaChannel* stanzaChannel; - IQRouter* iqRouter; - bool finished; - boost::optional<FileTransferError> error; - boost::shared_ptr<ByteArrayWriteBytestream> bytestream; + private: + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + bool finished; + boost::optional<FileTransferError> error; + boost::shared_ptr<ByteArrayWriteBytestream> bytestream; }; CPPUNIT_TEST_SUITE_REGISTRATION(IBBReceiveSessionTest); diff --git a/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp b/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp index a1c9c4c..e417c77 100644 --- a/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp @@ -20,213 +20,213 @@ using namespace Swift; class IBBSendSessionTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(IBBSendSessionTest); - CPPUNIT_TEST(testStart); - CPPUNIT_TEST(testStart_ResponseStartsSending); - CPPUNIT_TEST(testResponseContinuesSending); - CPPUNIT_TEST(testRespondToAllFinishes); - CPPUNIT_TEST(testErrorResponseFinishesWithError); - CPPUNIT_TEST(testStopDuringSessionCloses); - CPPUNIT_TEST(testStopAfterFinishedDoesNotClose); - CPPUNIT_TEST(testDataStreamPauseStopsSendingData); - CPPUNIT_TEST(testDataStreamResumeAfterPauseSendsData); - CPPUNIT_TEST(testDataStreamResumeBeforePauseDoesNotSendData); - CPPUNIT_TEST(testDataStreamResumeAfterResumeDoesNotSendData); - - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - stanzaChannel = new DummyStanzaChannel(); - iqRouter = new IQRouter(stanzaChannel); - bytestream = boost::make_shared<ByteArrayReadBytestream>(createByteArray("abcdefg")); - finished = false; - } - - void tearDown() { - delete iqRouter; - delete stanzaChannel; - } - - void testStart() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - testling->setBlockSize(1234); - - testling->start(); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); - CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(0, JID("foo@bar.com/baz"), IQ::Set)); - IBB::ref ibb = stanzaChannel->sentStanzas[0]->getPayload<IBB>(); - CPPUNIT_ASSERT_EQUAL(IBB::Open, ibb->getAction()); - CPPUNIT_ASSERT_EQUAL(1234, ibb->getBlockSize()); - CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); - } - - void testStart_ResponseStartsSending() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - testling->setBlockSize(3); - testling->start(); - - stanzaChannel->onIQReceived(createIBBResult()); - - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); - CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); - IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); - CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); - CPPUNIT_ASSERT(createByteArray("abc") == ibb->getData()); - CPPUNIT_ASSERT_EQUAL(0, ibb->getSequenceNumber()); - CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); - } - - void testResponseContinuesSending() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - testling->setBlockSize(3); - testling->start(); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - - CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(stanzaChannel->sentStanzas.size())); - CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(2, JID("foo@bar.com/baz"), IQ::Set)); - IBB::ref ibb = stanzaChannel->sentStanzas[2]->getPayload<IBB>(); - CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); - CPPUNIT_ASSERT(createByteArray("def") == ibb->getData()); - CPPUNIT_ASSERT_EQUAL(1, ibb->getSequenceNumber()); - CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); - } - - void testRespondToAllFinishes() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - testling->setBlockSize(3); - testling->start(); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - - CPPUNIT_ASSERT(finished); - CPPUNIT_ASSERT(!error); - } - - void testErrorResponseFinishesWithError() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - testling->setBlockSize(3); - testling->start(); - stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID())); - - CPPUNIT_ASSERT(finished); - CPPUNIT_ASSERT(error); - } - - void testStopDuringSessionCloses() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - testling->setBlockSize(3); - testling->start(); - testling->stop(); - - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); - CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); - IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); - CPPUNIT_ASSERT_EQUAL(IBB::Close, ibb->getAction()); - CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); - CPPUNIT_ASSERT(finished); - CPPUNIT_ASSERT(!error); - } - - void testStopAfterFinishedDoesNotClose() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - testling->setBlockSize(16); - testling->start(); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - CPPUNIT_ASSERT(finished); - - testling->stop(); - - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); - } - - void testDataStreamPauseStopsSendingData() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - bytestream->setDataComplete(false); - testling->setBlockSize(3); - testling->start(); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - - CPPUNIT_ASSERT(!finished); - CPPUNIT_ASSERT(!error); - - CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(stanzaChannel->sentStanzas.size())); - } - - void testDataStreamResumeAfterPauseSendsData() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - bytestream->setDataComplete(false); - testling->setBlockSize(3); - testling->start(); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - - bytestream->addData(createByteArray("xyz")); - - CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(stanzaChannel->sentStanzas.size())); - } - - void testDataStreamResumeBeforePauseDoesNotSendData() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - bytestream->setDataComplete(false); - testling->setBlockSize(3); - testling->start(); - stanzaChannel->onIQReceived(createIBBResult()); - - bytestream->addData(createByteArray("xyz")); - - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); - } - - void testDataStreamResumeAfterResumeDoesNotSendData() { - boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); - bytestream->setDataComplete(false); - testling->setBlockSize(3); - testling->start(); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - stanzaChannel->onIQReceived(createIBBResult()); - - bytestream->addData(createByteArray("xyz")); - bytestream->addData(createByteArray("xuv")); - - CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(stanzaChannel->sentStanzas.size())); - } - - private: - IQ::ref createIBBResult() { - return IQ::createResult(JID("baz@fum.com/dum"), stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getTo(), stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getID(), boost::shared_ptr<IBB>()); - } - - private: - boost::shared_ptr<IBBSendSession> createSession(const std::string& to) { - boost::shared_ptr<IBBSendSession> session(new IBBSendSession("myid", JID(), JID(to), bytestream, iqRouter)); - session->onFinished.connect(boost::bind(&IBBSendSessionTest::handleFinished, this, _1)); - return session; - } - - void handleFinished(boost::optional<FileTransferError> error) { - finished = true; - this->error = error; - } - - private: - DummyStanzaChannel* stanzaChannel; - IQRouter* iqRouter; - bool finished; - boost::optional<FileTransferError> error; - boost::shared_ptr<ByteArrayReadBytestream> bytestream; + CPPUNIT_TEST_SUITE(IBBSendSessionTest); + CPPUNIT_TEST(testStart); + CPPUNIT_TEST(testStart_ResponseStartsSending); + CPPUNIT_TEST(testResponseContinuesSending); + CPPUNIT_TEST(testRespondToAllFinishes); + CPPUNIT_TEST(testErrorResponseFinishesWithError); + CPPUNIT_TEST(testStopDuringSessionCloses); + CPPUNIT_TEST(testStopAfterFinishedDoesNotClose); + CPPUNIT_TEST(testDataStreamPauseStopsSendingData); + CPPUNIT_TEST(testDataStreamResumeAfterPauseSendsData); + CPPUNIT_TEST(testDataStreamResumeBeforePauseDoesNotSendData); + CPPUNIT_TEST(testDataStreamResumeAfterResumeDoesNotSendData); + + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + bytestream = boost::make_shared<ByteArrayReadBytestream>(createByteArray("abcdefg")); + finished = false; + } + + void tearDown() { + delete iqRouter; + delete stanzaChannel; + } + + void testStart() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(1234); + + testling->start(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(0, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[0]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Open, ibb->getAction()); + CPPUNIT_ASSERT_EQUAL(1234, ibb->getBlockSize()); + CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); + } + + void testStart_ResponseStartsSending() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + + stanzaChannel->onIQReceived(createIBBResult()); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); + CPPUNIT_ASSERT(createByteArray("abc") == ibb->getData()); + CPPUNIT_ASSERT_EQUAL(0, ibb->getSequenceNumber()); + CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); + } + + void testResponseContinuesSending() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(2, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[2]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); + CPPUNIT_ASSERT(createByteArray("def") == ibb->getData()); + CPPUNIT_ASSERT_EQUAL(1, ibb->getSequenceNumber()); + CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); + } + + void testRespondToAllFinishes() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(!error); + } + + void testErrorResponseFinishesWithError() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(IQ::createError(JID("baz@fum.com/foo"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID())); + + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(error); + } + + void testStopDuringSessionCloses() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(3); + testling->start(); + testling->stop(); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); + IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); + CPPUNIT_ASSERT_EQUAL(IBB::Close, ibb->getAction()); + CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID()); + CPPUNIT_ASSERT(finished); + CPPUNIT_ASSERT(!error); + } + + void testStopAfterFinishedDoesNotClose() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + testling->setBlockSize(16); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + CPPUNIT_ASSERT(finished); + + testling->stop(); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testDataStreamPauseStopsSendingData() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + bytestream->setDataComplete(false); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + CPPUNIT_ASSERT(!finished); + CPPUNIT_ASSERT(!error); + + CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testDataStreamResumeAfterPauseSendsData() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + bytestream->setDataComplete(false); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + bytestream->addData(createByteArray("xyz")); + + CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testDataStreamResumeBeforePauseDoesNotSendData() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + bytestream->setDataComplete(false); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + + bytestream->addData(createByteArray("xyz")); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testDataStreamResumeAfterResumeDoesNotSendData() { + boost::shared_ptr<IBBSendSession> testling = createSession("foo@bar.com/baz"); + bytestream->setDataComplete(false); + testling->setBlockSize(3); + testling->start(); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + stanzaChannel->onIQReceived(createIBBResult()); + + bytestream->addData(createByteArray("xyz")); + bytestream->addData(createByteArray("xuv")); + + CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + private: + IQ::ref createIBBResult() { + return IQ::createResult(JID("baz@fum.com/dum"), stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getTo(), stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getID(), boost::shared_ptr<IBB>()); + } + + private: + boost::shared_ptr<IBBSendSession> createSession(const std::string& to) { + boost::shared_ptr<IBBSendSession> session(new IBBSendSession("myid", JID(), JID(to), bytestream, iqRouter)); + session->onFinished.connect(boost::bind(&IBBSendSessionTest::handleFinished, this, _1)); + return session; + } + + void handleFinished(boost::optional<FileTransferError> error) { + finished = true; + this->error = error; + } + + private: + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + bool finished; + boost::optional<FileTransferError> error; + boost::shared_ptr<ByteArrayReadBytestream> bytestream; }; CPPUNIT_TEST_SUITE_REGISTRATION(IBBSendSessionTest); diff --git a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp index 2fb39bb..a76773c 100644 --- a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp +++ b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp @@ -48,198 +48,198 @@ using namespace Swift; using namespace boost; 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(); + 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 boost::make_shared<IncomingJingleFileTransfer>(ourJID, shared_ptr<JingleSession>(session), jingleContentPayload, ftTransporterFactory, timerFactory, crypto.get()); - } - - 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() { - crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); - eventLoop = new DummyEventLoop(); - resolver = new StaticDomainNameResolver(eventLoop); - session = boost::make_shared<FakeJingleSession>("foo@bar.com/baz", "mysession"); - jingleContentPayload = make_shared<JingleContentPayload>(); - // fakeRJTCSF = make_shared<FakeRemoteJingleTransportCandidateSelectorFactory>(); - // fakeLJTCF = make_shared<FakeLocalJingleTransportCandidateGeneratorFactory>(); - stanzaChannel = new DummyStanzaChannel(); - connectionFactory = new DummyConnectionFactory(eventLoop); - serverConnectionFactory = new DummyConnectionServerFactory(eventLoop); - iqRouter = new IQRouter(stanzaChannel); - bytestreamRegistry = new SOCKS5BytestreamRegistry(); - networkEnvironment = new PlatformNetworkEnvironment(); - natTraverser = new PlatformNATTraversalWorker(eventLoop); - bytestreamServerManager = new SOCKS5BytestreamServerManager(bytestreamRegistry, serverConnectionFactory, networkEnvironment, natTraverser); - idGenerator = new SimpleIDGenerator(); - timerFactory = new DummyTimerFactory(); - bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory, resolver, iqRouter, "bar.com"); - ftTransporterFactory = new DefaultFileTransferTransporterFactory(bytestreamRegistry, bytestreamServerManager, bytestreamProxy, idGenerator, connectionFactory, timerFactory, crypto.get(), iqRouter); - } - - void tearDown() { - delete ftTransporterFactory; - delete bytestreamProxy; - delete timerFactory; - delete idGenerator; - delete bytestreamServerManager; - delete natTraverser; - delete networkEnvironment; - delete bytestreamRegistry; - delete iqRouter; - delete serverConnectionFactory; - delete connectionFactory; - delete stanzaChannel; - delete resolver; - delete eventLoop; - Log::setLogLevel(Log::error); - } - - // 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->setFileInfo(JingleFileTransferFileInfo("foo.txt", "", 10)); - 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->setFileInfo(JingleFileTransferFileInfo("file.txt", "", 10)); - 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); - - // candidates are gathered - - // 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) - session->handleTransportReplaceReceived(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()); - } + shared_ptr<IncomingJingleFileTransfer> createTestling() { + JID ourJID("our@jid.org/full"); + return boost::make_shared<IncomingJingleFileTransfer>(ourJID, shared_ptr<JingleSession>(session), jingleContentPayload, ftTransporterFactory, timerFactory, crypto.get()); + } + + 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() { + crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); + eventLoop = new DummyEventLoop(); + resolver = new StaticDomainNameResolver(eventLoop); + session = boost::make_shared<FakeJingleSession>("foo@bar.com/baz", "mysession"); + jingleContentPayload = make_shared<JingleContentPayload>(); + // fakeRJTCSF = make_shared<FakeRemoteJingleTransportCandidateSelectorFactory>(); + // fakeLJTCF = make_shared<FakeLocalJingleTransportCandidateGeneratorFactory>(); + stanzaChannel = new DummyStanzaChannel(); + connectionFactory = new DummyConnectionFactory(eventLoop); + serverConnectionFactory = new DummyConnectionServerFactory(eventLoop); + iqRouter = new IQRouter(stanzaChannel); + bytestreamRegistry = new SOCKS5BytestreamRegistry(); + networkEnvironment = new PlatformNetworkEnvironment(); + natTraverser = new PlatformNATTraversalWorker(eventLoop); + bytestreamServerManager = new SOCKS5BytestreamServerManager(bytestreamRegistry, serverConnectionFactory, networkEnvironment, natTraverser); + idGenerator = new SimpleIDGenerator(); + timerFactory = new DummyTimerFactory(); + bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory, resolver, iqRouter, "bar.com"); + ftTransporterFactory = new DefaultFileTransferTransporterFactory(bytestreamRegistry, bytestreamServerManager, bytestreamProxy, idGenerator, connectionFactory, timerFactory, crypto.get(), iqRouter); + } + + void tearDown() { + delete ftTransporterFactory; + delete bytestreamProxy; + delete timerFactory; + delete idGenerator; + delete bytestreamServerManager; + delete natTraverser; + delete networkEnvironment; + delete bytestreamRegistry; + delete iqRouter; + delete serverConnectionFactory; + delete connectionFactory; + delete stanzaChannel; + delete resolver; + delete eventLoop; + Log::setLogLevel(Log::error); + } + + // 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->setFileInfo(JingleFileTransferFileInfo("foo.txt", "", 10)); + 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->setFileInfo(JingleFileTransferFileInfo("file.txt", "", 10)); + 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); + + // candidates are gathered + + // 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) + session->handleTransportReplaceReceived(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()); + } #if 0 - void test_S5BTransferReceiveTest() { - addFileTransferDescription(); - JingleS5BTransportPayload::ref payLoad = addJingleS5BPayload(); - } + void test_S5BTransferReceiveTest() { + addFileTransferDescription(); + JingleS5BTransportPayload::ref payLoad = addJingleS5BPayload(); + } #endif private: - void addFileTransferDescription() { - shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); - desc->setFileInfo(JingleFileTransferFileInfo("file.txt", "", 10)); - 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 < session->calledCommands.size()); - T* cmd = boost::get<T>(&session->calledCommands[index]); - CPPUNIT_ASSERT(cmd); - return *cmd; - } + void addFileTransferDescription() { + shared_ptr<JingleFileTransferDescription> desc = make_shared<JingleFileTransferDescription>(); + desc->setFileInfo(JingleFileTransferFileInfo("file.txt", "", 10)); + 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 < session->calledCommands.size()); + T* cmd = boost::get<T>(&session->calledCommands[index]); + CPPUNIT_ASSERT(cmd); + return *cmd; + } private: - EventLoop* eventLoop; - boost::shared_ptr<CryptoProvider> crypto; - boost::shared_ptr<FakeJingleSession> session; - shared_ptr<JingleContentPayload> jingleContentPayload; -// shared_ptr<FakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF; -// shared_ptr<FakeLocalJingleTransportCandidateGeneratorFactory> fakeLJTCF; - FileTransferTransporterFactory* ftTransporterFactory; - SOCKS5BytestreamServerManager* bytestreamServerManager; - DummyStanzaChannel* stanzaChannel; - IQRouter* iqRouter; - SOCKS5BytestreamRegistry* bytestreamRegistry; - DummyConnectionFactory* connectionFactory; - DummyConnectionServerFactory* serverConnectionFactory; - SOCKS5BytestreamProxiesManager* bytestreamProxy; - DummyTimerFactory* timerFactory; - NetworkEnvironment* networkEnvironment; - NATTraverser* natTraverser; - IDGenerator* idGenerator; - DomainNameResolver* resolver; + EventLoop* eventLoop; + boost::shared_ptr<CryptoProvider> crypto; + boost::shared_ptr<FakeJingleSession> session; + shared_ptr<JingleContentPayload> jingleContentPayload; +// shared_ptr<FakeRemoteJingleTransportCandidateSelectorFactory> fakeRJTCSF; +// shared_ptr<FakeLocalJingleTransportCandidateGeneratorFactory> fakeLJTCF; + FileTransferTransporterFactory* ftTransporterFactory; + SOCKS5BytestreamServerManager* bytestreamServerManager; + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + SOCKS5BytestreamRegistry* bytestreamRegistry; + DummyConnectionFactory* connectionFactory; + DummyConnectionServerFactory* serverConnectionFactory; + SOCKS5BytestreamProxiesManager* bytestreamProxy; + DummyTimerFactory* timerFactory; + NetworkEnvironment* networkEnvironment; + NATTraverser* natTraverser; + IDGenerator* idGenerator; + DomainNameResolver* resolver; }; CPPUNIT_TEST_SUITE_REGISTRATION(IncomingJingleFileTransferTest); diff --git a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp index fee26d5..401463c 100644 --- a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp +++ b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp @@ -52,232 +52,232 @@ using namespace Swift; class OutgoingJingleFileTransferTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(OutgoingJingleFileTransferTest); - CPPUNIT_TEST(test_SendSessionInitiateOnStart); - CPPUNIT_TEST(test_FallbackToIBBAfterFailingS5B); - CPPUNIT_TEST(test_ReceiveSessionTerminateAfterSessionInitiate); - CPPUNIT_TEST(test_DeclineEmitsFinishedStateCanceled); - CPPUNIT_TEST_SUITE_END(); - - class FTStatusHelper { - public: - FTStatusHelper() : finishedCalled(false), error(FileTransferError::UnknownError) { - } - - void handleFileTransferFinished(boost::optional<FileTransferError> error) { - finishedCalled = true; - if (error.is_initialized()) this->error = error.get().getType(); - } - - void handleFileTransferStatusChanged(FileTransfer::State fileTransferSTate) { - state = fileTransferSTate; - } - - public: - bool finishedCalled; - FileTransferError::Type error; - boost::optional<FileTransfer::State> state; - }; + CPPUNIT_TEST_SUITE(OutgoingJingleFileTransferTest); + CPPUNIT_TEST(test_SendSessionInitiateOnStart); + CPPUNIT_TEST(test_FallbackToIBBAfterFailingS5B); + CPPUNIT_TEST(test_ReceiveSessionTerminateAfterSessionInitiate); + CPPUNIT_TEST(test_DeclineEmitsFinishedStateCanceled); + CPPUNIT_TEST_SUITE_END(); + + class FTStatusHelper { + public: + FTStatusHelper() : finishedCalled(false), error(FileTransferError::UnknownError) { + } + + void handleFileTransferFinished(boost::optional<FileTransferError> error) { + finishedCalled = true; + if (error.is_initialized()) this->error = error.get().getType(); + } + + void handleFileTransferStatusChanged(FileTransfer::State fileTransferSTate) { + state = fileTransferSTate; + } + + public: + bool finishedCalled; + FileTransferError::Type error; + boost::optional<FileTransfer::State> state; + }; public: - boost::shared_ptr<OutgoingJingleFileTransfer> createTestling(const FileTransferOptions& options = FileTransferOptions().withAssistedAllowed(false).withDirectAllowed(false).withProxiedAllowed(false)) { - JID to("test@foo.com/bla"); - JingleFileTransferFileInfo fileInfo; - fileInfo.setDescription("some file"); - fileInfo.setName("test.bin"); - fileInfo.addHash(HashElement("sha-1", ByteArray())); - fileInfo.setSize(1024 * 1024); - return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer( - to, - boost::shared_ptr<JingleSession>(fakeJingleSession), - stream, - ftTransportFactory, - timerFactory, - idGen, - fileInfo, - options, - crypto.get())); - } - - 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() { - crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); - fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession"); - jingleContentPayload = boost::make_shared<JingleContentPayload>(); - stanzaChannel = new DummyStanzaChannel(); - iqRouter = new IQRouter(stanzaChannel); - eventLoop = new DummyEventLoop(); - timerFactory = new DummyTimerFactory(); - connectionFactory = new DummyConnectionFactory(eventLoop); - serverConnectionFactory = new DummyConnectionServerFactory(eventLoop); - s5bRegistry = new SOCKS5BytestreamRegistry(); - networkEnvironment = new PlatformNetworkEnvironment(); - natTraverser = new PlatformNATTraversalWorker(eventLoop); - bytestreamServerManager = new SOCKS5BytestreamServerManager(s5bRegistry, serverConnectionFactory, networkEnvironment, natTraverser); - - data.clear(); - for (int n=0; n < 1024 * 1024; ++n) { - data.push_back(34); - } - - 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 s5bProxy; - delete idGen; - delete bytestreamServerManager; - delete natTraverser; - delete networkEnvironment; - delete s5bRegistry; - delete serverConnectionFactory; - 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(static_cast<size_t>(1048576) == description->getFileInfo().getSize()); - - JingleIBBTransportPayload::ref transport = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(call.payload); - CPPUNIT_ASSERT(transport); - } - - void test_FallbackToIBBAfterFailingS5B() { - boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(FileTransferOptions().withAssistedAllowed(true).withDirectAllowed(true).withProxiedAllowed(true)); - transfer->start(); - - FakeJingleSession::InitiateCall call = getCall<FakeJingleSession::InitiateCall>(0); - - CPPUNIT_ASSERT(boost::dynamic_pointer_cast<JingleS5BTransportPayload>(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() { - 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->handleSessionTerminateReceived(JinglePayload::Reason(JinglePayload::Reason::Busy)); - CPPUNIT_ASSERT_EQUAL(true, helper.finishedCalled); - CPPUNIT_ASSERT(FileTransferError::PeerError == helper.error); - } - - void test_DeclineEmitsFinishedStateCanceled() { - 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)); - transfer->onStateChanged.connect(bind(&FTStatusHelper::handleFileTransferStatusChanged, &helper, _1)); - fakeJingleSession->handleSessionTerminateReceived(JinglePayload::Reason(JinglePayload::Reason::Decline)); - CPPUNIT_ASSERT_EQUAL(true, helper.finishedCalled); - CPPUNIT_ASSERT(FileTransferError::UnknownError == helper.error); - CPPUNIT_ASSERT_EQUAL(true, helper.state.is_initialized()); - CPPUNIT_ASSERT(FileTransfer::State::Canceled == helper.state.get().type); - } + boost::shared_ptr<OutgoingJingleFileTransfer> createTestling(const FileTransferOptions& options = FileTransferOptions().withAssistedAllowed(false).withDirectAllowed(false).withProxiedAllowed(false)) { + JID to("test@foo.com/bla"); + JingleFileTransferFileInfo fileInfo; + fileInfo.setDescription("some file"); + fileInfo.setName("test.bin"); + fileInfo.addHash(HashElement("sha-1", ByteArray())); + fileInfo.setSize(1024 * 1024); + return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer( + to, + boost::shared_ptr<JingleSession>(fakeJingleSession), + stream, + ftTransportFactory, + timerFactory, + idGen, + fileInfo, + options, + crypto.get())); + } + + 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() { + crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); + fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession"); + jingleContentPayload = boost::make_shared<JingleContentPayload>(); + stanzaChannel = new DummyStanzaChannel(); + iqRouter = new IQRouter(stanzaChannel); + eventLoop = new DummyEventLoop(); + timerFactory = new DummyTimerFactory(); + connectionFactory = new DummyConnectionFactory(eventLoop); + serverConnectionFactory = new DummyConnectionServerFactory(eventLoop); + s5bRegistry = new SOCKS5BytestreamRegistry(); + networkEnvironment = new PlatformNetworkEnvironment(); + natTraverser = new PlatformNATTraversalWorker(eventLoop); + bytestreamServerManager = new SOCKS5BytestreamServerManager(s5bRegistry, serverConnectionFactory, networkEnvironment, natTraverser); + + data.clear(); + for (int n=0; n < 1024 * 1024; ++n) { + data.push_back(34); + } + + 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 s5bProxy; + delete idGen; + delete bytestreamServerManager; + delete natTraverser; + delete networkEnvironment; + delete s5bRegistry; + delete serverConnectionFactory; + 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(static_cast<size_t>(1048576) == description->getFileInfo().getSize()); + + JingleIBBTransportPayload::ref transport = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(call.payload); + CPPUNIT_ASSERT(transport); + } + + void test_FallbackToIBBAfterFailingS5B() { + boost::shared_ptr<OutgoingJingleFileTransfer> transfer = createTestling(FileTransferOptions().withAssistedAllowed(true).withDirectAllowed(true).withProxiedAllowed(true)); + transfer->start(); + + FakeJingleSession::InitiateCall call = getCall<FakeJingleSession::InitiateCall>(0); + + CPPUNIT_ASSERT(boost::dynamic_pointer_cast<JingleS5BTransportPayload>(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() { + 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->handleSessionTerminateReceived(JinglePayload::Reason(JinglePayload::Reason::Busy)); + CPPUNIT_ASSERT_EQUAL(true, helper.finishedCalled); + CPPUNIT_ASSERT(FileTransferError::PeerError == helper.error); + } + + void test_DeclineEmitsFinishedStateCanceled() { + 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)); + transfer->onStateChanged.connect(bind(&FTStatusHelper::handleFileTransferStatusChanged, &helper, _1)); + fakeJingleSession->handleSessionTerminateReceived(JinglePayload::Reason(JinglePayload::Reason::Decline)); + CPPUNIT_ASSERT_EQUAL(true, helper.finishedCalled); + CPPUNIT_ASSERT(FileTransferError::UnknownError == helper.error); + CPPUNIT_ASSERT_EQUAL(true, helper.state.is_initialized()); + CPPUNIT_ASSERT(FileTransfer::State::Canceled == helper.state.get().type); + } //TODO: some more testcases private: - void addFileTransferDescription() { - boost::shared_ptr<JingleFileTransferDescription> desc = boost::make_shared<JingleFileTransferDescription>(); - desc->setFileInfo(JingleFileTransferFileInfo()); - 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; - } + void addFileTransferDescription() { + boost::shared_ptr<JingleFileTransferDescription> desc = boost::make_shared<JingleFileTransferDescription>(); + desc->setFileInfo(JingleFileTransferFileInfo()); + 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; - FileTransferTransporterFactory* ftTransportFactory; - SOCKS5BytestreamServerManager* bytestreamServerManager; - DummyStanzaChannel* stanzaChannel; - IQRouter* iqRouter; - IDGenerator* idGen; - EventLoop *eventLoop; - SOCKS5BytestreamRegistry* s5bRegistry; - SOCKS5BytestreamProxiesManager* s5bProxy; - DummyTimerFactory* timerFactory; - DummyConnectionFactory* connectionFactory; - DummyConnectionServerFactory* serverConnectionFactory; - boost::shared_ptr<CryptoProvider> crypto; - NetworkEnvironment* networkEnvironment; - NATTraverser* natTraverser; - DomainNameResolver* resolver; + std::vector<unsigned char> data; + boost::shared_ptr<ByteArrayReadBytestream> stream; + FakeJingleSession* fakeJingleSession; + boost::shared_ptr<JingleContentPayload> jingleContentPayload; + FileTransferTransporterFactory* ftTransportFactory; + SOCKS5BytestreamServerManager* bytestreamServerManager; + DummyStanzaChannel* stanzaChannel; + IQRouter* iqRouter; + IDGenerator* idGen; + EventLoop *eventLoop; + SOCKS5BytestreamRegistry* s5bRegistry; + SOCKS5BytestreamProxiesManager* s5bProxy; + DummyTimerFactory* timerFactory; + DummyConnectionFactory* connectionFactory; + DummyConnectionServerFactory* serverConnectionFactory; + boost::shared_ptr<CryptoProvider> crypto; + NetworkEnvironment* networkEnvironment; + NATTraverser* natTraverser; + DomainNameResolver* resolver; }; CPPUNIT_TEST_SUITE_REGISTRATION(OutgoingJingleFileTransferTest); diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp index a0f6033..ceffdb7 100644 --- a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp @@ -43,275 +43,275 @@ using namespace Swift; static boost::mt19937 randomGen; class SOCKS5BytestreamClientSessionTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(SOCKS5BytestreamClientSessionTest); - CPPUNIT_TEST(testForSessionReady); - CPPUNIT_TEST(testErrorHandlingHello); - CPPUNIT_TEST(testErrorHandlingRequest); - CPPUNIT_TEST(testWriteBytestream); - CPPUNIT_TEST(testReadBytestream); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(SOCKS5BytestreamClientSessionTest); + CPPUNIT_TEST(testForSessionReady); + CPPUNIT_TEST(testErrorHandlingHello); + CPPUNIT_TEST(testErrorHandlingRequest); + CPPUNIT_TEST(testWriteBytestream); + CPPUNIT_TEST(testReadBytestream); + CPPUNIT_TEST_SUITE_END(); public: - SOCKS5BytestreamClientSessionTest() : destinationAddressPort(HostAddressPort(HostAddress("127.0.0.1"), 8888)) {} - - void setUp() { - crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); - destination = "092a44d859d19c9eed676b551ee80025903351c2"; - randomGen.seed(static_cast<unsigned int>(time(NULL))); - eventLoop = new DummyEventLoop(); - timerFactory = new DummyTimerFactory(); - connection = boost::make_shared<MockeryConnection>(failingPorts, true, eventLoop); - //connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); - //stream1 = boost::make_shared<ByteArrayReadBytestream>(createByteArray("abcdefg"))); -// connection->onDataRead.connect(boost::bind(&SOCKS5BytestreamClientSessionTest::handleDataRead, this, _1)); - } - - void tearDown() { - //connection.reset(); - delete timerFactory; - delete eventLoop; - } - - void testForSessionReady() { - TestHelper helper; - connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); - - SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); - clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); - - clientSession->start(); - eventLoop->processEvents(); - CPPUNIT_ASSERT(createByteArray("\x05\x01\x00", 3) == helper.unprocessedInput); - - helper.unprocessedInput.clear(); - serverRespondHelloOK(); - eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00\x03", 4), createByteArray(&helper.unprocessedInput[0], 4)); - CPPUNIT_ASSERT_EQUAL(createByteArray(static_cast<char>(destination.size())), createByteArray(static_cast<char>(helper.unprocessedInput[4]))); - CPPUNIT_ASSERT_EQUAL(createByteArray(destination), createByteArray(&helper.unprocessedInput[5], destination.size())); - CPPUNIT_ASSERT_EQUAL(createByteArray("\x00", 1), createByteArray(&helper.unprocessedInput[5 + destination.size()], 1)); - - helper.unprocessedInput.clear(); - serverRespondRequestOK(); - eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); - CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); - } - - void testErrorHandlingHello() { - TestHelper helper; - connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); - - SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); - clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); - - clientSession->start(); - eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00", 3), helper.unprocessedInput); - - helper.unprocessedInput.clear(); - serverRespondHelloAuthFail(); - eventLoop->processEvents(); - - CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); - CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyError); - CPPUNIT_ASSERT_EQUAL(true, connection->disconnectCalled); - } - - void testErrorHandlingRequest() { - TestHelper helper; - connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); - - SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); - clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); - - clientSession->start(); - eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00", 3), helper.unprocessedInput); - - helper.unprocessedInput.clear(); - serverRespondHelloOK(); - eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00\x03", 4), createByteArray(&helper.unprocessedInput[0], 4)); - CPPUNIT_ASSERT_EQUAL(createByteArray(static_cast<char>(destination.size())), createByteArray(static_cast<char>(helper.unprocessedInput[4]))); - CPPUNIT_ASSERT_EQUAL(createByteArray(destination), createByteArray(&helper.unprocessedInput[5], destination.size())); - CPPUNIT_ASSERT_EQUAL(createByteArray("\x00", 1), createByteArray(&helper.unprocessedInput[5 + destination.size()], 1)); - - helper.unprocessedInput.clear(); - serverRespondRequestFail(); - eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); - CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyError); - CPPUNIT_ASSERT_EQUAL(true, connection->disconnectCalled); - } - - void testWriteBytestream() { - TestHelper helper; - connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); - - SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); - clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); - - clientSession->start(); - eventLoop->processEvents(); - - helper.unprocessedInput.clear(); - serverRespondHelloOK(); - eventLoop->processEvents(); - - helper.unprocessedInput.clear(); - serverRespondRequestOK(); - eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); - CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); - - boost::shared_ptr<ByteArrayWriteBytestream> output = boost::make_shared<ByteArrayWriteBytestream>(); - clientSession->startReceiving(output); - - ByteArray transferData = generateRandomByteArray(1024); - connection->onDataRead(createSafeByteArrayRef(vecptr(transferData), transferData.size())); - CPPUNIT_ASSERT_EQUAL(transferData, output->getData()); - } - - void testReadBytestream() { - TestHelper helper; - connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); - - SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); - clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); - - clientSession->start(); - eventLoop->processEvents(); - - helper.unprocessedInput.clear(); - serverRespondHelloOK(); - eventLoop->processEvents(); - - helper.unprocessedInput.clear(); - serverRespondRequestOK(); - eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); - CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); - - helper.unprocessedInput.clear(); - ByteArray transferData = generateRandomByteArray(1024); - boost::shared_ptr<ByteArrayReadBytestream> input = boost::make_shared<ByteArrayReadBytestream>(transferData); - clientSession->startSending(input); - eventLoop->processEvents(); + SOCKS5BytestreamClientSessionTest() : destinationAddressPort(HostAddressPort(HostAddress("127.0.0.1"), 8888)) {} + + void setUp() { + crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); + destination = "092a44d859d19c9eed676b551ee80025903351c2"; + randomGen.seed(static_cast<unsigned int>(time(NULL))); + eventLoop = new DummyEventLoop(); + timerFactory = new DummyTimerFactory(); + connection = boost::make_shared<MockeryConnection>(failingPorts, true, eventLoop); + //connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); + //stream1 = boost::make_shared<ByteArrayReadBytestream>(createByteArray("abcdefg"))); +// connection->onDataRead.connect(boost::bind(&SOCKS5BytestreamClientSessionTest::handleDataRead, this, _1)); + } + + void tearDown() { + //connection.reset(); + delete timerFactory; + delete eventLoop; + } + + void testForSessionReady() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + CPPUNIT_ASSERT(createByteArray("\x05\x01\x00", 3) == helper.unprocessedInput); + + helper.unprocessedInput.clear(); + serverRespondHelloOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00\x03", 4), createByteArray(&helper.unprocessedInput[0], 4)); + CPPUNIT_ASSERT_EQUAL(createByteArray(static_cast<char>(destination.size())), createByteArray(static_cast<char>(helper.unprocessedInput[4]))); + CPPUNIT_ASSERT_EQUAL(createByteArray(destination), createByteArray(&helper.unprocessedInput[5], destination.size())); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x00", 1), createByteArray(&helper.unprocessedInput[5 + destination.size()], 1)); + + helper.unprocessedInput.clear(); + serverRespondRequestOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); + } + + void testErrorHandlingHello() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00", 3), helper.unprocessedInput); + + helper.unprocessedInput.clear(); + serverRespondHelloAuthFail(); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyError); + CPPUNIT_ASSERT_EQUAL(true, connection->disconnectCalled); + } + + void testErrorHandlingRequest() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00", 3), helper.unprocessedInput); + + helper.unprocessedInput.clear(); + serverRespondHelloOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x05\x01\x00\x03", 4), createByteArray(&helper.unprocessedInput[0], 4)); + CPPUNIT_ASSERT_EQUAL(createByteArray(static_cast<char>(destination.size())), createByteArray(static_cast<char>(helper.unprocessedInput[4]))); + CPPUNIT_ASSERT_EQUAL(createByteArray(destination), createByteArray(&helper.unprocessedInput[5], destination.size())); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x00", 1), createByteArray(&helper.unprocessedInput[5 + destination.size()], 1)); + + helper.unprocessedInput.clear(); + serverRespondRequestFail(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyError); + CPPUNIT_ASSERT_EQUAL(true, connection->disconnectCalled); + } + + void testWriteBytestream() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + + helper.unprocessedInput.clear(); + serverRespondHelloOK(); + eventLoop->processEvents(); + + helper.unprocessedInput.clear(); + serverRespondRequestOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); + + boost::shared_ptr<ByteArrayWriteBytestream> output = boost::make_shared<ByteArrayWriteBytestream>(); + clientSession->startReceiving(output); + + ByteArray transferData = generateRandomByteArray(1024); + connection->onDataRead(createSafeByteArrayRef(vecptr(transferData), transferData.size())); + CPPUNIT_ASSERT_EQUAL(transferData, output->getData()); + } + + void testReadBytestream() { + TestHelper helper; + connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); + + SOCKS5BytestreamClientSession::ref clientSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory); + clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); + + clientSession->start(); + eventLoop->processEvents(); + + helper.unprocessedInput.clear(); + serverRespondHelloOK(); + eventLoop->processEvents(); + + helper.unprocessedInput.clear(); + serverRespondRequestOK(); + eventLoop->processEvents(); + CPPUNIT_ASSERT_EQUAL(true, helper.sessionReadyCalled); + CPPUNIT_ASSERT_EQUAL(false, helper.sessionReadyError); + + helper.unprocessedInput.clear(); + ByteArray transferData = generateRandomByteArray(1024); + boost::shared_ptr<ByteArrayReadBytestream> input = boost::make_shared<ByteArrayReadBytestream>(transferData); + clientSession->startSending(input); + eventLoop->processEvents(); - CPPUNIT_ASSERT_EQUAL(createByteArray(vecptr(transferData), transferData.size()), helper.unprocessedInput); - } + CPPUNIT_ASSERT_EQUAL(createByteArray(vecptr(transferData), transferData.size()), helper.unprocessedInput); + } private: - static ByteArray generateRandomByteArray(size_t len) { - boost::uniform_int<> dist(0, 255); - boost::variate_generator<boost::mt19937&, boost::uniform_int<> > randomByte(randomGen, dist); - ByteArray result(len); - for (size_t i=0; i < len; ++i ) { - result[i] = static_cast<unsigned char>(randomByte()); - } - return result; - } - - // Server responses - void serverRespondHelloOK() { - connection->onDataRead(createSafeByteArrayRef("\x05\00", 2)); - } - - void serverRespondHelloAuthFail() { - connection->onDataRead(createSafeByteArrayRef("\x05\xFF", 2)); - } - - void serverRespondRequestOK() { - boost::shared_ptr<SafeByteArray> dataToSend = createSafeByteArrayRef("\x05\x00\x00\x03", 4); - append(*dataToSend, createSafeByteArray(static_cast<char>(destination.size()))); - append(*dataToSend, createSafeByteArray(destination)); - append(*dataToSend, createSafeByteArray("\x00", 1)); - connection->onDataRead(dataToSend); - } - - void serverRespondRequestFail() { - boost::shared_ptr<SafeByteArray> correctData = createSafeByteArrayRef("\x05\x00\x00\x03", 4); - append(*correctData, createSafeByteArray(static_cast<char>(destination.size()))); - append(*correctData, createSafeByteArray(destination)); - append(*correctData, createSafeByteArray("\x00", 1)); - - boost::shared_ptr<SafeByteArray> dataToSend; - //ByteArray failingData = Hexify::unhexify("8417947d1d305c72c11520ea7d2c6e787396705e72c312c6ccc3f66613d7cae1b91b7ab48e8b59a17d559c15fb51"); - //append(dataToSend, failingData); - //SWIFT_LOG(debug) << "hexed: " << Hexify::hexify(failingData) << std::endl; - do { - ByteArray rndArray = generateRandomByteArray(correctData->size()); - dataToSend = createSafeByteArrayRef(vecptr(rndArray), rndArray.size()); - } while (*dataToSend == *correctData); - connection->onDataRead(dataToSend); - } + static ByteArray generateRandomByteArray(size_t len) { + boost::uniform_int<> dist(0, 255); + boost::variate_generator<boost::mt19937&, boost::uniform_int<> > randomByte(randomGen, dist); + ByteArray result(len); + for (size_t i=0; i < len; ++i ) { + result[i] = static_cast<unsigned char>(randomByte()); + } + return result; + } + + // Server responses + void serverRespondHelloOK() { + connection->onDataRead(createSafeByteArrayRef("\x05\00", 2)); + } + + void serverRespondHelloAuthFail() { + connection->onDataRead(createSafeByteArrayRef("\x05\xFF", 2)); + } + + void serverRespondRequestOK() { + boost::shared_ptr<SafeByteArray> dataToSend = createSafeByteArrayRef("\x05\x00\x00\x03", 4); + append(*dataToSend, createSafeByteArray(static_cast<char>(destination.size()))); + append(*dataToSend, createSafeByteArray(destination)); + append(*dataToSend, createSafeByteArray("\x00", 1)); + connection->onDataRead(dataToSend); + } + + void serverRespondRequestFail() { + boost::shared_ptr<SafeByteArray> correctData = createSafeByteArrayRef("\x05\x00\x00\x03", 4); + append(*correctData, createSafeByteArray(static_cast<char>(destination.size()))); + append(*correctData, createSafeByteArray(destination)); + append(*correctData, createSafeByteArray("\x00", 1)); + + boost::shared_ptr<SafeByteArray> dataToSend; + //ByteArray failingData = Hexify::unhexify("8417947d1d305c72c11520ea7d2c6e787396705e72c312c6ccc3f66613d7cae1b91b7ab48e8b59a17d559c15fb51"); + //append(dataToSend, failingData); + //SWIFT_LOG(debug) << "hexed: " << Hexify::hexify(failingData) << std::endl; + do { + ByteArray rndArray = generateRandomByteArray(correctData->size()); + dataToSend = createSafeByteArrayRef(vecptr(rndArray), rndArray.size()); + } while (*dataToSend == *correctData); + connection->onDataRead(dataToSend); + } private: - struct TestHelper { - TestHelper() : sessionReadyCalled(false), sessionReadyError(false) {} - ByteArray unprocessedInput; - bool sessionReadyCalled; - bool sessionReadyError; + struct TestHelper { + TestHelper() : sessionReadyCalled(false), sessionReadyError(false) {} + ByteArray unprocessedInput; + bool sessionReadyCalled; + bool sessionReadyError; - void handleConnectionDataWritten(const SafeByteArray& data) { - append(unprocessedInput, data); - //SWIFT_LOG(debug) << "unprocessedInput (" << unprocessedInput.size() << "): " << Hexify::hexify(unprocessedInput) << std::endl; - } + void handleConnectionDataWritten(const SafeByteArray& data) { + append(unprocessedInput, data); + //SWIFT_LOG(debug) << "unprocessedInput (" << unprocessedInput.size() << "): " << Hexify::hexify(unprocessedInput) << std::endl; + } - void handleSessionReady(bool error) { - sessionReadyCalled = true; - sessionReadyError = error; - } - }; + void handleSessionReady(bool error) { + sessionReadyCalled = true; + sessionReadyError = error; + } + }; private: - struct MockeryConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<MockeryConnection> { - public: - MockeryConnection(const std::vector<HostAddressPort>& failingPorts, bool isResponsive, EventLoop* eventLoop) : eventLoop(eventLoop), failingPorts(failingPorts), isResponsive(isResponsive), disconnectCalled(false) {} - - void listen() { assert(false); } - void connect(const HostAddressPort& address) { - hostAddressPort = address; - if (isResponsive) { - bool fail = std::find(failingPorts.begin(), failingPorts.end(), address) != failingPorts.end(); - eventLoop->postEvent(boost::bind(boost::ref(onConnectFinished), fail)); - } - } - - HostAddressPort getLocalAddress() const { return HostAddressPort(); } - - HostAddressPort getRemoteAddress() const { return HostAddressPort(); } - - void disconnect() { - disconnectCalled = true; - } - - void write(const SafeByteArray& data) { - eventLoop->postEvent(boost::ref(onDataWritten), shared_from_this()); - onDataSent(data); - } - - boost::signal<void (const SafeByteArray&)> onDataSent; - - EventLoop* eventLoop; - boost::optional<HostAddressPort> hostAddressPort; - std::vector<HostAddressPort> failingPorts; - bool isResponsive; - bool disconnectCalled; - }; + struct MockeryConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<MockeryConnection> { + public: + MockeryConnection(const std::vector<HostAddressPort>& failingPorts, bool isResponsive, EventLoop* eventLoop) : eventLoop(eventLoop), failingPorts(failingPorts), isResponsive(isResponsive), disconnectCalled(false) {} + + void listen() { assert(false); } + void connect(const HostAddressPort& address) { + hostAddressPort = address; + if (isResponsive) { + bool fail = std::find(failingPorts.begin(), failingPorts.end(), address) != failingPorts.end(); + eventLoop->postEvent(boost::bind(boost::ref(onConnectFinished), fail)); + } + } + + HostAddressPort getLocalAddress() const { return HostAddressPort(); } + + HostAddressPort getRemoteAddress() const { return HostAddressPort(); } + + void disconnect() { + disconnectCalled = true; + } + + void write(const SafeByteArray& data) { + eventLoop->postEvent(boost::ref(onDataWritten), shared_from_this()); + onDataSent(data); + } + + boost::signal<void (const SafeByteArray&)> onDataSent; + + EventLoop* eventLoop; + boost::optional<HostAddressPort> hostAddressPort; + std::vector<HostAddressPort> failingPorts; + bool isResponsive; + bool disconnectCalled; + }; private: - HostAddressPort destinationAddressPort; - std::string destination; - DummyEventLoop* eventLoop; - DummyTimerFactory* timerFactory; - boost::shared_ptr<MockeryConnection> connection; - const std::vector<HostAddressPort> failingPorts; - boost::shared_ptr<CryptoProvider> crypto; + HostAddressPort destinationAddressPort; + std::string destination; + DummyEventLoop* eventLoop; + DummyTimerFactory* timerFactory; + boost::shared_ptr<MockeryConnection> connection; + const std::vector<HostAddressPort> failingPorts; + boost::shared_ptr<CryptoProvider> crypto; }; CPPUNIT_TEST_SUITE_REGISTRATION(SOCKS5BytestreamClientSessionTest); diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp index 84dcf7c..12690ff 100644 --- a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp @@ -21,193 +21,193 @@ using namespace Swift; class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(SOCKS5BytestreamServerSessionTest); - CPPUNIT_TEST(testAuthenticate); - CPPUNIT_TEST(testAuthenticate_Chunked); - CPPUNIT_TEST(testRequest); - CPPUNIT_TEST(testRequest_UnknownBytestream); - CPPUNIT_TEST(testReceiveData); - CPPUNIT_TEST(testReceiveData_Chunked); - CPPUNIT_TEST(testDataStreamPauseStopsSendingData); - CPPUNIT_TEST(testDataStreamResumeAfterPauseSendsData); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - receivedDataChunks = 0; - eventLoop = new DummyEventLoop(); - bytestreams = new SOCKS5BytestreamRegistry(); - connection = boost::make_shared<DummyConnection>(eventLoop); - connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); - stream1 = boost::make_shared<ByteArrayReadBytestream>(createByteArray("abcdefg")); - finished = false; - } - - void tearDown() { - connection.reset(); - delete bytestreams; - delete eventLoop; - } - - void testAuthenticate() { - boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); - StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - - receive(createSafeByteArray("\x05\x02\x01\x02")); - - CPPUNIT_ASSERT(createByteArray("\x05\x00", 2) == receivedData); - } - - void testAuthenticate_Chunked() { - boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); - StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - - receive(createSafeByteArray("\x05\x02\x01")); - - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedData.size())); - receive(createSafeByteArray("\x01")); - CPPUNIT_ASSERT(createByteArray("\x05\x00", 2) == receivedData); - } - - void testRequest() { - boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); - StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - bytestreams->setHasBytestream("abcdef", true); - authenticate(); - - ByteArray hostname(createByteArray("abcdef")); - receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(static_cast<char>(hostname.size())), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); - CPPUNIT_ASSERT(createByteArray("\x05\x00\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13) == createByteArray(&receivedData[0], 13)); - } - - void testRequest_UnknownBytestream() { - boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); - StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - authenticate(); - - ByteArray hostname(createByteArray("abcdef")); - receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(static_cast<char>(hostname.size())), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); - CPPUNIT_ASSERT(createByteArray("\x05\x04\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13) == receivedData); - } - - void testReceiveData() { - boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); - StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - bytestreams->setHasBytestream("abcdef", true); - authenticate(); - request("abcdef"); - eventLoop->processEvents(); - testling->startSending(stream1); - skipHeader("abcdef"); - eventLoop->processEvents(); - - CPPUNIT_ASSERT(createByteArray("abcdefg") == receivedData); - CPPUNIT_ASSERT_EQUAL(2, receivedDataChunks); - } - - void testReceiveData_Chunked() { - boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); - testling->setChunkSize(3); - StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - bytestreams->setHasBytestream("abcdef", true); - authenticate(); - request("abcdef"); - eventLoop->processEvents(); - testling->startSending(stream1); - eventLoop->processEvents(); - skipHeader("abcdef"); - CPPUNIT_ASSERT(createByteArray("abcdefg") == receivedData); - CPPUNIT_ASSERT_EQUAL(4, receivedDataChunks); - } - - void testDataStreamPauseStopsSendingData() { - boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); - testling->setChunkSize(3); - stream1->setDataComplete(false); - StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - bytestreams->setHasBytestream("abcdef", true); - authenticate(); - request("abcdef"); - eventLoop->processEvents(); - testling->startSending(stream1); - eventLoop->processEvents(); - skipHeader("abcdef"); - CPPUNIT_ASSERT(createByteArray("abcdefg") == receivedData); - CPPUNIT_ASSERT_EQUAL(4, receivedDataChunks); - - CPPUNIT_ASSERT(!finished); - CPPUNIT_ASSERT(!error); - } - - void testDataStreamResumeAfterPauseSendsData() { - boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); - testling->setChunkSize(3); - stream1->setDataComplete(false); - StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); - bytestreams->setHasBytestream("abcdef", true); - authenticate(); - request("abcdef"); - eventLoop->processEvents(); - testling->startSending(stream1); - eventLoop->processEvents(); - skipHeader("abcdef"); - - stream1->addData(createByteArray("xyz")); - eventLoop->processEvents(); - - CPPUNIT_ASSERT(createByteArray("abcdefgxyz") == receivedData); - CPPUNIT_ASSERT(!finished); - CPPUNIT_ASSERT(!error); - } - - private: - void receive(const SafeByteArray& data) { - connection->receive(data); - eventLoop->processEvents(); - } - - void authenticate() { - receive(createSafeByteArray("\x05\x02\x01\x02")); - receivedData.clear(); - receivedDataChunks = 0; - } - - void request(const std::string& hostname) { - receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(static_cast<char>(hostname.size())), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); - } - - void skipHeader(const std::string& hostname) { - size_t headerSize = 7 + hostname.size(); - receivedData = createByteArray(&receivedData[headerSize], receivedData.size() - headerSize); - } - - - void handleDataWritten(const SafeByteArray& data) { - receivedData.insert(receivedData.end(), data.begin(), data.end()); - receivedDataChunks++; - } - - private: - SOCKS5BytestreamServerSession* createSession() { - SOCKS5BytestreamServerSession* session = new SOCKS5BytestreamServerSession(connection, bytestreams); - session->onFinished.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleFinished, this, _1)); - return session; - } - - void handleFinished(boost::optional<FileTransferError> error) { - finished = true; - this->error = error; - } - - private: - DummyEventLoop* eventLoop; - SOCKS5BytestreamRegistry* bytestreams; - boost::shared_ptr<DummyConnection> connection; - std::vector<unsigned char> receivedData; - int receivedDataChunks; - boost::shared_ptr<ByteArrayReadBytestream> stream1; - bool finished; - boost::optional<FileTransferError> error; + CPPUNIT_TEST_SUITE(SOCKS5BytestreamServerSessionTest); + CPPUNIT_TEST(testAuthenticate); + CPPUNIT_TEST(testAuthenticate_Chunked); + CPPUNIT_TEST(testRequest); + CPPUNIT_TEST(testRequest_UnknownBytestream); + CPPUNIT_TEST(testReceiveData); + CPPUNIT_TEST(testReceiveData_Chunked); + CPPUNIT_TEST(testDataStreamPauseStopsSendingData); + CPPUNIT_TEST(testDataStreamResumeAfterPauseSendsData); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + receivedDataChunks = 0; + eventLoop = new DummyEventLoop(); + bytestreams = new SOCKS5BytestreamRegistry(); + connection = boost::make_shared<DummyConnection>(eventLoop); + connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); + stream1 = boost::make_shared<ByteArrayReadBytestream>(createByteArray("abcdefg")); + finished = false; + } + + void tearDown() { + connection.reset(); + delete bytestreams; + delete eventLoop; + } + + void testAuthenticate() { + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + + receive(createSafeByteArray("\x05\x02\x01\x02")); + + CPPUNIT_ASSERT(createByteArray("\x05\x00", 2) == receivedData); + } + + void testAuthenticate_Chunked() { + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + + receive(createSafeByteArray("\x05\x02\x01")); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedData.size())); + receive(createSafeByteArray("\x01")); + CPPUNIT_ASSERT(createByteArray("\x05\x00", 2) == receivedData); + } + + void testRequest() { + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + bytestreams->setHasBytestream("abcdef", true); + authenticate(); + + ByteArray hostname(createByteArray("abcdef")); + receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(static_cast<char>(hostname.size())), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); + CPPUNIT_ASSERT(createByteArray("\x05\x00\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13) == createByteArray(&receivedData[0], 13)); + } + + void testRequest_UnknownBytestream() { + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + authenticate(); + + ByteArray hostname(createByteArray("abcdef")); + receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(static_cast<char>(hostname.size())), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); + CPPUNIT_ASSERT(createByteArray("\x05\x04\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13) == receivedData); + } + + void testReceiveData() { + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + bytestreams->setHasBytestream("abcdef", true); + authenticate(); + request("abcdef"); + eventLoop->processEvents(); + testling->startSending(stream1); + skipHeader("abcdef"); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(createByteArray("abcdefg") == receivedData); + CPPUNIT_ASSERT_EQUAL(2, receivedDataChunks); + } + + void testReceiveData_Chunked() { + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + testling->setChunkSize(3); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + bytestreams->setHasBytestream("abcdef", true); + authenticate(); + request("abcdef"); + eventLoop->processEvents(); + testling->startSending(stream1); + eventLoop->processEvents(); + skipHeader("abcdef"); + CPPUNIT_ASSERT(createByteArray("abcdefg") == receivedData); + CPPUNIT_ASSERT_EQUAL(4, receivedDataChunks); + } + + void testDataStreamPauseStopsSendingData() { + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + testling->setChunkSize(3); + stream1->setDataComplete(false); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + bytestreams->setHasBytestream("abcdef", true); + authenticate(); + request("abcdef"); + eventLoop->processEvents(); + testling->startSending(stream1); + eventLoop->processEvents(); + skipHeader("abcdef"); + CPPUNIT_ASSERT(createByteArray("abcdefg") == receivedData); + CPPUNIT_ASSERT_EQUAL(4, receivedDataChunks); + + CPPUNIT_ASSERT(!finished); + CPPUNIT_ASSERT(!error); + } + + void testDataStreamResumeAfterPauseSendsData() { + boost::shared_ptr<SOCKS5BytestreamServerSession> testling(createSession()); + testling->setChunkSize(3); + stream1->setDataComplete(false); + StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); + bytestreams->setHasBytestream("abcdef", true); + authenticate(); + request("abcdef"); + eventLoop->processEvents(); + testling->startSending(stream1); + eventLoop->processEvents(); + skipHeader("abcdef"); + + stream1->addData(createByteArray("xyz")); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(createByteArray("abcdefgxyz") == receivedData); + CPPUNIT_ASSERT(!finished); + CPPUNIT_ASSERT(!error); + } + + private: + void receive(const SafeByteArray& data) { + connection->receive(data); + eventLoop->processEvents(); + } + + void authenticate() { + receive(createSafeByteArray("\x05\x02\x01\x02")); + receivedData.clear(); + receivedDataChunks = 0; + } + + void request(const std::string& hostname) { + receive(concat(createSafeByteArray("\x05\x01\x00\x03", 4), createSafeByteArray(static_cast<char>(hostname.size())), createSafeByteArray(hostname), createSafeByteArray("\x00\x00", 2))); + } + + void skipHeader(const std::string& hostname) { + size_t headerSize = 7 + hostname.size(); + receivedData = createByteArray(&receivedData[headerSize], receivedData.size() - headerSize); + } + + + void handleDataWritten(const SafeByteArray& data) { + receivedData.insert(receivedData.end(), data.begin(), data.end()); + receivedDataChunks++; + } + + private: + SOCKS5BytestreamServerSession* createSession() { + SOCKS5BytestreamServerSession* session = new SOCKS5BytestreamServerSession(connection, bytestreams); + session->onFinished.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleFinished, this, _1)); + return session; + } + + void handleFinished(boost::optional<FileTransferError> error) { + finished = true; + this->error = error; + } + + private: + DummyEventLoop* eventLoop; + SOCKS5BytestreamRegistry* bytestreams; + boost::shared_ptr<DummyConnection> connection; + std::vector<unsigned char> receivedData; + int receivedDataChunks; + boost::shared_ptr<ByteArrayReadBytestream> stream1; + bool finished; + boost::optional<FileTransferError> error; }; CPPUNIT_TEST_SUITE_REGISTRATION(SOCKS5BytestreamServerSessionTest); |