dns_server_unittest.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  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 <config.h>
  15. #include <gtest/gtest.h>
  16. #include <asio.hpp>
  17. #include <asiolink/io_endpoint.h>
  18. #include <asiolink/io_error.h>
  19. #include <asiodns/udp_server.h>
  20. #include <asiodns/tcp_server.h>
  21. #include <asiodns/dns_answer.h>
  22. #include <asiodns/dns_lookup.h>
  23. #include <string>
  24. #include <cstring>
  25. #include <cerrno>
  26. #include <csignal>
  27. #include <unistd.h> //for alarm
  28. #include <boost/shared_ptr.hpp>
  29. #include <boost/bind.hpp>
  30. #include <boost/function.hpp>
  31. #include <sys/types.h>
  32. #include <sys/socket.h>
  33. /// The following tests focus on stop interface for udp and
  34. /// tcp server, there are lots of things can be shared to test
  35. /// both tcp and udp server, so they are in the same unittest
  36. /// The general work flow for dns server, is that wait for user
  37. /// query, once get one query, we will check the data is valid or
  38. /// not, if it passed, we will try to loop up the question, then
  39. /// compose the answer and finally send it back to user. The server
  40. /// may be stopped at any point during this porcess, so the test strategy
  41. /// is that we define 5 stop point and stop the server at these
  42. /// 5 points, to check whether stop is successful
  43. /// The 5 test points are :
  44. /// Before the server start to run
  45. /// After we get the query and check whether it's valid
  46. /// After we lookup the query
  47. /// After we compoisite the answer
  48. /// After user get the final result.
  49. /// The standard about whether we stop the server successfully or not
  50. /// is based on the fact that if the server is still running, the io
  51. /// service won't quit since it will wait for some asynchronized event for
  52. /// server. So if the io service block function run returns we assume
  53. /// that the server is stopped. To avoid stop interface failure which
  54. /// will block followed tests, using alarm signal to stop the blocking
  55. /// io service
  56. ///
  57. /// The whole test context including one server and one client, and
  58. /// five stop checkpoints, we call them ServerStopper exclude the first
  59. /// stop point. Once the unittest fired, the client will send message
  60. /// to server, and the stopper may stop the server at the checkpoint, then
  61. /// we check the client get feedback or not. Since there is no DNS logic
  62. /// involved so the message sending between client and server is plain text
  63. /// And the valid checker, question lookup and answer composition are dummy.
  64. using namespace isc::asiolink;
  65. using namespace isc::asiodns;
  66. using namespace asio;
  67. namespace {
  68. const char* const server_ip = "::1";
  69. const int server_port = 5553;
  70. const char* const server_port_str = "5553";
  71. //message client send to udp server, which isn't dns package
  72. //just for simple testing
  73. const char* const query_message = "BIND10 is awesome";
  74. // \brief provide capacity to derived class the ability
  75. // to stop DNSServer at certern point
  76. class ServerStopper {
  77. public:
  78. ServerStopper() : server_to_stop_(NULL) {}
  79. virtual ~ServerStopper(){}
  80. void setServerToStop(DNSServer* server) {
  81. server_to_stop_ = server;
  82. }
  83. void stopServer() const {
  84. if (server_to_stop_) {
  85. server_to_stop_->stop();
  86. }
  87. }
  88. private:
  89. DNSServer* server_to_stop_;
  90. };
  91. // \brief no check logic at all,just provide a checkpoint to stop the server
  92. class DummyChecker : public SimpleCallback, public ServerStopper {
  93. public:
  94. virtual void operator()(const IOMessage&) const {
  95. stopServer();
  96. }
  97. };
  98. // \brief no lookup logic at all,just provide a checkpoint to stop the server
  99. class DummyLookup : public DNSLookup, public ServerStopper {
  100. public:
  101. void operator()(const IOMessage& io_message,
  102. isc::dns::MessagePtr message,
  103. isc::dns::MessagePtr answer_message,
  104. isc::util::OutputBufferPtr buffer,
  105. DNSServer* server) const {
  106. stopServer();
  107. server->resume(true);
  108. }
  109. };
  110. // \brief copy the data received from user to the answer part
  111. // provide checkpoint to stop server
  112. class SimpleAnswer : public DNSAnswer, public ServerStopper {
  113. public:
  114. void operator()(const IOMessage& message,
  115. isc::dns::MessagePtr query_message,
  116. isc::dns::MessagePtr answer_message,
  117. isc::util::OutputBufferPtr buffer) const
  118. {
  119. //copy what we get from user
  120. buffer->writeData(message.getData(), message.getDataSize());
  121. stopServer();
  122. }
  123. };
  124. // \brief simple client, send one string to server and wait for response
  125. // in case, server stopped and client cann't get response, there is a timer wait
  126. // for specified seconds (the value is just a estimate since server process logic is quite
  127. // simple, and all the intercommunication is local) then cancel the waiting.
  128. class SimpleClient : public ServerStopper {
  129. public:
  130. static const size_t MAX_DATA_LEN = 256;
  131. SimpleClient(asio::io_service& service,
  132. unsigned int wait_server_time_out)
  133. {
  134. wait_for_response_timer_.reset(new deadline_timer(service));
  135. received_data_ = new char[MAX_DATA_LEN];
  136. received_data_len_ = 0;
  137. wait_server_time_out_ = wait_server_time_out;
  138. }
  139. virtual ~SimpleClient() {
  140. delete [] received_data_;
  141. }
  142. void setGetFeedbackCallback(boost::function<void()>& func) {
  143. get_response_call_back_ = func;
  144. }
  145. virtual void sendDataThenWaitForFeedback(const std::string& data) = 0;
  146. virtual std::string getReceivedData() const = 0;
  147. void startTimer() {
  148. wait_for_response_timer_->cancel();
  149. wait_for_response_timer_->
  150. expires_from_now(boost::posix_time::
  151. seconds(wait_server_time_out_));
  152. wait_for_response_timer_->
  153. async_wait(boost::bind(&SimpleClient::stopWaitingforResponse,
  154. this));
  155. }
  156. void cancelTimer() { wait_for_response_timer_->cancel(); }
  157. void getResponseCallBack(const asio::error_code& error, size_t
  158. received_bytes)
  159. {
  160. cancelTimer();
  161. if (!error)
  162. received_data_len_ = received_bytes;
  163. if (!get_response_call_back_.empty()) {
  164. get_response_call_back_();
  165. }
  166. stopServer();
  167. }
  168. protected:
  169. virtual void stopWaitingforResponse() = 0;
  170. boost::shared_ptr<deadline_timer> wait_for_response_timer_;
  171. char* received_data_;
  172. size_t received_data_len_;
  173. boost::function<void()> get_response_call_back_;
  174. unsigned int wait_server_time_out_;
  175. };
  176. class UDPClient : public SimpleClient {
  177. public:
  178. //After 1 second without feedback client will stop wait
  179. static const unsigned int server_time_out = 1;
  180. UDPClient(asio::io_service& service, const ip::udp::endpoint& server) :
  181. SimpleClient(service, server_time_out)
  182. {
  183. server_ = server;
  184. socket_.reset(new ip::udp::socket(service));
  185. socket_->open(ip::udp::v6());
  186. }
  187. void sendDataThenWaitForFeedback(const std::string& data) {
  188. received_data_len_ = 0;
  189. socket_->send_to(buffer(data.c_str(), data.size() + 1), server_);
  190. socket_->async_receive_from(buffer(received_data_, MAX_DATA_LEN),
  191. received_from_,
  192. boost::bind(&SimpleClient::
  193. getResponseCallBack, this, _1,
  194. _2));
  195. startTimer();
  196. }
  197. virtual std::string getReceivedData() const {
  198. return (received_data_len_ == 0 ? std::string("") :
  199. std::string(received_data_));
  200. }
  201. private:
  202. void stopWaitingforResponse() {
  203. socket_->close();
  204. }
  205. boost::shared_ptr<ip::udp::socket> socket_;
  206. ip::udp::endpoint server_;
  207. ip::udp::endpoint received_from_;
  208. };
  209. class TCPClient : public SimpleClient {
  210. public:
  211. // after 2 seconds without feedback client will stop wait,
  212. // this includes connect, send message and recevice message
  213. static const unsigned int server_time_out = 2;
  214. TCPClient(asio::io_service& service, const ip::tcp::endpoint& server)
  215. : SimpleClient(service, server_time_out)
  216. {
  217. server_ = server;
  218. socket_.reset(new ip::tcp::socket(service));
  219. socket_->open(ip::tcp::v6());
  220. }
  221. virtual void sendDataThenWaitForFeedback(const std::string &data) {
  222. received_data_len_ = 0;
  223. data_to_send_ = data;
  224. data_to_send_len_ = data.size() + 1;
  225. socket_->async_connect(server_, boost::bind(&TCPClient::connectHandler,
  226. this, _1));
  227. startTimer();
  228. }
  229. virtual std::string getReceivedData() const {
  230. return (received_data_len_ == 0 ? std::string("") :
  231. std::string(received_data_ + 2));
  232. }
  233. private:
  234. void stopWaitingforResponse() {
  235. socket_->close();
  236. }
  237. void connectHandler(const asio::error_code& error) {
  238. if (!error) {
  239. data_to_send_len_ = htons(data_to_send_len_);
  240. socket_->async_send(buffer(&data_to_send_len_, 2),
  241. boost::bind(&TCPClient::sendMessageBodyHandler,
  242. this, _1, _2));
  243. }
  244. }
  245. void sendMessageBodyHandler(const asio::error_code& error,
  246. size_t send_bytes)
  247. {
  248. if (!error && send_bytes == 2) {
  249. socket_->async_send(buffer(data_to_send_.c_str(),
  250. data_to_send_.size() + 1),
  251. boost::bind(&TCPClient::finishSendHandler, this, _1, _2));
  252. }
  253. }
  254. void finishSendHandler(const asio::error_code& error, size_t send_bytes) {
  255. if (!error && send_bytes == data_to_send_.size() + 1) {
  256. socket_->async_receive(buffer(received_data_, MAX_DATA_LEN),
  257. boost::bind(&SimpleClient::getResponseCallBack, this, _1,
  258. _2));
  259. }
  260. }
  261. boost::shared_ptr<ip::tcp::socket> socket_;
  262. ip::tcp::endpoint server_;
  263. std::string data_to_send_;
  264. uint16_t data_to_send_len_;
  265. };
  266. // \brief provide the context which including two clients and
  267. // two servers, UDP client will only communicate with UDP server, same for TCP
  268. // client
  269. //
  270. // This is only the active part of the test. We run the test case twice, once
  271. // for each type of initialization (once when giving it the address and port,
  272. // once when giving the file descriptor), to ensure it works both ways exactly
  273. // the same.
  274. class DNSServerTestBase : public::testing::Test {
  275. protected:
  276. DNSServerTestBase() :
  277. udp_server_(NULL),
  278. tcp_server_(NULL)
  279. { }
  280. void TearDown() {
  281. if (udp_server_) {
  282. udp_server_->stop();
  283. }
  284. if (tcp_server_) {
  285. tcp_server_->stop();
  286. }
  287. delete checker_;
  288. delete lookup_;
  289. delete answer_;
  290. delete udp_server_;
  291. delete udp_client_;
  292. delete tcp_server_;
  293. delete tcp_client_;
  294. }
  295. void testStopServerByStopper(DNSServer* server, SimpleClient* client,
  296. ServerStopper* stopper)
  297. {
  298. static const unsigned int io_service_time_out = 5;
  299. io_service_is_time_out = false;
  300. stopper->setServerToStop(server);
  301. (*server)();
  302. client->sendDataThenWaitForFeedback(query_message);
  303. // Since thread hasn't been introduced into the tool box, using
  304. // signal to make sure run function will eventually return even
  305. // server stop failed
  306. void (*prev_handler)(int) =
  307. std::signal(SIGALRM, DNSServerTestBase::stopIOService);
  308. alarm(io_service_time_out);
  309. service.run();
  310. service.reset();
  311. //cancel scheduled alarm
  312. alarm(0);
  313. std::signal(SIGALRM, prev_handler);
  314. }
  315. void commonSetup() {
  316. server_address_ = ip::address::from_string(server_ip);
  317. checker_ = new DummyChecker();
  318. lookup_ = new DummyLookup();
  319. answer_ = new SimpleAnswer();
  320. udp_client_ = new UDPClient(service,
  321. ip::udp::endpoint(server_address_,
  322. server_port));
  323. tcp_client_ = new TCPClient(service,
  324. ip::tcp::endpoint(server_address_,
  325. server_port));
  326. }
  327. static void stopIOService(int _no_use_parameter) {
  328. io_service_is_time_out = true;
  329. service.stop();
  330. }
  331. bool serverStopSucceed() const {
  332. return (!io_service_is_time_out);
  333. }
  334. DummyChecker* checker_;
  335. DummyLookup* lookup_;
  336. SimpleAnswer* answer_;
  337. UDPServer* udp_server_;
  338. UDPClient* udp_client_;
  339. TCPClient* tcp_client_;
  340. TCPServer* tcp_server_;
  341. ip::address server_address_;
  342. // To access them in signal handle function, the following
  343. // variables have to be static.
  344. static asio::io_service service;
  345. static bool io_service_is_time_out;
  346. };
  347. // Initialization with name and port
  348. class AddrPortInit : public DNSServerTestBase {
  349. protected:
  350. void SetUp() {
  351. commonSetup();
  352. udp_server_ = new UDPServer(service, server_address_, server_port,
  353. checker_, lookup_, answer_);
  354. tcp_server_ = new TCPServer(service, server_address_, server_port,
  355. checker_, lookup_, answer_);
  356. }
  357. };
  358. // Initialization by the file descriptor
  359. class FdInit : public DNSServerTestBase {
  360. private:
  361. // Opens the file descriptor for us
  362. // It uses the low-level C api, as it seems to be the easiest way to get
  363. // a raw file descriptor. It also is what the socket creator does and this
  364. // API is aimed to it.
  365. int getFd(int type) {
  366. struct addrinfo hints;
  367. memset(&hints, 0, sizeof(hints));
  368. hints.ai_family = AF_UNSPEC;
  369. hints.ai_socktype = type;
  370. hints.ai_protocol = (type == SOCK_STREAM) ? IPPROTO_TCP : IPPROTO_UDP;
  371. hints.ai_flags = AI_NUMERICSERV | AI_NUMERICHOST;
  372. struct addrinfo* res;
  373. const int error = getaddrinfo(server_ip, server_port_str,
  374. &hints, &res);
  375. if (error != 0) {
  376. freeaddrinfo(res);
  377. isc_throw(IOError, "getaddrinfo failed: " << gai_strerror(error));
  378. }
  379. int sock;
  380. int on(1);
  381. // Go as far as you can and stop on failure
  382. // Create the socket
  383. // set the options
  384. // and bind it
  385. bool failed((sock = socket(res->ai_family, res->ai_socktype,
  386. res->ai_protocol)) == -1 ||
  387. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
  388. sizeof on) == -1 ||
  389. bind(sock, res->ai_addr, res->ai_addrlen) == -1);
  390. // No matter if it succeeded or not, free the address info
  391. freeaddrinfo(res);
  392. if (failed) {
  393. if (sock != -1) {
  394. close(sock);
  395. }
  396. return (-1);
  397. } else {
  398. return (sock);
  399. }
  400. }
  401. protected:
  402. void SetUp() {
  403. commonSetup();
  404. int fdUDP(getFd(SOCK_DGRAM));
  405. ASSERT_NE(-1, fdUDP) << strerror(errno);
  406. udp_server_ = new UDPServer(service, fdUDP, AF_INET6, checker_,
  407. lookup_, answer_);
  408. int fdTCP(getFd(SOCK_STREAM));
  409. ASSERT_NE(-1, fdTCP) << strerror(errno);
  410. tcp_server_ = new TCPServer(service, fdTCP, AF_INET6, checker_,
  411. lookup_, answer_);
  412. }
  413. };
  414. // This makes it the template as gtest wants it.
  415. template<class Parent>
  416. class DNSServerTest : public Parent { };
  417. typedef ::testing::Types<AddrPortInit, FdInit> ServerTypes;
  418. TYPED_TEST_CASE(DNSServerTest, ServerTypes);
  419. bool DNSServerTestBase::io_service_is_time_out = false;
  420. asio::io_service DNSServerTestBase::service;
  421. // Test whether server stopped successfully after client get response
  422. // client will send query and start to wait for response, once client
  423. // get response, udp server will be stopped, the io service won't quit
  424. // if udp server doesn't stop successfully.
  425. TYPED_TEST(DNSServerTest, stopUDPServerAfterOneQuery) {
  426. this->testStopServerByStopper(this->udp_server_, this->udp_client_,
  427. this->udp_client_);
  428. EXPECT_EQ(query_message, this->udp_client_->getReceivedData());
  429. EXPECT_TRUE(this->serverStopSucceed());
  430. }
  431. // Test whether udp server stopped successfully before server start to serve
  432. TYPED_TEST(DNSServerTest, stopUDPServerBeforeItStartServing) {
  433. this->udp_server_->stop();
  434. this->testStopServerByStopper(this->udp_server_, this->udp_client_,
  435. this->udp_client_);
  436. EXPECT_EQ(std::string(""), this->udp_client_->getReceivedData());
  437. EXPECT_TRUE(this->serverStopSucceed());
  438. }
  439. // Test whether udp server stopped successfully during message check
  440. TYPED_TEST(DNSServerTest, stopUDPServerDuringMessageCheck) {
  441. this->testStopServerByStopper(this->udp_server_, this->udp_client_,
  442. this->checker_);
  443. EXPECT_EQ(std::string(""), this->udp_client_->getReceivedData());
  444. EXPECT_TRUE(this->serverStopSucceed());
  445. }
  446. // Test whether udp server stopped successfully during query lookup
  447. TYPED_TEST(DNSServerTest, stopUDPServerDuringQueryLookup) {
  448. this->testStopServerByStopper(this->udp_server_, this->udp_client_,
  449. this->lookup_);
  450. EXPECT_EQ(std::string(""), this->udp_client_->getReceivedData());
  451. EXPECT_TRUE(this->serverStopSucceed());
  452. }
  453. // Test whether udp server stopped successfully during composing answer
  454. TYPED_TEST(DNSServerTest, stopUDPServerDuringPrepareAnswer) {
  455. this->testStopServerByStopper(this->udp_server_, this->udp_client_,
  456. this->answer_);
  457. EXPECT_EQ(std::string(""), this->udp_client_->getReceivedData());
  458. EXPECT_TRUE(this->serverStopSucceed());
  459. }
  460. static void stopServerManyTimes(DNSServer *server, unsigned int times) {
  461. for (int i = 0; i < times; ++i) {
  462. server->stop();
  463. }
  464. }
  465. // Test whether udp server stop interface can be invoked several times without
  466. // throw any exception
  467. TYPED_TEST(DNSServerTest, stopUDPServeMoreThanOnce) {
  468. ASSERT_NO_THROW({
  469. boost::function<void()> stop_server_3_times
  470. = boost::bind(stopServerManyTimes, this->udp_server_, 3);
  471. this->udp_client_->setGetFeedbackCallback(stop_server_3_times);
  472. this->testStopServerByStopper(this->udp_server_,
  473. this->udp_client_, this->udp_client_);
  474. EXPECT_EQ(query_message, this->udp_client_->getReceivedData());
  475. });
  476. EXPECT_TRUE(this->serverStopSucceed());
  477. }
  478. TYPED_TEST(DNSServerTest, stopTCPServerAfterOneQuery) {
  479. this->testStopServerByStopper(this->tcp_server_, this->tcp_client_,
  480. this->tcp_client_);
  481. EXPECT_EQ(query_message, this->tcp_client_->getReceivedData());
  482. EXPECT_TRUE(this->serverStopSucceed());
  483. }
  484. // Test whether tcp server stopped successfully before server start to serve
  485. TYPED_TEST(DNSServerTest, stopTCPServerBeforeItStartServing) {
  486. this->tcp_server_->stop();
  487. this->testStopServerByStopper(this->tcp_server_, this->tcp_client_,
  488. this->tcp_client_);
  489. EXPECT_EQ(std::string(""), this->tcp_client_->getReceivedData());
  490. EXPECT_TRUE(this->serverStopSucceed());
  491. }
  492. // Test whether tcp server stopped successfully during message check
  493. TYPED_TEST(DNSServerTest, stopTCPServerDuringMessageCheck) {
  494. this->testStopServerByStopper(this->tcp_server_, this->tcp_client_,
  495. this->checker_);
  496. EXPECT_EQ(std::string(""), this->tcp_client_->getReceivedData());
  497. EXPECT_TRUE(this->serverStopSucceed());
  498. }
  499. // Test whether tcp server stopped successfully during query lookup
  500. TYPED_TEST(DNSServerTest, stopTCPServerDuringQueryLookup) {
  501. this->testStopServerByStopper(this->tcp_server_, this->tcp_client_,
  502. this->lookup_);
  503. EXPECT_EQ(std::string(""), this->tcp_client_->getReceivedData());
  504. EXPECT_TRUE(this->serverStopSucceed());
  505. }
  506. // Test whether tcp server stopped successfully during composing answer
  507. TYPED_TEST(DNSServerTest, stopTCPServerDuringPrepareAnswer) {
  508. this->testStopServerByStopper(this->tcp_server_, this->tcp_client_,
  509. this->answer_);
  510. EXPECT_EQ(std::string(""), this->tcp_client_->getReceivedData());
  511. EXPECT_TRUE(this->serverStopSucceed());
  512. }
  513. // Test whether tcp server stop interface can be invoked several times without
  514. // throw any exception
  515. TYPED_TEST(DNSServerTest, stopTCPServeMoreThanOnce) {
  516. ASSERT_NO_THROW({
  517. boost::function<void()> stop_server_3_times
  518. = boost::bind(stopServerManyTimes, this->tcp_server_, 3);
  519. this->tcp_client_->setGetFeedbackCallback(stop_server_3_times);
  520. this->testStopServerByStopper(this->tcp_server_, this->tcp_client_,
  521. this->tcp_client_);
  522. EXPECT_EQ(query_message, this->tcp_client_->getReceivedData());
  523. });
  524. EXPECT_TRUE(this->serverStopSucceed());
  525. }
  526. // It raises an exception when invalid address family is passed
  527. TEST_F(DNSServerTestBase, invalidFamily) {
  528. // We abuse DNSServerTestBase for this test, as we don't need the
  529. // initialization.
  530. commonSetup();
  531. EXPECT_THROW(UDPServer(service, 0, AF_UNIX, checker_, lookup_,
  532. answer_), isc::InvalidParameter);
  533. EXPECT_THROW(TCPServer(service, 0, AF_UNIX, checker_, lookup_,
  534. answer_), isc::InvalidParameter);
  535. }
  536. // It raises an exception when invalid address family is passed
  537. TEST_F(DNSServerTestBase, invalidFD) {
  538. // We abuse DNSServerTestBase for this test, as we don't need the
  539. // initialization.
  540. commonSetup();
  541. /*
  542. FIXME: The UDP server doesn't fail reliably with an invalid FD.
  543. We need to find a way to trigger it reliably (it seems epoll
  544. asio backend does fail as it tries to insert it right away, but
  545. not the others, maybe we could make it run this at last on epoll-based
  546. systems).
  547. EXPECT_THROW(UDPServer(service, -1, AF_INET, checker_, lookup_,
  548. answer_), isc::asiolink::IOError);
  549. */
  550. EXPECT_THROW(TCPServer(service, -1, AF_INET, checker_, lookup_,
  551. answer_), isc::asiolink::IOError);
  552. }
  553. }