Chromium Code Reviews| Index: device/serial/data_source_unittest.cc |
| diff --git a/device/serial/data_source_unittest.cc b/device/serial/data_source_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..550b1d5f46833af161b5fd7e0c5db2b371e17abe |
| --- /dev/null |
| +++ b/device/serial/data_source_unittest.cc |
| @@ -0,0 +1,239 @@ |
| +// Copyright 2014 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 "base/bind.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/run_loop.h" |
| +#include "base/strings/string_piece.h" |
| +#include "device/serial/async_waiter.h" |
| +#include "device/serial/buffer.h" |
| +#include "device/serial/data_receiver.h" |
| +#include "device/serial/data_source_sender.h" |
| +#include "device/serial/data_stream.mojom.h" |
| +#include "mojo/public/cpp/bindings/interface_ptr.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace device { |
| + |
| +class DataSourceTest : public testing::Test { |
| + public: |
| + DataSourceTest() : error_(0), seen_connection_error_(false) {} |
| + |
| + virtual void SetUp() OVERRIDE { |
| + message_loop_.reset(new base::MessageLoop); |
| + mojo::InterfacePtr<serial::DataSource> source_sender_handle; |
| + source_sender_ = mojo::WeakBindToProxy( |
| + new DataSourceSender( |
| + base::Bind(&DataSourceTest::CanWriteData, base::Unretained(this)), |
| + base::Bind(&DataSourceTest::OnError, base::Unretained(this))), |
| + &source_sender_handle); |
| + receiver_ = new DataReceiver(source_sender_handle.Pass(), 100, -10); |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { |
| + write_buffer_.reset(); |
| + buffer_.reset(); |
| + message_loop_.reset(); |
| + } |
| + |
| + void OnError() { |
| + seen_connection_error_ = true; |
| + StopMessageLoop(); |
| + } |
| + |
| + void RunMessageLoop() { |
| + base::RunLoop run_loop; |
| + stop_run_loop_ = run_loop.QuitClosure(); |
| + run_loop.Run(); |
| + } |
| + |
| + void StopMessageLoop() { |
| + if (!stop_run_loop_.is_null()) |
| + stop_run_loop_.Run(); |
| + } |
| + |
| + bool Receive() { |
| + return receiver_->Receive( |
| + base::Bind(&DataSourceTest::OnDataReceived, base::Unretained(this)), |
| + base::Bind(&DataSourceTest::OnReceiveError, base::Unretained(this))); |
| + } |
| + |
| + bool FillWriteBuffer(const base::StringPiece& data, int32_t error) { |
| + if (!write_buffer_) |
| + RunMessageLoop(); |
|
raymes
2014/08/11 04:04:51
-Add a comment // Run the message loop until CanWr
Sam McNally
2014/08/11 04:56:42
Done.
|
| + if (!write_buffer_) |
| + return false; |
|
raymes
2014/08/11 04:04:51
We never check the return value, so you could just
Sam McNally
2014/08/11 04:56:42
Done.
|
| + if (write_buffer_->GetSize() < static_cast<uint32_t>(data.size())) { |
|
raymes
2014/08/11 04:04:51
DCHECK(write_buffer_->GetSize() >= static_cast<uin
Sam McNally
2014/08/11 04:56:42
Done.
|
| + write_buffer_->Done(0); |
| + write_buffer_.reset(); |
| + return false; |
| + } |
| + |
| + memcpy(write_buffer_->GetData(), data.data(), data.size()); |
| + if (error) |
| + write_buffer_->DoneWithError(static_cast<uint32_t>(data.size()), error); |
| + else |
| + write_buffer_->Done(static_cast<uint32_t>(data.size())); |
| + write_buffer_.reset(); |
| + return true; |
| + } |
| + |
| + bool ReceiveAndWait() { |
| + if (!Receive()) |
| + return false; |
| + RunMessageLoop(); |
|
raymes
2014/08/11 04:04:51
Add a comment here, // Run the message loop until
Sam McNally
2014/08/11 04:56:42
Done.
|
| + return true; |
| + } |
| + |
| + void OnDataReceived(scoped_ptr<ReadOnlyBuffer> buffer) { |
| + ASSERT_TRUE(buffer); |
| + error_ = 0; |
| + buffer_ = buffer.Pass(); |
| + buffer_contents_ = std::string(buffer_->GetData(), buffer_->GetSize()); |
| + StopMessageLoop(); |
| + } |
| + |
| + void OnReceiveError(int32_t error) { |
| + buffer_contents_.clear(); |
| + error_ = error; |
| + StopMessageLoop(); |
| + } |
| + |
| + void CanWriteData(scoped_ptr<WritableBuffer> buffer) { |
| + write_buffer_ = buffer.Pass(); |
| + StopMessageLoop(); |
| + } |
| + |
| + protected: |
| + scoped_ptr<base::MessageLoop> message_loop_; |
| + base::Closure stop_run_loop_; |
| + |
| + scoped_refptr<DataSourceSender> source_sender_; |
| + scoped_refptr<DataReceiver> receiver_; |
| + |
| + scoped_ptr<ReadOnlyBuffer> buffer_; |
| + std::string buffer_contents_; |
| + int32_t error_; |
| + scoped_ptr<WritableBuffer> write_buffer_; |
| + |
| + bool seen_connection_error_; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(DataSourceTest); |
| +}; |
| + |
| +TEST_F(DataSourceTest, Basic) { |
|
raymes
2014/08/11 04:04:51
Add a comment above each test explaining what it i
Sam McNally
2014/08/11 04:56:43
Done.
|
| + FillWriteBuffer("a", 0); |
| + |
| + // Wait until we get a new write_buffer_ before we wait to receive. |
| + RunMessageLoop(); |
| + ASSERT_TRUE(write_buffer_); |
| + |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + EXPECT_EQ(0, error_); |
| + ASSERT_TRUE(buffer_); |
| + EXPECT_EQ("a", buffer_contents_); |
| + buffer_->Done(1); |
| + |
| + FillWriteBuffer("b", 0); |
| + |
| + // Wait until we get a new write_buffer_ before we wait to receive. |
| + RunMessageLoop(); |
| + ASSERT_TRUE(write_buffer_); |
| + |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + EXPECT_EQ(0, error_); |
| + ASSERT_TRUE(buffer_); |
| + EXPECT_EQ("b", buffer_contents_); |
| +} |
| + |
| +TEST_F(DataSourceTest, PartialReceive) { |
| + FillWriteBuffer("ab", 0); |
| + |
| + // Wait until we get a new write_buffer_ before we wait to receive. |
| + RunMessageLoop(); |
| + ASSERT_TRUE(write_buffer_); |
| + |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + EXPECT_EQ(0, error_); |
| + ASSERT_TRUE(buffer_); |
| + EXPECT_EQ("ab", buffer_contents_); |
| + buffer_->Done(1); |
| + |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + EXPECT_EQ(0, error_); |
| + ASSERT_TRUE(buffer_); |
| + EXPECT_EQ("b", buffer_contents_); |
|
raymes
2014/08/11 04:04:51
You might as well call Done again and check that t
Sam McNally
2014/08/11 04:56:42
As discussed, the API doesn't support this.
|
| +} |
| + |
| +TEST_F(DataSourceTest, ErrorAndData) { |
| + FillWriteBuffer("abc", -1); |
| + |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + ASSERT_TRUE(buffer_); |
| + EXPECT_EQ("abc", buffer_contents_); |
| + buffer_->Done(1); |
| + EXPECT_EQ(0, error_); |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + ASSERT_TRUE(buffer_); |
| + EXPECT_EQ("bc", buffer_contents_); |
| + buffer_->Done(1); |
| + EXPECT_EQ(0, error_); |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + ASSERT_TRUE(buffer_); |
| + EXPECT_EQ("c", buffer_contents_); |
| + buffer_->Done(1); |
| + EXPECT_EQ(0, error_); |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + EXPECT_EQ(-1, error_); |
| + ASSERT_FALSE(write_buffer_); |
| + |
| + ASSERT_TRUE(Receive()); |
| + FillWriteBuffer("d", -2); |
|
raymes
2014/08/11 04:04:51
Maybe test a non-error transmission is successful
Sam McNally
2014/08/11 04:56:42
Done.
|
| + |
| + RunMessageLoop(); |
| + ASSERT_TRUE(buffer_); |
| + EXPECT_EQ("d", buffer_contents_); |
| + buffer_->Done(1); |
| + EXPECT_EQ(0, error_); |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + EXPECT_EQ(-2, error_); |
| +} |
| + |
| +TEST_F(DataSourceTest, ErrorOnly) { |
| + FillWriteBuffer("", -1); |
| + |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + EXPECT_FALSE(buffer_); |
| + EXPECT_EQ(-1, error_); |
| + ASSERT_FALSE(write_buffer_); |
| + |
| + ASSERT_TRUE(Receive()); |
| + FillWriteBuffer("", -2); |
| + |
| + RunMessageLoop(); |
| + EXPECT_FALSE(buffer_); |
| + EXPECT_EQ(-2, error_); |
| + ASSERT_FALSE(write_buffer_); |
| +} |
| + |
| +TEST_F(DataSourceTest, ProducerShutdown) { |
|
raymes
2014/08/11 04:04:51
Maybe call this "SourceShutDown" since that matche
Sam McNally
2014/08/11 04:56:42
Done.
|
| + source_sender_->ShutDown(); |
| + source_sender_ = NULL; |
| + ASSERT_TRUE(ReceiveAndWait()); |
| + EXPECT_FALSE(buffer_); |
| + EXPECT_EQ(-10, error_); |
|
raymes
2014/08/11 04:04:51
Make this a global constant to clarify what's happ
Sam McNally
2014/08/11 04:56:43
Done.
|
| + ASSERT_FALSE(write_buffer_); |
| + ASSERT_FALSE(Receive()); |
| +} |
| + |
| +TEST_F(DataSourceTest, ReceiverShutdown) { |
| + Receive(); |
| + receiver_ = NULL; |
| + EXPECT_EQ(-10, error_); |
| + RunMessageLoop(); |
| + EXPECT_TRUE(seen_connection_error_); |
| +} |
| + |
| +} // namespace device |