OLD | NEW |
1 // Copyright (c) 2012 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/protocol/buffered_socket_writer.h" | 5 #include "remoting/base/buffered_socket_writer.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
14 #include "remoting/protocol/fake_session.h" | 14 #include "net/socket/socket_test_util.h" |
15 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 namespace remoting { | 18 namespace remoting { |
19 namespace protocol { | |
20 | 19 |
21 namespace { | 20 namespace { |
22 const int kTestBufferSize = 10 * 1024; // 10k; | 21 const int kTestBufferSize = 10 * 1024; // 10k; |
23 const size_t kWriteChunkSize = 1024U; | 22 const size_t kWriteChunkSize = 1024U; |
| 23 |
| 24 class SocketDataProvider: public net::SocketDataProvider { |
| 25 public: |
| 26 SocketDataProvider() |
| 27 : write_limit_(-1), async_write_(false), next_write_error_(net::OK) {} |
| 28 |
| 29 net::MockRead GetNextRead() override { |
| 30 return net::MockRead(net::ASYNC, net::ERR_IO_PENDING); |
| 31 } |
| 32 |
| 33 net::MockWriteResult OnWrite(const std::string& data) override { |
| 34 if (next_write_error_ != net::OK) { |
| 35 int r = next_write_error_; |
| 36 next_write_error_ = net::OK; |
| 37 return net::MockWriteResult(async_write_ ? net::ASYNC : net::SYNCHRONOUS, |
| 38 r); |
| 39 } |
| 40 int size = data.size(); |
| 41 if (write_limit_ > 0) |
| 42 size = std::min(write_limit_, size); |
| 43 written_data_.append(data, 0, size); |
| 44 return net::MockWriteResult(async_write_ ? net::ASYNC : net::SYNCHRONOUS, |
| 45 size); |
| 46 } |
| 47 |
| 48 void Reset() override {} |
| 49 |
| 50 std::string written_data() { return written_data_; } |
| 51 |
| 52 void set_write_limit(int limit) { write_limit_ = limit; } |
| 53 void set_async_write(bool async_write) { async_write_ = async_write; } |
| 54 void set_next_write_error(int error) { next_write_error_ = error; } |
| 55 |
| 56 private: |
| 57 std::string written_data_; |
| 58 int write_limit_; |
| 59 bool async_write_; |
| 60 int next_write_error_; |
| 61 }; |
| 62 |
24 } // namespace | 63 } // namespace |
25 | 64 |
26 class BufferedSocketWriterTest : public testing::Test { | 65 class BufferedSocketWriterTest : public testing::Test { |
27 public: | 66 public: |
28 BufferedSocketWriterTest() | 67 BufferedSocketWriterTest() |
29 : write_error_(0) { | 68 : write_error_(0) { |
30 } | 69 } |
31 | 70 |
32 void OnDone() { | 71 void DestroyWriter() { |
33 base::MessageLoop::current()->PostTask(FROM_HERE, | |
34 base::MessageLoop::QuitClosure()); | |
35 } | |
36 | |
37 void DestroyWriterAndQuit() { | |
38 written_data_ = socket_->written_data(); | |
39 writer_.reset(); | 72 writer_.reset(); |
40 socket_.reset(); | 73 socket_.reset(); |
41 base::MessageLoop::current()->PostTask(FROM_HERE, | |
42 base::MessageLoop::QuitClosure()); | |
43 } | 74 } |
44 | 75 |
45 void Unexpected() { | 76 void Unexpected() { |
46 EXPECT_TRUE(false); | 77 EXPECT_TRUE(false); |
47 } | 78 } |
48 | 79 |
49 protected: | 80 protected: |
50 void SetUp() override { | 81 void SetUp() override { |
51 socket_.reset(new FakeStreamSocket()); | 82 socket_.reset(new net::MockTCPClientSocket(net::AddressList(), &net_log_, |
| 83 &socket_data_provider_)); |
| 84 socket_data_provider_.set_connect_data( |
| 85 net::MockConnect(net::SYNCHRONOUS, net::OK)); |
| 86 EXPECT_EQ(net::OK, socket_->Connect(net::CompletionCallback())); |
| 87 |
52 writer_.reset(new BufferedSocketWriter()); | 88 writer_.reset(new BufferedSocketWriter()); |
53 writer_->Init(socket_.get(), base::Bind( | 89 writer_->Init(socket_.get(), base::Bind( |
54 &BufferedSocketWriterTest::OnWriteFailed, base::Unretained(this))); | 90 &BufferedSocketWriterTest::OnWriteFailed, base::Unretained(this))); |
55 test_buffer_ = new net::IOBufferWithSize(kTestBufferSize); | 91 test_buffer_ = new net::IOBufferWithSize(kTestBufferSize); |
56 test_buffer_2_ = new net::IOBufferWithSize(kTestBufferSize); | 92 test_buffer_2_ = new net::IOBufferWithSize(kTestBufferSize); |
57 for (int i = 0; i< kTestBufferSize; ++i) { | 93 for (int i = 0; i< kTestBufferSize; ++i) { |
58 test_buffer_->data()[i] = rand() % 256; | 94 test_buffer_->data()[i] = rand() % 256; |
59 test_buffer_2_->data()[i] = rand() % 256; | 95 test_buffer_2_->data()[i] = rand() % 256; |
60 } | 96 } |
61 } | 97 } |
62 | 98 |
63 void OnWriteFailed(int error) { | 99 void OnWriteFailed(int error) { |
64 write_error_ = error; | 100 write_error_ = error; |
65 } | 101 } |
66 | 102 |
67 void TestWrite() { | 103 void TestWrite() { |
68 writer_->Write(test_buffer_, base::Bind(&BufferedSocketWriterTest::OnDone, | 104 writer_->Write(test_buffer_, base::Closure()); |
69 base::Unretained(this))); | 105 writer_->Write(test_buffer_2_, base::Closure()); |
70 writer_->Write(test_buffer_2_, base::Bind(&BufferedSocketWriterTest::OnDone, | 106 base::RunLoop().RunUntilIdle(); |
71 base::Unretained(this))); | |
72 message_loop_.Run(); | |
73 ASSERT_EQ(static_cast<size_t>(test_buffer_->size() + | 107 ASSERT_EQ(static_cast<size_t>(test_buffer_->size() + |
74 test_buffer_2_->size()), | 108 test_buffer_2_->size()), |
75 socket_->written_data().size()); | 109 socket_data_provider_.written_data().size()); |
76 EXPECT_EQ(0, memcmp(test_buffer_->data(), socket_->written_data().data(), | 110 EXPECT_EQ(0, memcmp(test_buffer_->data(), |
| 111 socket_data_provider_.written_data().data(), |
77 test_buffer_->size())); | 112 test_buffer_->size())); |
78 EXPECT_EQ(0, memcmp(test_buffer_2_->data(), | 113 EXPECT_EQ(0, memcmp(test_buffer_2_->data(), |
79 socket_->written_data().data() + test_buffer_->size(), | 114 socket_data_provider_.written_data().data() + |
| 115 test_buffer_->size(), |
80 test_buffer_2_->size())); | 116 test_buffer_2_->size())); |
81 } | 117 } |
82 | 118 |
83 void TestAppendInCallback() { | 119 void TestAppendInCallback() { |
84 writer_->Write(test_buffer_, base::Bind( | 120 writer_->Write(test_buffer_, base::Bind( |
85 base::IgnoreResult(&BufferedSocketWriterBase::Write), | 121 base::IgnoreResult(&BufferedSocketWriterBase::Write), |
86 base::Unretained(writer_.get()), test_buffer_2_, | 122 base::Unretained(writer_.get()), test_buffer_2_, |
87 base::Bind(&BufferedSocketWriterTest::OnDone, | 123 base::Closure())); |
88 base::Unretained(this)))); | 124 base::RunLoop().RunUntilIdle(); |
89 message_loop_.Run(); | |
90 ASSERT_EQ(static_cast<size_t>(test_buffer_->size() + | 125 ASSERT_EQ(static_cast<size_t>(test_buffer_->size() + |
91 test_buffer_2_->size()), | 126 test_buffer_2_->size()), |
92 socket_->written_data().size()); | 127 socket_data_provider_.written_data().size()); |
93 EXPECT_EQ(0, memcmp(test_buffer_->data(), socket_->written_data().data(), | 128 EXPECT_EQ(0, memcmp(test_buffer_->data(), |
| 129 socket_data_provider_.written_data().data(), |
94 test_buffer_->size())); | 130 test_buffer_->size())); |
95 EXPECT_EQ(0, memcmp(test_buffer_2_->data(), | 131 EXPECT_EQ(0, memcmp(test_buffer_2_->data(), |
96 socket_->written_data().data() + test_buffer_->size(), | 132 socket_data_provider_.written_data().data() + |
| 133 test_buffer_->size(), |
97 test_buffer_2_->size())); | 134 test_buffer_2_->size())); |
98 } | 135 } |
99 | 136 |
100 base::MessageLoop message_loop_; | 137 base::MessageLoop message_loop_; |
101 scoped_ptr<FakeStreamSocket> socket_; | 138 net::NetLog net_log_; |
| 139 SocketDataProvider socket_data_provider_; |
| 140 scoped_ptr<net::StreamSocket> socket_; |
102 scoped_ptr<BufferedSocketWriter> writer_; | 141 scoped_ptr<BufferedSocketWriter> writer_; |
103 scoped_refptr<net::IOBufferWithSize> test_buffer_; | 142 scoped_refptr<net::IOBufferWithSize> test_buffer_; |
104 scoped_refptr<net::IOBufferWithSize> test_buffer_2_; | 143 scoped_refptr<net::IOBufferWithSize> test_buffer_2_; |
105 std::string written_data_; | |
106 int write_error_; | 144 int write_error_; |
107 }; | 145 }; |
108 | 146 |
109 // Test synchronous write. | 147 // Test synchronous write. |
110 TEST_F(BufferedSocketWriterTest, WriteFull) { | 148 TEST_F(BufferedSocketWriterTest, WriteFull) { |
111 TestWrite(); | 149 TestWrite(); |
112 } | 150 } |
113 | 151 |
114 // Test synchronous write in 1k chunks. | 152 // Test synchronous write in 1k chunks. |
115 TEST_F(BufferedSocketWriterTest, WriteChunks) { | 153 TEST_F(BufferedSocketWriterTest, WriteChunks) { |
116 socket_->set_write_limit(kWriteChunkSize); | 154 socket_data_provider_.set_write_limit(kWriteChunkSize); |
117 TestWrite(); | 155 TestWrite(); |
118 } | 156 } |
119 | 157 |
120 // Test asynchronous write. | 158 // Test asynchronous write. |
121 TEST_F(BufferedSocketWriterTest, WriteAsync) { | 159 TEST_F(BufferedSocketWriterTest, WriteAsync) { |
122 socket_->set_async_write(true); | 160 socket_data_provider_.set_async_write(true); |
123 socket_->set_write_limit(kWriteChunkSize); | 161 socket_data_provider_.set_write_limit(kWriteChunkSize); |
124 TestWrite(); | 162 TestWrite(); |
125 } | 163 } |
126 | 164 |
127 // Make sure we can call Write() from the done callback. | 165 // Make sure we can call Write() from the done callback. |
128 TEST_F(BufferedSocketWriterTest, AppendInCallbackSync) { | 166 TEST_F(BufferedSocketWriterTest, AppendInCallbackSync) { |
129 TestAppendInCallback(); | 167 TestAppendInCallback(); |
130 } | 168 } |
131 | 169 |
132 // Make sure we can call Write() from the done callback. | 170 // Make sure we can call Write() from the done callback. |
133 TEST_F(BufferedSocketWriterTest, AppendInCallbackAsync) { | 171 TEST_F(BufferedSocketWriterTest, AppendInCallbackAsync) { |
134 socket_->set_async_write(true); | 172 socket_data_provider_.set_async_write(true); |
135 socket_->set_write_limit(kWriteChunkSize); | 173 socket_data_provider_.set_write_limit(kWriteChunkSize); |
136 TestAppendInCallback(); | 174 TestAppendInCallback(); |
137 } | 175 } |
138 | 176 |
139 // Test that the writer can be destroyed from callback. | 177 // Test that the writer can be destroyed from callback. |
140 TEST_F(BufferedSocketWriterTest, DestroyFromCallback) { | 178 TEST_F(BufferedSocketWriterTest, DestroyFromCallback) { |
141 socket_->set_async_write(true); | 179 socket_data_provider_.set_async_write(true); |
142 writer_->Write(test_buffer_, base::Bind( | 180 writer_->Write(test_buffer_, base::Bind( |
143 &BufferedSocketWriterTest::DestroyWriterAndQuit, | 181 &BufferedSocketWriterTest::DestroyWriter, |
144 base::Unretained(this))); | 182 base::Unretained(this))); |
145 writer_->Write(test_buffer_2_, base::Bind( | 183 writer_->Write(test_buffer_2_, base::Bind( |
146 &BufferedSocketWriterTest::Unexpected, | 184 &BufferedSocketWriterTest::Unexpected, |
147 base::Unretained(this))); | 185 base::Unretained(this))); |
148 socket_->set_async_write(false); | 186 socket_data_provider_.set_async_write(false); |
149 message_loop_.Run(); | 187 base::RunLoop().RunUntilIdle(); |
150 ASSERT_GE(written_data_.size(), | 188 ASSERT_GE(socket_data_provider_.written_data().size(), |
151 static_cast<size_t>(test_buffer_->size())); | 189 static_cast<size_t>(test_buffer_->size())); |
152 EXPECT_EQ(0, memcmp(test_buffer_->data(), written_data_.data(), | 190 EXPECT_EQ(0, memcmp(test_buffer_->data(), |
| 191 socket_data_provider_.written_data().data(), |
153 test_buffer_->size())); | 192 test_buffer_->size())); |
154 } | 193 } |
155 | 194 |
156 // Verify that it stops writing after the first error. | 195 // Verify that it stops writing after the first error. |
157 TEST_F(BufferedSocketWriterTest, TestWriteErrorSync) { | 196 TEST_F(BufferedSocketWriterTest, TestWriteErrorSync) { |
158 socket_->set_write_limit(kWriteChunkSize); | 197 socket_data_provider_.set_write_limit(kWriteChunkSize); |
159 writer_->Write(test_buffer_, base::Closure()); | 198 writer_->Write(test_buffer_, base::Closure()); |
160 socket_->set_async_write(true); | 199 socket_data_provider_.set_async_write(true); |
| 200 socket_data_provider_.set_next_write_error(net::ERR_FAILED); |
161 writer_->Write(test_buffer_2_, | 201 writer_->Write(test_buffer_2_, |
162 base::Bind(&BufferedSocketWriterTest::Unexpected, | 202 base::Bind(&BufferedSocketWriterTest::Unexpected, |
163 base::Unretained(this))); | 203 base::Unretained(this))); |
164 socket_->set_next_write_error(net::ERR_FAILED); | 204 socket_data_provider_.set_async_write(false); |
165 socket_->set_async_write(false); | |
166 base::RunLoop().RunUntilIdle(); | 205 base::RunLoop().RunUntilIdle(); |
167 EXPECT_EQ(net::ERR_FAILED, write_error_); | 206 EXPECT_EQ(net::ERR_FAILED, write_error_); |
168 EXPECT_EQ(static_cast<size_t>(test_buffer_->size()), | 207 EXPECT_EQ(static_cast<size_t>(test_buffer_->size()), |
169 socket_->written_data().size()); | 208 socket_data_provider_.written_data().size()); |
170 } | 209 } |
171 | 210 |
172 // Verify that it stops writing after the first error. | 211 // Verify that it stops writing after the first error. |
173 TEST_F(BufferedSocketWriterTest, TestWriteErrorAsync) { | 212 TEST_F(BufferedSocketWriterTest, TestWriteErrorAsync) { |
174 socket_->set_write_limit(kWriteChunkSize); | 213 socket_data_provider_.set_write_limit(kWriteChunkSize); |
175 writer_->Write(test_buffer_, base::Closure()); | 214 writer_->Write(test_buffer_, base::Closure()); |
176 socket_->set_async_write(true); | 215 socket_data_provider_.set_async_write(true); |
| 216 socket_data_provider_.set_next_write_error(net::ERR_FAILED); |
177 writer_->Write(test_buffer_2_, | 217 writer_->Write(test_buffer_2_, |
178 base::Bind(&BufferedSocketWriterTest::Unexpected, | 218 base::Bind(&BufferedSocketWriterTest::Unexpected, |
179 base::Unretained(this))); | 219 base::Unretained(this))); |
180 socket_->set_next_write_error(net::ERR_FAILED); | |
181 base::RunLoop().RunUntilIdle(); | 220 base::RunLoop().RunUntilIdle(); |
182 EXPECT_EQ(net::ERR_FAILED, write_error_); | 221 EXPECT_EQ(net::ERR_FAILED, write_error_); |
183 EXPECT_EQ(static_cast<size_t>(test_buffer_->size()), | 222 EXPECT_EQ(static_cast<size_t>(test_buffer_->size()), |
184 socket_->written_data().size()); | 223 socket_data_provider_.written_data().size()); |
185 } | 224 } |
186 | 225 |
187 } // namespace protocol | |
188 } // namespace remoting | 226 } // namespace remoting |
189 | |
OLD | NEW |