diff options
Diffstat (limited to 'Swiften/QA')
31 files changed, 2185 insertions, 999 deletions
diff --git a/Swiften/QA/ClientTest/ClientTest.cpp b/Swiften/QA/ClientTest/ClientTest.cpp index e88e5ac..c5117fa 100644 --- a/Swiften/QA/ClientTest/ClientTest.cpp +++ b/Swiften/QA/ClientTest/ClientTest.cpp @@ -1,98 +1,110 @@ /* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2018 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ -#include <boost/bind.hpp> -#include <boost/thread.hpp> #include <iostream> +#include <thread> + +#include <boost/bind.hpp> +#include <boost/numeric/conversion/cast.hpp> #include <Swiften/Client/Client.h> -#include <Swiften/Network/TimerFactory.h> -#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/Client/ClientXMLTracer.h> #include <Swiften/EventLoop/EventLoop.h> #include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/Network/TimerFactory.h> #include <Swiften/Roster/GetRosterRequest.h> -#include <Swiften/Client/ClientXMLTracer.h> using namespace Swift; static SimpleEventLoop eventLoop; static BoostNetworkFactories networkFactories(&eventLoop); -static Client* client = 0; +static Client* client = nullptr; static bool rosterReceived = false; enum TestStage { - FirstConnect, - Reconnect + FirstConnect, + Reconnect }; static TestStage stage; static ClientOptions options; static void handleDisconnected(boost::optional<ClientError> e) { - std::cout << "Disconnected: " << e << std::endl; - if (stage == FirstConnect) { - stage = Reconnect; - client->connect(options); - } - else { - eventLoop.stop(); - } + std::cout << "Disconnected: " << (e ? e.get().getType() : ClientError::UnknownError) << std::endl; + if (stage == FirstConnect) { + stage = Reconnect; + client->connect(options); + } + else { + eventLoop.stop(); + } } -static void handleRosterReceived(boost::shared_ptr<Payload>) { - rosterReceived = true; - std::cout << "Disconnecting" << std::endl; - client->disconnect(); +static void handleRosterReceived(std::shared_ptr<Payload>) { + rosterReceived = true; + std::cout << "Disconnecting" << std::endl; + client->disconnect(); } static void handleConnected() { - std::cout << "Connected" << std::endl; - rosterReceived = false; - GetRosterRequest::ref rosterRequest = GetRosterRequest::create(client->getIQRouter()); - rosterRequest->onResponse.connect(boost::bind(&handleRosterReceived, _1)); - rosterRequest->send(); + std::cout << "Connected" << std::endl; + rosterReceived = false; + GetRosterRequest::ref rosterRequest = GetRosterRequest::create(client->getIQRouter()); + rosterRequest->onResponse.connect(boost::bind(&handleRosterReceived, _1)); + rosterRequest->send(); } int main(int, char**) { - char* jid = getenv("SWIFT_CLIENTTEST_JID"); - if (!jid) { - std::cerr << "Please set the SWIFT_CLIENTTEST_JID environment variable" << std::endl; - return -1; - } - char* pass = getenv("SWIFT_CLIENTTEST_PASS"); - if (!pass) { - std::cerr << "Please set the SWIFT_CLIENTTEST_PASS environment variable" << std::endl; - return -1; - } - - char* boshHost = getenv("SWIFT_CLIENTTEST_BOSH_HOST"); - char* boshPort = getenv("SWIFT_CLIENTTEST_BOSH_PORT"); - char* boshPath = getenv("SWIFT_CLIENTTEST_BOSH_PATH"); - - if (boshHost && boshPort && boshPath) { - std::cout << "Using BOSH with URL: http://" << boshHost << ":" << boshPort << "/" << boshPath << std::endl; - options.boshURL = URL("http", boshHost, atoi(boshPort), boshPath); - } - - client = new Swift::Client(JID(jid), std::string(pass), &networkFactories); - ClientXMLTracer* tracer = new ClientXMLTracer(client, !options.boshURL.isEmpty()); - client->onConnected.connect(&handleConnected); - client->onDisconnected.connect(boost::bind(&handleDisconnected, _1)); - client->setAlwaysTrustCertificates(); - stage = FirstConnect; - client->connect(options); - - { - Timer::ref timer = networkFactories.getTimerFactory()->createTimer(60000); - timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop)); - timer->start(); - - eventLoop.run(); - } - - delete tracer; - delete client; - return !rosterReceived; + char* jid = getenv("SWIFT_CLIENTTEST_JID"); + if (!jid) { + std::cerr << "Please set the SWIFT_CLIENTTEST_JID environment variable" << std::endl; + return -1; + } + char* pass = getenv("SWIFT_CLIENTTEST_PASS"); + if (!pass) { + std::cerr << "Please set the SWIFT_CLIENTTEST_PASS environment variable" << std::endl; + return -1; + } + + char* boshHost = getenv("SWIFT_CLIENTTEST_BOSH_HOST"); + char* boshPort = getenv("SWIFT_CLIENTTEST_BOSH_PORT"); + char* boshPath = getenv("SWIFT_CLIENTTEST_BOSH_PATH"); + + if (boshHost && boshPort && boshPath) { + std::cout << "Using BOSH with URL: http://" << boshHost << ":" << boshPort << boshPath << std::endl; + try { + options.boshURL = URL("http", boshHost, boost::numeric_cast<unsigned short>(boost::lexical_cast<int>(boshPort)), boshPath); + } + catch (const boost::numeric::bad_numeric_cast& e) { + std::cerr << "SWIFT_CLIENTTEST_BOSH_PORT doesn't hold a valid port number: " << e.what() << std::endl; + return -1; + } + catch (const boost::bad_lexical_cast& e) { + std::cerr << "SWIFT_CLIENTTEST_BOSH_PORT doesn't hold a valid port number: " << e.what() << std::endl; + return -1; + } + } + + client = new Swift::Client(JID(jid), std::string(pass), &networkFactories); + ClientXMLTracer* tracer = new ClientXMLTracer(client, !options.boshURL.isEmpty()); + client->onConnected.connect(&handleConnected); + client->onDisconnected.connect(boost::bind(&handleDisconnected, _1)); + client->setAlwaysTrustCertificates(); + stage = FirstConnect; + client->connect(options); + + { + Timer::ref timer = networkFactories.getTimerFactory()->createTimer(60000); + timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop)); + timer->start(); + + eventLoop.run(); + } + + delete tracer; + delete client; + return !rosterReceived; } diff --git a/Swiften/QA/ClientTest/SConscript b/Swiften/QA/ClientTest/SConscript index 15a68c6..812c472 100644 --- a/Swiften/QA/ClientTest/SConscript +++ b/Swiften/QA/ClientTest/SConscript @@ -3,15 +3,15 @@ import os Import("env") if env["TEST"] : - myenv = env.Clone() - myenv.UseFlags(myenv["SWIFTEN_FLAGS"]) - myenv.UseFlags(myenv["SWIFTEN_DEP_FLAGS"]) + myenv = env.Clone() + myenv.UseFlags(myenv["SWIFTEN_FLAGS"]) + myenv.UseFlags(myenv["SWIFTEN_DEP_FLAGS"]) - for i in ["SWIFT_CLIENTTEST_JID", "SWIFT_CLIENTTEST_PASS"]: - if ARGUMENTS.get(i.lower(), False) : - myenv["ENV"][i] = ARGUMENTS[i.lower()] - elif os.environ.get(i, "") : - myenv["ENV"][i] = os.environ[i] + for i in ["SWIFT_CLIENTTEST_JID", "SWIFT_CLIENTTEST_PASS"]: + if ARGUMENTS.get(i.lower(), False) : + myenv["ENV"][i] = ARGUMENTS[i.lower()] + elif os.environ.get(i, "") : + myenv["ENV"][i] = os.environ[i] - tester = myenv.Program("ClientTest", ["ClientTest.cpp"]) - myenv.Test(tester, "system") + tester = myenv.Program("ClientTest", ["ClientTest.cpp"]) + myenv.Test(tester, "system") diff --git a/Swiften/QA/ConcurrentFileTransferTest/ConcurrentFileTransferTest.cpp b/Swiften/QA/ConcurrentFileTransferTest/ConcurrentFileTransferTest.cpp new file mode 100644 index 0000000..22ee9d7 --- /dev/null +++ b/Swiften/QA/ConcurrentFileTransferTest/ConcurrentFileTransferTest.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <fstream> +#include <map> +#include <string> + +#include <boost/filesystem.hpp> +#include <boost/numeric/conversion/cast.hpp> + +#include <Swiften/Base/Debug.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Base/sleep.h> +#include <Swiften/Base/StdRandomGenerator.h> +#include <Swiften/Client/Client.h> +#include <Swiften/Client/ClientXMLTracer.h> +#include <Swiften/Disco/ClientDiscoManager.h> +#include <Swiften/Disco/EntityCapsProvider.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/FileTransfer/FileReadBytestream.h> +#include <Swiften/FileTransfer/FileTransferManager.h> +#include <Swiften/FileTransfer/FileWriteBytestream.h> +#include <Swiften/FileTransfer/OutgoingFileTransfer.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/Network/Timer.h> +#include <Swiften/Network/TimerFactory.h> + +using namespace Swift; + +static const std::string CLIENT_NAME = "Swiften FT Test"; +static const std::string CLIENT_NODE = "http://swift.im"; + +static std::shared_ptr<SimpleEventLoop> eventLoop; +static std::shared_ptr<BoostNetworkFactories> networkFactories; + +StdRandomGenerator randGen; + +enum Candidate { + InBandBytestream = 1, + S5B_Direct = 2, + S5B_Proxied = 4, + S5B_Assisted = 8, +}; + +class ConcurrentFileTransferTest { + public: + ConcurrentFileTransferTest(int clientACandidates, int clientBCandidates) : clientACandidates_(clientACandidates), clientBCandidates_(clientBCandidates) { + + } + + private: + int clientACandidates_; + std::shared_ptr<Client> clientA_; + std::map<std::string, ByteArray> clientASendFiles_; + + + int clientBCandidates_; + std::shared_ptr<Client> clientB_; +}; + +/** + * This program tests the concurrent transfer of multiple file-transfers. + * + */ +int main(int argc, char** argv) { + int failedTests = 0; + + if (!env("SWIFT_FILETRANSFERTEST_JID") && !env("SWIFT_FILETRANSFERTEST_PASS") && !env("SWIFT_FILETRANSFERTEST2_JID") && !env("SWIFT_FILETRANSFERTEST2_PASS")) { + + return -1; + } + + + return failedTests; +} diff --git a/Swiften/QA/ConcurrentFileTransferTest/SConscript b/Swiften/QA/ConcurrentFileTransferTest/SConscript new file mode 100644 index 0000000..94b37fd --- /dev/null +++ b/Swiften/QA/ConcurrentFileTransferTest/SConscript @@ -0,0 +1,17 @@ +import os + +Import("env") + +if env["TEST"] : + myenv = env.Clone() + myenv.UseFlags(myenv["SWIFTEN_FLAGS"]) + myenv.UseFlags(myenv["SWIFTEN_DEP_FLAGS"]) + + for i in ["SWIFT_FILETRANSFERTEST_JID", "SWIFT_FILETRANSFERTEST_PASS", "SWIFT_FILETRANSFERTEST2_JID", "SWIFT_FILETRANSFERTEST2_PASS"]: + if ARGUMENTS.get(i.lower(), False) : + myenv["ENV"][i] = ARGUMENTS[i.lower()] + elif os.environ.get(i, "") : + myenv["ENV"][i] = os.environ[i] + + tester = myenv.Program("ConcurrentFileTransferTest", ["ConcurrentFileTransferTest.cpp"]) + myenv.Test(tester, "system") diff --git a/Swiften/QA/DNSSDTest/DNSSDTest.cpp b/Swiften/QA/DNSSDTest/DNSSDTest.cpp index 7e2a189..5a78d2f 100644 --- a/Swiften/QA/DNSSDTest/DNSSDTest.cpp +++ b/Swiften/QA/DNSSDTest/DNSSDTest.cpp @@ -1,7 +1,7 @@ /* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2018 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ // TODO: Test registering on different interfaces @@ -28,120 +28,120 @@ using namespace Swift; template <typename DNSSDQuerierType> class DNSSDTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(DNSSDTest); - CPPUNIT_TEST(testPublish); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - eventLoop = new DummyEventLoop(); - querier = boost::shared_ptr<DNSSDQuerier>(new DNSSDQuerierType()); - querier->start(); - } - - void tearDown() { - querier->stop(); - querier.reset(); - delete eventLoop; - } - - void testPublish() { - boost::shared_ptr<DNSSDBrowseQuery> browseQuery = querier->createBrowseQuery(); - browseQuery->onServiceAdded.connect(boost::bind(&DNSSDTest::handleServiceAdded, this, _1)); - browseQuery->onServiceRemoved.connect(boost::bind(&DNSSDTest::handleServiceRemoved, this, _1)); - browseQuery->onError.connect(boost::bind(&DNSSDTest::handleBrowseError, this)); - browseQuery->startBrowsing(); - eventLoop->processEvents(); - - // Publish the service - LinkLocalServiceInfo info; - boost::shared_ptr<DNSSDRegisterQuery> registerQuery = querier->createRegisterQuery("DNSSDTest", 1234, info.toTXTRecord()); - registerQuery->onRegisterFinished.connect(boost::bind(&DNSSDTest::handleRegisterFinished, this, _1)); - registerQuery->registerService(); - - // Wait for a while - wait(); - - // Check that our registered queries are correct - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>((registered.size()))); - CPPUNIT_ASSERT_EQUAL(std::string("DNSSDTest"), registered[0].getName()); - CPPUNIT_ASSERT_EQUAL(std::string("local"), registered[0].getDomain()); - CPPUNIT_ASSERT_EQUAL(std::string("_presence._tcp"), registered[0].getType()); - - // Check that our browse query discovered us - std::sort(added.begin(), added.end()); - CPPUNIT_ASSERT(added.size() >= 1); - //for (size_t i = 0; i < added.size(); ++i) { - for (size_t i = 0; i < added.size(); ++i) { - CPPUNIT_ASSERT_EQUAL(std::string("DNSSDTest"), added[i].getName()); - CPPUNIT_ASSERT_EQUAL(std::string("local"), added[i].getDomain()); - CPPUNIT_ASSERT_EQUAL(std::string("_presence._tcp"), added[i].getType()); - CPPUNIT_ASSERT(added[i].getNetworkInterfaceID() != 0); - } - - // Resolve all added services - for (size_t i = 0; i < added.size(); ++i) { - resolvedServices.clear(); - boost::shared_ptr<DNSSDResolveServiceQuery> resolveServiceQuery = querier->createResolveServiceQuery(added[i]); - resolveServiceQuery->onServiceResolved.connect(boost::bind(&DNSSDTest::handleResolveFinished, this, _1)); - resolveServiceQuery->start(); - wait(); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(resolvedServices.size())); - resolveServiceQuery->stop(); - } - - // Unregister the service & check if the browse query picks this up - toRemove.clear(); - toRemove.insert(toRemove.begin(), added.begin(), added.end()); - registerQuery->unregisterService(); - while (!toRemove.empty()) { - Swift::sleep(100); - eventLoop->processEvents(); - } - - browseQuery->stopBrowsing(); - eventLoop->processEvents(); - } - - private: - void handleServiceAdded(const DNSSDServiceID& id) { - std::cout << "Service added: " << id.getNetworkInterfaceID() << std::endl; - added.push_back(id); - } - - void handleServiceRemoved(const DNSSDServiceID& id) { - CPPUNIT_ASSERT(std::find(toRemove.begin(), toRemove.end(), id) != toRemove.end()); - erase(toRemove, id); - } - - void handleRegisterFinished(boost::optional<DNSSDServiceID> id) { - if (id) { - registered.push_back(*id); - } - } - - void handleBrowseError() { - } - - void wait() { - for (int i = 0; i < SLEEP_INTERVALS; ++i) { - Swift::sleep(100); - eventLoop->processEvents(); - } - } - - void handleResolveFinished(const boost::optional<DNSSDResolveServiceQuery::Result>& result) { - CPPUNIT_ASSERT(result); - resolvedServices.push_back(*result); - } - - private: - DummyEventLoop* eventLoop; - boost::shared_ptr<DNSSDQuerier> querier; - std::vector<DNSSDServiceID> added; - std::vector<DNSSDServiceID> registered; - std::vector<DNSSDServiceID> toRemove; - std::vector<DNSSDResolveServiceQuery::Result> resolvedServices; + CPPUNIT_TEST_SUITE(DNSSDTest); + CPPUNIT_TEST(testPublish); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + eventLoop = new DummyEventLoop(); + querier = std::make_shared<DNSSDQuerierType>(eventLoop); + querier->start(); + } + + void tearDown() { + querier->stop(); + querier.reset(); + delete eventLoop; + } + + void testPublish() { + std::shared_ptr<DNSSDBrowseQuery> browseQuery = querier->createBrowseQuery(); + browseQuery->onServiceAdded.connect(boost::bind(&DNSSDTest::handleServiceAdded, this, _1)); + browseQuery->onServiceRemoved.connect(boost::bind(&DNSSDTest::handleServiceRemoved, this, _1)); + browseQuery->onError.connect(boost::bind(&DNSSDTest::handleBrowseError, this)); + browseQuery->startBrowsing(); + eventLoop->processEvents(); + + // Publish the service + LinkLocalServiceInfo info; + std::shared_ptr<DNSSDRegisterQuery> registerQuery = querier->createRegisterQuery("DNSSDTest", 1234, *info.toTXTRecord()); + registerQuery->onRegisterFinished.connect(boost::bind(&DNSSDTest::handleRegisterFinished, this, _1)); + registerQuery->registerService(); + + // Wait for a while + wait(); + + // Check that our registered queries are correct + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>((registered.size()))); + CPPUNIT_ASSERT_EQUAL(std::string("DNSSDTest"), registered[0].getName()); + CPPUNIT_ASSERT_EQUAL(std::string("local"), registered[0].getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("_presence._tcp"), registered[0].getType()); + + // Check that our browse query discovered us + std::sort(added.begin(), added.end()); + CPPUNIT_ASSERT(added.size() >= 1); + //for (size_t i = 0; i < added.size(); ++i) { + for (size_t i = 0; i < added.size(); ++i) { + CPPUNIT_ASSERT_EQUAL(std::string("DNSSDTest"), added[i].getName()); + CPPUNIT_ASSERT_EQUAL(std::string("local"), added[i].getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("_presence._tcp"), added[i].getType()); + CPPUNIT_ASSERT(added[i].getNetworkInterfaceID() != 0); + } + + // Resolve all added services + for (size_t i = 0; i < added.size(); ++i) { + resolvedServices.clear(); + std::shared_ptr<DNSSDResolveServiceQuery> resolveServiceQuery = querier->createResolveServiceQuery(added[i]); + resolveServiceQuery->onServiceResolved.connect(boost::bind(&DNSSDTest::handleResolveFinished, this, _1)); + resolveServiceQuery->start(); + wait(); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(resolvedServices.size())); + resolveServiceQuery->stop(); + } + + // Unregister the service & check if the browse query picks this up + toRemove.clear(); + toRemove.insert(toRemove.begin(), added.begin(), added.end()); + registerQuery->unregisterService(); + while (!toRemove.empty()) { + Swift::sleep(100); + eventLoop->processEvents(); + } + + browseQuery->stopBrowsing(); + eventLoop->processEvents(); + } + + private: + void handleServiceAdded(const DNSSDServiceID& id) { + std::cout << "Service added: " << id.getNetworkInterfaceID() << std::endl; + added.push_back(id); + } + + void handleServiceRemoved(const DNSSDServiceID& id) { + CPPUNIT_ASSERT(std::find(toRemove.begin(), toRemove.end(), id) != toRemove.end()); + erase(toRemove, id); + } + + void handleRegisterFinished(boost::optional<DNSSDServiceID> id) { + if (id) { + registered.push_back(*id); + } + } + + void handleBrowseError() { + } + + void wait() { + for (int i = 0; i < SLEEP_INTERVALS; ++i) { + Swift::sleep(100); + eventLoop->processEvents(); + } + } + + void handleResolveFinished(const boost::optional<DNSSDResolveServiceQuery::Result>& result) { + CPPUNIT_ASSERT(result); + resolvedServices.push_back(*result); + } + + private: + DummyEventLoop* eventLoop; + std::shared_ptr<DNSSDQuerierType> querier; + std::vector<DNSSDServiceID> added; + std::vector<DNSSDServiceID> registered; + std::vector<DNSSDServiceID> toRemove; + std::vector<DNSSDResolveServiceQuery::Result> resolvedServices; }; #ifdef HAVE_AVAHI diff --git a/Swiften/QA/DNSSDTest/SConscript b/Swiften/QA/DNSSDTest/SConscript index d35d06f..d9c9b04 100644 --- a/Swiften/QA/DNSSDTest/SConscript +++ b/Swiften/QA/DNSSDTest/SConscript @@ -3,19 +3,21 @@ import os Import("env") if env["TEST"] : - myenv = env.Clone() - myenv.MergeFlags(myenv["CHECKER_FLAGS"]) - myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) - myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) - myenv.MergeFlags(myenv["BOOST_FLAGS"]) - myenv.MergeFlags(myenv["LIBIDN_FLAGS"]) - if myenv.get("HAVE_BONJOUR", 0) : - myenv.Append(CPPDEFINES = "HAVE_BONJOUR") - elif myenv.get("HAVE_AVAHI", 0) : - myenv.Append(CPPDEFINES = ["HAVE_AVAHI"]) - myenv.MergeFlags(myenv["AVAHI_FLAGS"]) + myenv = env.Clone() + myenv.MergeFlags(myenv["CHECKER_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) + myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) + myenv.MergeFlags(myenv["GOOGLETEST_FLAGS"]) + myenv.MergeFlags(myenv["BOOST_FLAGS"]) + myenv.MergeFlags(myenv["LIBIDN_FLAGS"]) + if myenv.get("HAVE_BONJOUR", 0) : + myenv.Append(CPPDEFINES = "HAVE_BONJOUR") + elif myenv.get("HAVE_AVAHI", 0) : + myenv.Append(CPPDEFINES = ["HAVE_AVAHI"]) + myenv.MergeFlags(myenv["AVAHI_FLAGS"]) + myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) - tester = myenv.Program("DNSSDTest", [ - "DNSSDTest.cpp", - ]) - myenv.Test(tester, "system") + tester = myenv.Program("DNSSDTest", [ + "DNSSDTest.cpp", + ]) + myenv.Test(tester, "system") diff --git a/Swiften/QA/FileTransferTest/.gitignore b/Swiften/QA/FileTransferTest/.gitignore new file mode 100644 index 0000000..768c501 --- /dev/null +++ b/Swiften/QA/FileTransferTest/.gitignore @@ -0,0 +1 @@ +FileTransferTest diff --git a/Swiften/QA/FileTransferTest/FileTransferTest.cpp b/Swiften/QA/FileTransferTest/FileTransferTest.cpp new file mode 100644 index 0000000..7d69277 --- /dev/null +++ b/Swiften/QA/FileTransferTest/FileTransferTest.cpp @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2014-2018 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <fstream> + +#include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> + + +#include <Swiften/Base/Debug.h> +#include <Swiften/Base/Log.h> +#include <Swiften/Base/sleep.h> +#include <Swiften/Base/StdRandomGenerator.h> +#include <Swiften/Client/Client.h> +#include <Swiften/Client/ClientXMLTracer.h> +#include <Swiften/Disco/ClientDiscoManager.h> +#include <Swiften/Disco/EntityCapsProvider.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/EventLoop/SimpleEventLoop.h> +#include <Swiften/FileTransfer/FileReadBytestream.h> +#include <Swiften/FileTransfer/FileTransferManager.h> +#include <Swiften/FileTransfer/FileWriteBytestream.h> +#include <Swiften/FileTransfer/OutgoingFileTransfer.h> +#include <Swiften/FileTransfer/ReadBytestream.h> +#include <Swiften/Network/BoostNetworkFactories.h> +#include <Swiften/Network/Timer.h> +#include <Swiften/Network/TimerFactory.h> + +using namespace Swift; + +static const std::string CLIENT_NAME = "Swiften FT Test"; +static const std::string CLIENT_NODE = "http://swift.im"; + +static std::shared_ptr<SimpleEventLoop> eventLoop; +static std::shared_ptr<BoostNetworkFactories> networkFactories; + +StdRandomGenerator randGen; + +enum Candidate { + InBandBytestream = 1, + S5B_Direct = 2, + S5B_Proxied = 4, + S5B_Assisted = 8, +}; + +class FileTransferTest { + public: + FileTransferTest(int senderCandidates, int receiverCandidates) : senderCandidates_(senderCandidates), senderError_(FileTransferError::UnknownError), senderIsDone_(false), receiverCandidates_(receiverCandidates), receiverError_(FileTransferError::UnknownError), receiverIsDone_(false) { + sender_ = std::make_shared<Client>(JID(getenv("SWIFT_FILETRANSFERTEST_JID")), getenv("SWIFT_FILETRANSFERTEST_PASS"), networkFactories.get()); + sender_->onDisconnected.connect(boost::bind(&FileTransferTest::handleSenderDisconnected, this, _1)); + sender_->onConnected.connect(boost::bind(&FileTransferTest::handleSenderConnected, this)); + sender_->getEntityCapsProvider()->onCapsChanged.connect(boost::bind(&FileTransferTest::handleSenderCapsChanged, this, _1)); + + receiver_ = std::make_shared<Client>(JID(getenv("SWIFT_FILETRANSFERTEST2_JID")), getenv("SWIFT_FILETRANSFERTEST2_PASS"), networkFactories.get()); + receiver_->onConnected.connect(boost::bind(&FileTransferTest::handleReceiverConnected, this)); + receiver_->onDisconnected.connect(boost::bind(&FileTransferTest::handleReceiverDisconnected, this, _1)); + + senderTracer_ = new ClientXMLTracer(sender_.get()); + receiverTracer_ = new ClientXMLTracer(receiver_.get()); + + ClientOptions options; + options.useTLS = ClientOptions::NeverUseTLS; + options.useStreamCompression = false; + options.useStreamResumption = false; + options.useAcks = false; + + sender_->connect(options); + receiver_->connect(options); + + timeOut_ = networkFactories->getTimerFactory()->createTimer(60000); + timeOut_->onTick.connect(boost::bind(&FileTransferTest::handleTimeOut, this)); + + // Create randomly sized data to exchange. + sendFilePath_ = boost::filesystem::unique_path("ft_send_%%%%%%%%%%%%%%%%.bin"); + receiveFilePath_ = boost::filesystem::unique_path("ft_receive_%%%%%%%%%%%%%%%%.bin"); + + size_t size = 1024 + static_cast<size_t>(randGen.generateRandomInteger(1024 * 10)); + sendData_.resize(size); + for (unsigned char& n : sendData_) { + n = static_cast<unsigned char>(randGen.generateRandomInteger(255)); + } + + std::ofstream outfile(sendFilePath_.native().c_str(), std::ios::out | std::ios::binary); + outfile.write(reinterpret_cast<char *>(&sendData_[0]), static_cast<ptrdiff_t>(sendData_.size())); + outfile.close(); + } + + ~FileTransferTest() { + timeOut_->stop(); + + delete senderTracer_; + delete receiverTracer_; + + // Free file-transfer objects so file handles are closed and files can be removed afterwards. + assert(!outgoingFileTransfer_ && incomingFileTransfers_.empty()); + + if(boost::filesystem::exists(sendFilePath_)) { + boost::filesystem::remove(sendFilePath_); + } + + if(boost::filesystem::exists(receiveFilePath_)) { + boost::filesystem::remove(receiveFilePath_); + } + } + + void handleSenderConnected() { + DiscoInfo discoInfo; + discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc")); + discoInfo.addFeature(DiscoInfo::JingleFeature); + discoInfo.addFeature(DiscoInfo::JingleFTFeature); + discoInfo.addFeature(DiscoInfo::Bytestream); + if (senderCandidates_ & InBandBytestream) { + discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature); + } + if (senderCandidates_ & (S5B_Direct | S5B_Assisted | S5B_Proxied)) { + discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature); + } + sender_->getDiscoManager()->setCapsNode(CLIENT_NODE); + sender_->getDiscoManager()->setDiscoInfo(discoInfo); + sender_->sendPresence(Presence::create()); + } + + void handleReceiverConnected() { + receiver_->getFileTransferManager()->onIncomingFileTransfer.connect(boost::bind(&FileTransferTest::handleReceiverIncomingFileTransfer, this, _1)); + + DiscoInfo discoInfo; + discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc")); + discoInfo.addFeature(DiscoInfo::JingleFeature); + discoInfo.addFeature(DiscoInfo::JingleFTFeature); + discoInfo.addFeature(DiscoInfo::Bytestream); + if (receiverCandidates_ & InBandBytestream) { + discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature); + } + if (receiverCandidates_ & (S5B_Direct | S5B_Assisted | S5B_Proxied)) { + discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature); + } + receiver_->getDiscoManager()->setCapsNode(CLIENT_NODE); + receiver_->getDiscoManager()->setDiscoInfo(discoInfo); + receiver_->getPresenceSender()->sendPresence(Presence::create()); + } + + void handleReceiverIncomingFileTransfer(IncomingFileTransfer::ref transfer) { + incomingFileTransfers_.push_back(transfer); + std::shared_ptr<FileWriteBytestream> out = std::make_shared<FileWriteBytestream>(receiveFilePath_.native()); + transfer->onFinished.connect(boost::bind(&FileTransferTest::handleReceiverFileTransferFinished, this, _1, out)); + + FileTransferOptions options; + options = options.withInBandAllowed(receiverCandidates_ & InBandBytestream); + options = options.withDirectAllowed(receiverCandidates_ & S5B_Direct); + options = options.withAssistedAllowed(receiverCandidates_ & S5B_Assisted); + options = options.withProxiedAllowed(receiverCandidates_ & S5B_Proxied); + + std::cout << "Incoming transfer options: " << "IBB (" << options.isInBandAllowed() << ")" << ", "; + std::cout << "S5B Direct (" << options.isDirectAllowed() << ")" << ", "; + std::cout << "S5B Assisted (" << options.isAssistedAllowed() << ")" << ", "; + std::cout << "S5B Proxied (" << options.isProxiedAllowed() << ")" << std::endl; + + transfer->accept(out, options); + } + + void handleSenderCapsChanged(const JID &jid) { + if (receiver_ && (receiver_->getJID().toBare() == jid.toBare())) { + std::shared_ptr<FileReadBytestream> fileStream = std::make_shared<FileReadBytestream>(sendFilePath_); + + FileTransferOptions options; + options = options.withInBandAllowed(senderCandidates_ & InBandBytestream); + options = options.withDirectAllowed(senderCandidates_ & S5B_Direct); + options = options.withAssistedAllowed(senderCandidates_ & S5B_Assisted); + options = options.withProxiedAllowed(senderCandidates_ & S5B_Proxied); + + std::cout << "Outgoing transfer options: " << "IBB (" << options.isInBandAllowed() << ")" << ", "; + std::cout << "S5B Direct (" << options.isDirectAllowed() << ")" << ", "; + std::cout << "S5B Assisted (" << options.isAssistedAllowed() << ")" << ", "; + std::cout << "S5B Proxied (" << options.isProxiedAllowed() << ")" << std::endl; + + outgoingFileTransfer_ = sender_->getFileTransferManager()->createOutgoingFileTransfer(jid.toBare(), sendFilePath_, "Some File!", fileStream, options); + + if (outgoingFileTransfer_) { + outgoingFileTransfer_->onFinished.connect(boost::bind(&FileTransferTest::handleSenderFileTransferFinished, this, _1)); + outgoingFileTransfer_->start(); + } else { + std::cout << "ERROR: No outgoing file transfer returned." << std::endl; + receiverIsDone_ = true; + senderIsDone_ = true; + endTest(); + } + } + } + + void handleReceiverFileTransferFinished(const boost::optional<FileTransferError>& error, std::shared_ptr<FileWriteBytestream> out) { + out->close(); + receiverError_ = error; + receiverIsDone_ = true; + if (senderIsDone_) { + timeOut_->stop(); + timeOut_ = networkFactories->getTimerFactory()->createTimer(1000); + timeOut_->onTick.connect(boost::bind(&FileTransferTest::endTest, this)); + timeOut_->start(); + } + } + + void handleSenderDisconnected(const boost::optional<ClientError>& error) { + if (error) { + std::cout << this << " " << "handleSenderDisconnected: error: " << error.get() << std::endl; + } + + // All file-transfers related to a Client instance need to be freed + // *before* freeing the Client instance. + outgoingFileTransfer_.reset(); + + sender_.reset(); + if (!sender_ && !receiver_) { + eventLoop->stop(); + } + } + + void handleReceiverDisconnected(const boost::optional<ClientError>& error) { + if (error) { + std::cout << this << " " << "handleReceiverDisconnected: error: " << error.get() << std::endl; + } + + // All file-transfers related to a Client instance need to be freed + // *before* freeing the Client instance. + incomingFileTransfers_.clear(); + + receiver_.reset(); + if (!sender_ && !receiver_) { + eventLoop->stop(); + } + } + + void handleSenderFileTransferFinished(const boost::optional<FileTransferError>& error) { + senderError_ = error; + senderIsDone_ = true; + if (receiverIsDone_) { + timeOut_->stop(); + timeOut_ = networkFactories->getTimerFactory()->createTimer(1000); + timeOut_->onTick.connect(boost::bind(&FileTransferTest::endTest, this)); + timeOut_->start(); + } + else if (error) { + endTest(); + } + } + + void run() { + timeOut_->start(); + eventLoop->run(); + } + + void endTest() { + if (sender_) { + sender_->disconnect(); + } + if (receiver_) { + receiver_->disconnect(); + } + } + + void handleTimeOut() { + std::cout << "Test timed out!!!" << std::endl; + endTest(); + } + + bool isDone() const { + return senderIsDone_ && receiverIsDone_; + } + + bool wasSuccessful() const { + return !senderError_ && !receiverError_; + } + + private: + int senderCandidates_; + std::shared_ptr<Client> sender_; + ClientXMLTracer* senderTracer_; + ByteArray sendData_; + OutgoingFileTransfer::ref outgoingFileTransfer_; + boost::filesystem::path sendFilePath_; + boost::optional<FileTransferError> senderError_; + bool senderIsDone_; + + int receiverCandidates_; + std::shared_ptr<Client> receiver_; + ClientXMLTracer* receiverTracer_; + ByteArray receiveData_; + std::vector<IncomingFileTransfer::ref> incomingFileTransfers_; + boost::filesystem::path receiveFilePath_; + boost::optional<FileTransferError> receiverError_; + bool receiverIsDone_; + + Timer::ref timeOut_; +}; + +static bool runTest(int senderCandidates, int receiverCandidates) { + bool success = false; + + std::cout << "senderCandidates: " << senderCandidates << ", receiverCandidates: " << receiverCandidates << std::endl; + bool expectSuccess = (senderCandidates & receiverCandidates) > 0; + + eventLoop = std::make_shared<SimpleEventLoop>(); + networkFactories = std::make_shared<BoostNetworkFactories>(eventLoop.get()); + + std::shared_ptr<FileTransferTest> testRun = std::make_shared<FileTransferTest>(senderCandidates, receiverCandidates); + + testRun->run(); + + bool wasSuccessful = testRun->wasSuccessful(); + if (expectSuccess == wasSuccessful) { + success = true; + } + else { + if (!testRun->isDone()) { + std::cout << "Test did not finish transfer. Sender candidates = " << senderCandidates << ", receiver candidates = " << receiverCandidates << "." << std::endl; + } + } + std::cout << "expected success: " << expectSuccess << ", wasSuccessful: " << wasSuccessful << std::endl; + + + testRun.reset(); + networkFactories.reset(); + eventLoop->runUntilEvents(); + + eventLoop->stop(); + eventLoop.reset(); + + return success; +} + +/** + * This program test file-transfer interop between Swift and itself with various connection candidates. + * The all combinations of the candidates, IBB, S5B (direct) and S5B (proxied), on sender and receiver side are tested. + */ +int main(int argc, char** argv) { + int failedTests = 0; + + std::vector<std::pair<int, int> > failedTestPairs; + std::cout << "Swiften File-Transfer Connectivity Test Suite" << std::endl; + if (argc == 1) { + if (getenv("SWIFT_FILETRANSFERTEST_CONFIG")) { + // test configuration described in SWIFT_FILETRANSFERTEST_CONFIG environment variable, e.g. "1:1|2:2" + std::vector<std::string> configurations; + std::string configs_env = std::string(getenv("SWIFT_FILETRANSFERTEST_CONFIG")); + boost::split(configurations, configs_env, boost::is_any_of("|")); + for (const auto& config : configurations) { + std::vector<std::string> split_config; + boost::split(split_config, config, boost::is_any_of(":")); + assert(split_config.size() == 2); + + int senderCandidates = atoi(split_config[0].c_str()); + int receiverCandidates = atoi(split_config[1].c_str()); + + if (!runTest(senderCandidates, receiverCandidates)) { + failedTests++; + failedTestPairs.push_back(std::pair<int, int>(senderCandidates, receiverCandidates)); + } + } + + for (auto&& failedTest : failedTestPairs) { + std::cout << "Failed test: " << "( " << failedTest.first << ", " << failedTest.second << ") " << std::endl; + } + } + else { + // test all configurations + for (int n = 0; n < (1 << 7); n++) { + int senderCandidates = n & 0xF; + int receiverCandidates = (n >> 4) & 0xF; + std::cout << "Run test " << n + 1 << " of " << (1 << 7) << ", (" << senderCandidates << ", " << receiverCandidates << ")" << std::endl; + if (!runTest(senderCandidates, receiverCandidates)) { + failedTests++; + failedTestPairs.push_back(std::pair<int, int>(senderCandidates, receiverCandidates)); + } + } + + for (auto&& failedTest : failedTestPairs) { + std::cout << "Failed test: " << "( " << failedTest.first << ", " << failedTest.second << ") " << std::endl; + } + } + } + else if (argc == 3) { + Log::setLogLevel(Log::debug); + int senderCandidates = atoi(argv[1]); + int receiverCandidates = atoi(argv[2]); + if (!runTest(senderCandidates, receiverCandidates)) { + failedTests++; + } + } + else { + std::cout << "Usage:" << std::endl; + std::cout << "\t- to test all combinations pass no arguments" << std::endl; + std::cout << "\t- to test a specific combination pass two integers describing sender and receiver candidates" << std::endl; + } + return failedTests; +} diff --git a/Swiften/QA/FileTransferTest/SConscript b/Swiften/QA/FileTransferTest/SConscript new file mode 100644 index 0000000..4b77674 --- /dev/null +++ b/Swiften/QA/FileTransferTest/SConscript @@ -0,0 +1,20 @@ +import os + +Import("env") + +if env["TEST"] : + myenv = env.Clone() + myenv.UseFlags(myenv["SWIFTEN_FLAGS"]) + myenv.UseFlags(myenv["SWIFTEN_DEP_FLAGS"]) + + for i in ["SWIFT_FILETRANSFERTEST_JID", "SWIFT_FILETRANSFERTEST_PASS", "SWIFT_FILETRANSFERTEST2_JID", "SWIFT_FILETRANSFERTEST2_PASS"]: + if ARGUMENTS.get(i.lower(), False) : + myenv["ENV"][i] = ARGUMENTS[i.lower()] + elif os.environ.get(i, "") : + myenv["ENV"][i] = os.environ[i] + + # test in-band transfers, direct SOCKS5 bytestream transfers and proxied SOCKS5 bytestream transfers + myenv["ENV"]["SWIFT_FILETRANSFERTEST_CONFIG"] = "1:1|2:2|4:4" + + tester = myenv.Program("FileTransferTest", ["FileTransferTest.cpp"]) + myenv.Test(tester, "system") diff --git a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp index 14da358..6982c0c 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp @@ -1,81 +1,215 @@ /* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ +#include <memory> +#include <string> + #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include <boost/shared_ptr.hpp> -#include <string> +#include <Swiften/Base/sleep.h> +#include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/Network/BoostConnectionServer.h> #include <Swiften/Network/BoostIOServiceThread.h> -#include <Swiften/EventLoop/DummyEventLoop.h> using namespace Swift; class BoostConnectionServerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(BoostConnectionServerTest); - CPPUNIT_TEST(testConstructor_TwoServersOnSamePort); - CPPUNIT_TEST(testStart_Conflict); - CPPUNIT_TEST(testStop); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - boostIOServiceThread_ = new BoostIOServiceThread(); - eventLoop_ = new DummyEventLoop(); - stopped = false; - stoppedError.reset(); - } - - void tearDown() { - while (eventLoop_->hasEvents()) { - eventLoop_->processEvents(); - } - delete eventLoop_; - delete boostIOServiceThread_; - } - - void testConstructor_TwoServersOnSamePort() { - BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); - BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); - } - - void testStart_Conflict() { - BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); - testling->start(); - - BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); - testling2->onStopped.connect( - boost::bind(&BoostConnectionServerTest::handleStopped, this, _1)); - - testling->stop(); - } - - void testStop() { - BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); - testling->start(); - - testling->stop(); - - BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); - testling2->start(); - - testling2->stop(); - } - - void handleStopped(boost::optional<BoostConnectionServer::Error> e) { - stopped = true; - stoppedError = e; - } - - private: - BoostIOServiceThread* boostIOServiceThread_; - DummyEventLoop* eventLoop_; - bool stopped; - boost::optional<BoostConnectionServer::Error> stoppedError; + CPPUNIT_TEST_SUITE(BoostConnectionServerTest); + CPPUNIT_TEST(testConstructor_TwoServersOnSamePort); + CPPUNIT_TEST(testStart_Conflict); + CPPUNIT_TEST(testStop); + CPPUNIT_TEST(testIPv4Server); + CPPUNIT_TEST(testIPv6Server); + CPPUNIT_TEST(testIPv4IPv6DualStackServer); + CPPUNIT_TEST(testIPv6DualStackServerPeerAddress); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + eventLoop_ = new DummyEventLoop(); + boostIOServiceThread_ = new BoostIOServiceThread(); + stopped_ = false; + stoppedError_.reset(); + receivedNewConnection_ = false; + connectFinished_ = false; + remoteAddress_ = boost::optional<HostAddressPort>(); + } + + void tearDown() { + delete boostIOServiceThread_; + while (eventLoop_->hasEvents()) { + eventLoop_->processEvents(); + } + delete eventLoop_; + } + + void testConstructor_TwoServersOnSamePort() { + BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); + BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); + } + + void testStart_Conflict() { + BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); + testling->start(); + + BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); + testling2->onStopped.connect( + boost::bind(&BoostConnectionServerTest::handleStopped_, this, _1)); + + testling->stop(); + } + + void testStop() { + BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); + testling->start(); + + testling->stop(); + + BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); + testling2->start(); + + testling2->stop(); + } + + void testIPv4Server() { + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress::fromString("127.0.0.1").get(), 9999, boostIOServiceThread_->getIOService(), eventLoop_); + testling->onNewConnection.connect(boost::bind(&BoostConnectionServerTest::handleNewConnection, this, _1)); + testling->start(); + + BoostConnection::ref clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); + clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("127.0.0.1").get(), 9999)); + + while (!connectFinished_) { + Swift::sleep(10); + eventLoop_->processEvents(); + } + + CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); + + testling->stop(); + } + + void testIPv6Server() { + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress::fromString("::1").get(), 9999, boostIOServiceThread_->getIOService(), eventLoop_); + testling->onNewConnection.connect(boost::bind(&BoostConnectionServerTest::handleNewConnection, this, _1)); + testling->start(); + + BoostConnection::ref clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); + clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("::1").get(), 9999)); + + while (!connectFinished_) { + Swift::sleep(10); + eventLoop_->processEvents(); + } + + CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); + + testling->stop(); + } + + void testIPv4IPv6DualStackServer() { + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress::fromString("::").get(), 9999, boostIOServiceThread_->getIOService(), eventLoop_); + testling->onNewConnection.connect(boost::bind(&BoostConnectionServerTest::handleNewConnection, this, _1)); + testling->start(); + + // Test IPv4. + BoostConnection::ref clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); + clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("127.0.0.1").get(), 9999)); + + while (!connectFinished_) { + Swift::sleep(10); + eventLoop_->processEvents(); + } + + CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); + + receivedNewConnection_ = false; + connectFinished_ = false; + + // Test IPv6. + clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); + clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("::1").get(), 9999)); + + while (!connectFinished_) { + Swift::sleep(10); + eventLoop_->processEvents(); + } + + CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); + + testling->stop(); + } + + void testIPv6DualStackServerPeerAddress() { + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress::fromString("::").get(), 9999, boostIOServiceThread_->getIOService(), eventLoop_); + testling->onNewConnection.connect(boost::bind(&BoostConnectionServerTest::handleNewConnection, this, _1)); + testling->start(); + + // Test IPv4. + BoostConnection::ref clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); + clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("127.0.0.1").get(), 9999)); + + while (!connectFinished_) { + Swift::sleep(10); + eventLoop_->processEvents(); + } + + CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); + // The IPv4 localhost mapped to a IPv6 address is expected here. + CPPUNIT_ASSERT(HostAddress::fromString("::ffff:127.0.0.1").get() == remoteAddress_.get().getAddress()); + + receivedNewConnection_ = false; + connectFinished_ = false; + remoteAddress_ = boost::optional<HostAddressPort>(); + + // Test IPv6. + clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); + clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("::1").get(), 9999)); + + while (!connectFinished_) { + Swift::sleep(10); + eventLoop_->processEvents(); + } + + CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); + // The IPv6 local host is expected here. + CPPUNIT_ASSERT(HostAddress::fromString("::1").get() == remoteAddress_.get().getAddress()); + + testling->stop(); + } + + void handleStopped_(boost::optional<BoostConnectionServer::Error> e) { + stopped_ = true; + stoppedError_ = e; + } + + void handleNewConnection(std::shared_ptr<Connection> connection) { + receivedNewConnection_ = true; + remoteAddress_ = connection->getRemoteAddress(); + } + + void handleConnectFinished(bool /*error*/) { + connectFinished_ = true; + } + + private: + BoostIOServiceThread* boostIOServiceThread_; + DummyEventLoop* eventLoop_; + bool stopped_; + bool receivedNewConnection_; + bool connectFinished_; + boost::optional<BoostConnectionServer::Error> stoppedError_; + boost::optional<HostAddressPort> remoteAddress_; }; CPPUNIT_TEST_SUITE_REGISTRATION(BoostConnectionServerTest); diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp index 53faff7..e0890bf 100644..100755 --- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp @@ -1,155 +1,179 @@ /* - * Copyright (c) 2010-2013 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ +#include <memory> +#include <string> + +#include <boost/date_time/posix_time/posix_time_types.hpp> + #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include <boost/shared_ptr.hpp> -#include <boost/smart_ptr/make_shared.hpp> -#include <string> #include <Swiften/Base/Algorithm.h> #include <Swiften/Base/sleep.h> +#include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/Network/BoostConnection.h> +#include <Swiften/Network/BoostIOServiceThread.h> #include <Swiften/Network/HostAddress.h> #include <Swiften/Network/HostAddressPort.h> -#include <Swiften/Network/BoostIOServiceThread.h> -#include <Swiften/EventLoop/DummyEventLoop.h> - -static const unsigned char* address = reinterpret_cast<const unsigned char*>("\x4A\x32\x3e\x31"); using namespace Swift; class BoostConnectionTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(BoostConnectionTest); - CPPUNIT_TEST(testDestructor); - CPPUNIT_TEST(testDestructor_PendingEvents); - CPPUNIT_TEST(testWrite); - CPPUNIT_TEST(testWriteMultipleSimultaniouslyQueuesWrites); + CPPUNIT_TEST_SUITE(BoostConnectionTest); + CPPUNIT_TEST(testDestructor); + CPPUNIT_TEST(testDestructor_PendingEvents); + CPPUNIT_TEST(testWrite); + CPPUNIT_TEST(testWriteMultipleSimultaniouslyQueuesWrites); #ifdef TEST_IPV6 - CPPUNIT_TEST(testWrite_IPv6); + CPPUNIT_TEST(testWrite_IPv6); #endif - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - boostIOServiceThread_ = new BoostIOServiceThread(); - boostIOService = boost::make_shared<boost::asio::io_service>(); - eventLoop_ = new DummyEventLoop(); - disconnected = false; - connectFinished = false; - } - - void tearDown() { - delete eventLoop_; - delete boostIOServiceThread_; - } - - void testDestructor() { - { - BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); - testling->connect(HostAddressPort(HostAddress(address, 4), 5222)); - } - } - - void testDestructor_PendingEvents() { - { - BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); - testling->connect(HostAddressPort(HostAddress(address, 4), 5222)); - while (!eventLoop_->hasEvents()) { - Swift::sleep(10); - } - } - eventLoop_->processEvents(); - } - - void testWrite() { - BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); - testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get())); - testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); - testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); - testling->connect(HostAddressPort(HostAddress("74.50.62.49"), 5222)); - while (receivedData.empty()) { - Swift::sleep(10); - eventLoop_->processEvents(); - } - testling->disconnect(); - } - - void testWrite_IPv6() { - BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); - testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get())); - testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); - testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); - testling->connect(HostAddressPort(HostAddress("2001:470:1f0e:852::2"), 80)); - while (receivedData.empty()) { - Swift::sleep(10); - eventLoop_->processEvents(); - } - testling->disconnect(); - } - - - void testWriteMultipleSimultaniouslyQueuesWrites() { - BoostConnection::ref testling(BoostConnection::create(boostIOService, eventLoop_)); - testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::handleConnectFinished, this)); - testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); - testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); - testling->connect(HostAddressPort(HostAddress("74.50.62.49"), 5222)); - while (!connectFinished) { - boostIOService->run_one(); - eventLoop_->processEvents(); - } - - testling->write(createSafeByteArray("<stream:strea")); - testling->write(createSafeByteArray("m")); - testling->write(createSafeByteArray(">")); - - // Check that we only did one write event, the others are queued - /*int runHandlers = */boostIOService->poll(); - // Disabling this test, because poll runns all handlers that are added during poll() as well, so - // this test doesn't really work any more. We'll have to trust that things are queued. - //CPPUNIT_ASSERT_EQUAL(1, runHandlers); - // Process the other events - while (receivedData.empty()) { - boostIOService->run_one(); - eventLoop_->processEvents(); - } - - // Disconnect & clean up - testling->disconnect(); - while (!disconnected) { - boostIOService->run_one(); - eventLoop_->processEvents(); - } - } - - void doWrite(BoostConnection* connection) { - connection->write(createSafeByteArray("<stream:stream>")); - connection->write(createSafeByteArray("\r\n\r\n")); // Temporarily, while we don't have an xmpp server running on ipv6 - } - - void handleDataRead(boost::shared_ptr<SafeByteArray> data) { - append(receivedData, *data); - } - - void handleDisconnected() { - disconnected = true; - } - - void handleConnectFinished() { - connectFinished = true; - } - - private: - BoostIOServiceThread* boostIOServiceThread_; - boost::shared_ptr<boost::asio::io_service> boostIOService; - DummyEventLoop* eventLoop_; - ByteArray receivedData; - bool disconnected; - bool connectFinished; + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + eventLoop_ = new DummyEventLoop(); + boostIOServiceThread_ = new BoostIOServiceThread(); + boostIOService_ = std::make_shared<boost::asio::io_service>(); + disconnected_ = false; + connectFinished_ = false; + } + + void tearDown() { + delete boostIOServiceThread_; + while (eventLoop_->hasEvents()) { + eventLoop_->processEvents(); + } + delete eventLoop_; + } + + void testDestructor() { + { + BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV4")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); + } + } + + void testDestructor_PendingEvents() { + { + BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV4")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); + while (!eventLoop_->hasEvents()) { + Swift::sleep(10); + } + } + eventLoop_->processEvents(); + } + + void testWrite() { + using namespace boost::posix_time; + + BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); + testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get())); + testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); + testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV4")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); + + boost::posix_time::ptime start = second_clock::local_time(); + while (receivedData_.empty() && ((second_clock::local_time() - start) < seconds(60))) { + Swift::sleep(10); + eventLoop_->processEvents(); + } + CPPUNIT_ASSERT_EQUAL(false, receivedData_.empty()); + testling->disconnect(); + } + + void testWrite_IPv6() { + using namespace boost::posix_time; + + BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); + testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get())); + testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); + testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV6")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); + + boost::posix_time::ptime start = second_clock::local_time(); + while (receivedData_.empty() && ((second_clock::local_time() - start) < seconds(60))) { + Swift::sleep(10); + eventLoop_->processEvents(); + } + CPPUNIT_ASSERT_EQUAL(false, receivedData_.empty()); + testling->disconnect(); + } + + + void testWriteMultipleSimultaniouslyQueuesWrites() { + BoostConnection::ref testling(BoostConnection::create(boostIOService_, eventLoop_)); + testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::handleConnectFinished, this)); + testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); + testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); + + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV4")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); + while (!connectFinished_) { + boostIOService_->run_one(); + eventLoop_->processEvents(); + } + + testling->write(createSafeByteArray("<stream:strea")); + testling->write(createSafeByteArray("m")); + testling->write(createSafeByteArray(">")); + + // Check that we only did one write event, the others are queued + /*int runHandlers = */boostIOService_->poll(); + // Disabling this test, because poll runns all handlers that are added during poll() as well, so + // this test doesn't really work any more. We'll have to trust that things are queued. + //CPPUNIT_ASSERT_EQUAL(1, runHandlers); + // Process the other events + while (receivedData_.empty()) { + boostIOService_->run_one(); + eventLoop_->processEvents(); + } + + // Disconnect & clean up + testling->disconnect(); + while (!disconnected_) { + boostIOService_->run_one(); + eventLoop_->processEvents(); + } + } + + void doWrite(BoostConnection* connection) { + connection->write(createSafeByteArray("<stream:stream>")); + connection->write(createSafeByteArray("\r\n\r\n")); // Temporarily, while we don't have an xmpp server running on ipv6 + } + + void handleDataRead(std::shared_ptr<SafeByteArray> data) { + append(receivedData_, *data); + } + + void handleDisconnected() { + disconnected_ = true; + } + + void handleConnectFinished() { + connectFinished_ = true; + } + + private: + BoostIOServiceThread* boostIOServiceThread_; + std::shared_ptr<boost::asio::io_service> boostIOService_; + DummyEventLoop* eventLoop_; + ByteArray receivedData_; + bool disconnected_; + bool connectFinished_; }; CPPUNIT_TEST_SUITE_REGISTRATION(BoostConnectionTest); diff --git a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp index bc4f1a3..69e6fe8 100644 --- a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp +++ b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp @@ -1,242 +1,254 @@ /* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2018 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ +#include <algorithm> +#include <string> + +#include <boost/bind.hpp> + #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include <boost/bind.hpp> -#include <algorithm> -#include <Swiften/Base/sleep.h> -#include <string> #include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/Platform.h> +#include <Swiften/Base/sleep.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/IDN/IDNConverter.h> +#include <Swiften/IDN/PlatformIDNConverter.h> +#include <Swiften/Network/BoostIOServiceThread.h> +#include <Swiften/Network/BoostTimerFactory.h> +#include <Swiften/Network/DomainNameAddressQuery.h> +#include <Swiften/Network/DomainNameServiceQuery.h> +#include <Swiften/Network/NetworkFactories.h> #ifdef USE_UNBOUND #include <Swiften/Network/UnboundDomainNameResolver.h> #else #include <Swiften/Network/PlatformDomainNameResolver.h> #endif -#include <Swiften/Network/BoostTimerFactory.h> -#include <Swiften/Network/NetworkFactories.h> -#include <Swiften/Network/BoostIOServiceThread.h> -#include <Swiften/Network/DomainNameAddressQuery.h> -#include <Swiften/Network/DomainNameServiceQuery.h> -#include <Swiften/EventLoop/DummyEventLoop.h> -#include <Swiften/IDN/IDNConverter.h> -#include <Swiften/IDN/PlatformIDNConverter.h> using namespace Swift; struct CompareHostAddresses { - bool operator()(const HostAddress& h1, const HostAddress& h2) { - return h1.toString() < h2.toString(); - } + bool operator()(const HostAddress& h1, const HostAddress& h2) { + return h1.toString() < h2.toString(); + } }; class DomainNameResolverTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(DomainNameResolverTest); - CPPUNIT_TEST(testResolveAddress); - CPPUNIT_TEST(testResolveAddress_Error); + CPPUNIT_TEST_SUITE(DomainNameResolverTest); + CPPUNIT_TEST(testResolveAddress); + CPPUNIT_TEST(testResolveAddress_Error); #ifndef USE_UNBOUND - CPPUNIT_TEST(testResolveAddress_IPv6); - CPPUNIT_TEST(testResolveAddress_IPv4and6); - CPPUNIT_TEST(testResolveAddress_International); + /** + * The native DNS resolver of Windows behaves oddly if the system has no global IPv6 + * routed address and no IPv6 reachability. It will not return IPv6 records from DNS + * requests for an unspecified protocol (IPv6 or IPv4). + * The following tests are only enabled on Windows if scons is run with the 'test_ipv6=1' + * argument, indicating working IPv6 on the test machine. + */ +#if !defined(SWIFTEN_PLATFORM_WINDOWS) || defined(TEST_IPV6) + CPPUNIT_TEST(testResolveAddress_IPv6); + CPPUNIT_TEST(testResolveAddress_IPv4and6); +#endif + CPPUNIT_TEST(testResolveAddress_International); #endif - CPPUNIT_TEST(testResolveAddress_Localhost); - CPPUNIT_TEST(testResolveAddress_Parallel); + CPPUNIT_TEST(testResolveAddress_Localhost); + CPPUNIT_TEST(testResolveAddress_Parallel); #ifndef USE_UNBOUND - CPPUNIT_TEST(testResolveService); + CPPUNIT_TEST(testResolveService); #endif - CPPUNIT_TEST(testResolveService_Error); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - ioServiceThread = new BoostIOServiceThread(); - eventLoop = new DummyEventLoop(); + CPPUNIT_TEST(testResolveService_Error); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + ioServiceThread = new BoostIOServiceThread(); + eventLoop = new DummyEventLoop(); + idnConverter = std::shared_ptr<IDNConverter>(PlatformIDNConverter::create()); #ifdef USE_UNBOUND - resolver = new UnboundDomainNameResolver(ioServiceThread->getIOService(), eventLoop); + resolver = new UnboundDomainNameResolver(idnConverter.get(), ioServiceThread->getIOService(), eventLoop); #else - idnConverter = boost::shared_ptr<IDNConverter>(PlatformIDNConverter::create()); - resolver = new PlatformDomainNameResolver(idnConverter.get(), eventLoop); + resolver = new PlatformDomainNameResolver(idnConverter.get(), eventLoop); #endif - resultsAvailable = false; - } - - void tearDown() { - delete ioServiceThread; - delete resolver; - delete eventLoop; - } - - void testResolveAddress() { - boost::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("xmpp.test.swift.im")); - - query->run(); - waitForResults(); - - CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addressQueryResult.size())); - CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), addressQueryResult[0].toString()); - } - - void testResolveAddress_Error() { - boost::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("invalid.test.swift.im")); - - query->run(); - waitForResults(); - - CPPUNIT_ASSERT(addressQueryError); - } - - void testResolveAddress_IPv6() { - boost::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("xmpp-ipv6.test.swift.im")); - - query->run(); - waitForResults(); - - CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT_EQUAL(std::string("2001:470:1f0e:852::2"), addressQueryResult[0].toString()); - } - - void testResolveAddress_IPv4and6() { - boost::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("xmpp-ipv46.test.swift.im")); - - query->run(); - waitForResults(); - - CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(addressQueryResult.size())); - CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.7"), addressQueryResult[0].toString()); - CPPUNIT_ASSERT_EQUAL(std::string("1234:5678:9abc:def0:fed:cba9:8765:4321"), addressQueryResult[1].toString()); - } - - void testResolveAddress_International() { - boost::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("tron\xc3\xa7on.test.swift.im")); - - query->run(); - waitForResults(); - - CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addressQueryResult.size())); - CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.3"), addressQueryResult[0].toString()); - } - - void testResolveAddress_Localhost() { - boost::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("localhost")); - - query->run(); - waitForResults(); - - CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT(std::find(addressQueryResult.begin(), addressQueryResult.end(), HostAddress("127.0.0.1")) != addressQueryResult.end()); - } - - void testResolveAddress_Parallel() { - std::vector<DomainNameAddressQuery::ref> queries; - static const size_t numQueries = 100; - for (size_t i = 0; i < numQueries; ++i) { - DomainNameAddressQuery::ref query(createAddressQuery("xmpp.test.swift.im")); - queries.push_back(query); - query->run(); - } - - eventLoop->processEvents(); - int ticks = 0; - while (allAddressQueryResults.size() < numQueries) { - ticks++; - if (ticks > 1000) { - CPPUNIT_ASSERT(false); - } - Swift::sleep(10); - eventLoop->processEvents(); - } - - CPPUNIT_ASSERT_EQUAL(numQueries, allAddressQueryResults.size()); - for (size_t i = 0; i < numQueries; ++i) { - CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), allAddressQueryResults[i].toString()); - } - } - - void testResolveService() { - boost::shared_ptr<DomainNameServiceQuery> query(createServiceQuery("_xmpp-client._tcp.xmpp-srv.test.swift.im")); - - query->run(); - waitForResults(); - - CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(serviceQueryResult.size())); - CPPUNIT_ASSERT_EQUAL(std::string("xmpp1.test.swift.im"), serviceQueryResult[0].hostname); - CPPUNIT_ASSERT_EQUAL(5000, serviceQueryResult[0].port); - CPPUNIT_ASSERT_EQUAL(0, serviceQueryResult[0].priority); - CPPUNIT_ASSERT_EQUAL(1, serviceQueryResult[0].weight); - CPPUNIT_ASSERT_EQUAL(std::string("xmpp-invalid.test.swift.im"), serviceQueryResult[1].hostname); - CPPUNIT_ASSERT_EQUAL(5000, serviceQueryResult[1].port); - CPPUNIT_ASSERT_EQUAL(1, serviceQueryResult[1].priority); - CPPUNIT_ASSERT_EQUAL(100, serviceQueryResult[1].weight); - CPPUNIT_ASSERT_EQUAL(std::string("xmpp3.test.swift.im"), serviceQueryResult[2].hostname); - CPPUNIT_ASSERT_EQUAL(5000, serviceQueryResult[2].port); - CPPUNIT_ASSERT_EQUAL(3, serviceQueryResult[2].priority); - CPPUNIT_ASSERT_EQUAL(100, serviceQueryResult[2].weight); - CPPUNIT_ASSERT_EQUAL(std::string("xmpp2.test.swift.im"), serviceQueryResult[3].hostname); - CPPUNIT_ASSERT_EQUAL(5000, serviceQueryResult[3].port); - CPPUNIT_ASSERT_EQUAL(5, serviceQueryResult[3].priority); - CPPUNIT_ASSERT_EQUAL(100, serviceQueryResult[3].weight); - } - - void testResolveService_Error() { - } - - private: - boost::shared_ptr<DomainNameAddressQuery> createAddressQuery(const std::string& domain) { - boost::shared_ptr<DomainNameAddressQuery> result = resolver->createAddressQuery(domain); - result->onResult.connect(boost::bind(&DomainNameResolverTest::handleAddressQueryResult, this, _1, _2)); - return result; - } - - void handleAddressQueryResult(const std::vector<HostAddress>& addresses, boost::optional<DomainNameResolveError> error) { - addressQueryResult = addresses; - std::sort(addressQueryResult.begin(), addressQueryResult.end(), CompareHostAddresses()); - allAddressQueryResults.insert(allAddressQueryResults.begin(), addresses.begin(), addresses.end()); - addressQueryError = error; - resultsAvailable = true; - } - - boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& domain) { - boost::shared_ptr<DomainNameServiceQuery> result = resolver->createServiceQuery(domain); - result->onResult.connect(boost::bind(&DomainNameResolverTest::handleServiceQueryResult, this, _1)); - return result; - } - - void handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result) { - serviceQueryResult = result; - resultsAvailable = true; - } - - void waitForResults() { - eventLoop->processEvents(); - int ticks = 0; - while (!resultsAvailable) { - ticks++; - if (ticks > 1000) { - CPPUNIT_ASSERT(false); - } - Swift::sleep(10); - eventLoop->processEvents(); - } - } - - private: - BoostIOServiceThread* ioServiceThread; - DummyEventLoop* eventLoop; - boost::shared_ptr<IDNConverter> idnConverter; - boost::shared_ptr<TimerFactory> timerFactory; - bool resultsAvailable; - std::vector<HostAddress> addressQueryResult; - std::vector<HostAddress> allAddressQueryResults; - boost::optional<DomainNameResolveError> addressQueryError; - std::vector<DomainNameServiceQuery::Result> serviceQueryResult; - DomainNameResolver* resolver; + resultsAvailable = false; + } + + void tearDown() { + delete ioServiceThread; + delete resolver; + delete eventLoop; + } + + void testResolveAddress() { + std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("xmpp.test.swift.im")); + + query->run(); + waitForResults(); + + CPPUNIT_ASSERT(!addressQueryError); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addressQueryResult.size())); + CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), addressQueryResult[0].toString()); + } + + void testResolveAddress_Error() { + std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("invalid.test.swift.im")); + + query->run(); + waitForResults(); + + CPPUNIT_ASSERT(addressQueryError); + } + + void testResolveAddress_IPv6() { + std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("xmpp-ipv6.test.swift.im")); + + query->run(); + waitForResults(); + + CPPUNIT_ASSERT(!addressQueryError); + CPPUNIT_ASSERT_EQUAL(std::string("2001:470:1f0e:852::2"), addressQueryResult[0].toString()); + } + + void testResolveAddress_IPv4and6() { + std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("xmpp-ipv46.test.swift.im")); + + query->run(); + waitForResults(); + + CPPUNIT_ASSERT(!addressQueryError); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(addressQueryResult.size())); + CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.7"), addressQueryResult[0].toString()); + CPPUNIT_ASSERT_EQUAL(std::string("1234:5678:9abc:def0:fed:cba9:8765:4321"), addressQueryResult[1].toString()); + } + + void testResolveAddress_International() { + std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("tron\xc3\xa7on.test.swift.im")); + + query->run(); + waitForResults(); + + CPPUNIT_ASSERT(!addressQueryError); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addressQueryResult.size())); + CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.3"), addressQueryResult[0].toString()); + } + + void testResolveAddress_Localhost() { + std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("localhost")); + + query->run(); + waitForResults(); + + CPPUNIT_ASSERT(!addressQueryError); + CPPUNIT_ASSERT(std::find(addressQueryResult.begin(), addressQueryResult.end(), HostAddress::fromString("127.0.0.1").get()) != addressQueryResult.end()); + } + + void testResolveAddress_Parallel() { + std::vector<DomainNameAddressQuery::ref> queries; + static const size_t numQueries = 100; + for (size_t i = 0; i < numQueries; ++i) { + DomainNameAddressQuery::ref query(createAddressQuery("xmpp.test.swift.im")); + queries.push_back(query); + query->run(); + } + + eventLoop->processEvents(); + int ticks = 0; + while (allAddressQueryResults.size() < numQueries) { + ticks++; + if (ticks > 1000) { + CPPUNIT_ASSERT(false); + } + Swift::sleep(10); + eventLoop->processEvents(); + } + + CPPUNIT_ASSERT_EQUAL(numQueries, allAddressQueryResults.size()); + for (size_t i = 0; i < numQueries; ++i) { + CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), allAddressQueryResults[i].toString()); + } + } + + void testResolveService() { + std::shared_ptr<DomainNameServiceQuery> query(createServiceQuery("_xmpp-client._tcp.", "xmpp-srv.test.swift.im")); + + query->run(); + waitForResults(); + + CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(serviceQueryResult.size())); + CPPUNIT_ASSERT_EQUAL(std::string("xmpp1.test.swift.im"), serviceQueryResult[0].hostname); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(5000), serviceQueryResult[0].port); + CPPUNIT_ASSERT_EQUAL(0, serviceQueryResult[0].priority); + CPPUNIT_ASSERT_EQUAL(1, serviceQueryResult[0].weight); + CPPUNIT_ASSERT_EQUAL(std::string("xmpp-invalid.test.swift.im"), serviceQueryResult[1].hostname); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(5000), serviceQueryResult[1].port); + CPPUNIT_ASSERT_EQUAL(1, serviceQueryResult[1].priority); + CPPUNIT_ASSERT_EQUAL(100, serviceQueryResult[1].weight); + CPPUNIT_ASSERT_EQUAL(std::string("xmpp3.test.swift.im"), serviceQueryResult[2].hostname); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(5000), serviceQueryResult[2].port); + CPPUNIT_ASSERT_EQUAL(3, serviceQueryResult[2].priority); + CPPUNIT_ASSERT_EQUAL(100, serviceQueryResult[2].weight); + CPPUNIT_ASSERT_EQUAL(std::string("xmpp2.test.swift.im"), serviceQueryResult[3].hostname); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(5000), serviceQueryResult[3].port); + CPPUNIT_ASSERT_EQUAL(5, serviceQueryResult[3].priority); + CPPUNIT_ASSERT_EQUAL(100, serviceQueryResult[3].weight); + } + + void testResolveService_Error() { + } + + private: + std::shared_ptr<DomainNameAddressQuery> createAddressQuery(const std::string& domain) { + std::shared_ptr<DomainNameAddressQuery> result = resolver->createAddressQuery(domain); + result->onResult.connect(boost::bind(&DomainNameResolverTest::handleAddressQueryResult, this, _1, _2)); + return result; + } + + void handleAddressQueryResult(const std::vector<HostAddress>& addresses, boost::optional<DomainNameResolveError> error) { + addressQueryResult = addresses; + std::sort(addressQueryResult.begin(), addressQueryResult.end(), CompareHostAddresses()); + allAddressQueryResults.insert(allAddressQueryResults.begin(), addresses.begin(), addresses.end()); + addressQueryError = error; + resultsAvailable = true; + } + + std::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain) { + std::shared_ptr<DomainNameServiceQuery> result = resolver->createServiceQuery(serviceLookupPrefix, domain); + result->onResult.connect(boost::bind(&DomainNameResolverTest::handleServiceQueryResult, this, _1)); + return result; + } + + void handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result) { + serviceQueryResult = result; + resultsAvailable = true; + } + + void waitForResults() { + eventLoop->processEvents(); + int ticks = 0; + while (!resultsAvailable) { + ticks++; + if (ticks > 1000) { + CPPUNIT_ASSERT(false); + } + Swift::sleep(10); + eventLoop->processEvents(); + } + } + + private: + BoostIOServiceThread* ioServiceThread; + DummyEventLoop* eventLoop; + std::shared_ptr<IDNConverter> idnConverter; + std::shared_ptr<TimerFactory> timerFactory; + bool resultsAvailable; + std::vector<HostAddress> addressQueryResult; + std::vector<HostAddress> allAddressQueryResults; + boost::optional<DomainNameResolveError> addressQueryError; + std::vector<DomainNameServiceQuery::Result> serviceQueryResult; + DomainNameResolver* resolver; }; CPPUNIT_TEST_SUITE_REGISTRATION(DomainNameResolverTest); diff --git a/Swiften/QA/NetworkTest/SConscript b/Swiften/QA/NetworkTest/SConscript index b090165..606af5d 100644 --- a/Swiften/QA/NetworkTest/SConscript +++ b/Swiften/QA/NetworkTest/SConscript @@ -3,20 +3,21 @@ import os Import("env") if env["TEST"] : - myenv = env.Clone() - if "test_ipv6" in ARGUMENTS : - myenv.Append(CPPDEFINES = ["TEST_IPV6"]) - myenv.MergeFlags(myenv["CHECKER_FLAGS"]) - myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) - myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) - myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) + myenv = env.Clone() + if "test_ipv6" in ARGUMENTS : + myenv.Append(CPPDEFINES = ["TEST_IPV6"]) + myenv.MergeFlags(myenv["CHECKER_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) + myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) + myenv.MergeFlags(myenv["GOOGLETEST_FLAGS"]) - if env.get("unbound", False) : - myenv.Append(CPPDEFINES = ["USE_UNBOUND"]) + if env.get("unbound", False) : + myenv.Append(CPPDEFINES = ["USE_UNBOUND"]) - tester = myenv.Program("NetworkTest", [ - "BoostConnectionServerTest.cpp", - "BoostConnectionTest.cpp", - "DomainNameResolverTest.cpp", - ]) - myenv.Test(tester, "system", is_checker = True) + tester = myenv.Program("NetworkTest", [ + "BoostConnectionServerTest.cpp", + "BoostConnectionTest.cpp", + "DomainNameResolverTest.cpp", + ]) + myenv.Test(tester, "system", is_checker = True) diff --git a/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp b/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp index ddaee01..53f9e60 100644 --- a/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp +++ b/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp @@ -4,32 +4,37 @@ * See Documentation/Licenses/BSD.txt for more information. */ +/* + * Copyright (c) 2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + #include <iostream> #include <Swiften/Network/PlatformProxyProvider.h> -#include <Swiften/Base/foreach.h> using namespace Swift; int main(void) { - int ret = 0; - HostAddressPort hap; - - std::cout << "constructing PlatfromProxyProvider instance ..." << std::endl; - PlatformProxyProvider ppp; - - hap = ppp.getSOCKS5Proxy(); - std::cout << "SOCKS5 Proxy configured: " << hap.isValid() << std::endl; - if(hap.isValid()) { - std::cout << "SOCKS5 Proxy: " << hap.getAddress().toString() << ":" << hap.getPort() << std::endl; - } - - hap = ppp.getHTTPConnectProxy(); - std::cout << "HTTPConnect Proxy configured: " << hap.isValid() << std::endl; - if(hap.isValid()) { - std::cout << "HTTPConnect Proxy: " << hap.getAddress().toString() << ":" << hap.getPort() << std::endl; - } - - return ret; + int ret = 0; + HostAddressPort hap; + + std::cout << "constructing PlatfromProxyProvider instance ..." << std::endl; + PlatformProxyProvider ppp; + + hap = ppp.getSOCKS5Proxy(); + std::cout << "SOCKS5 Proxy configured: " << hap.isValid() << std::endl; + if(hap.isValid()) { + std::cout << "SOCKS5 Proxy: " << hap.getAddress().toString() << ":" << hap.getPort() << std::endl; + } + + hap = ppp.getHTTPConnectProxy(); + std::cout << "HTTPConnect Proxy configured: " << hap.isValid() << std::endl; + if(hap.isValid()) { + std::cout << "HTTPConnect Proxy: " << hap.getAddress().toString() << ":" << hap.getPort() << std::endl; + } + + return ret; } diff --git a/Swiften/QA/ProxyProviderTest/SConscript b/Swiften/QA/ProxyProviderTest/SConscript index 2eb123d..3e28360 100644 --- a/Swiften/QA/ProxyProviderTest/SConscript +++ b/Swiften/QA/ProxyProviderTest/SConscript @@ -7,5 +7,5 @@ myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) myenv.Program("ProxyProviderTest", [ - "ProxyProviderTest.cpp", - ]) + "ProxyProviderTest.cpp", + ]) diff --git a/Swiften/QA/ReconnectTest/ReconnectTest.cpp b/Swiften/QA/ReconnectTest/ReconnectTest.cpp index 933d5d2..af3369c 100644 --- a/Swiften/QA/ReconnectTest/ReconnectTest.cpp +++ b/Swiften/QA/ReconnectTest/ReconnectTest.cpp @@ -1,20 +1,21 @@ /* - * Copyright (c) 2010 Kevin Smith - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ +#include <thread> + #include <boost/bind.hpp> -#include <boost/thread.hpp> #include <Swiften/Client/Client.h> -#include <Swiften/Network/BoostTimer.h> +#include <Swiften/Client/ClientXMLTracer.h> #include <Swiften/EventLoop/EventLoop.h> #include <Swiften/EventLoop/SimpleEventLoop.h> -#include <Swiften/Roster/GetRosterRequest.h> -#include <Swiften/Client/ClientXMLTracer.h> #include <Swiften/Network/BoostIOServiceThread.h> +#include <Swiften/Network/BoostTimer.h> #include <Swiften/Network/MainBoostIOServiceThread.h> +#include <Swiften/Roster/GetRosterRequest.h> using namespace Swift; @@ -25,49 +26,49 @@ Client* client_; SimpleEventLoop eventLoop_; int count = 0; -void handleTick(boost::shared_ptr<BoostTimer> timer) { - std::cout << "Count " << count++ << std::endl; - if (timer) { - timer->stop(); - } - if (connecting_) { - client_->disconnect(); - } else { - if (count > 60) { - eventLoop_.stop(); - return; - } - client_->connect(); - } - connecting_ = !connecting_; - - int delay = 500; -// int delay = 0; - boost::shared_ptr<BoostTimer> newTimer(BoostTimer::create(delay, &MainBoostIOServiceThread::getInstance().getIOService())); - newTimer->onTick.connect(boost::bind(&handleTick, timer)); - newTimer->start(); +void handleTick(std::shared_ptr<BoostTimer> timer) { + std::cout << "Count " << count++ << std::endl; + if (timer) { + timer->stop(); + } + if (connecting_) { + client_->disconnect(); + } else { + if (count > 60) { + eventLoop_.stop(); + return; + } + client_->connect(); + } + connecting_ = !connecting_; + + int delay = 500; +// int delay = 0; + std::shared_ptr<BoostTimer> newTimer(BoostTimer::create(delay, &MainBoostIOServiceThread::getInstance().getIOService())); + newTimer->onTick.connect(boost::bind(&handleTick, timer)); + newTimer->start(); } int main(int, char**) { - char* jidChars = getenv("SWIFT_CLIENTTEST_JID"); - if (!jidChars) { - std::cerr << "Please set the SWIFT_CLIENTTEST_JID environment variable" << std::endl; - return -1; - } - char* passChars = getenv("SWIFT_CLIENTTEST_PASS"); - if (!passChars) { - std::cerr << "Please set the SWIFT_CLIENTTEST_PASS environment variable" << std::endl; - return -1; - } - - JID jid(jidChars); - std::string pass(passChars); + char* jidChars = getenv("SWIFT_CLIENTTEST_JID"); + if (!jidChars) { + std::cerr << "Please set the SWIFT_CLIENTTEST_JID environment variable" << std::endl; + return -1; + } + char* passChars = getenv("SWIFT_CLIENTTEST_PASS"); + if (!passChars) { + std::cerr << "Please set the SWIFT_CLIENTTEST_PASS environment variable" << std::endl; + return -1; + } + + JID jid(jidChars); + std::string pass(passChars); + + client_ = new Swift::Client(jid, pass); + handleTick(std::shared_ptr<BoostTimer>()); + eventLoop_.run(); - client_ = new Swift::Client(jid, pass); - handleTick(boost::shared_ptr<BoostTimer>()); - eventLoop_.run(); - - delete client_; - return 0; + delete client_; + return 0; } diff --git a/Swiften/QA/ReconnectTest/SConscript b/Swiften/QA/ReconnectTest/SConscript index 6db6a6f..a94af5e 100644 --- a/Swiften/QA/ReconnectTest/SConscript +++ b/Swiften/QA/ReconnectTest/SConscript @@ -3,23 +3,23 @@ import os Import("env") if env["TEST"] : - myenv = env.Clone() - myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) - myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) - myenv.MergeFlags(myenv["LIBIDN_FLAGS"]) - myenv.MergeFlags(myenv["BOOST_FLAGS"]) - myenv.MergeFlags(myenv.get("SQLITE_FLAGS", "")) - myenv.MergeFlags(myenv["ZLIB_FLAGS"]) - myenv.MergeFlags(myenv["OPENSSL_FLAGS"]) - myenv.MergeFlags(myenv.get("LIBXML_FLAGS", "")) - myenv.MergeFlags(myenv.get("EXPAT_FLAGS", "")) - myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) -# myenv.Append(LIBPATH = ["/opt/local/lib"]) -# myenv.Append(LIBS = ["efence"]) + myenv = env.Clone() + myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) + myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) + myenv.MergeFlags(myenv["LIBIDN_FLAGS"]) + myenv.MergeFlags(myenv["BOOST_FLAGS"]) + myenv.MergeFlags(myenv.get("SQLITE_FLAGS", "")) + myenv.MergeFlags(myenv["ZLIB_FLAGS"]) + myenv.MergeFlags(myenv["OPENSSL_FLAGS"]) + myenv.MergeFlags(myenv.get("LIBXML_FLAGS", "")) + myenv.MergeFlags(myenv.get("EXPAT_FLAGS", "")) + myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) +# myenv.Append(LIBPATH = ["/opt/local/lib"]) +# myenv.Append(LIBS = ["efence"]) - for i in ["SWIFT_CLIENTTEST_JID", "SWIFT_CLIENTTEST_PASS"]: - if os.environ.get(i, "") : - myenv["ENV"][i] = os.environ[i] + for i in ["SWIFT_CLIENTTEST_JID", "SWIFT_CLIENTTEST_PASS"]: + if os.environ.get(i, "") : + myenv["ENV"][i] = os.environ[i] - tester = myenv.Program("ReconnectTest", ["ReconnectTest.cpp"]) - myenv.Test(tester, "system", is_checker = True) + tester = myenv.Program("ReconnectTest", ["ReconnectTest.cpp"]) + myenv.Test(tester, "system", is_checker = True) diff --git a/Swiften/QA/SConscript b/Swiften/QA/SConscript index 2f2be6e..2bb3e51 100644 --- a/Swiften/QA/SConscript +++ b/Swiften/QA/SConscript @@ -1,12 +1,13 @@ Import("swiften_env") SConscript(dirs = [ - "NetworkTest", -# "ReconnectTest", - "ClientTest", -# "DNSSDTest", -# "StorageTest", - "TLSTest", - "ScriptedTests", - "ProxyProviderTest", - ]) + "NetworkTest", +# "ReconnectTest", + "ClientTest", +# "DNSSDTest", + "StorageTest", + "TLSTest", + "ScriptedTests", + "ProxyProviderTest", + "FileTransferTest", + ]) diff --git a/Swiften/QA/ScriptedTests/MultipleClients.lua b/Swiften/QA/ScriptedTests/MultipleClients.lua index ddc7c44..ba29adb 100644 --- a/Swiften/QA/ScriptedTests/MultipleClients.lua +++ b/Swiften/QA/ScriptedTests/MultipleClients.lua @@ -1,7 +1,7 @@ -- --- Copyright (c) 2010-2013 Remko Tronçon --- Licensed under the GNU General Public License v3. --- See Documentation/Licenses/GPLv3.txt for more information. +-- Copyright (c) 2010-2013 Isode Limited. +-- All rights reserved.v3. +-- See the COPYING file for more information. -- require "sluift" diff --git a/Swiften/QA/ScriptedTests/PubSub.lua b/Swiften/QA/ScriptedTests/PubSub.lua index cb4679a..04a82ba 100644 --- a/Swiften/QA/ScriptedTests/PubSub.lua +++ b/Swiften/QA/ScriptedTests/PubSub.lua @@ -1,6 +1,6 @@ --[[ - Copyright (c) 2013 Remko Tronçon - Licensed under the GNU General Public License. + Copyright (c) 2013 Isode Limited. + All rights reserved. See the COPYING file for more information. --]] @@ -60,11 +60,15 @@ function test_entity_use_cases() -- 5.6 Subscriptions assert(node:create()) assert(subscriber_node:subscribe({ jid = subscriber_jid })) - local service_subscriptions = assert(pubsub:get_subscriptions()) - -- FIXME: Doesn't seem to return anything on M-Link. Test this later if this is supposed to work. - --print(service_subscriptions) - local node_subscriptions = assert(node:get_subscriptions()) - --print(node_subscriptions) + local service_subscriptions = assert(subscriber_pubsub:get_subscriptions()) + assert(#service_subscriptions == 1) + assert(service_subscriptions[1].node == node_id) + assert(service_subscriptions[1].jid == subscriber_jid) + assert(service_subscriptions[1].subscription == 'subscribed') + local node_subscriptions = assert(subscriber_node:get_subscriptions()) + assert(#node_subscriptions == 1) + assert(node_subscriptions[1].jid == subscriber_jid) + assert(node_subscriptions[1].subscription == 'subscribed') assert(node:delete()) -- 5.7 Retrieve affiliations @@ -282,7 +286,25 @@ function test_owner_use_cases() -- 8.7 Process pending subscription requests -- TODO - -- ... + -- 8.8 Manage Subscriptions + assert(node:create()) + assert(subscriber_node:subscribe({ jid = subscriber_jid })) + local items = assert(node:get_owner_subscriptions()) + assert(#items == 1) + assert(items[1].jid == subscriber_jid) + assert(items[1].subscription == "subscribed") + assert(node:delete()) + + -- 8.9 Manage Affiliations + assert(node:create()) + assert(node:set_owner_affiliations{affiliations = {{jid = subscriber_jid, type = 'publisher'}}}) + local items = assert(node:get_owner_affiliations()) + assert(#items == 2) + assert(items[1].jid == publisher_jid) + assert(items[1].type == "owner") + assert(items[2].jid == subscriber_jid) + assert(items[2].type == "publisher") + assert(node:delete()) end function run_tests() diff --git a/Swiften/QA/ScriptedTests/SConscript b/Swiften/QA/ScriptedTests/SConscript index 298c455..ae315fe 100644 --- a/Swiften/QA/ScriptedTests/SConscript +++ b/Swiften/QA/ScriptedTests/SConscript @@ -1,7 +1,7 @@ Import("env") if env["TEST"] : - env.ScriptTests([ - "SendMessage.lua", - "MultipleClients.lua", - ], "Swiften.QA.ScriptedTests", "system") + env.ScriptTests([ + "SendMessage.lua", + "MultipleClients.lua", + ], "Swiften.QA.ScriptedTests", "system") diff --git a/Swiften/QA/ScriptedTests/SendMessage.lua b/Swiften/QA/ScriptedTests/SendMessage.lua index 9623ef4..f6e5b00 100644 --- a/Swiften/QA/ScriptedTests/SendMessage.lua +++ b/Swiften/QA/ScriptedTests/SendMessage.lua @@ -1,7 +1,7 @@ -- --- Copyright (c) 2010-2013 Remko Tronçon --- Licensed under the GNU General Public License v3. --- See Documentation/Licenses/GPLv3.txt for more information. +-- Copyright (c) 2010-2013 Isode Limited. +-- All rights reserved.v3. +-- See the COPYING file for more information. -- require "sluift" diff --git a/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp b/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp index e090c6c..e601de9 100644 --- a/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp +++ b/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp @@ -1,7 +1,7 @@ /* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ #include <cppunit/extensions/HelperMacros.h> @@ -9,66 +9,67 @@ #include <Swiften/Base/ByteArray.h> #include <Swiften/FileTransfer/FileReadBytestream.h> -#include "SwifTools/Application/PlatformApplicationPathProvider.h" + +#include <SwifTools/Application/PlatformApplicationPathProvider.h> using namespace Swift; class FileReadBytestreamTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(FileReadBytestreamTest); - CPPUNIT_TEST(testRead); - CPPUNIT_TEST(testRead_Twice); - CPPUNIT_TEST(testIsFinished_NotFinished); - CPPUNIT_TEST(testIsFinished_IsFinished); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(FileReadBytestreamTest); + CPPUNIT_TEST(testRead); + CPPUNIT_TEST(testRead_Twice); + CPPUNIT_TEST(testIsFinished_NotFinished); + CPPUNIT_TEST(testIsFinished_IsFinished); + CPPUNIT_TEST_SUITE_END(); - public: - void setUp() { - pathProvider = new PlatformApplicationPathProvider("FileReadBytestreamTest"); - } + public: + void setUp() { + pathProvider = new PlatformApplicationPathProvider("FileReadBytestreamTest"); + } - void tearDown() { - delete pathProvider; - } + void tearDown() { + delete pathProvider; + } - void testRead() { - boost::shared_ptr<FileReadBytestream> testling(createTestling()); + void testRead() { + std::shared_ptr<FileReadBytestream> testling(createTestling()); - std::vector<unsigned char> result = testling->read(10); + std::shared_ptr< std::vector<unsigned char> > result = testling->read(10); - CPPUNIT_ASSERT(ByteArray::create("/*\n * Copy") == result); - } + CPPUNIT_ASSERT(createByteArray("/*\n * Copy") == *result.get()); + } - void testRead_Twice() { - boost::shared_ptr<FileReadBytestream> testling(createTestling()); + void testRead_Twice() { + std::shared_ptr<FileReadBytestream> testling(createTestling()); - testling->read(10); - ByteArray result(testling->read(10)); + testling->read(10); + std::shared_ptr< std::vector<unsigned char> > result = testling->read(10); - CPPUNIT_ASSERT_EQUAL(std::string("right (c) "), result.toString()); - } + CPPUNIT_ASSERT_EQUAL(std::string("right (c) "), byteArrayToString(*result)); + } - void testIsFinished_NotFinished() { - boost::shared_ptr<FileReadBytestream> testling(createTestling()); + void testIsFinished_NotFinished() { + std::shared_ptr<FileReadBytestream> testling(createTestling()); - testling->read(10); + testling->read(10); - CPPUNIT_ASSERT(!testling->isFinished()); - } + CPPUNIT_ASSERT(!testling->isFinished()); + } - void testIsFinished_IsFinished() { - boost::shared_ptr<FileReadBytestream> testling(createTestling()); + void testIsFinished_IsFinished() { + std::shared_ptr<FileReadBytestream> testling(createTestling()); - testling->read(4096); + testling->read(4096); - CPPUNIT_ASSERT(testling->isFinished()); - } + CPPUNIT_ASSERT(testling->isFinished()); + } - private: - FileReadBytestream* createTestling() { - return new FileReadBytestream(pathProvider->getExecutableDir() / "FileReadBytestreamTest.cpp"); - } + private: + FileReadBytestream* createTestling() { + return new FileReadBytestream(pathProvider->getExecutableDir() / "FileReadBytestreamTest.cpp"); + } - PlatformApplicationPathProvider* pathProvider; + PlatformApplicationPathProvider* pathProvider; }; CPPUNIT_TEST_SUITE_REGISTRATION(FileReadBytestreamTest); diff --git a/Swiften/QA/StorageTest/FileWriteBytestreamTest.cpp b/Swiften/QA/StorageTest/FileWriteBytestreamTest.cpp new file mode 100644 index 0000000..393d1d7 --- /dev/null +++ b/Swiften/QA/StorageTest/FileWriteBytestreamTest.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <boost/bind.hpp> +#include <boost/filesystem.hpp> +#include <boost/signals2.hpp> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/FileTransfer/FileWriteBytestream.h> + +using namespace Swift; + +class FileWriteBytestreamTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(FileWriteBytestreamTest); + CPPUNIT_TEST(testSuccessfulWrite); + CPPUNIT_TEST(testFailingWrite); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + onWriteWasCalled = false; + } + + void testSuccessfulWrite() { + boost::filesystem::path filename = boost::filesystem::unique_path("write_file_bytestream_test_%%%%%%%%%%%%%%%%.bin"); + std::shared_ptr<WriteBytestream> writeBytestream = std::make_shared<FileWriteBytestream>(filename.string()); + writeBytestream->onWrite.connect(boost::bind(&FileWriteBytestreamTest::handleOnWrite, this, _1)); + + CPPUNIT_ASSERT_EQUAL(true, writeBytestream->write(createByteArray("Some data."))); + CPPUNIT_ASSERT_EQUAL(true, onWriteWasCalled); + writeBytestream->close(); + boost::filesystem::remove(filename); + } + + void testFailingWrite() { + std::shared_ptr<WriteBytestream> writeBytestream = std::make_shared<FileWriteBytestream>(""); + writeBytestream->onWrite.connect(boost::bind(&FileWriteBytestreamTest::handleOnWrite, this, _1)); + + CPPUNIT_ASSERT_EQUAL(false, writeBytestream->write(createByteArray("Some data."))); + CPPUNIT_ASSERT_EQUAL(false, onWriteWasCalled); + } + + + void handleOnWrite(const std::vector<unsigned char>& /*data*/) { + onWriteWasCalled = true; + } + + private: + bool onWriteWasCalled; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(FileWriteBytestreamTest); diff --git a/Swiften/QA/StorageTest/SConscript b/Swiften/QA/StorageTest/SConscript index 6d65b30..46107a0 100644 --- a/Swiften/QA/StorageTest/SConscript +++ b/Swiften/QA/StorageTest/SConscript @@ -3,19 +3,22 @@ import os Import("env") if env["TEST"] : - myenv = env.Clone() - myenv.MergeFlags(myenv["CHECKER_FLAGS"]) - myenv.MergeFlags(myenv["SWIFTOOLS_FLAGS"]) - myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) - myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) - myenv.MergeFlags(myenv["BOOST_FLAGS"]) - myenv.MergeFlags(myenv["LIBIDN_FLAGS"]) - myenv.MergeFlags(myenv.get("EXPAT_FLAGS", {})) - myenv.MergeFlags(myenv.get("LIBXML_FLAGS", {})) - myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) + myenv = env.Clone() + myenv.MergeFlags(myenv["CHECKER_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTOOLS_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) + myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) + myenv.MergeFlags(myenv["GOOGLETEST_FLAGS"]) + myenv.MergeFlags(myenv["BOOST_FLAGS"]) + myenv.MergeFlags(myenv.get("LIBIDN_FLAGS", {})) + myenv.MergeFlags(myenv.get("ICU_FLAGS", {})) + myenv.MergeFlags(myenv.get("EXPAT_FLAGS", {})) + myenv.MergeFlags(myenv.get("LIBXML_FLAGS", {})) + myenv.MergeFlags(myenv["PLATFORM_FLAGS"]) - tester = myenv.Program("StorageTest", [ - "VCardFileStorageTest.cpp", - "FileReadBytestreamTest.cpp", - ]) - myenv.Test(tester, "system", is_checker = True) + tester = myenv.Program("StorageTest", [ + #"VCardFileStorageTest.cpp", + "FileReadBytestreamTest.cpp", + "FileWriteBytestreamTest.cpp", + ]) + myenv.Test(tester, "system", is_checker = True) diff --git a/Swiften/QA/StorageTest/VCardFileStorageTest.cpp b/Swiften/QA/StorageTest/VCardFileStorageTest.cpp index 4145696..1be2490 100644 --- a/Swiften/QA/StorageTest/VCardFileStorageTest.cpp +++ b/Swiften/QA/StorageTest/VCardFileStorageTest.cpp @@ -1,113 +1,117 @@ /* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ +#include <memory> +#include <sstream> + +#include <boost/algorithm/string.hpp> + #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include <boost/algorithm/string.hpp> -#include <sstream> -#include <Swiften/VCards/VCardFileStorage.h> -#include <Swiften/JID/JID.h> -#include "SwifTools/Application/PlatformApplicationPathProvider.h" #include <Swiften/Elements/VCard.h> +#include <Swiften/JID/JID.h> +#include <Swiften/VCards/VCardFileStorage.h> + +#include <SwifTools/Application/PlatformApplicationPathProvider.h> using namespace Swift; class VCardFileStorageTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(VCardFileStorageTest); - CPPUNIT_TEST(testSetVCard); - // Temporarily disabling this, because it generates error messages on console. Need to figure - // out something for not showing error messages during tests. - //CPPUNIT_TEST(testSetVCard_LargeFilename); - CPPUNIT_TEST(testGetVCard); - CPPUNIT_TEST(testGetVCard_FileDoesNotExist); - //CPPUNIT_TEST(testGetVCard_LargeFilename); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - pathProvider = new PlatformApplicationPathProvider("VCardStorageTest"); - vcardsPath = pathProvider->getExecutableDir() / "vcards"; - boost::filesystem::remove_all(vcardsPath); - } - - void tearDown() { - delete pathProvider; - boost::filesystem::remove_all(vcardsPath); - } - - void testSetVCard() { - boost::shared_ptr<VCardFileStorage> testling(createTestling()); - VCard::ref vcard(new VCard()); - vcard->setFullName("Alice In Wonderland"); - - testling->setVCard(JID("alice@wonderland.lit/TeaRoom"), vcard); - - boost::filesystem::path vcardFile(vcardsPath / "alice@wonderland.lit%2fTeaRoom.xml"); - CPPUNIT_ASSERT(boost::filesystem::exists(vcardFile)); - ByteArray data; - data.readFromFile(vcardFile); - CPPUNIT_ASSERT(boost::starts_with(data.toString(), "<vCard xmlns=\"vcard-temp\">")); - } - - void testSetVCard_LargeFilename() { - std::auto_ptr<VCardFileStorage> testling(createTestling()); - VCard::ref vcard(new VCard()); - vcard->setFullName("Alice In Wonderland"); - - std::ostringstream s; - for (int i = 0; i < 1000; ++i) { - s << "_"; - } - - JID jid("alice@wonderland.lit/" + s.str()); - testling->setVCard(jid, vcard); - - // Just check whether we don't crash - } - - void testGetVCard() { - boost::shared_ptr<VCardFileStorage> testling(createTestling()); - VCard::ref vcard(new VCard()); - vcard->setFullName("Alice In Wonderland"); - testling->setVCard(JID("alice@wonderland.lit"), vcard); - - VCard::ref result = testling->getVCard(JID("alice@wonderland.lit")); - CPPUNIT_ASSERT_EQUAL(std::string("Alice In Wonderland"), result->getFullName()); - } - - void testGetVCard_LargeFilename() { - std::auto_ptr<VCardFileStorage> testling(createTestling()); - VCard::ref vcard(new VCard()); - vcard->setFullName("Alice In Wonderland"); - - std::ostringstream s; - for (int i = 0; i < 1000; ++i) { - s << "_"; - } - JID jid("alice@wonderland.lit/" + s.str()); - - VCard::ref result = testling->getVCard(jid); - - // Just check that we don't have an exception - } - - void testGetVCard_FileDoesNotExist() { - boost::shared_ptr<VCardFileStorage> testling(createTestling()); - VCard::ref result = testling->getVCard(JID("alice@wonderland.lit")); - CPPUNIT_ASSERT(!result); - } - - private: - VCardFileStorage* createTestling() { - return new VCardFileStorage(vcardsPath); - } - - PlatformApplicationPathProvider* pathProvider; - boost::filesystem::path vcardsPath; + CPPUNIT_TEST_SUITE(VCardFileStorageTest); + CPPUNIT_TEST(testSetVCard); + // Temporarily disabling this, because it generates error messages on console. Need to figure + // out something for not showing error messages during tests. + //CPPUNIT_TEST(testSetVCard_LargeFilename); + CPPUNIT_TEST(testGetVCard); + CPPUNIT_TEST(testGetVCard_FileDoesNotExist); + //CPPUNIT_TEST(testGetVCard_LargeFilename); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + pathProvider = new PlatformApplicationPathProvider("VCardStorageTest"); + vcardsPath = pathProvider->getExecutableDir() / "vcards"; + boost::filesystem::remove_all(vcardsPath); + } + + void tearDown() { + delete pathProvider; + boost::filesystem::remove_all(vcardsPath); + } + + void testSetVCard() { + std::shared_ptr<VCardFileStorage> testling(createTestling()); + VCard::ref vcard(new VCard()); + vcard->setFullName("Alice In Wonderland"); + + testling->setVCard(JID("alice@wonderland.lit/TeaRoom"), vcard); + + boost::filesystem::path vcardFile(vcardsPath / "alice@wonderland.lit%2fTeaRoom.xml"); + CPPUNIT_ASSERT(boost::filesystem::exists(vcardFile)); + ByteArray data; + data.readFromFile(vcardFile); + CPPUNIT_ASSERT(boost::starts_with(data.toString(), "<vCard xmlns=\"vcard-temp\">")); + } + + void testSetVCard_LargeFilename() { + std::unique_ptr<VCardFileStorage> testling(createTestling()); + VCard::ref vcard(new VCard()); + vcard->setFullName("Alice In Wonderland"); + + std::ostringstream s; + for (int i = 0; i < 1000; ++i) { + s << "_"; + } + + JID jid("alice@wonderland.lit/" + s.str()); + testling->setVCard(jid, vcard); + + // Just check whether we don't crash + } + + void testGetVCard() { + std::shared_ptr<VCardFileStorage> testling(createTestling()); + VCard::ref vcard(new VCard()); + vcard->setFullName("Alice In Wonderland"); + testling->setVCard(JID("alice@wonderland.lit"), vcard); + + VCard::ref result = testling->getVCard(JID("alice@wonderland.lit")); + CPPUNIT_ASSERT_EQUAL(std::string("Alice In Wonderland"), result->getFullName()); + } + + void testGetVCard_LargeFilename() { + std::unique_ptr<VCardFileStorage> testling(createTestling()); + VCard::ref vcard(new VCard()); + vcard->setFullName("Alice In Wonderland"); + + std::ostringstream s; + for (int i = 0; i < 1000; ++i) { + s << "_"; + } + JID jid("alice@wonderland.lit/" + s.str()); + + VCard::ref result = testling->getVCard(jid); + + // Just check that we don't have an exception + } + + void testGetVCard_FileDoesNotExist() { + std::shared_ptr<VCardFileStorage> testling(createTestling()); + VCard::ref result = testling->getVCard(JID("alice@wonderland.lit")); + CPPUNIT_ASSERT(!result); + } + + private: + VCardFileStorage* createTestling() { + return new VCardFileStorage(vcardsPath); + } + + PlatformApplicationPathProvider* pathProvider; + boost::filesystem::path vcardsPath; }; CPPUNIT_TEST_SUITE_REGISTRATION(VCardFileStorageTest); diff --git a/Swiften/QA/TLSTest/CertificateErrorTest.cpp b/Swiften/QA/TLSTest/CertificateErrorTest.cpp new file mode 100644 index 0000000..abd004e --- /dev/null +++ b/Swiften/QA/TLSTest/CertificateErrorTest.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2015-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + + /* + This file uses http://www.tls-o-matic.com/ to test the currently configured TLS backend for correct certificate validation behavior. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Base/Log.h> +#include <Swiften/EventLoop/DummyEventLoop.h> +#include <Swiften/IDN/IDNConverter.h> +#include <Swiften/IDN/PlatformIDNConverter.h> +#include <Swiften/Network/BoostConnectionFactory.h> +#include <Swiften/Network/BoostIOServiceThread.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/Network/PlatformDomainNameResolver.h> +#include <Swiften/Network/TLSConnection.h> +#include <Swiften/Network/TLSConnectionFactory.h> +#include <Swiften/TLS/CertificateVerificationError.h> +#include <Swiften/TLS/PlatformTLSFactories.h> +#include <Swiften/TLS/TLSContext.h> +#include <Swiften/TLS/TLSContextFactory.h> + +using namespace Swift; + +class CertificateErrorTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(CertificateErrorTest); + + // These test require the TLS-O-Matic testing CA to be trusted. For more info see https://www.tls-o-matic.com/https/test1 . + CPPUNIT_TEST(testTLS_O_MaticTrusted); + CPPUNIT_TEST(testTLS_O_MaticCertificateFromTheFuture); + CPPUNIT_TEST(testTLS_O_MaticCertificateFromThePast); + CPPUNIT_TEST(testTLS_O_MaticCertificateFromUnknownCA); + CPPUNIT_TEST(testTLS_O_MaticCertificateWrongPurpose); + +#if !defined(HAVE_OPENSSL) + // Our OpenSSL backend does not support revocation. We excluded it from the revocation tests. + CPPUNIT_TEST(testRevokedCertificateRevocationDisabled); + CPPUNIT_TEST(testRevokedCertificateRevocationEnabled); +#endif + + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + eventLoop_ = new DummyEventLoop(); + boostIOServiceThread_ = new BoostIOServiceThread(); + boostIOService_ = std::make_shared<boost::asio::io_service>(); + connectionFactory_ = new BoostConnectionFactory(boostIOServiceThread_->getIOService(), eventLoop_); + idnConverter_ = PlatformIDNConverter::create(); + domainNameResolver_ = new PlatformDomainNameResolver(idnConverter_, eventLoop_); + + tlsFactories_ = new PlatformTLSFactories(); + tlsContextFactory_ = tlsFactories_->getTLSContextFactory(); + + tlsContextFactory_->setCheckCertificateRevocation(false); + + tlsConnectionFactory_ = new TLSConnectionFactory(tlsContextFactory_, connectionFactory_, TLSOptions()); + + connectFinished_ = false; + connectFinishedWithError_ = false; + } + + void tearDown() { + delete tlsConnectionFactory_; + delete tlsFactories_; + + delete domainNameResolver_; + delete idnConverter_; + delete connectionFactory_; + delete boostIOServiceThread_; + while (eventLoop_->hasEvents()) { + eventLoop_->processEvents(); + } + delete eventLoop_; + } + + HostAddress resolveName(const std::string& name) { + std::shared_ptr<DomainNameAddressQuery> query = domainNameResolver_->createAddressQuery(name); + query->onResult.connect(boost::bind(&CertificateErrorTest::handleAddressQueryResult, this, _1, _2)); + lastResoverResult_ = HostAddress(); + resolvingDone_ = false; + + query->run(); + while(!resolvingDone_) { + eventLoop_->processEvents(); + } + + return lastResoverResult_; + } + + void connectToServer(std::shared_ptr<TLSConnection> connection, const std::string& hostname, int port) { + connection->onConnectFinished.connect(boost::bind(&CertificateErrorTest::handleConnectFinished, this, _1)); + + HostAddress address = resolveName(hostname); + + connection->connect(HostAddressPort(address, port)); + + while (!connectFinished_) { + eventLoop_->processEvents(); + } + } + + void testTLS_O_MaticTrusted() { + std::shared_ptr<TLSConnection> connection = std::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); + TLSContext* context = connection->getTLSContext(); + + connectToServer(connection, "test1.tls-o-matic.com", 443); + + CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); + CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::ref(), context->getPeerCertificateVerificationError()); + } + + void testTLS_O_MaticCertificateFromTheFuture() { + std::shared_ptr<TLSConnection> connection = std::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); + TLSContext* context = connection->getTLSContext(); + + connectToServer(connection, "test5.tls-o-matic.com", 405); + + CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); + CPPUNIT_ASSERT(context->getPeerCertificateVerificationError()); +#if defined(HAVE_SCHANNEL) + // Windows SChannel API does not differentiate between expired and not yet valid. + CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::Expired, context->getPeerCertificateVerificationError()->getType()); +#else + CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::NotYetValid, context->getPeerCertificateVerificationError()->getType()); +#endif + } + + void testTLS_O_MaticCertificateFromThePast() { + std::shared_ptr<TLSConnection> connection = std::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); + TLSContext* context = connection->getTLSContext(); + + connectToServer(connection, "test6.tls-o-matic.com", 406); + + CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); + CPPUNIT_ASSERT(context->getPeerCertificateVerificationError()); + CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::Expired, context->getPeerCertificateVerificationError()->getType()); + } + + void testTLS_O_MaticCertificateFromUnknownCA() { + std::shared_ptr<TLSConnection> connection = std::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); + TLSContext* context = connection->getTLSContext(); + + connectToServer(connection, "test7.tls-o-matic.com", 407); + + CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); + CPPUNIT_ASSERT(context->getPeerCertificateVerificationError()); + CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::Untrusted, context->getPeerCertificateVerificationError()->getType()); + } + + // test14.tls-o-matic.com:414 + void testTLS_O_MaticCertificateWrongPurpose() { + std::shared_ptr<TLSConnection> connection = std::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); + TLSContext* context = connection->getTLSContext(); + + connectToServer(connection, "test14.tls-o-matic.com", 414); + + CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); + CPPUNIT_ASSERT(context->getPeerCertificateVerificationError()); + CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::InvalidPurpose, context->getPeerCertificateVerificationError()->getType()); + } + + void testRevokedCertificateRevocationDisabled() { + tlsContextFactory_->setCheckCertificateRevocation(false); + std::shared_ptr<TLSConnection> connection = std::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); + TLSContext* context = connection->getTLSContext(); + + connectToServer(connection, "revoked.grc.com", 443); + + CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); + CPPUNIT_ASSERT(!context->getPeerCertificateVerificationError()); + } + + void testRevokedCertificateRevocationEnabled() { + tlsContextFactory_->setCheckCertificateRevocation(true); + std::shared_ptr<TLSConnection> connection = std::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); + TLSContext* context = connection->getTLSContext(); + + connectToServer(connection, "revoked.grc.com", 443); + + CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); + CPPUNIT_ASSERT(context->getPeerCertificateVerificationError()); + CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::Revoked, context->getPeerCertificateVerificationError()->getType()); + } + + private: + void handleAddressQueryResult(const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> /* error */) { + if (address.size() > 0) { + lastResoverResult_ = address[0]; + } + resolvingDone_ = true; + } + + void handleConnectFinished(bool error) { + connectFinished_ = true; + connectFinishedWithError_ = error; + } + + private: + BoostIOServiceThread* boostIOServiceThread_; + std::shared_ptr<boost::asio::io_service> boostIOService_; + DummyEventLoop* eventLoop_; + ConnectionFactory* connectionFactory_; + PlatformTLSFactories* tlsFactories_; + TLSContextFactory* tlsContextFactory_; + TLSConnectionFactory* tlsConnectionFactory_; + + IDNConverter* idnConverter_; + DomainNameResolver* domainNameResolver_; + HostAddress lastResoverResult_; + bool resolvingDone_; + + bool connectFinished_; + bool connectFinishedWithError_; +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(CertificateErrorTest); diff --git a/Swiften/QA/TLSTest/CertificateTest.cpp b/Swiften/QA/TLSTest/CertificateTest.cpp index 2fa4c04..463ef9e 100644 --- a/Swiften/QA/TLSTest/CertificateTest.cpp +++ b/Swiften/QA/TLSTest/CertificateTest.cpp @@ -1,99 +1,166 @@ /* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ -#include <Swiften/Base/ByteArray.h> +#include <memory> + +#include <boost/bind.hpp> #include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> -#include <boost/bind.hpp> +#include <Swiften/Base/ByteArray.h> #include <Swiften/TLS/CertificateFactory.h> -#include "SwifTools/Application/PlatformApplicationPathProvider.h" +#include <Swiften/TLS/TLSContext.h> +#include <Swiften/TLS/PlatformTLSFactories.h> +#include <Swiften/TLS/TLSContextFactory.h> + +#include <SwifTools/Application/PlatformApplicationPathProvider.h> using namespace Swift; template<typename CERTIFICATE_FACTORY> class CertificateTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(CertificateTest); - CPPUNIT_TEST(testConstructFromDER); - CPPUNIT_TEST(testToDER); - //CPPUNIT_TEST(testGetSubjectName); - CPPUNIT_TEST(testGetCommonNames); - CPPUNIT_TEST(testGetSRVNames); - CPPUNIT_TEST(testGetDNSNames); - CPPUNIT_TEST(testGetXMPPAddresses); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - pathProvider = new PlatformApplicationPathProvider("FileReadBytestreamTest"); - readByteArrayFromFile(certificateData, (pathProvider->getExecutableDir() / "jabber_org.crt")); - certificateFactory = new CERTIFICATE_FACTORY(); - } - - void tearDown() { - delete certificateFactory; - delete pathProvider; - } - - void testConstructFromDER() { - Certificate::ref testling = certificateFactory->createCertificateFromDER(certificateData); - - CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getCommonNames()[0]); - } - - void testToDER() { - Certificate::ref testling = certificateFactory->createCertificateFromDER(certificateData); - - CPPUNIT_ASSERT_EQUAL(certificateData, testling->toDER()); - } + CPPUNIT_TEST_SUITE(CertificateTest); + CPPUNIT_TEST(testConstructFromDER); + CPPUNIT_TEST(testToDER); + //CPPUNIT_TEST(testGetSubjectName); + CPPUNIT_TEST(testGetCommonNames); + CPPUNIT_TEST(testGetSRVNames); + CPPUNIT_TEST(testGetDNSNames); + CPPUNIT_TEST(testGetXMPPAddresses); + CPPUNIT_TEST(testCreateCertificateChain); + CPPUNIT_TEST(testCreateTlsContext); + CPPUNIT_TEST(testCreateTlsContextDisableSystemTAs); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + pathProvider = std::make_unique<PlatformApplicationPathProvider>("FileReadBytestreamTest"); + readByteArrayFromFile(certificateData, (pathProvider->getExecutableDir() / "jabber_org.crt")); + readByteArrayFromFile(chainData, (pathProvider->getExecutableDir() / "certificateChain.pem")); + readByteArrayFromFile(keyData, (pathProvider->getExecutableDir() / "privateKey.pem")); + certificateFactory = std::unique_ptr<CertificateFactory>(new CERTIFICATE_FACTORY()); + + PlatformTLSFactories* tlsFactories_ = new PlatformTLSFactories(); + tlsContextFactory_ = tlsFactories_->getTLSContextFactory(); + } + + void testConstructFromDER() { + Certificate::ref testling = Certificate::ref(certificateFactory->createCertificateFromDER(certificateData)); + + CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getCommonNames()[0]); + } + + void testToDER() { + Certificate::ref testling = Certificate::ref(certificateFactory->createCertificateFromDER(certificateData)); + + CPPUNIT_ASSERT_EQUAL(certificateData, testling->toDER()); + } /* - void testGetSubjectName() { - Certificate::ref testling = certificateFactory->createCertificateFromDER(certificateData); - - CPPUNIT_ASSERT_EQUAL(std::string("/description=114072-VMk8pdi1aj5kTXxO/C=US/ST=Colorado/L=Denver/O=Peter Saint-Andre/OU=StartCom Trusted Certificate Member/CN=*.jabber.org/emailAddress=hostmaster@jabber.org"), testling->getSubjectName()); - } - */ - - void testGetCommonNames() { - Certificate::ref testling = certificateFactory->createCertificateFromDER(certificateData); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(testling->getCommonNames().size())); - CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getCommonNames()[0]); - } - - void testGetSRVNames() { - Certificate::ref testling = certificateFactory->createCertificateFromDER(certificateData); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(testling->getSRVNames().size())); - CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getSRVNames()[0]); - } - - void testGetDNSNames() { - Certificate::ref testling = certificateFactory->createCertificateFromDER(certificateData); - - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(testling->getDNSNames().size())); - CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getDNSNames()[0]); - CPPUNIT_ASSERT_EQUAL(std::string("jabber.org"), testling->getDNSNames()[1]); - } - - void testGetXMPPAddresses() { - Certificate::ref testling = certificateFactory->createCertificateFromDER(certificateData); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(testling->getXMPPAddresses().size())); - CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getXMPPAddresses()[0]); - } - - private: - PlatformApplicationPathProvider* pathProvider; - ByteArray certificateData; - CertificateFactory* certificateFactory; + void testGetSubjectName() { + Certificate::ref testling = Certificate::ref(certificateFactory->createCertificateFromDER(certificateData); + + CPPUNIT_ASSERT_EQUAL(std::string("/description=114072-VMk8pdi1aj5kTXxO/C=US/ST=Colorado/L=Denver/O=Peter Saint-Andre/OU=StartCom Trusted Certificate Member/CN=*.jabber.org/emailAddress=hostmaster@jabber.org"), testling->getSubjectName()); + } + */ + + void testGetCommonNames() { + Certificate::ref testling = Certificate::ref(certificateFactory->createCertificateFromDER(certificateData)); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(testling->getCommonNames().size())); + CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getCommonNames()[0]); + } + + void testGetSRVNames() { + Certificate::ref testling = Certificate::ref(certificateFactory->createCertificateFromDER(certificateData)); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(testling->getSRVNames().size())); + CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getSRVNames()[0]); + } + + void testGetDNSNames() { + Certificate::ref testling = Certificate::ref(certificateFactory->createCertificateFromDER(certificateData)); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(testling->getDNSNames().size())); + CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getDNSNames()[0]); + CPPUNIT_ASSERT_EQUAL(std::string("jabber.org"), testling->getDNSNames()[1]); + } + + void testGetXMPPAddresses() { + Certificate::ref testling = Certificate::ref(certificateFactory->createCertificateFromDER(certificateData)); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(testling->getXMPPAddresses().size())); + CPPUNIT_ASSERT_EQUAL(std::string("*.jabber.org"), testling->getXMPPAddresses()[0]); + } + + void testCreateCertificateChain() { + // The input chain contains a 2-certificate chain: + // the first certificate has: + // a subject of "O=messaging,CN=Mixer Messaging Configuration,CN=badger.isode.net" + // an issuer of "O=messaging, CN=New Messaging CA" + // the second certificate has: + // a subject of "O=messaging, CN=New Messaging CA" + // an issuer of "O=messaging, CN=New Messaging CA" + // i.e. it is a self-signed certificate + std::vector<std::shared_ptr<Certificate>> chain = certificateFactory->createCertificateChain(chainData); + CPPUNIT_ASSERT_EQUAL(2,static_cast<int>(chain.size())); + CPPUNIT_ASSERT_EQUAL(std::string("Mixer Messaging Configuration"), chain[0]->getCommonNames()[0]); + CPPUNIT_ASSERT_EQUAL(std::string("badger.isode.net"), chain[0]->getCommonNames()[1]); + CPPUNIT_ASSERT_EQUAL(std::string("New Messaging CA"), chain[1]->getCommonNames()[0]); + } + + void testCreateTlsContext() { + // Create 2-certificate chain as in previous test + std::vector<std::shared_ptr<Certificate>> chain = certificateFactory->createCertificateChain(chainData); + CPPUNIT_ASSERT_EQUAL(2,static_cast<int>(chain.size())); + + // Load private key from string + PrivateKey::ref key = certificateFactory->createPrivateKey(Swift::createSafeByteArray(keyData)); + CPPUNIT_ASSERT(key); + + const TLSOptions options; + auto context = tlsContextFactory_->createTLSContext(options, TLSContext::Mode::Server); + CPPUNIT_ASSERT(context); + + context->setCertificateChain(chain); + context->setPrivateKey(key); + } + + /** + * This test does not actually verify that use of system TAs has been disabled, it just provides + * a convenient mechanism for testing via a debugger. + **/ + void testCreateTlsContextDisableSystemTAs() { + // Create 2-certificate chain as in previous test + std::vector<std::shared_ptr<Certificate>> chain = certificateFactory->createCertificateChain(chainData); + CPPUNIT_ASSERT_EQUAL(2,static_cast<int>(chain.size())); + + // Load private key from string + PrivateKey::ref key = certificateFactory->createPrivateKey(Swift::createSafeByteArray(keyData)); + CPPUNIT_ASSERT(key); + + // Turn off use of system TAs + TLSOptions options; + options.ignoreSystemTrustAnchors = true; + auto context = tlsContextFactory_->createTLSContext(options, TLSContext::Mode::Server); + CPPUNIT_ASSERT(context); + + context->setCertificateChain(chain); + context->setPrivateKey(key); + } + private: + std::unique_ptr<PlatformApplicationPathProvider> pathProvider; + ByteArray certificateData; + ByteArray chainData; + ByteArray keyData; + std::unique_ptr<CertificateFactory> certificateFactory; + TLSContextFactory* tlsContextFactory_; }; #ifdef HAVE_OPENSSL diff --git a/Swiften/QA/TLSTest/SConscript b/Swiften/QA/TLSTest/SConscript index 18f6998..81e2471 100644 --- a/Swiften/QA/TLSTest/SConscript +++ b/Swiften/QA/TLSTest/SConscript @@ -3,14 +3,25 @@ import os Import("env") if env["TEST"] : - myenv = env.Clone() - myenv.MergeFlags(myenv["CHECKER_FLAGS"]) - myenv.MergeFlags(myenv["SWIFTOOLS_FLAGS"]) - myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) - myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) - myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) - - tester = myenv.Program("TLSTest", [ - "CertificateTest.cpp", - ]) - myenv.Test(tester, "system") + myenv = env.Clone() + myenv.MergeFlags(myenv["CHECKER_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTOOLS_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) + myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) + myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) + myenv.MergeFlags(myenv["GOOGLETEST_FLAGS"]) + + if myenv.get("HAVE_OPENSSL", 0) : + myenv.Append(CPPDEFINES = "HAVE_OPENSSL") + myenv.MergeFlags(myenv["OPENSSL_FLAGS"]) + elif myenv.get("HAVE_SCHANNEL", 0) : + myenv.Append(CPPDEFINES = "HAVE_SCHANNEL") + elif myenv.get("HAVE_SECURETRANSPORT", 0) : + myenv.Append(CPPDEFINES = "HAVE_SECURETRANSPORT") + + tester = myenv.Program("TLSTest", [ + "CertificateTest.cpp", + # Reenable if either http://www.tls-o-matic.com/ is fixed or we have setup a replacement. + #"CertificateErrorTest.cpp" + ]) + myenv.Test(tester, "system") diff --git a/Swiften/QA/TLSTest/certificateChain.pem b/Swiften/QA/TLSTest/certificateChain.pem new file mode 100644 index 0000000..cb3c0fb --- /dev/null +++ b/Swiften/QA/TLSTest/certificateChain.pem @@ -0,0 +1,49 @@ +-----BEGIN CERTIFICATE----- +MIIFFTCCA/2gAwIBAgIKXmMION+1bnZpIzANBgkqhkiG9w0BAQsFADAvMRIwEAYD +VQQKEwltZXNzYWdpbmcxGTAXBgNVBAMTEE5ldyBNZXNzYWdpbmcgQ0EwHhcNMTkw +NzI5MTAxMjMxWhcNMjAwNzI5MTAxMjMxWjBXMRIwEAYDVQQKEwltZXNzYWdpbmcx +JjAkBgNVBAMTHU1peGVyIE1lc3NhZ2luZyBDb25maWd1cmF0aW9uMRkwFwYDVQQD +ExBiYWRnZXIuaXNvZGUubmV0MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKC +AYEAt42TMYe9oO4K6XmvST4kiy4cG+nmVDCtZRfAfF/A+1GQXTZ8OfLbPF5noLIF +f1Jj6fBDA2HiKoLQWfNnIklNEzgPbOREuAuCe660sW1JzJFr5O5qYyf6bHKkYmRr +CGHJ3G5kkXZOW3MhczPNHrTIUSL7lYLMZAcyWStkhgBy7lBuYtgDEXbdRH8OGgly +XC39AAU93y7ynw6W3SorU6h9cwvS0Ho8KVemCXoE38WLeSrIw1ks+Kf1YQopg9O3 +2SkXp6Z9elG5Wk5Rh0L0H2XHnAvmodr9TW6rtrPkJZfLL+NfcnGtI6QKnvL8EhYG +d+XiPOV8jyGAFRC1Be72wlF29Rw20zdoD3kAdeqBLWfL8H9mnQpebEIDj8Lmahub ++W4uuUqCG8NuY43lGJzJni9CFWvhD7ss1yVGz84zqRHu5iXNDncWH2luJT1gXvFW +6mxcfe+AwSiZ8PrhDQZBfTyx7ob4Ozdc1d59XTPyckj2msnCo2ayg+jKaViDd4vz +nNwhAgMBAAGjggGJMIIBhTAbBgNVHREEFDASghBiYWRnZXIuaXNvZGUubmV0MA4G +A1UdDwEB/wQEAwIF4DAMBgNVHRMBAf8EAjAAMHQGA1UdHwRtMGswaaBnoGWGY2xk +YXA6Ly9kaWFib2xvLmlzb2RlLm5ldDoxOTM4OS9jbj1OZXclMjBNZXNzYWdpbmcl +MjBDQSxvPW1lc3NhZ2luZz9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFy +eTCBkQYIKwYBBQUHAQEEgYQwgYEwfwYIKwYBBQUHMAKGc2xkYXA6Ly9kaWFib2xv +Lmlzb2RlLm5ldDoxOTM4OS9jbj1OZXclMjBNZXNzYWdpbmclMjBDQSxvPW1lc3Nh +Z2luZz9jQUNlcnRpZmljYXRlO2JpbmFyeSxjcm9zc0NlcnRpZmljYXRlUGFpcjti +aW5hcnkwHQYDVR0OBBYEFFjf69BczlDoKiSBSvxCr9sy0OJ2MB8GA1UdIwQYMBaA +FJvoU0Lwg8vVCEmEMoKy29zFo/Y7MA0GCSqGSIb3DQEBCwUAA4IBAQCS4zLVH98S +Cl4gsmTkxM+lBsdzQ18ymA6p9ZRXGmJ405C9rN7um9XnbWwOHO6ach7zie2GxWLp +KOYKjX/5Pjt7mPwG8eKepPAxDenzKw5TocjscR9VxBsym0oEkWHPQG+xSqySQGUw +/5QoGy6v06yE8CZ7BKHPh91Jy7IjIDBxWaEtTAPyuH4i4DnsmA0/xSrJ7ez6g399 +YgqDnBInC63bYv5IDD1CmEr/0boBWpsOf50OC6JVhaPLAldwTAxLSOMBJ4q4onXC +ZqDHY3EMRtwYEffNg9ZorXJwLmU3Lq/R3B9lC22XNPDFj/bZ5RpwVFtuN5HfeZzO +aPbNoa0Nf+QB +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDJDCCAgygAwIBAgIKSm7KkUZOigMk9zANBgkqhkiG9w0BAQsFADAvMRIwEAYD +VQQKEwltZXNzYWdpbmcxGTAXBgNVBAMTEE5ldyBNZXNzYWdpbmcgQ0EwHhcNMTYw +MTI2MTU1MTU2WhcNMjYwMTI2MTU1MTU2WjAvMRIwEAYDVQQKEwltZXNzYWdpbmcx +GTAXBgNVBAMTEE5ldyBNZXNzYWdpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDgcuX1s8EvO8GDHx7vSW9oeDnLUBx5E48Vb2qcJVc34ik1j6ZV +d8/+tzmyy/BskFbaOJ0KD5XYOoI8TJtu28lASWZj1vAEZkfrDdBbKeb1BQhShMt2 +ICgzp7l4ubwd6rqCGHpD/f12RVhSlU3y6TniaK62a9RwJOpL/wvnCcJLPjaTw8om +EY62EyUP+FymUbo3Rb3aWLM7avHl1/32pyzUgRzvZR63hlMHnlE5Sgc84j9KMwJH +k+mCyXIGPc+yhL33ljR63Eoiqynyk0HPU6pWai1WKuSv6zMDPwnNaJA3VpLNUHsd +eVe1GyOmPFePnhRPZYfC+Dk8lxDUmZfNFKZlAgMBAAGjQjBAMA4GA1UdDwEB/wQE +AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSb6FNC8IPL1QhJhDKCstvc +xaP2OzANBgkqhkiG9w0BAQsFAAOCAQEApgA5oupwTS2Ylt9mhS/TDX9wzR0DqnC5 +t9skgU9B/1MnzgqEMKGmuhRBiqDyr0jsPegBFI/CpTdIpakpSUrIvBTZADzkrkI+ +3k2jnpEv0vodaFIHQonDysq5h4bXsCSdSprdhiUa1GKFtnJ92Ro/2Uaw5UcqFPCg +7kj7RmRVlAIynUAT81cefQww0HBFPN9SdBEpp6YP4P1u1x8GV0Bfq93r4G5jkiHN +dA6xejk7RZK4mTH+K2aFpWoHCqMr7RAzV5UiXis4cFAmtv+5K/G7eazNx0Y+ODo4 +fweh+xW+dOXuP1lzW4DzwhEf/8tgFgI0jIvscPgdgHY7t9SQRJPYQQ== +-----END CERTIFICATE----- diff --git a/Swiften/QA/TLSTest/privateKey.pem b/Swiften/QA/TLSTest/privateKey.pem new file mode 100644 index 0000000..5769000 --- /dev/null +++ b/Swiften/QA/TLSTest/privateKey.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +MIIG/wIBADANBgkqhkiG9w0BAQEFAASCBukwggblAgEAAoIBgQDu1QdEBrcWj+D/ +rkmh++QSu2f0qlJ6Re8dEBtbqpxLiyYZ5IeaLts9szXabfSTchdJr/d0IyHfHQFS +MGXDphKRaNnV5r//XuojUtorPyGe0DnZR2mp8S9adD7WxNjQLSQabr8PPPW8jrTx +eJyIvYToLs9lx1IIDcr/3ZTuhBe2FK3Q173M5GF36Jb4yKWLPIfJ6auZjO5G9LZF +3o2vVWxfc7ESnXvf3sAcWQPR08/ud0vLa3W3A8dC0XGk4BbE32cxvSuzWPHZd257 +HiHIW5pKLZXSMTu7fVNzBzDlo8BYQ5kad1ic+hhyIHBwTUO0Hz3EYP+9FG3TNG84 +65K9EeN3/Qw2P9468GHWAXqlzKFiIGikxYHGwvGd0CdegHtZ/TwIgVvpIDp6XB6U +ez/TYPEiMCqX8TCIQi8FU3obEouMoPMHKM8vzQdSItZtPn6gD16M4xKdMm6fbvCD +1okdcrWQnZo72pp8cfpS87KhP5z1ec9B/Wqysh4nrO35v8LXH60CAwEAAQKCAYEA +jPDUJ9XaqAriWaBtvZTbpB5KG72DjLrGgB0oN/E36PDF3FPbniZ2pTOj3TI0OesD +SS351uSAsZz5UZpUA6B2pq78llllBnvpqkzTiN/ppEH3UXzuIya8riGZj758wGVT +P/II+CIeVlbU+wcVQTCuRSKSq9pzU2NoX5RQtmznXUFYzbzzOf2wc0WkCk7GOqPO +8l3eMXBUkTUKd7L9Y/ICUVYBsh2To6pdLp1tPp9DvtNRvEq/HfCx34GgEg9YAHhg +1rcPhh71M+TLYHznl5r/Jm1kIVrP3zyr1Bm5DDgZLE3GTN/oFumgXQyFCPyslup1 +gdZzS6W+fbeKxoPzjPOhzHVUxVZ/yqJH1xa1gs4ECQ4QXxdnr7yY1H5k5S8dabO5 +bEvXP+tH95HcAtAbvoRt+NC+xIJ39d6X7X2c4TPLoMIxDxmbEOCi9sg+4Ws+7E2s +a/01fTZFT+lzuGBdp9Zz/tltDrwfYD0V+Q7qO0o/nJPINI+alAWlqQia00ZyZr4V +AoHBAPxwCls99/LUzY7IJc0TV3ukk3sFi3rt58u8BE4+RaCtmgPMDj1l+EnaY9RW +IOj91ECZ8+a23elNPZOkXKuYuJmJIpjOogOMM8r+Q4WF87xoRcdcjPh+PBat66HZ ++8mbm0VQ98cjxs0/kTRRayzz7UG9Onf1PhFfnw55sbMGItVssRDi9lRZJdSRU+CC +qyAt8TUEH0lo+8AKbRn7xW4VHiD0hmLKDi4F713QLCPgmNlPQ/C60FTIRYS18gzK +ARhuzwKBwQDyM9YiiFFQ3irGKtbj9W3bDHNmMl9YOHMYVXJAvh83Zcp80qRsShtw +n3mV3vcVI+KNeZtKFUrJIYNTspNBP/w8U4lGGW+7tAt0dd0WY9m3ygnZg0GOHoaC +uUusGicZR7FgbYlJzCiRhFhWcFyh0VOrm/k7OjznAvwfWbRKrlLvQdrWrLj7dyN3 +8n9lArq9ZxXJLpBXDUJ1R+F+hPIIIRKeYF2ULUFNE0U9Pj7SVTT7L7jPMWKnrVJh +U4/hVAEHyMMCgcB4hCTtmpAdZmscl4E0ft9tMA0Y1nTYo2veYEzN7fzf0QGOfoTt +2xjGaXTvko7zrPsAPH+szfDzyOR08Cst4SOAaXAS89N1TiIL74fc3y6V7FIj85N5 +rwqQ6UdtZdxHS/q9BQLGF9Z5drej+proQywqDmUzj+mp8bTF/GNRzMQkkFeYcEKZ +0lW1PgyFStzX6BcX8HffXDeUX2Xm2cRP4dUYdqUR1NUgM8UrTI9GMZvHY4hUDVwY +neRSj2qXoHkVaRECgcEArilkM9S+VF5Nd85aU/WqFzeuy7AxK2j8KmVXEQMlw1oo +7vUxUsU/Ug77CTAZkFQLlxv49J629kZo/wiMJwFxyZdwQL4NwHXJPud6IZ2Pcz+P +MZ/WxfFhXCMOLSVpNB5/iA18CVsLWQhH1XBay+mQNvijkVlhbeSRk6GXqZQNAwrh +6Divk/Opx5jSzrnVulikK9SV6mMYhOk5VxcWS44sq0I0SFb6fAf9Y/qchfbLcExy +olqqzFQvxtilv6v+SbCtAoHBAOXPUQ7VVuQZo4HA+CaQRYgQjGMxo4jeGiqrUAaX +b+MpUjU7VxiSrfH3wFxCuMfW7dfQJKp7BAG8PCNzP1eW3+LhPkRSPAT0nwk/bQ5E +N/n6NBqwsJFoTqueS0qDVdPichwKGvnIrraHSVeMeHZNv+TQdMjmTJ5AfBNCal9b +7EPTFQO0Tj4GAB77fVRzewyVB+qXccoD2Gts9aWbY9FVGyhkvRenL7CcbgrzLZvt +php/1crfbWtZ/3Nwz6L8LEdZHA== +-----END PRIVATE KEY----- |