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 "base/run_loop.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h"
14 #include "remoting/protocol/fake_session.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
22 const int kTestBufferSize
= 10 * 1024; // 10k;
23 const size_t kWriteChunkSize
= 1024U;
26 class BufferedSocketWriterTest
: public testing::Test
{
28 BufferedSocketWriterTest()
33 base::MessageLoop::current()->PostTask(FROM_HERE
,
34 base::MessageLoop::QuitClosure());
37 void DestroyWriterAndQuit() {
38 written_data_
= socket_
->written_data();
41 base::MessageLoop::current()->PostTask(FROM_HERE
,
42 base::MessageLoop::QuitClosure());
50 virtual void SetUp() OVERRIDE
{
51 socket_
.reset(new FakeSocket());
52 writer_
.reset(new BufferedSocketWriter());
53 writer_
->Init(socket_
.get(), base::Bind(
54 &BufferedSocketWriterTest::OnWriteFailed
, base::Unretained(this)));
55 test_buffer_
= new net::IOBufferWithSize(kTestBufferSize
);
56 test_buffer_2_
= new net::IOBufferWithSize(kTestBufferSize
);
57 for (int i
= 0; i
< kTestBufferSize
; ++i
) {
58 test_buffer_
->data()[i
] = rand() % 256;
59 test_buffer_2_
->data()[i
] = rand() % 256;
63 void OnWriteFailed(int error
) {
68 writer_
->Write(test_buffer_
, base::Bind(&BufferedSocketWriterTest::OnDone
,
69 base::Unretained(this)));
70 writer_
->Write(test_buffer_2_
, base::Bind(&BufferedSocketWriterTest::OnDone
,
71 base::Unretained(this)));
73 ASSERT_EQ(static_cast<size_t>(test_buffer_
->size() +
74 test_buffer_2_
->size()),
75 socket_
->written_data().size());
76 EXPECT_EQ(0, memcmp(test_buffer_
->data(), socket_
->written_data().data(),
77 test_buffer_
->size()));
78 EXPECT_EQ(0, memcmp(test_buffer_2_
->data(),
79 socket_
->written_data().data() + test_buffer_
->size(),
80 test_buffer_2_
->size()));
83 void TestAppendInCallback() {
84 writer_
->Write(test_buffer_
, base::Bind(
85 base::IgnoreResult(&BufferedSocketWriterBase::Write
),
86 base::Unretained(writer_
.get()), test_buffer_2_
,
87 base::Bind(&BufferedSocketWriterTest::OnDone
,
88 base::Unretained(this))));
90 ASSERT_EQ(static_cast<size_t>(test_buffer_
->size() +
91 test_buffer_2_
->size()),
92 socket_
->written_data().size());
93 EXPECT_EQ(0, memcmp(test_buffer_
->data(), socket_
->written_data().data(),
94 test_buffer_
->size()));
95 EXPECT_EQ(0, memcmp(test_buffer_2_
->data(),
96 socket_
->written_data().data() + test_buffer_
->size(),
97 test_buffer_2_
->size()));
100 base::MessageLoop message_loop_
;
101 scoped_ptr
<FakeSocket
> socket_
;
102 scoped_ptr
<BufferedSocketWriter
> writer_
;
103 scoped_refptr
<net::IOBufferWithSize
> test_buffer_
;
104 scoped_refptr
<net::IOBufferWithSize
> test_buffer_2_
;
105 std::string written_data_
;
109 // Test synchronous write.
110 TEST_F(BufferedSocketWriterTest
, WriteFull
) {
114 // Test synchronous write in 1k chunks.
115 TEST_F(BufferedSocketWriterTest
, WriteChunks
) {
116 socket_
->set_write_limit(kWriteChunkSize
);
120 // Test asynchronous write.
121 TEST_F(BufferedSocketWriterTest
, WriteAsync
) {
122 socket_
->set_async_write(true);
123 socket_
->set_write_limit(kWriteChunkSize
);
127 // Make sure we can call Write() from the done callback.
128 TEST_F(BufferedSocketWriterTest
, AppendInCallbackSync
) {
129 TestAppendInCallback();
132 // Make sure we can call Write() from the done callback.
133 TEST_F(BufferedSocketWriterTest
, AppendInCallbackAsync
) {
134 socket_
->set_async_write(true);
135 socket_
->set_write_limit(kWriteChunkSize
);
136 TestAppendInCallback();
139 // Test that the writer can be destroyed from callback.
140 TEST_F(BufferedSocketWriterTest
, DestroyFromCallback
) {
141 socket_
->set_async_write(true);
142 writer_
->Write(test_buffer_
, base::Bind(
143 &BufferedSocketWriterTest::DestroyWriterAndQuit
,
144 base::Unretained(this)));
145 writer_
->Write(test_buffer_2_
, base::Bind(
146 &BufferedSocketWriterTest::Unexpected
,
147 base::Unretained(this)));
148 socket_
->set_async_write(false);
150 ASSERT_GE(written_data_
.size(),
151 static_cast<size_t>(test_buffer_
->size()));
152 EXPECT_EQ(0, memcmp(test_buffer_
->data(), written_data_
.data(),
153 test_buffer_
->size()));
156 // Verify that it stops writing after the first error.
157 TEST_F(BufferedSocketWriterTest
, TestWriteErrorSync
) {
158 socket_
->set_write_limit(kWriteChunkSize
);
159 writer_
->Write(test_buffer_
, base::Closure());
160 socket_
->set_async_write(true);
161 writer_
->Write(test_buffer_2_
,
162 base::Bind(&BufferedSocketWriterTest::Unexpected
,
163 base::Unretained(this)));
164 socket_
->set_next_write_error(net::ERR_FAILED
);
165 socket_
->set_async_write(false);
166 base::RunLoop().RunUntilIdle();
167 EXPECT_EQ(net::ERR_FAILED
, write_error_
);
168 EXPECT_EQ(static_cast<size_t>(test_buffer_
->size()),
169 socket_
->written_data().size());
172 // Verify that it stops writing after the first error.
173 TEST_F(BufferedSocketWriterTest
, TestWriteErrorAsync
) {
174 socket_
->set_write_limit(kWriteChunkSize
);
175 writer_
->Write(test_buffer_
, base::Closure());
176 socket_
->set_async_write(true);
177 writer_
->Write(test_buffer_2_
,
178 base::Bind(&BufferedSocketWriterTest::Unexpected
,
179 base::Unretained(this)));
180 socket_
->set_next_write_error(net::ERR_FAILED
);
181 base::RunLoop().RunUntilIdle();
182 EXPECT_EQ(net::ERR_FAILED
, write_error_
);
183 EXPECT_EQ(static_cast<size_t>(test_buffer_
->size()),
184 socket_
->written_data().size());
187 } // namespace protocol
188 } // namespace remoting