diff options
Diffstat (limited to 'cras/src/tests/cras_client_unittest.cc')
-rw-r--r-- | cras/src/tests/cras_client_unittest.cc | 432 |
1 files changed, 0 insertions, 432 deletions
diff --git a/cras/src/tests/cras_client_unittest.cc b/cras/src/tests/cras_client_unittest.cc deleted file mode 100644 index c1103afb..00000000 --- a/cras/src/tests/cras_client_unittest.cc +++ /dev/null @@ -1,432 +0,0 @@ -// 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 <gtest/gtest.h> -#include <stdio.h> - -extern "C" { -#include "cras_messages.h" - -// Include C file to test static functions. -#include "cras_client.c" -} - -static const cras_stream_id_t FIRST_STREAM_ID = 1; - -static int pthread_create_called; -static int pthread_join_called; -static int pthread_cond_timedwait_called; -static int pthread_cond_timedwait_retval; -static int close_called; -static int sendmsg_called; -static void* mmap_return_value; -static int samples_ready_called; -static int samples_ready_frames_value; -static uint8_t* samples_ready_samples_value; - -static int pthread_create_returned_value; - -namespace { - -void InitStaticVariables() { - pthread_create_called = 0; - pthread_join_called = 0; - pthread_cond_timedwait_called = 0; - pthread_cond_timedwait_retval = 0; - close_called = 0; - sendmsg_called = 0; - pthread_create_returned_value = 0; - mmap_return_value = NULL; - samples_ready_called = 0; - samples_ready_frames_value = 0; -} - -class CrasClientTestSuite : public testing::Test { - protected: - struct cras_audio_shm* InitShm() { - struct cras_audio_shm* shm = - static_cast<struct cras_audio_shm*>(calloc(1, sizeof(*shm))); - shm->header = - static_cast<cras_audio_shm_header*>(calloc(1, sizeof(*shm->header))); - cras_shm_set_frame_bytes(shm, 4); - uint32_t used_size = shm_writable_frames_ * 4; - cras_shm_set_used_size(shm, used_size); - shm->samples_info.length = used_size * 2; - memcpy(&shm->header->config, &shm->config, sizeof(shm->config)); - return shm; - } - - virtual void SetUp() { - shm_writable_frames_ = 100; - InitStaticVariables(); - - memset(&client_, 0, sizeof(client_)); - client_.server_fd_state = CRAS_SOCKET_STATE_CONNECTED; - memset(&stream_, 0, sizeof(stream_)); - stream_.id = FIRST_STREAM_ID; - - struct cras_stream_params* config = - static_cast<cras_stream_params*>(calloc(1, sizeof(*config))); - config->buffer_frames = 1024; - config->cb_threshold = 512; - stream_.config = config; - } - - virtual void TearDown() { - if (stream_.config) { - free(stream_.config); - stream_.config = NULL; - } - - if (stream_.shm) { - free(stream_.shm->header); - } - free(stream_.shm); - stream_.shm = NULL; - } - - void StreamConnected(CRAS_STREAM_DIRECTION direction); - - void StreamConnectedFail(CRAS_STREAM_DIRECTION direction); - - struct client_stream stream_; - struct cras_client client_; - int shm_writable_frames_; -}; - -void set_audio_format(struct cras_audio_format* format, - snd_pcm_format_t pcm_format, - size_t frame_rate, - size_t num_channels) { - format->format = pcm_format; - format->frame_rate = frame_rate; - format->num_channels = num_channels; - for (size_t i = 0; i < CRAS_CH_MAX; ++i) - format->channel_layout[i] = i < num_channels ? i : -1; -} - -int capture_samples_ready(cras_client* client, - cras_stream_id_t stream_id, - uint8_t* samples, - size_t frames, - const timespec* sample_ts, - void* arg) { - samples_ready_called++; - samples_ready_samples_value = samples; - samples_ready_frames_value = frames; - return frames; -} - -TEST_F(CrasClientTestSuite, HandleCaptureDataReady) { - struct cras_audio_shm* shm; - - stream_.direction = CRAS_STREAM_INPUT; - - shm_writable_frames_ = 480; - shm = InitShm(); - stream_.shm = shm; - stream_.config->buffer_frames = 480; - stream_.config->cb_threshold = 480; - stream_.config->aud_cb = capture_samples_ready; - stream_.config->unified_cb = 0; - - shm->header->write_buf_idx = 0; - shm->header->read_buf_idx = 0; - shm->header->write_offset[0] = 480 * 4; - shm->header->read_offset[0] = 0; - - /* Normal scenario: read buffer has full of data written, - * handle_capture_data_ready() should consume all 480 frames and move - * read_buf_idx to the next buffer. */ - handle_capture_data_ready(&stream_, 480); - EXPECT_EQ(1, samples_ready_called); - EXPECT_EQ(480, samples_ready_frames_value); - EXPECT_EQ(cras_shm_buff_for_idx(shm, 0), samples_ready_samples_value); - EXPECT_EQ(1, shm->header->read_buf_idx); - EXPECT_EQ(0, shm->header->write_offset[0]); - EXPECT_EQ(0, shm->header->read_offset[0]); - - /* At the beginning of overrun: handle_capture_data_ready() should not - * proceed to call audio_cb because there's no data captured. */ - shm->header->read_buf_idx = 0; - shm->header->write_offset[0] = 0; - shm->header->read_offset[0] = 0; - handle_capture_data_ready(&stream_, 480); - EXPECT_EQ(1, samples_ready_called); - EXPECT_EQ(0, shm->header->read_buf_idx); - - /* In the middle of overrun: partially written buffer should trigger - * audio_cb, feed the full-sized read buffer to client. */ - shm->header->read_buf_idx = 0; - shm->header->write_offset[0] = 123; - shm->header->read_offset[0] = 0; - handle_capture_data_ready(&stream_, 480); - EXPECT_EQ(1, samples_ready_called); - EXPECT_EQ(0, shm->header->read_buf_idx); -} - -void CrasClientTestSuite::StreamConnected(CRAS_STREAM_DIRECTION direction) { - struct cras_client_stream_connected msg; - int shm_fds[2] = {0, 1}; - int shm_max_size = 600; - size_t format_bytes; - size_t effects = 123; - struct cras_audio_shm_header* header; - - stream_.direction = direction; - set_audio_format(&stream_.config->format, SND_PCM_FORMAT_S16_LE, 48000, 4); - - struct cras_audio_format server_format; - set_audio_format(&server_format, SND_PCM_FORMAT_S16_LE, 44100, 2); - - // Initialize shm area - format_bytes = cras_get_format_bytes(&server_format); - header = (struct cras_audio_shm_header*)calloc(1, sizeof(*header)); - header->config.frame_bytes = format_bytes; - header->config.used_size = shm_writable_frames_ * format_bytes; - - mmap_return_value = header; - - cras_fill_client_stream_connected(&msg, 0, stream_.id, &server_format, - shm_max_size, effects); - - stream_connected(&stream_, &msg, shm_fds, 2); - - EXPECT_EQ(CRAS_THREAD_RUNNING, stream_.thread.state); - EXPECT_EQ(header, stream_.shm->header); -} - -TEST_F(CrasClientTestSuite, InputStreamConnected) { - StreamConnected(CRAS_STREAM_INPUT); -} - -TEST_F(CrasClientTestSuite, OutputStreamConnected) { - StreamConnected(CRAS_STREAM_OUTPUT); -} - -void CrasClientTestSuite::StreamConnectedFail(CRAS_STREAM_DIRECTION direction) { - struct cras_client_stream_connected msg; - int shm_fds[2] = {0, 1}; - int shm_max_size = 600; - size_t format_bytes; - size_t effects = 123; - struct cras_audio_shm_header header; - int rc; - - stream_.direction = direction; - set_audio_format(&stream_.config->format, SND_PCM_FORMAT_S16_LE, 48000, 4); - - struct cras_audio_format server_format; - set_audio_format(&server_format, SND_PCM_FORMAT_S16_LE, 44100, 2); - - // Thread setup - rc = pipe(stream_.wake_fds); - ASSERT_EQ(0, rc); - stream_.thread.state = CRAS_THREAD_WARMUP; - - // Initialize shm area - format_bytes = cras_get_format_bytes(&server_format); - memset(&header, 0, sizeof(header)); - header.config.frame_bytes = format_bytes; - header.config.used_size = shm_writable_frames_ * format_bytes; - - mmap_return_value = &header; - - // Put an error in the message. - cras_fill_client_stream_connected(&msg, 1, stream_.id, &server_format, - shm_max_size, effects); - - stream_connected(&stream_, &msg, shm_fds, 2); - - EXPECT_EQ(CRAS_THREAD_STOP, stream_.thread.state); - EXPECT_EQ(4, close_called); // close the pipefds and shm_fds -} - -TEST_F(CrasClientTestSuite, InputStreamConnectedFail) { - StreamConnectedFail(CRAS_STREAM_INPUT); -} - -TEST_F(CrasClientTestSuite, OutputStreamConnectedFail) { - StreamConnectedFail(CRAS_STREAM_OUTPUT); -} - -TEST_F(CrasClientTestSuite, AddAndRemoveStream) { - cras_stream_id_t stream_id; - struct cras_disconnect_stream_message msg; - int serv_fds[2]; - int rc; - - // Dynamically allocate the stream so that it can be freed later. - struct client_stream* stream_ptr = - (struct client_stream*)malloc(sizeof(*stream_ptr)); - memcpy(stream_ptr, &stream_, sizeof(client_stream)); - - stream_ptr->config = - (struct cras_stream_params*)malloc(sizeof(*(stream_ptr->config))); - memcpy(stream_ptr->config, stream_.config, sizeof(*(stream_.config))); - - stream_ptr->wake_fds[0] = -1; - stream_ptr->wake_fds[1] = -1; - - pthread_cond_timedwait_retval = ETIMEDOUT; - EXPECT_EQ(-ETIMEDOUT, client_thread_add_stream(&client_, stream_ptr, - &stream_id, NO_DEVICE)); - EXPECT_EQ(pthread_cond_timedwait_called, 1); - EXPECT_EQ(pthread_join_called, 0); - - InitStaticVariables(); - EXPECT_EQ( - 0, client_thread_add_stream(&client_, stream_ptr, &stream_id, NO_DEVICE)); - EXPECT_EQ(&client_, stream_ptr->client); - EXPECT_EQ(stream_id, stream_ptr->id); - EXPECT_EQ(pthread_create_called, 1); - EXPECT_NE(-1, stream_ptr->wake_fds[0]); - EXPECT_NE(-1, stream_ptr->wake_fds[1]); - EXPECT_EQ(1, sendmsg_called); // send connect message to server - EXPECT_EQ(stream_ptr, stream_from_id(&client_, stream_id)); - - stream_ptr->thread.state = CRAS_THREAD_RUNNING; - - rc = pipe(serv_fds); - EXPECT_EQ(0, rc); - client_.server_fd = serv_fds[1]; - client_.server_fd_state = CRAS_SOCKET_STATE_CONNECTED; - EXPECT_EQ(0, client_thread_rm_stream(&client_, stream_id)); - - rc = read(serv_fds[0], &msg, sizeof(msg)); - EXPECT_EQ(sizeof(msg), rc); - EXPECT_EQ(stream_id, msg.stream_id); - EXPECT_EQ(1, pthread_join_called); - - EXPECT_EQ(NULL, stream_from_id(&client_, stream_id)); -} - -TEST_F(CrasClientTestSuite, SetOutputStreamVolume) { - cras_stream_id_t stream_id; - - client_thread_add_stream(&client_, &stream_, &stream_id, NO_DEVICE); - EXPECT_EQ(&stream_, stream_from_id(&client_, stream_id)); - - /* Set volume before stream connected. */ - client_thread_set_stream_volume(&client_, stream_id, 0.3f); - StreamConnected(CRAS_STREAM_OUTPUT); - EXPECT_EQ(0.3f, cras_shm_get_volume_scaler(stream_.shm)); - - /* Set volume after stream connected. */ - client_thread_set_stream_volume(&client_, stream_id, 0.6f); - EXPECT_EQ(0.6f, cras_shm_get_volume_scaler(stream_.shm)); -} - -TEST_F(CrasClientTestSuite, SetInputStreamVolume) { - cras_stream_id_t stream_id; - - client_thread_add_stream(&client_, &stream_, &stream_id, NO_DEVICE); - EXPECT_EQ(&stream_, stream_from_id(&client_, stream_id)); - - /* Set volume before stream connected. */ - client_thread_set_stream_volume(&client_, stream_id, 0.3f); - StreamConnected(CRAS_STREAM_INPUT); - EXPECT_EQ(0.3f, cras_shm_get_volume_scaler(stream_.shm)); - - /* Set volume after stream connected. */ - client_thread_set_stream_volume(&client_, stream_id, 0.6f); - EXPECT_EQ(0.6f, cras_shm_get_volume_scaler(stream_.shm)); -} - -TEST(CrasClientTest, InitStreamVolume) { - cras_stream_id_t stream_id; - struct cras_stream_params config; - struct add_stream_command_message cmd_msg; - int rc; - struct cras_client client; - - memset(&client, 0, sizeof(client)); - memset(&config, 0, sizeof(config)); - client.server_fd_state = CRAS_SOCKET_STATE_CONNECTED; - - config.aud_cb = reinterpret_cast<cras_playback_cb_t>(0x123); - config.err_cb = reinterpret_cast<cras_error_cb_t>(0x456); - client.thread.state = CRAS_THREAD_RUNNING; - rc = pipe(client.command_reply_fds); - EXPECT_EQ(0, rc); - rc = pipe(client.command_fds); - EXPECT_EQ(0, rc); - - rc = write(client.command_reply_fds[1], &rc, sizeof(rc)); - cras_client_add_stream(&client, &stream_id, &config); - - rc = read(client.command_fds[0], &cmd_msg, sizeof(cmd_msg)); - EXPECT_EQ(sizeof(cmd_msg), rc); - EXPECT_NE((void*)NULL, cmd_msg.stream); - - EXPECT_EQ(1.0f, cmd_msg.stream->volume_scaler); - - if (cmd_msg.stream->config) - free(cmd_msg.stream->config); - free(cmd_msg.stream); -} - -} // namespace - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - -/* stubs */ -extern "C" { - -ssize_t sendmsg(int sockfd, const struct msghdr* msg, int flags) { - ++sendmsg_called; - return msg->msg_iov->iov_len; -} - -int close(int fd) { - ++close_called; - return 0; -} - -int pthread_create(pthread_t* thread, - const pthread_attr_t* attr, - void* (*start_routine)(void*), - void* arg) { - ++pthread_create_called; - return pthread_create_returned_value; -} - -int pthread_join(pthread_t thread, void** retval) { - ++pthread_join_called; - return 0; -} - -int pthread_cond_timedwait(pthread_cond_t* __restrict cond, - pthread_mutex_t* __restrict mutex, - const struct timespec* __restrict timeout) { - ++pthread_cond_timedwait_called; - return pthread_cond_timedwait_retval; -} - -int clock_gettime(clockid_t clk_id, struct timespec* tp) { - tp->tv_sec = 0; - tp->tv_nsec = 0; - return 0; -} - -void* mmap(void* addr, - size_t length, - int prot, - int flags, - int fd, - off_t offset) { - return mmap_return_value; -} - -struct cras_audio_format* cras_audio_format_create(snd_pcm_format_t format, - size_t frame_rate, - size_t num_channels) { - return reinterpret_cast<struct cras_audio_format*>(0x123); -} - -void cras_audio_format_destroy(struct cras_audio_format* fmt) {} -} |