// 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