| 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 "remoting/base/buffered_socket_writer.h" | 5 #include "remoting/base/buffered_socket_writer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 13 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
| 14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/socket/socket_test_util.h" | 15 #include "net/socket/socket_test_util.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 namespace remoting { | 19 namespace remoting { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 const int kTestBufferSize = 10000; | 23 const int kTestBufferSize = 10000; |
| 24 const size_t kWriteChunkSize = 1024U; | 24 const size_t kWriteChunkSize = 1024U; |
| 25 | 25 |
| 26 int WriteNetSocket(net::Socket* socket, |
| 27 const scoped_refptr<net::IOBuffer>& buf, |
| 28 int buf_len, |
| 29 const net::CompletionCallback& callback) { |
| 30 return socket->Write(buf.get(), buf_len, callback); |
| 31 } |
| 32 |
| 26 class SocketDataProvider: public net::SocketDataProvider { | 33 class SocketDataProvider: public net::SocketDataProvider { |
| 27 public: | 34 public: |
| 28 SocketDataProvider() | 35 SocketDataProvider() |
| 29 : write_limit_(-1), async_write_(false), next_write_error_(net::OK) {} | 36 : write_limit_(-1), async_write_(false), next_write_error_(net::OK) {} |
| 30 | 37 |
| 31 net::MockRead OnRead() override { | 38 net::MockRead OnRead() override { |
| 32 return net::MockRead(net::ASYNC, net::ERR_IO_PENDING); | 39 return net::MockRead(net::ASYNC, net::ERR_IO_PENDING); |
| 33 } | 40 } |
| 34 | 41 |
| 35 net::MockWriteResult OnWrite(const std::string& data) override { | 42 net::MockWriteResult OnWrite(const std::string& data) override { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 } | 95 } |
| 89 | 96 |
| 90 protected: | 97 protected: |
| 91 void SetUp() override { | 98 void SetUp() override { |
| 92 socket_.reset(new net::MockTCPClientSocket(net::AddressList(), &net_log_, | 99 socket_.reset(new net::MockTCPClientSocket(net::AddressList(), &net_log_, |
| 93 &socket_data_provider_)); | 100 &socket_data_provider_)); |
| 94 socket_data_provider_.set_connect_data( | 101 socket_data_provider_.set_connect_data( |
| 95 net::MockConnect(net::SYNCHRONOUS, net::OK)); | 102 net::MockConnect(net::SYNCHRONOUS, net::OK)); |
| 96 EXPECT_EQ(net::OK, socket_->Connect(net::CompletionCallback())); | 103 EXPECT_EQ(net::OK, socket_->Connect(net::CompletionCallback())); |
| 97 | 104 |
| 98 writer_ = BufferedSocketWriter::CreateForSocket( | 105 writer_.reset(new BufferedSocketWriter()); |
| 99 socket_.get(), base::Bind(&BufferedSocketWriterTest::OnWriteFailed, | |
| 100 base::Unretained(this))); | |
| 101 test_buffer_ = new net::IOBufferWithSize(kTestBufferSize); | 106 test_buffer_ = new net::IOBufferWithSize(kTestBufferSize); |
| 102 test_buffer_2_ = new net::IOBufferWithSize(kTestBufferSize); | 107 test_buffer_2_ = new net::IOBufferWithSize(kTestBufferSize); |
| 103 for (int i = 0; i< kTestBufferSize; ++i) { | 108 for (int i = 0; i < kTestBufferSize; ++i) { |
| 104 test_buffer_->data()[i] = rand() % 256; | 109 test_buffer_->data()[i] = rand() % 256; |
| 105 test_buffer_2_->data()[i] = rand() % 256; | 110 test_buffer_2_->data()[i] = rand() % 256; |
| 106 } | 111 } |
| 107 } | 112 } |
| 108 | 113 |
| 114 void StartWriter() { |
| 115 writer_->Start(base::Bind(&WriteNetSocket, socket_.get()), |
| 116 base::Bind(&BufferedSocketWriterTest::OnWriteFailed, |
| 117 base::Unretained(this))); |
| 118 }; |
| 119 |
| 109 void OnWriteFailed(int error) { | 120 void OnWriteFailed(int error) { |
| 110 write_error_ = error; | 121 write_error_ = error; |
| 111 } | 122 } |
| 112 | 123 |
| 113 void TestWrite() { | 124 void VerifyWrittenData() { |
| 114 writer_->Write(test_buffer_, base::Closure()); | |
| 115 writer_->Write(test_buffer_2_, base::Closure()); | |
| 116 base::RunLoop().RunUntilIdle(); | |
| 117 ASSERT_EQ(static_cast<size_t>(test_buffer_->size() + | 125 ASSERT_EQ(static_cast<size_t>(test_buffer_->size() + |
| 118 test_buffer_2_->size()), | 126 test_buffer_2_->size()), |
| 119 socket_data_provider_.written_data().size()); | 127 socket_data_provider_.written_data().size()); |
| 120 EXPECT_EQ(0, memcmp(test_buffer_->data(), | 128 EXPECT_EQ(0, memcmp(test_buffer_->data(), |
| 121 socket_data_provider_.written_data().data(), | 129 socket_data_provider_.written_data().data(), |
| 122 test_buffer_->size())); | 130 test_buffer_->size())); |
| 123 EXPECT_EQ(0, memcmp(test_buffer_2_->data(), | 131 EXPECT_EQ(0, memcmp(test_buffer_2_->data(), |
| 124 socket_data_provider_.written_data().data() + | 132 socket_data_provider_.written_data().data() + |
| 125 test_buffer_->size(), | 133 test_buffer_->size(), |
| 126 test_buffer_2_->size())); | 134 test_buffer_2_->size())); |
| 127 } | 135 } |
| 128 | 136 |
| 137 void TestWrite() { |
| 138 writer_->Write(test_buffer_, base::Closure()); |
| 139 writer_->Write(test_buffer_2_, base::Closure()); |
| 140 base::RunLoop().RunUntilIdle(); |
| 141 VerifyWrittenData(); |
| 142 } |
| 143 |
| 129 void TestAppendInCallback() { | 144 void TestAppendInCallback() { |
| 130 writer_->Write(test_buffer_, base::Bind( | 145 writer_->Write(test_buffer_, base::Bind( |
| 131 base::IgnoreResult(&BufferedSocketWriter::Write), | 146 base::IgnoreResult(&BufferedSocketWriter::Write), |
| 132 base::Unretained(writer_.get()), test_buffer_2_, | 147 base::Unretained(writer_.get()), test_buffer_2_, |
| 133 base::Closure())); | 148 base::Closure())); |
| 134 base::RunLoop().RunUntilIdle(); | 149 base::RunLoop().RunUntilIdle(); |
| 135 ASSERT_EQ(static_cast<size_t>(test_buffer_->size() + | 150 VerifyWrittenData(); |
| 136 test_buffer_2_->size()), | |
| 137 socket_data_provider_.written_data().size()); | |
| 138 EXPECT_EQ(0, memcmp(test_buffer_->data(), | |
| 139 socket_data_provider_.written_data().data(), | |
| 140 test_buffer_->size())); | |
| 141 EXPECT_EQ(0, memcmp(test_buffer_2_->data(), | |
| 142 socket_data_provider_.written_data().data() + | |
| 143 test_buffer_->size(), | |
| 144 test_buffer_2_->size())); | |
| 145 } | 151 } |
| 146 | 152 |
| 147 base::MessageLoop message_loop_; | 153 base::MessageLoop message_loop_; |
| 148 net::NetLog net_log_; | 154 net::NetLog net_log_; |
| 149 SocketDataProvider socket_data_provider_; | 155 SocketDataProvider socket_data_provider_; |
| 150 scoped_ptr<net::StreamSocket> socket_; | 156 scoped_ptr<net::StreamSocket> socket_; |
| 151 scoped_ptr<BufferedSocketWriter> writer_; | 157 scoped_ptr<BufferedSocketWriter> writer_; |
| 152 scoped_refptr<net::IOBufferWithSize> test_buffer_; | 158 scoped_refptr<net::IOBufferWithSize> test_buffer_; |
| 153 scoped_refptr<net::IOBufferWithSize> test_buffer_2_; | 159 scoped_refptr<net::IOBufferWithSize> test_buffer_2_; |
| 154 int write_error_; | 160 int write_error_; |
| 155 }; | 161 }; |
| 156 | 162 |
| 157 // Test synchronous write. | 163 // Test synchronous write. |
| 158 TEST_F(BufferedSocketWriterTest, WriteFull) { | 164 TEST_F(BufferedSocketWriterTest, WriteFull) { |
| 165 StartWriter(); |
| 159 TestWrite(); | 166 TestWrite(); |
| 160 } | 167 } |
| 161 | 168 |
| 162 // Test synchronous write in 1k chunks. | 169 // Test synchronous write in 1k chunks. |
| 163 TEST_F(BufferedSocketWriterTest, WriteChunks) { | 170 TEST_F(BufferedSocketWriterTest, WriteChunks) { |
| 171 StartWriter(); |
| 164 socket_data_provider_.set_write_limit(kWriteChunkSize); | 172 socket_data_provider_.set_write_limit(kWriteChunkSize); |
| 165 TestWrite(); | 173 TestWrite(); |
| 166 } | 174 } |
| 167 | 175 |
| 168 // Test asynchronous write. | 176 // Test asynchronous write. |
| 169 TEST_F(BufferedSocketWriterTest, WriteAsync) { | 177 TEST_F(BufferedSocketWriterTest, WriteAsync) { |
| 178 StartWriter(); |
| 170 socket_data_provider_.set_async_write(true); | 179 socket_data_provider_.set_async_write(true); |
| 171 socket_data_provider_.set_write_limit(kWriteChunkSize); | 180 socket_data_provider_.set_write_limit(kWriteChunkSize); |
| 172 TestWrite(); | 181 TestWrite(); |
| 173 } | 182 } |
| 174 | 183 |
| 175 // Make sure we can call Write() from the done callback. | 184 // Make sure we can call Write() from the done callback. |
| 176 TEST_F(BufferedSocketWriterTest, AppendInCallbackSync) { | 185 TEST_F(BufferedSocketWriterTest, AppendInCallbackSync) { |
| 186 StartWriter(); |
| 177 TestAppendInCallback(); | 187 TestAppendInCallback(); |
| 178 } | 188 } |
| 179 | 189 |
| 180 // Make sure we can call Write() from the done callback. | 190 // Make sure we can call Write() from the done callback. |
| 181 TEST_F(BufferedSocketWriterTest, AppendInCallbackAsync) { | 191 TEST_F(BufferedSocketWriterTest, AppendInCallbackAsync) { |
| 192 StartWriter(); |
| 182 socket_data_provider_.set_async_write(true); | 193 socket_data_provider_.set_async_write(true); |
| 183 socket_data_provider_.set_write_limit(kWriteChunkSize); | 194 socket_data_provider_.set_write_limit(kWriteChunkSize); |
| 184 TestAppendInCallback(); | 195 TestAppendInCallback(); |
| 185 } | 196 } |
| 186 | 197 |
| 187 // Test that the writer can be destroyed from callback. | 198 // Test that the writer can be destroyed from callback. |
| 188 TEST_F(BufferedSocketWriterTest, DestroyFromCallback) { | 199 TEST_F(BufferedSocketWriterTest, DestroyFromCallback) { |
| 200 StartWriter(); |
| 189 socket_data_provider_.set_async_write(true); | 201 socket_data_provider_.set_async_write(true); |
| 190 writer_->Write(test_buffer_, base::Bind( | 202 writer_->Write(test_buffer_, base::Bind( |
| 191 &BufferedSocketWriterTest::DestroyWriter, | 203 &BufferedSocketWriterTest::DestroyWriter, |
| 192 base::Unretained(this))); | 204 base::Unretained(this))); |
| 193 writer_->Write(test_buffer_2_, base::Bind( | 205 writer_->Write(test_buffer_2_, base::Bind( |
| 194 &BufferedSocketWriterTest::Unexpected, | 206 &BufferedSocketWriterTest::Unexpected, |
| 195 base::Unretained(this))); | 207 base::Unretained(this))); |
| 196 socket_data_provider_.set_async_write(false); | 208 socket_data_provider_.set_async_write(false); |
| 197 base::RunLoop().RunUntilIdle(); | 209 base::RunLoop().RunUntilIdle(); |
| 198 ASSERT_GE(socket_data_provider_.written_data().size(), | 210 ASSERT_GE(socket_data_provider_.written_data().size(), |
| 199 static_cast<size_t>(test_buffer_->size())); | 211 static_cast<size_t>(test_buffer_->size())); |
| 200 EXPECT_EQ(0, memcmp(test_buffer_->data(), | 212 EXPECT_EQ(0, memcmp(test_buffer_->data(), |
| 201 socket_data_provider_.written_data().data(), | 213 socket_data_provider_.written_data().data(), |
| 202 test_buffer_->size())); | 214 test_buffer_->size())); |
| 203 } | 215 } |
| 204 | 216 |
| 205 // Verify that it stops writing after the first error. | 217 // Verify that it stops writing after the first error. |
| 206 TEST_F(BufferedSocketWriterTest, TestWriteErrorSync) { | 218 TEST_F(BufferedSocketWriterTest, TestWriteErrorSync) { |
| 219 StartWriter(); |
| 207 socket_data_provider_.set_write_limit(kWriteChunkSize); | 220 socket_data_provider_.set_write_limit(kWriteChunkSize); |
| 208 writer_->Write(test_buffer_, base::Closure()); | 221 writer_->Write(test_buffer_, base::Closure()); |
| 209 socket_data_provider_.set_async_write(true); | 222 socket_data_provider_.set_async_write(true); |
| 210 socket_data_provider_.set_next_write_error(net::ERR_FAILED); | 223 socket_data_provider_.set_next_write_error(net::ERR_FAILED); |
| 211 writer_->Write(test_buffer_2_, | 224 writer_->Write(test_buffer_2_, |
| 212 base::Bind(&BufferedSocketWriterTest::Unexpected, | 225 base::Bind(&BufferedSocketWriterTest::Unexpected, |
| 213 base::Unretained(this))); | 226 base::Unretained(this))); |
| 214 socket_data_provider_.set_async_write(false); | 227 socket_data_provider_.set_async_write(false); |
| 215 base::RunLoop().RunUntilIdle(); | 228 base::RunLoop().RunUntilIdle(); |
| 216 EXPECT_EQ(net::ERR_FAILED, write_error_); | 229 EXPECT_EQ(net::ERR_FAILED, write_error_); |
| 217 EXPECT_EQ(static_cast<size_t>(test_buffer_->size()), | 230 EXPECT_EQ(static_cast<size_t>(test_buffer_->size()), |
| 218 socket_data_provider_.written_data().size()); | 231 socket_data_provider_.written_data().size()); |
| 219 } | 232 } |
| 220 | 233 |
| 221 // Verify that it stops writing after the first error. | 234 // Verify that it stops writing after the first error. |
| 222 TEST_F(BufferedSocketWriterTest, TestWriteErrorAsync) { | 235 TEST_F(BufferedSocketWriterTest, TestWriteErrorAsync) { |
| 236 StartWriter(); |
| 223 socket_data_provider_.set_write_limit(kWriteChunkSize); | 237 socket_data_provider_.set_write_limit(kWriteChunkSize); |
| 224 writer_->Write(test_buffer_, base::Closure()); | 238 writer_->Write(test_buffer_, base::Closure()); |
| 225 socket_data_provider_.set_async_write(true); | 239 socket_data_provider_.set_async_write(true); |
| 226 socket_data_provider_.set_next_write_error(net::ERR_FAILED); | 240 socket_data_provider_.set_next_write_error(net::ERR_FAILED); |
| 227 writer_->Write(test_buffer_2_, | 241 writer_->Write(test_buffer_2_, |
| 228 base::Bind(&BufferedSocketWriterTest::Unexpected, | 242 base::Bind(&BufferedSocketWriterTest::Unexpected, |
| 229 base::Unretained(this))); | 243 base::Unretained(this))); |
| 230 base::RunLoop().RunUntilIdle(); | 244 base::RunLoop().RunUntilIdle(); |
| 231 EXPECT_EQ(net::ERR_FAILED, write_error_); | 245 EXPECT_EQ(net::ERR_FAILED, write_error_); |
| 232 EXPECT_EQ(static_cast<size_t>(test_buffer_->size()), | 246 EXPECT_EQ(static_cast<size_t>(test_buffer_->size()), |
| 233 socket_data_provider_.written_data().size()); | 247 socket_data_provider_.written_data().size()); |
| 234 } | 248 } |
| 235 | 249 |
| 250 TEST_F(BufferedSocketWriterTest, WriteBeforeStart) { |
| 251 writer_->Write(test_buffer_, base::Closure()); |
| 252 writer_->Write(test_buffer_2_, base::Closure()); |
| 253 |
| 254 StartWriter(); |
| 255 base::RunLoop().RunUntilIdle(); |
| 256 |
| 257 VerifyWrittenData(); |
| 258 } |
| 259 |
| 236 } // namespace remoting | 260 } // namespace remoting |
| OLD | NEW |