summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Network')
-rw-r--r--Swiften/Network/ChainedConnector.cpp19
-rw-r--r--Swiften/Network/ChainedConnector.h8
-rw-r--r--Swiften/Network/Connector.cpp8
-rw-r--r--Swiften/Network/Connector.h3
-rw-r--r--Swiften/Network/UnitTest/ChainedConnectorTest.cpp29
-rw-r--r--Swiften/Network/UnitTest/ConnectorTest.cpp34
6 files changed, 75 insertions, 26 deletions
diff --git a/Swiften/Network/ChainedConnector.cpp b/Swiften/Network/ChainedConnector.cpp
index 1a38e53..0a1283f 100644
--- a/Swiften/Network/ChainedConnector.cpp
+++ b/Swiften/Network/ChainedConnector.cpp
@@ -35,48 +35,49 @@ void ChainedConnector::setTimeoutMilliseconds(int milliseconds) {
void ChainedConnector::start() {
SWIFT_LOG(debug) << "Starting queued connector for " << hostname << std::endl;
connectionFactoryQueue = std::deque<ConnectionFactory*>(connectionFactories.begin(), connectionFactories.end());
tryNextConnectionFactory();
}
void ChainedConnector::stop() {
if (currentConnector) {
- currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1));
+ currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1, _2));
currentConnector->stop();
currentConnector.reset();
}
- finish(boost::shared_ptr<Connection>());
+ finish(boost::shared_ptr<Connection>(), boost::shared_ptr<Error>());
}
void ChainedConnector::tryNextConnectionFactory() {
assert(!currentConnector);
if (connectionFactoryQueue.empty()) {
SWIFT_LOG(debug) << "No more connection factories" << std::endl;
- finish(boost::shared_ptr<Connection>());
+ finish(boost::shared_ptr<Connection>(), lastError);
}
else {
ConnectionFactory* connectionFactory = connectionFactoryQueue.front();
SWIFT_LOG(debug) << "Trying next connection factory: " << typeid(*connectionFactory).name() << std::endl;
connectionFactoryQueue.pop_front();
currentConnector = Connector::create(hostname, resolver, connectionFactory, timerFactory);
currentConnector->setTimeoutMilliseconds(timeoutMilliseconds);
- currentConnector->onConnectFinished.connect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1));
+ currentConnector->onConnectFinished.connect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1, _2));
currentConnector->start();
}
}
-void ChainedConnector::handleConnectorFinished(boost::shared_ptr<Connection> connection) {
+void ChainedConnector::handleConnectorFinished(boost::shared_ptr<Connection> connection, boost::shared_ptr<Error> error) {
SWIFT_LOG(debug) << "Connector finished" << std::endl;
- currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1));
+ currentConnector->onConnectFinished.disconnect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1, _2));
+ lastError = error;
currentConnector.reset();
if (connection) {
- finish(connection);
+ finish(connection, error);
}
else {
tryNextConnectionFactory();
}
}
-void ChainedConnector::finish(boost::shared_ptr<Connection> connection) {
- onConnectFinished(connection);
+void ChainedConnector::finish(boost::shared_ptr<Connection> connection, boost::shared_ptr<Error> error) {
+ onConnectFinished(connection, error);
}
diff --git a/Swiften/Network/ChainedConnector.h b/Swiften/Network/ChainedConnector.h
index 15b17f3..12ef023 100644
--- a/Swiften/Network/ChainedConnector.h
+++ b/Swiften/Network/ChainedConnector.h
@@ -6,42 +6,44 @@
#pragma once
#include <string>
#include <vector>
#include <deque>
#include <boost/shared_ptr.hpp>
#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/Error.h>
namespace Swift {
class Connection;
class Connector;
class ConnectionFactory;
class TimerFactory;
class DomainNameResolver;
class ChainedConnector {
public:
ChainedConnector(const std::string& hostname, DomainNameResolver*, const std::vector<ConnectionFactory*>&, TimerFactory*);
void setTimeoutMilliseconds(int milliseconds);
void start();
void stop();
- boost::signal<void (boost::shared_ptr<Connection>)> onConnectFinished;
+ boost::signal<void (boost::shared_ptr<Connection>, boost::shared_ptr<Error>)> onConnectFinished;
private:
- void finish(boost::shared_ptr<Connection> connection);
+ void finish(boost::shared_ptr<Connection> connection, boost::shared_ptr<Error>);
void tryNextConnectionFactory();
- void handleConnectorFinished(boost::shared_ptr<Connection>);
+ void handleConnectorFinished(boost::shared_ptr<Connection>, boost::shared_ptr<Error>);
private:
std::string hostname;
DomainNameResolver* resolver;
std::vector<ConnectionFactory*> connectionFactories;
TimerFactory* timerFactory;
int timeoutMilliseconds;
std::deque<ConnectionFactory*> connectionFactoryQueue;
boost::shared_ptr<Connector> currentConnector;
+ boost::shared_ptr<Error> lastError;
};
};
diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp
index 378875b..5e7f8d9 100644
--- a/Swiften/Network/Connector.cpp
+++ b/Swiften/Network/Connector.cpp
@@ -11,19 +11,19 @@
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/DomainNameResolver.h>
#include <Swiften/Network/DomainNameAddressQuery.h>
#include <Swiften/Network/TimerFactory.h>
#include <Swiften/Base/Log.h>
namespace Swift {
-Connector::Connector(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, int defaultPort) : hostname(hostname), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), defaultPort(defaultPort), timeoutMilliseconds(0), queriedAllServices(true) {
+Connector::Connector(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, int defaultPort) : hostname(hostname), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), defaultPort(defaultPort), timeoutMilliseconds(0), queriedAllServices(true), foundSomeDNS(false) {
}
void Connector::setTimeoutMilliseconds(int milliseconds) {
timeoutMilliseconds = milliseconds;
}
void Connector::start() {
SWIFT_LOG(debug) << "Starting connector for " << hostname << std::endl;
//std::cout << "Connector::start()" << std::endl;
@@ -50,18 +50,21 @@ void Connector::queryAddress(const std::string& hostname) {
addressQuery = resolver->createAddressQuery(hostname);
addressQuery->onResult.connect(boost::bind(&Connector::handleAddressQueryResult, shared_from_this(), _1, _2));
addressQuery->run();
}
void Connector::handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result) {
SWIFT_LOG(debug) << result.size() << " SRV result(s)" << std::endl;
serviceQueryResults = std::deque<DomainNameServiceQuery::Result>(result.begin(), result.end());
serviceQuery.reset();
+ if (!serviceQueryResults.empty()) {
+ foundSomeDNS = true;
+ }
tryNextServiceOrFallback();
}
void Connector::tryNextServiceOrFallback() {
if (queriedAllServices) {
SWIFT_LOG(debug) << "Queried all services" << std::endl;
finish(boost::shared_ptr<Connection>());
}
else if (serviceQueryResults.empty()) {
@@ -80,18 +83,19 @@ void Connector::handleAddressQueryResult(const std::vector<HostAddress>& address
SWIFT_LOG(debug) << addresses.size() << " addresses" << std::endl;
addressQuery.reset();
if (error || addresses.empty()) {
if (!serviceQueryResults.empty()) {
serviceQueryResults.pop_front();
}
tryNextServiceOrFallback();
}
else {
+ foundSomeDNS = true;
addressQueryResults = std::deque<HostAddress>(addresses.begin(), addresses.end());
tryNextAddress();
}
}
void Connector::tryNextAddress() {
if (addressQueryResults.empty()) {
SWIFT_LOG(debug) << "Done trying addresses. Moving on." << std::endl;
// Done trying all addresses. Move on to the next host.
@@ -154,18 +158,18 @@ void Connector::finish(boost::shared_ptr<Connection> connection) {
}
if (addressQuery) {
addressQuery->onResult.disconnect(boost::bind(&Connector::handleAddressQueryResult, shared_from_this(), _1, _2));
addressQuery.reset();
}
if (currentConnection) {
currentConnection->onConnectFinished.disconnect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1));
currentConnection.reset();
}
- onConnectFinished(connection);
+ onConnectFinished(connection, (connection || foundSomeDNS) ? boost::shared_ptr<Error>() : boost::make_shared<DomainNameResolveError>());
}
void Connector::handleTimeout() {
SWIFT_LOG(debug) << "Timeout" << std::endl;
finish(boost::shared_ptr<Connection>());
}
};
diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h
index 8f2c359..bf0efaf 100644
--- a/Swiften/Network/Connector.h
+++ b/Swiften/Network/Connector.h
@@ -29,19 +29,19 @@ namespace Swift {
static Connector::ref create(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, int defaultPort = 5222) {
return ref(new Connector(hostname, resolver, connectionFactory, timerFactory, defaultPort));
}
void setTimeoutMilliseconds(int milliseconds);
void start();
void stop();
- boost::signal<void (boost::shared_ptr<Connection>)> onConnectFinished;
+ boost::signal<void (boost::shared_ptr<Connection>, boost::shared_ptr<Error>)> onConnectFinished;
private:
Connector(const std::string& hostname, DomainNameResolver*, ConnectionFactory*, TimerFactory*, int defaultPort);
void handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result);
void handleAddressQueryResult(const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error);
void queryAddress(const std::string& hostname);
void tryNextServiceOrFallback();
@@ -61,11 +61,12 @@ namespace Swift {
int defaultPort;
int timeoutMilliseconds;
boost::shared_ptr<Timer> timer;
boost::shared_ptr<DomainNameServiceQuery> serviceQuery;
std::deque<DomainNameServiceQuery::Result> serviceQueryResults;
boost::shared_ptr<DomainNameAddressQuery> addressQuery;
std::deque<HostAddress> addressQueryResults;
bool queriedAllServices;
boost::shared_ptr<Connection> currentConnection;
+ bool foundSomeDNS;
};
};
diff --git a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
index c7d23da..a2fceb9 100644
--- a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
+++ b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
@@ -11,31 +11,34 @@
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Network/ChainedConnector.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Network/StaticDomainNameResolver.h>
#include <Swiften/Network/DummyTimerFactory.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
+#include <Swiften/Network/DomainNameResolveError.h>
using namespace Swift;
class ChainedConnectorTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ChainedConnectorTest);
CPPUNIT_TEST(testConnect_FirstConnectorSucceeds);
CPPUNIT_TEST(testConnect_SecondConnectorSucceeds);
CPPUNIT_TEST(testConnect_NoConnectorSucceeds);
+ CPPUNIT_TEST(testConnect_NoDNS);
CPPUNIT_TEST(testStop);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
+ error.reset();
host = HostAddressPort(HostAddress("1.1.1.1"), 1234);
eventLoop = new DummyEventLoop();
resolver = new StaticDomainNameResolver(eventLoop);
resolver->addXMPPClientService("foo.com", host);
connectionFactory1 = new MockConnectionFactory(eventLoop, 1);
connectionFactory2 = new MockConnectionFactory(eventLoop, 2);
timerFactory = new DummyTimerFactory();
}
@@ -52,43 +55,63 @@ class ChainedConnectorTest : public CppUnit::TestFixture {
connectionFactory1->connects = true;
connectionFactory2->connects = false;
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(connections[0]);
CPPUNIT_ASSERT_EQUAL(1, boost::dynamic_pointer_cast<MockConnection>(connections[0])->id);
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_SecondConnectorSucceeds() {
boost::shared_ptr<ChainedConnector> testling(createConnector());
connectionFactory1->connects = false;
connectionFactory2->connects = true;
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(connections[0]);
CPPUNIT_ASSERT_EQUAL(2, boost::dynamic_pointer_cast<MockConnection>(connections[0])->id);
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_NoConnectorSucceeds() {
boost::shared_ptr<ChainedConnector> testling(createConnector());
connectionFactory1->connects = false;
connectionFactory2->connects = false;
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(!connections[0]);
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
+ }
+
+ void testConnect_NoDNS() {
+ /* Reset resolver so there's no record */
+ delete resolver;
+ resolver = new StaticDomainNameResolver(eventLoop);
+ boost::shared_ptr<ChainedConnector> testling(createConnector());
+ connectionFactory1->connects = false;
+ connectionFactory2->connects = false;
+
+ testling->start();
+ //testling->stop();
+ eventLoop->processEvents();
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
+ CPPUNIT_ASSERT(!connections[0]);
+ CPPUNIT_ASSERT(boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testStop() {
boost::shared_ptr<ChainedConnector> testling(createConnector());
connectionFactory1->connects = true;
connectionFactory2->connects = false;
testling->start();
testling->stop();
@@ -98,23 +121,24 @@ class ChainedConnectorTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT(!connections[0]);
}
private:
boost::shared_ptr<ChainedConnector> createConnector() {
std::vector<ConnectionFactory*> factories;
factories.push_back(connectionFactory1);
factories.push_back(connectionFactory2);
boost::shared_ptr<ChainedConnector> connector = boost::make_shared<ChainedConnector>("foo.com", resolver, factories, timerFactory);
- connector->onConnectFinished.connect(boost::bind(&ChainedConnectorTest::handleConnectorFinished, this, _1));
+ connector->onConnectFinished.connect(boost::bind(&ChainedConnectorTest::handleConnectorFinished, this, _1, _2));
return connector;
}
- void handleConnectorFinished(boost::shared_ptr<Connection> connection) {
+ void handleConnectorFinished(boost::shared_ptr<Connection> connection, boost::shared_ptr<Error> resultError) {
+ error = resultError;
boost::shared_ptr<MockConnection> c(boost::dynamic_pointer_cast<MockConnection>(connection));
if (connection) {
assert(c);
}
connections.push_back(c);
}
struct MockConnection : public Connection {
public:
@@ -150,12 +174,13 @@ class ChainedConnectorTest : public CppUnit::TestFixture {
private:
HostAddressPort host;
DummyEventLoop* eventLoop;
StaticDomainNameResolver* resolver;
MockConnectionFactory* connectionFactory1;
MockConnectionFactory* connectionFactory2;
DummyTimerFactory* timerFactory;
std::vector< boost::shared_ptr<MockConnection> > connections;
+ boost::shared_ptr<Error> error;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChainedConnectorTest);
diff --git a/Swiften/Network/UnitTest/ConnectorTest.cpp b/Swiften/Network/UnitTest/ConnectorTest.cpp
index 6488e67..67270be 100644
--- a/Swiften/Network/UnitTest/ConnectorTest.cpp
+++ b/Swiften/Network/UnitTest/ConnectorTest.cpp
@@ -11,18 +11,19 @@
#include <boost/bind.hpp>
#include <Swiften/Network/Connector.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Network/StaticDomainNameResolver.h>
#include <Swiften/Network/DummyTimerFactory.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
+#include <Swiften/Network/DomainNameAddressQuery.h>
using namespace Swift;
class ConnectorTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ConnectorTest);
CPPUNIT_TEST(testConnect);
CPPUNIT_TEST(testConnect_FirstAddressHostFails);
CPPUNIT_TEST(testConnect_NoSRVHost);
CPPUNIT_TEST(testConnect_NoHosts);
@@ -61,171 +62,183 @@ class ConnectorTest : public CppUnit::TestFixture {
resolver->addXMPPClientService("foo.com", host2);
resolver->addAddress("foo.com", host3.getAddress());
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(connections[0]);
CPPUNIT_ASSERT(host1 == *(connections[0]->hostAddressPort));
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_NoSRVHost() {
Connector::ref testling(createConnector());
resolver->addAddress("foo.com", host3.getAddress());
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(connections[0]);
CPPUNIT_ASSERT(host3 == *(connections[0]->hostAddressPort));
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_FirstAddressHostFails() {
Connector::ref testling(createConnector());
HostAddress address1("1.1.1.1");
HostAddress address2("2.2.2.2");
resolver->addXMPPClientService("foo.com", "host-foo.com", 1234);
resolver->addAddress("host-foo.com", address1);
resolver->addAddress("host-foo.com", address2);
connectionFactory->failingPorts.push_back(HostAddressPort(address1, 1234));
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(connections[0]);
CPPUNIT_ASSERT(HostAddressPort(address2, 1234) == *(connections[0]->hostAddressPort));
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_NoHosts() {
Connector::ref testling(createConnector());
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(!connections[0]);
+ CPPUNIT_ASSERT(boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_FirstSRVHostFails() {
Connector::ref testling(createConnector());
resolver->addXMPPClientService("foo.com", host1);
resolver->addXMPPClientService("foo.com", host2);
connectionFactory->failingPorts.push_back(host1);
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(host2 == *(connections[0]->hostAddressPort));
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_AllSRVHostsFailWithoutFallbackHost() {
Connector::ref testling(createConnector());
resolver->addXMPPClientService("foo.com", host1);
resolver->addXMPPClientService("foo.com", host2);
connectionFactory->failingPorts.push_back(host1);
connectionFactory->failingPorts.push_back(host2);
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(!connections[0]);
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_AllSRVHostsFailWithFallbackHost() {
Connector::ref testling(createConnector());
resolver->addXMPPClientService("foo.com", host1);
resolver->addXMPPClientService("foo.com", host2);
resolver->addAddress("foo.com", host3.getAddress());
connectionFactory->failingPorts.push_back(host1);
connectionFactory->failingPorts.push_back(host2);
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(connections[0]);
CPPUNIT_ASSERT(host3 == *(connections[0]->hostAddressPort));
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_SRVAndFallbackHostsFail() {
Connector::ref testling(createConnector());
resolver->addXMPPClientService("foo.com", host1);
resolver->addAddress("foo.com", host3.getAddress());
connectionFactory->failingPorts.push_back(host1);
connectionFactory->failingPorts.push_back(host3);
testling->start();
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(!connections[0]);
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_TimeoutDuringResolve() {
Connector::ref testling(createConnector());
testling->setTimeoutMilliseconds(10);
resolver->setIsResponsive(false);
testling->start();
eventLoop->processEvents();
timerFactory->setTime(10);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
+ CPPUNIT_ASSERT(boost::dynamic_pointer_cast<DomainNameResolveError>(error));
CPPUNIT_ASSERT(!connections[0]);
}
void testConnect_TimeoutDuringConnect() {
Connector::ref testling(createConnector());
testling->setTimeoutMilliseconds(10);
resolver->addXMPPClientService("foo.com", host1);
connectionFactory->isResponsive = false;
testling->start();
eventLoop->processEvents();
timerFactory->setTime(10);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(!connections[0]);
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testConnect_NoTimeout() {
Connector::ref testling(createConnector());
testling->setTimeoutMilliseconds(10);
resolver->addXMPPClientService("foo.com", host1);
testling->start();
eventLoop->processEvents();
timerFactory->setTime(10);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(connections[0]);
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testStop_DuringSRVQuery() {
- Connector::ref testling(createConnector());
- resolver->addXMPPClientService("foo.com", host1);
+ Connector::ref testling(createConnector());
+ resolver->addXMPPClientService("foo.com", host1);
- testling->start();
- testling->stop();
+ testling->start();
+ testling->stop();
- eventLoop->processEvents();
+ eventLoop->processEvents();
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
- CPPUNIT_ASSERT(!connections[0]);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
+ CPPUNIT_ASSERT(!connections[0]);
+ CPPUNIT_ASSERT(boost::dynamic_pointer_cast<DomainNameResolveError>(error));
}
void testStop_Timeout() {
Connector::ref testling(createConnector());
testling->setTimeoutMilliseconds(10);
resolver->addXMPPClientService("foo.com", host1);
testling->start();
testling->stop();
@@ -236,28 +249,29 @@ class ConnectorTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
CPPUNIT_ASSERT(!connections[0]);
}
private:
Connector::ref createConnector() {
Connector::ref connector = Connector::create("foo.com", resolver, connectionFactory, timerFactory);
- connector->onConnectFinished.connect(boost::bind(&ConnectorTest::handleConnectorFinished, this, _1));
+ connector->onConnectFinished.connect(boost::bind(&ConnectorTest::handleConnectorFinished, this, _1, _2));
return connector;
}
- void handleConnectorFinished(boost::shared_ptr<Connection> connection) {
+ void handleConnectorFinished(boost::shared_ptr<Connection> connection, boost::shared_ptr<Error> resultError) {
boost::shared_ptr<MockConnection> c(boost::dynamic_pointer_cast<MockConnection>(connection));
if (connection) {
assert(c);
}
connections.push_back(c);
+ error = resultError;
}
struct MockConnection : public Connection {
public:
MockConnection(const std::vector<HostAddressPort>& failingPorts, bool isResponsive, EventLoop* eventLoop) : eventLoop(eventLoop), failingPorts(failingPorts), isResponsive(isResponsive) {}
void listen() { assert(false); }
void connect(const HostAddressPort& address) {
hostAddressPort = address;
@@ -293,12 +307,14 @@ class ConnectorTest : public CppUnit::TestFixture {
private:
HostAddressPort host1;
HostAddressPort host2;
HostAddressPort host3;
DummyEventLoop* eventLoop;
StaticDomainNameResolver* resolver;
MockConnectionFactory* connectionFactory;
DummyTimerFactory* timerFactory;
std::vector< boost::shared_ptr<MockConnection> > connections;
+ boost::shared_ptr<Error> error;
+
};
CPPUNIT_TEST_SUITE_REGISTRATION(ConnectorTest);