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