Home | History | Annotate | Download | only in ipc
      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 "build/build_config.h"
      6 
      7 #if defined(OS_WIN)
      8 #include <windows.h>
      9 #endif
     10 
     11 #include <string>
     12 
     13 #include "base/message_loop/message_loop.h"
     14 #include "base/pickle.h"
     15 #include "base/threading/thread.h"
     16 #include "ipc/ipc_message.h"
     17 #include "ipc/ipc_test_base.h"
     18 #include "ipc/ipc_test_channel_listener.h"
     19 
     20 namespace {
     21 
     22 class IPCChannelTest : public IPCTestBase {
     23 };
     24 
     25 // TODO(viettrungluu): Move to a separate IPCMessageTest.
     26 TEST_F(IPCChannelTest, BasicMessageTest) {
     27   int v1 = 10;
     28   std::string v2("foobar");
     29   std::wstring v3(L"hello world");
     30 
     31   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
     32   EXPECT_TRUE(m.WriteInt(v1));
     33   EXPECT_TRUE(m.WriteString(v2));
     34   EXPECT_TRUE(m.WriteWString(v3));
     35 
     36   PickleIterator iter(m);
     37 
     38   int vi;
     39   std::string vs;
     40   std::wstring vw;
     41 
     42   EXPECT_TRUE(m.ReadInt(&iter, &vi));
     43   EXPECT_EQ(v1, vi);
     44 
     45   EXPECT_TRUE(m.ReadString(&iter, &vs));
     46   EXPECT_EQ(v2, vs);
     47 
     48   EXPECT_TRUE(m.ReadWString(&iter, &vw));
     49   EXPECT_EQ(v3, vw);
     50 
     51   // should fail
     52   EXPECT_FALSE(m.ReadInt(&iter, &vi));
     53   EXPECT_FALSE(m.ReadString(&iter, &vs));
     54   EXPECT_FALSE(m.ReadWString(&iter, &vw));
     55 }
     56 
     57 TEST_F(IPCChannelTest, ChannelTest) {
     58   Init("GenericClient");
     59 
     60   // Set up IPC channel and start client.
     61   IPC::TestChannelListener listener;
     62   CreateChannel(&listener);
     63   listener.Init(sender());
     64   ASSERT_TRUE(ConnectChannel());
     65   ASSERT_TRUE(StartClient());
     66 
     67   IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
     68 
     69   // Run message loop.
     70   base::MessageLoop::current()->Run();
     71 
     72   // Close the channel so the client's OnChannelError() gets fired.
     73   channel()->Close();
     74 
     75   EXPECT_TRUE(WaitForClientShutdown());
     76   DestroyChannel();
     77 }
     78 
     79 // TODO(viettrungluu): Move to a separate IPCChannelWinTest.
     80 #if defined(OS_WIN)
     81 TEST_F(IPCChannelTest, ChannelTestExistingPipe) {
     82   Init("GenericClient");
     83 
     84   // Create pipe manually using the standard Chromium name and set up IPC
     85   // channel.
     86   IPC::TestChannelListener listener;
     87   std::string name("\\\\.\\pipe\\chrome.");
     88   name.append(GetChannelName("GenericClient"));
     89   HANDLE pipe = CreateNamedPipeA(name.c_str(),
     90                                  PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
     91                                      FILE_FLAG_FIRST_PIPE_INSTANCE,
     92                                  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
     93                                  1,
     94                                  4096,
     95                                  4096,
     96                                  5000,
     97                                  NULL);
     98   CreateChannelFromChannelHandle(IPC::ChannelHandle(pipe), &listener);
     99   CloseHandle(pipe);  // The channel duplicates the handle.
    100   listener.Init(sender());
    101 
    102   // Connect to channel and start client.
    103   ASSERT_TRUE(ConnectChannel());
    104   ASSERT_TRUE(StartClient());
    105 
    106   IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
    107 
    108   // Run message loop.
    109   base::MessageLoop::current()->Run();
    110 
    111   // Close the channel so the client's OnChannelError() gets fired.
    112   channel()->Close();
    113 
    114   EXPECT_TRUE(WaitForClientShutdown());
    115   DestroyChannel();
    116 }
    117 #endif  // defined (OS_WIN)
    118 
    119 TEST_F(IPCChannelTest, ChannelProxyTest) {
    120   Init("GenericClient");
    121 
    122   base::Thread thread("ChannelProxyTestServer");
    123   base::Thread::Options options;
    124   options.message_loop_type = base::MessageLoop::TYPE_IO;
    125   thread.StartWithOptions(options);
    126 
    127   // Set up IPC channel proxy.
    128   IPC::TestChannelListener listener;
    129   CreateChannelProxy(&listener, thread.message_loop_proxy().get());
    130   listener.Init(sender());
    131 
    132   ASSERT_TRUE(StartClient());
    133 
    134   IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
    135 
    136   // Run message loop.
    137   base::MessageLoop::current()->Run();
    138 
    139   EXPECT_TRUE(WaitForClientShutdown());
    140 
    141   // Destroy the channel proxy before shutting down the thread.
    142   DestroyChannelProxy();
    143   thread.Stop();
    144 }
    145 
    146 class ChannelListenerWithOnConnectedSend : public IPC::TestChannelListener {
    147  public:
    148   ChannelListenerWithOnConnectedSend() {}
    149   virtual ~ChannelListenerWithOnConnectedSend() {}
    150 
    151   virtual void OnChannelConnected(int32 peer_pid) OVERRIDE {
    152     SendNextMessage();
    153   }
    154 };
    155 
    156 #if defined(OS_WIN)
    157 // Acting flakey in Windows. http://crbug.com/129595
    158 #define MAYBE_SendMessageInChannelConnected DISABLED_SendMessageInChannelConnected
    159 #else
    160 #define MAYBE_SendMessageInChannelConnected SendMessageInChannelConnected
    161 #endif
    162 // This tests the case of a listener sending back an event in its
    163 // OnChannelConnected handler.
    164 TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) {
    165   Init("GenericClient");
    166 
    167   // Set up IPC channel and start client.
    168   ChannelListenerWithOnConnectedSend listener;
    169   CreateChannel(&listener);
    170   listener.Init(sender());
    171   ASSERT_TRUE(ConnectChannel());
    172   ASSERT_TRUE(StartClient());
    173 
    174   IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
    175 
    176   // Run message loop.
    177   base::MessageLoop::current()->Run();
    178 
    179   // Close the channel so the client's OnChannelError() gets fired.
    180   channel()->Close();
    181 
    182   EXPECT_TRUE(WaitForClientShutdown());
    183   DestroyChannel();
    184 }
    185 
    186 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(GenericClient) {
    187   base::MessageLoopForIO main_message_loop;
    188   IPC::TestChannelListener listener;
    189 
    190   // Set up IPC channel.
    191   scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
    192       IPCTestBase::GetChannelName("GenericClient"),
    193       &listener));
    194   CHECK(channel->Connect());
    195   listener.Init(channel.get());
    196   IPC::TestChannelListener::SendOneMessage(channel.get(), "hello from child");
    197 
    198   base::MessageLoop::current()->Run();
    199   return 0;
    200 }
    201 
    202 }  // namespace
    203