// Copyright 2015 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 #include #include "base/callback_helpers.h" #include "base/message_loop/message_loop.h" #include "blimp/common/proto/blimp_message.pb.h" #include "blimp/net/blimp_connection.h" #include "blimp/net/common.h" #include "blimp/net/connection_error_observer.h" #include "blimp/net/test_common.h" #include "net/base/completion_callback.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_; using testing::InSequence; using testing::Return; using testing::SaveArg; namespace blimp { namespace { class BlimpConnectionTest : public testing::Test { public: BlimpConnectionTest() { scoped_ptr> writer( new testing::StrictMock); writer_ = writer.get(); connection_.reset(new BlimpConnection(make_scoped_ptr(new MockPacketReader), std::move(writer))); connection_->AddConnectionErrorObserver(&error_observer1_); connection_->AddConnectionErrorObserver(&error_observer2_); connection_->AddConnectionErrorObserver(&error_observer3_); connection_->RemoveConnectionErrorObserver(&error_observer3_); } ~BlimpConnectionTest() override {} protected: scoped_ptr CreateInputMessage() { scoped_ptr msg(new BlimpMessage); msg->set_type(BlimpMessage::INPUT); return msg; } scoped_ptr CreateControlMessage() { scoped_ptr msg(new BlimpMessage); msg->set_type(BlimpMessage::TAB_CONTROL); return msg; } base::MessageLoop message_loop_; testing::StrictMock* writer_; testing::StrictMock error_observer1_; testing::StrictMock error_observer2_; // This error observer is Removed() immediately after it's added; // it should never be called. testing::StrictMock error_observer3_; testing::StrictMock receiver_; scoped_ptr connection_; }; // Write completes writing two packets asynchronously. TEST_F(BlimpConnectionTest, AsyncTwoPacketsWrite) { net::CompletionCallback write_packet_cb; InSequence s; EXPECT_CALL(*writer_, WritePacket(BufferEqualsProto(*CreateInputMessage()), _)) .WillOnce(SaveArg<1>(&write_packet_cb)) .RetiresOnSaturation(); EXPECT_CALL(*writer_, WritePacket(BufferEqualsProto(*CreateControlMessage()), _)) .WillOnce(SaveArg<1>(&write_packet_cb)) .RetiresOnSaturation(); BlimpMessageProcessor* sender = connection_->GetOutgoingMessageProcessor(); net::TestCompletionCallback complete_cb_1; ASSERT_TRUE(write_packet_cb.is_null()); sender->ProcessMessage(CreateInputMessage(), complete_cb_1.callback()); ASSERT_FALSE(write_packet_cb.is_null()); base::ResetAndReturn(&write_packet_cb).Run(net::OK); EXPECT_EQ(net::OK, complete_cb_1.WaitForResult()); net::TestCompletionCallback complete_cb_2; ASSERT_TRUE(write_packet_cb.is_null()); sender->ProcessMessage(CreateControlMessage(), complete_cb_2.callback()); ASSERT_FALSE(write_packet_cb.is_null()); base::ResetAndReturn(&write_packet_cb).Run(net::OK); EXPECT_EQ(net::OK, complete_cb_2.WaitForResult()); } // Writer completes writing two packets asynchronously. // First write succeeds, second fails. TEST_F(BlimpConnectionTest, AsyncTwoPacketsWriteWithError) { net::CompletionCallback write_packet_cb; InSequence s; EXPECT_CALL(*writer_, WritePacket(BufferEqualsProto(*CreateInputMessage()), _)) .WillOnce(SaveArg<1>(&write_packet_cb)) .RetiresOnSaturation(); EXPECT_CALL(*writer_, WritePacket(BufferEqualsProto(*CreateControlMessage()), _)) .WillOnce(SaveArg<1>(&write_packet_cb)) .RetiresOnSaturation(); EXPECT_CALL(error_observer1_, OnConnectionError(net::ERR_FAILED)); EXPECT_CALL(error_observer2_, OnConnectionError(net::ERR_FAILED)); BlimpMessageProcessor* sender = connection_->GetOutgoingMessageProcessor(); net::TestCompletionCallback complete_cb_1; sender->ProcessMessage(CreateInputMessage(), complete_cb_1.callback()); base::ResetAndReturn(&write_packet_cb).Run(net::OK); EXPECT_EQ(net::OK, complete_cb_1.WaitForResult()); net::TestCompletionCallback complete_cb_2; sender->ProcessMessage(CreateControlMessage(), complete_cb_2.callback()); base::ResetAndReturn(&write_packet_cb).Run(net::ERR_FAILED); EXPECT_EQ(net::ERR_FAILED, complete_cb_2.WaitForResult()); } } // namespace } // namespace blimp