xref: /aosp_15_r20/external/libbrillo/brillo/dbus/dbus_object_test.cc (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright 2014 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li 
5*1a96fba6SXin Li #include <brillo/dbus/dbus_object.h>
6*1a96fba6SXin Li 
7*1a96fba6SXin Li #include <memory>
8*1a96fba6SXin Li 
9*1a96fba6SXin Li #include <base/bind.h>
10*1a96fba6SXin Li #include <brillo/dbus/dbus_object_test_helpers.h>
11*1a96fba6SXin Li #include <brillo/dbus/mock_exported_object_manager.h>
12*1a96fba6SXin Li #include <dbus/message.h>
13*1a96fba6SXin Li #include <dbus/property.h>
14*1a96fba6SXin Li #include <dbus/object_path.h>
15*1a96fba6SXin Li #include <dbus/mock_bus.h>
16*1a96fba6SXin Li #include <dbus/mock_exported_object.h>
17*1a96fba6SXin Li 
18*1a96fba6SXin Li using ::testing::AnyNumber;
19*1a96fba6SXin Li using ::testing::Return;
20*1a96fba6SXin Li using ::testing::_;
21*1a96fba6SXin Li 
22*1a96fba6SXin Li namespace brillo {
23*1a96fba6SXin Li namespace dbus_utils {
24*1a96fba6SXin Li 
25*1a96fba6SXin Li namespace {
26*1a96fba6SXin Li 
27*1a96fba6SXin Li const char kMethodsExportedOn[] = "/export";
28*1a96fba6SXin Li 
29*1a96fba6SXin Li const char kTestInterface1[] = "org.chromium.Test.MathInterface";
30*1a96fba6SXin Li const char kTestMethod_Add[] = "Add";
31*1a96fba6SXin Li const char kTestMethod_Negate[] = "Negate";
32*1a96fba6SXin Li const char kTestMethod_Positive[] = "Positive";
33*1a96fba6SXin Li const char kTestMethod_AddSubtract[] = "AddSubtract";
34*1a96fba6SXin Li 
35*1a96fba6SXin Li const char kTestInterface2[] = "org.chromium.Test.StringInterface";
36*1a96fba6SXin Li const char kTestMethod_StrLen[] = "StrLen";
37*1a96fba6SXin Li const char kTestMethod_CheckNonEmpty[] = "CheckNonEmpty";
38*1a96fba6SXin Li 
39*1a96fba6SXin Li const char kTestInterface3[] = "org.chromium.Test.NoOpInterface";
40*1a96fba6SXin Li const char kTestMethod_NoOp[] = "NoOp";
41*1a96fba6SXin Li const char kTestMethod_WithMessage[] = "TestWithMessage";
42*1a96fba6SXin Li const char kTestMethod_WithMessageAsync[] = "TestWithMessageAsync";
43*1a96fba6SXin Li 
44*1a96fba6SXin Li const char kTestInterface4[] = "org.chromium.Test.LateInterface";
45*1a96fba6SXin Li 
46*1a96fba6SXin Li struct Calc {
Addbrillo::dbus_utils::__anon860037380111::Calc47*1a96fba6SXin Li   int Add(int x, int y) { return x + y; }
Negatebrillo::dbus_utils::__anon860037380111::Calc48*1a96fba6SXin Li   int Negate(int x) { return -x; }
Positivebrillo::dbus_utils::__anon860037380111::Calc49*1a96fba6SXin Li   void Positive(std::unique_ptr<DBusMethodResponse<double>> response,
50*1a96fba6SXin Li                 double x) {
51*1a96fba6SXin Li     if (x >= 0.0) {
52*1a96fba6SXin Li       response->Return(x);
53*1a96fba6SXin Li       return;
54*1a96fba6SXin Li     }
55*1a96fba6SXin Li     ErrorPtr error;
56*1a96fba6SXin Li     Error::AddTo(&error, FROM_HERE, "test", "not_positive",
57*1a96fba6SXin Li                  "Negative value passed in");
58*1a96fba6SXin Li     response->ReplyWithError(error.get());
59*1a96fba6SXin Li   }
AddSubtractbrillo::dbus_utils::__anon860037380111::Calc60*1a96fba6SXin Li   void AddSubtract(int x, int y, int* sum, int* diff) {
61*1a96fba6SXin Li     *sum = x + y;
62*1a96fba6SXin Li     *diff = x - y;
63*1a96fba6SXin Li   }
64*1a96fba6SXin Li };
65*1a96fba6SXin Li 
StrLen(const std::string & str)66*1a96fba6SXin Li int StrLen(const std::string& str) {
67*1a96fba6SXin Li   return str.size();
68*1a96fba6SXin Li }
69*1a96fba6SXin Li 
CheckNonEmpty(ErrorPtr * error,const std::string & str)70*1a96fba6SXin Li bool CheckNonEmpty(ErrorPtr* error, const std::string& str) {
71*1a96fba6SXin Li   if (!str.empty())
72*1a96fba6SXin Li     return true;
73*1a96fba6SXin Li   Error::AddTo(error, FROM_HERE, "test", "string_empty", "String is empty");
74*1a96fba6SXin Li   return false;
75*1a96fba6SXin Li }
76*1a96fba6SXin Li 
NoOp()77*1a96fba6SXin Li void NoOp() {}
78*1a96fba6SXin Li 
TestWithMessage(ErrorPtr *,dbus::Message * message,std::string * str)79*1a96fba6SXin Li bool TestWithMessage(ErrorPtr* /* error */,
80*1a96fba6SXin Li                      dbus::Message* message,
81*1a96fba6SXin Li                      std::string* str) {
82*1a96fba6SXin Li   *str = message->GetSender();
83*1a96fba6SXin Li   return true;
84*1a96fba6SXin Li }
85*1a96fba6SXin Li 
TestWithMessageAsync(std::unique_ptr<DBusMethodResponse<std::string>> response,dbus::Message * message)86*1a96fba6SXin Li void TestWithMessageAsync(
87*1a96fba6SXin Li     std::unique_ptr<DBusMethodResponse<std::string>> response,
88*1a96fba6SXin Li     dbus::Message* message) {
89*1a96fba6SXin Li   response->Return(message->GetSender());
90*1a96fba6SXin Li }
91*1a96fba6SXin Li 
OnInterfaceExported(bool success)92*1a96fba6SXin Li void OnInterfaceExported(bool success) {
93*1a96fba6SXin Li   // Does nothing.
94*1a96fba6SXin Li }
95*1a96fba6SXin Li 
96*1a96fba6SXin Li }  // namespace
97*1a96fba6SXin Li 
98*1a96fba6SXin Li class DBusObjectTest : public ::testing::Test {
99*1a96fba6SXin Li  public:
SetUp()100*1a96fba6SXin Li   virtual void SetUp() {
101*1a96fba6SXin Li     dbus::Bus::Options options;
102*1a96fba6SXin Li     options.bus_type = dbus::Bus::SYSTEM;
103*1a96fba6SXin Li     bus_ = new dbus::MockBus(options);
104*1a96fba6SXin Li     // By default, don't worry about threading assertions.
105*1a96fba6SXin Li     EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
106*1a96fba6SXin Li     EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
107*1a96fba6SXin Li     // Use a mock exported object.
108*1a96fba6SXin Li     const dbus::ObjectPath kMethodsExportedOnPath{
109*1a96fba6SXin Li         std::string{kMethodsExportedOn}};
110*1a96fba6SXin Li     mock_exported_object_ =
111*1a96fba6SXin Li         new dbus::MockExportedObject(bus_.get(), kMethodsExportedOnPath);
112*1a96fba6SXin Li     EXPECT_CALL(*bus_, GetExportedObject(kMethodsExportedOnPath))
113*1a96fba6SXin Li         .Times(AnyNumber())
114*1a96fba6SXin Li         .WillRepeatedly(Return(mock_exported_object_.get()));
115*1a96fba6SXin Li     EXPECT_CALL(*mock_exported_object_, ExportMethod(_, _, _, _))
116*1a96fba6SXin Li         .Times(AnyNumber());
117*1a96fba6SXin Li     EXPECT_CALL(*mock_exported_object_, Unregister()).Times(1);
118*1a96fba6SXin Li 
119*1a96fba6SXin Li     dbus_object_ = std::unique_ptr<DBusObject>(
120*1a96fba6SXin Li         new DBusObject(nullptr, bus_, kMethodsExportedOnPath));
121*1a96fba6SXin Li 
122*1a96fba6SXin Li     DBusInterface* itf1 = dbus_object_->AddOrGetInterface(kTestInterface1);
123*1a96fba6SXin Li     itf1->AddSimpleMethodHandler(
124*1a96fba6SXin Li         kTestMethod_Add, base::Unretained(&calc_), &Calc::Add);
125*1a96fba6SXin Li     itf1->AddSimpleMethodHandler(
126*1a96fba6SXin Li         kTestMethod_Negate, base::Unretained(&calc_), &Calc::Negate);
127*1a96fba6SXin Li     itf1->AddMethodHandler(
128*1a96fba6SXin Li         kTestMethod_Positive, base::Unretained(&calc_), &Calc::Positive);
129*1a96fba6SXin Li     itf1->AddSimpleMethodHandler(
130*1a96fba6SXin Li         kTestMethod_AddSubtract, base::Unretained(&calc_), &Calc::AddSubtract);
131*1a96fba6SXin Li     DBusInterface* itf2 = dbus_object_->AddOrGetInterface(kTestInterface2);
132*1a96fba6SXin Li     itf2->AddSimpleMethodHandler(kTestMethod_StrLen, StrLen);
133*1a96fba6SXin Li     itf2->AddSimpleMethodHandlerWithError(kTestMethod_CheckNonEmpty,
134*1a96fba6SXin Li                                           CheckNonEmpty);
135*1a96fba6SXin Li     DBusInterface* itf3 = dbus_object_->AddOrGetInterface(kTestInterface3);
136*1a96fba6SXin Li     base::Callback<void()> noop_callback = base::Bind(NoOp);
137*1a96fba6SXin Li     itf3->AddSimpleMethodHandler(kTestMethod_NoOp, noop_callback);
138*1a96fba6SXin Li     itf3->AddSimpleMethodHandlerWithErrorAndMessage(
139*1a96fba6SXin Li         kTestMethod_WithMessage, base::Bind(&TestWithMessage));
140*1a96fba6SXin Li     itf3->AddMethodHandlerWithMessage(kTestMethod_WithMessageAsync,
141*1a96fba6SXin Li                                       base::Bind(&TestWithMessageAsync));
142*1a96fba6SXin Li 
143*1a96fba6SXin Li     dbus_object_->RegisterAsync(
144*1a96fba6SXin Li         AsyncEventSequencer::GetDefaultCompletionAction());
145*1a96fba6SXin Li   }
146*1a96fba6SXin Li 
ExpectError(dbus::Response * response,const std::string & expected_code)147*1a96fba6SXin Li   void ExpectError(dbus::Response* response, const std::string& expected_code) {
148*1a96fba6SXin Li     EXPECT_EQ(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
149*1a96fba6SXin Li     EXPECT_EQ(expected_code, response->GetErrorName());
150*1a96fba6SXin Li   }
151*1a96fba6SXin Li 
152*1a96fba6SXin Li   scoped_refptr<dbus::MockBus> bus_;
153*1a96fba6SXin Li   scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
154*1a96fba6SXin Li   std::unique_ptr<DBusObject> dbus_object_;
155*1a96fba6SXin Li   Calc calc_;
156*1a96fba6SXin Li };
157*1a96fba6SXin Li 
TEST_F(DBusObjectTest,Add)158*1a96fba6SXin Li TEST_F(DBusObjectTest, Add) {
159*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_Add);
160*1a96fba6SXin Li   method_call.SetSerial(123);
161*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
162*1a96fba6SXin Li   writer.AppendInt32(2);
163*1a96fba6SXin Li   writer.AppendInt32(3);
164*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
165*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
166*1a96fba6SXin Li   int result;
167*1a96fba6SXin Li   ASSERT_TRUE(reader.PopInt32(&result));
168*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
169*1a96fba6SXin Li   ASSERT_EQ(5, result);
170*1a96fba6SXin Li }
171*1a96fba6SXin Li 
TEST_F(DBusObjectTest,Negate)172*1a96fba6SXin Li TEST_F(DBusObjectTest, Negate) {
173*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_Negate);
174*1a96fba6SXin Li   method_call.SetSerial(123);
175*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
176*1a96fba6SXin Li   writer.AppendInt32(98765);
177*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
178*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
179*1a96fba6SXin Li   int result;
180*1a96fba6SXin Li   ASSERT_TRUE(reader.PopInt32(&result));
181*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
182*1a96fba6SXin Li   ASSERT_EQ(-98765, result);
183*1a96fba6SXin Li }
184*1a96fba6SXin Li 
TEST_F(DBusObjectTest,PositiveSuccess)185*1a96fba6SXin Li TEST_F(DBusObjectTest, PositiveSuccess) {
186*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_Positive);
187*1a96fba6SXin Li   method_call.SetSerial(123);
188*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
189*1a96fba6SXin Li   writer.AppendDouble(17.5);
190*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
191*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
192*1a96fba6SXin Li   double result;
193*1a96fba6SXin Li   ASSERT_TRUE(reader.PopDouble(&result));
194*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
195*1a96fba6SXin Li   ASSERT_DOUBLE_EQ(17.5, result);
196*1a96fba6SXin Li }
197*1a96fba6SXin Li 
TEST_F(DBusObjectTest,PositiveFailure)198*1a96fba6SXin Li TEST_F(DBusObjectTest, PositiveFailure) {
199*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_Positive);
200*1a96fba6SXin Li   method_call.SetSerial(123);
201*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
202*1a96fba6SXin Li   writer.AppendDouble(-23.2);
203*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
204*1a96fba6SXin Li   ExpectError(response.get(), DBUS_ERROR_FAILED);
205*1a96fba6SXin Li }
206*1a96fba6SXin Li 
TEST_F(DBusObjectTest,AddSubtract)207*1a96fba6SXin Li TEST_F(DBusObjectTest, AddSubtract) {
208*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_AddSubtract);
209*1a96fba6SXin Li   method_call.SetSerial(123);
210*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
211*1a96fba6SXin Li   writer.AppendInt32(2);
212*1a96fba6SXin Li   writer.AppendInt32(3);
213*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
214*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
215*1a96fba6SXin Li   int sum = 0, diff = 0;
216*1a96fba6SXin Li   ASSERT_TRUE(reader.PopInt32(&sum));
217*1a96fba6SXin Li   ASSERT_TRUE(reader.PopInt32(&diff));
218*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
219*1a96fba6SXin Li   EXPECT_EQ(5, sum);
220*1a96fba6SXin Li   EXPECT_EQ(-1, diff);
221*1a96fba6SXin Li }
222*1a96fba6SXin Li 
TEST_F(DBusObjectTest,StrLen0)223*1a96fba6SXin Li TEST_F(DBusObjectTest, StrLen0) {
224*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface2, kTestMethod_StrLen);
225*1a96fba6SXin Li   method_call.SetSerial(123);
226*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
227*1a96fba6SXin Li   writer.AppendString("");
228*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
229*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
230*1a96fba6SXin Li   int result;
231*1a96fba6SXin Li   ASSERT_TRUE(reader.PopInt32(&result));
232*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
233*1a96fba6SXin Li   ASSERT_EQ(0, result);
234*1a96fba6SXin Li }
235*1a96fba6SXin Li 
TEST_F(DBusObjectTest,StrLen4)236*1a96fba6SXin Li TEST_F(DBusObjectTest, StrLen4) {
237*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface2, kTestMethod_StrLen);
238*1a96fba6SXin Li   method_call.SetSerial(123);
239*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
240*1a96fba6SXin Li   writer.AppendString("test");
241*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
242*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
243*1a96fba6SXin Li   int result;
244*1a96fba6SXin Li   ASSERT_TRUE(reader.PopInt32(&result));
245*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
246*1a96fba6SXin Li   ASSERT_EQ(4, result);
247*1a96fba6SXin Li }
248*1a96fba6SXin Li 
TEST_F(DBusObjectTest,CheckNonEmpty_Success)249*1a96fba6SXin Li TEST_F(DBusObjectTest, CheckNonEmpty_Success) {
250*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface2, kTestMethod_CheckNonEmpty);
251*1a96fba6SXin Li   method_call.SetSerial(123);
252*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
253*1a96fba6SXin Li   writer.AppendString("test");
254*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
255*1a96fba6SXin Li   ASSERT_EQ(dbus::Message::MESSAGE_METHOD_RETURN, response->GetMessageType());
256*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
257*1a96fba6SXin Li   EXPECT_FALSE(reader.HasMoreData());
258*1a96fba6SXin Li }
259*1a96fba6SXin Li 
TEST_F(DBusObjectTest,CheckNonEmpty_Failure)260*1a96fba6SXin Li TEST_F(DBusObjectTest, CheckNonEmpty_Failure) {
261*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface2, kTestMethod_CheckNonEmpty);
262*1a96fba6SXin Li   method_call.SetSerial(123);
263*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
264*1a96fba6SXin Li   writer.AppendString("");
265*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
266*1a96fba6SXin Li   ASSERT_EQ(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
267*1a96fba6SXin Li   ErrorPtr error;
268*1a96fba6SXin Li   ExtractMethodCallResults(response.get(), &error);
269*1a96fba6SXin Li   ASSERT_NE(nullptr, error.get());
270*1a96fba6SXin Li   EXPECT_EQ("test", error->GetDomain());
271*1a96fba6SXin Li   EXPECT_EQ("string_empty", error->GetCode());
272*1a96fba6SXin Li   EXPECT_EQ("String is empty", error->GetMessage());
273*1a96fba6SXin Li }
274*1a96fba6SXin Li 
TEST_F(DBusObjectTest,CheckNonEmpty_MissingParams)275*1a96fba6SXin Li TEST_F(DBusObjectTest, CheckNonEmpty_MissingParams) {
276*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface2, kTestMethod_CheckNonEmpty);
277*1a96fba6SXin Li   method_call.SetSerial(123);
278*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
279*1a96fba6SXin Li   ASSERT_EQ(dbus::Message::MESSAGE_ERROR, response->GetMessageType());
280*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
281*1a96fba6SXin Li   std::string message;
282*1a96fba6SXin Li   ASSERT_TRUE(reader.PopString(&message));
283*1a96fba6SXin Li   EXPECT_EQ(DBUS_ERROR_INVALID_ARGS, response->GetErrorName());
284*1a96fba6SXin Li   EXPECT_EQ("Too few parameters in a method call", message);
285*1a96fba6SXin Li   EXPECT_FALSE(reader.HasMoreData());
286*1a96fba6SXin Li }
287*1a96fba6SXin Li 
TEST_F(DBusObjectTest,NoOp)288*1a96fba6SXin Li TEST_F(DBusObjectTest, NoOp) {
289*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface3, kTestMethod_NoOp);
290*1a96fba6SXin Li   method_call.SetSerial(123);
291*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
292*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
293*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
294*1a96fba6SXin Li }
295*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TestWithMessage)296*1a96fba6SXin Li TEST_F(DBusObjectTest, TestWithMessage) {
297*1a96fba6SXin Li   const std::string sender{":1.2345"};
298*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface3, kTestMethod_WithMessage);
299*1a96fba6SXin Li   method_call.SetSerial(123);
300*1a96fba6SXin Li   method_call.SetSender(sender);
301*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
302*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
303*1a96fba6SXin Li   std::string message;
304*1a96fba6SXin Li   ASSERT_TRUE(reader.PopString(&message));
305*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
306*1a96fba6SXin Li   EXPECT_EQ(sender, message);
307*1a96fba6SXin Li }
308*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TestWithMessageAsync)309*1a96fba6SXin Li TEST_F(DBusObjectTest, TestWithMessageAsync) {
310*1a96fba6SXin Li   const std::string sender{":6.7890"};
311*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface3, kTestMethod_WithMessageAsync);
312*1a96fba6SXin Li   method_call.SetSerial(123);
313*1a96fba6SXin Li   method_call.SetSender(sender);
314*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
315*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
316*1a96fba6SXin Li   std::string message;
317*1a96fba6SXin Li   ASSERT_TRUE(reader.PopString(&message));
318*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
319*1a96fba6SXin Li   EXPECT_EQ(sender, message);
320*1a96fba6SXin Li }
321*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TestRemovedInterface)322*1a96fba6SXin Li TEST_F(DBusObjectTest, TestRemovedInterface) {
323*1a96fba6SXin Li   // Removes the interface to be tested.
324*1a96fba6SXin Li   dbus_object_->RemoveInterface(kTestInterface3);
325*1a96fba6SXin Li 
326*1a96fba6SXin Li   const std::string sender{":1.2345"};
327*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface3, kTestMethod_WithMessage);
328*1a96fba6SXin Li   method_call.SetSerial(123);
329*1a96fba6SXin Li   method_call.SetSender(sender);
330*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
331*1a96fba6SXin Li   // The response should contain error UnknownInterface since the interface has
332*1a96fba6SXin Li   // been intentionally removed.
333*1a96fba6SXin Li   EXPECT_EQ(DBUS_ERROR_UNKNOWN_INTERFACE, response->GetErrorName());
334*1a96fba6SXin Li }
335*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TestUnexportInterfaceAsync)336*1a96fba6SXin Li TEST_F(DBusObjectTest, TestUnexportInterfaceAsync) {
337*1a96fba6SXin Li   // Unexport the interface to be tested. It should unexport the methods on that
338*1a96fba6SXin Li   // interface.
339*1a96fba6SXin Li   EXPECT_CALL(*mock_exported_object_,
340*1a96fba6SXin Li               UnexportMethod(kTestInterface3, kTestMethod_NoOp, _))
341*1a96fba6SXin Li       .Times(1);
342*1a96fba6SXin Li   EXPECT_CALL(*mock_exported_object_,
343*1a96fba6SXin Li               UnexportMethod(kTestInterface3, kTestMethod_WithMessage, _))
344*1a96fba6SXin Li       .Times(1);
345*1a96fba6SXin Li   EXPECT_CALL(*mock_exported_object_,
346*1a96fba6SXin Li               UnexportMethod(kTestInterface3, kTestMethod_WithMessageAsync, _))
347*1a96fba6SXin Li       .Times(1);
348*1a96fba6SXin Li   dbus_object_->UnexportInterfaceAsync(kTestInterface3,
349*1a96fba6SXin Li                                        base::Bind(&OnInterfaceExported));
350*1a96fba6SXin Li }
351*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TestUnexportInterfaceBlocking)352*1a96fba6SXin Li TEST_F(DBusObjectTest, TestUnexportInterfaceBlocking) {
353*1a96fba6SXin Li   // Unexport the interface to be tested. It should unexport the methods on that
354*1a96fba6SXin Li   // interface.
355*1a96fba6SXin Li   EXPECT_CALL(*mock_exported_object_,
356*1a96fba6SXin Li               UnexportMethodAndBlock(kTestInterface3, kTestMethod_NoOp))
357*1a96fba6SXin Li       .WillOnce(Return(true));
358*1a96fba6SXin Li   EXPECT_CALL(*mock_exported_object_,
359*1a96fba6SXin Li               UnexportMethodAndBlock(kTestInterface3, kTestMethod_WithMessage))
360*1a96fba6SXin Li       .WillOnce(Return(true));
361*1a96fba6SXin Li   EXPECT_CALL(
362*1a96fba6SXin Li       *mock_exported_object_,
363*1a96fba6SXin Li       UnexportMethodAndBlock(kTestInterface3, kTestMethod_WithMessageAsync))
364*1a96fba6SXin Li       .WillOnce(Return(true));
365*1a96fba6SXin Li   dbus_object_->UnexportInterfaceAndBlock(kTestInterface3);
366*1a96fba6SXin Li }
367*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TestInterfaceExportedLateAsync)368*1a96fba6SXin Li TEST_F(DBusObjectTest, TestInterfaceExportedLateAsync) {
369*1a96fba6SXin Li   // Registers a new interface late.
370*1a96fba6SXin Li   dbus_object_->ExportInterfaceAsync(kTestInterface4,
371*1a96fba6SXin Li                                      base::Bind(&OnInterfaceExported));
372*1a96fba6SXin Li 
373*1a96fba6SXin Li   const std::string sender{":1.2345"};
374*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface4, kTestMethod_WithMessage);
375*1a96fba6SXin Li   method_call.SetSerial(123);
376*1a96fba6SXin Li   method_call.SetSender(sender);
377*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
378*1a96fba6SXin Li   // The response should contain error UnknownMethod rather than
379*1a96fba6SXin Li   // UnknownInterface since the interface has been registered late.
380*1a96fba6SXin Li   EXPECT_EQ(DBUS_ERROR_UNKNOWN_METHOD, response->GetErrorName());
381*1a96fba6SXin Li }
382*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TestInterfaceExportedLateBlocking)383*1a96fba6SXin Li TEST_F(DBusObjectTest, TestInterfaceExportedLateBlocking) {
384*1a96fba6SXin Li   // Registers a new interface late.
385*1a96fba6SXin Li   dbus_object_->ExportInterfaceAndBlock(kTestInterface4);
386*1a96fba6SXin Li 
387*1a96fba6SXin Li   const std::string sender{":1.2345"};
388*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface4, kTestMethod_WithMessage);
389*1a96fba6SXin Li   method_call.SetSerial(123);
390*1a96fba6SXin Li   method_call.SetSender(sender);
391*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
392*1a96fba6SXin Li   // The response should contain error UnknownMethod rather than
393*1a96fba6SXin Li   // UnknownInterface since the interface has been registered late.
394*1a96fba6SXin Li   EXPECT_EQ(DBUS_ERROR_UNKNOWN_METHOD, response->GetErrorName());
395*1a96fba6SXin Li }
396*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TooFewParams)397*1a96fba6SXin Li TEST_F(DBusObjectTest, TooFewParams) {
398*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_Add);
399*1a96fba6SXin Li   method_call.SetSerial(123);
400*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
401*1a96fba6SXin Li   writer.AppendInt32(2);
402*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
403*1a96fba6SXin Li   ExpectError(response.get(), DBUS_ERROR_INVALID_ARGS);
404*1a96fba6SXin Li }
405*1a96fba6SXin Li 
TEST_F(DBusObjectTest,TooManyParams)406*1a96fba6SXin Li TEST_F(DBusObjectTest, TooManyParams) {
407*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_Add);
408*1a96fba6SXin Li   method_call.SetSerial(123);
409*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
410*1a96fba6SXin Li   writer.AppendInt32(1);
411*1a96fba6SXin Li   writer.AppendInt32(2);
412*1a96fba6SXin Li   writer.AppendInt32(3);
413*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
414*1a96fba6SXin Li   ExpectError(response.get(), DBUS_ERROR_INVALID_ARGS);
415*1a96fba6SXin Li }
416*1a96fba6SXin Li 
TEST_F(DBusObjectTest,ParamTypeMismatch)417*1a96fba6SXin Li TEST_F(DBusObjectTest, ParamTypeMismatch) {
418*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_Add);
419*1a96fba6SXin Li   method_call.SetSerial(123);
420*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
421*1a96fba6SXin Li   writer.AppendInt32(1);
422*1a96fba6SXin Li   writer.AppendBool(false);
423*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
424*1a96fba6SXin Li   ExpectError(response.get(), DBUS_ERROR_INVALID_ARGS);
425*1a96fba6SXin Li }
426*1a96fba6SXin Li 
TEST_F(DBusObjectTest,ParamAsVariant)427*1a96fba6SXin Li TEST_F(DBusObjectTest, ParamAsVariant) {
428*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface1, kTestMethod_Add);
429*1a96fba6SXin Li   method_call.SetSerial(123);
430*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
431*1a96fba6SXin Li   writer.AppendVariantOfInt32(10);
432*1a96fba6SXin Li   writer.AppendVariantOfInt32(3);
433*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
434*1a96fba6SXin Li   dbus::MessageReader reader(response.get());
435*1a96fba6SXin Li   int result;
436*1a96fba6SXin Li   ASSERT_TRUE(reader.PopInt32(&result));
437*1a96fba6SXin Li   ASSERT_FALSE(reader.HasMoreData());
438*1a96fba6SXin Li   ASSERT_EQ(13, result);
439*1a96fba6SXin Li }
440*1a96fba6SXin Li 
TEST_F(DBusObjectTest,UnknownMethod)441*1a96fba6SXin Li TEST_F(DBusObjectTest, UnknownMethod) {
442*1a96fba6SXin Li   dbus::MethodCall method_call(kTestInterface2, kTestMethod_Add);
443*1a96fba6SXin Li   method_call.SetSerial(123);
444*1a96fba6SXin Li   dbus::MessageWriter writer(&method_call);
445*1a96fba6SXin Li   writer.AppendInt32(1);
446*1a96fba6SXin Li   writer.AppendBool(false);
447*1a96fba6SXin Li   auto response = testing::CallMethod(*dbus_object_, &method_call);
448*1a96fba6SXin Li   ExpectError(response.get(), DBUS_ERROR_UNKNOWN_METHOD);
449*1a96fba6SXin Li }
450*1a96fba6SXin Li 
TEST_F(DBusObjectTest,ShouldReleaseOnlyClaimedInterfaces)451*1a96fba6SXin Li TEST_F(DBusObjectTest, ShouldReleaseOnlyClaimedInterfaces) {
452*1a96fba6SXin Li   const dbus::ObjectPath kObjectManagerPath{std::string{"/"}};
453*1a96fba6SXin Li   const dbus::ObjectPath kMethodsExportedOnPath{
454*1a96fba6SXin Li       std::string{kMethodsExportedOn}};
455*1a96fba6SXin Li   MockExportedObjectManager mock_object_manager{bus_, kObjectManagerPath};
456*1a96fba6SXin Li   dbus_object_ = std::unique_ptr<DBusObject>(
457*1a96fba6SXin Li       new DBusObject(&mock_object_manager, bus_, kMethodsExportedOnPath));
458*1a96fba6SXin Li   EXPECT_CALL(mock_object_manager, ClaimInterface(_, _, _)).Times(0);
459*1a96fba6SXin Li   EXPECT_CALL(mock_object_manager, ReleaseInterface(_, _)).Times(0);
460*1a96fba6SXin Li   DBusInterface* itf1 = dbus_object_->AddOrGetInterface(kTestInterface1);
461*1a96fba6SXin Li   itf1->AddSimpleMethodHandler(
462*1a96fba6SXin Li       kTestMethod_Add, base::Unretained(&calc_), &Calc::Add);
463*1a96fba6SXin Li   // When we tear down our DBusObject, it should release only interfaces it has
464*1a96fba6SXin Li   // previously claimed.  This prevents a check failing inside the
465*1a96fba6SXin Li   // ExportedObjectManager.  Since no interfaces have finished exporting
466*1a96fba6SXin Li   // handlers, nothing should be released.
467*1a96fba6SXin Li   dbus_object_.reset();
468*1a96fba6SXin Li }
469*1a96fba6SXin Li 
470*1a96fba6SXin Li }  // namespace dbus_utils
471*1a96fba6SXin Li }  // namespace brillo
472