From 632c6c8dd641e74c62e9561770af0a66711bc3da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 31 Oct 2009 14:38:05 +0100
Subject: Moving tests around.


diff --git a/.gitignore b/.gitignore
index 712408e..fc04978 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,5 @@ config.log
 .sconf_temp
 .sconsign.dblite
 Swiften/Examples/TuneBot/TuneBot
-Swiften/QA/ClientTest/ClientTest
 Swift/QtUI/swift
 Swift/QtUI/DefaultTheme.qrc
diff --git a/QA/Checker/SConscript b/QA/Checker/SConscript
new file mode 100644
index 0000000..7516bb9
--- /dev/null
+++ b/QA/Checker/SConscript
@@ -0,0 +1,10 @@
+Import("env")
+
+checker_env = env.Clone()
+checker_env.MergeFlags(env["CPPUNIT_FLAGS"])
+checker_env.Library("Checker", "checker.cpp")
+env["CHECKER_FLAGS"] = { 
+    "LIBS": ["Checker"],
+    "LIBPATH": [Dir(".")],
+		"LINKFLAGS": ["/SUBSYSTEM:CONSOLE"] if env["PLATFORM"] == "win32" else []
+  }
diff --git a/QA/Checker/checker.cpp b/QA/Checker/checker.cpp
new file mode 100644
index 0000000..b59cea6
--- /dev/null
+++ b/QA/Checker/checker.cpp
@@ -0,0 +1,73 @@
+#include <string>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/XmlOutputter.h>
+#include <cppunit/TextTestResult.h>
+#include <cppunit/BriefTestProgressListener.h>
+#include <cppunit/TextTestProgressListener.h>
+#include <cppunit/TextOutputter.h>
+
+int main(int argc, char* argv[]) {
+	bool verbose = false;
+	bool outputXML = false;
+
+	// Parse parameters
+	std::vector<std::string> testsToRun;
+	for (int i = 1; i < argc; ++i) {
+		std::string param(argv[i]);
+		if (param == "--verbose") {
+			verbose = true;
+		}
+		else if (param == "--xml") {
+			outputXML = true;
+		}
+		else {
+			testsToRun.push_back(param);
+		}
+	}
+	if (testsToRun.empty()) {
+		testsToRun.push_back("");
+	}
+
+	// Set up the listeners
+	CppUnit::TestResult controller;
+
+	CppUnit::TestResultCollector result;
+	controller.addListener(&result);
+
+	CppUnit::TextTestProgressListener progressListener;
+	CppUnit::BriefTestProgressListener verboseListener;
+	if (!outputXML) {
+		if (verbose) {
+			controller.addListener(&verboseListener);
+		}
+		else {
+			controller.addListener(&progressListener);
+		}
+	}
+
+	// Run the tests
+	CppUnit::TestRunner runner;
+	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+	for (std::vector<std::string>::const_iterator i = testsToRun.begin(); i != testsToRun.end(); ++i) {
+		try {
+			runner.run(controller, *i);
+		}
+		catch (const std::exception& e) {
+			std::cerr << "Error: " << e.what() << std::endl;
+			return -1;
+		}
+	}
+
+	// Output the results
+	if (outputXML) {
+		CppUnit::XmlOutputter outputter(&result, std::cerr);
+		outputter.write();
+	}
+	else {
+		CppUnit::TextOutputter outputter(&result, std::cerr);
+		outputter.write();
+	}
+
+	return result.wasSuccessful() ? 0 : 1;
+}
diff --git a/QA/SConscript b/QA/SConscript
deleted file mode 100644
index feafb0c..0000000
--- a/QA/SConscript
+++ /dev/null
@@ -1,4 +0,0 @@
-SConscript(dirs = [
-    "UnitTest",
-    "Swiften"
-  ])
diff --git a/QA/Swiften/ClientTest/.gitignore b/QA/Swiften/ClientTest/.gitignore
deleted file mode 100644
index 9fb3e67..0000000
--- a/QA/Swiften/ClientTest/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-ClientTest
diff --git a/QA/Swiften/ClientTest/ClientTest.cpp b/QA/Swiften/ClientTest/ClientTest.cpp
deleted file mode 100644
index 412eb53..0000000
--- a/QA/Swiften/ClientTest/ClientTest.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <boost/bind.hpp>
-#include <boost/thread.hpp>
-
-#include "Swiften/Client/Client.h"
-#include "Swiften/Network/Timer.h"
-#include "Swiften/EventLoop/MainEventLoop.h"
-#include "Swiften/EventLoop/SimpleEventLoop.h"
-#include "Swiften/Queries/Requests/GetRosterRequest.h"
-#include "Swiften/Client/ClientXMLTracer.h"
-#include "Swiften/Network/BoostIOServiceThread.h"
-#include "Swiften/Network/MainBoostIOServiceThread.h"
-
-using namespace Swift;
-
-SimpleEventLoop eventLoop;
-
-Client* client = 0;
-bool rosterReceived = false;
-
-void handleRosterReceived(boost::shared_ptr<Payload>) {
-	rosterReceived = true;
-	eventLoop.stop();
-}
-
-void handleConnected() {
-	boost::shared_ptr<GetRosterRequest> rosterRequest(new GetRosterRequest(client));
-	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;
-	}
-
-	client = new Swift::Client(JID(jid), String(pass));
-	ClientXMLTracer* tracer = new ClientXMLTracer(client);
-	client->onConnected.connect(&handleConnected);
-	client->connect();
-
-	{
-		boost::shared_ptr<Timer> timer(new Timer(10000, &MainBoostIOServiceThread::getInstance().getIOService()));
-		timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop));
-		timer->start();
-
-		eventLoop.run();
-	}
-	delete tracer;
-	delete client;
-	return !rosterReceived;
-}
diff --git a/QA/Swiften/ClientTest/SConscript b/QA/Swiften/ClientTest/SConscript
deleted file mode 100644
index a9d9a19..0000000
--- a/QA/Swiften/ClientTest/SConscript
+++ /dev/null
@@ -1,22 +0,0 @@
-import os
-
-Import("env")
-
-if env["TEST"] :
-	myenv = env.Clone()
-	myenv.MergeFlags(env["SWIFTEN_FLAGS"])
-	myenv.MergeFlags(env["CPPUNIT_FLAGS"])
-	myenv.MergeFlags(env["LIBIDN_FLAGS"])
-	myenv.MergeFlags(env["BOOST_FLAGS"])
-	myenv.MergeFlags(env["SQLITE_FLAGS"])
-	myenv.MergeFlags(env["ZLIB_FLAGS"])
-	myenv.MergeFlags(env["OPENSSL_FLAGS"])
-	myenv.MergeFlags(env.get("LIBXML_FLAGS", ""))
-	myenv.MergeFlags(env.get("EXPAT_FLAGS", ""))
-
-	for i in ["SWIFT_CLIENTTEST_JID", "SWIFT_CLIENTTEST_PASS"]:
-		if os.environ.get(i, "") :
-			myenv["ENV"][i] = os.environ[i]
-
-	tester = myenv.Program("ClientTest", ["ClientTest.cpp"])
-	myenv.Test(tester, "system")
diff --git a/QA/Swiften/NetworkTest/.gitignore b/QA/Swiften/NetworkTest/.gitignore
deleted file mode 100644
index 5a3caca..0000000
--- a/QA/Swiften/NetworkTest/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-NetworkTest
diff --git a/QA/Swiften/NetworkTest/BoostConnectionServerTest.cpp b/QA/Swiften/NetworkTest/BoostConnectionServerTest.cpp
deleted file mode 100644
index a5c51aa..0000000
--- a/QA/Swiften/NetworkTest/BoostConnectionServerTest.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <boost/shared_ptr.hpp>
-
-#include "Swiften/Base/String.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() {
-			delete eventLoop_;
-			delete boostIOServiceThread_;
-		}
-
-		void testConstructor_TwoServersOnSamePort() {
-			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
-			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
-		}
-
-		void testStart_Conflict() {
-			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
-			testling->start();
-
-			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
-			testling2->onStopped.connect(
-					boost::bind(&BoostConnectionServerTest::handleStopped, this, _1));
-
-			testling->stop();
-		}
-
-		void testStop() {
-			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
-			testling->start();
-
-			testling->stop();
-
-			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
-			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_REGISTRATION(BoostConnectionServerTest);
diff --git a/QA/Swiften/NetworkTest/BoostConnectionTest.cpp b/QA/Swiften/NetworkTest/BoostConnectionTest.cpp
deleted file mode 100644
index 9929eaa..0000000
--- a/QA/Swiften/NetworkTest/BoostConnectionTest.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <boost/shared_ptr.hpp>
-
-#include "Swiften/Base/String.h"
-#include "Swiften/Base/sleep.h"
-#include "Swiften/Network/BoostConnection.h"
-#include "Swiften/Network/HostAddress.h"
-#include "Swiften/Network/HostAddressPort.h"
-#include "Swiften/Network/BoostIOServiceThread.h"
-#include "Swiften/EventLoop/DummyEventLoop.h"
-
-const unsigned char* address = reinterpret_cast<const unsigned char*>("\x41\x63\xde\x89");
-
-using namespace Swift;
-
-class BoostConnectionTest : public CppUnit::TestFixture {
-		CPPUNIT_TEST_SUITE(BoostConnectionTest);
-		CPPUNIT_TEST(testDestructor);
-		CPPUNIT_TEST(testDestructor_PendingEvents);
-		CPPUNIT_TEST_SUITE_END();
-
-	public:
-		BoostConnectionTest() {}
-
-		void setUp() {
-			boostIOServiceThread_ = new BoostIOServiceThread();
-			eventLoop_ = new DummyEventLoop();
-		}
-
-		void tearDown() {
-			delete eventLoop_;
-			delete boostIOServiceThread_;
-		}
-
-		void testDestructor() {
-			{
-				boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService()));
-				testling->connect(HostAddressPort(HostAddress(address, 4), 5222));
-			}
-		}
-
-		void testDestructor_PendingEvents() {
-			{
-				boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService()));
-				testling->connect(HostAddressPort(HostAddress(address, 4), 5222));
-				while (!eventLoop_->hasEvents()) {
-					Swift::sleep(10);
-				}
-			}
-			eventLoop_->processEvents();
-		}
-
-	private:
-		BoostIOServiceThread* boostIOServiceThread_;
-		DummyEventLoop* eventLoop_;
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION(BoostConnectionTest);
diff --git a/QA/Swiften/NetworkTest/DomainNameResolverTest.cpp b/QA/Swiften/NetworkTest/DomainNameResolverTest.cpp
deleted file mode 100644
index 8968efd..0000000
--- a/QA/Swiften/NetworkTest/DomainNameResolverTest.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-
-#include "Swiften/Base/String.h"
-#include "Swiften/Network/DomainNameResolver.h"
-#include "Swiften/Network/DomainNameResolveException.h"
-
-using namespace Swift;
-
-class DomainNameResolverTest : public CppUnit::TestFixture {
-		CPPUNIT_TEST_SUITE(DomainNameResolverTest);
-		CPPUNIT_TEST(testResolve_NoSRV);
-		CPPUNIT_TEST(testResolve_SRV);
-		CPPUNIT_TEST(testResolve_Invalid);
-		//CPPUNIT_TEST(testResolve_IPv6);
-		CPPUNIT_TEST(testResolve_International);
-		CPPUNIT_TEST_SUITE_END();
-
-	public:
-		DomainNameResolverTest() {}
-
-		void setUp() {
-			resolver_ = new DomainNameResolver();
-		}
-
-		void tearDown() {
-			delete resolver_;
-		}
-
-		void testResolve_NoSRV() {
-			HostAddressPort result = resolver_->resolve("xmpp.test.swift.im");
-
-			CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), result.getAddress().toString());
-			CPPUNIT_ASSERT_EQUAL(5222, result.getPort());
-		}
-
-		void testResolve_SRV() {
-			HostAddressPort result = resolver_->resolve("xmpp-srv.test.swift.im");
-
-			CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.1"), result.getAddress().toString());
-			CPPUNIT_ASSERT_EQUAL(5000, result.getPort());
-		}
-
-		void testResolve_Invalid() {
-			CPPUNIT_ASSERT_THROW(resolver_->resolve("invalid.test.swift.im"), DomainNameResolveException);
-		}
-
-		void testResolve_IPv6() {
-			HostAddressPort result = resolver_->resolve("xmpp-ipv6.test.swift.im");
-			CPPUNIT_ASSERT_EQUAL(std::string("0000:0000:0000:0000:0000:ffff:0a00:0104"), result.getAddress().toString());
-			CPPUNIT_ASSERT_EQUAL(5222, result.getPort());
-		}
-
-		void testResolve_International() {
-			HostAddressPort result = resolver_->resolve("tron\xc3\xa7on.test.swift.im");
-			CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.3"), result.getAddress().toString());
-			CPPUNIT_ASSERT_EQUAL(5222, result.getPort());
-		}
-
-	private:
-		DomainNameResolver* resolver_;
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION(DomainNameResolverTest);
diff --git a/QA/Swiften/NetworkTest/SConscript b/QA/Swiften/NetworkTest/SConscript
deleted file mode 100644
index cf66a68..0000000
--- a/QA/Swiften/NetworkTest/SConscript
+++ /dev/null
@@ -1,18 +0,0 @@
-import os
-
-Import("env")
-
-if env["TEST"] :
-	myenv = env.Clone()
-	myenv.MergeFlags(env["CHECKER_FLAGS"])
-	myenv.MergeFlags(env["SWIFTEN_FLAGS"])
-	myenv.MergeFlags(env["CPPUNIT_FLAGS"])
-	myenv.MergeFlags(env["BOOST_FLAGS"])
-	myenv.MergeFlags(env["LIBIDN_FLAGS"])
-
-	tester = myenv.Program("NetworkTest", [
-			"BoostConnectionServerTest.cpp",
-			"BoostConnectionTest.cpp",
-			"DomainNameResolverTest.cpp",
-		])
-	myenv.Test(tester, "system")
diff --git a/QA/Swiften/SConscript b/QA/Swiften/SConscript
deleted file mode 100644
index ede7b39..0000000
--- a/QA/Swiften/SConscript
+++ /dev/null
@@ -1,4 +0,0 @@
-SConscript([
-		"NetworkTest/SConscript",
-		"ClientTest/SConscript",
-	])
diff --git a/QA/UnitTest/SConscript b/QA/UnitTest/SConscript
index f93cdc2..f4bb358 100644
--- a/QA/UnitTest/SConscript
+++ b/QA/UnitTest/SConscript
@@ -2,16 +2,6 @@ import os
 
 Import("env")
 
