Home | History | Annotate | Download | only in dbus
      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 "dbus/message.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/logging.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/posix/eintr_wrapper.h"
     11 #include "dbus/object_path.h"
     12 #include "dbus/test_proto.pb.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 namespace dbus {
     16 
     17 // Test that a byte can be properly written and read. We only have this
     18 // test for byte, as repeating this for other basic types is too redundant.
     19 TEST(MessageTest, AppendAndPopByte) {
     20   scoped_ptr<Response> message(Response::CreateEmpty());
     21   MessageWriter writer(message.get());
     22   writer.AppendByte(123);  // The input is 123.
     23 
     24   MessageReader reader(message.get());
     25   ASSERT_TRUE(reader.HasMoreData());  // Should have data to read.
     26   ASSERT_EQ(Message::BYTE, reader.GetDataType());
     27   ASSERT_EQ("y", reader.GetDataSignature());
     28 
     29   bool bool_value = false;
     30   // Should fail as the type is not bool here.
     31   ASSERT_FALSE(reader.PopBool(&bool_value));
     32 
     33   uint8 byte_value = 0;
     34   ASSERT_TRUE(reader.PopByte(&byte_value));
     35   EXPECT_EQ(123, byte_value);  // Should match with the input.
     36   ASSERT_FALSE(reader.HasMoreData());  // Should not have more data to read.
     37 
     38   // Try to get another byte. Should fail.
     39   ASSERT_FALSE(reader.PopByte(&byte_value));
     40 }
     41 
     42 // Check all basic types can be properly written and read.
     43 TEST(MessageTest, AppendAndPopBasicDataTypes) {
     44   scoped_ptr<Response> message(Response::CreateEmpty());
     45   MessageWriter writer(message.get());
     46 
     47   // Append 0, 1, 2, 3, 4, 5, 6, 7, 8, "string", "/object/path".
     48   writer.AppendByte(0);
     49   writer.AppendBool(true);
     50   writer.AppendInt16(2);
     51   writer.AppendUint16(3);
     52   writer.AppendInt32(4);
     53   writer.AppendUint32(5);
     54   writer.AppendInt64(6);
     55   writer.AppendUint64(7);
     56   writer.AppendDouble(8.0);
     57   writer.AppendString("string");
     58   writer.AppendObjectPath(ObjectPath("/object/path"));
     59 
     60   uint8 byte_value = 0;
     61   bool bool_value = false;
     62   int16 int16_value = 0;
     63   uint16 uint16_value = 0;
     64   int32 int32_value = 0;
     65   uint32 uint32_value = 0;
     66   int64 int64_value = 0;
     67   uint64 uint64_value = 0;
     68   double double_value = 0;
     69   std::string string_value;
     70   ObjectPath object_path_value;
     71 
     72   MessageReader reader(message.get());
     73   ASSERT_TRUE(reader.HasMoreData());
     74   ASSERT_EQ("y", reader.GetDataSignature());
     75   ASSERT_TRUE(reader.PopByte(&byte_value));
     76   ASSERT_EQ("b", reader.GetDataSignature());
     77   ASSERT_TRUE(reader.PopBool(&bool_value));
     78   ASSERT_EQ("n", reader.GetDataSignature());
     79   ASSERT_TRUE(reader.PopInt16(&int16_value));
     80   ASSERT_EQ("q", reader.GetDataSignature());
     81   ASSERT_TRUE(reader.PopUint16(&uint16_value));
     82   ASSERT_EQ("i", reader.GetDataSignature());
     83   ASSERT_TRUE(reader.PopInt32(&int32_value));
     84   ASSERT_EQ("u", reader.GetDataSignature());
     85   ASSERT_TRUE(reader.PopUint32(&uint32_value));
     86   ASSERT_EQ("x", reader.GetDataSignature());
     87   ASSERT_TRUE(reader.PopInt64(&int64_value));
     88   ASSERT_EQ("t", reader.GetDataSignature());
     89   ASSERT_TRUE(reader.PopUint64(&uint64_value));
     90   ASSERT_EQ("d", reader.GetDataSignature());
     91   ASSERT_TRUE(reader.PopDouble(&double_value));
     92   ASSERT_EQ("s", reader.GetDataSignature());
     93   ASSERT_TRUE(reader.PopString(&string_value));
     94   ASSERT_EQ("o", reader.GetDataSignature());
     95   ASSERT_TRUE(reader.PopObjectPath(&object_path_value));
     96   ASSERT_EQ("", reader.GetDataSignature());
     97   ASSERT_FALSE(reader.HasMoreData());
     98 
     99   // 0, 1, 2, 3, 4, 5, 6, 7, 8, "string", "/object/path" should be returned.
    100   EXPECT_EQ(0, byte_value);
    101   EXPECT_EQ(true, bool_value);
    102   EXPECT_EQ(2, int16_value);
    103   EXPECT_EQ(3U, uint16_value);
    104   EXPECT_EQ(4, int32_value);
    105   EXPECT_EQ(5U, uint32_value);
    106   EXPECT_EQ(6, int64_value);
    107   EXPECT_EQ(7U, uint64_value);
    108   EXPECT_DOUBLE_EQ(8.0, double_value);
    109   EXPECT_EQ("string", string_value);
    110   EXPECT_EQ(ObjectPath("/object/path"), object_path_value);
    111 }
    112 
    113 // Check all basic types can be properly written and read.
    114 TEST(MessageTest, AppendAndPopFileDescriptor) {
    115   if (!IsDBusTypeUnixFdSupported()) {
    116     LOG(WARNING) << "FD passing is not supported";
    117     return;
    118   }
    119 
    120   scoped_ptr<Response> message(Response::CreateEmpty());
    121   MessageWriter writer(message.get());
    122 
    123   // Append stdout.
    124   FileDescriptor temp(1);
    125   // Descriptor should not be valid until checked.
    126   ASSERT_FALSE(temp.is_valid());
    127   // NB: thread IO requirements not relevant for unit tests.
    128   temp.CheckValidity();
    129   ASSERT_TRUE(temp.is_valid());
    130   writer.AppendFileDescriptor(temp);
    131 
    132   FileDescriptor fd_value;
    133 
    134   MessageReader reader(message.get());
    135   ASSERT_TRUE(reader.HasMoreData());
    136   ASSERT_EQ(Message::UNIX_FD, reader.GetDataType());
    137   ASSERT_EQ("h", reader.GetDataSignature());
    138   ASSERT_TRUE(reader.PopFileDescriptor(&fd_value));
    139   ASSERT_FALSE(reader.HasMoreData());
    140   // Descriptor is not valid until explicitly checked.
    141   ASSERT_FALSE(fd_value.is_valid());
    142   fd_value.CheckValidity();
    143   ASSERT_TRUE(fd_value.is_valid());
    144 
    145   // Stdout should be returned but we cannot check the descriptor
    146   // value because stdout will be dup'd.  Instead check st_rdev
    147   // which should be identical.
    148   struct stat sb_stdout;
    149   int status_stdout = HANDLE_EINTR(fstat(1, &sb_stdout));
    150   ASSERT_GE(status_stdout, 0);
    151   struct stat sb_fd;
    152   int status_fd = HANDLE_EINTR(fstat(fd_value.value(), &sb_fd));
    153   ASSERT_GE(status_fd, 0);
    154   EXPECT_EQ(sb_stdout.st_rdev, sb_fd.st_rdev);
    155 }
    156 
    157 // Check all variant types can be properly written and read.
    158 TEST(MessageTest, AppendAndPopVariantDataTypes) {
    159   scoped_ptr<Response> message(Response::CreateEmpty());
    160   MessageWriter writer(message.get());
    161 
    162   // Append 0, 1, 2, 3, 4, 5, 6, 7, 8, "string", "/object/path".
    163   writer.AppendVariantOfByte(0);
    164   writer.AppendVariantOfBool(true);
    165   writer.AppendVariantOfInt16(2);
    166   writer.AppendVariantOfUint16(3);
    167   writer.AppendVariantOfInt32(4);
    168   writer.AppendVariantOfUint32(5);
    169   writer.AppendVariantOfInt64(6);
    170   writer.AppendVariantOfUint64(7);
    171   writer.AppendVariantOfDouble(8.0);
    172   writer.AppendVariantOfString("string");
    173   writer.AppendVariantOfObjectPath(ObjectPath("/object/path"));
    174 
    175   uint8 byte_value = 0;
    176   bool bool_value = false;
    177   int16 int16_value = 0;
    178   uint16 uint16_value = 0;
    179   int32 int32_value = 0;
    180   uint32 uint32_value = 0;
    181   int64 int64_value = 0;
    182   uint64 uint64_value = 0;
    183   double double_value = 0;
    184   std::string string_value;
    185   ObjectPath object_path_value;
    186 
    187   MessageReader reader(message.get());
    188   ASSERT_TRUE(reader.HasMoreData());
    189   ASSERT_EQ("v", reader.GetDataSignature());
    190   ASSERT_TRUE(reader.PopVariantOfByte(&byte_value));
    191   ASSERT_EQ("v", reader.GetDataSignature());
    192   ASSERT_TRUE(reader.PopVariantOfBool(&bool_value));
    193   ASSERT_EQ("v", reader.GetDataSignature());
    194   ASSERT_TRUE(reader.PopVariantOfInt16(&int16_value));
    195   ASSERT_EQ("v", reader.GetDataSignature());
    196   ASSERT_TRUE(reader.PopVariantOfUint16(&uint16_value));
    197   ASSERT_EQ("v", reader.GetDataSignature());
    198   ASSERT_TRUE(reader.PopVariantOfInt32(&int32_value));
    199   ASSERT_EQ("v", reader.GetDataSignature());
    200   ASSERT_TRUE(reader.PopVariantOfUint32(&uint32_value));
    201   ASSERT_EQ("v", reader.GetDataSignature());
    202   ASSERT_TRUE(reader.PopVariantOfInt64(&int64_value));
    203   ASSERT_EQ("v", reader.GetDataSignature());
    204   ASSERT_TRUE(reader.PopVariantOfUint64(&uint64_value));
    205   ASSERT_EQ("v", reader.GetDataSignature());
    206   ASSERT_TRUE(reader.PopVariantOfDouble(&double_value));
    207   ASSERT_EQ("v", reader.GetDataSignature());
    208   ASSERT_TRUE(reader.PopVariantOfString(&string_value));
    209   ASSERT_EQ("v", reader.GetDataSignature());
    210   ASSERT_TRUE(reader.PopVariantOfObjectPath(&object_path_value));
    211   ASSERT_EQ("", reader.GetDataSignature());
    212   ASSERT_FALSE(reader.HasMoreData());
    213 
    214   // 0, 1, 2, 3, 4, 5, 6, 7, 8, "string", "/object/path" should be returned.
    215   EXPECT_EQ(0, byte_value);
    216   EXPECT_EQ(true, bool_value);
    217   EXPECT_EQ(2, int16_value);
    218   EXPECT_EQ(3U, uint16_value);
    219   EXPECT_EQ(4, int32_value);
    220   EXPECT_EQ(5U, uint32_value);
    221   EXPECT_EQ(6, int64_value);
    222   EXPECT_EQ(7U, uint64_value);
    223   EXPECT_DOUBLE_EQ(8.0, double_value);
    224   EXPECT_EQ("string", string_value);
    225   EXPECT_EQ(ObjectPath("/object/path"), object_path_value);
    226 }
    227 
    228 TEST(MessageTest, ArrayOfBytes) {
    229   scoped_ptr<Response> message(Response::CreateEmpty());
    230   MessageWriter writer(message.get());
    231   std::vector<uint8> bytes;
    232   bytes.push_back(1);
    233   bytes.push_back(2);
    234   bytes.push_back(3);
    235   writer.AppendArrayOfBytes(bytes.data(), bytes.size());
    236 
    237   MessageReader reader(message.get());
    238   const uint8* output_bytes = NULL;
    239   size_t length = 0;
    240   ASSERT_EQ("ay", reader.GetDataSignature());
    241   ASSERT_TRUE(reader.PopArrayOfBytes(&output_bytes, &length));
    242   ASSERT_FALSE(reader.HasMoreData());
    243   ASSERT_EQ(3U, length);
    244   EXPECT_EQ(1, output_bytes[0]);
    245   EXPECT_EQ(2, output_bytes[1]);
    246   EXPECT_EQ(3, output_bytes[2]);
    247 }
    248 
    249 TEST(MessageTest, ArrayOfBytes_Empty) {
    250   scoped_ptr<Response> message(Response::CreateEmpty());
    251   MessageWriter writer(message.get());
    252   std::vector<uint8> bytes;
    253   writer.AppendArrayOfBytes(bytes.data(), bytes.size());
    254 
    255   MessageReader reader(message.get());
    256   const uint8* output_bytes = NULL;
    257   size_t length = 0;
    258   ASSERT_EQ("ay", reader.GetDataSignature());
    259   ASSERT_TRUE(reader.PopArrayOfBytes(&output_bytes, &length));
    260   ASSERT_FALSE(reader.HasMoreData());
    261   ASSERT_EQ(0U, length);
    262   EXPECT_EQ(NULL, output_bytes);
    263 }
    264 
    265 TEST(MessageTest, ArrayOfStrings) {
    266   scoped_ptr<Response> message(Response::CreateEmpty());
    267   MessageWriter writer(message.get());
    268   std::vector<std::string> strings;
    269   strings.push_back("fee");
    270   strings.push_back("fie");
    271   strings.push_back("foe");
    272   strings.push_back("fum");
    273   writer.AppendArrayOfStrings(strings);
    274 
    275   MessageReader reader(message.get());
    276   std::vector<std::string> output_strings;
    277   ASSERT_EQ("as", reader.GetDataSignature());
    278   ASSERT_TRUE(reader.PopArrayOfStrings(&output_strings));
    279   ASSERT_FALSE(reader.HasMoreData());
    280   ASSERT_EQ(4U, output_strings.size());
    281   EXPECT_EQ("fee", output_strings[0]);
    282   EXPECT_EQ("fie", output_strings[1]);
    283   EXPECT_EQ("foe", output_strings[2]);
    284   EXPECT_EQ("fum", output_strings[3]);
    285 }
    286 
    287 TEST(MessageTest, ArrayOfObjectPaths) {
    288   scoped_ptr<Response> message(Response::CreateEmpty());
    289   MessageWriter writer(message.get());
    290   std::vector<ObjectPath> object_paths;
    291   object_paths.push_back(ObjectPath("/object/path/1"));
    292   object_paths.push_back(ObjectPath("/object/path/2"));
    293   object_paths.push_back(ObjectPath("/object/path/3"));
    294   writer.AppendArrayOfObjectPaths(object_paths);
    295 
    296   MessageReader reader(message.get());
    297   std::vector<ObjectPath> output_object_paths;
    298   ASSERT_EQ("ao", reader.GetDataSignature());
    299   ASSERT_TRUE(reader.PopArrayOfObjectPaths(&output_object_paths));
    300   ASSERT_FALSE(reader.HasMoreData());
    301   ASSERT_EQ(3U, output_object_paths.size());
    302   EXPECT_EQ(ObjectPath("/object/path/1"), output_object_paths[0]);
    303   EXPECT_EQ(ObjectPath("/object/path/2"), output_object_paths[1]);
    304   EXPECT_EQ(ObjectPath("/object/path/3"), output_object_paths[2]);
    305 }
    306 
    307 TEST(MessageTest, ProtoBuf) {
    308   scoped_ptr<Response> message(Response::CreateEmpty());
    309   MessageWriter writer(message.get());
    310   TestProto send_message;
    311   send_message.set_text("testing");
    312   send_message.set_number(123);
    313   writer.AppendProtoAsArrayOfBytes(send_message);
    314 
    315   MessageReader reader(message.get());
    316   TestProto receive_message;
    317   ASSERT_EQ("ay", reader.GetDataSignature());
    318   ASSERT_TRUE(reader.PopArrayOfBytesAsProto(&receive_message));
    319   EXPECT_EQ(receive_message.text(), send_message.text());
    320   EXPECT_EQ(receive_message.number(), send_message.number());
    321 }
    322 
    323 
    324 // Test that an array can be properly written and read. We only have this
    325 // test for array, as repeating this for other container types is too
    326 // redundant.
    327 TEST(MessageTest, OpenArrayAndPopArray) {
    328   scoped_ptr<Response> message(Response::CreateEmpty());
    329   MessageWriter writer(message.get());
    330   MessageWriter array_writer(NULL);
    331   writer.OpenArray("s", &array_writer);  // Open an array of strings.
    332   array_writer.AppendString("foo");
    333   array_writer.AppendString("bar");
    334   array_writer.AppendString("baz");
    335   writer.CloseContainer(&array_writer);
    336 
    337   MessageReader reader(message.get());
    338   ASSERT_EQ(Message::ARRAY, reader.GetDataType());
    339   ASSERT_EQ("as", reader.GetDataSignature());
    340   MessageReader array_reader(NULL);
    341   ASSERT_TRUE(reader.PopArray(&array_reader));
    342   ASSERT_FALSE(reader.HasMoreData());  // Should not have more data to read.
    343 
    344   std::string string_value;
    345   ASSERT_TRUE(array_reader.PopString(&string_value));
    346   EXPECT_EQ("foo", string_value);
    347   ASSERT_TRUE(array_reader.PopString(&string_value));
    348   EXPECT_EQ("bar", string_value);
    349   ASSERT_TRUE(array_reader.PopString(&string_value));
    350   EXPECT_EQ("baz", string_value);
    351   // Should not have more data to read.
    352   ASSERT_FALSE(array_reader.HasMoreData());
    353 }
    354 
    355 // Create a complex message using array, struct, variant, dict entry, and
    356 // make sure it can be read properly.
    357 TEST(MessageTest, CreateComplexMessageAndReadIt) {
    358   scoped_ptr<Response> message(Response::CreateEmpty());
    359   MessageWriter writer(message.get());
    360   {
    361     MessageWriter array_writer(NULL);
    362     // Open an array of variants.
    363     writer.OpenArray("v", &array_writer);
    364     {
    365       // The first value in the array.
    366       {
    367         MessageWriter variant_writer(NULL);
    368         // Open a variant of a boolean.
    369         array_writer.OpenVariant("b", &variant_writer);
    370         variant_writer.AppendBool(true);
    371         array_writer.CloseContainer(&variant_writer);
    372       }
    373 
    374       // The second value in the array.
    375       {
    376         MessageWriter variant_writer(NULL);
    377         // Open a variant of a struct that contains a string and an int32.
    378         array_writer.OpenVariant("(si)", &variant_writer);
    379         {
    380           MessageWriter struct_writer(NULL);
    381           variant_writer.OpenStruct(&struct_writer);
    382           struct_writer.AppendString("string");
    383           struct_writer.AppendInt32(123);
    384           variant_writer.CloseContainer(&struct_writer);
    385         }
    386         array_writer.CloseContainer(&variant_writer);
    387       }
    388 
    389       // The third value in the array.
    390       {
    391         MessageWriter variant_writer(NULL);
    392         // Open a variant of an array of string-to-int64 dict entries.
    393         array_writer.OpenVariant("a{sx}", &variant_writer);
    394         {
    395           // Opens an array of string-to-int64 dict entries.
    396           MessageWriter dict_array_writer(NULL);
    397           variant_writer.OpenArray("{sx}", &dict_array_writer);
    398           {
    399             // Opens a string-to-int64 dict entries.
    400             MessageWriter dict_entry_writer(NULL);
    401             dict_array_writer.OpenDictEntry(&dict_entry_writer);
    402             dict_entry_writer.AppendString("foo");
    403             dict_entry_writer.AppendInt64(GG_INT64_C(1234567890123456789));
    404             dict_array_writer.CloseContainer(&dict_entry_writer);
    405           }
    406           variant_writer.CloseContainer(&dict_array_writer);
    407         }
    408         array_writer.CloseContainer(&variant_writer);
    409       }
    410     }
    411     writer.CloseContainer(&array_writer);
    412   }
    413   // What we have created looks like this:
    414   EXPECT_EQ("message_type: MESSAGE_METHOD_RETURN\n"
    415             "signature: av\n"
    416             "\n"
    417             "array [\n"
    418             "  variant     bool true\n"
    419             "  variant     struct {\n"
    420             "      string \"string\"\n"
    421             "      int32 123\n"
    422             "    }\n"
    423             "  variant     array [\n"
    424             "      dict entry {\n"
    425             "        string \"foo\"\n"
    426             "        int64 1234567890123456789\n"
    427             "      }\n"
    428             "    ]\n"
    429             "]\n",
    430             message->ToString());
    431 
    432   MessageReader reader(message.get());
    433   ASSERT_EQ("av", reader.GetDataSignature());
    434   MessageReader array_reader(NULL);
    435   ASSERT_TRUE(reader.PopArray(&array_reader));
    436 
    437   // The first value in the array.
    438   bool bool_value = false;
    439   ASSERT_EQ("v", array_reader.GetDataSignature());
    440   ASSERT_TRUE(array_reader.PopVariantOfBool(&bool_value));
    441   EXPECT_EQ(true, bool_value);
    442 
    443   // The second value in the array.
    444   {
    445     MessageReader variant_reader(NULL);
    446     ASSERT_TRUE(array_reader.PopVariant(&variant_reader));
    447     {
    448       MessageReader struct_reader(NULL);
    449       ASSERT_EQ("(si)", variant_reader.GetDataSignature());
    450       ASSERT_TRUE(variant_reader.PopStruct(&struct_reader));
    451       std::string string_value;
    452       ASSERT_TRUE(struct_reader.PopString(&string_value));
    453       EXPECT_EQ("string", string_value);
    454       int32 int32_value = 0;
    455       ASSERT_TRUE(struct_reader.PopInt32(&int32_value));
    456       EXPECT_EQ(123, int32_value);
    457       ASSERT_FALSE(struct_reader.HasMoreData());
    458     }
    459     ASSERT_FALSE(variant_reader.HasMoreData());
    460   }
    461 
    462   // The third value in the array.
    463   {
    464     MessageReader variant_reader(NULL);
    465     ASSERT_TRUE(array_reader.PopVariant(&variant_reader));
    466     {
    467       MessageReader dict_array_reader(NULL);
    468       ASSERT_EQ("a{sx}", variant_reader.GetDataSignature());
    469       ASSERT_TRUE(variant_reader.PopArray(&dict_array_reader));
    470       {
    471         MessageReader dict_entry_reader(NULL);
    472         ASSERT_TRUE(dict_array_reader.PopDictEntry(&dict_entry_reader));
    473         std::string string_value;
    474         ASSERT_TRUE(dict_entry_reader.PopString(&string_value));
    475         EXPECT_EQ("foo", string_value);
    476         int64 int64_value = 0;
    477         ASSERT_TRUE(dict_entry_reader.PopInt64(&int64_value));
    478         EXPECT_EQ(GG_INT64_C(1234567890123456789), int64_value);
    479       }
    480       ASSERT_FALSE(dict_array_reader.HasMoreData());
    481     }
    482     ASSERT_FALSE(variant_reader.HasMoreData());
    483   }
    484   ASSERT_FALSE(array_reader.HasMoreData());
    485   ASSERT_FALSE(reader.HasMoreData());
    486 }
    487 
    488 TEST(MessageTest, MethodCall) {
    489   MethodCall method_call("com.example.Interface", "SomeMethod");
    490   EXPECT_TRUE(method_call.raw_message() != NULL);
    491   EXPECT_EQ(Message::MESSAGE_METHOD_CALL, method_call.GetMessageType());
    492   EXPECT_EQ("MESSAGE_METHOD_CALL", method_call.GetMessageTypeAsString());
    493   method_call.SetDestination("com.example.Service");
    494   method_call.SetPath(ObjectPath("/com/example/Object"));
    495 
    496   MessageWriter writer(&method_call);
    497   writer.AppendString("payload");
    498 
    499   EXPECT_EQ("message_type: MESSAGE_METHOD_CALL\n"
    500             "destination: com.example.Service\n"
    501             "path: /com/example/Object\n"
    502             "interface: com.example.Interface\n"
    503             "member: SomeMethod\n"
    504             "signature: s\n"
    505             "\n"
    506             "string \"payload\"\n",
    507             method_call.ToString());
    508 }
    509 
    510 TEST(MessageTest, MethodCall_FromRawMessage) {
    511   DBusMessage* raw_message = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
    512   dbus_message_set_interface(raw_message, "com.example.Interface");
    513   dbus_message_set_member(raw_message, "SomeMethod");
    514 
    515   scoped_ptr<MethodCall> method_call(MethodCall::FromRawMessage(raw_message));
    516   EXPECT_EQ("com.example.Interface", method_call->GetInterface());
    517   EXPECT_EQ("SomeMethod", method_call->GetMember());
    518 }
    519 
    520 TEST(MessageTest, Signal) {
    521   Signal signal("com.example.Interface", "SomeSignal");
    522   EXPECT_TRUE(signal.raw_message() != NULL);
    523   EXPECT_EQ(Message::MESSAGE_SIGNAL, signal.GetMessageType());
    524   EXPECT_EQ("MESSAGE_SIGNAL", signal.GetMessageTypeAsString());
    525   signal.SetPath(ObjectPath("/com/example/Object"));
    526 
    527   MessageWriter writer(&signal);
    528   writer.AppendString("payload");
    529 
    530   EXPECT_EQ("message_type: MESSAGE_SIGNAL\n"
    531             "path: /com/example/Object\n"
    532             "interface: com.example.Interface\n"
    533             "member: SomeSignal\n"
    534             "signature: s\n"
    535             "\n"
    536             "string \"payload\"\n",
    537             signal.ToString());
    538 }
    539 
    540 TEST(MessageTest, Signal_FromRawMessage) {
    541   DBusMessage* raw_message = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
    542   dbus_message_set_interface(raw_message, "com.example.Interface");
    543   dbus_message_set_member(raw_message, "SomeSignal");
    544 
    545   scoped_ptr<Signal> signal(Signal::FromRawMessage(raw_message));
    546   EXPECT_EQ("com.example.Interface", signal->GetInterface());
    547   EXPECT_EQ("SomeSignal", signal->GetMember());
    548 }
    549 
    550 TEST(MessageTest, Response) {
    551   scoped_ptr<Response> response(Response::CreateEmpty());
    552   EXPECT_TRUE(response->raw_message());
    553   EXPECT_EQ(Message::MESSAGE_METHOD_RETURN, response->GetMessageType());
    554   EXPECT_EQ("MESSAGE_METHOD_RETURN", response->GetMessageTypeAsString());
    555 }
    556 
    557 TEST(MessageTest, Response_FromMethodCall) {
    558   const uint32 kSerial = 123;
    559   MethodCall method_call("com.example.Interface", "SomeMethod");
    560   method_call.SetSerial(kSerial);
    561 
    562   scoped_ptr<Response> response(
    563       Response::FromMethodCall(&method_call));
    564   EXPECT_EQ(Message::MESSAGE_METHOD_RETURN, response->GetMessageType());
    565   EXPECT_EQ("MESSAGE_METHOD_RETURN", response->GetMessageTypeAsString());
    566   // The serial should be copied to the reply serial.
    567   EXPECT_EQ(kSerial, response->GetReplySerial());
    568 }
    569 
    570 TEST(MessageTest, ErrorResponse_FromMethodCall) {
    571   const uint32 kSerial = 123;
    572 const char kErrorMessage[] = "error message";
    573 
    574   MethodCall method_call("com.example.Interface", "SomeMethod");
    575   method_call.SetSerial(kSerial);
    576 
    577   scoped_ptr<ErrorResponse> error_response(
    578       ErrorResponse::FromMethodCall(&method_call,
    579                                     DBUS_ERROR_FAILED,
    580                                     kErrorMessage));
    581   EXPECT_EQ(Message::MESSAGE_ERROR, error_response->GetMessageType());
    582   EXPECT_EQ("MESSAGE_ERROR", error_response->GetMessageTypeAsString());
    583   // The serial should be copied to the reply serial.
    584   EXPECT_EQ(kSerial, error_response->GetReplySerial());
    585 
    586   // Error message should be added to the payload.
    587   MessageReader reader(error_response.get());
    588   std::string error_message;
    589   ASSERT_TRUE(reader.PopString(&error_message));
    590   EXPECT_EQ(kErrorMessage, error_message);
    591 }
    592 
    593 TEST(MessageTest, GetAndSetHeaders) {
    594   scoped_ptr<Response> message(Response::CreateEmpty());
    595 
    596   EXPECT_EQ("", message->GetDestination());
    597   EXPECT_EQ(ObjectPath(std::string()), message->GetPath());
    598   EXPECT_EQ("", message->GetInterface());
    599   EXPECT_EQ("", message->GetMember());
    600   EXPECT_EQ("", message->GetErrorName());
    601   EXPECT_EQ("", message->GetSender());
    602   EXPECT_EQ(0U, message->GetSerial());
    603   EXPECT_EQ(0U, message->GetReplySerial());
    604 
    605   EXPECT_TRUE(message->SetDestination("org.chromium.destination"));
    606   EXPECT_TRUE(message->SetPath(ObjectPath("/org/chromium/path")));
    607   EXPECT_TRUE(message->SetInterface("org.chromium.interface"));
    608   EXPECT_TRUE(message->SetMember("member"));
    609   EXPECT_TRUE(message->SetErrorName("org.chromium.error"));
    610   EXPECT_TRUE(message->SetSender(":1.2"));
    611   message->SetSerial(123);
    612   message->SetReplySerial(456);
    613 
    614   EXPECT_EQ("org.chromium.destination", message->GetDestination());
    615   EXPECT_EQ(ObjectPath("/org/chromium/path"), message->GetPath());
    616   EXPECT_EQ("org.chromium.interface", message->GetInterface());
    617   EXPECT_EQ("member", message->GetMember());
    618   EXPECT_EQ("org.chromium.error", message->GetErrorName());
    619   EXPECT_EQ(":1.2", message->GetSender());
    620   EXPECT_EQ(123U, message->GetSerial());
    621   EXPECT_EQ(456U, message->GetReplySerial());
    622 }
    623 
    624 TEST(MessageTest, SetInvalidHeaders) {
    625   scoped_ptr<Response> message(Response::CreateEmpty());
    626   EXPECT_EQ("", message->GetDestination());
    627   EXPECT_EQ(ObjectPath(std::string()), message->GetPath());
    628   EXPECT_EQ("", message->GetInterface());
    629   EXPECT_EQ("", message->GetMember());
    630   EXPECT_EQ("", message->GetErrorName());
    631   EXPECT_EQ("", message->GetSender());
    632 
    633   // Empty element between periods.
    634   EXPECT_FALSE(message->SetDestination("org..chromium"));
    635   // Trailing '/' is only allowed for the root path.
    636   EXPECT_FALSE(message->SetPath(ObjectPath("/org/chromium/")));
    637   // Interface name cannot contain '/'.
    638   EXPECT_FALSE(message->SetInterface("org/chromium/interface"));
    639   // Member name cannot begin with a digit.
    640   EXPECT_FALSE(message->SetMember("1member"));
    641   // Error name cannot begin with a period.
    642   EXPECT_FALSE(message->SetErrorName(".org.chromium.error"));
    643   // Disallowed characters.
    644   EXPECT_FALSE(message->SetSender("?!#*"));
    645 
    646   EXPECT_EQ("", message->GetDestination());
    647   EXPECT_EQ(ObjectPath(std::string()), message->GetPath());
    648   EXPECT_EQ("", message->GetInterface());
    649   EXPECT_EQ("", message->GetMember());
    650   EXPECT_EQ("", message->GetErrorName());
    651   EXPECT_EQ("", message->GetSender());
    652 }
    653 
    654 TEST(MessageTest, ToString_LongString) {
    655   const std::string kLongString(1000, 'o');
    656 
    657   scoped_ptr<Response> message(Response::CreateEmpty());
    658   MessageWriter writer(message.get());
    659   writer.AppendString(kLongString);
    660 
    661   ASSERT_EQ("message_type: MESSAGE_METHOD_RETURN\n"
    662             "signature: s\n\n"
    663             "string \"oooooooooooooooooooooooooooooooooooooooooooooooo"
    664             "oooooooooooooooooooooooooooooooooooooooooooooooooooo... "
    665             "(1000 bytes in total)\"\n",
    666             message->ToString());
    667 }
    668 
    669 }  // namespace dbus
    670