From 5d16ce2a51e866aae75b609e40c31c88a5aa4d80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 19 Jun 2010 09:48:42 +0200
Subject: Added DNSSDTest.


diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h
index 09cb069..2045328 100644
--- a/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h
+++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h
@@ -38,6 +38,10 @@ namespace Swift {
 			}
 
 			void unregisterService() {
+				if (group) {
+					avahi_entry_group_free(group);
+					group = NULL;
+				}
 			}
 
 			void updateServiceInfo(const ByteArray& txtRecord) {
diff --git a/Swiften/QA/DNSSDTest/.gitignore b/Swiften/QA/DNSSDTest/.gitignore
new file mode 100644
index 0000000..d06e99e
--- /dev/null
+++ b/Swiften/QA/DNSSDTest/.gitignore
@@ -0,0 +1 @@
+DNSSDTest
diff --git a/Swiften/QA/DNSSDTest/DNSSDTest.cpp b/Swiften/QA/DNSSDTest/DNSSDTest.cpp
new file mode 100644
index 0000000..7aa7b5e
--- /dev/null
+++ b/Swiften/QA/DNSSDTest/DNSSDTest.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+// TODO: Test registering on different interfaces
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <boost/bind.hpp>
+
+#include <algorithm>
+
+#include "Swiften/Base/sleep.h"
+#include "Swiften/Base/ByteArray.h"
+#include "Swiften/EventLoop/DummyEventLoop.h"
+#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h"
+#ifdef HAVE_AVAHI
+#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h"
+#endif
+
+#define SLEEP_INTERVALS 20
+
+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(String("DNSSDTest"), registered[0].getName());
+			CPPUNIT_ASSERT_EQUAL(String("local"), registered[0].getDomain());
+			CPPUNIT_ASSERT_EQUAL(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(String("DNSSDTest"), added[i].getName());
+				CPPUNIT_ASSERT_EQUAL(String("local"), added[i].getDomain());
+				CPPUNIT_ASSERT_EQUAL(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.size() > 0) {
+				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());
+			toRemove.erase(std::remove(toRemove.begin(), toRemove.end(), 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;
+};
+
+#ifdef HAVE_AVAHI
+CPPUNIT_TEST_SUITE_REGISTRATION(DNSSDTest<AvahiQuerier>);
+#endif
diff --git a/Swiften/QA/DNSSDTest/SConscript b/Swiften/QA/DNSSDTest/SConscript
new file mode 100644
index 0000000..d35d06f
--- /dev/null
+++ b/Swiften/QA/DNSSDTest/SConscript
@@ -0,0 +1,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"])
+
+	tester = myenv.Program("DNSSDTest", [
+			"DNSSDTest.cpp",
+		])
+	myenv.Test(tester, "system")
diff --git a/Swiften/QA/NetworkTest/SConscript b/Swiften/QA/NetworkTest/SConscript
index 871df39..764bc42 100644
--- a/Swiften/QA/NetworkTest/SConscript
+++ b/Swiften/QA/NetworkTest/SConscript
@@ -14,5 +14,6 @@ if env["TEST"] :
 			"BoostConnectionServerTest.cpp",
 			"BoostConnectionTest.cpp",
 			"DomainNameResolverTest.cpp",
+			"DNSSDTest.cpp",
 		])
 	myenv.Test(tester, "system")
diff --git a/Swiften/QA/SConscript b/Swiften/QA/SConscript
index dda6524..4cc56c9 100644
--- a/Swiften/QA/SConscript
+++ b/Swiften/QA/SConscript
@@ -1,5 +1,6 @@
-SConscript([
-		"NetworkTest/SConscript",
-		"ReconnectTest/SConscript",
-		"ClientTest/SConscript",
+SConscript(dirs = [
+		"NetworkTest",
+		"ReconnectTest",
+		"ClientTest",
+		"DNSSDTest",
 	])
-- 
cgit v0.10.2-6-g49f6