• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "remoting/protocol/buffered_socket_writer.h"
6 
7 #include <stdlib.h>
8 
9 #include "base/bind.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"
16 
17 namespace remoting {
18 namespace protocol {
19 
20 namespace {
21 const int kTestBufferSize = 10 * 1024; // 10k;
22 const size_t kWriteChunkSize = 1024U;
23 }  // namespace
24 
25 class BufferedSocketWriterTest : public testing::Test {
26  public:
BufferedSocketWriterTest()27   BufferedSocketWriterTest()
28       : write_error_(0) {
29   }
30 
OnDone()31   void OnDone() {
32     base::MessageLoop::current()->PostTask(FROM_HERE,
33                                            base::MessageLoop::QuitClosure());
34   }
35 
DestroyWriterAndQuit()36   void DestroyWriterAndQuit() {
37     written_data_ = socket_->written_data();
38     writer_.reset();
39     socket_.reset();
40     base::MessageLoop::current()->PostTask(FROM_HERE,
41                                            base::MessageLoop::QuitClosure());
42   }
43 
Unexpected()44   void Unexpected() {
45     EXPECT_TRUE(false);
46   }
47 
48  protected:
SetUp()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;
59     }
60   }
61 
OnWriteFailed(int error)62   void OnWriteFailed(int error) {
63     write_error_ = error;
64   }
65 
TestWrite()66   void TestWrite() {
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)));
71     message_loop_.Run();
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()));
80   }
81 
TestAppendInCallback()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))));
88     message_loop_.Run();
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()));
97   }
98 
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_;
105   int write_error_;
106 };
107 
108 // Test synchronous write.
TEST_F(BufferedSocketWriterTest,WriteFull)109 TEST_F(BufferedSocketWriterTest, WriteFull) {
110   TestWrite();
111 }
112 
113 // Test synchronous write in 1k chunks.
TEST_F(BufferedSocketWriterTest,WriteChunks)114 TEST_F(BufferedSocketWriterTest, WriteChunks) {
115   socket_->set_write_limit(kWriteChunkSize);
116   TestWrite();
117 }
118 
119 // Test asynchronous write.
TEST_F(BufferedSocketWriterTest,WriteAsync)120 TEST_F(BufferedSocketWriterTest, WriteAsync) {
121   socket_->set_async_write(true);
122   socket_->set_write_limit(kWriteChunkSize);
123   TestWrite();
124 }
125 
126 // Make sure we can call Write() from the done callback.
TEST_F(BufferedSocketWriterTest,AppendInCallbackSync)127 TEST_F(BufferedSocketWriterTest, AppendInCallbackSync) {
128   TestAppendInCallback();
129 }
130 
131 // Make sure we can call Write() from the done callback.
TEST_F(BufferedSocketWriterTest,AppendInCallbackAsync)132 TEST_F(BufferedSocketWriterTest, AppendInCallbackAsync) {
133   socket_->set_async_write(true);
134   socket_->set_write_limit(kWriteChunkSize);
135   TestAppendInCallback();
136 }
137 
138 // Test that the writer can be destroyed from callback.
TEST_F(BufferedSocketWriterTest,DestroyFromCallback)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);
148   message_loop_.Run();
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()));
153 }
154 
155 // Verify that it stops writing after the first error.
TEST_F(BufferedSocketWriterTest,TestWriteErrorSync)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());
169 }
170 
171 // Verify that it stops writing after the first error.
TEST_F(BufferedSocketWriterTest,TestWriteErrorAsync)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());
184 }
185 
186 }  // namespace protocol
187 }  // namespace remoting
188 
189