| 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 |