1 /* Copyright (c) 2013 The Chromium OS 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 
6 #include <dbus/dbus.h>
7 #include <gtest/gtest.h>
8 #include <stdio.h>
9 #include <sys/socket.h>
10 
11 #include "dbus_test.h"
12 
13 extern "C" {
14 #include "cras_bt_constants.h"
15 #include "cras_bt_profile.h"
16 }
17 
18 namespace {
19 
20 static struct cras_bt_profile fake_profile;
21 static struct cras_bt_transport *fake_transport;
22 static int profile_release_called;
23 static struct cras_bt_profile *profile_release_arg_value;
24 static int profile_new_connection_called;
25 static struct cras_bt_transport *profile_new_connection_arg_value;
26 static int profile_request_disconnection_called;
27 static struct cras_bt_transport *profile_request_disconnection_arg_value;
28 static int profile_cancel_called;
29 static struct cras_bt_profile *profile_cancel_arg_value;
30 static int cras_bt_transport_get_called;
31 static const char *cras_bt_transport_get_arg_value;
32 
33 void fake_profile_release(struct cras_bt_profile *profile);
34 void fake_profile_new_connection(struct cras_bt_profile *profile,
35 				 struct cras_bt_transport *transport);
36 void fake_profile_request_disconnection(struct cras_bt_profile *profile,
37 					struct cras_bt_transport *transport);
38 void fake_profile_cancel(struct cras_bt_profile *profile);
39 
40 class BtProfileTestSuite : public DBusTest {
SetUp()41   virtual void SetUp() {
42     DBusTest::SetUp();
43 
44     profile_release_called = 0;
45     profile_new_connection_called = 0;
46     profile_request_disconnection_called = 0;
47     profile_cancel_called = 0;
48 
49     fake_profile.name = "fake";
50     fake_profile.object_path = "/fake";
51     fake_profile.uuid = "0";
52     fake_profile.version = 0;
53     fake_profile.role = NULL;
54     fake_profile.features = 0;
55     fake_profile.release = fake_profile_release;
56     fake_profile.new_connection = fake_profile_new_connection;
57     fake_profile.request_disconnection = fake_profile_request_disconnection;
58     fake_profile.cancel = fake_profile_cancel;
59 
60     fake_transport = reinterpret_cast<struct cras_bt_transport*>(0x321);
61     cras_bt_transport_get_called = 0;
62   }
63 };
64 
TEST_F(BtProfileTestSuite,RegisterProfile)65 TEST_F(BtProfileTestSuite, RegisterProfile) {
66   struct cras_bt_profile *profile;
67 
68   ExpectMethodCall(PROFILE_MANAGER_OBJ_PATH, BLUEZ_PROFILE_MGMT_INTERFACE,
69                    "RegisterProfile")
70       .WithObjectPath("/fake")
71       .SendReply();
72 
73   cras_bt_add_profile(conn_, &fake_profile);
74   cras_bt_register_profiles(conn_);
75 
76   WaitForMatches();
77   profile = cras_bt_profile_get("/fake");
78 
79   EXPECT_TRUE(profile == &fake_profile);
80 }
81 
TEST_F(BtProfileTestSuite,ResetProfile)82 TEST_F(BtProfileTestSuite, ResetProfile) {
83   cras_bt_add_profile(conn_, &fake_profile);
84   cras_bt_profile_reset();
85 
86   ASSERT_EQ(1, profile_release_called);
87 }
88 
TEST_F(BtProfileTestSuite,HandleMessage)89 TEST_F(BtProfileTestSuite, HandleMessage) {
90   ExpectMethodCall(PROFILE_MANAGER_OBJ_PATH, BLUEZ_PROFILE_MGMT_INTERFACE,
91 		   "RegisterProfile")
92       .WithObjectPath("/fake")
93       .SendReply();
94 
95   cras_bt_add_profile(conn_, &fake_profile);
96   cras_bt_register_profiles(conn_);
97 
98   WaitForMatches();
99 
100   /* Use stdin as mock fd */
101   CreateMessageCall("/fake", "org.bluez.Profile1", "NewConnection")
102       .WithString("device")
103       .WithUnixFd(0)
104       .Send();
105 
106   WaitForMatches();
107   ASSERT_EQ(1, profile_new_connection_called);
108   ASSERT_STREQ("device", cras_bt_transport_get_arg_value);
109   ASSERT_EQ(1, cras_bt_transport_get_called);
110   ASSERT_EQ(fake_transport, profile_new_connection_arg_value);
111 
112   CreateMessageCall("/fake", "org.bluez.Profile1", "RequestDisconnection")
113       .WithString("device")
114       .Send();
115   WaitForMatches();
116   ASSERT_EQ(2, cras_bt_transport_get_called);
117   ASSERT_EQ(1, profile_request_disconnection_called);
118   ASSERT_EQ(fake_transport, profile_request_disconnection_arg_value);
119 
120   CreateMessageCall("/fake", "org.bluez.Profile1", "Release")
121       .Send();
122   WaitForMatches();
123   ASSERT_EQ(1, profile_release_called);
124   ASSERT_EQ(&fake_profile, profile_release_arg_value);
125 
126   CreateMessageCall("/fake", "org.bluez.Profile1", "Cancel")
127       .Send();
128   WaitForMatches();
129   ASSERT_EQ(1, profile_cancel_called);
130   ASSERT_EQ(&fake_profile, profile_cancel_arg_value);
131 }
132 
fake_profile_release(struct cras_bt_profile * profile)133 void fake_profile_release(struct cras_bt_profile *profile)
134 {
135   profile_release_arg_value = profile;
136   profile_release_called++;
137 }
138 
fake_profile_new_connection(struct cras_bt_profile * profile,struct cras_bt_transport * transport)139 void fake_profile_new_connection(struct cras_bt_profile *profile,
140 				 struct cras_bt_transport *transport)
141 {
142   profile_new_connection_arg_value = transport;
143   profile_new_connection_called++;
144 }
145 
fake_profile_request_disconnection(struct cras_bt_profile * profile,struct cras_bt_transport * transport)146 void fake_profile_request_disconnection(struct cras_bt_profile *profile,
147 					struct cras_bt_transport *transport)
148 {
149   profile_request_disconnection_arg_value = transport;
150   profile_request_disconnection_called++;
151 }
152 
fake_profile_cancel(struct cras_bt_profile * profile)153 void fake_profile_cancel(struct cras_bt_profile *profile)
154 {
155   profile_cancel_arg_value = profile;
156   profile_cancel_called++;
157 }
158 
159 } // namespace
160 
161 extern "C" {
append_key_value(DBusMessageIter * iter,const char * key,int type,const char * type_string,void * value)162 dbus_bool_t append_key_value(DBusMessageIter *iter, const char *key,
163                              int type, const char *type_string,
164                              void *value)
165 {
166   return TRUE;
167 }
168 
cras_bt_transport_get(const char * object_path)169 struct cras_bt_transport *cras_bt_transport_get(const char *object_path)
170 {
171   cras_bt_transport_get_called++;
172   cras_bt_transport_get_arg_value = object_path;
173   return fake_transport;
174 }
175 
cras_bt_transport_destroy(struct cras_bt_transport * transport)176 void cras_bt_transport_destroy(struct cras_bt_transport *transport)
177 {
178 }
179 
cras_bt_transport_create(DBusConnection * conn,const char * object_path)180 struct cras_bt_transport *cras_bt_transport_create(DBusConnection *conn,
181 						   const char *object_path)
182 {
183   return fake_transport;
184 }
185 
186 } // extern "C"
187 
main(int argc,char ** argv)188 int main(int argc, char **argv) {
189     ::testing::InitGoogleTest(&argc, argv);
190   return RUN_ALL_TESTS();
191 }
192