OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <string> | 5 #include <string> |
6 | 6 |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
9 #include "blimp/net/blimp_connection_statistics.h" | |
10 #include "blimp/net/common.h" | 9 #include "blimp/net/common.h" |
11 #include "blimp/net/stream_packet_writer.h" | 10 #include "blimp/net/stream_packet_writer.h" |
12 #include "blimp/net/test_common.h" | 11 #include "blimp/net/test_common.h" |
13 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
14 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
15 #include "net/base/test_completion_callback.h" | 14 #include "net/base/test_completion_callback.h" |
16 #include "net/socket/socket.h" | 15 #include "net/socket/socket.h" |
17 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
19 | 18 |
20 using testing::_; | 19 using testing::_; |
21 using testing::DoAll; | 20 using testing::DoAll; |
22 using testing::InSequence; | 21 using testing::InSequence; |
23 using testing::Mock; | 22 using testing::Mock; |
24 using testing::NotNull; | 23 using testing::NotNull; |
25 using testing::Return; | 24 using testing::Return; |
26 using testing::SaveArg; | 25 using testing::SaveArg; |
27 | 26 |
28 namespace blimp { | 27 namespace blimp { |
29 namespace { | 28 namespace { |
30 | 29 |
31 class StreamPacketWriterTest : public testing::Test { | 30 class StreamPacketWriterTest : public testing::Test { |
32 public: | 31 public: |
33 StreamPacketWriterTest() | 32 StreamPacketWriterTest() |
34 : test_data_( | 33 : test_data_( |
35 new net::DrainableIOBuffer(new net::StringIOBuffer(test_data_str_), | 34 new net::DrainableIOBuffer(new net::StringIOBuffer(test_data_str_), |
36 test_data_str_.size())), | 35 test_data_str_.size())), |
37 message_writer_(&socket_, &statistics_) {} | 36 message_writer_(&socket_) {} |
38 | 37 |
39 protected: | 38 protected: |
40 const std::string test_data_str_ = "U WOT M8"; | 39 const std::string test_data_str_ = "U WOT M8"; |
41 scoped_refptr<net::DrainableIOBuffer> test_data_; | 40 scoped_refptr<net::DrainableIOBuffer> test_data_; |
42 | 41 |
43 base::MessageLoop message_loop_; | 42 base::MessageLoop message_loop_; |
44 MockStreamSocket socket_; | 43 MockStreamSocket socket_; |
45 BlimpConnectionStatistics statistics_; | |
46 StreamPacketWriter message_writer_; | 44 StreamPacketWriter message_writer_; |
47 testing::InSequence mock_sequence_; | 45 testing::InSequence mock_sequence_; |
48 | 46 |
49 private: | 47 private: |
50 DISALLOW_COPY_AND_ASSIGN(StreamPacketWriterTest); | 48 DISALLOW_COPY_AND_ASSIGN(StreamPacketWriterTest); |
51 }; | 49 }; |
52 | 50 |
53 // Successful write with 1 async header write and 1 async payload write. | 51 // Successful write with 1 async header write and 1 async payload write. |
54 TEST_F(StreamPacketWriterTest, TestWriteAsync) { | 52 TEST_F(StreamPacketWriterTest, TestWriteAsync) { |
55 net::TestCompletionCallback writer_cb; | 53 net::TestCompletionCallback writer_cb; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 .WillOnce(DoAll(SaveArg<2>(&payload_cb), Return(net::ERR_IO_PENDING))) | 87 .WillOnce(DoAll(SaveArg<2>(&payload_cb), Return(net::ERR_IO_PENDING))) |
90 .RetiresOnSaturation(); | 88 .RetiresOnSaturation(); |
91 EXPECT_CALL(socket_, | 89 EXPECT_CALL(socket_, |
92 Write(BufferEquals(payload.substr(1, payload.size() - 1)), | 90 Write(BufferEquals(payload.substr(1, payload.size() - 1)), |
93 payload.size() - 1, _)) | 91 payload.size() - 1, _)) |
94 .WillOnce(DoAll(SaveArg<2>(&payload_cb), Return(net::ERR_IO_PENDING))) | 92 .WillOnce(DoAll(SaveArg<2>(&payload_cb), Return(net::ERR_IO_PENDING))) |
95 .RetiresOnSaturation(); | 93 .RetiresOnSaturation(); |
96 | 94 |
97 message_writer_.WritePacket(test_data_, writer_cb.callback()); | 95 message_writer_.WritePacket(test_data_, writer_cb.callback()); |
98 | 96 |
99 EXPECT_EQ(static_cast<int>(payload.size()), | |
100 statistics_.Get(BlimpConnectionStatistics::BYTES_SENT)); | |
101 | |
102 // Header is written - first one byte, then the remainder. | 97 // Header is written - first one byte, then the remainder. |
103 header_cb.Run(1); | 98 header_cb.Run(1); |
104 header_cb.Run(header.size() - 1); | 99 header_cb.Run(header.size() - 1); |
105 | 100 |
106 // Payload is written - first one byte, then the remainder. | 101 // Payload is written - first one byte, then the remainder. |
107 payload_cb.Run(1); | 102 payload_cb.Run(1); |
108 payload_cb.Run(payload.size() - 1); | 103 payload_cb.Run(payload.size() - 1); |
109 | 104 |
110 EXPECT_EQ(net::OK, writer_cb.WaitForResult()); | 105 EXPECT_EQ(net::OK, writer_cb.WaitForResult()); |
111 } | 106 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 message_writer_.WritePacket(test_data_, writer_cb.callback()); | 191 message_writer_.WritePacket(test_data_, writer_cb.callback()); |
197 EXPECT_EQ(net::ERR_FAILED, writer_cb.WaitForResult()); | 192 EXPECT_EQ(net::ERR_FAILED, writer_cb.WaitForResult()); |
198 } | 193 } |
199 | 194 |
200 // Verify that asynchronous header write completions don't cause a | 195 // Verify that asynchronous header write completions don't cause a |
201 // use-after-free error if the writer object is deleted. | 196 // use-after-free error if the writer object is deleted. |
202 TEST_F(StreamPacketWriterTest, DeletedDuringHeaderWrite) { | 197 TEST_F(StreamPacketWriterTest, DeletedDuringHeaderWrite) { |
203 net::TestCompletionCallback writer_cb; | 198 net::TestCompletionCallback writer_cb; |
204 net::CompletionCallback header_cb; | 199 net::CompletionCallback header_cb; |
205 net::CompletionCallback payload_cb; | 200 net::CompletionCallback payload_cb; |
206 std::unique_ptr<StreamPacketWriter> writer( | 201 std::unique_ptr<StreamPacketWriter> writer(new StreamPacketWriter(&socket_)); |
207 new StreamPacketWriter(&socket_, &statistics_)); | |
208 | 202 |
209 // Write header. | 203 // Write header. |
210 EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())), | 204 EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())), |
211 kPacketHeaderSizeBytes, _)) | 205 kPacketHeaderSizeBytes, _)) |
212 .WillOnce(DoAll(SaveArg<2>(&header_cb), Return(net::ERR_IO_PENDING))); | 206 .WillOnce(DoAll(SaveArg<2>(&header_cb), Return(net::ERR_IO_PENDING))); |
213 writer->WritePacket(test_data_, writer_cb.callback()); | 207 writer->WritePacket(test_data_, writer_cb.callback()); |
214 Mock::VerifyAndClearExpectations(&socket_); | 208 Mock::VerifyAndClearExpectations(&socket_); |
215 | 209 |
216 // Header write completion callback is invoked after the writer died. | 210 // Header write completion callback is invoked after the writer died. |
217 writer.reset(); | 211 writer.reset(); |
218 header_cb.Run(kPacketHeaderSizeBytes); | 212 header_cb.Run(kPacketHeaderSizeBytes); |
219 } | 213 } |
220 | 214 |
221 // Verify that asynchronous payload write completions don't cause a | 215 // Verify that asynchronous payload write completions don't cause a |
222 // use-after-free error if the writer object is deleted. | 216 // use-after-free error if the writer object is deleted. |
223 TEST_F(StreamPacketWriterTest, DeletedDuringPayloadWrite) { | 217 TEST_F(StreamPacketWriterTest, DeletedDuringPayloadWrite) { |
224 net::TestCompletionCallback writer_cb; | 218 net::TestCompletionCallback writer_cb; |
225 net::CompletionCallback header_cb; | 219 net::CompletionCallback header_cb; |
226 net::CompletionCallback payload_cb; | 220 net::CompletionCallback payload_cb; |
227 std::unique_ptr<StreamPacketWriter> writer( | 221 std::unique_ptr<StreamPacketWriter> writer(new StreamPacketWriter(&socket_)); |
228 new StreamPacketWriter(&socket_, &statistics_)); | |
229 | 222 |
230 EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())), | 223 EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())), |
231 kPacketHeaderSizeBytes, _)) | 224 kPacketHeaderSizeBytes, _)) |
232 .WillOnce(DoAll(SaveArg<2>(&header_cb), Return(net::ERR_IO_PENDING))); | 225 .WillOnce(DoAll(SaveArg<2>(&header_cb), Return(net::ERR_IO_PENDING))); |
233 EXPECT_CALL(socket_, | 226 EXPECT_CALL(socket_, |
234 Write(BufferEquals(test_data_str_), test_data_str_.size(), _)) | 227 Write(BufferEquals(test_data_str_), test_data_str_.size(), _)) |
235 .WillOnce(DoAll(SaveArg<2>(&payload_cb), Return(net::ERR_IO_PENDING))); | 228 .WillOnce(DoAll(SaveArg<2>(&payload_cb), Return(net::ERR_IO_PENDING))); |
236 | 229 |
237 writer->WritePacket(test_data_, writer_cb.callback()); | 230 writer->WritePacket(test_data_, writer_cb.callback()); |
238 | 231 |
239 // Header write completes successfully. | 232 // Header write completes successfully. |
240 header_cb.Run(kPacketHeaderSizeBytes); | 233 header_cb.Run(kPacketHeaderSizeBytes); |
241 | 234 |
242 // Payload write completion callback is invoked after the writer died. | 235 // Payload write completion callback is invoked after the writer died. |
243 writer.reset(); | 236 writer.reset(); |
244 payload_cb.Run(test_data_str_.size()); | 237 payload_cb.Run(test_data_str_.size()); |
245 } | 238 } |
246 | 239 |
247 } // namespace | 240 } // namespace |
248 } // namespace blimp | 241 } // namespace blimp |
OLD | NEW |