|
@@ -16,6 +16,7 @@
|
|
|
#include <boost/bind.hpp>
|
|
|
#include <cstdlib>
|
|
|
#include <string>
|
|
|
+#include <iostream>
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
@@ -29,12 +30,14 @@
|
|
|
#include <dns/name.h>
|
|
|
#include <dns/rcode.h>
|
|
|
|
|
|
+#include <asiolink/io_address.h>
|
|
|
+#include <asiolink/io_endpoint.h>
|
|
|
#include <asiolink/io_fetch.h>
|
|
|
#include <asiolink/io_service.h>
|
|
|
|
|
|
using namespace asio;
|
|
|
using namespace isc::dns;
|
|
|
-using asio::ip::udp;
|
|
|
+using namespace asio::ip;
|
|
|
|
|
|
namespace asiolink {
|
|
|
|
|
@@ -51,13 +54,16 @@ public:
|
|
|
IOFetch::Result expected_; ///< Expected result of the callback
|
|
|
bool run_; ///< Did the callback run already?
|
|
|
Question question_; ///< What to ask
|
|
|
- OutputBufferPtr buff_; ///< Buffer to hold result
|
|
|
+ OutputBufferPtr result_buff_; ///< Buffer to hold result of fetch
|
|
|
+ OutputBufferPtr msgbuf_; ///< Buffer corresponding to known question
|
|
|
IOFetch udp_fetch_; ///< For UDP query test
|
|
|
- //IOFetch tcp_fetch_; ///< For TCP query test
|
|
|
+ IOFetch tcp_fetch_; ///< For TCP query test
|
|
|
+ IOFetch::Protocol protocol_; ///< Protocol being tested
|
|
|
|
|
|
- // The next member is the buffer iin which the "server" (implemented by the
|
|
|
- // response handler method) receives the question sent by the fetch object.
|
|
|
- char server_buff_[512]; ///< Server buffer
|
|
|
+ // The next member is the buffer in which the "server" (implemented by the
|
|
|
+ // response handler methods in this class) receives the question sent by the
|
|
|
+ // fetch object.
|
|
|
+ uint8_t server_buff_[512]; ///< Server buffer
|
|
|
|
|
|
/// \brief Constructor
|
|
|
IOFetchTest() :
|
|
@@ -65,106 +71,293 @@ public:
|
|
|
expected_(IOFetch::NOTSET),
|
|
|
run_(false),
|
|
|
question_(Name("example.net"), RRClass::IN(), RRType::A()),
|
|
|
- buff_(new OutputBuffer(512)),
|
|
|
+ result_buff_(new OutputBuffer(512)),
|
|
|
+ msgbuf_(new OutputBuffer(512)),
|
|
|
udp_fetch_(IOFetch::UDP, service_, question_, IOAddress(TEST_HOST),
|
|
|
- TEST_PORT, buff_, this, 100)
|
|
|
- // tcp_fetch_(service_, question_, IOAddress(TEST_HOST), TEST_PORT,
|
|
|
- // buff_, this, 100, IPPROTO_UDP)
|
|
|
- { }
|
|
|
-
|
|
|
- /// \brief Fetch completion callback
|
|
|
- ///
|
|
|
- /// This is the callback's operator() method which is called when the fetch
|
|
|
- /// is complete. Check that the data received is the wire format of the
|
|
|
- /// question, then send back an arbitrary response.
|
|
|
- void operator()(IOFetch::Result result) {
|
|
|
- EXPECT_EQ(expected_, result); // Check correct result returned
|
|
|
- EXPECT_FALSE(run_); // Check it is run only once
|
|
|
- run_ = true; // Note success
|
|
|
- service_.stop(); // ... and exit run loop
|
|
|
- }
|
|
|
-
|
|
|
- /// \brief Response handler, pretending to be remote DNS server
|
|
|
- ///
|
|
|
- /// This checks that the data sent is what we expected to receive, and
|
|
|
- /// sends back a test answer.
|
|
|
- void respond(udp::endpoint* remote, udp::socket* socket,
|
|
|
- asio::error_code ec = asio::error_code(), size_t length = 0) {
|
|
|
-
|
|
|
+ TEST_PORT, result_buff_, this, 100),
|
|
|
+ tcp_fetch_(IOFetch::TCP, service_, question_, IOAddress(TEST_HOST),
|
|
|
+ TEST_PORT, result_buff_, this, 1000),
|
|
|
+ protocol_(IOFetch::TCP) // for initialization - will be changed
|
|
|
+ {
|
|
|
// Construct the data buffer for question we expect to receive.
|
|
|
- OutputBuffer msgbuf(512);
|
|
|
Message msg(Message::RENDER);
|
|
|
msg.setQid(0);
|
|
|
msg.setOpcode(Opcode::QUERY());
|
|
|
msg.setRcode(Rcode::NOERROR());
|
|
|
msg.setHeaderFlag(Message::HEADERFLAG_RD);
|
|
|
msg.addQuestion(question_);
|
|
|
- MessageRenderer renderer(msgbuf);
|
|
|
+ MessageRenderer renderer(*msgbuf_);
|
|
|
msg.toWire(renderer);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// \brief Read uint16_t from network-byte-order buffer
|
|
|
+ ///
|
|
|
+ /// Adapted from isc::dns::InputBuffer::readUint16().
|
|
|
+ ///
|
|
|
+ /// \param data Pointer to at least two bytes of data which are in network
|
|
|
+ /// byte order.
|
|
|
+ ///
|
|
|
+ /// \return uint16_t value in host byte order.
|
|
|
+ uint16_t readUint16(const void* data) {
|
|
|
+ const uint8_t* cp = static_cast<const uint8_t*>(data);
|
|
|
+
|
|
|
+ uint16_t value = ((unsigned int)(cp[0])) << 8;
|
|
|
+ value |= ((unsigned int)(cp[1]));
|
|
|
+
|
|
|
+ return (value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// \brief Write uint16_t to network-byte-order buffer
|
|
|
+ ///
|
|
|
+ /// Adapted from isc::dns::OutputBuffer::writeUint16().
|
|
|
+ ///
|
|
|
+ /// \param value The 16-bit integer to be written into the buffer.
|
|
|
+ /// \param data Pointer to buffer at least two bytes long
|
|
|
+ void writeUint16(uint16_t value, uint8_t* data) {
|
|
|
+ data[0] = static_cast<uint8_t>((value & 0xff00U) >> 8);
|
|
|
+ data[1] = static_cast<uint8_t>(value & 0x00ffU);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// \brief UDP Response handler (the "remote UDP DNS server")
|
|
|
+ ///
|
|
|
+ /// When IOFetch is sending data, this response handler emulates the remote
|
|
|
+ /// DNS server. It checks that the data sent by the IOFetch object is what
|
|
|
+ /// was expected to have been sent, then sends back a known buffer of data.
|
|
|
+ ///
|
|
|
+ /// \param remote Endpoint to which to send the answer
|
|
|
+ /// \param socket Socket to use to send the answer
|
|
|
+ /// \param ec ASIO error code, completion code of asynchronous I/O issued
|
|
|
+ /// by the "server" to receive data.
|
|
|
+ /// \param length Amount of data received.
|
|
|
+ void udpReceiveHandler(udp::endpoint* remote, udp::socket* socket,
|
|
|
+ error_code ec = error_code(), size_t length = 0) {
|
|
|
|
|
|
// The QID in the incoming data is random so set it to 0 for the
|
|
|
- // data comparison check. (It was set to 0 when the buffer containing
|
|
|
- // the expected data was constructed above.)
|
|
|
+ // data comparison check. (It is set to 0 in the buffer containing
|
|
|
+ // the expected data.)
|
|
|
server_buff_[0] = server_buff_[1] = 0;
|
|
|
|
|
|
- // Check that lengths are identical.
|
|
|
- EXPECT_EQ(msgbuf.getLength(), length);
|
|
|
- EXPECT_TRUE(memcmp(msgbuf.getData(), server_buff_, length) == 0);
|
|
|
+ // Check that length of the received data and the expected data are
|
|
|
+ // identical, then check that the data is identical as well.
|
|
|
+ EXPECT_EQ(msgbuf_->getLength(), length);
|
|
|
+ EXPECT_TRUE(memcmp(msgbuf_->getData(), server_buff_, length) == 0);
|
|
|
|
|
|
- // ... and return a message back.
|
|
|
+ // Return a message back to the IOFetch object.
|
|
|
socket->send_to(asio::buffer(TEST_DATA, sizeof TEST_DATA), *remote);
|
|
|
}
|
|
|
-};
|
|
|
|
|
|
+ /// \brief Completion Handler for accepting TCP data
|
|
|
+ ///
|
|
|
+ /// Called when the remote system connects to the "server". It issues
|
|
|
+ /// an asynchronous read on the socket to read data.
|
|
|
+ ///
|
|
|
+ /// \param socket Socket on which data will be received
|
|
|
+ /// \param ec Boost error code, value should be zero.
|
|
|
+ void tcpAcceptHandler(tcp::socket* socket, error_code ec = error_code())
|
|
|
+ {
|
|
|
+ std::cerr << "TCP Accept Handler\n";
|
|
|
+ EXPECT_EQ(0, ec.value()); // Expect no error
|
|
|
+
|
|
|
+ // Initiate a read on the socket
|
|
|
+ socket->async_receive(asio::buffer(server_buff_, sizeof(server_buff_)),
|
|
|
+ boost::bind(&IOFetchTest::tcpReceiveHandler, this, socket, _1, _2));
|
|
|
+ }
|
|
|
|
|
|
-/// Test that when we run the query and stop it after it was run,
|
|
|
-/// it returns "stopped" correctly.
|
|
|
-///
|
|
|
-/// That is why stop() is posted to the service_ as well instead
|
|
|
-/// of calling it.
|
|
|
-TEST_F(IOFetchTest, UdpStop) {
|
|
|
- expected_ = IOFetch::STOPPED;
|
|
|
+ /// \brief Completion handler for receiving TCP data
|
|
|
+ ///
|
|
|
+ /// When IOFetch is sending data, this response handler emulates the remote
|
|
|
+ /// DNS server. It checks that the data sent by the IOFetch object is what
|
|
|
+ /// was expected to have been sent, then sends back a known buffer of data.
|
|
|
+ ///
|
|
|
+ /// \param socket Socket to use to send the answer
|
|
|
+ /// \param ec ASIO error code, completion code of asynchronous I/O issued
|
|
|
+ /// by the "server" to receive data.
|
|
|
+ /// \param length Amount of data received.
|
|
|
+ void tcpReceiveHandler(tcp::socket* socket, error_code ec = error_code(),
|
|
|
+ size_t length = 0)
|
|
|
+ {
|
|
|
+ std::cerr << "TCP Receive Handler\n";
|
|
|
+ // TODO - need to loop until all the data is received.
|
|
|
+
|
|
|
+ // Interpret the received data. The first two bytes, when converted
|
|
|
+ // to host byte order, are the count of the length of the message.
|
|
|
+ EXPECT_GE(2, length);
|
|
|
+ uint16_t dns_length = readUint16(server_buff_);
|
|
|
+ EXPECT_EQ(length, dns_length + 2);
|
|
|
+
|
|
|
+ // Check that length of the DNS message received is that expected.
|
|
|
+ EXPECT_EQ(msgbuf_->getLength(), dns_length);
|
|
|
+
|
|
|
+ // Compare buffers, zeroing the QID in the received buffer to match
|
|
|
+ // that set in our expected question. Note that due to the length
|
|
|
+ // field the QID in the received buffer is in the thrid and fourth
|
|
|
+ // bytes.
|
|
|
+ server_buff_[2] = server_buff_[3] = 0;
|
|
|
+ EXPECT_TRUE(memcmp(msgbuf_->getData(), server_buff_ + 2, dns_length) == 0);
|
|
|
+
|
|
|
+ // ... and return a message back. This has to be preceded by a two-byte
|
|
|
+ // count field. It's simpler to do this as two writes - it shouldn't
|
|
|
+ // make any difference to the IOFetch object.
|
|
|
+ uint8_t count[2];
|
|
|
+ writeUint16(sizeof(TEST_DATA), count);
|
|
|
+ socket->async_send(asio::buffer(count, 2),
|
|
|
+ boost::bind(&IOFetchTest::tcpSendHandler, this,
|
|
|
+ sizeof(count), _1, _2));
|
|
|
+ socket->async_send(asio::buffer(TEST_DATA, sizeof(TEST_DATA)),
|
|
|
+ boost::bind(&IOFetchTest::tcpSendHandler, this,
|
|
|
+ sizeof(count), _1, _2));
|
|
|
+ }
|
|
|
|
|
|
- // Post the query
|
|
|
- service_.get_io_service().post(udp_fetch_);
|
|
|
+ /// \brief Completion Handler for Sending TCP data
|
|
|
+ ///
|
|
|
+ /// Called when the asynchronous send of data back to the IOFetch object
|
|
|
+ /// by the TCP "server" in this class has completed. (This send has to
|
|
|
+ /// be asynchronous because control needs to return to the caller in order
|
|
|
+ /// for the IOService "run()" method to be called to run the handlers.)
|
|
|
+ ///
|
|
|
+ /// \param expected Number of bytes that were expected to have been sent.
|
|
|
+ /// \param ec Boost error code, value should be zero.
|
|
|
+ /// \param length Number of bytes sent.
|
|
|
+ void tcpSendHandler(size_t expected = 0, error_code ec = error_code(),
|
|
|
+ size_t length = 0)
|
|
|
+ {
|
|
|
+ std::cerr << "TCP Send Handler\n";
|
|
|
+ EXPECT_EQ(0, ec.value()); // Expect no error
|
|
|
+ EXPECT_EQ(expected, length); // And that amount sent is as expected
|
|
|
+ }
|
|
|
+
|
|
|
+ /// \brief Fetch completion callback
|
|
|
+ ///
|
|
|
+ /// This is the callback's operator() method which is called when the fetch
|
|
|
+ /// is complete. It checks that the data received is the wire format of the
|
|
|
+ /// data sent back by the server.
|
|
|
+ ///
|
|
|
+ /// \param result Result indicated by the callback
|
|
|
+ void operator()(IOFetch::Result result) {
|
|
|
+ std::cerr << "Fetch completion\n";
|
|
|
+ EXPECT_EQ(expected_, result); // Check correct result returned
|
|
|
+ EXPECT_FALSE(run_); // Check it is run only once
|
|
|
+ run_ = true; // Note success
|
|
|
|
|
|
- // Post query_.stop() (yes, the boost::bind thing is just
|
|
|
- // query_.stop()).
|
|
|
- service_.get_io_service().post(
|
|
|
- boost::bind(&IOFetch::stop, udp_fetch_, IOFetch::STOPPED));
|
|
|
+ // If the expected result for SUCCESS, then this should have been called
|
|
|
+ // when one of the "servers" in this class has sent back the TEST_DATA.
|
|
|
+ // Check the data is as expected/
|
|
|
+ if (expected_ == IOFetch::SUCCESS) {
|
|
|
+ size_t offset = 0; // Offset into start of buffer of data
|
|
|
+ if (protocol_ == IOFetch::UDP) {
|
|
|
+
|
|
|
+ // Check the length of data received against the amount expected.
|
|
|
+ EXPECT_EQ(sizeof(TEST_DATA), result_buff_->getLength());
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // Check the length of data received against the amount expected
|
|
|
+ EXPECT_EQ(sizeof(TEST_DATA) + 2, result_buff_->getLength());
|
|
|
+
|
|
|
+ // Check the count field. This should be equal to the total
|
|
|
+ // length of the packet less 2 (the count field is equal to
|
|
|
+ // the total length of the message less the count field itself -
|
|
|
+ // RFC 1035, section 4.2.2).
|
|
|
+ uint16_t count = readUint16(result_buff_->getData());
|
|
|
+ EXPECT_EQ(result_buff_->getLength(), count + 2);
|
|
|
+
|
|
|
+ // Update offset and count for the content check.
|
|
|
+ offset += 2;
|
|
|
+ }
|
|
|
+ const void* start = static_cast<const void*>(
|
|
|
+ static_cast<const uint8_t*>(result_buff_->getData()) + offset);
|
|
|
+ EXPECT_TRUE(memcmp(TEST_DATA, start, sizeof(TEST_DATA)) == 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // ... and cause the run loop to exit.
|
|
|
+ service_.stop();
|
|
|
+ }
|
|
|
|
|
|
- // Run both of them. run() returns when everything in the I/O service
|
|
|
- // queue has completed.
|
|
|
- service_.run();
|
|
|
- EXPECT_TRUE(run_);
|
|
|
-}
|
|
|
+ // The next set of methods are the tests themselves. A number of the TCP
|
|
|
+ // and UDP tests are very similar.
|
|
|
|
|
|
-// Test that when we queue the query to service_ and call stop() before it gets
|
|
|
-// executed, it acts sanely as well (eg. has the same result as running stop()
|
|
|
-// after - calls the callback).
|
|
|
-TEST_F(IOFetchTest, UdpPrematureStop) {
|
|
|
- expected_ = IOFetch::STOPPED;
|
|
|
+ /// \brief Check for stop()
|
|
|
+ ///
|
|
|
+ /// Test that when we run the query and stop it after it was run, it returns
|
|
|
+ /// "stopped" correctly. (That is why stop() is posted to the service_ as
|
|
|
+ /// well instead of calling it.)
|
|
|
+ ///
|
|
|
+ /// \param protocol Test protocol
|
|
|
+ /// \param fetch Fetch object being tested
|
|
|
+ void stopTest(IOFetch::Protocol protocol, IOFetch& fetch) {
|
|
|
+ protocol_ = protocol;
|
|
|
+ expected_ = IOFetch::STOPPED;
|
|
|
+
|
|
|
+ // Post the query
|
|
|
+ service_.get_io_service().post(fetch);
|
|
|
+
|
|
|
+ // Post query_.stop() (yes, the boost::bind thing is just
|
|
|
+ // query_.stop()).
|
|
|
+ service_.get_io_service().post(
|
|
|
+ boost::bind(&IOFetch::stop, fetch, IOFetch::STOPPED));
|
|
|
+
|
|
|
+ // Run both of them. run() returns when everything in the I/O service
|
|
|
+ // queue has completed.
|
|
|
+ service_.run();
|
|
|
+ EXPECT_TRUE(run_);
|
|
|
+ }
|
|
|
|
|
|
- // Stop before it is started
|
|
|
- udp_fetch_.stop();
|
|
|
- service_.get_io_service().post(udp_fetch_);
|
|
|
+ /// \brief Premature stop test
|
|
|
+ ///
|
|
|
+ /// Test that when we queue the query to service_ and call stop() before it
|
|
|
+ /// gets executed, it acts sanely as well (eg. has the same result as
|
|
|
+ /// running stop() after - calls the callback).
|
|
|
+ ///
|
|
|
+ /// \param protocol Test protocol
|
|
|
+ /// \param fetch Fetch object being tested
|
|
|
+ void prematureStopTest(IOFetch::Protocol protocol, IOFetch& fetch) {
|
|
|
+ protocol_ = protocol;
|
|
|
+ expected_ = IOFetch::STOPPED;
|
|
|
+
|
|
|
+ // Stop before it is started
|
|
|
+ fetch.stop();
|
|
|
+ service_.get_io_service().post(fetch);
|
|
|
+
|
|
|
+ service_.run();
|
|
|
+ EXPECT_TRUE(run_);
|
|
|
+ }
|
|
|
|
|
|
- service_.run();
|
|
|
- EXPECT_TRUE(run_);
|
|
|
+ /// \brief Timeout test
|
|
|
+ ///
|
|
|
+ /// Test that fetch times out when no answer arrives.
|
|
|
+ ///
|
|
|
+ /// \param protocol Test protocol
|
|
|
+ /// \param fetch Fetch object being tested
|
|
|
+ void timeoutTest(IOFetch::Protocol protocol, IOFetch& fetch) {
|
|
|
+ protocol_ = protocol;
|
|
|
+ expected_ = IOFetch::TIME_OUT;
|
|
|
+
|
|
|
+ service_.get_io_service().post(fetch);
|
|
|
+ service_.run();
|
|
|
+ EXPECT_TRUE(run_);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+/// UDP Stop test - see IOFetchTest::stopTest() header.
|
|
|
+TEST_F(IOFetchTest, UdpStop) {
|
|
|
+ stopTest(IOFetch::UDP, udp_fetch_);
|
|
|
}
|
|
|
|
|
|
-// Test that it will timeout when no answer arrives.
|
|
|
-TEST_F(IOFetchTest, UdpTimeout) {
|
|
|
- expected_ = IOFetch::TIME_OUT;
|
|
|
+/// UDP premature stop test - see IOFetchTest::prematureStopTest() header.
|
|
|
+TEST_F(IOFetchTest, UdpPrematureStop) {
|
|
|
+ prematureStopTest(IOFetch::UDP, udp_fetch_);
|
|
|
+}
|
|
|
|
|
|
- service_.get_io_service().post(udp_fetch_);
|
|
|
- service_.run();
|
|
|
- EXPECT_TRUE(run_);
|
|
|
+/// UDP premature stop test - see IOFetchTest::timeoutTest() header.
|
|
|
+TEST_F(IOFetchTest, UdpTimeout) {
|
|
|
+ timeoutTest(IOFetch::UDP, udp_fetch_);
|
|
|
}
|
|
|
|
|
|
-// Test that it will succeed when we fake an answer and stores the same data we
|
|
|
-// send. This is done through a real socket on the loopback address.
|
|
|
-TEST_F(IOFetchTest, UdpReceive) {
|
|
|
+// UDP SendReceive test. Set up a UDP server then ports a UDP fetch object.
|
|
|
+// This will send question_ to the server and receive the answer back from it.
|
|
|
+TEST_F(IOFetchTest, UdpSendReceive) {
|
|
|
+ protocol_ = IOFetch::UDP;
|
|
|
expected_ = IOFetch::SUCCESS;
|
|
|
|
|
|
udp::socket socket(service_.get_io_service(), udp::v4());
|
|
@@ -174,15 +367,56 @@ TEST_F(IOFetchTest, UdpReceive) {
|
|
|
udp::endpoint remote;
|
|
|
socket.async_receive_from(asio::buffer(server_buff_, sizeof(server_buff_)),
|
|
|
remote,
|
|
|
- boost::bind(&IOFetchTest::respond, this, &remote, &socket, _1, _2));
|
|
|
+ boost::bind(&IOFetchTest::udpReceiveHandler, this, &remote, &socket,
|
|
|
+ _1, _2));
|
|
|
service_.get_io_service().post(udp_fetch_);
|
|
|
service_.run();
|
|
|
|
|
|
socket.close();
|
|
|
|
|
|
- EXPECT_TRUE(run_);
|
|
|
- ASSERT_EQ(sizeof TEST_DATA, buff_->getLength());
|
|
|
- EXPECT_EQ(0, memcmp(TEST_DATA, buff_->getData(), sizeof TEST_DATA));
|
|
|
+ EXPECT_TRUE(run_);;
|
|
|
+}
|
|
|
+
|
|
|
+// Do the same tests for TCP transport
|
|
|
+
|
|
|
+TEST_F(IOFetchTest, TcpStop) {
|
|
|
+ stopTest(IOFetch::TCP, tcp_fetch_);
|
|
|
+}
|
|
|
+
|
|
|
+TEST_F(IOFetchTest, TcpPrematureStop) {
|
|
|
+ prematureStopTest(IOFetch::TCP, tcp_fetch_);
|
|
|
+}
|
|
|
+
|
|
|
+TEST_F(IOFetchTest, TcpTimeout) {
|
|
|
+ timeoutTest(IOFetch::TCP, tcp_fetch_);
|
|
|
+}
|
|
|
+
|
|
|
+TEST_F(IOFetchTest, TcpSendReceive) {
|
|
|
+ protocol_ = IOFetch::TCP;
|
|
|
+ expected_ = IOFetch::SUCCESS;
|
|
|
+
|
|
|
+ std::cerr << "Creating socket\n";
|
|
|
+ // Socket into which the connection will be accepted
|
|
|
+ tcp::socket socket(service_.get_io_service());
|
|
|
+
|
|
|
+ std::cerr << "Creating acceptor\n";
|
|
|
+ // Acceptor object - called when the connection is made, the handler will
|
|
|
+ // initiate a read on the socket.
|
|
|
+ tcp::acceptor acceptor(service_.get_io_service(),
|
|
|
+ tcp::endpoint(tcp::v4(), TEST_PORT));
|
|
|
+ std::cerr << "Issuing async accept call\n";
|
|
|
+ acceptor.async_accept(socket,
|
|
|
+ boost::bind(&IOFetchTest::tcpAcceptHandler, this, &socket, _1));
|
|
|
+
|
|
|
+ // Post the TCP fetch object to send the query and receive the response.
|
|
|
+ std::cerr << "Posting TCP fetch\n";
|
|
|
+ service_.get_io_service().post(tcp_fetch_);
|
|
|
+
|
|
|
+ // ... and execute all the callbacks. This exits when the fetch completes.
|
|
|
+ service_.run();
|
|
|
+ EXPECT_TRUE(run_); // Make sure the callback did execute
|
|
|
+
|
|
|
+ socket.close();
|
|
|
}
|
|
|
|
|
|
} // namespace asiolink
|