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.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 MessageLoop::current()->PostTask(FROM_HERE
, MessageLoop::QuitClosure());
35 void DestroyWriterAndQuit() {
36 written_data_
= socket_
->written_data();
39 MessageLoop::current()->PostTask(FROM_HERE
, MessageLoop::QuitClosure());
47 virtual void SetUp() OVERRIDE
{
48 socket_
.reset(new FakeSocket());
49 writer_
.reset(new BufferedSocketWriter());
50 writer_
->Init(socket_
.get(), base::Bind(
51 &BufferedSocketWriterTest::OnWriteFailed
, base::Unretained(this)));
52 test_buffer_
= new net::IOBufferWithSize(kTestBufferSize
);
53 test_buffer_2_
= new net::IOBufferWithSize(kTestBufferSize
);
54 for (int i
= 0; i
< kTestBufferSize
; ++i
) {
55 test_buffer_
->data()[i
] = rand() % 256;
56 test_buffer_2_
->data()[i
] = rand() % 256;
60 void OnWriteFailed(int error
) {
65 writer_
->Write(test_buffer_
, base::Bind(&BufferedSocketWriterTest::OnDone
,
66 base::Unretained(this)));
67 writer_
->Write(test_buffer_2_
, base::Bind(&BufferedSocketWriterTest::OnDone
,
68 base::Unretained(this)));
70 ASSERT_EQ(static_cast<size_t>(test_buffer_
->size() +
71 test_buffer_2_
->size()),
72 socket_
->written_data().size());
73 EXPECT_EQ(0, memcmp(test_buffer_
->data(), socket_
->written_data().data(),
74 test_buffer_
->size()));
75 EXPECT_EQ(0, memcmp(test_buffer_2_
->data(),
76 socket_
->written_data().data() + test_buffer_
->size(),
77 test_buffer_2_
->size()));
80 void TestAppendInCallback() {
81 writer_
->Write(test_buffer_
, base::Bind(
82 base::IgnoreResult(&BufferedSocketWriterBase::Write
),
83 base::Unretained(writer_
.get()), test_buffer_2_
,
84 base::Bind(&BufferedSocketWriterTest::OnDone
,
85 base::Unretained(this))));
87 ASSERT_EQ(static_cast<size_t>(test_buffer_
->size() +
88 test_buffer_2_
->size()),
89 socket_
->written_data().size());
90 EXPECT_EQ(0, memcmp(test_buffer_
->data(), socket_
->written_data().data(),
91 test_buffer_
->size()));
92 EXPECT_EQ(0, memcmp(test_buffer_2_
->data(),
93 socket_
->written_data().data() + test_buffer_
->size(),
94 test_buffer_2_
->size()));
97 MessageLoop message_loop_
;
98 scoped_ptr
<FakeSocket
> socket_
;
99 scoped_ptr
<BufferedSocketWriter
> writer_
;
100 scoped_refptr
<net::IOBufferWithSize
> test_buffer_
;
101 scoped_refptr
<net::IOBufferWithSize
> test_buffer_2_
;
102 std::string written_data_
;
106 // Test synchronous write.
107 TEST_F(BufferedSocketWriterTest
, WriteFull
) {
111 // Test synchronous write in 1k chunks.
112 TEST_F(BufferedSocketWriterTest
, WriteChunks
) {
113 socket_
->set_write_limit(kWriteChunkSize
);
117 // Test asynchronous write.
118 TEST_F(BufferedSocketWriterTest
, WriteAsync
) {
119 socket_
->set_async_write(true);
120 socket_
->set_write_limit(kWriteChunkSize
);
124 // Make sure we can call Write() from the done callback.
125 TEST_F(BufferedSocketWriterTest
, AppendInCallbackSync
) {
126 TestAppendInCallback();
129 // Make sure we can call Write() from the done callback.
130 TEST_F(BufferedSocketWriterTest
, AppendInCallbackAsync
) {
131 socket_
->set_async_write(true);
132 socket_
->set_write_limit(kWriteChunkSize
);
133 TestAppendInCallback();
136 // Test that the writer can be destroyed from callback.
137 TEST_F(BufferedSocketWriterTest
, DestroyFromCallback
) {
138 socket_
->set_async_write(true);
139 writer_
->Write(test_buffer_
, base::Bind(
140 &BufferedSocketWriterTest::DestroyWriterAndQuit
,
141 base::Unretained(this)));
142 writer_
->Write(test_buffer_2_
, base::Bind(
143 &BufferedSocketWriterTest::Unexpected
,
144 base::Unretained(this)));
145 socket_
->set_async_write(false);
147 ASSERT_GE(written_data_
.size(),
148 static_cast<size_t>(test_buffer_
->size()));
149 EXPECT_EQ(0, memcmp(test_buffer_
->data(), written_data_
.data(),
150 test_buffer_
->size()));
153 // Verify that it stops writing after the first error.
154 TEST_F(BufferedSocketWriterTest
, TestWriteErrorSync
) {
155 socket_
->set_write_limit(kWriteChunkSize
);
156 writer_
->Write(test_buffer_
, base::Closure());
157 socket_
->set_async_write(true);
158 writer_
->Write(test_buffer_2_
,
159 base::Bind(&BufferedSocketWriterTest::Unexpected
,
160 base::Unretained(this)));
161 socket_
->set_next_write_error(net::ERR_FAILED
);
162 socket_
->set_async_write(false);
163 message_loop_
.RunUntilIdle();
164 EXPECT_EQ(net::ERR_FAILED
, write_error_
);
165 EXPECT_EQ(static_cast<size_t>(test_buffer_
->size()),
166 socket_
->written_data().size());
169 // Verify that it stops writing after the first error.
170 TEST_F(BufferedSocketWriterTest
, TestWriteErrorAsync
) {
171 socket_
->set_write_limit(kWriteChunkSize
);
172 writer_
->Write(test_buffer_
, base::Closure());
173 socket_
->set_async_write(true);
174 writer_
->Write(test_buffer_2_
,
175 base::Bind(&BufferedSocketWriterTest::Unexpected
,
176 base::Unretained(this)));
177 socket_
->set_next_write_error(net::ERR_FAILED
);
178 message_loop_
.RunUntilIdle();
179 EXPECT_EQ(net::ERR_FAILED
, write_error_
);
180 EXPECT_EQ(static_cast<size_t>(test_buffer_
->size()),
181 socket_
->written_data().size());
184 } // namespace protocol
185 } // namespace remoting