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").Send();
121   WaitForMatches();
122   ASSERT_EQ(1, profile_release_called);
123   ASSERT_EQ(&fake_profile, profile_release_arg_value);
124 
125   CreateMessageCall("/fake", "org.bluez.Profile1", "Cancel").Send();
126   WaitForMatches();
127   ASSERT_EQ(1, profile_cancel_called);
128   ASSERT_EQ(&fake_profile, profile_cancel_arg_value);
129 }
130 
fake_profile_release(struct cras_bt_profile * profile)131 void fake_profile_release(struct cras_bt_profile* profile) {
132   profile_release_arg_value = profile;
133   profile_release_called++;
134 }
135 
fake_profile_new_connection(struct cras_bt_profile * profile,struct cras_bt_transport * transport)136 void fake_profile_new_connection(struct cras_bt_profile* profile,
137                                  struct cras_bt_transport* transport) {
138   profile_new_connection_arg_value = transport;
139   profile_new_connection_called++;
140 }
141 
fake_profile_request_disconnection(struct cras_bt_profile * profile,struct cras_bt_transport * transport)142 void fake_profile_request_disconnection(struct cras_bt_profile* profile,
143                                         struct cras_bt_transport* transport) {
144   profile_request_disconnection_arg_value = transport;
145   profile_request_disconnection_called++;
146 }
147 
fake_profile_cancel(struct cras_bt_profile * profile)148 void fake_profile_cancel(struct cras_bt_profile* profile) {
149   profile_cancel_arg_value = profile;
150   profile_cancel_called++;
151 }
152 
153 }  // namespace
154 
155 extern "C" {
append_key_value(DBusMessageIter * iter,const char * key,int type,const char * type_string,void * value)156 dbus_bool_t append_key_value(DBusMessageIter* iter,
157                              const char* key,
158                              int type,
159                              const char* type_string,
160                              void* value) {
161   return TRUE;
162 }
163 
cras_bt_transport_get(const char * object_path)164 struct cras_bt_transport* cras_bt_transport_get(const char* object_path) {
165   cras_bt_transport_get_called++;
166   cras_bt_transport_get_arg_value = object_path;
167   return fake_transport;
168 }
169 
cras_bt_transport_destroy(struct cras_bt_transport * transport)170 void cras_bt_transport_destroy(struct cras_bt_transport* transport) {}
171 
cras_bt_transport_create(DBusConnection * conn,const char * object_path)172 struct cras_bt_transport* cras_bt_transport_create(DBusConnection* conn,
173                                                    const char* object_path) {
174   return fake_transport;
175 }
176 
177 }  // extern "C"
178 
main(int argc,char ** argv)179 int main(int argc, char** argv) {
180   ::testing::InitGoogleTest(&argc, argv);
181   return RUN_ALL_TESTS();
182 }
183