udpdns_unittest.cc 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright (C) 2010 CZ.NIC
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <gtest/gtest.h>
  15. #include <asio.hpp>
  16. #include <boost/bind.hpp>
  17. #include <cstdlib>
  18. #include <dns/question.h>
  19. #include <asiolink/internal/udpdns.h>
  20. using namespace asio;
  21. using namespace isc::dns;
  22. using asio::ip::udp;
  23. namespace {
  24. const asio::ip::address TEST_HOST(asio::ip::address::from_string("127.0.0.1"));
  25. const uint16_t TEST_PORT(5301);
  26. // FIXME Shouldn't we send something that is real message?
  27. const char TEST_DATA[] = "TEST DATA";
  28. class UDPQueryTest : public ::testing::Test,
  29. public asiolink::UDPQuery::Callback
  30. {
  31. public:
  32. asiolink::UDPQuery::Result expected;
  33. bool run;
  34. io_service service;
  35. Question question;
  36. // To keep a reference so noone calls delete this;
  37. OutputBufferPtr buffer;
  38. asiolink::UDPQuery query;
  39. UDPQueryTest() :
  40. run(false),
  41. question(Name("example.net"), RRClass::IN(), RRType::A()),
  42. buffer(new OutputBuffer(512)),
  43. query(service, question, asiolink::IOAddress(TEST_HOST), TEST_PORT,
  44. buffer, this, 100)
  45. { }
  46. void operator()(asiolink::UDPQuery::Result result) {
  47. EXPECT_EQ(expected, result);
  48. run = true;
  49. }
  50. void respond(udp::endpoint* remote, udp::socket* socket) {
  51. // Some data came, just send something back.
  52. socket->send_to(asio::buffer(TEST_DATA, sizeof TEST_DATA),
  53. *remote);
  54. socket->close();
  55. }
  56. };
  57. TEST_F(UDPQueryTest, stop) {
  58. expected = asiolink::UDPQuery::STOPPED;
  59. service.post(query);
  60. // Make sure stop is called after executing () of the query
  61. // Why doesn't boost::bind support default parameters?
  62. service.post(boost::bind(&asiolink::UDPQuery::stop, query,
  63. asiolink::UDPQuery::STOPPED));
  64. service.run();
  65. EXPECT_TRUE(run);
  66. }
  67. TEST_F(UDPQueryTest, prematureStop) {
  68. expected = asiolink::UDPQuery::STOPPED;
  69. // Stop before it is started
  70. query.stop();
  71. service.post(query);
  72. service.run();
  73. EXPECT_TRUE(run);
  74. }
  75. TEST_F(UDPQueryTest, timeout) {
  76. expected = asiolink::UDPQuery::TIME_OUT;
  77. service.post(query);
  78. service.run();
  79. EXPECT_TRUE(run);
  80. }
  81. TEST_F(UDPQueryTest, receive) {
  82. expected = asiolink::UDPQuery::SUCCESS;
  83. udp::socket socket(service, udp::v4());
  84. socket.set_option(socket_base::reuse_address(true));
  85. socket.bind(udp::endpoint(TEST_HOST, TEST_PORT));
  86. char inbuff[512];
  87. udp::endpoint remote;
  88. socket.async_receive_from(asio::buffer(inbuff, 512), remote, boost::bind(
  89. &UDPQueryTest::respond, this, &remote, &socket));
  90. service.post(query);
  91. service.run();
  92. EXPECT_TRUE(run);
  93. ASSERT_EQ(sizeof TEST_DATA, buffer->getLength());
  94. EXPECT_EQ(0, memcmp(TEST_DATA, buffer->getData(), sizeof TEST_DATA));
  95. }
  96. }