| Index: components/arc/arc_bridge_service_unittest.cc | 
| diff --git a/components/arc/arc_bridge_service_unittest.cc b/components/arc/arc_bridge_service_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..be17e9bf8d280c2cc4f65274c8ce41d157aa6bd1 | 
| --- /dev/null | 
| +++ b/components/arc/arc_bridge_service_unittest.cc | 
| @@ -0,0 +1,124 @@ | 
| +// 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 "components/arc/arc_bridge_service.h" | 
| + | 
| +#include "base/memory/ref_counted.h" | 
| +#include "base/run_loop.h" | 
| +#include "chromeos/arc/bridge/common/arc_host_messages.h" | 
| +#include "ipc/ipc_channel.h" | 
| +#include "ipc/ipc_channel_proxy.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +namespace arc { | 
| + | 
| +namespace { | 
| + | 
| +// A fake sender that can connect to a specified IPC::ChannelHandle. | 
| +class IPCSenderFake : public IPC::Listener, | 
| +                      public IPC::Sender { | 
| + public: | 
| +  IPCSenderFake() | 
| +    : ipc_thread_("IPCSenderFake") { | 
| +    ipc_thread_.StartWithOptions( | 
| +        base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 
| +  } | 
| +  ~IPCSenderFake() override {} | 
| + | 
| +  // Connects as a client to the specified |handle|. | 
| +  bool Connect(const IPC::ChannelHandle& handle) { | 
| +    ipc_channel_ = IPC::ChannelProxy::Create(handle, | 
| +                                             IPC::Channel::MODE_CLIENT, | 
| +                                             this, | 
| +                                             ipc_thread_.task_runner().get()); | 
| +    return ipc_channel_; | 
| +  } | 
| + | 
| +  bool Send(IPC::Message* msg) override { | 
| +    return ipc_channel_->Send(msg); | 
| +  } | 
| + | 
| +  bool OnMessageReceived(const IPC::Message& message) override { | 
| +    return true; | 
| +  } | 
| + | 
| + private: | 
| +  // Thread in which IPC messaging is performed. | 
| +  base::Thread ipc_thread_; | 
| + | 
| +  // The channel through which messages are sent. | 
| +  scoped_ptr<IPC::ChannelProxy> ipc_channel_; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(IPCSenderFake); | 
| +}; | 
| + | 
| +}  // namespace | 
| + | 
| +class ArcBridgeTest : public testing::Test, | 
| +                      public ArcBridgeService::Observer { | 
| + public: | 
| +  ArcBridgeTest() : ready_(false) {} | 
| +  ~ArcBridgeTest() override {} | 
| + | 
| +  void OnStateChanged(ArcBridgeService::State state) override { | 
| +    if (state == ArcBridgeService::READY) { | 
| +      ready_ = true; | 
| +      message_loop_.Quit(); | 
| +    } | 
| +  } | 
| + | 
| +  bool ready() const { return ready_; } | 
| + | 
| + protected: | 
| +  scoped_ptr<IPCSenderFake> fake_sender_; | 
| + | 
| + private: | 
| +  void SetUp() override { | 
| +    ready_ = false; | 
| +    service_.reset(new ArcBridgeService(message_loop_.task_runner())); | 
| + | 
| +    service_->AddObserver(this); | 
| +    service_->SetEnabled(true); | 
| + | 
| +    IPC::ChannelHandle handle(IPC::Channel::GenerateUniqueRandomChannelID()); | 
| +    // Testing code does not do all the steps that are done by regular | 
| +    // connection. In particular, it does not need to create a directory for | 
| +    // the socket, so manually set the state to CONNECTING. | 
| +    service_->SetState(ArcBridgeService::CONNECTING); | 
| +    // Connect directly to the specified channel instead of going through | 
| +    // D-Bus, since it is not available for tests. | 
| +    EXPECT_TRUE(service_->Connect(handle, IPC::Channel::MODE_SERVER)); | 
| +    // Testing code does also not send D-Bus messages, so set the state to | 
| +    // STARTING. | 
| +    service_->SetState(ArcBridgeService::STARTING); | 
| +    fake_sender_.reset(new IPCSenderFake()); | 
| +    EXPECT_TRUE(fake_sender_); | 
| +    EXPECT_TRUE(fake_sender_->Connect(handle)); | 
| +  } | 
| + | 
| +  void TearDown() override { | 
| +    fake_sender_.reset(); | 
| +    service_->RemoveObserver(this); | 
| +    service_.reset(); | 
| +  } | 
| + | 
| +  bool ready_; | 
| +  base::MessageLoopForUI message_loop_; | 
| +  scoped_ptr<ArcBridgeService> service_; | 
| +}; | 
| + | 
| +// Exercises the basic functionality of the ARC Bridge Service.  A message from | 
| +// within the instance should cause the observer to be notified. | 
| +TEST_F(ArcBridgeTest, Basic) { | 
| +  ASSERT_FALSE(ready()); | 
| + | 
| +  ASSERT_TRUE(fake_sender_->Send(new ArcInstanceHostMsg_InstanceReady())); | 
| + | 
| +  base::RunLoop run_loop; | 
| +  run_loop.Run(); | 
| + | 
| +  EXPECT_TRUE(ready()); | 
| +} | 
| + | 
| +}  // namespace arc | 
|  |