blob: 212b31ad74f569341584a3ca2901a1a32d3ebdd5 [file] [log] [blame]
// Copyright (c) 2012 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 <gtest/gtest.h>
#include <iniparser.h>
#include <stdio.h>
#include <map>
extern "C" {
#include "cras_alsa_ucm.h"
#include "cras_types.h"
// Include C file to test static functions.
#include "cras_alsa_ucm.c"
}
namespace {
static int snd_use_case_mgr_open_return;
static snd_use_case_mgr_t *snd_use_case_mgr_open_mgr_ptr;
static unsigned snd_use_case_mgr_open_called;
static unsigned snd_use_case_mgr_close_called;
static unsigned snd_use_case_get_called;
static std::vector<std::string> snd_use_case_get_id;
static std::map<std::string, int> snd_use_case_get_ret_value;
static int snd_use_case_set_return;
static std::map<std::string, std::string> snd_use_case_get_value;
static unsigned snd_use_case_set_called;
static std::vector<std::pair<std::string, std::string> > snd_use_case_set_param;
static std::map<std::string, const char **> fake_list;
static std::map<std::string, unsigned> fake_list_size;
static unsigned snd_use_case_free_list_called;
static void ResetStubData() {
snd_use_case_mgr_open_called = 0;
snd_use_case_mgr_open_return = 0;
snd_use_case_mgr_close_called = 0;
snd_use_case_set_return = 0;
snd_use_case_get_called = 0;
snd_use_case_set_called = 0;
snd_use_case_set_param.clear();
snd_use_case_free_list_called = 0;
snd_use_case_get_id.clear();
snd_use_case_get_value.clear();
snd_use_case_get_ret_value.clear();
fake_list.clear();
fake_list_size.clear();
}
TEST(AlsaUcm, CreateFailInvalidCard) {
ResetStubData();
EXPECT_EQ(NULL, ucm_create(NULL));
EXPECT_EQ(0, snd_use_case_mgr_open_called);
}
TEST(AlsaUcm, CreateFailCardNotFound) {
ResetStubData();
snd_use_case_mgr_open_return = -1;
EXPECT_EQ(NULL, ucm_create("foo"));
EXPECT_EQ(1, snd_use_case_mgr_open_called);
}
TEST(AlsaUcm, CreateFailNoHiFi) {
ResetStubData();
snd_use_case_set_return = -1;
EXPECT_EQ(NULL, ucm_create("foo"));
EXPECT_EQ(1, snd_use_case_mgr_open_called);
EXPECT_EQ(1, snd_use_case_set_called);
EXPECT_EQ(1, snd_use_case_mgr_close_called);
}
TEST(AlsaUcm, CreateSuccess) {
snd_use_case_mgr_t* mgr;
ResetStubData();
snd_use_case_mgr_open_mgr_ptr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
mgr = ucm_create("foo");
EXPECT_NE(static_cast<snd_use_case_mgr_t*>(NULL), mgr);
EXPECT_EQ(1, snd_use_case_mgr_open_called);
EXPECT_EQ(1, snd_use_case_set_called);
EXPECT_EQ(0, snd_use_case_mgr_close_called);
ucm_destroy(mgr);
EXPECT_EQ(1, snd_use_case_mgr_close_called);
}
TEST(AlsaUcm, CheckEnabledEmptyList) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
ResetStubData();
fake_list["_enadevs"] = NULL;
fake_list_size["_enadevs"] = 0;
EXPECT_EQ(0, ucm_set_enabled(mgr, "Dev1", 0));
EXPECT_EQ(0, snd_use_case_set_called);
EXPECT_EQ(0, ucm_set_enabled(mgr, "Dev1", 1));
EXPECT_EQ(1, snd_use_case_set_called);
EXPECT_EQ(0, snd_use_case_free_list_called);
}
TEST(AlsaUcm, CheckEnabledAlready) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
const char *enabled[] = { "Dev2", "Dev1" };
ResetStubData();
fake_list["_enadevs"] = enabled;
fake_list_size["_enadevs"] = 2;
EXPECT_EQ(0, ucm_set_enabled(mgr, "Dev1", 1));
EXPECT_EQ(0, snd_use_case_set_called);
EXPECT_EQ(0, ucm_set_enabled(mgr, "Dev1", 0));
EXPECT_EQ(1, snd_use_case_set_called);
EXPECT_EQ(2, snd_use_case_free_list_called);
}
TEST(AlsaUcm, GetEdidForDev) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
std::string id = "=EDIDFile/Dev1/HiFi";
std::string value = "EdidFileName";
const char *file_name;
ResetStubData();
snd_use_case_get_value[id] = value;
snd_use_case_get_ret_value[id] = 0;
file_name = ucm_get_edid_file_for_dev(mgr, "Dev1");
ASSERT_TRUE(file_name);
EXPECT_EQ(0, strcmp(file_name, value.c_str()));
free((void*)file_name);
ASSERT_EQ(1, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id);
}
TEST(AlsaUcm, GetCapControlForDev) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
char *cap_control;
std::string id = "=CaptureControl/Dev1/HiFi";
std::string value = "MIC";
ResetStubData();
snd_use_case_get_value[id] = value;
snd_use_case_get_ret_value[id] = 0;
cap_control = ucm_get_cap_control(mgr, "Dev1");
ASSERT_TRUE(cap_control);
EXPECT_EQ(0, strcmp(cap_control, value.c_str()));
free(cap_control);
ASSERT_EQ(1, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id);
}
TEST(AlsaUcm, GetOverrideType) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
const char *override_type_name;
std::string id = "=OverrideNodeType/Dev1/HiFi";
std::string value = "HDMI";
ResetStubData();
snd_use_case_get_value[id] = value;
snd_use_case_get_ret_value[id] = 0;
override_type_name = ucm_get_override_type_name(mgr, "Dev1");
ASSERT_TRUE(override_type_name);
EXPECT_EQ(0, strcmp(override_type_name, value.c_str()));
free((void*)override_type_name);
ASSERT_EQ(1, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id);
}
TEST(AlsaUcm, GetSectionForVar) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
const char *section_name;
ResetStubData();
const char *sections[] = { "Sec1", "Comment for Sec1", "Sec2",
"Comment for Sec2" };
fake_list["Identifier"] = sections;
fake_list_size["Identifier"] = 4;
std::string id_1 = "=Var/Sec1/HiFi";
std::string id_2 = "=Var/Sec2/HiFi";
std::string value_1 = "Value1";
std::string value_2 = "Value2";
snd_use_case_get_ret_value[id_1] = 0;
snd_use_case_get_value[id_1] = value_1;
snd_use_case_get_ret_value[id_2] = 0;
snd_use_case_get_value[id_2] = value_2;
section_name = ucm_get_section_for_var(mgr, "Var", "Value2", "Identifier",
CRAS_STREAM_OUTPUT);
ASSERT_TRUE(section_name);
EXPECT_EQ(0, strcmp(section_name, "Sec2"));
free((void*)section_name);
ASSERT_EQ(2, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id_1);
EXPECT_EQ(snd_use_case_get_id[1], id_2);
}
TEST(AlsaUcm, GetDevForJack) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
const char *dev_name;
const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
"Comment for Dev2" };
ResetStubData();
fake_list["_devices/HiFi"] = devices;
fake_list_size["_devices/HiFi"] = 4;
std::string id_1 = "=JackName/Dev1/HiFi";
std::string id_2 = "=JackName/Dev2/HiFi";
std::string value_1 = "Value1";
std::string value_2 = "Value2";
snd_use_case_get_ret_value[id_1] = 0;
snd_use_case_get_value[id_1] = value_1;
snd_use_case_get_ret_value[id_2] = 0;
snd_use_case_get_value[id_2] = value_2;
dev_name = ucm_get_dev_for_jack(mgr, value_2.c_str(), CRAS_STREAM_OUTPUT);
ASSERT_TRUE(dev_name);
EXPECT_EQ(0, strcmp(dev_name, "Dev2"));
free((void*)dev_name);
ASSERT_EQ(2, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id_1);
EXPECT_EQ(snd_use_case_get_id[1], id_2);
}
TEST(AlsaUcm, GetDeviceNameForDevice) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
const char *input_dev_name, *output_dev_name;
const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
"Comment for Dev2" };
ResetStubData();
fake_list["_devices/HiFi"] = devices;
fake_list_size["_devices/HiFi"] = 4;
std::string id_1 = "=CapturePCM/Dev1/HiFi";
std::string id_2 = "=PlaybackPCM/Dev2/HiFi";
std::string value_1 = "DeviceName1";
std::string value_2 = "DeviceName2";
snd_use_case_get_ret_value[id_1] = 0;
snd_use_case_get_value[id_1] = value_1;
snd_use_case_get_ret_value[id_2] = 0;
snd_use_case_get_value[id_2] = value_2;
input_dev_name = ucm_get_device_name_for_dev(mgr, "Dev1", CRAS_STREAM_INPUT);
output_dev_name = ucm_get_device_name_for_dev(mgr, "Dev2", CRAS_STREAM_OUTPUT);
ASSERT_TRUE(input_dev_name);
ASSERT_TRUE(output_dev_name);
EXPECT_EQ(0, strcmp(input_dev_name, value_1.c_str()));
EXPECT_EQ(0, strcmp(output_dev_name, value_2.c_str()));
ASSERT_EQ(2, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id_1);
EXPECT_EQ(snd_use_case_get_id[1], id_2);
}
TEST(AlsaUcm, SwapModeExists) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
int rc;
const char *modifiers_1[] = { "Speaker Swap Mode",
"Comment for Speaker Swap Mode",
"Microphone Swap Mode",
"Comment for Microphone Swap Mode" };
const char *modifiers_2[] = { "Speaker Some Mode",
"Comment for Speaker Some Mode",
"Microphone Some Mode",
"Comment for Microphone Some Mode" };
ResetStubData();
fake_list["_modifiers/HiFi"] = modifiers_1;
fake_list_size["_modifiers/HiFi"] = 4;
rc = ucm_swap_mode_exists(mgr);
EXPECT_EQ(1, rc);
fake_list["_modifiers/HiFi"] = modifiers_2;
fake_list_size["_modifiers/HiFi"] = 4;
rc = ucm_swap_mode_exists(mgr);
EXPECT_EQ(0, rc);
}
TEST(AlsaUcm, EnableSwapMode) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
int rc;
const char *modifiers[] = { "Speaker Swap Mode",
"Comment for Speaker Swap Mode",
"Microphone Swap Mode",
"Comment for Microphone Swap Mode" };
const char *modifiers_enabled[] = {"Speaker Swap Mode"};
ResetStubData();
fake_list["_modifiers/HiFi"] = modifiers;
fake_list_size["_modifiers/HiFi"] = 4;
fake_list["_enamods"] = modifiers_enabled;
fake_list_size["_enamods"] = 1;
snd_use_case_set_return = 0;
rc = ucm_enable_swap_mode(mgr, "Headphone", 1);
EXPECT_EQ(-EPERM, rc);
EXPECT_EQ(0, snd_use_case_set_called);
rc = ucm_enable_swap_mode(mgr, "Speaker", 1);
EXPECT_EQ(0, rc);
EXPECT_EQ(0, snd_use_case_set_called);
rc = ucm_enable_swap_mode(mgr, "Microphone", 1);
EXPECT_EQ(0, rc);
EXPECT_EQ(1, snd_use_case_set_called);
}
TEST(AlsaUcm, DisableSwapMode) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
int rc;
const char *modifiers[] = { "Speaker Swap Mode",
"Comment for Speaker Swap Mode",
"Microphone Swap Mode",
"Comment for Microphone Swap Mode" };
const char *modifiers_enabled[] = {"Speaker Swap Mode"};
ResetStubData();
fake_list["_modifiers/HiFi"] = modifiers;
fake_list_size["_modifiers/HiFi"] = 4;
fake_list["_enamods"] = modifiers_enabled;
fake_list_size["_enamods"] = 1;
snd_use_case_set_return = 0;
rc = ucm_enable_swap_mode(mgr, "Headphone", 0);
EXPECT_EQ(-EPERM, rc);
EXPECT_EQ(0, snd_use_case_set_called);
rc = ucm_enable_swap_mode(mgr, "Microphone", 0);
EXPECT_EQ(0, rc);
EXPECT_EQ(0, snd_use_case_set_called);
rc = ucm_enable_swap_mode(mgr, "Speaker", 0);
EXPECT_EQ(0, rc);
EXPECT_EQ(1, snd_use_case_set_called);
}
TEST(AlsaFlag, GetFlag) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
char *flag_value;
std::string id = "=FlagName//HiFi";
std::string value = "1";
ResetStubData();
snd_use_case_get_value[id] = value;
flag_value = ucm_get_flag(mgr, "FlagName");
ASSERT_TRUE(flag_value);
EXPECT_EQ(0, strcmp(flag_value, value.c_str()));
free(flag_value);
ASSERT_EQ(1, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id);
}
TEST(AlsaUcm, ModifierEnabled) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
int enabled;
ResetStubData();
const char *mods[] = { "Mod1", "Mod2" };
fake_list["_enamods"] = mods;
fake_list_size["_enamods"] = 2;
enabled = modifier_enabled(mgr, "Mod1");
EXPECT_EQ(1, enabled);
enabled = modifier_enabled(mgr, "Mod2");
EXPECT_EQ(1, enabled);
enabled = modifier_enabled(mgr, "Mod3");
EXPECT_EQ(0, enabled);
}
TEST(AlsaUcm, SetModifierEnabled) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
ResetStubData();
ucm_set_modifier_enabled(mgr, "Mod1", 1);
EXPECT_EQ(snd_use_case_set_param[0],
std::make_pair(std::string("_enamod"), std::string("Mod1")));
EXPECT_EQ(1, snd_use_case_set_called);
ucm_set_modifier_enabled(mgr, "Mod1", 0);
EXPECT_EQ(snd_use_case_set_param[1],
std::make_pair(std::string("_dismod"), std::string("Mod1")));
EXPECT_EQ(2, snd_use_case_set_called);
}
TEST(AlsaUcm, EndWithSuffix) {
EXPECT_EQ(1, ucm_str_ends_with_suffix("Foo bar", "bar"));
EXPECT_EQ(1, ucm_str_ends_with_suffix("bar", "bar"));
EXPECT_EQ(0, ucm_str_ends_with_suffix("Foo car", "bar"));
}
TEST(AlsaUcm, SectionExistsWithName) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
const char *sections[] = { "Sec1", "Comment for Sec1", "Sec2",
"Comment for Sec2" };
ResetStubData();
fake_list["Identifier"] = sections;
fake_list_size["Identifier"] = 4;
EXPECT_EQ(1, ucm_section_exists_with_name(mgr, "Sec1", "Identifier"));
EXPECT_EQ(1, ucm_section_exists_with_name(mgr, "Sec2", "Identifier"));
EXPECT_EQ(0, ucm_section_exists_with_name(mgr, "Sec3", "Identifier"));
}
TEST(AlsaUcm, SectionExistsWithSuffix) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
ResetStubData();
const char *sections[] = { "Sec1 Suffix1", "Comment for Sec1",
"Sec2 Suffix2", "Comment for Sec2" };
fake_list["Identifier"] = sections;
fake_list_size["Identifier"] = 4;
EXPECT_EQ(1, ucm_section_exists_with_suffix(mgr, "Suffix1", "Identifier"));
EXPECT_EQ(1, ucm_section_exists_with_suffix(mgr, "Suffix2", "Identifier"));
EXPECT_EQ(0, ucm_section_exists_with_suffix(mgr, "Suffix3", "Identifier"));
}
TEST(AlsaUcm, DisableSoftwareVolume) {
snd_use_case_mgr_t* mgr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
unsigned int disable_software_volume;
std::string id = "=DisableSoftwareVolume//HiFi";
std::string value = "1";
ResetStubData();
snd_use_case_get_value[id] = value;
snd_use_case_get_ret_value[id] = 0;
disable_software_volume = ucm_get_disable_software_volume(mgr);
ASSERT_TRUE(disable_software_volume);
ASSERT_EQ(1, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id);
}
/* Stubs */
extern "C" {
int snd_use_case_mgr_open(snd_use_case_mgr_t** uc_mgr, const char* card_name) {
snd_use_case_mgr_open_called++;
*uc_mgr = snd_use_case_mgr_open_mgr_ptr;
return snd_use_case_mgr_open_return;
}
int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr) {
snd_use_case_mgr_close_called++;
return 0;
}
int snd_use_case_get(snd_use_case_mgr_t* uc_mgr,
const char *identifier,
const char **value) {
snd_use_case_get_called++;
*value = strdup(snd_use_case_get_value[identifier].c_str());
snd_use_case_get_id.push_back(std::string(identifier));
return snd_use_case_get_ret_value[identifier];
}
int snd_use_case_set(snd_use_case_mgr_t* uc_mgr,
const char *identifier,
const char *value) {
snd_use_case_set_called++;
snd_use_case_set_param.push_back(
std::make_pair(std::string(identifier), std::string(value)));
return snd_use_case_set_return;;
}
int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
const char *identifier,
const char **list[]) {
*list = fake_list[identifier];
return fake_list_size[identifier];
}
int snd_use_case_free_list(const char *list[], int items) {
snd_use_case_free_list_called++;
return 0;
}
} /* extern "C" */
} // namespace
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}