/* Copyright (c) 2013 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 <dbus/dbus.h>
#include <gtest/gtest.h>
#include <stdio.h>
#include <sys/socket.h>
#include "dbus_test.h"
extern "C" {
#include "cras_bt_constants.h"
#include "cras_bt_profile.h"
}
namespace {
static struct cras_bt_profile fake_profile;
static struct cras_bt_transport *fake_transport;
static int profile_release_called;
static struct cras_bt_profile *profile_release_arg_value;
static int profile_new_connection_called;
static struct cras_bt_transport *profile_new_connection_arg_value;
static int profile_request_disconnection_called;
static struct cras_bt_transport *profile_request_disconnection_arg_value;
static int profile_cancel_called;
static struct cras_bt_profile *profile_cancel_arg_value;
static int cras_bt_transport_get_called;
static const char *cras_bt_transport_get_arg_value;
void fake_profile_release(struct cras_bt_profile *profile);
void fake_profile_new_connection(struct cras_bt_profile *profile,
struct cras_bt_transport *transport);
void fake_profile_request_disconnection(struct cras_bt_profile *profile,
struct cras_bt_transport *transport);
void fake_profile_cancel(struct cras_bt_profile *profile);
class BtProfileTestSuite : public DBusTest {
virtual void SetUp() {
DBusTest::SetUp();
profile_release_called = 0;
profile_new_connection_called = 0;
profile_request_disconnection_called = 0;
profile_cancel_called = 0;
fake_profile.name = "fake";
fake_profile.object_path = "/fake";
fake_profile.uuid = "0";
fake_profile.version = 0;
fake_profile.role = NULL;
fake_profile.features = 0;
fake_profile.release = fake_profile_release;
fake_profile.new_connection = fake_profile_new_connection;
fake_profile.request_disconnection = fake_profile_request_disconnection;
fake_profile.cancel = fake_profile_cancel;
fake_transport = reinterpret_cast<struct cras_bt_transport*>(0x321);
cras_bt_transport_get_called = 0;
}
};
TEST_F(BtProfileTestSuite, RegisterProfile) {
struct cras_bt_profile *profile;
ExpectMethodCall(PROFILE_MANAGER_OBJ_PATH, BLUEZ_PROFILE_MGMT_INTERFACE,
"RegisterProfile")
.WithObjectPath("/fake")
.SendReply();
cras_bt_add_profile(conn_, &fake_profile);
cras_bt_register_profiles(conn_);
WaitForMatches();
profile = cras_bt_profile_get("/fake");
EXPECT_TRUE(profile == &fake_profile);
}
TEST_F(BtProfileTestSuite, ResetProfile) {
cras_bt_add_profile(conn_, &fake_profile);
cras_bt_profile_reset();
ASSERT_EQ(1, profile_release_called);
}
TEST_F(BtProfileTestSuite, HandleMessage) {
ExpectMethodCall(PROFILE_MANAGER_OBJ_PATH, BLUEZ_PROFILE_MGMT_INTERFACE,
"RegisterProfile")
.WithObjectPath("/fake")
.SendReply();
cras_bt_add_profile(conn_, &fake_profile);
cras_bt_register_profiles(conn_);
WaitForMatches();
/* Use stdin as mock fd */
CreateMessageCall("/fake", "org.bluez.Profile1", "NewConnection")
.WithString("device")
.WithUnixFd(0)
.Send();
WaitForMatches();
ASSERT_EQ(1, profile_new_connection_called);
ASSERT_STREQ("device", cras_bt_transport_get_arg_value);
ASSERT_EQ(1, cras_bt_transport_get_called);
ASSERT_EQ(fake_transport, profile_new_connection_arg_value);
CreateMessageCall("/fake", "org.bluez.Profile1", "RequestDisconnection")
.WithString("device")
.Send();
WaitForMatches();
ASSERT_EQ(2, cras_bt_transport_get_called);
ASSERT_EQ(1, profile_request_disconnection_called);
ASSERT_EQ(fake_transport, profile_request_disconnection_arg_value);
CreateMessageCall("/fake", "org.bluez.Profile1", "Release")
.Send();
WaitForMatches();
ASSERT_EQ(1, profile_release_called);
ASSERT_EQ(&fake_profile, profile_release_arg_value);
CreateMessageCall("/fake", "org.bluez.Profile1", "Cancel")
.Send();
WaitForMatches();
ASSERT_EQ(1, profile_cancel_called);
ASSERT_EQ(&fake_profile, profile_cancel_arg_value);
}
void fake_profile_release(struct cras_bt_profile *profile)
{
profile_release_arg_value = profile;
profile_release_called++;
}
void fake_profile_new_connection(struct cras_bt_profile *profile,
struct cras_bt_transport *transport)
{
profile_new_connection_arg_value = transport;
profile_new_connection_called++;
}
void fake_profile_request_disconnection(struct cras_bt_profile *profile,
struct cras_bt_transport *transport)
{
profile_request_disconnection_arg_value = transport;
profile_request_disconnection_called++;
}
void fake_profile_cancel(struct cras_bt_profile *profile)
{
profile_cancel_arg_value = profile;
profile_cancel_called++;
}
} // namespace
extern "C" {
dbus_bool_t append_key_value(DBusMessageIter *iter, const char *key,
int type, const char *type_string,
void *value)
{
return TRUE;
}
struct cras_bt_transport *cras_bt_transport_get(const char *object_path)
{
cras_bt_transport_get_called++;
cras_bt_transport_get_arg_value = object_path;
return fake_transport;
}
void cras_bt_transport_destroy(struct cras_bt_transport *transport)
{
}
struct cras_bt_transport *cras_bt_transport_create(DBusConnection *conn,
const char *object_path)
{
return fake_transport;
}
} // extern "C"
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}