Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: net/dns/mdns_client_unittest.cc

Issue 937743003: Fix MDnsClient's cache entry cleanup logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add unit tests; miscellaneous lint fixes Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« net/dns/mdns_client_impl.cc ('K') | « net/dns/mdns_client_impl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <queue> 5 #include <queue>
6 6
7 #include "base/memory/ref_counted.h" 7 #include "base/memory/ref_counted.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/time/clock.h"
10 #include "base/time/default_clock.h"
11 #include "base/timer/mock_timer.h"
9 #include "net/base/rand_callback.h" 12 #include "net/base/rand_callback.h"
10 #include "net/base/test_completion_callback.h" 13 #include "net/base/test_completion_callback.h"
11 #include "net/dns/mdns_client_impl.h" 14 #include "net/dns/mdns_client_impl.h"
12 #include "net/dns/mock_mdns_socket_factory.h" 15 #include "net/dns/mock_mdns_socket_factory.h"
13 #include "net/dns/record_rdata.h" 16 #include "net/dns/record_rdata.h"
14 #include "net/udp/udp_client_socket.h" 17 #include "net/udp/udp_client_socket.h"
15 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
17 20
18 using ::testing::Invoke; 21 using ::testing::Invoke;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 0xc0, 0x14, // Pointer to "._tcp.local" 218 0xc0, 0x14, // Pointer to "._tcp.local"
216 0x00, 0x0c, // TYPE is PTR. 219 0x00, 0x0c, // TYPE is PTR.
217 0x00, 0x01, // CLASS is IN. 220 0x00, 0x01, // CLASS is IN.
218 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. 221 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
219 0x24, 0x74, 222 0x24, 0x74,
220 0x00, 0x08, // RDLENGTH is 8 bytes. 223 0x00, 0x08, // RDLENGTH is 8 bytes.
221 0x05, 'z', 'z', 'z', 'z', 'z', 224 0x05, 'z', 'z', 'z', 'z', 'z',
222 0xc0, 0x32 225 0xc0, 0x32
223 }; 226 };
224 227
228 const uint8 kSamplePacket3[] = {
229 // Header
230 0x00, 0x00, // ID is zeroed out
231 0x81, 0x80, // Standard query response, RA, no error
232 0x00, 0x00, // No questions (for simplicity)
233 0x00, 0x02, // 2 RRs (answers)
234 0x00, 0x00, // 0 authority RRs
235 0x00, 0x00, // 0 additional RRs
236
237 // Answer 1
238 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
239 0x04, '_', 't', 'c', 'p', 0x05, 'l', 'o',
240 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
241 0x00, 0x01, // CLASS is IN.
242 0x00, 0x00, // TTL (4 bytes) is 1 second;
243 0x00, 0x01, 0x00, 0x08, // RDLENGTH is 8 bytes.
244 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
245
246 // Answer 2
247 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e',
248 'r', 0xc0, 0x14, // Pointer to "._tcp.local"
249 0x00, 0x0c, // TYPE is PTR.
250 0x00, 0x01, // CLASS is IN.
251 0x00, 0x00, // TTL (4 bytes) is 3 seconds.
252 0x00, 0x03, 0x00, 0x08, // RDLENGTH is 8 bytes.
253 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x32
254 };
255
225 const uint8 kQueryPacketPrivet[] = { 256 const uint8 kQueryPacketPrivet[] = {
226 // Header 257 // Header
227 0x00, 0x00, // ID is zeroed out 258 0x00, 0x00, // ID is zeroed out
228 0x00, 0x00, // No flags. 259 0x00, 0x00, // No flags.
229 0x00, 0x01, // One question. 260 0x00, 0x01, // One question.
230 0x00, 0x00, // 0 RRs (answers) 261 0x00, 0x00, // 0 RRs (answers)
231 0x00, 0x00, // 0 authority RRs 262 0x00, 0x00, // 0 authority RRs
232 0x00, 0x00, // 0 additional RRs 263 0x00, 0x00, // 0 additional RRs
233 264
234 // Question 265 // Question
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 const std::string& ptrdomain() { return ptrdomain_; } 413 const std::string& ptrdomain() { return ptrdomain_; }
383 int ttl() { return ttl_; } 414 int ttl() { return ttl_; }
384 415
385 private: 416 private:
386 bool set_; 417 bool set_;
387 std::string name_; 418 std::string name_;
388 std::string ptrdomain_; 419 std::string ptrdomain_;
389 int ttl_; 420 int ttl_;
390 }; 421 };
391 422
423 class MockClock : public base::DefaultClock {
424 public:
425 MockClock() : base::DefaultClock() {}
426 virtual ~MockClock() {}
427
428 MOCK_METHOD0(Now, base::Time());
429
430 private:
431 DISALLOW_COPY_AND_ASSIGN(MockClock);
432 };
433
434 class MockTimer : public base::MockTimer {
435 public:
436 MockTimer() : base::MockTimer(false, false) {}
437 ~MockTimer() {}
438
439 void Start(const tracked_objects::Location& posted_from,
440 base::TimeDelta delay,
441 const base::Closure& user_task) {
442 StartObserver(posted_from, delay, user_task);
443 base::MockTimer::Start(posted_from, delay, user_task);
444 }
445
446 // StartObserver is invoked when MockTimer::Start() is called.
447 // Does not replace the behavior of MockTimer::Start().
448 MOCK_METHOD3(StartObserver,
449 void(const tracked_objects::Location& posted_from,
450 base::TimeDelta delay,
451 const base::Closure& user_task));
452
453 private:
454 DISALLOW_COPY_AND_ASSIGN(MockTimer);
455 };
456
457 } // namespace
458
392 class MDnsTest : public ::testing::Test { 459 class MDnsTest : public ::testing::Test {
393 public: 460 public:
394 virtual void SetUp() override; 461 void SetUp() override;
395 void DeleteTransaction(); 462 void DeleteTransaction();
396 void DeleteBothListeners(); 463 void DeleteBothListeners();
397 void RunFor(base::TimeDelta time_period); 464 void RunFor(base::TimeDelta time_period);
398 void Stop(); 465 void Stop();
399 466
400 MOCK_METHOD2(MockableRecordCallback, void(MDnsTransaction::Result result, 467 MOCK_METHOD2(MockableRecordCallback, void(MDnsTransaction::Result result,
401 const RecordParsed* record)); 468 const RecordParsed* record));
402 469
403 MOCK_METHOD2(MockableRecordCallback2, void(MDnsTransaction::Result result, 470 MOCK_METHOD2(MockableRecordCallback2, void(MDnsTransaction::Result result,
404 const RecordParsed* record)); 471 const RecordParsed* record));
405 472
406
407 protected: 473 protected:
408 void ExpectPacket(const uint8* packet, unsigned size); 474 void ExpectPacket(const uint8* packet, unsigned size);
409 void SimulatePacketReceive(const uint8* packet, unsigned size); 475 void SimulatePacketReceive(const uint8* packet, unsigned size);
410 476
411 MDnsClientImpl test_client_; 477 MDnsClientImpl test_client_;
412 IPEndPoint mdns_ipv4_endpoint_; 478 IPEndPoint mdns_ipv4_endpoint_;
413 StrictMock<MockMDnsSocketFactory> socket_factory_; 479 StrictMock<MockMDnsSocketFactory> socket_factory_;
414 480
415 // Transactions and listeners that can be deleted by class methods for 481 // Transactions and listeners that can be deleted by class methods for
416 // reentrancy tests. 482 // reentrancy tests.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 .WillOnce(DoAll(InvokeWithoutArgs(this, &MDnsTest::Stop), 604 .WillOnce(DoAll(InvokeWithoutArgs(this, &MDnsTest::Stop),
539 Invoke(&record_privet2, 605 Invoke(&record_privet2,
540 &PtrRecordCopyContainer::SaveWithDummyArg))); 606 &PtrRecordCopyContainer::SaveWithDummyArg)));
541 607
542 RunFor(base::TimeDelta::FromSeconds(record_privet.ttl() + 1)); 608 RunFor(base::TimeDelta::FromSeconds(record_privet.ttl() + 1));
543 609
544 EXPECT_TRUE(record_privet2.IsRecordWith("_privet._tcp.local", 610 EXPECT_TRUE(record_privet2.IsRecordWith("_privet._tcp.local",
545 "hello._privet._tcp.local")); 611 "hello._privet._tcp.local"));
546 } 612 }
547 613
614 // Ensure that the cleanup task scheduler won't schedule cleanup tasks in the
615 // past if the system clock creeps past the expiration time while in the
616 // cleanup dispatcher.
617 TEST_F(MDnsTest, CacheCleanupWithShortTTL) {
618 // Use a nonzero starting time as a base.
619 base::Time start_time = base::Time() + base::TimeDelta::FromSeconds(1);
620
621 MockClock* clock = new MockClock;
622 MockTimer* timer = new MockTimer;
623
624 EXPECT_CALL(*timer, StartObserver(_, _, _)).Times(1);
625 EXPECT_CALL(*clock, Now())
626 .Times(3)
627 .WillRepeatedly(Return(start_time))
628 .RetiresOnSaturation();
629
630 test_client_.core()->set_cleanup_timer_for_test(make_scoped_ptr(timer));
631 test_client_.core()->set_clock_for_test(make_scoped_ptr(clock));
632
633 // Receive two records with different TTL values.
634 // TTL(privet)=1.0s
635 // TTL(printer)=3.0s
636 StrictMock<MockListenerDelegate> delegate_privet;
637 StrictMock<MockListenerDelegate> delegate_printer;
638
639 PtrRecordCopyContainer record_privet;
640 PtrRecordCopyContainer record_printer;
641
642 scoped_ptr<MDnsListener> listener_privet = test_client_.CreateListener(
643 dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
644 scoped_ptr<MDnsListener> listener_printer = test_client_.CreateListener(
645 dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer);
646
647 ASSERT_TRUE(listener_privet->Start());
648 ASSERT_TRUE(listener_printer->Start());
649
650 EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
651 .Times(Exactly(1));
652 EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
653 .Times(Exactly(1));
654
655 SimulatePacketReceive(kSamplePacket3, sizeof(kSamplePacket3));
656
657 EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _))
658 .Times(Exactly(1));
659
660 // Set the clock to 2.0s, which should clean up the 'privet' record, but not
661 // the printer. The mock clock will change Now() mid-execution from 2s to 4s.
662 // Note: expectations are FILO-ordered -- t+2 seconds is returned, then t+4.
663 EXPECT_CALL(*clock, Now())
664 .WillOnce(Return(start_time + base::TimeDelta::FromSeconds(4)))
665 .RetiresOnSaturation();
666 EXPECT_CALL(*clock, Now())
667 .WillOnce(Return(start_time + base::TimeDelta::FromSeconds(2)))
668 .RetiresOnSaturation();
669
670 EXPECT_CALL(*timer, StartObserver(_, base::TimeDelta(), _));
671
672 timer->Fire();
673 }
674
548 TEST_F(MDnsTest, MalformedPacket) { 675 TEST_F(MDnsTest, MalformedPacket) {
549 StrictMock<MockListenerDelegate> delegate_printer; 676 StrictMock<MockListenerDelegate> delegate_printer;
550 677
551 PtrRecordCopyContainer record_printer; 678 PtrRecordCopyContainer record_printer;
552 679
553 scoped_ptr<MDnsListener> listener_printer = 680 scoped_ptr<MDnsListener> listener_printer =
554 test_client_.CreateListener(dns_protocol::kTypePTR, "_printer._tcp.local", 681 test_client_.CreateListener(dns_protocol::kTypePTR, "_printer._tcp.local",
555 &delegate_printer); 682 &delegate_printer);
556 683
557 ASSERT_TRUE(listener_printer->Start()); 684 ASSERT_TRUE(listener_printer->Start());
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 MOCK_METHOD1(OnConnectionError, void(int error)); 1207 MOCK_METHOD1(OnConnectionError, void(int error));
1081 }; 1208 };
1082 1209
1083 class MDnsConnectionTest : public ::testing::Test { 1210 class MDnsConnectionTest : public ::testing::Test {
1084 public: 1211 public:
1085 MDnsConnectionTest() : connection_(&delegate_) { 1212 MDnsConnectionTest() : connection_(&delegate_) {
1086 } 1213 }
1087 1214
1088 protected: 1215 protected:
1089 // Follow successful connection initialization. 1216 // Follow successful connection initialization.
1090 virtual void SetUp() override { 1217 void SetUp() override {
1091 socket_ipv4_ = new MockMDnsDatagramServerSocket(ADDRESS_FAMILY_IPV4); 1218 socket_ipv4_ = new MockMDnsDatagramServerSocket(ADDRESS_FAMILY_IPV4);
1092 socket_ipv6_ = new MockMDnsDatagramServerSocket(ADDRESS_FAMILY_IPV6); 1219 socket_ipv6_ = new MockMDnsDatagramServerSocket(ADDRESS_FAMILY_IPV6);
1093 factory_.PushSocket(socket_ipv6_); 1220 factory_.PushSocket(socket_ipv6_);
1094 factory_.PushSocket(socket_ipv4_); 1221 factory_.PushSocket(socket_ipv4_);
1095 sample_packet_ = MakeString(kSamplePacket1, sizeof(kSamplePacket1)); 1222 sample_packet_ = MakeString(kSamplePacket1, sizeof(kSamplePacket1));
1096 sample_buffer_ = new StringIOBuffer(sample_packet_); 1223 sample_buffer_ = new StringIOBuffer(sample_packet_);
1097 } 1224 }
1098 1225
1099 bool InitConnection() { 1226 bool InitConnection() {
1100 return connection_.Init(&factory_); 1227 return connection_.Init(&factory_);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 EXPECT_CALL(*socket_ipv4_, 1339 EXPECT_CALL(*socket_ipv4_,
1213 SendToInternal(sample_packet_, "224.0.0.251:5353", _)) 1340 SendToInternal(sample_packet_, "224.0.0.251:5353", _))
1214 .Times(0); 1341 .Times(0);
1215 // Expect call for the second IPv6 packed. 1342 // Expect call for the second IPv6 packed.
1216 EXPECT_CALL(*socket_ipv6_, 1343 EXPECT_CALL(*socket_ipv6_,
1217 SendToInternal(sample_packet_, "[ff02::fb]:5353", _)) 1344 SendToInternal(sample_packet_, "[ff02::fb]:5353", _))
1218 .WillOnce(Return(OK)); 1345 .WillOnce(Return(OK));
1219 callback.Run(OK); 1346 callback.Run(OK);
1220 } 1347 }
1221 1348
1222 } // namespace
1223
1224 } // namespace net 1349 } // namespace net
OLDNEW
« net/dns/mdns_client_impl.cc ('K') | « net/dns/mdns_client_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698