summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/QA')
-rw-r--r--Swiften/QA/ClientTest/ClientTest.cpp146
-rw-r--r--Swiften/QA/ClientTest/SConscript20
-rw-r--r--Swiften/QA/ConcurrentFileTransferTest/ConcurrentFileTransferTest.cpp80
-rw-r--r--Swiften/QA/ConcurrentFileTransferTest/SConscript17
-rw-r--r--Swiften/QA/DNSSDTest/DNSSDTest.cpp234
-rw-r--r--Swiften/QA/DNSSDTest/SConscript32
-rw-r--r--Swiften/QA/FileTransferTest/.gitignore1
-rw-r--r--Swiften/QA/FileTransferTest/FileTransferTest.cpp397
-rw-r--r--Swiften/QA/FileTransferTest/SConscript20
-rw-r--r--Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp266
-rwxr-xr-x[-rw-r--r--]Swiften/QA/NetworkTest/BoostConnectionTest.cpp294
-rw-r--r--Swiften/QA/NetworkTest/DomainNameResolverTest.cpp438
-rw-r--r--Swiften/QA/NetworkTest/SConscript31
-rw-r--r--Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp45
-rw-r--r--Swiften/QA/ProxyProviderTest/SConscript4
-rw-r--r--Swiften/QA/ReconnectTest/ReconnectTest.cpp95
-rw-r--r--Swiften/QA/ReconnectTest/SConscript36
-rw-r--r--Swiften/QA/SConscript19
-rw-r--r--Swiften/QA/ScriptedTests/MultipleClients.lua6
-rw-r--r--Swiften/QA/ScriptedTests/PubSub.lua38
-rw-r--r--Swiften/QA/ScriptedTests/SConscript8
-rw-r--r--Swiften/QA/ScriptedTests/SendMessage.lua6
-rw-r--r--Swiften/QA/StorageTest/FileReadBytestreamTest.cpp87
-rw-r--r--Swiften/QA/StorageTest/FileWriteBytestreamTest.cpp58
-rw-r--r--Swiften/QA/StorageTest/SConscript33
-rw-r--r--Swiften/QA/StorageTest/VCardFileStorageTest.cpp202
-rw-r--r--Swiften/QA/TLSTest/CertificateErrorTest.cpp224
-rw-r--r--Swiften/QA/TLSTest/CertificateTest.cpp225
-rw-r--r--Swiften/QA/TLSTest/SConscript33
-rw-r--r--Swiften/QA/TLSTest/certificateChain.pem49
-rw-r--r--Swiften/QA/TLSTest/privateKey.pem40
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-----