OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "base/memory/ref_counted.h" | 5 #include "base/memory/ref_counted.h" |
6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
7 #include "net/base/rand_callback.h" | 7 #include "net/base/rand_callback.h" |
8 #include "net/base/test_completion_callback.h" | 8 #include "net/base/test_completion_callback.h" |
9 #include "net/dns/mdns_client_impl.h" | 9 #include "net/dns/mdns_client_impl.h" |
10 #include "net/dns/record_rdata.h" | 10 #include "net/dns/record_rdata.h" |
11 #include "net/udp/udp_client_socket.h" | 11 #include "net/udp/udp_client_socket.h" |
12 #include "testing/gmock/include/gmock/gmock.h" | 12 #include "testing/gmock/include/gmock/gmock.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
14 | 14 |
15 using ::testing::Invoke; | 15 using ::testing::Invoke; |
16 using ::testing::InvokeWithoutArgs; | 16 using ::testing::InvokeWithoutArgs; |
17 using ::testing::StrictMock; | 17 using ::testing::StrictMock; |
18 using ::testing::Exactly; | 18 using ::testing::Exactly; |
19 using ::testing::Return; | 19 using ::testing::Return; |
| 20 using ::testing::SaveArg; |
20 using ::testing::_; | 21 using ::testing::_; |
21 | 22 |
22 namespace net { | 23 namespace net { |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 const char kSamplePacket1[] = { | 27 const char kSamplePacket1[] = { |
27 // Header | 28 // Header |
28 0x00, 0x00, // ID is zeroed out | 29 0x00, 0x00, // ID is zeroed out |
29 0x81, 0x80, // Standard query response, RA, no error | 30 0x81, 0x80, // Standard query response, RA, no error |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. | 180 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds. |
180 0x24, 0x74, | 181 0x24, 0x74, |
181 0x00, 0x08, // RDLENGTH is 8 bytes. | 182 0x00, 0x08, // RDLENGTH is 8 bytes. |
182 0x05, 'z', 'z', 'z', 'z', 'z', | 183 0x05, 'z', 'z', 'z', 'z', 'z', |
183 0xc0, 0x32 | 184 0xc0, 0x32 |
184 }; | 185 }; |
185 | 186 |
186 const char kQueryPacketPrivet[] = { | 187 const char kQueryPacketPrivet[] = { |
187 // Header | 188 // Header |
188 0x00, 0x00, // ID is zeroed out | 189 0x00, 0x00, // ID is zeroed out |
189 0x00, 0x00, // Standard query. | 190 0x01, 0x00, // RD flag set |
190 0x00, 0x01, // One question. | 191 0x00, 0x01, // One question. |
191 0x00, 0x00, // 0 RRs (answers) | 192 0x00, 0x00, // 0 RRs (answers) |
192 0x00, 0x00, // 0 authority RRs | 193 0x00, 0x00, // 0 authority RRs |
193 0x00, 0x00, // 0 additional RRs | 194 0x00, 0x00, // 0 additional RRs |
194 | 195 |
195 // Question | 196 // Question |
196 // This part is echoed back from the respective query. | 197 // This part is echoed back from the respective query. |
197 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', | 198 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', |
198 0x04, '_', 't', 'c', 'p', | 199 0x04, '_', 't', 'c', 'p', |
199 0x05, 'l', 'o', 'c', 'a', 'l', | 200 0x05, 'l', 'o', 'c', 'a', 'l', |
(...skipping 30 matching lines...) Expand all Loading... |
230 class MockMDnsConnection : public MDnsConnection { | 231 class MockMDnsConnection : public MDnsConnection { |
231 public: | 232 public: |
232 MockMDnsConnection(MDnsConnection::Delegate* delegate, | 233 MockMDnsConnection(MDnsConnection::Delegate* delegate, |
233 MockMDnsConnectionFactory* factory) | 234 MockMDnsConnectionFactory* factory) |
234 : delegate_(delegate), factory_(factory) { | 235 : delegate_(delegate), factory_(factory) { |
235 } | 236 } |
236 | 237 |
237 virtual ~MockMDnsConnection() { | 238 virtual ~MockMDnsConnection() { |
238 } | 239 } |
239 | 240 |
240 virtual bool Init() OVERRIDE { | 241 virtual int Init() OVERRIDE { |
241 return true; | 242 return OK; |
242 } | 243 } |
243 | 244 |
244 virtual bool Send(IOBuffer* buffer, unsigned size) OVERRIDE; | 245 virtual int Send(IOBuffer* buffer, unsigned size) OVERRIDE; |
245 | 246 |
246 void SimulateRecieve(const char* packet, int size); | 247 void SimulateRecieve(const char* packet, int size); |
247 | 248 |
248 private: | 249 private: |
249 DnsResponse response; | 250 DnsResponse response; |
250 MDnsConnection::Delegate* delegate_; | 251 MDnsConnection::Delegate* delegate_; |
251 MockMDnsConnectionFactory* factory_; | 252 MockMDnsConnectionFactory* factory_; |
252 }; | 253 }; |
253 | 254 |
254 class MockMDnsConnectionFactory : public MDnsConnectionFactory { | 255 class MockMDnsConnectionFactory : public MDnsConnectionFactory { |
255 public: | 256 public: |
256 MockMDnsConnectionFactory() {} | 257 MockMDnsConnectionFactory() {} |
257 virtual ~MockMDnsConnectionFactory() {} | 258 virtual ~MockMDnsConnectionFactory() {} |
258 virtual scoped_ptr<MDnsConnection> CreateConnection( | 259 virtual scoped_ptr<MDnsConnection> CreateConnection( |
259 MDnsConnection::Delegate* delegate) OVERRIDE; | 260 MDnsConnection::Delegate* delegate) OVERRIDE; |
260 | 261 |
261 MOCK_METHOD1(OnSend, void(std::string)); | 262 MOCK_METHOD1(OnSend, void(std::string packet)); |
262 | 263 |
263 MockMDnsConnection* latest_connection() { return latest_connection_; } | 264 MockMDnsConnection* latest_connection() { return latest_connection_; } |
264 | 265 |
265 private: | 266 private: |
266 MockMDnsConnection* latest_connection_; | 267 MockMDnsConnection* latest_connection_; |
267 }; | 268 }; |
268 | 269 |
269 class MockMDnsConnectionDelegate : public MDnsConnection::Delegate { | 270 class MockMDnsConnectionDelegate : public MDnsConnection::Delegate { |
270 public: | 271 public: |
271 virtual void HandlePacket(DnsResponse* response, int size) { | 272 virtual void HandlePacket(DnsResponse* response, int size) { |
272 OnHandlePacket(std::string(response->io_buffer()->data(), size)); | 273 HandlePacketInternal(std::string(response->io_buffer()->data(), size)); |
273 } | 274 } |
274 | 275 |
275 MOCK_METHOD1(OnHandlePacket, void(std::string)); | 276 MOCK_METHOD1(HandlePacketInternal, void(std::string packet)); |
| 277 |
| 278 MOCK_METHOD1(OnConnectionError, void(int error)); |
276 }; | 279 }; |
277 | 280 |
278 bool MockMDnsConnection::Send(IOBuffer* buffer, unsigned size) { | 281 int MockMDnsConnection::Send(IOBuffer* buffer, unsigned size) { |
279 factory_->OnSend(std::string(buffer->data(), size)); | 282 factory_->OnSend(std::string(buffer->data(), size)); |
280 return true; | 283 return OK; |
281 } | 284 } |
282 | 285 |
283 void MockMDnsConnection::SimulateRecieve(const char* packet, int size) { | 286 void MockMDnsConnection::SimulateRecieve(const char* packet, int size) { |
284 memcpy(response.io_buffer()->data(), packet, size); | 287 memcpy(response.io_buffer()->data(), packet, size); |
285 delegate_->HandlePacket(&response, size); | 288 delegate_->HandlePacket(&response, size); |
286 } | 289 } |
287 | 290 |
288 scoped_ptr<MDnsConnection> MockMDnsConnectionFactory::CreateConnection( | 291 scoped_ptr<MDnsConnection> MockMDnsConnectionFactory::CreateConnection( |
289 MDnsConnection::Delegate* delegate) { | 292 MDnsConnection::Delegate* delegate) { |
290 latest_connection_ = new MockMDnsConnection(delegate, this); | 293 latest_connection_ = new MockMDnsConnection(delegate, this); |
(...skipping 27 matching lines...) Expand all Loading... |
318 class MDnsTest : public ::testing::Test { | 321 class MDnsTest : public ::testing::Test { |
319 public: | 322 public: |
320 MDnsTest(); | 323 MDnsTest(); |
321 virtual ~MDnsTest(); | 324 virtual ~MDnsTest(); |
322 void DeleteTransaction(); | 325 void DeleteTransaction(); |
323 void DeleteBothListeners(); | 326 void DeleteBothListeners(); |
324 void RunUntilIdle(); | 327 void RunUntilIdle(); |
325 void RunFor(base::TimeDelta time_period); | 328 void RunFor(base::TimeDelta time_period); |
326 void Stop(); | 329 void Stop(); |
327 | 330 |
328 MOCK_METHOD2(MockableRecordCallback, void(MDnsTransactionResult, | 331 MOCK_METHOD2(MockableRecordCallback, void(MDnsTransactionResult result, |
329 const RecordParsed*)); | 332 const RecordParsed* record)); |
330 | 333 |
331 protected: | 334 protected: |
332 void ExpectPacket(const char* packet, unsigned size); | 335 void ExpectPacket(const char* packet, unsigned size); |
333 void SendPacket(const char* packet, unsigned size); | 336 void SendPacket(const char* packet, unsigned size); |
334 void ExpectPtrRecord( | 337 void ExpectPtrRecord( |
335 const std::string& name, | 338 const std::string& name, |
336 const std::string& ptrdomain, | 339 const std::string& ptrdomain, |
337 const RecordParsedCopyContainer& record); | 340 const RecordParsedCopyContainer& record); |
338 | 341 |
339 base::MessageLoop* message_loop_; | 342 base::MessageLoop* message_loop_; |
340 | 343 |
341 scoped_ptr<MDnsClientImpl> test_client_; | 344 scoped_ptr<MDnsClientImpl> test_client_; |
342 IPEndPoint mdns_ipv4_endpoint_; | 345 IPEndPoint mdns_ipv4_endpoint_; |
343 StrictMock<MockMDnsConnectionFactory> connection_factory_; | 346 StrictMock<MockMDnsConnectionFactory> connection_factory_; |
344 | 347 |
345 // Transactions and listeners that can be deleted by class methods for | 348 // Transactions and listeners that can be deleted by class methods for |
346 // reentrancy tests. | 349 // reentrancy tests. |
347 scoped_ptr<MDnsTransaction> transaction_; | 350 scoped_ptr<MDnsTransaction> transaction_; |
348 scoped_ptr<MDnsListener> listener1_; | 351 scoped_ptr<MDnsListener> listener1_; |
349 scoped_ptr<MDnsListener> listener2_; | 352 scoped_ptr<MDnsListener> listener2_; |
350 }; | 353 }; |
351 | 354 |
352 class MockListenerDelegate : public MDnsListener::Delegate { | 355 class MockListenerDelegate : public MDnsListener::Delegate { |
353 public: | 356 public: |
354 MOCK_METHOD2(OnRecordUpdate, | 357 MOCK_METHOD2(OnRecordUpdate, |
355 void(MDnsUpdateType, const RecordParsed*)); | 358 void(MDnsUpdateType update, const RecordParsed* records)); |
356 MOCK_METHOD2(OnNsecRecord, void(const std::string&, unsigned)); | 359 MOCK_METHOD2(OnNsecRecord, void(const std::string&, unsigned)); |
| 360 MOCK_METHOD0(OnCachePurged, void()); |
357 }; | 361 }; |
358 | 362 |
359 MDnsTest::MDnsTest() | 363 MDnsTest::MDnsTest() |
360 : message_loop_(base::MessageLoop::current()) { | 364 : message_loop_(base::MessageLoop::current()) { |
361 test_client_.reset(new MDnsClientImpl(&connection_factory_)); | 365 test_client_.reset(new MDnsClientImpl(&connection_factory_)); |
362 } | 366 } |
363 | 367 |
364 MDnsTest::~MDnsTest() { | 368 MDnsTest::~MDnsTest() { |
365 } | 369 } |
366 | 370 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 | 420 |
417 TEST_F(MDnsTest, PassiveListeners) { | 421 TEST_F(MDnsTest, PassiveListeners) { |
418 StrictMock<MockListenerDelegate> delegate_privet; | 422 StrictMock<MockListenerDelegate> delegate_privet; |
419 StrictMock<MockListenerDelegate> delegate_printer; | 423 StrictMock<MockListenerDelegate> delegate_printer; |
420 StrictMock<MockListenerDelegate> delegate_ptr; | 424 StrictMock<MockListenerDelegate> delegate_ptr; |
421 | 425 |
422 RecordParsedCopyContainer record_privet; | 426 RecordParsedCopyContainer record_privet; |
423 RecordParsedCopyContainer record_printer; | 427 RecordParsedCopyContainer record_printer; |
424 | 428 |
425 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( | 429 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( |
426 dns_protocol::kTypePTR, "_privet._tcp.local", false, false, | 430 dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); |
427 &delegate_privet); | |
428 scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener( | 431 scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener( |
429 dns_protocol::kTypePTR, "_printer._tcp.local", false, false, | 432 dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer); |
430 &delegate_printer); | |
431 scoped_ptr<MDnsListener> listener_ptr = test_client_->CreateListener( | 433 scoped_ptr<MDnsListener> listener_ptr = test_client_->CreateListener( |
432 dns_protocol::kTypePTR, "", false, false, &delegate_ptr); | 434 dns_protocol::kTypePTR, "", &delegate_ptr); |
433 | 435 |
434 listener_privet->Start(); | 436 listener_privet->Start(); |
435 listener_printer->Start(); | 437 listener_printer->Start(); |
436 listener_ptr->Start(); | 438 listener_ptr->Start(); |
437 | 439 |
438 ASSERT_TRUE(test_client_->IsListeningForTests()); | 440 ASSERT_TRUE(test_client_->IsListeningForTests()); |
439 | 441 |
440 // Send the same packet twice to ensure no records are double-counted. | 442 // Send the same packet twice to ensure no records are double-counted. |
441 | 443 |
442 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) | 444 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 ASSERT_FALSE(test_client_->IsListeningForTests()); | 487 ASSERT_FALSE(test_client_->IsListeningForTests()); |
486 } | 488 } |
487 | 489 |
488 TEST_F(MDnsTest, PassiveListenersCleanup) { | 490 TEST_F(MDnsTest, PassiveListenersCleanup) { |
489 StrictMock<MockListenerDelegate> delegate_privet; | 491 StrictMock<MockListenerDelegate> delegate_privet; |
490 | 492 |
491 RecordParsedCopyContainer record_privet; | 493 RecordParsedCopyContainer record_privet; |
492 RecordParsedCopyContainer record_privet2; | 494 RecordParsedCopyContainer record_privet2; |
493 | 495 |
494 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( | 496 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( |
495 dns_protocol::kTypePTR, "_privet._tcp.local", false, false, | 497 dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); |
496 &delegate_privet); | |
497 | 498 |
498 listener_privet->Start(); | 499 listener_privet->Start(); |
499 | 500 |
500 ASSERT_TRUE(test_client_->IsListeningForTests()); | 501 ASSERT_TRUE(test_client_->IsListeningForTests()); |
501 | 502 |
502 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) | 503 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) |
503 .Times(Exactly(1)) | 504 .Times(Exactly(1)) |
504 .WillOnce(Invoke( | 505 .WillOnce(Invoke( |
505 &record_privet, | 506 &record_privet, |
506 &RecordParsedCopyContainer::SaveWithDummyArg)); | 507 &RecordParsedCopyContainer::SaveWithDummyArg)); |
(...skipping 12 matching lines...) Expand all Loading... |
519 &RecordParsedCopyContainer::SaveWithDummyArg))); | 520 &RecordParsedCopyContainer::SaveWithDummyArg))); |
520 | 521 |
521 RunFor(base::TimeDelta::FromSeconds(record_privet->ttl() + 1)); | 522 RunFor(base::TimeDelta::FromSeconds(record_privet->ttl() + 1)); |
522 | 523 |
523 RunUntilIdle(); | 524 RunUntilIdle(); |
524 | 525 |
525 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", | 526 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", |
526 record_privet2); | 527 record_privet2); |
527 } | 528 } |
528 | 529 |
529 TEST_F(MDnsTest, PassiveListenersNotifyExisting) { | |
530 StrictMock<MockListenerDelegate> delegate_privet; | |
531 StrictMock<MockListenerDelegate> delegate_privet2; | |
532 | |
533 RecordParsedCopyContainer record_privet; | |
534 RecordParsedCopyContainer record_privet2; | |
535 | |
536 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( | |
537 dns_protocol::kTypePTR, "_privet._tcp.local", false, false, | |
538 &delegate_privet); | |
539 | |
540 listener_privet->Start(); | |
541 | |
542 ASSERT_TRUE(test_client_->IsListeningForTests()); | |
543 | |
544 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) | |
545 .Times(Exactly(1)) | |
546 .WillOnce(Invoke( | |
547 &record_privet, | |
548 &RecordParsedCopyContainer::SaveWithDummyArg)); | |
549 | |
550 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); | |
551 | |
552 RunUntilIdle(); | |
553 | |
554 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", | |
555 record_privet); | |
556 | |
557 EXPECT_CALL(delegate_privet2, OnRecordUpdate(kMDnsRecordAdded, _)) | |
558 .Times(Exactly(1)) | |
559 .WillOnce(Invoke( | |
560 &record_privet2, | |
561 &RecordParsedCopyContainer::SaveWithDummyArg)); | |
562 | |
563 scoped_ptr<MDnsListener> listener_privet2 = test_client_->CreateListener( | |
564 dns_protocol::kTypePTR, "_privet._tcp.local", false, true, | |
565 &delegate_privet2); | |
566 | |
567 listener_privet2->Start(); | |
568 | |
569 RunUntilIdle(); | |
570 | |
571 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", | |
572 record_privet2); | |
573 } | |
574 | |
575 TEST_F(MDnsTest, MalformedPacket) { | 530 TEST_F(MDnsTest, MalformedPacket) { |
576 StrictMock<MockListenerDelegate> delegate_printer; | 531 StrictMock<MockListenerDelegate> delegate_printer; |
577 | 532 |
578 RecordParsedCopyContainer record_printer; | 533 RecordParsedCopyContainer record_printer; |
579 | 534 |
580 scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener( | 535 scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener( |
581 dns_protocol::kTypePTR, "_printer._tcp.local", false, false, | 536 dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer); |
582 &delegate_printer); | |
583 | 537 |
584 listener_printer->Start(); | 538 listener_printer->Start(); |
585 | 539 |
586 ASSERT_TRUE(test_client_->IsListeningForTests()); | 540 ASSERT_TRUE(test_client_->IsListeningForTests()); |
587 | 541 |
588 EXPECT_CALL(delegate_printer, OnRecordUpdate(kMDnsRecordAdded, _)) | 542 EXPECT_CALL(delegate_printer, OnRecordUpdate(kMDnsRecordAdded, _)) |
589 .Times(Exactly(1)) | 543 .Times(Exactly(1)) |
590 .WillOnce(Invoke( | 544 .WillOnce(Invoke( |
591 &record_printer, | 545 &record_printer, |
592 &RecordParsedCopyContainer::SaveWithDummyArg)); | 546 &RecordParsedCopyContainer::SaveWithDummyArg)); |
593 | 547 |
594 // First, send unsalvagable packet to ensure we can deal with it. | 548 // First, send unsalvagable packet to ensure we can deal with it. |
595 SendPacket(kCorruptedPacketUnsalvagable, | 549 SendPacket(kCorruptedPacketUnsalvagable, |
596 sizeof(kCorruptedPacketUnsalvagable)); | 550 sizeof(kCorruptedPacketUnsalvagable)); |
597 | 551 |
598 // Regression test: send a packet where the question cannot be read. | 552 // Regression test: send a packet where the question cannot be read. |
599 SendPacket(kCorruptedPacketBadQuestion, | 553 SendPacket(kCorruptedPacketBadQuestion, |
600 sizeof(kCorruptedPacketBadQuestion)); | 554 sizeof(kCorruptedPacketBadQuestion)); |
601 | 555 |
602 // Then send salvagable packet to ensure we can extract useful records. | 556 // Then send salvagable packet to ensure we can extract useful records. |
603 SendPacket(kCorruptedPacketSalvagable, | 557 SendPacket(kCorruptedPacketSalvagable, |
604 sizeof(kCorruptedPacketSalvagable)); | 558 sizeof(kCorruptedPacketSalvagable)); |
605 | 559 |
606 RunUntilIdle(); | 560 RunUntilIdle(); |
607 | 561 |
608 ExpectPtrRecord("_printer._tcp.local", "hello._printer._tcp.local", | 562 ExpectPtrRecord("_printer._tcp.local", "hello._printer._tcp.local", |
609 record_printer); | 563 record_printer); |
610 } | 564 } |
611 | 565 |
612 TEST_F(MDnsTest, QueryCache) { | |
613 StrictMock<MockListenerDelegate> delegate_privet; | |
614 | |
615 RecordParsedCopyContainer record_privet; | |
616 std::vector<const RecordParsed*> records_from_cache; | |
617 | |
618 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( | |
619 dns_protocol::kTypePTR, "_privet._tcp.local", false, false, | |
620 &delegate_privet); | |
621 | |
622 listener_privet->Start(); | |
623 | |
624 ASSERT_TRUE(test_client_->IsListeningForTests()); | |
625 | |
626 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) | |
627 .Times(Exactly(1)) | |
628 .WillOnce(Invoke( | |
629 &record_privet, | |
630 &RecordParsedCopyContainer::SaveWithDummyArg)); | |
631 | |
632 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); | |
633 | |
634 RunUntilIdle(); | |
635 | |
636 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", | |
637 record_privet); | |
638 | |
639 listener_privet->QueryCache(&records_from_cache); | |
640 | |
641 EXPECT_EQ(1u, records_from_cache.size()); | |
642 EXPECT_EQ("_privet._tcp.local", records_from_cache.front()->name()); | |
643 EXPECT_EQ(dns_protocol::kTypePTR, records_from_cache.front()->type()); | |
644 EXPECT_EQ(dns_protocol::kClassIN, records_from_cache.front()->klass()); | |
645 | |
646 const PtrRecordRdata* ptr_rdata = | |
647 records_from_cache.front()->rdata<PtrRecordRdata>(); | |
648 | |
649 EXPECT_TRUE(ptr_rdata != NULL); | |
650 | |
651 EXPECT_EQ("hello._privet._tcp.local", | |
652 ptr_rdata->ptrdomain()); | |
653 } | |
654 | |
655 TEST_F(MDnsTest, Query) { | |
656 StrictMock<MockListenerDelegate> delegate_privet; | |
657 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); | |
658 | |
659 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( | |
660 dns_protocol::kTypePTR, "_privet._tcp.local", false, false, | |
661 &delegate_privet); | |
662 | |
663 listener_privet->Start(); | |
664 | |
665 ASSERT_TRUE(listener_privet->SendQuery(false)); | |
666 | |
667 // Active listeners should send queries when created. | |
668 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); | |
669 | |
670 scoped_ptr<MDnsListener> listener_privet2 = test_client_->CreateListener( | |
671 dns_protocol::kTypePTR, "_privet._tcp.local", true /*active*/, | |
672 false /*existing*/, &delegate_privet); | |
673 | |
674 listener_privet2->Start(); | |
675 } | |
676 | |
677 TEST_F(MDnsTest, TransactionNoCache) { | 566 TEST_F(MDnsTest, TransactionNoCache) { |
678 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); | 567 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); |
679 | 568 |
680 scoped_ptr<MDnsTransaction> transaction_privet = | 569 scoped_ptr<MDnsTransaction> transaction_privet = |
681 test_client_->CreateTransaction( | 570 test_client_->CreateTransaction( |
682 dns_protocol::kTypePTR, "_privet._tcp.local", | 571 dns_protocol::kTypePTR, "_privet._tcp.local", |
| 572 kMDnsTransactionQueryNetwork | |
| 573 kMDnsTransactionQueryCache | |
| 574 kMDnsTransactionSingleResult, |
683 base::Bind(&MDnsTest::MockableRecordCallback, | 575 base::Bind(&MDnsTest::MockableRecordCallback, |
684 base::Unretained(this))); | 576 base::Unretained(this))); |
685 | 577 |
686 transaction_privet->Start(); | 578 transaction_privet->Start(); |
687 | 579 |
688 EXPECT_TRUE(test_client_->IsListeningForTests()); | 580 EXPECT_TRUE(test_client_->IsListeningForTests()); |
689 | 581 |
690 RecordParsedCopyContainer record_privet; | 582 RecordParsedCopyContainer record_privet; |
691 | 583 |
692 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionSuccess, _)) | 584 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionRecord, _)) |
693 .Times(Exactly(1)) | 585 .Times(Exactly(1)) |
694 .WillOnce(Invoke(&record_privet, | 586 .WillOnce(Invoke(&record_privet, |
695 &RecordParsedCopyContainer::SaveWithDummyArg)); | 587 &RecordParsedCopyContainer::SaveWithDummyArg)); |
696 | 588 |
697 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); | 589 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); |
698 | 590 |
699 RunUntilIdle(); | 591 RunUntilIdle(); |
700 | 592 |
701 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", | 593 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", |
702 record_privet); | 594 record_privet); |
703 | 595 |
704 EXPECT_FALSE(test_client_->IsListeningForTests()); | 596 EXPECT_FALSE(test_client_->IsListeningForTests()); |
705 } | 597 } |
706 | 598 |
| 599 |
| 600 TEST_F(MDnsTest, TransactionCacheOnlyNoResult) { |
| 601 scoped_ptr<MDnsTransaction> transaction_privet = |
| 602 test_client_->CreateTransaction( |
| 603 dns_protocol::kTypePTR, "_privet._tcp.local", |
| 604 kMDnsTransactionQueryCache | |
| 605 kMDnsTransactionSingleResult, |
| 606 base::Bind(&MDnsTest::MockableRecordCallback, |
| 607 base::Unretained(this))); |
| 608 |
| 609 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionNoResults, _)) |
| 610 .Times(Exactly(1)); |
| 611 |
| 612 transaction_privet->Start(); |
| 613 |
| 614 EXPECT_FALSE(test_client_->IsListeningForTests()); |
| 615 |
| 616 RunUntilIdle(); |
| 617 } |
| 618 |
| 619 |
707 TEST_F(MDnsTest, TransactionWithCache) { | 620 TEST_F(MDnsTest, TransactionWithCache) { |
708 // Listener to force the client to listen | 621 // Listener to force the client to listen |
709 StrictMock<MockListenerDelegate> delegate_irrelevant; | 622 StrictMock<MockListenerDelegate> delegate_irrelevant; |
710 scoped_ptr<MDnsListener> listener_irrelevant = test_client_->CreateListener( | 623 scoped_ptr<MDnsListener> listener_irrelevant = test_client_->CreateListener( |
711 dns_protocol::kTypeA, "codereview.chromium.local", false, false, | 624 dns_protocol::kTypeA, "codereview.chromium.local", |
712 &delegate_irrelevant); | 625 &delegate_irrelevant); |
713 | 626 |
714 listener_irrelevant->Start(); | 627 listener_irrelevant->Start(); |
715 | 628 |
716 EXPECT_TRUE(test_client_->IsListeningForTests()); | 629 EXPECT_TRUE(test_client_->IsListeningForTests()); |
717 | 630 |
718 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); | 631 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); |
719 | 632 |
720 RunUntilIdle(); | 633 RunUntilIdle(); |
721 | 634 |
722 RecordParsedCopyContainer record_privet; | 635 RecordParsedCopyContainer record_privet; |
723 | 636 |
724 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionSuccess, _)) | 637 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionRecord, _)) |
725 .WillOnce(Invoke(&record_privet, | 638 .WillOnce(Invoke(&record_privet, |
726 &RecordParsedCopyContainer::SaveWithDummyArg)); | 639 &RecordParsedCopyContainer::SaveWithDummyArg)); |
727 | 640 |
728 scoped_ptr<MDnsTransaction> transaction_privet = | 641 scoped_ptr<MDnsTransaction> transaction_privet = |
729 test_client_->CreateTransaction( | 642 test_client_->CreateTransaction( |
730 dns_protocol::kTypePTR, "_privet._tcp.local", | 643 dns_protocol::kTypePTR, "_privet._tcp.local", |
| 644 kMDnsTransactionQueryNetwork | |
| 645 kMDnsTransactionQueryCache | |
| 646 kMDnsTransactionSingleResult, |
731 base::Bind(&MDnsTest::MockableRecordCallback, | 647 base::Bind(&MDnsTest::MockableRecordCallback, |
732 base::Unretained(this))); | 648 base::Unretained(this))); |
733 | 649 |
734 transaction_privet->Start(); | 650 transaction_privet->Start(); |
735 | 651 |
736 RunUntilIdle(); | 652 RunUntilIdle(); |
737 | 653 |
738 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", | 654 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", |
739 record_privet); | 655 record_privet); |
740 } | 656 } |
741 | 657 |
742 TEST_F(MDnsTest, AdditionalRecords) { | 658 TEST_F(MDnsTest, AdditionalRecords) { |
743 StrictMock<MockListenerDelegate> delegate_privet; | 659 StrictMock<MockListenerDelegate> delegate_privet; |
744 | 660 |
745 RecordParsedCopyContainer record_privet; | 661 RecordParsedCopyContainer record_privet; |
746 | 662 |
747 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( | 663 scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( |
748 dns_protocol::kTypePTR, "_privet._tcp.local", false, false, | 664 dns_protocol::kTypePTR, "_privet._tcp.local", |
749 &delegate_privet); | 665 &delegate_privet); |
750 | 666 |
751 listener_privet->Start(); | 667 listener_privet->Start(); |
752 | 668 |
753 ASSERT_TRUE(test_client_->IsListeningForTests()); | 669 ASSERT_TRUE(test_client_->IsListeningForTests()); |
754 | 670 |
755 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) | 671 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) |
756 .Times(Exactly(1)) | 672 .Times(Exactly(1)) |
757 .WillOnce(Invoke( | 673 .WillOnce(Invoke( |
758 &record_privet, | 674 &record_privet, |
759 &RecordParsedCopyContainer::SaveWithDummyArg)); | 675 &RecordParsedCopyContainer::SaveWithDummyArg)); |
760 | 676 |
761 SendPacket(kSamplePacketAdditionalOnly, sizeof(kSamplePacket1)); | 677 SendPacket(kSamplePacketAdditionalOnly, sizeof(kSamplePacket1)); |
762 | 678 |
763 RunUntilIdle(); | 679 RunUntilIdle(); |
764 | 680 |
765 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", | 681 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", |
766 record_privet); | 682 record_privet); |
767 } | 683 } |
768 | 684 |
769 TEST_F(MDnsTest, TransactionTimeout) { | 685 TEST_F(MDnsTest, TransactionTimeout) { |
770 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); | 686 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); |
771 | 687 |
772 scoped_ptr<MDnsTransaction> transaction_privet = | 688 scoped_ptr<MDnsTransaction> transaction_privet = |
773 test_client_->CreateTransaction( | 689 test_client_->CreateTransaction( |
774 dns_protocol::kTypePTR, "_privet._tcp.local", | 690 dns_protocol::kTypePTR, "_privet._tcp.local", |
| 691 kMDnsTransactionQueryNetwork | |
| 692 kMDnsTransactionQueryCache | |
| 693 kMDnsTransactionSingleResult, |
775 base::Bind(&MDnsTest::MockableRecordCallback, | 694 base::Bind(&MDnsTest::MockableRecordCallback, |
776 base::Unretained(this))); | 695 base::Unretained(this))); |
777 | 696 |
778 transaction_privet->Start(); | 697 transaction_privet->Start(); |
779 | 698 |
780 EXPECT_TRUE(test_client_->IsListeningForTests()); | 699 EXPECT_TRUE(test_client_->IsListeningForTests()); |
781 | 700 |
782 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionTimeout, NULL)) | 701 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionNoResults, NULL)) |
783 .Times(Exactly(1)) | 702 .Times(Exactly(1)) |
784 .WillOnce(InvokeWithoutArgs(this, &MDnsTest::Stop)); | 703 .WillOnce(InvokeWithoutArgs(this, &MDnsTest::Stop)); |
785 | 704 |
786 RunFor(base::TimeDelta::FromSeconds(4)); | 705 RunFor(base::TimeDelta::FromSeconds(4)); |
787 | 706 |
788 EXPECT_FALSE(test_client_->IsListeningForTests()); | 707 EXPECT_FALSE(test_client_->IsListeningForTests()); |
789 } | 708 } |
790 | 709 |
| 710 TEST_F(MDnsTest, TransactionMultipleRecords) { |
| 711 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); |
| 712 |
| 713 scoped_ptr<MDnsTransaction> transaction_privet = |
| 714 test_client_->CreateTransaction( |
| 715 dns_protocol::kTypePTR, "_privet._tcp.local", |
| 716 kMDnsTransactionQueryNetwork | |
| 717 kMDnsTransactionQueryCache , |
| 718 base::Bind(&MDnsTest::MockableRecordCallback, |
| 719 base::Unretained(this))); |
| 720 |
| 721 transaction_privet->Start(); |
| 722 |
| 723 EXPECT_TRUE(test_client_->IsListeningForTests()); |
| 724 |
| 725 RecordParsedCopyContainer record_privet; |
| 726 RecordParsedCopyContainer record_privet2; |
| 727 |
| 728 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionRecord, _)) |
| 729 .Times(Exactly(2)) |
| 730 .WillOnce(Invoke(&record_privet, |
| 731 &RecordParsedCopyContainer::SaveWithDummyArg)) |
| 732 .WillOnce(Invoke(&record_privet2, |
| 733 &RecordParsedCopyContainer::SaveWithDummyArg)); |
| 734 |
| 735 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); |
| 736 SendPacket(kSamplePacket2, sizeof(kSamplePacket2)); |
| 737 |
| 738 RunUntilIdle(); |
| 739 |
| 740 ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local", |
| 741 record_privet); |
| 742 |
| 743 ExpectPtrRecord("_privet._tcp.local", "zzzzz._privet._tcp.local", |
| 744 record_privet2); |
| 745 |
| 746 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionDone, NULL)) |
| 747 .WillOnce(InvokeWithoutArgs(this, &MDnsTest::Stop)); |
| 748 |
| 749 RunFor(base::TimeDelta::FromSeconds(4)); |
| 750 |
| 751 EXPECT_FALSE(test_client_->IsListeningForTests()); |
| 752 } |
| 753 |
| 754 |
791 TEST_F(MDnsTest, TransactionReentrantDelete) { | 755 TEST_F(MDnsTest, TransactionReentrantDelete) { |
792 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); | 756 ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); |
793 | 757 |
794 transaction_ = test_client_->CreateTransaction( | 758 transaction_ = test_client_->CreateTransaction( |
795 dns_protocol::kTypePTR, "_privet._tcp.local", | 759 dns_protocol::kTypePTR, "_privet._tcp.local", |
| 760 kMDnsTransactionQueryNetwork | |
| 761 kMDnsTransactionQueryCache | |
| 762 kMDnsTransactionSingleResult, |
796 base::Bind(&MDnsTest::MockableRecordCallback, | 763 base::Bind(&MDnsTest::MockableRecordCallback, |
797 base::Unretained(this))); | 764 base::Unretained(this))); |
798 | 765 |
799 transaction_->Start(); | 766 transaction_->Start(); |
800 | 767 |
801 EXPECT_TRUE(test_client_->IsListeningForTests()); | 768 EXPECT_TRUE(test_client_->IsListeningForTests()); |
802 | 769 |
803 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionTimeout, NULL)) | 770 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionNoResults, NULL)) |
804 .Times(Exactly(1)) | 771 .Times(Exactly(1)) |
805 .WillOnce(DoAll(InvokeWithoutArgs(this, &MDnsTest::DeleteTransaction), | 772 .WillOnce(DoAll(InvokeWithoutArgs(this, &MDnsTest::DeleteTransaction), |
806 InvokeWithoutArgs(this, &MDnsTest::Stop))); | 773 InvokeWithoutArgs(this, &MDnsTest::Stop))); |
807 | 774 |
808 | 775 |
809 RunFor(base::TimeDelta::FromSeconds(4)); | 776 RunFor(base::TimeDelta::FromSeconds(4)); |
810 | 777 |
811 EXPECT_EQ(NULL, transaction_.get()); | 778 EXPECT_EQ(NULL, transaction_.get()); |
812 | 779 |
813 EXPECT_FALSE(test_client_->IsListeningForTests()); | 780 EXPECT_FALSE(test_client_->IsListeningForTests()); |
814 } | 781 } |
815 | 782 |
| 783 |
| 784 TEST_F(MDnsTest, TransactionReentrantDeleteFromCache) { |
| 785 StrictMock<MockListenerDelegate> delegate_irrelevant; |
| 786 scoped_ptr<MDnsListener> listener_irrelevant = test_client_->CreateListener( |
| 787 dns_protocol::kTypeA, "codereview.chromium.local", |
| 788 &delegate_irrelevant); |
| 789 listener_irrelevant->Start(); |
| 790 |
| 791 ASSERT_TRUE(test_client_->IsListeningForTests()); |
| 792 |
| 793 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); |
| 794 |
| 795 transaction_ = test_client_->CreateTransaction( |
| 796 dns_protocol::kTypePTR, "_privet._tcp.local", |
| 797 kMDnsTransactionQueryNetwork | |
| 798 kMDnsTransactionQueryCache, |
| 799 base::Bind(&MDnsTest::MockableRecordCallback, |
| 800 base::Unretained(this))); |
| 801 |
| 802 |
| 803 EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionRecord, _)) |
| 804 .Times(Exactly(1)) |
| 805 .WillOnce(InvokeWithoutArgs(this, &MDnsTest::DeleteTransaction)); |
| 806 |
| 807 transaction_->Start(); |
| 808 |
| 809 |
| 810 RunUntilIdle(); |
| 811 |
| 812 EXPECT_EQ(NULL, transaction_.get()); |
| 813 } |
| 814 |
| 815 |
816 // In order to reliably test reentrant listener deletes, we create two listeners | 816 // In order to reliably test reentrant listener deletes, we create two listeners |
817 // and have each of them delete both, so we're guaranteed to try and deliver a | 817 // and have each of them delete both, so we're guaranteed to try and deliver a |
818 // callback to at least one deleted listener. | 818 // callback to at least one deleted listener. |
819 | 819 |
820 TEST_F(MDnsTest, ListenerReentrantDelete) { | 820 TEST_F(MDnsTest, ListenerReentrantDelete) { |
821 StrictMock<MockListenerDelegate> delegate_privet; | 821 StrictMock<MockListenerDelegate> delegate_privet; |
822 | 822 |
823 listener1_ = test_client_->CreateListener( | 823 listener1_ = test_client_->CreateListener( |
824 dns_protocol::kTypePTR, "_privet._tcp.local", false, false, | 824 dns_protocol::kTypePTR, "_privet._tcp.local", |
825 &delegate_privet); | 825 &delegate_privet); |
826 | 826 |
827 listener2_ = test_client_->CreateListener( | 827 listener2_ = test_client_->CreateListener( |
828 dns_protocol::kTypePTR, "_privet._tcp.local", false, false, | 828 dns_protocol::kTypePTR, "_privet._tcp.local", |
829 &delegate_privet); | 829 &delegate_privet); |
830 | 830 |
831 listener1_->Start(); | 831 listener1_->Start(); |
832 | 832 |
833 listener2_->Start(); | 833 listener2_->Start(); |
834 | 834 |
835 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) | 835 EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _)) |
836 .Times(Exactly(1)) | 836 .Times(Exactly(1)) |
837 .WillOnce(InvokeWithoutArgs(this, &MDnsTest::DeleteBothListeners)); | 837 .WillOnce(InvokeWithoutArgs(this, &MDnsTest::DeleteBothListeners)); |
838 | 838 |
839 EXPECT_TRUE(test_client_->IsListeningForTests()); | 839 EXPECT_TRUE(test_client_->IsListeningForTests()); |
840 | 840 |
841 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); | 841 SendPacket(kSamplePacket1, sizeof(kSamplePacket1)); |
842 | 842 |
843 RunUntilIdle(); | 843 RunUntilIdle(); |
844 | 844 |
845 EXPECT_EQ(NULL, listener1_.get()); | 845 EXPECT_EQ(NULL, listener1_.get()); |
846 EXPECT_EQ(NULL, listener2_.get()); | 846 EXPECT_EQ(NULL, listener2_.get()); |
847 | 847 |
848 EXPECT_FALSE(test_client_->IsListeningForTests()); | 848 EXPECT_FALSE(test_client_->IsListeningForTests()); |
849 } | 849 } |
850 | 850 |
851 // Connection tests. These tests are disabled because, due to their dependence | 851 class MockDatagramServerSocket : public DatagramServerSocket { |
852 // on multicast networking, they are falky. | 852 public: |
| 853 int Listen(const IPEndPoint& address) { |
| 854 return ListenInternal(address.ToString()); |
| 855 } |
853 | 856 |
854 // TODO (noamsml): Migrate these tests to use a MockDatagramServerSocket. | 857 MOCK_METHOD1(ListenInternal, int(const std::string& address)); |
| 858 |
| 859 void SetResponsePacket(std::string response_packet) { |
| 860 response_packet_ = response_packet; |
| 861 } |
| 862 |
| 863 int RespondImmediately(IOBuffer* buffer, int size, IPEndPoint* address, |
| 864 const CompletionCallback& callback) { |
| 865 int to_copy = std::min(response_packet_.size(), (unsigned)size); |
| 866 memcpy(buffer->data(), response_packet_.data(), to_copy); |
| 867 return to_copy; |
| 868 } |
| 869 |
| 870 int RespondDelayed(IOBuffer* buffer, int size, IPEndPoint* address, |
| 871 const CompletionCallback& callback) { |
| 872 int rv = RespondImmediately(buffer, size, address, callback); |
| 873 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, rv)); |
| 874 return ERR_IO_PENDING; |
| 875 } |
| 876 |
| 877 MOCK_METHOD4(RecvFrom, int(IOBuffer* buffer, int size, |
| 878 IPEndPoint* address, |
| 879 const CompletionCallback& callback)); |
| 880 |
| 881 int SendTo(IOBuffer* buf, int buf_len, const IPEndPoint& address, |
| 882 const CompletionCallback& callback) { |
| 883 return SendToInternal(std::string(buf->data(), buf_len), address.ToString(), |
| 884 callback); |
| 885 } |
| 886 |
| 887 MOCK_METHOD3(SendToInternal, int(const std::string&, const std::string, |
| 888 const CompletionCallback&)); |
| 889 |
| 890 MOCK_METHOD1(SetReceiveBufferSize, bool(int32 size)); |
| 891 MOCK_METHOD1(SetSendBufferSize, bool(int32 size)); |
| 892 |
| 893 MOCK_METHOD0(Close, void()); |
| 894 |
| 895 MOCK_CONST_METHOD1(GetPeerAddress, int(IPEndPoint* address)); |
| 896 MOCK_CONST_METHOD1(GetLocalAddress, int(IPEndPoint* address)); |
| 897 MOCK_CONST_METHOD0(NetLog, const BoundNetLog&()); |
| 898 |
| 899 MOCK_METHOD0(AllowAddressReuse, void()); |
| 900 MOCK_METHOD0(AllowBroadcast, void()); |
| 901 |
| 902 int JoinGroup(const IPAddressNumber& group_address) const { |
| 903 return JoinGroupInternal(IPAddressToString(group_address)); |
| 904 } |
| 905 |
| 906 MOCK_CONST_METHOD1(JoinGroupInternal, int(const std::string& group)); |
| 907 |
| 908 int LeaveGroup(const IPAddressNumber& group_address) const { |
| 909 return JoinGroupInternal(IPAddressToString(group_address)); |
| 910 } |
| 911 |
| 912 MOCK_CONST_METHOD1(LeaveGroupInternal, int(const std::string& group)); |
| 913 |
| 914 MOCK_METHOD1(SetMulticastTimeToLive, int(int ttl)); |
| 915 |
| 916 MOCK_METHOD1(SetMulticastLoopbackMode, int(bool loopback)); |
| 917 |
| 918 private: |
| 919 std::string response_packet_; |
| 920 }; |
855 | 921 |
856 class MDnsConnectionTest : public ::testing::Test { | 922 class MDnsConnectionTest : public ::testing::Test { |
857 public: | 923 public: |
858 MDnsConnectionTest() : connection_(&delegate_) { | 924 MDnsConnectionTest() : connection_(&socket_ipv4_, &socket_ipv6_, &delegate_) { |
859 EXPECT_TRUE(ParseIPLiteralToNumber("224.0.0.251", &multicast_address4_)); | 925 } |
860 // TODO(noamsml): Figure out why client socket fails to connect to ipv6 | 926 |
861 // multicast address. | 927 protected: |
862 EXPECT_TRUE(ParseIPLiteralToNumber("::1", &multicast_address6_)); | 928 // Follow successful connection initialization |
| 929 void InitConnection() { |
| 930 EXPECT_CALL(socket_ipv4_, AllowAddressReuse()); |
| 931 EXPECT_CALL(socket_ipv6_, AllowAddressReuse()); |
| 932 |
| 933 EXPECT_CALL(socket_ipv4_, SetMulticastLoopbackMode(false)); |
| 934 EXPECT_CALL(socket_ipv6_, SetMulticastLoopbackMode(false)); |
| 935 |
| 936 EXPECT_CALL(socket_ipv4_, ListenInternal("0.0.0.0:5353")) |
| 937 .WillOnce(Return(OK)); |
| 938 EXPECT_CALL(socket_ipv6_, ListenInternal("[::]:5353")) |
| 939 .WillOnce(Return(OK)); |
| 940 |
| 941 EXPECT_CALL(socket_ipv4_, JoinGroupInternal("224.0.0.251")) |
| 942 .WillOnce(Return(OK)); |
| 943 EXPECT_CALL(socket_ipv6_, JoinGroupInternal("ff02::fb")) |
| 944 .WillOnce(Return(OK)); |
| 945 |
863 connection_.Init(); | 946 connection_.Init(); |
864 } | 947 } |
865 protected: | 948 |
866 IPAddressNumber multicast_address4_; | |
867 IPAddressNumber multicast_address6_; | |
868 StrictMock<MockMDnsConnectionDelegate> delegate_; | 949 StrictMock<MockMDnsConnectionDelegate> delegate_; |
869 | 950 |
| 951 MockDatagramServerSocket socket_ipv4_; |
| 952 MockDatagramServerSocket socket_ipv6_; |
870 MDnsConnectionImpl connection_; | 953 MDnsConnectionImpl connection_; |
871 TestCompletionCallback callback_; | 954 TestCompletionCallback callback_; |
872 }; | 955 }; |
873 | 956 |
874 TEST_F(MDnsConnectionTest, DISABLED_Recieve4) { | 957 TEST_F(MDnsConnectionTest, RecieveSynchronous) { |
875 scoped_refptr<IOBuffer> buf(new IOBuffer(sizeof(kSamplePacket1))); | 958 std::string sample_packet = |
876 memcpy(buf->data(), kSamplePacket1, sizeof(kSamplePacket1)); | 959 std::string(kSamplePacket1, sizeof(kSamplePacket1)); |
877 UDPSocket socket(DatagramSocket::DEFAULT_BIND, | 960 socket_ipv6_.SetResponsePacket(sample_packet); |
878 RandIntCallback(), | 961 EXPECT_CALL(socket_ipv4_, RecvFrom(_, _, _, _)) |
879 NULL, NetLog::Source()); | 962 .WillOnce(Return(ERR_IO_PENDING)); |
880 EXPECT_CALL(delegate_, OnHandlePacket(std::string(kSamplePacket1, | 963 EXPECT_CALL(socket_ipv6_, RecvFrom(_, _, _, _)) |
881 sizeof(kSamplePacket1)))); | 964 .WillOnce( |
| 965 Invoke(&socket_ipv6_, &MockDatagramServerSocket::RespondImmediately)) |
| 966 .WillOnce(Return(ERR_IO_PENDING)); |
882 | 967 |
883 EXPECT_EQ(OK, socket.Connect(IPEndPoint(multicast_address4_, 5353))); | 968 EXPECT_CALL(delegate_, HandlePacketInternal(sample_packet)); |
884 int rv = socket.Write(buf, sizeof(kSamplePacket1), callback_.callback()); | 969 |
885 if (rv == ERR_IO_PENDING) { | 970 InitConnection(); |
886 rv = callback_.GetResult(rv); | |
887 } | |
888 EXPECT_GT(rv, OK); | |
889 base::MessageLoop::current()->RunUntilIdle(); // Socket uses message loop. | |
890 } | 971 } |
891 | 972 |
892 TEST_F(MDnsConnectionTest, DISABLED_Recieve6) { | 973 TEST_F(MDnsConnectionTest, RecieveAsynchronous) { |
893 scoped_refptr<IOBuffer> buf(new IOBuffer(sizeof(kSamplePacket2))); | 974 std::string sample_packet = |
894 memcpy(buf->data(), kSamplePacket2, sizeof(kSamplePacket2)); | 975 std::string(kSamplePacket1, sizeof(kSamplePacket1)); |
895 UDPSocket socket(DatagramSocket::DEFAULT_BIND, | 976 socket_ipv6_.SetResponsePacket(sample_packet); |
896 RandIntCallback(), | 977 EXPECT_CALL(socket_ipv4_, RecvFrom(_, _, _, _)) |
897 NULL, NetLog::Source()); | 978 .WillOnce(Return(ERR_IO_PENDING)); |
898 EXPECT_CALL(delegate_, OnHandlePacket(std::string(kSamplePacket2, | 979 EXPECT_CALL(socket_ipv6_, RecvFrom(_, _, _, _)) |
899 sizeof(kSamplePacket2)))); | 980 .WillOnce( |
| 981 Invoke(&socket_ipv6_, &MockDatagramServerSocket::RespondDelayed)) |
| 982 .WillOnce(Return(ERR_IO_PENDING)); |
900 | 983 |
901 EXPECT_EQ(OK, socket.Connect(IPEndPoint(multicast_address6_, 5353))); | 984 InitConnection(); |
902 int rv = socket.Write(buf, sizeof(kSamplePacket2), callback_.callback()); | 985 |
903 if (rv == ERR_IO_PENDING) { | 986 EXPECT_CALL(delegate_, HandlePacketInternal(sample_packet)); |
904 rv = callback_.GetResult(rv); | 987 |
905 } | 988 base::MessageLoop::current()->RunUntilIdle(); |
906 EXPECT_GT(rv, OK); | 989 } |
907 base::MessageLoop::current()->RunUntilIdle(); // Socket uses message loop. | 990 |
| 991 TEST_F(MDnsConnectionTest, Send) { |
| 992 std::string sample_packet = |
| 993 std::string(kSamplePacket1, sizeof(kSamplePacket1)); |
| 994 |
| 995 scoped_refptr<IOBufferWithSize> buf( |
| 996 new IOBufferWithSize(sizeof kSamplePacket1)); |
| 997 memcpy(buf->data(), kSamplePacket1, sizeof(kSamplePacket1)); |
| 998 |
| 999 EXPECT_CALL(socket_ipv4_, RecvFrom(_, _, _, _)) |
| 1000 .WillOnce(Return(ERR_IO_PENDING)); |
| 1001 EXPECT_CALL(socket_ipv6_, RecvFrom(_, _, _, _)) |
| 1002 .WillOnce(Return(ERR_IO_PENDING)); |
| 1003 |
| 1004 InitConnection(); |
| 1005 |
| 1006 EXPECT_CALL(socket_ipv4_, |
| 1007 SendToInternal(sample_packet, "224.0.0.251:5353", _)); |
| 1008 EXPECT_CALL(socket_ipv6_, |
| 1009 SendToInternal(sample_packet, "[ff02::fb]:5353", _)); |
| 1010 |
| 1011 connection_.Send(buf, buf->size()); |
| 1012 } |
| 1013 |
| 1014 TEST_F(MDnsConnectionTest, Error) { |
| 1015 CompletionCallback callback; |
| 1016 |
| 1017 EXPECT_CALL(socket_ipv4_, RecvFrom(_, _, _, _)) |
| 1018 .WillOnce(Return(ERR_IO_PENDING)); |
| 1019 EXPECT_CALL(socket_ipv6_, RecvFrom(_, _, _, _)) |
| 1020 .WillOnce(DoAll(SaveArg<3>(&callback), Return(ERR_IO_PENDING))); |
| 1021 |
| 1022 InitConnection(); |
| 1023 |
| 1024 EXPECT_CALL(delegate_, OnConnectionError(ERR_SOCKET_NOT_CONNECTED)); |
| 1025 callback.Run(ERR_SOCKET_NOT_CONNECTED); |
908 } | 1026 } |
909 | 1027 |
910 } // namespace | 1028 } // namespace |
911 | 1029 |
912 } // namespace net | 1030 } // namespace net |
OLD | NEW |