Home | History | Annotate | Download | only in ipc
      1 // Copyright (c) 2011 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 // Unit test to make sure that the serialization of synchronous IPC messages
      6 // works.  This ensures that the macros and templates were defined correctly.
      7 // Doesn't test the IPC channel mechanism.
      8 
      9 #include <string.h>
     10 
     11 #include "base/basictypes.h"
     12 #include "ipc/ipc_message.h"
     13 #include "ipc/ipc_message_utils.h"
     14 #include "base/logging.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 #define IPC_MESSAGE_IMPL
     18 #include "ipc/ipc_sync_message_unittest.h"
     19 
     20 namespace {
     21 
     22 static IPC::Message* g_reply;
     23 
     24 class TestMessageReceiver {
     25  public:
     26 
     27   void On_0_1(bool* out1) {
     28     *out1 = false;
     29   }
     30 
     31   void On_0_2(bool* out1, int* out2) {
     32     *out1 = true;
     33     *out2 = 2;
     34   }
     35 
     36   void On_0_3(bool* out1, int* out2, std::string* out3) {
     37     *out1 = false;
     38     *out2 = 3;
     39     *out3 = "0_3";
     40   }
     41 
     42   void On_1_1(int in1, bool* out1) {
     43     DCHECK_EQ(1, in1);
     44     *out1 = true;
     45   }
     46 
     47   void On_1_2(bool in1, bool* out1, int* out2) {
     48     DCHECK(!in1);
     49     *out1 = true;
     50     *out2 = 12;
     51   }
     52 
     53   void On_1_3(int in1, std::string* out1, int* out2, bool* out3) {
     54     DCHECK_EQ(3, in1);
     55     *out1 = "1_3";
     56     *out2 = 13;
     57     *out3 = false;
     58   }
     59 
     60   void On_2_1(int in1, bool in2, bool* out1) {
     61     DCHECK_EQ(1, in1);
     62     DCHECK(!in2);
     63     *out1 = true;
     64   }
     65 
     66   void On_2_2(bool in1, int in2, bool* out1, int* out2) {
     67     DCHECK(!in1);
     68     DCHECK_EQ(2, in2);
     69     *out1 = true;
     70     *out2 = 22;
     71   }
     72 
     73   void On_2_3(int in1, bool in2, std::string* out1, int* out2, bool* out3) {
     74     DCHECK_EQ(3, in1);
     75     DCHECK(in2);
     76     *out1 = "2_3";
     77     *out2 = 23;
     78     *out3 = false;
     79   }
     80 
     81   void On_3_1(int in1, bool in2, std::string in3, bool* out1) {
     82     DCHECK_EQ(1, in1);
     83     DCHECK(!in2);
     84     DCHECK_EQ("3_1", in3);
     85     *out1 = true;
     86   }
     87 
     88   void On_3_2(std::string in1, bool in2, int in3, bool* out1, int* out2) {
     89     DCHECK_EQ("3_2", in1);
     90     DCHECK(!in2);
     91     DCHECK_EQ(2, in3);
     92     *out1 = true;
     93     *out2 = 32;
     94   }
     95 
     96   void On_3_3(int in1, std::string in2, bool in3, std::string* out1, int* out2,
     97               bool* out3) {
     98     DCHECK_EQ(3, in1);
     99     DCHECK_EQ("3_3", in2);
    100     DCHECK(in3);
    101     *out1 = "3_3";
    102     *out2 = 33;
    103     *out3 = false;
    104   }
    105 
    106   void On_3_4(bool in1, int in2, std::string in3, int* out1, bool* out2,
    107               std::string* out3, bool* out4) {
    108     DCHECK(in1);
    109     DCHECK_EQ(3, in2);
    110     DCHECK_EQ("3_4", in3);
    111     *out1 = 34;
    112     *out2 = true;
    113     *out3 = "3_4";
    114     *out4 = false;
    115   }
    116 
    117   bool Send(IPC::Message* message) {
    118     // gets the reply message, stash in global
    119     DCHECK(g_reply == NULL);
    120     g_reply = message;
    121     return true;
    122   }
    123 
    124   bool OnMessageReceived(const IPC::Message& msg) {
    125     IPC_BEGIN_MESSAGE_MAP(TestMessageReceiver, msg)
    126       IPC_MESSAGE_HANDLER(Msg_C_0_1, On_0_1)
    127       IPC_MESSAGE_HANDLER(Msg_C_0_2, On_0_2)
    128       IPC_MESSAGE_HANDLER(Msg_C_0_3, On_0_3)
    129       IPC_MESSAGE_HANDLER(Msg_C_1_1, On_1_1)
    130       IPC_MESSAGE_HANDLER(Msg_C_1_2, On_1_2)
    131       IPC_MESSAGE_HANDLER(Msg_C_1_3, On_1_3)
    132       IPC_MESSAGE_HANDLER(Msg_C_2_1, On_2_1)
    133       IPC_MESSAGE_HANDLER(Msg_C_2_2, On_2_2)
    134       IPC_MESSAGE_HANDLER(Msg_C_2_3, On_2_3)
    135       IPC_MESSAGE_HANDLER(Msg_C_3_1, On_3_1)
    136       IPC_MESSAGE_HANDLER(Msg_C_3_2, On_3_2)
    137       IPC_MESSAGE_HANDLER(Msg_C_3_3, On_3_3)
    138       IPC_MESSAGE_HANDLER(Msg_C_3_4, On_3_4)
    139       IPC_MESSAGE_HANDLER(Msg_R_0_1, On_0_1)
    140       IPC_MESSAGE_HANDLER(Msg_R_0_2, On_0_2)
    141       IPC_MESSAGE_HANDLER(Msg_R_0_3, On_0_3)
    142       IPC_MESSAGE_HANDLER(Msg_R_1_1, On_1_1)
    143       IPC_MESSAGE_HANDLER(Msg_R_1_2, On_1_2)
    144       IPC_MESSAGE_HANDLER(Msg_R_1_3, On_1_3)
    145       IPC_MESSAGE_HANDLER(Msg_R_2_1, On_2_1)
    146       IPC_MESSAGE_HANDLER(Msg_R_2_2, On_2_2)
    147       IPC_MESSAGE_HANDLER(Msg_R_2_3, On_2_3)
    148       IPC_MESSAGE_HANDLER(Msg_R_3_1, On_3_1)
    149       IPC_MESSAGE_HANDLER(Msg_R_3_2, On_3_2)
    150       IPC_MESSAGE_HANDLER(Msg_R_3_3, On_3_3)
    151       IPC_MESSAGE_HANDLER(Msg_R_3_4, On_3_4)
    152     IPC_END_MESSAGE_MAP()
    153     return true;
    154   }
    155 
    156 };
    157 
    158 void Send(IPC::SyncMessage* msg) {
    159   static TestMessageReceiver receiver;
    160 
    161   IPC::MessageReplyDeserializer* reply_serializer = msg->GetReplyDeserializer();
    162   DCHECK(reply_serializer != NULL);
    163 
    164   // "send" the message
    165   receiver.OnMessageReceived(*msg);
    166   delete msg;
    167 
    168   // get the reply message from the global, and deserialize the output
    169   // parameters into the output pointers.
    170   DCHECK(g_reply != NULL);
    171   bool result = reply_serializer->SerializeOutputParameters(*g_reply);
    172   DCHECK(result);
    173   delete g_reply;
    174   g_reply = NULL;
    175   delete reply_serializer;
    176 }
    177 
    178 TEST(IPCSyncMessageTest, Main) {
    179   bool bool1 = true;
    180   int int1 = 0;
    181   std::string string1;
    182 
    183   Send(new Msg_C_0_1(&bool1));
    184   DCHECK(!bool1);
    185 
    186   Send(new Msg_C_0_2(&bool1, &int1));
    187   DCHECK(bool1);
    188   DCHECK_EQ(2, int1);
    189 
    190   Send(new Msg_C_0_3(&bool1, &int1, &string1));
    191   DCHECK(!bool1);
    192   DCHECK_EQ(3, int1);
    193   DCHECK_EQ("0_3", string1);
    194 
    195   bool1 = false;
    196   Send(new Msg_C_1_1(1, &bool1));
    197   DCHECK(bool1);
    198 
    199   bool1 = false;
    200   Send(new Msg_C_1_2(false, &bool1, &int1));
    201   DCHECK(bool1);
    202   DCHECK_EQ(12, int1);
    203 
    204   bool1 = true;
    205   Send(new Msg_C_1_3(3, &string1, &int1, &bool1));
    206   DCHECK_EQ("1_3", string1);
    207   DCHECK_EQ(13, int1);
    208   DCHECK(!bool1);
    209 
    210   bool1 = false;
    211   Send(new Msg_C_2_1(1, false, &bool1));
    212   DCHECK(bool1);
    213 
    214   bool1 = false;
    215   Send(new Msg_C_2_2(false, 2, &bool1, &int1));
    216   DCHECK(bool1);
    217   DCHECK_EQ(22, int1);
    218 
    219   bool1 = true;
    220   Send(new Msg_C_2_3(3, true, &string1, &int1, &bool1));
    221   DCHECK_EQ("2_3", string1);
    222   DCHECK_EQ(23, int1);
    223   DCHECK(!bool1);
    224 
    225   bool1 = false;
    226   Send(new Msg_C_3_1(1, false, "3_1", &bool1));
    227   DCHECK(bool1);
    228 
    229   bool1 = false;
    230   Send(new Msg_C_3_2("3_2", false, 2, &bool1, &int1));
    231   DCHECK(bool1);
    232   DCHECK_EQ(32, int1);
    233 
    234   bool1 = true;
    235   Send(new Msg_C_3_3(3, "3_3", true, &string1, &int1, &bool1));
    236   DCHECK_EQ("3_3", string1);
    237   DCHECK_EQ(33, int1);
    238   DCHECK(!bool1);
    239 
    240   bool1 = false;
    241   bool bool2 = true;
    242   Send(new Msg_C_3_4(true, 3, "3_4", &int1, &bool1, &string1, &bool2));
    243   DCHECK_EQ(34, int1);
    244   DCHECK(bool1);
    245   DCHECK_EQ("3_4", string1);
    246   DCHECK(!bool2);
    247 
    248   // Routed messages, just a copy of the above but with extra routing paramater
    249   Send(new Msg_R_0_1(0, &bool1));
    250   DCHECK(!bool1);
    251 
    252   Send(new Msg_R_0_2(0, &bool1, &int1));
    253   DCHECK(bool1);
    254   DCHECK_EQ(2, int1);
    255 
    256   Send(new Msg_R_0_3(0, &bool1, &int1, &string1));
    257   DCHECK(!bool1);
    258   DCHECK_EQ(3, int1);
    259   DCHECK_EQ("0_3", string1);
    260 
    261   bool1 = false;
    262   Send(new Msg_R_1_1(0, 1, &bool1));
    263   DCHECK(bool1);
    264 
    265   bool1 = false;
    266   Send(new Msg_R_1_2(0, false, &bool1, &int1));
    267   DCHECK(bool1);
    268   DCHECK_EQ(12, int1);
    269 
    270   bool1 = true;
    271   Send(new Msg_R_1_3(0, 3, &string1, &int1, &bool1));
    272   DCHECK_EQ("1_3", string1);
    273   DCHECK_EQ(13, int1);
    274   DCHECK(!bool1);
    275 
    276   bool1 = false;
    277   Send(new Msg_R_2_1(0, 1, false, &bool1));
    278   DCHECK(bool1);
    279 
    280   bool1 = false;
    281   Send(new Msg_R_2_2(0, false, 2, &bool1, &int1));
    282   DCHECK(bool1);
    283   DCHECK_EQ(22, int1);
    284 
    285   bool1 = true;
    286   Send(new Msg_R_2_3(0, 3, true, &string1, &int1, &bool1));
    287   DCHECK(!bool1);
    288   DCHECK_EQ("2_3", string1);
    289   DCHECK_EQ(23, int1);
    290 
    291   bool1 = false;
    292   Send(new Msg_R_3_1(0, 1, false, "3_1", &bool1));
    293   DCHECK(bool1);
    294 
    295   bool1 = false;
    296   Send(new Msg_R_3_2(0, "3_2", false, 2, &bool1, &int1));
    297   DCHECK(bool1);
    298   DCHECK_EQ(32, int1);
    299 
    300   bool1 = true;
    301   Send(new Msg_R_3_3(0, 3, "3_3", true, &string1, &int1, &bool1));
    302   DCHECK_EQ("3_3", string1);
    303   DCHECK_EQ(33, int1);
    304   DCHECK(!bool1);
    305 }
    306 
    307 }  // namespace
    308