• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2021 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 <gtest/gtest.h>
7 
8 extern "C" {
9 #include "cras_client.c"
10 #include "cras_client.h"
11 
libcras_unsupported_func(struct libcras_client * client)12 inline int libcras_unsupported_func(struct libcras_client* client) {
13   CHECK_VERSION(client, INT_MAX);
14   return 0;
15 }
16 
17 cras_stream_id_t cb_stream_id;
18 uint8_t* cb_buf;
19 unsigned int cb_frames;
20 struct timespec cb_latency;
21 void* cb_usr_arg;
22 int get_stream_cb_called;
23 struct timespec now;
24 
get_stream_cb(struct libcras_stream_cb_data * data)25 int get_stream_cb(struct libcras_stream_cb_data* data) {
26   get_stream_cb_called++;
27   EXPECT_NE((void*)NULL, data);
28   EXPECT_EQ(0, libcras_stream_cb_data_get_stream_id(data, &cb_stream_id));
29   EXPECT_EQ(0, libcras_stream_cb_data_get_buf(data, &cb_buf));
30   EXPECT_EQ(0, libcras_stream_cb_data_get_frames(data, &cb_frames));
31   EXPECT_EQ(0, libcras_stream_cb_data_get_latency(data, &cb_latency));
32   EXPECT_EQ(0, libcras_stream_cb_data_get_usr_arg(data, &cb_usr_arg));
33   return 0;
34 }
35 }
36 
37 namespace {
38 class CrasAbiTestSuite : public testing::Test {
39  protected:
InitShm(int frames)40   struct cras_audio_shm* InitShm(int frames) {
41     struct cras_audio_shm* shm =
42         static_cast<struct cras_audio_shm*>(calloc(1, sizeof(*shm)));
43     shm->header =
44         static_cast<cras_audio_shm_header*>(calloc(1, sizeof(*shm->header)));
45     cras_shm_set_frame_bytes(shm, 4);
46     uint32_t used_size = frames * 4;
47     cras_shm_set_used_size(shm, used_size);
48     shm->samples_info.length = used_size * 2;
49     memcpy(&shm->header->config, &shm->config, sizeof(shm->config));
50     return shm;
51   }
52 
DestroyShm(struct cras_audio_shm * shm)53   void DestroyShm(struct cras_audio_shm* shm) {
54     if (shm)
55       free(shm->header);
56     free(shm);
57   }
58 
SetUp()59   virtual void SetUp() { get_stream_cb_called = 0; }
60 };
61 
TEST_F(CrasAbiTestSuite,CheckUnsupportedFunction)62 TEST_F(CrasAbiTestSuite, CheckUnsupportedFunction) {
63   auto* client = libcras_client_create();
64   EXPECT_NE((void*)NULL, client);
65   EXPECT_EQ(-ENOSYS, libcras_unsupported_func(client));
66   libcras_client_destroy(client);
67 }
68 
TEST_F(CrasAbiTestSuite,BasicStream)69 TEST_F(CrasAbiTestSuite, BasicStream) {
70   auto* client = libcras_client_create();
71   EXPECT_NE((void*)NULL, client);
72   auto* stream = libcras_stream_params_create();
73   EXPECT_NE((void*)NULL, stream);
74   /* Returns timeout because there is no real CRAS server in unittest. */
75   EXPECT_EQ(-ETIMEDOUT, libcras_client_connect_timeout(client, 0));
76   EXPECT_EQ(0, libcras_client_run_thread(client));
77   EXPECT_EQ(0, libcras_stream_params_set(stream, CRAS_STREAM_INPUT, 480, 480,
78                                          CRAS_STREAM_TYPE_DEFAULT,
79                                          CRAS_CLIENT_TYPE_TEST, 0, NULL, NULL,
80                                          NULL, 48000, SND_PCM_FORMAT_S16, 2));
81   cras_stream_id_t id;
82   /* Fails to add a stream because the stream callback is not set. */
83   EXPECT_EQ(-EINVAL, libcras_client_add_pinned_stream(client, 0, &id, stream));
84   /* Fails to set a stream volume because the stream is not added. */
85   EXPECT_EQ(-EINVAL, libcras_client_set_stream_volume(client, id, 1.0));
86   EXPECT_EQ(0, libcras_client_rm_stream(client, id));
87   EXPECT_EQ(0, libcras_client_stop(client));
88   libcras_stream_params_destroy(stream);
89   libcras_client_destroy(client);
90 }
91 
TEST_F(CrasAbiTestSuite,StreamCallback)92 TEST_F(CrasAbiTestSuite, StreamCallback) {
93   struct client_stream stream;
94   struct cras_stream_params params;
95   stream.id = 0x123;
96   stream.direction = CRAS_STREAM_INPUT;
97   stream.flags = 0;
98   stream.config = &params;
99   params.stream_cb = get_stream_cb;
100   params.cb_threshold = 480;
101   params.user_data = (void*)0x321;
102   stream.shm = InitShm(960);
103   stream.shm->header->write_offset[0] = 960 * 4;
104   stream.shm->header->write_buf_idx = 0;
105   stream.shm->header->read_offset[0] = 0;
106   stream.shm->header->read_buf_idx = 0;
107   now.tv_sec = 100;
108   now.tv_nsec = 0;
109   stream.shm->header->ts.tv_sec = 90;
110   stream.shm->header->ts.tv_nsec = 0;
111 
112   handle_capture_data_ready(&stream, 480);
113 
114   EXPECT_EQ(1, get_stream_cb_called);
115   EXPECT_EQ(stream.id, cb_stream_id);
116   EXPECT_EQ(cras_shm_get_write_buffer_base(stream.shm), cb_buf);
117   EXPECT_EQ(480, cb_frames);
118   EXPECT_EQ(10, cb_latency.tv_sec);
119   EXPECT_EQ(0, cb_latency.tv_nsec);
120   EXPECT_EQ((void*)0x321, cb_usr_arg);
121 
122   DestroyShm(stream.shm);
123 }
124 
125 }  // namespace
126 
127 extern "C" {
128 
clock_gettime(clockid_t clk_id,struct timespec * tp)129 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
130   *tp = now;
131   return 0;
132 }
133 }
134 
main(int argc,char ** argv)135 int main(int argc, char** argv) {
136   ::testing::InitGoogleTest(&argc, argv);
137   openlog(NULL, LOG_PERROR, LOG_USER);
138   return RUN_ALL_TESTS();
139 }
140