completed partial IPv6 compatibility in DNS; does retrieve and Cache IPv6 IPs
[pingcheck] / test / test_dns.cpp
CommitLineData
26b0f687
CH
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
20
21#define BOOST_TEST_MAIN
22#define BOOST_TEST_DYN_LINK
23
24#include <algorithm>
25
26#include <boost/test/unit_test.hpp>
27#include <boost/asio/io_service.hpp>
28#include <boost/asio/ip/address.hpp>
8d26221d
CH
29#include <boost/bind.hpp>
30
31#include <logfunc.hpp>
8f00b3df 32#include <filefunc.hxx>
26b0f687
CH
33
34#include "host/pingprotocol.h"
35#include "dns/hostaddress.h"
8f00b3df 36#include "dns/dnsipprotocol.h"
26b0f687
CH
37#include "dns/dnsmaster.h"
38#include "dns/dnscache.h"
39#include "dns/resolverbase.h"
8d26221d
CH
40#include "dns/cname.h"
41
42using boost::asio::ip::address;
26b0f687 43
cd71d095
CH
44// constants for master
45address name_server = address::from_string("127.0.0.1");
46const int resolved_ip_ttl_threshold = 5; // this should be greater than...
47const uint32_t min_time_between_resolves = 3; // ... this!
48const int max_address_resolution_attempts = 2;
49const int max_recursion_count = 10;
50const std::string cache_file = DnsCache::DoNotUseCacheFile;
51
26b0f687 52//------------------------------------------------------------------------------
8d26221d 53// Global Test fixture (created once for test suite)
26b0f687
CH
54//------------------------------------------------------------------------------
55
8d26221d
CH
56// rely on boost that there will only be one instance
57struct GlobalFixture;
58GlobalFixture *global_fixture;
26b0f687 59
8d26221d
CH
60
61struct GlobalFixture
26b0f687 62{
8d26221d
CH
63
64 GlobalFixture()
65 : IoService()
66 , Cache()
67 , Master()
26b0f687 68 {
8d26221d
CH
69 BOOST_TEST_MESSAGE("Create global fixture");
70
71 // setup logging so we can see output from out code
72 I2n::Logger::enable_stderr_log( true );
4389b86d 73 I2n::Logger::set_log_level( I2n::Logger::LogLevel::Info );
8d26221d
CH
74 I2n::Logger::GlobalLogger.info() << "Logging enabled for DnsTest";
75
76 // IoService
77 IoServiceItem io_service_temp( new boost::asio::io_service() );
78 io_service_temp.swap( IoService );
79 io_service_temp.reset();
80
81 // DNS Cache
82 DnsCacheItem cache_temp = DnsCacheItem(
f833126b 83 new DnsCache(IoService, cache_file, min_time_between_resolves) );
8d26221d
CH
84 cache_temp.swap( Cache );
85 cache_temp.reset();
86 fill_cache();
87
88 // create master
89 DnsMaster::create_master(IoService,
26b0f687
CH
90 name_server,
91 resolved_ip_ttl_threshold,
92 max_address_resolution_attempts,
cd71d095 93 max_recursion_count,
8d26221d
CH
94 Cache);
95 Master = DnsMaster::get_instance();
96
97 // remember this instance, so we can later access all these variables
98 if (global_fixture == 0)
99 global_fixture = this;
26b0f687 100 }
8d26221d
CH
101
102 ~GlobalFixture()
103 {
104 BOOST_TEST_MESSAGE("Destructing global fixture");
105 IoService->stop();
106 IoService.reset();
107 Master.reset();
108 }
109
110 void fill_cache()
111 {
112 BOOST_TEST_MESSAGE( "Filling cache..." );
113 {
114 HostAddress ip(address::from_string("192.168.42.1"), 61);
115 HostAddressVec ips;
116 ips.push_back(ip);
8f00b3df 117 Cache->update("host1.test", DNS_IPv4, ips);
8d26221d
CH
118 }
119
120 {
121 HostAddress ip1(address::from_string("192.168.42.2"), 92);
122 HostAddress ip2(address::from_string("192.168.42.3"), 93);
123 HostAddressVec ips;
124 ips.push_back(ip1);
125 ips.push_back(ip2);
8f00b3df 126 Cache->update("host2_3.test", DNS_IPv4, ips);
8d26221d
CH
127 }
128
00c81aa0
CH
129 {
130 // cname.test --> host1.test
131 Cache->update("cname.test", Cname("host1.test", 35) );
8d26221d 132
00c81aa0
CH
133 // cname2.test --> cname.test --> host1.test
134 Cache->update("cname2.test", Cname("cname.test", 33) );
9d1b2726 135
00c81aa0
CH
136 // cname3.test --> cname2.test --> cname.test --> host1.test
137 Cache->update("cname3.test", Cname("cname2.test", 37) );
138 }
139
f833126b 140 { // for cache_outdated_test
00c81aa0
CH
141 HostAddressVec ips;
142 ips.push_back( HostAddress( address::from_string("192.168.42.4"),
143 0 ) );
144 ips.push_back( HostAddress( address::from_string("192.168.42.5"),
145 resolved_ip_ttl_threshold-1 ) );
146 ips.push_back( HostAddress( address::from_string("192.168.42.6"),
147 resolved_ip_ttl_threshold ) );
148 ips.push_back( HostAddress( address::from_string("192.168.42.7"),
149 resolved_ip_ttl_threshold+1 ) );
8f00b3df 150 Cache->update("host_outdated.test", DNS_IPv4, ips);
00c81aa0
CH
151
152 Cache->update( "cname_outdated.test",
153 Cname("host_outdated.test", resolved_ip_ttl_threshold) );
154 Cache->update( "cname_up_to_date.test",
155 Cname("host_outdated.test", resolved_ip_ttl_threshold+1));
156 }
8d26221d 157
f833126b
CH
158 { // for cache_ttl_below_thresh_test
159 // TTLs < min_time_between_resolves should be corrected
160 HostAddressVec ips;
161 ips.push_back( HostAddress( address::from_string("192.128.42.8"),
162 1 ) );
8f00b3df 163 Cache->update("host_ttl_below_thresh.test", DNS_IPv4, ips);
f833126b
CH
164
165 Cache->update( "cname_ttl_below_thresh.test",
166 Cname("host_ttl_below_thresh.test", 2) );
167 }
168
cd71d095
CH
169 { // create a CNAME loop cname_loop1.test --> cname_loop2.test
170 // --> cname_loop3.test --> cname_loop1.test
171 Cache->update( "cname_loop1.test", Cname("cname_loop2.test", 60) );
172 Cache->update( "cname_loop2.test", Cname("cname_loop3.test", 60) );
173 Cache->update( "cname_loop3.test", Cname("cname_loop1.test", 60) );
174 }
175
8f00b3df
CH
176 { // create IPv4 and IPv6 for same host
177 HostAddressVec ips;
178 ips.push_back( HostAddress( address::from_string("192.168.42.8"),
179 432 ) );
180 Cache->update("host_v4_and_v6.test", DNS_IPv4, ips);
181 ips.clear();
182 ips.push_back( HostAddress(
183 address::from_string("2a00:1450:4001:808::1004"),
184 543 ) );
185 Cache->update("host_v4_and_v6.test", DNS_IPv6, ips);
186 }
187
8d26221d
CH
188 BOOST_TEST_MESSAGE( "Done filling cache." );
189 }
190
191 // these variables will not be available in test cases:
192 IoServiceItem IoService;
193 DnsCacheItem Cache;
194 DnsMasterItem Master;
195};
196
197// this causes above fixture to be created only once before tests start and
198// destructed after tests end; however, variables are not accessible in test
199// cases
200BOOST_GLOBAL_FIXTURE( GlobalFixture )
201
202
203// using this as suite-level fixture makes variable Master accessible in all
204// test cases
205struct TestFixture
206{
207 IoServiceItem IoService;
208 DnsCacheItem Cache;
209 DnsMasterItem Master;
210
211 TestFixture()
212 : IoService()
213 , Cache()
214 , Master()
215 {
216 BOOST_TEST_MESSAGE("Create test-level fixture");
217 GlobalFixture *global = global_fixture;
218 IoService = global->IoService;
219 Cache = global->Cache;
220 Master = global->Master;
221 }
222
223 virtual ~TestFixture() {}
224};
26b0f687
CH
225
226//------------------------------------------------------------------------------
227// test suite
228//------------------------------------------------------------------------------
229
8d26221d 230BOOST_FIXTURE_TEST_SUITE( TestDns, TestFixture )
26b0f687
CH
231
232BOOST_AUTO_TEST_CASE( create_master )
233{
8d26221d
CH
234 // simple checks
235 BOOST_CHECK_EQUAL( Master->get_resolved_ip_ttl_threshold(),
236 resolved_ip_ttl_threshold );
237 BOOST_CHECK_EQUAL( Master->get_max_address_resolution_attempts(),
238 max_address_resolution_attempts );
26b0f687
CH
239}
240
8d26221d
CH
241//------------------------------------------------------------------------------
242// test Cache
243//------------------------------------------------------------------------------
244BOOST_FIXTURE_TEST_SUITE( TestDnsCache, TestFixture )
245
246BOOST_AUTO_TEST_CASE( cache_retrieve_ip1 )
26b0f687 247{
8f00b3df 248 HostAddressVec ips = Cache->get_ips("host1.test", DNS_IPv4);
f833126b 249 BOOST_REQUIRE_EQUAL( ips.size(), 1 );
8d26221d 250 HostAddress ip = ips.front();
4389b86d 251 BOOST_CHECK( ip.is_valid() );
8d26221d
CH
252 BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.1" );
253 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 61 );
254}
255
256
257BOOST_AUTO_TEST_CASE( cache_retrieve_ip2 )
258{
8f00b3df 259 HostAddressVec ips = Cache->get_ips("host2_3.test", DNS_IPv4);
8d26221d
CH
260 BOOST_CHECK_EQUAL( ips.size(), 2 );
261 HostAddress ip = ips[0];
4389b86d 262 BOOST_CHECK( ip.is_valid() );
8d26221d
CH
263 BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.2" );
264 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 92 );
265 ip = ips[1];
4389b86d 266 BOOST_CHECK( ip.is_valid() );
8d26221d
CH
267 BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.3" );
268 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 93 );
269}
26b0f687 270
8d26221d
CH
271BOOST_AUTO_TEST_CASE( cache_retrieve_cname )
272{
8f00b3df 273 HostAddressVec ips = Cache->get_ips("cname.test", DNS_IPv4);
8d26221d
CH
274 BOOST_CHECK( ips.empty() );
275
276 Cname cname = Cache->get_cname("cname.test");
277 BOOST_CHECK_EQUAL( cname.Host, "host1.test" );
278 BOOST_CHECK_EQUAL( cname.Ttl.get_value(), 35 );
279}
280
281BOOST_AUTO_TEST_CASE( cache_retrieve_recursive1 )
282{
283 // should get IP from host1 but ttl from cname since is smaller
8f00b3df 284 HostAddressVec ips = Cache->get_ips_recursive("cname.test", DNS_IPv4);
f833126b 285 BOOST_REQUIRE_EQUAL( ips.size(), 1 );
8d26221d 286 HostAddress ip = ips.front();
4389b86d 287 BOOST_CHECK( ip.is_valid() );
8d26221d
CH
288 BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.1" );
289 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 35 );
290}
291
292BOOST_AUTO_TEST_CASE( cache_retrieve_recursive2 )
293{
294 // should get IP from host1 but ttl from cname2 since is smaller
8f00b3df 295 HostAddressVec ips = Cache->get_ips_recursive("cname3.test", DNS_IPv4);
f833126b 296 BOOST_REQUIRE_EQUAL( ips.size(), 1 );
8d26221d 297 HostAddress ip = ips.front();
4389b86d 298 BOOST_CHECK( ip.is_valid() );
8d26221d
CH
299 BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.1" );
300 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 33 );
301}
302
9d1b2726
CH
303void cname_skip_test(const uint32_t ttl1, const uint32_t ttl2,
304 const uint32_t ttl3, const uint32_t ttl4,
305 const DnsCacheItem &cache,
306 const std::string &correct_host_after_skip)
8d26221d 307{
9d1b2726
CH
308 { // create cname chain:
309 // skip_chain_first -(ttl1)-> skip_chain_second -(ttl2)->
310 // skip_chain_third -(ttl3)-> skip_chain_fourth -(ttl4)-> IPs
311 cache->update( "skip_chain_first.test",
312 Cname("skip_chain_second.test", ttl1) );
313 cache->update( "skip_chain_second.test",
314 Cname("skip_chain_third.test", ttl2) );
315 cache->update( "skip_chain_third.test",
316 Cname("skip_chain_fourth.test", ttl3) );
8d26221d 317 HostAddressVec ips;
00c81aa0
CH
318 ips.push_back( HostAddress( address::from_string("192.168.42.100"),
319 ttl4 ) );
8f00b3df 320 cache->update("skip_chain_fourth.test", DNS_IPv4, ips);
8d26221d
CH
321 }
322
9d1b2726 323 // normal recursive call should give nothing since one cname is outdated
8d26221d 324 bool check_up_to_date = true;
9d1b2726 325 HostAddressVec ips = cache->get_ips_recursive("skip_chain_first.test",
8f00b3df 326 DNS_IPv4,
8d26221d 327 check_up_to_date);
9d1b2726
CH
328 bool one_is_out_of_date = (ttl1 < 5) || (ttl2 < 5)
329 || (ttl3 < 5) || (ttl4 < 5);
330 BOOST_CHECK_EQUAL( ips.empty(), one_is_out_of_date );
8d26221d 331
9d1b2726
CH
332 // now find host to resolve after the outdated one
333 std::string first_outdated = cache->get_first_outdated_cname(
8d26221d 334 "skip_chain_first.test", 5);
9d1b2726
CH
335 BOOST_CHECK_EQUAL( first_outdated, correct_host_after_skip );
336}
337
338BOOST_AUTO_TEST_CASE( cache_skip_tests )
339{
340 // build a cname chain where first one is out of date
341 cname_skip_test(0, 120, 120, 60, Cache, "skip_chain_second.test");
342
343 // build a cname chain where second one is out of date
344 cname_skip_test(120, 0, 120, 60, Cache, "skip_chain_third.test");
345
346 // build a cname chain where third one is out of date
347 cname_skip_test(120, 120, 0, 120, Cache, "skip_chain_fourth.test");
348
349 // build a cname chain where just IPs are out of date
350 cname_skip_test(120, 120, 120, 0, Cache, "");
351
352 // build a cname chain where all are out of date
353 cname_skip_test(0, 0, 0, 0, Cache, "skip_chain_second.test");
354
355 // build a cname chain where all is up to date
356 cname_skip_test(120, 120, 120, 120, Cache, "");
357
358 // test case with very short cname list that is up-to-date
359 BOOST_CHECK_EQUAL( Cache->get_first_outdated_cname("cname.test", 5), "" );
360
361 // test case where there is no cname at all
362 BOOST_CHECK_EQUAL( Cache->get_first_outdated_cname("host1.test", 5), "" );
8d26221d
CH
363}
364
8f00b3df
CH
365
366void create_cache(const std::string &file_name, IoServiceItem io_serv)
4389b86d 367{
8f00b3df
CH
368 BOOST_TEST_MESSAGE( "creating cache for file " << file_name );
369 if ( I2n::file_exists(file_name) )
370 BOOST_CHECK( I2n::unlink(file_name) ); // try to remove
371 DnsCache save_cache( io_serv, file_name, min_time_between_resolves );
372
373 HostAddressVec ips;
374 ips.push_back( HostAddress(address::from_string("11.22.33.44"), 567) );
375 save_cache.update("abc.xyz", DNS_IPv4, ips);
376
377 save_cache.update("cname1.xyz", Cname("abc.xyz", 27));
378
379 // is saved when destructed
380}
381
382
383void test_cache(const std::string &file_name, IoServiceItem io_serv)
384{
385 BOOST_TEST_MESSAGE( "loading cache from file " << file_name );
386 DnsCache loaded_cache( io_serv,
387 file_name,
f833126b 388 min_time_between_resolves );
8f00b3df
CH
389 HostAddressVec ips = loaded_cache.get_ips("abc.xyz", DNS_IPv4);
390 BOOST_CHECK_EQUAL( ips.size(), 1 );
391 if (ips.size() == 1)
392 {
393 HostAddress ip = ips.front();
394 BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "11.22.33.44" );
395 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 567 );
396 //BOOST_CHECK_EQUAL( ip.get_ttl().get_updated_value(), 0 );
397 }
4389b86d
CH
398
399 Cname cname = loaded_cache.get_cname("cname1.xyz");
400 BOOST_CHECK_EQUAL( cname.Host, "abc.xyz" );
401 BOOST_CHECK_EQUAL( cname.Ttl.get_value(), 27 );
8f00b3df 402 //BOOST_CHECK_EQUAL( cname.Ttl.get_updated_value(), 0 );
4389b86d
CH
403
404 // not testing Ttl set time since is private
405}
406
8f00b3df
CH
407
408BOOST_AUTO_TEST_CASE( cache_save_and_load_test )
409{
410 std::stringstream file_name_temp;
411 file_name_temp << DATA_DIR_STRING << "/" << "dns_cache_save_load_test.xml";
412 std::string file_name = file_name_temp.str();
413
414 // create and save
415 create_cache( file_name, IoService );
416
417 // now load and test
418 test_cache( file_name, IoService );
419
420}
421
422BOOST_AUTO_TEST_CASE( cache_load_compatibility_test )
423{
424 std::stringstream file_name;
425 file_name << DATA_DIR_STRING << "/" << "dns_cache_compatibility_test.xml";
426 test_cache( file_name.str(), IoService );
427
428 // If this test fails because the cache structure was changed,
429 // you can overwrite the dns_cache_compatibility_test.xml by uncommenting
430 // the following code line.
431 //create_cache( file_name.str(), IoService );
432 //
433 // Run test again with arg --log_level=MESSAGE and look out for message
434 // "create cache for file [...]dns_cache_compatibility_test.xml"
435 // You should then copy the dns_cache_compatibility_test.xml to test/data
436 // in git and commit together with the new cache structure code
437}
438
00c81aa0
CH
439BOOST_AUTO_TEST_CASE( cache_outdated_test )
440{
441 bool check_up_to_date = false;
8f00b3df
CH
442 HostAddressVec ips = Cache->get_ips("host_outdated.test", DNS_IPv4,
443 check_up_to_date);
00c81aa0 444 BOOST_CHECK_EQUAL( ips.size(), 4 );
8f00b3df
CH
445 ips = Cache->get_ips_recursive("host_outdated.test", DNS_IPv4,
446 check_up_to_date);
00c81aa0
CH
447 BOOST_CHECK_EQUAL( ips.size(), 4 );
448 Cname cname = Cache->get_cname("cname_outdated.test", check_up_to_date);
449 BOOST_CHECK( !cname.Host.empty() );
8f00b3df
CH
450 ips = Cache->get_ips_recursive("cname_outdated.test", DNS_IPv4,
451 check_up_to_date);
00c81aa0 452 BOOST_CHECK_EQUAL( ips.size(), 4 );
8f00b3df
CH
453 ips = Cache->get_ips_recursive("cname_up_to_date.test", DNS_IPv4,
454 check_up_to_date);
00c81aa0
CH
455 BOOST_CHECK_EQUAL( ips.size(), 4 );
456
457 check_up_to_date = true;
8f00b3df 458 ips = Cache->get_ips( "host_outdated.test", DNS_IPv4, check_up_to_date );
00c81aa0 459 BOOST_CHECK_EQUAL( ips.size(), 1 );
8f00b3df
CH
460 ips = Cache->get_ips_recursive("host_outdated.test", DNS_IPv4,
461 check_up_to_date);
00c81aa0
CH
462 BOOST_CHECK_EQUAL( ips.size(), 1 );
463 cname = Cache->get_cname("cname_outdated.test", check_up_to_date);
464 BOOST_CHECK( cname.Host.empty() );
8f00b3df
CH
465 ips = Cache->get_ips_recursive("cname_outdated.test", DNS_IPv4,
466 check_up_to_date);
00c81aa0 467 BOOST_CHECK_EQUAL( ips.size(), 0 );
8f00b3df
CH
468 ips = Cache->get_ips_recursive("cname_up_to_date.test", DNS_IPv4,
469 check_up_to_date);
00c81aa0
CH
470 BOOST_CHECK_EQUAL( ips.size(), 1 );
471}
472
f833126b
CH
473BOOST_AUTO_TEST_CASE( cache_ttl_below_thresh_test )
474{
8f00b3df
CH
475 HostAddressVec ips = Cache->get_ips("host_ttl_below_thresh.test", DNS_IPv4,
476 false);
f833126b
CH
477 BOOST_REQUIRE_EQUAL( ips.size(), 1 );
478 HostAddress ip = ips.front();
479 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), min_time_between_resolves );
00c81aa0 480
f833126b
CH
481 Cname cname = Cache->get_cname("cname_ttl_below_thresh.test", false);
482 BOOST_CHECK_EQUAL( cname.Ttl.get_value(), min_time_between_resolves );
483}
8d26221d 484
cd71d095
CH
485BOOST_AUTO_TEST_CASE( cache_retrieve_loop )
486{
8f00b3df
CH
487 BOOST_CHECK_EQUAL(
488 Cache->get_ips_recursive("cname_loop1.test", DNS_IPv4).size(), 0 );
489 BOOST_CHECK_EQUAL(
490 Cache->get_ips_recursive("cname_loop2.test", DNS_IPv4).size(), 0 );
491 BOOST_CHECK_EQUAL(
492 Cache->get_ips_recursive("cname_loop3.test", DNS_IPv4).size(), 0 );
493}
494
495
496BOOST_AUTO_TEST_CASE( cache_IPv6 )
497{
498 HostAddressVec ips = Cache->get_ips("host_v4_and_v6.test", DNS_IPv4);
499 BOOST_REQUIRE_EQUAL( ips.size(), 1 );
500 HostAddress ip = ips.front();
501 BOOST_CHECK( ip.is_valid() );
502 BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "192.168.42.8" );
503 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 432 );
504
505 ips = Cache->get_ips("host_v4_and_v6.test", DNS_IPv6);
506 BOOST_REQUIRE_EQUAL( ips.size(), 1 );
507 ip = ips.front();
508 BOOST_CHECK( ip.is_valid() );
509 BOOST_CHECK_EQUAL( ip.get_ip().to_string(), "2a00:1450:4001:808::1004" );
510 BOOST_CHECK_EQUAL( ip.get_ttl().get_value(), 543 );
cd71d095
CH
511}
512
513
8d26221d
CH
514BOOST_AUTO_TEST_SUITE_END() // of TestDnsCache
515
516
517// -----------------------------------------------------------------------------
518// test resolver
519// -----------------------------------------------------------------------------
520
521BOOST_FIXTURE_TEST_SUITE( TestDnsResolver, TestFixture )
522
8d26221d
CH
523BOOST_AUTO_TEST_CASE( create_resolver_v4 )
524{
26b0f687
CH
525 // create resolver
526 std::string hostname = "www.intra2net.com";
8d26221d
CH
527 ResolverItem resolver = Master->get_resolver_for(hostname,
528 PingProtocol_ICMP);
26b0f687
CH
529 BOOST_CHECK_EQUAL( resolver->get_hostname(), hostname );
530 BOOST_CHECK( !resolver->is_resolving() );
4389b86d 531 BOOST_CHECK( !resolver->is_waiting_to_resolve() );
26b0f687
CH
532
533 // cancel should have no effect
534 resolver->cancel_resolve();
535 BOOST_CHECK( !resolver->is_resolving() );
4389b86d 536 BOOST_CHECK( !resolver->is_waiting_to_resolve() );
26b0f687
CH
537
538 // should not have any ips since cache did not load anything
539 BOOST_CHECK_EQUAL( resolver->get_resolved_ip_count(), 0 );
540 BOOST_CHECK( !resolver->have_up_to_date_ip() );
541 std::string no_ip = "0.0.0.0";
542 BOOST_CHECK_EQUAL( resolver->get_next_ip().get_ip().to_string(), no_ip );
543}
544
8d26221d 545
cd71d095 546struct ResolveCallback
8d26221d 547{
cd71d095
CH
548public:
549 IoServiceItem IoService;
550 ResolverItem Resolver;
551 int CallCount;
552 bool LastCallWasSuccess;
553 int LastCallRecursionCount;
554
555 ResolveCallback(IoServiceItem &io_serv, ResolverItem &resolver)
556 : IoService(io_serv)
557 , Resolver(resolver)
558 , CallCount(0)
559 , LastCallWasSuccess(true)
560 , LastCallRecursionCount(-10)
561 {}
562
563 void call(const bool was_success, const int recursion_count)
564 {
565 BOOST_TEST_MESSAGE( "Callback called" );
566 ++CallCount;
8d26221d 567
cd71d095
CH
568 Resolver->cancel_resolve();
569 IoService->stop();
570
571 LastCallWasSuccess = was_success;
572 LastCallRecursionCount = recursion_count;
573 }
574};
8d26221d
CH
575
576BOOST_AUTO_TEST_CASE( do_resolve )
577{
578 // create resolver
579 std::string hostname = "www.intra2net.com";
580 ResolverItem resolver = Master->get_resolver_for(hostname,
581 PingProtocol_ICMP);
4389b86d
CH
582 BOOST_CHECK( !resolver->is_resolving() );
583 BOOST_CHECK( !resolver->is_waiting_to_resolve() );
8d26221d
CH
584
585 // set callback
cd71d095
CH
586 ResolveCallback *callback_obj = new ResolveCallback(IoService, resolver);
587 // have to manually delete this obj in the end!
588 callback_type callback = boost::bind( &ResolveCallback::call, callback_obj,
8d26221d 589 _1, _2 );
cd71d095 590
8d26221d
CH
591 // start resolving
592 resolver->async_resolve(callback);
4389b86d 593 BOOST_CHECK( resolver->is_resolving() );
8d26221d
CH
594 IoService->run();
595 // this will block until io service is stopped in resolve_callback
cd71d095
CH
596 BOOST_TEST_MESSAGE( "Back to synchronous operation" );
597 IoService->reset();
8d26221d
CH
598
599 // check for result
cd71d095
CH
600 BOOST_CHECK_EQUAL( callback_obj->CallCount, 1 );
601 BOOST_CHECK( callback_obj->LastCallWasSuccess );
602 BOOST_CHECK_EQUAL( callback_obj->LastCallRecursionCount, 0 );
8d26221d 603 BOOST_CHECK( resolver->have_up_to_date_ip() );
cd71d095
CH
604
605 delete callback_obj;
8d26221d
CH
606}
607
608BOOST_AUTO_TEST_SUITE_END() // of TestDnsResolver
609
26b0f687 610BOOST_AUTO_TEST_SUITE_END()