-# The checker
-checker_env = env.Clone()
-checker_env.MergeFlags(env["CPPUNIT_FLAGS"])
-checker_env.Library("Checker", "checker.cpp")
-env["CHECKER_FLAGS"] = { 
-    "LIBS": ["Checker"],
-    "LIBPATH": [Dir(".")],
-		"LINKFLAGS": ["/SUBSYSTEM:CONSOLE"] if env["PLATFORM"] == "win32" else []
-  }
-
 if env["TEST"] :
 	myenv = env.Clone()
 	myenv.MergeFlags(env["CHECKER_FLAGS"])
diff --git a/QA/UnitTest/checker.cpp b/QA/UnitTest/checker.cpp
deleted file mode 100644
index b59cea6..0000000
--- a/QA/UnitTest/checker.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <string>
-#include <cppunit/ui/text/TestRunner.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <cppunit/XmlOutputter.h>
-#include <cppunit/TextTestResult.h>
-#include <cppunit/BriefTestProgressListener.h>
-#include <cppunit/TextTestProgressListener.h>
-#include <cppunit/TextOutputter.h>
-
-int main(int argc, char* argv[]) {
-	bool verbose = false;
-	bool outputXML = false;
-
-	// Parse parameters
-	std::vector<std::string> testsToRun;
-	for (int i = 1; i < argc; ++i) {
-		std::string param(argv[i]);
-		if (param == "--verbose") {
-			verbose = true;
-		}
-		else if (param == "--xml") {
-			outputXML = true;
-		}
-		else {
-			testsToRun.push_back(param);
-		}
-	}
-	if (testsToRun.empty()) {
-		testsToRun.push_back("");
-	}
-
-	// Set up the listeners
-	CppUnit::TestResult controller;
-
-	CppUnit::TestResultCollector result;
-	controller.addListener(&result);
-
-	CppUnit::TextTestProgressListener progressListener;
-	CppUnit::BriefTestProgressListener verboseListener;
-	if (!outputXML) {
-		if (verbose) {
-			controller.addListener(&verboseListener);
-		}
-		else {
-			controller.addListener(&progressListener);
-		}
-	}
-
-	// Run the tests
-	CppUnit::TestRunner runner;
-	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
-	for (std::vector<std::string>::const_iterator i = testsToRun.begin(); i != testsToRun.end(); ++i) {
-		try {
-			runner.run(controller, *i);
-		}
-		catch (const std::exception& e) {
-			std::cerr << "Error: " << e.what() << std::endl;
-			return -1;
-		}
-	}
-
-	// Output the results
-	if (outputXML) {
-		CppUnit::XmlOutputter outputter(&result, std::cerr);
-		outputter.write();
-	}
-	else {
-		CppUnit::TextOutputter outputter(&result, std::cerr);
-		outputter.write();
-	}
-
-	return result.wasSuccessful() ? 0 : 1;
-}
diff --git a/SConstruct b/SConstruct
index 6ee509a..51bf6a5 100644
--- a/SConstruct
+++ b/SConstruct
@@ -270,6 +270,9 @@ SConscript(dirs = [
 		"3rdParty/LibIDN",
 		"3rdParty/SQLite"])
 
