/* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include #include #include #include #include #include #include #include #include #include #include #include using namespace Swift; class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(LinkLocalServiceBrowserTest); CPPUNIT_TEST(testConstructor); CPPUNIT_TEST(testStart); CPPUNIT_TEST(testServiceAdded); CPPUNIT_TEST(testServiceAdded_NoServiceInfo); CPPUNIT_TEST(testServiceAdded_RegisteredService); CPPUNIT_TEST(testServiceAdded_UnregisteredService); CPPUNIT_TEST(testServiceAdded_Twice); CPPUNIT_TEST(testServiceChanged); CPPUNIT_TEST(testServiceRemoved); CPPUNIT_TEST(testServiceRemoved_UnregisteredService); CPPUNIT_TEST(testError_BrowseErrorAfterStart); CPPUNIT_TEST(testError_BrowseErrorAfterResolve); CPPUNIT_TEST(testRegisterService); CPPUNIT_TEST(testRegisterService_Error); CPPUNIT_TEST(testRegisterService_Reregister); CPPUNIT_TEST(testUpdateService); CPPUNIT_TEST_SUITE_END(); public: void setUp() { eventLoop = new DummyEventLoop(); querier = std::make_shared("wonderland.lit", eventLoop); aliceServiceID = new DNSSDServiceID("alice", "wonderland.lit"); aliceServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.wonderland.lit", "xmpp.wonderland.lit", 1234, LinkLocalServiceInfo().toTXTRecord()); testServiceID = new DNSSDServiceID("foo", "bar.local"); testServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.bar.local", "xmpp.bar.local", 1234, LinkLocalServiceInfo().toTXTRecord()); testServiceInfo2 = new DNSSDResolveServiceQuery::Result("_presence.tcp.bar.local", "xmpp.foo.local", 2345, LinkLocalServiceInfo().toTXTRecord()); errorStopReceived = false; normalStopReceived = false; } void tearDown() { querier->clearAllQueriesEverRun(); addedServices.clear(); removedServices.clear(); changedServices.clear(); delete aliceServiceID; delete aliceServiceInfo; delete testServiceInfo2; delete testServiceInfo; delete testServiceID; delete eventLoop; } void testConstructor() { std::shared_ptr testling = createTestling(); CPPUNIT_ASSERT(!testling->isRunning()); CPPUNIT_ASSERT(!testling->hasError()); } void testStart() { std::shared_ptr testling = createTestling(); testling->start(); CPPUNIT_ASSERT(testling->isRunning()); CPPUNIT_ASSERT(!testling->hasError()); testling->stop(); } void testServiceAdded() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); querier->setServiceInfo(*testServiceID,*testServiceInfo); querier->addService(*testServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast(addedServices.size())); CPPUNIT_ASSERT(addedServices[0].getID() == *testServiceID); CPPUNIT_ASSERT_EQUAL(0, static_cast(changedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast(removedServices.size())); std::vector services = testling->getServices(); CPPUNIT_ASSERT_EQUAL(1, static_cast(services.size())); CPPUNIT_ASSERT(*testServiceID == services[0].getID()); CPPUNIT_ASSERT(testServiceInfo->port == services[0].getPort()); CPPUNIT_ASSERT(testServiceInfo->host == services[0].getHostname()); testling->stop(); } void testServiceAdded_NoServiceInfo() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); querier->addService(*testServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, static_cast(addedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast(testling->getServices().size())); testling->stop(); } void testServiceAdded_RegisteredService() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); testling->registerService("alice", 1234, LinkLocalServiceInfo()); eventLoop->processEvents(); querier->setServiceInfo(*aliceServiceID, *aliceServiceInfo); querier->addService(*aliceServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, static_cast(addedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast(testling->getServices().size())); testling->stop(); } void testServiceAdded_UnregisteredService() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); testling->registerService("alice", 1234, LinkLocalServiceInfo()); eventLoop->processEvents(); testling->unregisterService(); eventLoop->processEvents(); querier->setServiceInfo(*aliceServiceID, *aliceServiceInfo); querier->addService(*aliceServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast(addedServices.size())); CPPUNIT_ASSERT(addedServices[0].getID() == *aliceServiceID); CPPUNIT_ASSERT_EQUAL(0, static_cast(changedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast(removedServices.size())); std::vector services = testling->getServices(); CPPUNIT_ASSERT_EQUAL(1, static_cast(services.size())); CPPUNIT_ASSERT(*aliceServiceID == services[0].getID()); CPPUNIT_ASSERT(aliceServiceInfo->port == services[0].getPort()); CPPUNIT_ASSERT(aliceServiceInfo->host == services[0].getHostname()); testling->stop(); } void testServiceRemoved_UnregisteredService() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); testling->registerService("alice", 1234, LinkLocalServiceInfo()); eventLoop->processEvents(); testling->unregisterService(); eventLoop->processEvents(); querier->removeService(*aliceServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, static_cast(removedServices.size())); testling->stop(); } void testServiceAdded_Twice() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); querier->setServiceInfo(*testServiceID,*testServiceInfo); querier->addService(*testServiceID); querier->addService(*testServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast(querier->getAllQueriesEverRun().size())); CPPUNIT_ASSERT_EQUAL(1, static_cast(addedServices.size())); CPPUNIT_ASSERT(addedServices[0].getID() == *testServiceID); CPPUNIT_ASSERT_EQUAL(0, static_cast(changedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast(removedServices.size())); std::vector services = testling->getServices(); CPPUNIT_ASSERT_EQUAL(1, static_cast(services.size())); CPPUNIT_ASSERT(*testServiceID == services[0].getID()); CPPUNIT_ASSERT(testServiceInfo->port == services[0].getPort()); CPPUNIT_ASSERT(testServiceInfo->host == services[0].getHostname()); testling->stop(); } void testServiceChanged() { std::shared_ptr testling = createTestling(); testling->start(); querier->setServiceInfo(*testServiceID,*testServiceInfo); querier->addService(*testServiceID); eventLoop->processEvents(); querier->setServiceInfo(*testServiceID,*testServiceInfo2); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast(addedServices.size())); CPPUNIT_ASSERT_EQUAL(1, static_cast(changedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast(removedServices.size())); CPPUNIT_ASSERT(changedServices[0].getID() == *testServiceID); std::vector services = testling->getServices(); CPPUNIT_ASSERT_EQUAL(1, static_cast(services.size())); CPPUNIT_ASSERT(*testServiceID == services[0].getID()); CPPUNIT_ASSERT(testServiceInfo2->port == services[0].getPort()); CPPUNIT_ASSERT(testServiceInfo2->host == services[0].getHostname()); testling->stop(); } void testServiceRemoved() { std::shared_ptr testling = createTestling(); testling->start(); querier->setServiceInfo(*testServiceID,*testServiceInfo); querier->addService(*testServiceID); eventLoop->processEvents(); querier->removeService(*testServiceID); eventLoop->processEvents(); querier->setServiceInfo(*testServiceID,*testServiceInfo2); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast(addedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast(changedServices.size())); CPPUNIT_ASSERT_EQUAL(1, static_cast(removedServices.size())); CPPUNIT_ASSERT(removedServices[0].getID() == *testServiceID); CPPUNIT_ASSERT_EQUAL(0, static_cast(testling->getServices().size())); testling->stop(); } void testError_BrowseErrorAfterStart() { std::shared_ptr testling = createTestling(); testling->start(); querier->setBrowseError(); eventLoop->processEvents(); CPPUNIT_ASSERT(!testling->isRunning()); CPPUNIT_ASSERT(testling->hasError()); CPPUNIT_ASSERT(errorStopReceived); } void testError_BrowseErrorAfterResolve() { std::shared_ptr testling = createTestling(); testling->start(); querier->setServiceInfo(*testServiceID,*testServiceInfo); querier->addService(*testServiceID); eventLoop->processEvents(); querier->setBrowseError(); eventLoop->processEvents(); querier->setServiceInfo(*testServiceID,*testServiceInfo2); eventLoop->processEvents(); CPPUNIT_ASSERT(!testling->isRunning()); CPPUNIT_ASSERT(testling->hasError()); CPPUNIT_ASSERT_EQUAL(0, static_cast(testling->getServices().size())); CPPUNIT_ASSERT_EQUAL(0, static_cast(changedServices.size())); CPPUNIT_ASSERT(errorStopReceived); } void testRegisterService() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); LinkLocalServiceInfo info; info.setFirstName("Foo"); testling->registerService("foo@bar", 1234, info); eventLoop->processEvents(); CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); CPPUNIT_ASSERT_EQUAL(1, static_cast(registeredServices.size())); CPPUNIT_ASSERT(registeredServices[0] == DNSSDServiceID("foo@bar", "wonderland.lit")); testling->stop(); } void testRegisterService_Error() { std::shared_ptr testling = createTestling(); testling->start(); LinkLocalServiceInfo info; testling->registerService("foo@bar", 1234, info); eventLoop->processEvents(); querier->setRegisterError(); eventLoop->processEvents(); CPPUNIT_ASSERT(!testling->isRunning()); CPPUNIT_ASSERT(testling->hasError()); CPPUNIT_ASSERT(errorStopReceived); CPPUNIT_ASSERT(!querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); } void testRegisterService_Reregister() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); LinkLocalServiceInfo info; info.setFirstName("Foo"); testling->registerService("foo@bar", 1234, info); eventLoop->processEvents(); testling->unregisterService(); eventLoop->processEvents(); info.setFirstName("Bar"); testling->registerService("bar@baz", 3456, info); eventLoop->processEvents(); CPPUNIT_ASSERT(querier->isServiceRegistered("bar@baz", 3456, info.toTXTRecord())); testling->stop(); } void testUpdateService() { std::shared_ptr testling = createTestling(); testling->start(); eventLoop->processEvents(); LinkLocalServiceInfo info; info.setFirstName("Foo"); testling->registerService("foo@bar", 1234, info); eventLoop->processEvents(); info.setFirstName("Bar"); testling->updateService(info); CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); testling->stop(); } private: std::shared_ptr createTestling() { std::shared_ptr testling( new LinkLocalServiceBrowser(querier)); testling->onServiceAdded.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceAdded, this, _1)); testling->onServiceChanged.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceChanged, this, _1)); testling->onServiceRemoved.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceRemoved, this, _1)); testling->onServiceRegistered.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceRegistered, this, _1)); testling->onStopped.connect(boost::bind( &LinkLocalServiceBrowserTest::handleStopped, this, _1)); return testling; } void handleServiceAdded(const LinkLocalService& service) { addedServices.push_back(service); } void handleServiceRemoved(const LinkLocalService& service) { removedServices.push_back(service); } void handleServiceChanged(const LinkLocalService& service) { changedServices.push_back(service); } void handleServiceRegistered(const DNSSDServiceID& service) { registeredServices.push_back(service); } void handleStopped(bool error) { CPPUNIT_ASSERT(!errorStopReceived); CPPUNIT_ASSERT(!normalStopReceived); if (error) { errorStopReceived = true; } else { normalStopReceived = true; } } private: DummyEventLoop* eventLoop; std::shared_ptr querier; std::vector addedServices; std::vector changedServices; std::vector removedServices; std::vector registeredServices; DNSSDServiceID* aliceServiceID; DNSSDResolveServiceQuery::Result* aliceServiceInfo; DNSSDServiceID* testServiceID; DNSSDResolveServiceQuery::Result* testServiceInfo; DNSSDResolveServiceQuery::Result* testServiceInfo2; bool errorStopReceived; bool normalStopReceived; }; CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceBrowserTest);