| Index: net/dns/mdns_client_unittest.cc
|
| diff --git a/net/dns/mdns_client_unittest.cc b/net/dns/mdns_client_unittest.cc
|
| index 0f5fe492624cc6c7081497209b4719f67d9c74ad..51105676a972c9c3a4d334f474f03d3d70ff0673 100644
|
| --- a/net/dns/mdns_client_unittest.cc
|
| +++ b/net/dns/mdns_client_unittest.cc
|
| @@ -17,6 +17,7 @@ using ::testing::InvokeWithoutArgs;
|
| using ::testing::StrictMock;
|
| using ::testing::Exactly;
|
| using ::testing::Return;
|
| +using ::testing::SaveArg;
|
| using ::testing::_;
|
|
|
| namespace net {
|
| @@ -186,7 +187,7 @@ const char kSamplePacket2[] = {
|
| const char kQueryPacketPrivet[] = {
|
| // Header
|
| 0x00, 0x00, // ID is zeroed out
|
| - 0x00, 0x00, // Standard query.
|
| + 0x01, 0x00, // RD flag set
|
| 0x00, 0x01, // One question.
|
| 0x00, 0x00, // 0 RRs (answers)
|
| 0x00, 0x00, // 0 authority RRs
|
| @@ -237,11 +238,11 @@ class MockMDnsConnection : public MDnsConnection {
|
| virtual ~MockMDnsConnection() {
|
| }
|
|
|
| - virtual bool Init() OVERRIDE {
|
| - return true;
|
| + virtual int Init() OVERRIDE {
|
| + return OK;
|
| }
|
|
|
| - virtual bool Send(IOBuffer* buffer, unsigned size) OVERRIDE;
|
| + virtual int Send(IOBuffer* buffer, unsigned size) OVERRIDE;
|
|
|
| void SimulateRecieve(const char* packet, int size);
|
|
|
| @@ -258,7 +259,7 @@ class MockMDnsConnectionFactory : public MDnsConnectionFactory {
|
| virtual scoped_ptr<MDnsConnection> CreateConnection(
|
| MDnsConnection::Delegate* delegate) OVERRIDE;
|
|
|
| - MOCK_METHOD1(OnSend, void(std::string));
|
| + MOCK_METHOD1(OnSend, void(std::string packet));
|
|
|
| MockMDnsConnection* latest_connection() { return latest_connection_; }
|
|
|
| @@ -269,15 +270,17 @@ class MockMDnsConnectionFactory : public MDnsConnectionFactory {
|
| class MockMDnsConnectionDelegate : public MDnsConnection::Delegate {
|
| public:
|
| virtual void HandlePacket(DnsResponse* response, int size) {
|
| - OnHandlePacket(std::string(response->io_buffer()->data(), size));
|
| + HandlePacketInternal(std::string(response->io_buffer()->data(), size));
|
| }
|
|
|
| - MOCK_METHOD1(OnHandlePacket, void(std::string));
|
| + MOCK_METHOD1(HandlePacketInternal, void(std::string packet));
|
| +
|
| + MOCK_METHOD1(OnConnectionError, void(int error));
|
| };
|
|
|
| -bool MockMDnsConnection::Send(IOBuffer* buffer, unsigned size) {
|
| +int MockMDnsConnection::Send(IOBuffer* buffer, unsigned size) {
|
| factory_->OnSend(std::string(buffer->data(), size));
|
| - return true;
|
| + return OK;
|
| }
|
|
|
| void MockMDnsConnection::SimulateRecieve(const char* packet, int size) {
|
| @@ -325,8 +328,8 @@ class MDnsTest : public ::testing::Test {
|
| void RunFor(base::TimeDelta time_period);
|
| void Stop();
|
|
|
| - MOCK_METHOD2(MockableRecordCallback, void(MDnsTransactionResult,
|
| - const RecordParsed*));
|
| + MOCK_METHOD2(MockableRecordCallback, void(MDnsTransactionResult result,
|
| + const RecordParsed* record));
|
|
|
| protected:
|
| void ExpectPacket(const char* packet, unsigned size);
|
| @@ -352,8 +355,9 @@ class MDnsTest : public ::testing::Test {
|
| class MockListenerDelegate : public MDnsListener::Delegate {
|
| public:
|
| MOCK_METHOD2(OnRecordUpdate,
|
| - void(MDnsUpdateType, const RecordParsed*));
|
| + void(MDnsUpdateType update, const RecordParsed* records));
|
| MOCK_METHOD2(OnNsecRecord, void(const std::string&, unsigned));
|
| + MOCK_METHOD0(OnCachePurged, void());
|
| };
|
|
|
| MDnsTest::MDnsTest()
|
| @@ -423,13 +427,11 @@ TEST_F(MDnsTest, PassiveListeners) {
|
| RecordParsedCopyContainer record_printer;
|
|
|
| scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, false,
|
| - &delegate_privet);
|
| + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
|
| scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_printer._tcp.local", false, false,
|
| - &delegate_printer);
|
| + dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer);
|
| scoped_ptr<MDnsListener> listener_ptr = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "", false, false, &delegate_ptr);
|
| + dns_protocol::kTypePTR, "", &delegate_ptr);
|
|
|
| listener_privet->Start();
|
| listener_printer->Start();
|
| @@ -492,8 +494,7 @@ TEST_F(MDnsTest, PassiveListenersCleanup) {
|
| RecordParsedCopyContainer record_privet2;
|
|
|
| scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, false,
|
| - &delegate_privet);
|
| + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
|
|
|
| listener_privet->Start();
|
|
|
| @@ -526,60 +527,13 @@ TEST_F(MDnsTest, PassiveListenersCleanup) {
|
| record_privet2);
|
| }
|
|
|
| -TEST_F(MDnsTest, PassiveListenersNotifyExisting) {
|
| - StrictMock<MockListenerDelegate> delegate_privet;
|
| - StrictMock<MockListenerDelegate> delegate_privet2;
|
| -
|
| - RecordParsedCopyContainer record_privet;
|
| - RecordParsedCopyContainer record_privet2;
|
| -
|
| - scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, false,
|
| - &delegate_privet);
|
| -
|
| - listener_privet->Start();
|
| -
|
| - ASSERT_TRUE(test_client_->IsListeningForTests());
|
| -
|
| - EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _))
|
| - .Times(Exactly(1))
|
| - .WillOnce(Invoke(
|
| - &record_privet,
|
| - &RecordParsedCopyContainer::SaveWithDummyArg));
|
| -
|
| - SendPacket(kSamplePacket1, sizeof(kSamplePacket1));
|
| -
|
| - RunUntilIdle();
|
| -
|
| - ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local",
|
| - record_privet);
|
| -
|
| - EXPECT_CALL(delegate_privet2, OnRecordUpdate(kMDnsRecordAdded, _))
|
| - .Times(Exactly(1))
|
| - .WillOnce(Invoke(
|
| - &record_privet2,
|
| - &RecordParsedCopyContainer::SaveWithDummyArg));
|
| -
|
| - scoped_ptr<MDnsListener> listener_privet2 = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, true,
|
| - &delegate_privet2);
|
| -
|
| - listener_privet2->Start();
|
| -
|
| - RunUntilIdle();
|
| -
|
| - ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local",
|
| - record_privet2);
|
| -}
|
| -
|
| TEST_F(MDnsTest, MalformedPacket) {
|
| StrictMock<MockListenerDelegate> delegate_printer;
|
|
|
| RecordParsedCopyContainer record_printer;
|
|
|
| scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_printer._tcp.local", false, false,
|
| - &delegate_printer);
|
| + dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer);
|
|
|
| listener_printer->Start();
|
|
|
| @@ -609,77 +563,15 @@ TEST_F(MDnsTest, MalformedPacket) {
|
| record_printer);
|
| }
|
|
|
| -TEST_F(MDnsTest, QueryCache) {
|
| - StrictMock<MockListenerDelegate> delegate_privet;
|
| -
|
| - RecordParsedCopyContainer record_privet;
|
| - std::vector<const RecordParsed*> records_from_cache;
|
| -
|
| - scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, false,
|
| - &delegate_privet);
|
| -
|
| - listener_privet->Start();
|
| -
|
| - ASSERT_TRUE(test_client_->IsListeningForTests());
|
| -
|
| - EXPECT_CALL(delegate_privet, OnRecordUpdate(kMDnsRecordAdded, _))
|
| - .Times(Exactly(1))
|
| - .WillOnce(Invoke(
|
| - &record_privet,
|
| - &RecordParsedCopyContainer::SaveWithDummyArg));
|
| -
|
| - SendPacket(kSamplePacket1, sizeof(kSamplePacket1));
|
| -
|
| - RunUntilIdle();
|
| -
|
| - ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local",
|
| - record_privet);
|
| -
|
| - listener_privet->QueryCache(&records_from_cache);
|
| -
|
| - EXPECT_EQ(1u, records_from_cache.size());
|
| - EXPECT_EQ("_privet._tcp.local", records_from_cache.front()->name());
|
| - EXPECT_EQ(dns_protocol::kTypePTR, records_from_cache.front()->type());
|
| - EXPECT_EQ(dns_protocol::kClassIN, records_from_cache.front()->klass());
|
| -
|
| - const PtrRecordRdata* ptr_rdata =
|
| - records_from_cache.front()->rdata<PtrRecordRdata>();
|
| -
|
| - EXPECT_TRUE(ptr_rdata != NULL);
|
| -
|
| - EXPECT_EQ("hello._privet._tcp.local",
|
| - ptr_rdata->ptrdomain());
|
| -}
|
| -
|
| -TEST_F(MDnsTest, Query) {
|
| - StrictMock<MockListenerDelegate> delegate_privet;
|
| - ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
|
| -
|
| - scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, false,
|
| - &delegate_privet);
|
| -
|
| - listener_privet->Start();
|
| -
|
| - ASSERT_TRUE(listener_privet->SendQuery(false));
|
| -
|
| - // Active listeners should send queries when created.
|
| - ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
|
| -
|
| - scoped_ptr<MDnsListener> listener_privet2 = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", true /*active*/,
|
| - false /*existing*/, &delegate_privet);
|
| -
|
| - listener_privet2->Start();
|
| -}
|
| -
|
| TEST_F(MDnsTest, TransactionNoCache) {
|
| ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
|
|
|
| scoped_ptr<MDnsTransaction> transaction_privet =
|
| test_client_->CreateTransaction(
|
| dns_protocol::kTypePTR, "_privet._tcp.local",
|
| + kMDnsTransactionQueryNetwork |
|
| + kMDnsTransactionQueryCache |
|
| + kMDnsTransactionSingleResult,
|
| base::Bind(&MDnsTest::MockableRecordCallback,
|
| base::Unretained(this)));
|
|
|
| @@ -689,7 +581,7 @@ TEST_F(MDnsTest, TransactionNoCache) {
|
|
|
| RecordParsedCopyContainer record_privet;
|
|
|
| - EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionSuccess, _))
|
| + EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionRecord, _))
|
| .Times(Exactly(1))
|
| .WillOnce(Invoke(&record_privet,
|
| &RecordParsedCopyContainer::SaveWithDummyArg));
|
| @@ -704,11 +596,32 @@ TEST_F(MDnsTest, TransactionNoCache) {
|
| EXPECT_FALSE(test_client_->IsListeningForTests());
|
| }
|
|
|
| +
|
| +TEST_F(MDnsTest, TransactionCacheOnlyNoResult) {
|
| + scoped_ptr<MDnsTransaction> transaction_privet =
|
| + test_client_->CreateTransaction(
|
| + dns_protocol::kTypePTR, "_privet._tcp.local",
|
| + kMDnsTransactionQueryCache |
|
| + kMDnsTransactionSingleResult,
|
| + base::Bind(&MDnsTest::MockableRecordCallback,
|
| + base::Unretained(this)));
|
| +
|
| + EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionNoResults, _))
|
| + .Times(Exactly(1));
|
| +
|
| + transaction_privet->Start();
|
| +
|
| + EXPECT_FALSE(test_client_->IsListeningForTests());
|
| +
|
| + RunUntilIdle();
|
| +}
|
| +
|
| +
|
| TEST_F(MDnsTest, TransactionWithCache) {
|
| // Listener to force the client to listen
|
| StrictMock<MockListenerDelegate> delegate_irrelevant;
|
| scoped_ptr<MDnsListener> listener_irrelevant = test_client_->CreateListener(
|
| - dns_protocol::kTypeA, "codereview.chromium.local", false, false,
|
| + dns_protocol::kTypeA, "codereview.chromium.local",
|
| &delegate_irrelevant);
|
|
|
| listener_irrelevant->Start();
|
| @@ -721,13 +634,16 @@ TEST_F(MDnsTest, TransactionWithCache) {
|
|
|
| RecordParsedCopyContainer record_privet;
|
|
|
| - EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionSuccess, _))
|
| + EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionRecord, _))
|
| .WillOnce(Invoke(&record_privet,
|
| &RecordParsedCopyContainer::SaveWithDummyArg));
|
|
|
| scoped_ptr<MDnsTransaction> transaction_privet =
|
| test_client_->CreateTransaction(
|
| dns_protocol::kTypePTR, "_privet._tcp.local",
|
| + kMDnsTransactionQueryNetwork |
|
| + kMDnsTransactionQueryCache |
|
| + kMDnsTransactionSingleResult,
|
| base::Bind(&MDnsTest::MockableRecordCallback,
|
| base::Unretained(this)));
|
|
|
| @@ -745,7 +661,7 @@ TEST_F(MDnsTest, AdditionalRecords) {
|
| RecordParsedCopyContainer record_privet;
|
|
|
| scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, false,
|
| + dns_protocol::kTypePTR, "_privet._tcp.local",
|
| &delegate_privet);
|
|
|
| listener_privet->Start();
|
| @@ -772,6 +688,9 @@ TEST_F(MDnsTest, TransactionTimeout) {
|
| scoped_ptr<MDnsTransaction> transaction_privet =
|
| test_client_->CreateTransaction(
|
| dns_protocol::kTypePTR, "_privet._tcp.local",
|
| + kMDnsTransactionQueryNetwork |
|
| + kMDnsTransactionQueryCache |
|
| + kMDnsTransactionSingleResult,
|
| base::Bind(&MDnsTest::MockableRecordCallback,
|
| base::Unretained(this)));
|
|
|
| @@ -779,7 +698,7 @@ TEST_F(MDnsTest, TransactionTimeout) {
|
|
|
| EXPECT_TRUE(test_client_->IsListeningForTests());
|
|
|
| - EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionTimeout, NULL))
|
| + EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionNoResults, NULL))
|
| .Times(Exactly(1))
|
| .WillOnce(InvokeWithoutArgs(this, &MDnsTest::Stop));
|
|
|
| @@ -788,11 +707,59 @@ TEST_F(MDnsTest, TransactionTimeout) {
|
| EXPECT_FALSE(test_client_->IsListeningForTests());
|
| }
|
|
|
| +TEST_F(MDnsTest, TransactionMultipleRecords) {
|
| + ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
|
| +
|
| + scoped_ptr<MDnsTransaction> transaction_privet =
|
| + test_client_->CreateTransaction(
|
| + dns_protocol::kTypePTR, "_privet._tcp.local",
|
| + kMDnsTransactionQueryNetwork |
|
| + kMDnsTransactionQueryCache ,
|
| + base::Bind(&MDnsTest::MockableRecordCallback,
|
| + base::Unretained(this)));
|
| +
|
| + transaction_privet->Start();
|
| +
|
| + EXPECT_TRUE(test_client_->IsListeningForTests());
|
| +
|
| + RecordParsedCopyContainer record_privet;
|
| + RecordParsedCopyContainer record_privet2;
|
| +
|
| + EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionRecord, _))
|
| + .Times(Exactly(2))
|
| + .WillOnce(Invoke(&record_privet,
|
| + &RecordParsedCopyContainer::SaveWithDummyArg))
|
| + .WillOnce(Invoke(&record_privet2,
|
| + &RecordParsedCopyContainer::SaveWithDummyArg));
|
| +
|
| + SendPacket(kSamplePacket1, sizeof(kSamplePacket1));
|
| + SendPacket(kSamplePacket2, sizeof(kSamplePacket2));
|
| +
|
| + RunUntilIdle();
|
| +
|
| + ExpectPtrRecord("_privet._tcp.local", "hello._privet._tcp.local",
|
| + record_privet);
|
| +
|
| + ExpectPtrRecord("_privet._tcp.local", "zzzzz._privet._tcp.local",
|
| + record_privet2);
|
| +
|
| + EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionDone, NULL))
|
| + .WillOnce(InvokeWithoutArgs(this, &MDnsTest::Stop));
|
| +
|
| + RunFor(base::TimeDelta::FromSeconds(4));
|
| +
|
| + EXPECT_FALSE(test_client_->IsListeningForTests());
|
| +}
|
| +
|
| +
|
| TEST_F(MDnsTest, TransactionReentrantDelete) {
|
| ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
|
|
|
| transaction_ = test_client_->CreateTransaction(
|
| dns_protocol::kTypePTR, "_privet._tcp.local",
|
| + kMDnsTransactionQueryNetwork |
|
| + kMDnsTransactionQueryCache |
|
| + kMDnsTransactionSingleResult,
|
| base::Bind(&MDnsTest::MockableRecordCallback,
|
| base::Unretained(this)));
|
|
|
| @@ -800,7 +767,7 @@ TEST_F(MDnsTest, TransactionReentrantDelete) {
|
|
|
| EXPECT_TRUE(test_client_->IsListeningForTests());
|
|
|
| - EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionTimeout, NULL))
|
| + EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionNoResults, NULL))
|
| .Times(Exactly(1))
|
| .WillOnce(DoAll(InvokeWithoutArgs(this, &MDnsTest::DeleteTransaction),
|
| InvokeWithoutArgs(this, &MDnsTest::Stop)));
|
| @@ -813,6 +780,39 @@ TEST_F(MDnsTest, TransactionReentrantDelete) {
|
| EXPECT_FALSE(test_client_->IsListeningForTests());
|
| }
|
|
|
| +
|
| +TEST_F(MDnsTest, TransactionReentrantDeleteFromCache) {
|
| + StrictMock<MockListenerDelegate> delegate_irrelevant;
|
| + scoped_ptr<MDnsListener> listener_irrelevant = test_client_->CreateListener(
|
| + dns_protocol::kTypeA, "codereview.chromium.local",
|
| + &delegate_irrelevant);
|
| + listener_irrelevant->Start();
|
| +
|
| + ASSERT_TRUE(test_client_->IsListeningForTests());
|
| +
|
| + SendPacket(kSamplePacket1, sizeof(kSamplePacket1));
|
| +
|
| + transaction_ = test_client_->CreateTransaction(
|
| + dns_protocol::kTypePTR, "_privet._tcp.local",
|
| + kMDnsTransactionQueryNetwork |
|
| + kMDnsTransactionQueryCache,
|
| + base::Bind(&MDnsTest::MockableRecordCallback,
|
| + base::Unretained(this)));
|
| +
|
| +
|
| + EXPECT_CALL(*this, MockableRecordCallback(kMDnsTransactionRecord, _))
|
| + .Times(Exactly(1))
|
| + .WillOnce(InvokeWithoutArgs(this, &MDnsTest::DeleteTransaction));
|
| +
|
| + transaction_->Start();
|
| +
|
| +
|
| + RunUntilIdle();
|
| +
|
| + EXPECT_EQ(NULL, transaction_.get());
|
| +}
|
| +
|
| +
|
| // In order to reliably test reentrant listener deletes, we create two listeners
|
| // and have each of them delete both, so we're guaranteed to try and deliver a
|
| // callback to at least one deleted listener.
|
| @@ -821,11 +821,11 @@ TEST_F(MDnsTest, ListenerReentrantDelete) {
|
| StrictMock<MockListenerDelegate> delegate_privet;
|
|
|
| listener1_ = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, false,
|
| + dns_protocol::kTypePTR, "_privet._tcp.local",
|
| &delegate_privet);
|
|
|
| listener2_ = test_client_->CreateListener(
|
| - dns_protocol::kTypePTR, "_privet._tcp.local", false, false,
|
| + dns_protocol::kTypePTR, "_privet._tcp.local",
|
| &delegate_privet);
|
|
|
| listener1_->Start();
|
| @@ -848,63 +848,181 @@ TEST_F(MDnsTest, ListenerReentrantDelete) {
|
| EXPECT_FALSE(test_client_->IsListeningForTests());
|
| }
|
|
|
| -// Connection tests. These tests are disabled because, due to their dependence
|
| -// on multicast networking, they are falky.
|
| +class MockDatagramServerSocket : public DatagramServerSocket {
|
| + public:
|
| + int Listen(const IPEndPoint& address) {
|
| + return ListenInternal(address.ToString());
|
| + }
|
| +
|
| + MOCK_METHOD1(ListenInternal, int(const std::string& address));
|
| +
|
| + void SetResponsePacket(std::string response_packet) {
|
| + response_packet_ = response_packet;
|
| + }
|
| +
|
| + int RespondImmediately(IOBuffer* buffer, int size, IPEndPoint* address,
|
| + const CompletionCallback& callback) {
|
| + int to_copy = std::min(response_packet_.size(), (unsigned)size);
|
| + memcpy(buffer->data(), response_packet_.data(), to_copy);
|
| + return to_copy;
|
| + }
|
| +
|
| + int RespondDelayed(IOBuffer* buffer, int size, IPEndPoint* address,
|
| + const CompletionCallback& callback) {
|
| + int rv = RespondImmediately(buffer, size, address, callback);
|
| + MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, rv));
|
| + return ERR_IO_PENDING;
|
| + }
|
| +
|
| + MOCK_METHOD4(RecvFrom, int(IOBuffer* buffer, int size,
|
| + IPEndPoint* address,
|
| + const CompletionCallback& callback));
|
| +
|
| + int SendTo(IOBuffer* buf, int buf_len, const IPEndPoint& address,
|
| + const CompletionCallback& callback) {
|
| + return SendToInternal(std::string(buf->data(), buf_len), address.ToString(),
|
| + callback);
|
| + }
|
| +
|
| + MOCK_METHOD3(SendToInternal, int(const std::string&, const std::string,
|
| + const CompletionCallback&));
|
| +
|
| + MOCK_METHOD1(SetReceiveBufferSize, bool(int32 size));
|
| + MOCK_METHOD1(SetSendBufferSize, bool(int32 size));
|
| +
|
| + MOCK_METHOD0(Close, void());
|
|
|
| -// TODO (noamsml): Migrate these tests to use a MockDatagramServerSocket.
|
| + MOCK_CONST_METHOD1(GetPeerAddress, int(IPEndPoint* address));
|
| + MOCK_CONST_METHOD1(GetLocalAddress, int(IPEndPoint* address));
|
| + MOCK_CONST_METHOD0(NetLog, const BoundNetLog&());
|
| +
|
| + MOCK_METHOD0(AllowAddressReuse, void());
|
| + MOCK_METHOD0(AllowBroadcast, void());
|
| +
|
| + int JoinGroup(const IPAddressNumber& group_address) const {
|
| + return JoinGroupInternal(IPAddressToString(group_address));
|
| + }
|
| +
|
| + MOCK_CONST_METHOD1(JoinGroupInternal, int(const std::string& group));
|
| +
|
| + int LeaveGroup(const IPAddressNumber& group_address) const {
|
| + return JoinGroupInternal(IPAddressToString(group_address));
|
| + }
|
| +
|
| + MOCK_CONST_METHOD1(LeaveGroupInternal, int(const std::string& group));
|
| +
|
| + MOCK_METHOD1(SetMulticastTimeToLive, int(int ttl));
|
| +
|
| + MOCK_METHOD1(SetMulticastLoopbackMode, int(bool loopback));
|
| +
|
| + private:
|
| + std::string response_packet_;
|
| +};
|
|
|
| class MDnsConnectionTest : public ::testing::Test {
|
| public:
|
| - MDnsConnectionTest() : connection_(&delegate_) {
|
| - EXPECT_TRUE(ParseIPLiteralToNumber("224.0.0.251", &multicast_address4_));
|
| - // TODO(noamsml): Figure out why client socket fails to connect to ipv6
|
| - // multicast address.
|
| - EXPECT_TRUE(ParseIPLiteralToNumber("::1", &multicast_address6_));
|
| - connection_.Init();
|
| + MDnsConnectionTest() : connection_(&socket_ipv4_, &socket_ipv6_, &delegate_) {
|
| }
|
| +
|
| protected:
|
| - IPAddressNumber multicast_address4_;
|
| - IPAddressNumber multicast_address6_;
|
| + // Follow successful connection initialization
|
| + void InitConnection() {
|
| + EXPECT_CALL(socket_ipv4_, AllowAddressReuse());
|
| + EXPECT_CALL(socket_ipv6_, AllowAddressReuse());
|
| +
|
| + EXPECT_CALL(socket_ipv4_, SetMulticastLoopbackMode(false));
|
| + EXPECT_CALL(socket_ipv6_, SetMulticastLoopbackMode(false));
|
| +
|
| + EXPECT_CALL(socket_ipv4_, ListenInternal("0.0.0.0:5353"))
|
| + .WillOnce(Return(OK));
|
| + EXPECT_CALL(socket_ipv6_, ListenInternal("[::]:5353"))
|
| + .WillOnce(Return(OK));
|
| +
|
| + EXPECT_CALL(socket_ipv4_, JoinGroupInternal("224.0.0.251"))
|
| + .WillOnce(Return(OK));
|
| + EXPECT_CALL(socket_ipv6_, JoinGroupInternal("ff02::fb"))
|
| + .WillOnce(Return(OK));
|
| +
|
| + connection_.Init();
|
| + }
|
| +
|
| StrictMock<MockMDnsConnectionDelegate> delegate_;
|
|
|
| + MockDatagramServerSocket socket_ipv4_;
|
| + MockDatagramServerSocket socket_ipv6_;
|
| MDnsConnectionImpl connection_;
|
| TestCompletionCallback callback_;
|
| };
|
|
|
| -TEST_F(MDnsConnectionTest, DISABLED_Recieve4) {
|
| - scoped_refptr<IOBuffer> buf(new IOBuffer(sizeof(kSamplePacket1)));
|
| +TEST_F(MDnsConnectionTest, RecieveSynchronous) {
|
| + std::string sample_packet =
|
| + std::string(kSamplePacket1, sizeof(kSamplePacket1));
|
| + socket_ipv6_.SetResponsePacket(sample_packet);
|
| + EXPECT_CALL(socket_ipv4_, RecvFrom(_, _, _, _))
|
| + .WillOnce(Return(ERR_IO_PENDING));
|
| + EXPECT_CALL(socket_ipv6_, RecvFrom(_, _, _, _))
|
| + .WillOnce(
|
| + Invoke(&socket_ipv6_, &MockDatagramServerSocket::RespondImmediately))
|
| + .WillOnce(Return(ERR_IO_PENDING));
|
| +
|
| + EXPECT_CALL(delegate_, HandlePacketInternal(sample_packet));
|
| +
|
| + InitConnection();
|
| +}
|
| +
|
| +TEST_F(MDnsConnectionTest, RecieveAsynchronous) {
|
| + std::string sample_packet =
|
| + std::string(kSamplePacket1, sizeof(kSamplePacket1));
|
| + socket_ipv6_.SetResponsePacket(sample_packet);
|
| + EXPECT_CALL(socket_ipv4_, RecvFrom(_, _, _, _))
|
| + .WillOnce(Return(ERR_IO_PENDING));
|
| + EXPECT_CALL(socket_ipv6_, RecvFrom(_, _, _, _))
|
| + .WillOnce(
|
| + Invoke(&socket_ipv6_, &MockDatagramServerSocket::RespondDelayed))
|
| + .WillOnce(Return(ERR_IO_PENDING));
|
| +
|
| + InitConnection();
|
| +
|
| + EXPECT_CALL(delegate_, HandlePacketInternal(sample_packet));
|
| +
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| +}
|
| +
|
| +TEST_F(MDnsConnectionTest, Send) {
|
| + std::string sample_packet =
|
| + std::string(kSamplePacket1, sizeof(kSamplePacket1));
|
| +
|
| + scoped_refptr<IOBufferWithSize> buf(
|
| + new IOBufferWithSize(sizeof kSamplePacket1));
|
| memcpy(buf->data(), kSamplePacket1, sizeof(kSamplePacket1));
|
| - UDPSocket socket(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL, NetLog::Source());
|
| - EXPECT_CALL(delegate_, OnHandlePacket(std::string(kSamplePacket1,
|
| - sizeof(kSamplePacket1))));
|
| -
|
| - EXPECT_EQ(OK, socket.Connect(IPEndPoint(multicast_address4_, 5353)));
|
| - int rv = socket.Write(buf, sizeof(kSamplePacket1), callback_.callback());
|
| - if (rv == ERR_IO_PENDING) {
|
| - rv = callback_.GetResult(rv);
|
| - }
|
| - EXPECT_GT(rv, OK);
|
| - base::MessageLoop::current()->RunUntilIdle(); // Socket uses message loop.
|
| +
|
| + EXPECT_CALL(socket_ipv4_, RecvFrom(_, _, _, _))
|
| + .WillOnce(Return(ERR_IO_PENDING));
|
| + EXPECT_CALL(socket_ipv6_, RecvFrom(_, _, _, _))
|
| + .WillOnce(Return(ERR_IO_PENDING));
|
| +
|
| + InitConnection();
|
| +
|
| + EXPECT_CALL(socket_ipv4_,
|
| + SendToInternal(sample_packet, "224.0.0.251:5353", _));
|
| + EXPECT_CALL(socket_ipv6_,
|
| + SendToInternal(sample_packet, "[ff02::fb]:5353", _));
|
| +
|
| + connection_.Send(buf, buf->size());
|
| }
|
|
|
| -TEST_F(MDnsConnectionTest, DISABLED_Recieve6) {
|
| - scoped_refptr<IOBuffer> buf(new IOBuffer(sizeof(kSamplePacket2)));
|
| - memcpy(buf->data(), kSamplePacket2, sizeof(kSamplePacket2));
|
| - UDPSocket socket(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL, NetLog::Source());
|
| - EXPECT_CALL(delegate_, OnHandlePacket(std::string(kSamplePacket2,
|
| - sizeof(kSamplePacket2))));
|
| -
|
| - EXPECT_EQ(OK, socket.Connect(IPEndPoint(multicast_address6_, 5353)));
|
| - int rv = socket.Write(buf, sizeof(kSamplePacket2), callback_.callback());
|
| - if (rv == ERR_IO_PENDING) {
|
| - rv = callback_.GetResult(rv);
|
| - }
|
| - EXPECT_GT(rv, OK);
|
| - base::MessageLoop::current()->RunUntilIdle(); // Socket uses message loop.
|
| +TEST_F(MDnsConnectionTest, Error) {
|
| + CompletionCallback callback;
|
| +
|
| + EXPECT_CALL(socket_ipv4_, RecvFrom(_, _, _, _))
|
| + .WillOnce(Return(ERR_IO_PENDING));
|
| + EXPECT_CALL(socket_ipv6_, RecvFrom(_, _, _, _))
|
| + .WillOnce(DoAll(SaveArg<3>(&callback), Return(ERR_IO_PENDING)));
|
| +
|
| + InitConnection();
|
| +
|
| + EXPECT_CALL(delegate_, OnConnectionError(ERR_SOCKET_NOT_CONNECTED));
|
| + callback.Run(ERR_SOCKET_NOT_CONNECTED);
|
| }
|
|
|
| } // namespace
|
|
|