+# Checker
+SConscript(dirs = ["QA/Checker"])
+
 # Swiften
 SConscript(dirs = "Swiften")
 
@@ -281,8 +284,8 @@ for dir in os.listdir(".") :
 	if os.path.isfile(sconscript) :
 		SConscript(sconscript)
 
-# QA
-SConscript(dirs = "QA")
+# Unit test runner
+SConscript(dirs = ["QA/UnitTest"])
 
 ################################################################################
 # Print summary
diff --git a/Swiften/QA/ClientTest/.gitignore b/Swiften/QA/ClientTest/.gitignore
new file mode 100644
index 0000000..9fb3e67
--- /dev/null
+++ b/Swiften/QA/ClientTest/.gitignore
@@ -0,0 +1 @@
+ClientTest
diff --git a/Swiften/QA/ClientTest/ClientTest.cpp b/Swiften/QA/ClientTest/ClientTest.cpp
new file mode 100644
index 0000000..412eb53
--- /dev/null
+++ b/Swiften/QA/ClientTest/ClientTest.cpp
@@ -0,0 +1,58 @@
+#include <boost/bind.hpp>
+#include <boost/thread.hpp>
+
+#include "Swiften/Client/Client.h"
+#include "Swiften/Network/Timer.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
+#include "Swiften/EventLoop/SimpleEventLoop.h"
+#include "Swiften/Queries/Requests/GetRosterRequest.h"
+#include "Swiften/Client/ClientXMLTracer.h"
+#include "Swiften/Network/BoostIOServiceThread.h"
+#include "Swiften/Network/MainBoostIOServiceThread.h"
+
+using namespace Swift;
+
+SimpleEventLoop eventLoop;
+
+Client* client = 0;
+bool rosterReceived = false;
+
+void handleRosterReceived(boost::shared_ptr<Payload>) {
+	rosterReceived = true;
+	eventLoop.stop();
+}
+
+void handleConnected() {
+	boost::shared_ptr<GetRosterRequest> rosterRequest(new GetRosterRequest(client));
+	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;
+	}
+
+	client = new Swift::Client(JID(jid), String(pass));
+	ClientXMLTracer* tracer = new ClientXMLTracer(client);
+	client->onConnected.connect(&handleConnected);
+	client->connect();
+
+	{
+		boost::shared_ptr<Timer> timer(new Timer(10000, &MainBoostIOServiceThread::getInstance().getIOService()));
+		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
new file mode 100644
index 0000000..a9d9a19
--- /dev/null
+++ b/Swiften/QA/ClientTest/SConscript
@@ -0,0 +1,22 @@
+import os
+
+Import("env")
+
+if env["TEST"] :
+	myenv = env.Clone()
+	myenv.MergeFlags(env["SWIFTEN_FLAGS"])
+	myenv.MergeFlags(env["CPPUNIT_FLAGS"])
+	myenv.MergeFlags(env["LIBIDN_FLAGS"])
+	myenv.MergeFlags(env["BOOST_FLAGS"])
+	myenv.MergeFlags(env["SQLITE_FLAGS"])
+	myenv.MergeFlags(env["ZLIB_FLAGS"])
+	myenv.MergeFlags(env["OPENSSL_FLAGS"])
+	myenv.MergeFlags(env.get("LIBXML_FLAGS", ""))
+	myenv.MergeFlags(env.get("EXPAT_FLAGS", ""))
+
+	for i in ["SWIFT_CLIENTTEST_JID", "SWIFT_CLIENTTEST_PASS"]:
+		if os.environ.get(i, "") :
+			myenv["ENV"][i] = os.environ[i]
+
+	tester = myenv.Program("ClientTest", ["ClientTest.cpp"])
+	myenv.Test(tester, "system")
diff --git a/Swiften/QA/NetworkTest/.gitignore b/Swiften/QA/NetworkTest/.gitignore
new file mode 100644
index 0000000..5a3caca
--- /dev/null
+++ b/Swiften/QA/NetworkTest/.gitignore
@@ -0,0 +1 @@
+NetworkTest
diff --git a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp
new file mode 100644
index 0000000..a5c51aa
--- /dev/null
+++ b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp
@@ -0,0 +1,72 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Base/String.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() {
+			delete eventLoop_;
+			delete boostIOServiceThread_;
+		}
+
+		void testConstructor_TwoServersOnSamePort() {
+			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+		}
+
+		void testStart_Conflict() {
+			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			testling->start();
+
+			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			testling2->onStopped.connect(
+					boost::bind(&BoostConnectionServerTest::handleStopped, this, _1));
+
+			testling->stop();
+		}
+
+		void testStop() {
+			boost::shared_ptr<BoostConnectionServer> testling(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			testling->start();
+
+			testling->stop();
+
+			boost::shared_ptr<BoostConnectionServer> testling2(new BoostConnectionServer(9999, &boostIOServiceThread_->getIOService()));
+			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_REGISTRATION(BoostConnectionServerTest);
diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
new file mode 100644
index 0000000..9929eaa
--- /dev/null
+++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
@@ -0,0 +1,59 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/Base/sleep.h"
+#include "Swiften/Network/BoostConnection.h"
+#include "Swiften/Network/HostAddress.h"
+#include "Swiften/Network/HostAddressPort.h"
+#include "Swiften/Network/BoostIOServiceThread.h"
+#include "Swiften/EventLoop/DummyEventLoop.h"
+
+const unsigned char* address = reinterpret_cast<const unsigned char*>("\x41\x63\xde\x89");
+
+using namespace Swift;
+
+class BoostConnectionTest : public CppUnit::TestFixture {
+		CPPUNIT_TEST_SUITE(BoostConnectionTest);
+		CPPUNIT_TEST(testDestructor);
+		CPPUNIT_TEST(testDestructor_PendingEvents);
+		CPPUNIT_TEST_SUITE_END();
+
+	public:
+		BoostConnectionTest() {}
+
+		void setUp() {
+			boostIOServiceThread_ = new BoostIOServiceThread();
+			eventLoop_ = new DummyEventLoop();
+		}
+
+		void tearDown() {
+			delete eventLoop_;
+			delete boostIOServiceThread_;
+		}
+
+		void testDestructor() {
+			{
+				boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService()));
+				testling->connect(HostAddressPort(HostAddress(address, 4), 5222));
+			}
+		}
+
+		void testDestructor_PendingEvents() {
+			{
+				boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService()));
+				testling->connect(HostAddressPort(HostAddress(address, 4), 5222));
+				while (!eventLoop_->hasEvents()) {
+					Swift::sleep(10);
+				}
+			}
+			eventLoop_->processEvents();
+		}
+
+	private:
+		BoostIOServiceThread* boostIOServiceThread_;
+		DummyEventLoop* eventLoop_;
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(BoostConnectionTest);
diff --git a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp
new file mode 100644
index 0000000..8968efd
--- /dev/null
+++ b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp
@@ -0,0 +1,64 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/Network/DomainNameResolver.h"
+#include "Swiften/Network/DomainNameResolveException.h"
+
+using namespace Swift;
+
+class DomainNameResolverTest : public CppUnit::TestFixture {
+		CPPUNIT_TEST_SUITE(DomainNameResolverTest);
+		CPPUNIT_TEST(testResolve_NoSRV);
+		CPPUNIT_TEST(testResolve_SRV);
+		CPPUNIT_TEST(testResolve_Invalid);
+		//CPPUNIT_TEST(testResolve_IPv6);
+		CPPUNIT_TEST(testResolve_International);
+		CPPUNIT_TEST_SUITE_END();
+
+	public:
+		DomainNameResolverTest() {}
+
+		void setUp() {
+			resolver_ = new DomainNameResolver();
+		}
+
+		void tearDown() {
+			delete resolver_;
+		}
+
+		void testResolve_NoSRV() {
+			HostAddressPort result = resolver_->resolve("xmpp.test.swift.im");
+
+			CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), result.getAddress().toString());
+			CPPUNIT_ASSERT_EQUAL(5222, result.getPort());
+		}
+
+		void testResolve_SRV() {
+			HostAddressPort result = resolver_->resolve("xmpp-srv.test.swift.im");
+
+			CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.1"), result.getAddress().toString());
+			CPPUNIT_ASSERT_EQUAL(5000, result.getPort());
+		}
+
+		void testResolve_Invalid() {
+			CPPUNIT_ASSERT_THROW(resolver_->resolve("invalid.test.swift.im"), DomainNameResolveException);
+		}
+
+		void testResolve_IPv6() {
+			HostAddressPort result = resolver_->resolve("xmpp-ipv6.test.swift.im");
+			CPPUNIT_ASSERT_EQUAL(std::string("0000:0000:0000:0000:0000:ffff:0a00:0104"), result.getAddress().toString());
+			CPPUNIT_ASSERT_EQUAL(5222, result.getPort());
+		}
+
+		void testResolve_International() {
+			HostAddressPort result = resolver_->resolve("tron\xc3\xa7on.test.swift.im");
+			CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.3"), result.getAddress().toString());
+			CPPUNIT_ASSERT_EQUAL(5222, result.getPort());
+		}
+
+	private:
+		DomainNameResolver* resolver_;
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DomainNameResolverTest);
diff --git a/Swiften/QA/NetworkTest/SConscript b/Swiften/QA/NetworkTest/SConscript
new file mode 100644
index 0000000..cf66a68
--- /dev/null
+++ b/Swiften/QA/NetworkTest/SConscript
@@ -0,0 +1,18 @@
+import os
+
+Import("env")
+
+if env["TEST"] :
+	myenv = env.Clone()
+	myenv.MergeFlags(env["CHECKER_FLAGS"])
+	myenv.MergeFlags(env["SWIFTEN_FLAGS"])
+	myenv.MergeFlags(env["CPPUNIT_FLAGS"])
+	myenv.MergeFlags(env["BOOST_FLAGS"])
+	myenv.MergeFlags(env["LIBIDN_FLAGS"])
+
+	tester = myenv.Program("NetworkTest", [
+			"BoostConnectionServerTest.cpp",
+			"BoostConnectionTest.cpp",
+			"DomainNameResolverTest.cpp",
+		])
+	myenv.Test(tester, "system")
diff --git a/Swiften/QA/SConscript b/Swiften/QA/SConscript
new file mode 100644
index 0000000..ede7b39
--- /dev/null
+++ b/Swiften/QA/SConscript
@@ -0,0 +1,4 @@
+SConscript([
+		"NetworkTest/SConscript",
+		"ClientTest/SConscript",
+	])
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 86c2a81..148f1f8 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -93,6 +93,7 @@ SConscript(dirs = [
 		"History",
 		"StreamStack",
 		"LinkLocal",
+		"QA",
 	])
 
 myenv.StaticLibrary("Swiften", sources + swiften_env["SWIFTEN_OBJECTS"])
-- 
cgit v0.10.2-6-g49f6