| Index: remoting/protocol/buffered_socket_writer_unittest.cc
|
| diff --git a/remoting/protocol/buffered_socket_writer_unittest.cc b/remoting/protocol/buffered_socket_writer_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..76d0409f0d6a52dd5eb6f270b0e3a6929e2102bf
|
| --- /dev/null
|
| +++ b/remoting/protocol/buffered_socket_writer_unittest.cc
|
| @@ -0,0 +1,186 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "remoting/protocol/buffered_socket_writer.h"
|
| +
|
| +#include <stdlib.h>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/message_loop.h"
|
| +#include "net/base/io_buffer.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "remoting/protocol/fake_session.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace remoting {
|
| +namespace protocol {
|
| +
|
| +namespace {
|
| +const int kTestBufferSize = 10 * 1024; // 10k;
|
| +const size_t kWriteChunkSize = 1024U;
|
| +} // namespace
|
| +
|
| +class BufferedSocketWriterTest : public testing::Test {
|
| + public:
|
| + BufferedSocketWriterTest()
|
| + : write_error_(0) {
|
| + }
|
| +
|
| + void OnDone() {
|
| + MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
|
| + }
|
| +
|
| + void DestroyWriterAndQuit() {
|
| + written_data_ = socket_->written_data();
|
| + writer_.reset();
|
| + socket_.reset();
|
| + MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
|
| + }
|
| +
|
| + void Unexpected() {
|
| + EXPECT_TRUE(false);
|
| + }
|
| +
|
| + protected:
|
| + void SetUp() OVERRIDE {
|
| + socket_.reset(new FakeSocket());
|
| + writer_.reset(new BufferedSocketWriter());
|
| + writer_->Init(socket_.get(), base::Bind(
|
| + &BufferedSocketWriterTest::OnWriteFailed, base::Unretained(this)));
|
| + test_buffer_ = new net::IOBufferWithSize(kTestBufferSize);
|
| + test_buffer_2_ = new net::IOBufferWithSize(kTestBufferSize);
|
| + for (int i = 0; i< kTestBufferSize; ++i) {
|
| + test_buffer_->data()[i] = rand() % 256;
|
| + test_buffer_2_->data()[i] = rand() % 256;
|
| + }
|
| + }
|
| +
|
| + void OnWriteFailed(int error) {
|
| + write_error_ = error;
|
| + }
|
| +
|
| + void TestWrite() {
|
| + writer_->Write(test_buffer_, base::Bind(&BufferedSocketWriterTest::OnDone,
|
| + base::Unretained(this)));
|
| + writer_->Write(test_buffer_2_, base::Bind(&BufferedSocketWriterTest::OnDone,
|
| + base::Unretained(this)));
|
| + message_loop_.Run();
|
| + ASSERT_EQ(static_cast<size_t>(test_buffer_->size() +
|
| + test_buffer_2_->size()),
|
| + socket_->written_data().size());
|
| + EXPECT_EQ(0, memcmp(test_buffer_->data(), socket_->written_data().data(),
|
| + test_buffer_->size()));
|
| + EXPECT_EQ(0, memcmp(test_buffer_2_->data(),
|
| + socket_->written_data().data() + test_buffer_->size(),
|
| + test_buffer_2_->size()));
|
| + }
|
| +
|
| + void TestAppendInCallback() {
|
| + writer_->Write(test_buffer_, base::Bind(
|
| + base::IgnoreResult(&BufferedSocketWriterBase::Write),
|
| + base::Unretained(writer_.get()), test_buffer_2_,
|
| + base::Bind(&BufferedSocketWriterTest::OnDone,
|
| + base::Unretained(this))));
|
| + message_loop_.Run();
|
| + ASSERT_EQ(static_cast<size_t>(test_buffer_->size() +
|
| + test_buffer_2_->size()),
|
| + socket_->written_data().size());
|
| + EXPECT_EQ(0, memcmp(test_buffer_->data(), socket_->written_data().data(),
|
| + test_buffer_->size()));
|
| + EXPECT_EQ(0, memcmp(test_buffer_2_->data(),
|
| + socket_->written_data().data() + test_buffer_->size(),
|
| + test_buffer_2_->size()));
|
| + }
|
| +
|
| + MessageLoop message_loop_;
|
| + scoped_ptr<FakeSocket> socket_;
|
| + scoped_ptr<BufferedSocketWriter> writer_;
|
| + scoped_refptr<net::IOBufferWithSize> test_buffer_;
|
| + scoped_refptr<net::IOBufferWithSize> test_buffer_2_;
|
| + std::string written_data_;
|
| + int write_error_;
|
| +};
|
| +
|
| +// Test synchronous write.
|
| +TEST_F(BufferedSocketWriterTest, WriteFull) {
|
| + TestWrite();
|
| +}
|
| +
|
| +// Test synchronous write in 1k chunks.
|
| +TEST_F(BufferedSocketWriterTest, WriteChunks) {
|
| + socket_->set_write_limit(kWriteChunkSize);
|
| + TestWrite();
|
| +}
|
| +
|
| +// Test asynchronous write.
|
| +TEST_F(BufferedSocketWriterTest, WriteAsync) {
|
| + socket_->set_async_write(true);
|
| + socket_->set_write_limit(kWriteChunkSize);
|
| + TestWrite();
|
| +}
|
| +
|
| +// Make sure we can call Write() from the done callback.
|
| +TEST_F(BufferedSocketWriterTest, AppendInCallbackSync) {
|
| + TestAppendInCallback();
|
| +}
|
| +
|
| +// Make sure we can call Write() from the done callback.
|
| +TEST_F(BufferedSocketWriterTest, AppendInCallbackAsync) {
|
| + socket_->set_async_write(true);
|
| + socket_->set_write_limit(kWriteChunkSize);
|
| + TestAppendInCallback();
|
| +}
|
| +
|
| +// Test that the writer can be destroyed from callback.
|
| +TEST_F(BufferedSocketWriterTest, DestroyFromCallback) {
|
| + socket_->set_async_write(true);
|
| + writer_->Write(test_buffer_, base::Bind(
|
| + &BufferedSocketWriterTest::DestroyWriterAndQuit,
|
| + base::Unretained(this)));
|
| + writer_->Write(test_buffer_2_, base::Bind(
|
| + &BufferedSocketWriterTest::Unexpected,
|
| + base::Unretained(this)));
|
| + socket_->set_async_write(false);
|
| + message_loop_.Run();
|
| + ASSERT_GE(written_data_.size(),
|
| + static_cast<size_t>(test_buffer_->size()));
|
| + EXPECT_EQ(0, memcmp(test_buffer_->data(), written_data_.data(),
|
| + test_buffer_->size()));
|
| +}
|
| +
|
| +// Verify that it stops writing after the first error.
|
| +TEST_F(BufferedSocketWriterTest, TestWriteErrorSync) {
|
| + socket_->set_write_limit(kWriteChunkSize);
|
| + writer_->Write(test_buffer_, base::Closure());
|
| + socket_->set_async_write(true);
|
| + writer_->Write(test_buffer_2_,
|
| + base::Bind(&BufferedSocketWriterTest::Unexpected,
|
| + base::Unretained(this)));
|
| + socket_->set_next_write_error(net::ERR_FAILED);
|
| + socket_->set_async_write(false);
|
| + message_loop_.RunAllPending();
|
| + EXPECT_EQ(net::ERR_FAILED, write_error_);
|
| + EXPECT_EQ(static_cast<size_t>(test_buffer_->size()),
|
| + socket_->written_data().size());
|
| +}
|
| +
|
| +// Verify that it stops writing after the first error.
|
| +TEST_F(BufferedSocketWriterTest, TestWriteErrorAsync) {
|
| + socket_->set_write_limit(kWriteChunkSize);
|
| + writer_->Write(test_buffer_, base::Closure());
|
| + socket_->set_async_write(true);
|
| + writer_->Write(test_buffer_2_,
|
| + base::Bind(&BufferedSocketWriterTest::Unexpected,
|
| + base::Unretained(this)));
|
| + socket_->set_next_write_error(net::ERR_FAILED);
|
| + message_loop_.RunAllPending();
|
| + EXPECT_EQ(net::ERR_FAILED, write_error_);
|
| + EXPECT_EQ(static_cast<size_t>(test_buffer_->size()),
|
| + socket_->written_data().size());
|
| +}
|
| +
|
| +} // namespace protocol
|
| +} // namespace remoting
|
| +
|
|
|