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
15namespace 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.
19TEST(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.
43TEST(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.
114TEST(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.
158TEST(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
228TEST(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
249TEST(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
265TEST(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
287TEST(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
307TEST(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.
327TEST(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.
357TEST(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
488TEST(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
510TEST(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
520TEST(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
540TEST(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
550TEST(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
557TEST(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
570TEST(MessageTest, ErrorResponse_FromMethodCall) {
571  const uint32 kSerial = 123;
572const 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
593TEST(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
624TEST(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
654TEST(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