// Copyright 2014 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <brillo/dbus/dbus_param_reader.h> #include <string> #include <brillo/variant_dictionary.h> #include <gtest/gtest.h> using dbus::MessageReader; using dbus::MessageWriter; using dbus::Response; namespace brillo { namespace dbus_utils { TEST(DBusParamReader, NoArgs) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageReader reader(message.get()); bool called = false; auto callback = [&called]() { called = true; }; EXPECT_TRUE(DBusParamReader<false>::Invoke(callback, &reader, nullptr)); EXPECT_TRUE(called); } TEST(DBusParamReader, OneArg) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, 123); MessageReader reader(message.get()); bool called = false; auto callback = [&called](int param1) { EXPECT_EQ(123, param1); called = true; }; EXPECT_TRUE( (DBusParamReader<false, int>::Invoke(callback, &reader, nullptr))); EXPECT_TRUE(called); } TEST(DBusParamReader, ManyArgs) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, true); AppendValueToWriter(&writer, 1972); AppendValueToWriter(&writer, VariantDictionary{{"key", std::string{"value"}}}); MessageReader reader(message.get()); bool called = false; auto callback = [&called](bool p1, int p2, const VariantDictionary& p3) { EXPECT_TRUE(p1); EXPECT_EQ(1972, p2); EXPECT_EQ(1, p3.size()); EXPECT_EQ("value", p3.find("key")->second.Get<std::string>()); called = true; }; EXPECT_TRUE((DBusParamReader<false, bool, int, VariantDictionary>::Invoke( callback, &reader, nullptr))); EXPECT_TRUE(called); } TEST(DBusParamReader, TooManyArgs) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, true); AppendValueToWriter(&writer, 1972); AppendValueToWriter(&writer, VariantDictionary{{"key", std::string{"value"}}}); MessageReader reader(message.get()); bool called = false; auto callback = [&called](bool param1, int param2) { EXPECT_TRUE(param1); EXPECT_EQ(1972, param2); called = true; }; ErrorPtr error; EXPECT_FALSE( (DBusParamReader<false, bool, int>::Invoke(callback, &reader, &error))); EXPECT_FALSE(called); EXPECT_EQ(errors::dbus::kDomain, error->GetDomain()); EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode()); EXPECT_EQ("Too many parameters in a method call", error->GetMessage()); } TEST(DBusParamReader, TooFewArgs) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, true); MessageReader reader(message.get()); bool called = false; auto callback = [&called](bool param1, int param2) { EXPECT_TRUE(param1); EXPECT_EQ(1972, param2); called = true; }; ErrorPtr error; EXPECT_FALSE( (DBusParamReader<false, bool, int>::Invoke(callback, &reader, &error))); EXPECT_FALSE(called); EXPECT_EQ(errors::dbus::kDomain, error->GetDomain()); EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode()); EXPECT_EQ("Too few parameters in a method call", error->GetMessage()); } TEST(DBusParamReader, TypeMismatch) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, true); AppendValueToWriter(&writer, 1972); MessageReader reader(message.get()); bool called = false; auto callback = [&called](bool param1, double param2) { EXPECT_TRUE(param1); EXPECT_DOUBLE_EQ(1972.0, param2); called = true; }; ErrorPtr error; EXPECT_FALSE(( DBusParamReader<false, bool, double>::Invoke(callback, &reader, &error))); EXPECT_FALSE(called); EXPECT_EQ(errors::dbus::kDomain, error->GetDomain()); EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode()); EXPECT_EQ("Method parameter type mismatch", error->GetMessage()); } TEST(DBusParamReader, NoArgs_With_OUT) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageReader reader(message.get()); bool called = false; auto callback = [&called](int* param1) { EXPECT_EQ(0, *param1); called = true; }; EXPECT_TRUE( (DBusParamReader<true, int*>::Invoke(callback, &reader, nullptr))); EXPECT_TRUE(called); } TEST(DBusParamReader, OneArg_Before_OUT) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, 123); MessageReader reader(message.get()); bool called = false; auto callback = [&called](int param1, double* param2) { EXPECT_EQ(123, param1); EXPECT_DOUBLE_EQ(0.0, *param2); called = true; }; EXPECT_TRUE(( DBusParamReader<true, int, double*>::Invoke(callback, &reader, nullptr))); EXPECT_TRUE(called); } TEST(DBusParamReader, OneArg_After_OUT) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, 123); MessageReader reader(message.get()); bool called = false; auto callback = [&called](double* param1, int param2) { EXPECT_DOUBLE_EQ(0.0, *param1); EXPECT_EQ(123, param2); called = true; }; EXPECT_TRUE(( DBusParamReader<true, double*, int>::Invoke(callback, &reader, nullptr))); EXPECT_TRUE(called); } TEST(DBusParamReader, ManyArgs_With_OUT) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, true); AppendValueToWriter(&writer, 1972); AppendValueToWriter(&writer, VariantDictionary{{"key", std::string{"value"}}}); MessageReader reader(message.get()); bool called = false; auto callback = [&called](bool p1, std::string* p2, int p3, int* p4, const VariantDictionary& p5, bool* p6) { EXPECT_TRUE(p1); EXPECT_EQ("", *p2); EXPECT_EQ(1972, p3); EXPECT_EQ(0, *p4); EXPECT_EQ(1, p5.size()); EXPECT_EQ("value", p5.find("key")->second.Get<std::string>()); EXPECT_FALSE(*p6); called = true; }; EXPECT_TRUE((DBusParamReader<true, bool, std::string*, int, int*, VariantDictionary, bool*>::Invoke(callback, &reader, nullptr))); EXPECT_TRUE(called); } TEST(DBusParamReader, TooManyArgs_With_OUT) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, true); AppendValueToWriter(&writer, 1972); AppendValueToWriter(&writer, VariantDictionary{{"key", std::string{"value"}}}); MessageReader reader(message.get()); bool called = false; auto callback = [&called](bool param1, int param2, int* param3) { EXPECT_TRUE(param1); EXPECT_EQ(1972, param2); EXPECT_EQ(0, *param3); called = true; }; ErrorPtr error; EXPECT_FALSE((DBusParamReader<true, bool, int, int*>::Invoke( callback, &reader, &error))); EXPECT_FALSE(called); EXPECT_EQ(errors::dbus::kDomain, error->GetDomain()); EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode()); EXPECT_EQ("Too many parameters in a method call", error->GetMessage()); } TEST(DBusParamReader, TooFewArgs_With_OUT) { std::unique_ptr<Response> message = Response::CreateEmpty(); MessageWriter writer(message.get()); AppendValueToWriter(&writer, true); MessageReader reader(message.get()); bool called = false; auto callback = [&called](bool param1, int param2, int* param3) { EXPECT_TRUE(param1); EXPECT_EQ(1972, param2); EXPECT_EQ(0, *param3); called = true; }; ErrorPtr error; EXPECT_FALSE((DBusParamReader<true, bool, int, int*>::Invoke( callback, &reader, &error))); EXPECT_FALSE(called); EXPECT_EQ(errors::dbus::kDomain, error->GetDomain()); EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, error->GetCode()); EXPECT_EQ("Too few parameters in a method call", error->GetMessage()); } } // namespace dbus_utils } // namespace brillo