1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/protocol/buffered_socket_writer.h"
10 #include "base/message_loop/message_loop.h"
11 #include "net/base/io_buffer.h"
12 #include "net/base/net_errors.h"
13 #include "remoting/protocol/fake_session.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
21 const int kTestBufferSize
= 10 * 1024; // 10k;
22 const size_t kWriteChunkSize
= 1024U;
25 class BufferedSocketWriterTest
: public testing::Test
{
27 BufferedSocketWriterTest()
32 base::MessageLoop::current()->PostTask(FROM_HERE
,
33 base::MessageLoop::QuitClosure());
36 void DestroyWriterAndQuit() {
37 written_data_
= socket_
->written_data();
40 base::MessageLoop::current()->PostTask(FROM_HERE
,
41 base::MessageLoop::QuitClosure());
49 virtual void SetUp() OVERRIDE
{
50 socket_
.reset(new FakeSocket());
51 writer_
.reset(new BufferedSocketWriter());
52 writer_
->Init(socket_
.get(), base::Bind(
53 &BufferedSocketWriterTest::OnWriteFailed
, base::Unretained(this)));
54 test_buffer_
= new net::IOBufferWithSize(kTestBufferSize
);
55 test_buffer_2_
= new net::IOBufferWithSize(kTestBufferSize
);
56 for (int i
= 0; i
< kTestBufferSize
; ++i
) {
57 test_buffer_
->data()[i
] = rand() % 256;
58 test_buffer_2_
->data()[i
] = rand() % 256;
62 void OnWriteFailed(int error
) {
67 writer_
->Write(test_buffer_
, base::Bind(&BufferedSocketWriterTest::OnDone
,
68 base::Unretained(this)));
69 writer_
->Write(test_buffer_2_
, base::Bind(&BufferedSocketWriterTest::OnDone
,
70 base::Unretained(this)));
72 ASSERT_EQ(static_cast<size_t>(test_buffer_
->size() +
73 test_buffer_2_
->size()),
74 socket_
->written_data().size());
75 EXPECT_EQ(0, memcmp(test_buffer_
->data(), socket_
->written_data().data(),
76 test_buffer_
->size()));
77 EXPECT_EQ(0, memcmp(test_buffer_2_
->data(),
78 socket_
->written_data().data() + test_buffer_
->size(),
79 test_buffer_2_
->size()));
82 void TestAppendInCallback() {
83 writer_
->Write(test_buffer_
, base::Bind(
84 base::IgnoreResult(&BufferedSocketWriterBase::Write
),
85 base::Unretained(writer_
.get()), test_buffer_2_
,
86 base::Bind(&BufferedSocketWriterTest::OnDone
,
87 base::Unretained(this))));
89 ASSERT_EQ(static_cast<size_t>(test_buffer_
->size() +
90 test_buffer_2_
->size()),
91 socket_
->written_data().size());
92 EXPECT_EQ(0, memcmp(test_buffer_
->data(), socket_
->written_data().data(),
93 test_buffer_
->size()));
94 EXPECT_EQ(0, memcmp(test_buffer_2_
->data(),
95 socket_
->written_data().data() + test_buffer_
->size(),
96 test_buffer_2_
->size()));
99 base::MessageLoop message_loop_
;
100 scoped_ptr
<FakeSocket
> socket_
;
101 scoped_ptr
<BufferedSocketWriter
> writer_
;
102 scoped_refptr
<net::IOBufferWithSize
> test_buffer_
;
103 scoped_refptr
<net::IOBufferWithSize
> test_buffer_2_
;
104 std::string written_data_
;
108 // Test synchronous write.
109 TEST_F(BufferedSocketWriterTest
, WriteFull
) {
113 // Test synchronous write in 1k chunks.
114 TEST_F(BufferedSocketWriterTest
, WriteChunks
) {
115 socket_
->set_write_limit(kWriteChunkSize
);
119 // Test asynchronous write.
120 TEST_F(BufferedSocketWriterTest
, WriteAsync
) {
121 socket_
->set_async_write(true);
122 socket_
->set_write_limit(kWriteChunkSize
);
126 // Make sure we can call Write() from the done callback.
127 TEST_F(BufferedSocketWriterTest
, AppendInCallbackSync
) {
128 TestAppendInCallback();
131 // Make sure we can call Write() from the done callback.
132 TEST_F(BufferedSocketWriterTest
, AppendInCallbackAsync
) {
133 socket_
->set_async_write(true);
134 socket_
->set_write_limit(kWriteChunkSize
);
135 TestAppendInCallback();
138 // Test that the writer can be destroyed from callback.
139 TEST_F(BufferedSocketWriterTest
, DestroyFromCallback
) {
140 socket_
->set_async_write(true);
141 writer_
->Write(test_buffer_
, base::Bind(
142 &BufferedSocketWriterTest::DestroyWriterAndQuit
,
143 base::Unretained(this)));
144 writer_
->Write(test_buffer_2_
, base::Bind(
145 &BufferedSocketWriterTest::Unexpected
,
146 base::Unretained(this)));
147 socket_
->set_async_write(false);
149 ASSERT_GE(written_data_
.size(),
150 static_cast<size_t>(test_buffer_
->size()));
151 EXPECT_EQ(0, memcmp(test_buffer_
->data(), written_data_
.data(),
152 test_buffer_
->size()));
155 // Verify that it stops writing after the first error.
156 TEST_F(BufferedSocketWriterTest
, TestWriteErrorSync
) {
157 socket_
->set_write_limit(kWriteChunkSize
);
158 writer_
->Write(test_buffer_
, base::Closure());
159 socket_
->set_async_write(true);
160 writer_
->Write(test_buffer_2_
,
161 base::Bind(&BufferedSocketWriterTest::Unexpected
,
162 base::Unretained(this)));
163 socket_
->set_next_write_error(net::ERR_FAILED
);
164 socket_
->set_async_write(false);
165 message_loop_
.RunUntilIdle();
166 EXPECT_EQ(net::ERR_FAILED
, write_error_
);
167 EXPECT_EQ(static_cast<size_t>(test_buffer_
->size()),
168 socket_
->written_data().size());
171 // Verify that it stops writing after the first error.
172 TEST_F(BufferedSocketWriterTest
, TestWriteErrorAsync
) {
173 socket_
->set_write_limit(kWriteChunkSize
);
174 writer_
->Write(test_buffer_
, base::Closure());
175 socket_
->set_async_write(true);
176 writer_
->Write(test_buffer_2_
,
177 base::Bind(&BufferedSocketWriterTest::Unexpected
,
178 base::Unretained(this)));
179 socket_
->set_next_write_error(net::ERR_FAILED
);
180 message_loop_
.RunUntilIdle();
181 EXPECT_EQ(net::ERR_FAILED
, write_error_
);
182 EXPECT_EQ(static_cast<size_t>(test_buffer_
->size()),
183 socket_
->written_data().size());
186 } // namespace protocol
187 } // namespace remoting