"Fossies" - the Fresh Open Source Software Archive

Member "google-gadgets-for-linux-0.11.2/ggadget/dbus/tests/dbus_marshaller_test.cc" (31 May 2009, 29080 Bytes) of package /linux/misc/old/google-gadgets-for-linux-0.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2    Copyright 2008 Google Inc.
    3 
    4    Licensed under the Apache License, Version 2.0 (the "License");
    5    you may not use this file except in compliance with the License.
    6    You may obtain a copy of the License at
    7 
    8 http://www.apache.org/licenses/LICENSE-2.0
    9 
   10 Unless required by applicable law or agreed to in writing, software
   11 distributed under the License is distributed on an "AS IS" BASIS,
   12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13 See the License for the specific language governing permissions and
   14 limitations under the License.
   15 */
   16 
   17 #include <set>
   18 #include <stdio.h>
   19 #include <stdlib.h>
   20 #include <dbus/dbus.h>
   21 #include <limits>
   22 
   23 #include "ggadget/dbus/dbus_proxy.h"
   24 #include "ggadget/dbus/dbus_utils.h"
   25 #include "ggadget/scriptable_array.h"
   26 #include "ggadget/logger.h"
   27 #include "unittest/gtest.h"
   28 
   29 using namespace ggadget;
   30 using namespace ggadget::dbus;
   31 
   32 namespace {
   33 
   34 DBusMessage* GetMarshalledMessage(const char *signature,
   35                                   const Variant &value) {
   36   DBusMessage *message = dbus_message_new_method_call("org.freedesktop.DBus",
   37                                                       "/org/freedesktop/DBus",
   38                                                       "org.freedesktop.DBus",
   39                                                       "Hello");
   40   if (!signature) return message;
   41 
   42   DBusMarshaller marshaller(message);
   43   Argument arg(signature, value);
   44   EXPECT_TRUE(marshaller.AppendArgument(arg));
   45   return message;
   46 }
   47 
   48 template <typename T>
   49 void TestBasicMarshal(const char *signature, int dbus_type,
   50                       const Variant &value, const T &check_value) {
   51   DLOG("Testing basic type: %s", signature);
   52   DBusMessage *message = GetMarshalledMessage(signature, value);
   53   DBusMessageIter iter;
   54   dbus_message_iter_init(message, &iter);
   55   int real_type = dbus_message_iter_get_arg_type(&iter);
   56   T v = 0;
   57   dbus_message_iter_get_basic(&iter, &v);
   58   EXPECT_EQ(check_value, v);
   59   EXPECT_EQ(dbus_type, real_type);
   60   EXPECT_FALSE(dbus_message_iter_has_next(&iter));
   61   dbus_message_unref(message);
   62 }
   63 
   64 template <>
   65 void TestBasicMarshal<std::string>(const char *signature, int dbus_type,
   66                                    const Variant &value,
   67                                    const std::string &check_value) {
   68   DBusMessage *message = GetMarshalledMessage(signature, value);
   69   DBusMessageIter iter;
   70   dbus_message_iter_init(message, &iter);
   71   int real_type = dbus_message_iter_get_arg_type(&iter);
   72   char *v = 0;
   73   dbus_message_iter_get_basic(&iter, &v);
   74   EXPECT_STREQ(check_value.c_str(), v);
   75   EXPECT_EQ(dbus_type, real_type);
   76   EXPECT_FALSE(dbus_message_iter_has_next(&iter));
   77   dbus_message_unref(message);
   78 }
   79 
   80 template <typename T>
   81 ResultVariant GenerateVariantArray(size_t size, T first, T diff) {
   82   ScriptableArray *array = new ScriptableArray();
   83   T value = first;
   84   for (size_t i = 0; i < size; ++i) {
   85     array->Append(Variant(value));
   86     value = value + diff;
   87   }
   88   return ResultVariant(Variant(array));
   89 }
   90 
   91 template <typename P1, typename P2>
   92 ResultVariant GenerateVariantDict(size_t size, P1 key, P1 key_diff,
   93                                   P2 value, P2 value_diff) {
   94   ScriptableDBusContainer *obj = new ScriptableDBusContainer;
   95   P1 k = key;
   96   P2 v = value;
   97   for (size_t i = 0; i < size; ++i) {
   98     Variant vk(k);
   99     Variant vv(v);
  100     std::string key;
  101     EXPECT_TRUE(vk.ConvertToString(&key));
  102     obj->AddProperty(key.c_str(), vv);
  103     k = k + key_diff;
  104     v = v + value_diff;
  105   }
  106   return ResultVariant(Variant(obj));
  107 }
  108 
  109 ResultVariant GenerateVariantStruct(size_t size, ...) {
  110   ScriptableArray *array = new ScriptableArray();
  111   va_list args;
  112   va_start(args, size);
  113   for (size_t i = 0; i < size; ++i) {
  114     Variant *v;
  115     v = va_arg(args, Variant*);
  116     array->Append(*v);
  117   }
  118   va_end(args);
  119   return ResultVariant(Variant(array));
  120 }
  121 
  122 void TestArrayMarshal() {
  123   DLOG("Testing Array Marshalling...");
  124   const size_t vector_size = 10;
  125   ResultVariant v = GenerateVariantArray<uint64_t>(vector_size, 12, 4);
  126   DBusMessage *message = GetMarshalledMessage("at", v.v());
  127   /* begin to demarshal the message. */
  128   DBusMessageIter iter, subiter;
  129   dbus_message_iter_init(message, &iter);
  130   char *sig = dbus_message_iter_get_signature(&iter);
  131   EXPECT_STREQ("at", sig);
  132   dbus_free(sig);
  133   EXPECT_FALSE(dbus_message_iter_has_next(&iter));
  134   EXPECT_EQ(DBUS_TYPE_ARRAY, dbus_message_iter_get_arg_type(&iter));
  135   dbus_message_iter_recurse(&iter, &subiter);
  136   for (size_t i = 0; i < vector_size; ++i) {
  137     uint64_t v;
  138     dbus_message_iter_get_basic(&subiter, &v);
  139     EXPECT_EQ(12 + i * 4, v);
  140     dbus_message_iter_next(&subiter);
  141   }
  142   EXPECT_FALSE(dbus_message_iter_has_next(&subiter));
  143   dbus_message_unref(message);
  144   /* testing marshal without explicit signature. */
  145   message = GetMarshalledMessage("", v.v());
  146   dbus_message_iter_init(message, &iter);
  147   sig = dbus_message_iter_get_signature(&iter);
  148   EXPECT_STREQ("ai", sig);
  149   dbus_free(sig);
  150   dbus_message_unref(message);
  151 }
  152 
  153 /* add a operator to Variant so that we can use the template function. */
  154 Variant operator+(const Variant &first, const Variant &second) {
  155   return first;
  156 }
  157 
  158 void TestStructMarshal() {
  159   DLOG("Testing Struct Marshalling...");
  160   Variant v1("Gadget"), v2(64), v3(true);
  161   ResultVariant vs = GenerateVariantStruct(3, &v1, &v2, &v3);
  162   DBusMessage *message = GetMarshalledMessage("(sub)", vs.v());
  163   DBusMessageIter iter, subiter;
  164   dbus_message_iter_init(message, &iter);
  165   EXPECT_EQ(DBUS_TYPE_STRUCT, dbus_message_iter_get_arg_type(&iter));
  166   EXPECT_FALSE(dbus_message_iter_has_next(&iter));
  167   char *sig = dbus_message_iter_get_signature(&iter);
  168   EXPECT_STREQ("(sub)", sig);
  169   dbus_free(sig);
  170   dbus_message_iter_recurse(&iter, &subiter);
  171   char *str;
  172   dbus_uint32_t num;
  173   dbus_bool_t yes;
  174   EXPECT_EQ(DBUS_TYPE_STRING, dbus_message_iter_get_arg_type(&subiter));
  175   dbus_message_iter_get_basic(&subiter, &str);
  176   EXPECT_STREQ("Gadget", str);
  177   EXPECT_TRUE(dbus_message_iter_next(&subiter));
  178   EXPECT_EQ(DBUS_TYPE_UINT32, dbus_message_iter_get_arg_type(&subiter));
  179   dbus_message_iter_get_basic(&subiter, &num);
  180   EXPECT_EQ(64u, num);
  181   EXPECT_TRUE(dbus_message_iter_next(&subiter));
  182   EXPECT_EQ(DBUS_TYPE_BOOLEAN, dbus_message_iter_get_arg_type(&subiter));
  183   dbus_message_iter_get_basic(&subiter, &yes);
  184   EXPECT_TRUE(yes);
  185   EXPECT_FALSE(dbus_message_iter_has_next(&subiter));
  186   dbus_message_unref(message);
  187   /* testing marshal without explicit signature. */
  188   message = GetMarshalledMessage("", vs.v());
  189   dbus_message_iter_init(message, &iter);
  190   sig = dbus_message_iter_get_signature(&iter);
  191   EXPECT_STREQ("(sib)", sig);
  192   dbus_free(sig);
  193   dbus_message_unref(message);
  194 }
  195 
  196 void TestDictMarshal() {
  197   DLOG("Testing Dict Marshalling...");
  198   const size_t dict_size = 10;
  199   ResultVariant v = GenerateVariantDict(dict_size, 123, 3, 256, 9);
  200   DBusMessage *message = GetMarshalledMessage("a{it}", v.v());
  201   DBusMessageIter iter, item_iter, dict_iter;
  202   dbus_message_iter_init(message, &iter);
  203   char *sig = dbus_message_iter_get_signature(&iter);
  204   EXPECT_STREQ("a{it}", sig);
  205   dbus_free(sig);
  206   EXPECT_EQ(DBUS_TYPE_ARRAY, dbus_message_iter_get_arg_type(&iter));
  207   EXPECT_FALSE(dbus_message_iter_has_next(&iter));
  208   dbus_message_iter_recurse(&iter, &item_iter);
  209   for (size_t i = 0; i < dict_size; ++i) {
  210     EXPECT_EQ(DBUS_TYPE_DICT_ENTRY, dbus_message_iter_get_arg_type(&item_iter));
  211     dbus_message_iter_recurse(&item_iter, &dict_iter);
  212     int key;
  213     uint64_t value;
  214     dbus_message_iter_get_basic(&dict_iter, &key);
  215     EXPECT_EQ(static_cast<int>(123 + 3 * i), key);
  216     EXPECT_TRUE(dbus_message_iter_next(&dict_iter));
  217     dbus_message_iter_get_basic(&dict_iter, &value);
  218     EXPECT_EQ(256 + i * 9, value);
  219     EXPECT_FALSE(dbus_message_iter_has_next(&dict_iter));
  220     dbus_message_iter_next(&item_iter);
  221   }
  222   EXPECT_FALSE(dbus_message_iter_has_next(&item_iter));
  223   dbus_message_unref(message);
  224   /* testing marshal without explicit signature. */
  225   message = GetMarshalledMessage("", v.v());
  226   dbus_message_iter_init(message, &iter);
  227   sig = dbus_message_iter_get_signature(&iter);
  228   EXPECT_STREQ("a{si}", sig);
  229   dbus_free(sig);
  230   dbus_message_unref(message);
  231 }
  232 
  233 void TestVariantMarshal() {
  234   DLOG("Testing Variant Marshalling...");
  235   DBusMessageIter iter, itemiter, arrayiter, subiter;
  236   /* testing basic types */
  237   DBusMessage *message = GetMarshalledMessage("v", Variant(false));
  238   dbus_message_iter_init(message, &iter);
  239   EXPECT_EQ(DBUS_TYPE_VARIANT, dbus_message_iter_get_arg_type(&iter));
  240   char *sig = dbus_message_iter_get_signature(&iter);
  241   EXPECT_STREQ("v", sig);
  242   dbus_free(sig);
  243   dbus_message_iter_recurse(&iter, &itemiter);
  244   sig = dbus_message_iter_get_signature(&itemiter);
  245   EXPECT_STREQ("b", sig);
  246   dbus_free(sig);
  247   bool yes = true;
  248   dbus_message_iter_get_basic(&itemiter, &yes);
  249   EXPECT_FALSE(yes);
  250   dbus_message_unref(message);
  251   message = GetMarshalledMessage("v", Variant(3.141592653589793));
  252   dbus_message_iter_init(message, &iter);
  253   EXPECT_EQ(DBUS_TYPE_VARIANT, dbus_message_iter_get_arg_type(&iter));
  254   sig = dbus_message_iter_get_signature(&iter);
  255   EXPECT_STREQ("v", sig);
  256   dbus_free(sig);
  257   dbus_message_iter_recurse(&iter, &itemiter);
  258   sig = dbus_message_iter_get_signature(&itemiter);
  259   EXPECT_STREQ("d", sig);
  260   dbus_free(sig);
  261   dbus_message_unref(message);
  262   message = GetMarshalledMessage("v", Variant("variant"));
  263   dbus_message_iter_init(message, &iter);
  264   EXPECT_EQ(DBUS_TYPE_VARIANT, dbus_message_iter_get_arg_type(&iter));
  265   sig = dbus_message_iter_get_signature(&iter);
  266   EXPECT_STREQ("v", sig);
  267   dbus_free(sig);
  268   dbus_message_iter_recurse(&iter, &itemiter);
  269   sig = dbus_message_iter_get_signature(&itemiter);
  270   EXPECT_STREQ("s", sig);
  271   dbus_free(sig);
  272   char *str;
  273   dbus_message_iter_get_basic(&itemiter, &str);
  274   EXPECT_STREQ("variant", str);
  275   dbus_message_unref(message);
  276 
  277   /* testing variant as an array container. */
  278   ResultVariant array = GenerateVariantArray<uint64_t>(4, 5, 39);
  279   message = GetMarshalledMessage("v", array.v());
  280   dbus_message_iter_init(message, &iter);
  281   EXPECT_EQ(DBUS_TYPE_VARIANT, dbus_message_iter_get_arg_type(&iter));
  282   sig = dbus_message_iter_get_signature(&iter);
  283   EXPECT_STREQ("v", sig);
  284   dbus_free(sig);
  285   EXPECT_FALSE(dbus_message_iter_has_next(&iter));
  286   dbus_message_iter_recurse(&iter, &itemiter);
  287   sig = dbus_message_iter_get_signature(&itemiter);
  288   EXPECT_STREQ("ai", sig);
  289   dbus_free(sig);
  290   EXPECT_FALSE(dbus_message_iter_has_next(&itemiter));
  291   dbus_message_iter_recurse(&itemiter, &subiter);
  292   for (int i = 0; i < 4; ++i) {
  293     int v;
  294     dbus_message_iter_get_basic(&subiter, &v);
  295     EXPECT_EQ(5 + 39 * i, v);
  296     dbus_message_iter_next(&subiter);
  297   }
  298   EXPECT_FALSE(dbus_message_iter_has_next(&subiter));
  299   dbus_message_unref(message);
  300   Variant v1("Gadget"), v2(64), v3(true);
  301   ResultVariant structure = GenerateVariantStruct(3, &v1, &v2, &v3);
  302 
  303   /* testing variant as a structure container. */
  304   message = GetMarshalledMessage("v", structure.v());
  305   dbus_message_iter_init(message, &iter);
  306   EXPECT_EQ(DBUS_TYPE_VARIANT, dbus_message_iter_get_arg_type(&iter));
  307   sig = dbus_message_iter_get_signature(&iter);
  308   EXPECT_STREQ("v", sig);
  309   dbus_free(sig);
  310   EXPECT_FALSE(dbus_message_iter_has_next(&iter));
  311   dbus_message_iter_recurse(&iter, &itemiter);
  312   sig = dbus_message_iter_get_signature(&itemiter);
  313   EXPECT_STREQ("(sib)", sig);
  314   dbus_free(sig);
  315   EXPECT_FALSE(dbus_message_iter_has_next(&itemiter));
  316   dbus_message_iter_recurse(&itemiter, &subiter);
  317   dbus_message_iter_get_basic(&subiter, &str);
  318   EXPECT_STREQ("Gadget", str);
  319   EXPECT_TRUE(dbus_message_iter_next(&subiter));
  320   int32_t v;
  321   dbus_message_iter_get_basic(&subiter, &v);
  322   EXPECT_EQ(64, v);
  323   EXPECT_TRUE(dbus_message_iter_next(&subiter));
  324   dbus_message_iter_get_basic(&subiter, &yes);
  325   EXPECT_TRUE(yes);
  326   EXPECT_FALSE(dbus_message_iter_has_next(&subiter));
  327   dbus_message_unref(message);
  328 
  329   /* testing variant as a dict container. */
  330   ResultVariant dict = GenerateVariantDict(10, 123, 3, 256, 9);
  331   message = GetMarshalledMessage("v", dict.v());
  332   dbus_message_iter_init(message, &iter);
  333   EXPECT_EQ(DBUS_TYPE_VARIANT, dbus_message_iter_get_arg_type(&iter));
  334   sig = dbus_message_iter_get_signature(&iter);
  335   EXPECT_STREQ("v", sig);
  336   dbus_free(sig);
  337   EXPECT_FALSE(dbus_message_iter_has_next(&iter));
  338   dbus_message_iter_recurse(&iter, &arrayiter);
  339   sig = dbus_message_iter_get_signature(&arrayiter);
  340   EXPECT_STREQ("a{si}", sig);
  341   dbus_free(sig);
  342   EXPECT_FALSE(dbus_message_iter_has_next(&arrayiter));
  343   dbus_message_iter_recurse(&arrayiter, &itemiter);
  344   for (int i = 0; i < 10; ++i) {
  345     dbus_message_iter_recurse(&itemiter, &subiter);
  346     char *key;
  347     int v;
  348     dbus_message_iter_get_basic(&subiter, &key);
  349     EXPECT_EQ(123 + 3 * i, atoi(key));
  350     EXPECT_TRUE(dbus_message_iter_next(&subiter));
  351     dbus_message_iter_get_basic(&subiter, &v);
  352     EXPECT_EQ(256 + 9 * i, v);
  353     EXPECT_FALSE(dbus_message_iter_next(&subiter));
  354     dbus_message_iter_next(&itemiter);
  355   }
  356   EXPECT_FALSE(dbus_message_iter_has_next(&itemiter));
  357   dbus_message_unref(message);
  358 }
  359 
  360 bool IsEqual(const Variant &v1, const Variant &v2);
  361 class ScriptableIterator {
  362  public:
  363   bool operator==(const ScriptableIterator &another) const {
  364     if (array_.size() != another.array_.size() ||
  365         properties_.size() != another.properties_.size()) {
  366       DLOG("size mismatch, array: %zu:%zu; property: %zu:%zu.",
  367            array_.size(), another.array_.size(),
  368            properties_.size(), another.properties_.size());
  369       return false;
  370     }
  371     for (size_t i = 0; i < array_.size(); ++i)
  372       if (!IsEqual(array_[i], another.array_[i])) {
  373         DLOG("index %zu mismatch: %s, %s", i, array_[i].Print().c_str(),
  374              another.array_[i].Print().c_str());
  375         return false;
  376       }
  377     for (PropertyMap::const_iterator it = properties_.begin();
  378          it != properties_.end(); ++it) {
  379       PropertyMap::const_iterator second = another.properties_.find(it->first);
  380       if (second == another.properties_.end()) {
  381         DLOG("property %s does not exist in another", it->first.c_str());
  382         return false;
  383       }
  384       if (!IsEqual(it->second, second->second)) {
  385         DLOG("property %s mismatch: %s, %s", it->first.c_str(),
  386              it->second.Print().c_str(), second->second.Print().c_str());
  387         return false;
  388       }
  389     }
  390     return true;
  391   }
  392   bool EnumerateArray(int id, const Variant &value) {
  393     array_.push_back(value);
  394     return true;
  395   }
  396   bool EnumerateProperties(const char *name,
  397                            ScriptableInterface::PropertyType type,
  398                            const Variant &value) {
  399     if (type != ScriptableInterface::PROPERTY_METHOD)
  400       properties_[name] = value;
  401     return true;
  402   }
  403  private:
  404   std::vector<Variant> array_;
  405   typedef std::map<std::string, Variant> PropertyMap;
  406   PropertyMap properties_;
  407 };
  408 
  409 bool IsEqual(ScriptableInterface *s1, ScriptableInterface *s2) {
  410   ScriptableIterator it1, it2;
  411   s1->EnumerateElements(NewSlot(&it1, &ScriptableIterator::EnumerateArray));
  412   s1->EnumerateProperties(NewSlot(&it1,
  413                                   &ScriptableIterator::EnumerateProperties));
  414   s2->EnumerateElements(NewSlot(&it2, &ScriptableIterator::EnumerateArray));
  415   s2->EnumerateProperties(NewSlot(&it2,
  416                                   &ScriptableIterator::EnumerateProperties));
  417   return it1 == it2;
  418 }
  419 
  420 bool IsEqual(const Variant &v1, const Variant &v2) {
  421   if (v1.type() != Variant::TYPE_SCRIPTABLE) {
  422     bool ret = (v1 == v2);
  423     if (!ret) DLOG("simple type mismatch: %s, %s",
  424                    v1.Print().c_str(), v2.Print().c_str());
  425     return ret;
  426   }
  427   if (v2.type() != Variant::TYPE_SCRIPTABLE) {
  428     DLOG("type mismatch. one is not scriptable but the other is.");
  429     return false;
  430   }
  431   return IsEqual(VariantValue<ScriptableInterface*>()(v1),
  432                 VariantValue<ScriptableInterface*>()(v2));
  433 }
  434 
  435 void TestBasicDemarshal(const char *signature,
  436                         const char *expect_signature, const Variant &value) {
  437   DLOG("Test Demarshal for signature: %s", expect_signature);
  438   DBusMessage *message = GetMarshalledMessage(signature, value);
  439   Argument arg(expect_signature);
  440   DBusDemarshaller demarshaller(message);
  441   EXPECT_TRUE(demarshaller.GetArgument(&arg));
  442   EXPECT_TRUE(IsEqual(value, arg.value.v()));
  443   dbus_message_unref(message);
  444 }
  445 
  446 void TestContainerDemarshal() {
  447   ResultVariant array = GenerateVariantArray<uint64_t>(4, 5, 39);
  448   TestBasicDemarshal("at", "at", array.v());
  449   TestBasicDemarshal("v", "v", array.v());
  450   Variant v1("Gadget"), v2(64), v3(true);
  451   ResultVariant structure = GenerateVariantStruct(3, &v1, &v2, &v3);
  452   TestBasicDemarshal("", "(sib)", structure.v());
  453   TestBasicDemarshal("v", "v", structure.v());
  454   ResultVariant dict = GenerateVariantDict(10, 123, 3, 256, 9);
  455   TestBasicDemarshal("a{yu}", "a{yu}", dict.v());
  456   TestBasicDemarshal("v", "v", dict.v());
  457   ResultVariant empty_dict = GenerateVariantDict(0, 0, 0, 0, 0);
  458   TestBasicDemarshal("a{sv}", "a{sv}", empty_dict.v());
  459 }
  460 
  461 template <typename T>
  462 void TestBasicValistMarshal(const char *signature, const T &value,
  463                             MessageType first_arg_type, ...) {
  464   Arguments args;
  465   va_list va_args;
  466   va_start(va_args, first_arg_type);
  467   EXPECT_TRUE(DBusMarshaller::ValistAdaptor(&args, first_arg_type, &va_args));
  468   DBusMessage *message = dbus_message_new_method_call("org.freedesktop.DBus",
  469                                                       "/org/freedesktop/DBus",
  470                                                       "org.freedesktop.DBus",
  471                                                       "Hello");
  472   DBusMarshaller marshaller(message);
  473   EXPECT_TRUE(marshaller.AppendArguments(args));
  474   DBusMessageIter iter;
  475   dbus_message_iter_init(message, &iter);
  476   char *sig = dbus_message_iter_get_signature(&iter);
  477   EXPECT_STREQ(signature, sig);
  478   dbus_free(sig);
  479   T v;
  480   dbus_message_iter_get_basic(&iter, &v);
  481   EXPECT_EQ(value, v);
  482   dbus_message_unref(message);
  483 }
  484 
  485 template <>
  486 void TestBasicValistMarshal<std::string>(const char *signature,
  487                                          const std::string &value,
  488                                          MessageType first_arg_type, ...) {
  489   Arguments args;
  490   va_list va_args;
  491   va_start(va_args, first_arg_type);
  492   EXPECT_TRUE(DBusMarshaller::ValistAdaptor(&args, first_arg_type, &va_args));
  493   DBusMessage *message = dbus_message_new_method_call("org.freedesktop.DBus",
  494                                                       "/org/freedesktop/DBus",
  495                                                       "org.freedesktop.DBus",
  496                                                       "Hello");
  497   DBusMarshaller marshaller(message);
  498   EXPECT_TRUE(marshaller.AppendArguments(args));
  499   DBusMessageIter iter;
  500   dbus_message_iter_init(message, &iter);
  501   char *sig = dbus_message_iter_get_signature(&iter);
  502   EXPECT_STREQ(signature, sig);
  503   dbus_free(sig);
  504   char *v;
  505   dbus_message_iter_get_basic(&iter, &v);
  506   EXPECT_STREQ(value.c_str(), v);
  507   dbus_message_unref(message);
  508 }
  509 
  510 void TestConvertedVariant(const Variant &value, const char *signature,
  511                           MessageType first_arg_type, ...) {
  512   DLOG("Test for valist signature: %s", signature);
  513   va_list va_args;
  514   va_start(va_args, first_arg_type);
  515   Arguments args;
  516   EXPECT_TRUE(DBusMarshaller::ValistAdaptor(&args, first_arg_type, &va_args));
  517   EXPECT_EQ(1u, args.size());
  518   EXPECT_TRUE(IsEqual(value, args[0].value.v()));
  519   EXPECT_STREQ(signature, args[0].signature.c_str());
  520 }
  521 
  522 void TestContainerValistMarshal() {
  523   ResultVariant array = GenerateVariantArray<std::string>(2, "AA", "a");
  524   TestConvertedVariant(array.v(), "as",
  525                        MESSAGE_TYPE_ARRAY, 2,
  526                        MESSAGE_TYPE_STRING, "AA",
  527                        MESSAGE_TYPE_STRING, "AAa",
  528                        MESSAGE_TYPE_INVALID);
  529   TestConvertedVariant(array.v(), "v", MESSAGE_TYPE_VARIANT,
  530                        MESSAGE_TYPE_ARRAY, 2,
  531                        MESSAGE_TYPE_STRING, "AA",
  532                        MESSAGE_TYPE_STRING, "AAa",
  533                        MESSAGE_TYPE_INVALID);
  534   Variant v1("Gadget"), v2(64), v3(true);
  535   ResultVariant structure = GenerateVariantStruct(3, &v1, &v2, &v3);
  536   TestConvertedVariant(structure.v(), "(syb)",
  537                        MESSAGE_TYPE_STRUCT, 3,
  538                        MESSAGE_TYPE_STRING, "Gadget",
  539                        MESSAGE_TYPE_BYTE, 64,
  540                        MESSAGE_TYPE_BOOLEAN, true,
  541                        MESSAGE_TYPE_INVALID);
  542   TestConvertedVariant(structure.v(), "v", MESSAGE_TYPE_VARIANT,
  543                        MESSAGE_TYPE_STRUCT, 3,
  544                        MESSAGE_TYPE_STRING, "Gadget",
  545                        MESSAGE_TYPE_BYTE, 64,
  546                        MESSAGE_TYPE_BOOLEAN, true,
  547                        MESSAGE_TYPE_INVALID);
  548   ResultVariant dict = GenerateVariantDict(2, 123, 3, 256, 9);
  549   TestConvertedVariant(dict.v(), "a{iu}",
  550                        MESSAGE_TYPE_DICT, 2,
  551                        MESSAGE_TYPE_INT32, 123,
  552                        MESSAGE_TYPE_UINT32, 256,
  553                        MESSAGE_TYPE_INT32, 126,
  554                        MESSAGE_TYPE_UINT32, 265,
  555                        MESSAGE_TYPE_INVALID);
  556   TestConvertedVariant(dict.v(), "v", MESSAGE_TYPE_VARIANT,
  557                        MESSAGE_TYPE_DICT, 2,
  558                        MESSAGE_TYPE_INT32, 123,
  559                        MESSAGE_TYPE_UINT32, 256,
  560                        MESSAGE_TYPE_INT32, 126,
  561                        MESSAGE_TYPE_UINT32, 265,
  562                        MESSAGE_TYPE_INVALID);
  563 }
  564 
  565 void TestValistDemarshal(MessageType first_arg_type, ...) {
  566   DLOG("Test Valist Demarshal. First arg: %d", first_arg_type);
  567   va_list va_args;
  568   Arguments in_args, out_args;
  569   va_start(va_args, first_arg_type);
  570   EXPECT_TRUE(DBusMarshaller::ValistAdaptor(&out_args, first_arg_type,
  571                                             &va_args));
  572   first_arg_type = static_cast<MessageType>(va_arg(va_args, int));
  573   EXPECT_TRUE(DBusDemarshaller::ValistAdaptor(out_args, first_arg_type,
  574                                               &va_args));
  575   va_end(va_args);
  576 }
  577 
  578 }  // anonymous namespace
  579 
  580 TEST(DBusMarshaller, AppendArgument) {
  581   TestBasicMarshal<unsigned char>("y", DBUS_TYPE_BYTE, Variant(true), 1);
  582   TestBasicMarshal<dbus_bool_t>("b", DBUS_TYPE_BOOLEAN, Variant(true), true);
  583   TestBasicMarshal<int16_t>("n", DBUS_TYPE_INT16, Variant("-1"), -1);
  584   TestBasicMarshal<uint16_t>("q", DBUS_TYPE_UINT16, Variant("1"), 1);
  585   TestBasicMarshal<int32_t>("i", DBUS_TYPE_INT32, Variant(true), 1);
  586   TestBasicMarshal<uint32_t>("u", DBUS_TYPE_UINT32, Variant(true), 1);
  587   TestBasicMarshal<int64_t>("x", DBUS_TYPE_INT64, Variant(true), 1);
  588   TestBasicMarshal<uint64_t>("t", DBUS_TYPE_UINT64, Variant(true), 1);
  589   TestBasicMarshal<double>("d", DBUS_TYPE_DOUBLE, Variant("0"), 0);
  590   TestBasicMarshal<std::string>("s", DBUS_TYPE_STRING, Variant(true), "true");
  591   TestArrayMarshal();
  592   TestStructMarshal();
  593   TestDictMarshal();
  594   TestVariantMarshal();
  595 }
  596 
  597 TEST(DBusMarshaller, ValistAdaptor) {
  598   TestBasicValistMarshal<unsigned char>("y", 142, MESSAGE_TYPE_BYTE, 142,
  599                                         MESSAGE_TYPE_INVALID);
  600   TestBasicValistMarshal<dbus_bool_t>("b", true, MESSAGE_TYPE_BOOLEAN, true,
  601                          MESSAGE_TYPE_INVALID);
  602   TestBasicValistMarshal("n", std::numeric_limits<int16_t>::min(),
  603                          MESSAGE_TYPE_INT16,
  604                          std::numeric_limits<int16_t>::min(),
  605                          MESSAGE_TYPE_INVALID);
  606   TestBasicValistMarshal("q", std::numeric_limits<uint16_t>::max(),
  607                          MESSAGE_TYPE_UINT16,
  608                          std::numeric_limits<uint16_t>::max(),
  609                          MESSAGE_TYPE_INVALID);
  610   TestBasicValistMarshal("i", std::numeric_limits<int32_t>::min(),
  611                          MESSAGE_TYPE_INT32,
  612                          std::numeric_limits<int32_t>::min(),
  613                          MESSAGE_TYPE_INVALID);
  614   TestBasicValistMarshal("u", std::numeric_limits<int32_t>::max(),
  615                          MESSAGE_TYPE_UINT32,
  616                          std::numeric_limits<int32_t>::max(),
  617                          MESSAGE_TYPE_INVALID);
  618   TestBasicValistMarshal("x", std::numeric_limits<int64_t>::min(),
  619                          MESSAGE_TYPE_INT64,
  620                          std::numeric_limits<int64_t>::min(),
  621                          MESSAGE_TYPE_INVALID);
  622   TestBasicValistMarshal("t", std::numeric_limits<uint64_t>::max(),
  623                          MESSAGE_TYPE_UINT64,
  624                          std::numeric_limits<uint64_t>::max(),
  625                          MESSAGE_TYPE_INVALID);
  626   TestBasicValistMarshal("d", 3.1415927, MESSAGE_TYPE_DOUBLE,
  627                          3.1415927, MESSAGE_TYPE_INVALID);
  628   TestBasicValistMarshal<std::string>("s", "3.1415927", MESSAGE_TYPE_STRING,
  629                                       "3.1415927", MESSAGE_TYPE_INVALID);
  630   TestContainerValistMarshal();
  631 }
  632 
  633 TEST(DBusDemarshaller, GetArgument) {
  634   TestBasicDemarshal("y", "y",
  635                      Variant(std::numeric_limits<unsigned char>::max()));
  636   TestBasicDemarshal("", "i",
  637                      Variant(std::numeric_limits<unsigned char>::max()));
  638   TestBasicDemarshal("v", "v",
  639                      Variant(std::numeric_limits<unsigned char>::max()));
  640 
  641   TestBasicDemarshal("b", "b", Variant(false));
  642   TestBasicDemarshal("v", "v", Variant(false));
  643   TestBasicDemarshal("", "b", Variant(false));
  644 
  645   TestBasicDemarshal("n", "n", Variant(std::numeric_limits<int16_t>::min()));
  646   TestBasicDemarshal("", "i", Variant(std::numeric_limits<int16_t>::min()));
  647   TestBasicDemarshal("q", "q", Variant(std::numeric_limits<uint16_t>::max()));
  648   TestBasicDemarshal("", "i", Variant(std::numeric_limits<uint16_t>::max()));
  649   TestBasicDemarshal("i", "i", Variant(std::numeric_limits<int32_t>::min()));
  650   TestBasicDemarshal("", "i", Variant(std::numeric_limits<int32_t>::min()));
  651   TestBasicDemarshal("u", "u", Variant(std::numeric_limits<uint32_t>::max()));
  652   TestBasicDemarshal("", "i", Variant(25));
  653   TestBasicDemarshal("x", "x", Variant(std::numeric_limits<int64_t>::min()));
  654   TestBasicDemarshal("", "i", Variant(-123));
  655   TestBasicDemarshal("t", "t", Variant(std::numeric_limits<uint64_t>::max()));
  656   TestBasicDemarshal("", "i", Variant(321));
  657 
  658   TestBasicDemarshal("d", "d", Variant(3.1415926));
  659   TestBasicDemarshal("", "d", Variant(3.1415926));
  660   TestBasicDemarshal("v", "v", Variant(3.1415926));
  661 
  662   TestBasicDemarshal("s", "s", Variant("Google Gadget for Linux"));
  663   TestBasicDemarshal("", "s", Variant("Google Gadget for Linux"));
  664   TestBasicDemarshal("v", "v", Variant("Google Gadget for Linux"));
  665   TestContainerDemarshal();
  666 }
  667 
  668 TEST(DBusDemarshaller, ValistAdaptor) {
  669   unsigned char uc;
  670   TestValistDemarshal(MESSAGE_TYPE_BYTE, 21, MESSAGE_TYPE_INVALID,
  671                       MESSAGE_TYPE_BYTE, &uc, MESSAGE_TYPE_INVALID);
  672   EXPECT_EQ(21u, uc);
  673   bool yes = false;
  674   TestValistDemarshal(MESSAGE_TYPE_BOOLEAN, true, MESSAGE_TYPE_INVALID,
  675                       MESSAGE_TYPE_BOOLEAN, &yes, MESSAGE_TYPE_INVALID);
  676   EXPECT_TRUE(yes);
  677   int16_t int16 = 0;
  678   TestValistDemarshal(MESSAGE_TYPE_INT16, -423, MESSAGE_TYPE_INVALID,
  679                       MESSAGE_TYPE_INT16, &int16, MESSAGE_TYPE_INVALID);
  680   EXPECT_EQ(-423, int16);
  681   uint16_t uint16 = 0;
  682   TestValistDemarshal(MESSAGE_TYPE_UINT16, 987, MESSAGE_TYPE_INVALID,
  683                       MESSAGE_TYPE_UINT16, &uint16, MESSAGE_TYPE_INVALID);
  684   EXPECT_EQ(987u, uint16);
  685   int32_t int32 = 0;
  686   TestValistDemarshal(MESSAGE_TYPE_INT32, -42332, MESSAGE_TYPE_INVALID,
  687                       MESSAGE_TYPE_INT32, &int32, MESSAGE_TYPE_INVALID);
  688   EXPECT_EQ(-42332, int32);
  689   uint32_t uint32 = 0;
  690   TestValistDemarshal(MESSAGE_TYPE_UINT32, 4256, MESSAGE_TYPE_INVALID,
  691                       MESSAGE_TYPE_UINT32, &uint32, MESSAGE_TYPE_INVALID);
  692   EXPECT_EQ(4256u, uint32);
  693   int64_t int64 = 0;
  694   TestValistDemarshal(MESSAGE_TYPE_INT64, 98787866LL, MESSAGE_TYPE_INVALID,
  695                       MESSAGE_TYPE_INT64, &int64, MESSAGE_TYPE_INVALID);
  696   EXPECT_EQ(98787866LL, int64);
  697   uint64_t uint64 = 0;
  698   TestValistDemarshal(MESSAGE_TYPE_UINT64, 1234567890ULL, MESSAGE_TYPE_INVALID,
  699                       MESSAGE_TYPE_UINT64, &uint64, MESSAGE_TYPE_INVALID);
  700   EXPECT_EQ(1234567890u, uint64);
  701   double d = 0.0;
  702   TestValistDemarshal(MESSAGE_TYPE_DOUBLE, 1.41421, MESSAGE_TYPE_INVALID,
  703                       MESSAGE_TYPE_DOUBLE, &d, MESSAGE_TYPE_INVALID);
  704   EXPECT_EQ(1.41421, d);
  705   char *str = NULL;
  706   TestValistDemarshal(MESSAGE_TYPE_STRING, "e", MESSAGE_TYPE_INVALID,
  707                       MESSAGE_TYPE_STRING, &str, MESSAGE_TYPE_INVALID);
  708   EXPECT_STREQ("e", str);
  709   delete str;
  710   TestValistDemarshal(MESSAGE_TYPE_STRING, "pi ~= ",
  711                       MESSAGE_TYPE_DOUBLE, 3.1415926, MESSAGE_TYPE_INVALID,
  712                       MESSAGE_TYPE_STRING, &str,
  713                       MESSAGE_TYPE_DOUBLE, &d, MESSAGE_TYPE_INVALID);
  714   EXPECT_EQ(3.1415926, d);
  715   EXPECT_STREQ("pi ~= ", str);
  716   delete str;
  717 }
  718 
  719 int main(int argc, char **argv) {
  720   testing::ParseGTestFlags(&argc, argv);
  721   int result = RUN_ALL_TESTS();
  722   return result;
  723 }