1 // Copyright (c) 2012 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 #include <fcntl.h>
6 #include <stdio.h>
7 #include <sys/mman.h>
8 #include <sys/types.h>
9 #include <gtest/gtest.h>
10
11 extern "C" {
12 #include "cras_audio_area.h"
13 #include "cras_messages.h"
14 #include "cras_rstream.h"
15 #include "cras_shm.h"
16 }
17
18 namespace {
19
20 class RstreamTestSuite : public testing::Test {
21 protected:
SetUp()22 virtual void SetUp() {
23 fmt_.format = SND_PCM_FORMAT_S16_LE;
24 fmt_.frame_rate = 48000;
25 fmt_.num_channels = 2;
26
27 config_.stream_id = 555;
28 config_.stream_type = CRAS_STREAM_TYPE_DEFAULT;
29 config_.direction = CRAS_STREAM_OUTPUT;
30 config_.dev_idx = NO_DEVICE;
31 config_.flags = 0;
32 config_.format = &fmt_;
33 config_.buffer_frames = 4096;
34 config_.cb_threshold = 2048;
35 config_.audio_fd = 1;
36 config_.client = NULL;
37 }
38
format_equal(cras_audio_format * fmt1,cras_audio_format * fmt2)39 static bool format_equal(cras_audio_format *fmt1, cras_audio_format *fmt2) {
40 return fmt1->format == fmt2->format &&
41 fmt1->frame_rate == fmt2->frame_rate &&
42 fmt1->num_channels == fmt2->num_channels;
43 }
44
45 struct cras_audio_format fmt_;
46 struct cras_rstream_config config_;
47 };
48
TEST_F(RstreamTestSuite,InvalidDirection)49 TEST_F(RstreamTestSuite, InvalidDirection) {
50 struct cras_rstream *s;
51 int rc;
52
53 config_.direction = (enum CRAS_STREAM_DIRECTION)66;
54 rc = cras_rstream_create(&config_, &s);
55 EXPECT_NE(0, rc);
56 }
57
TEST_F(RstreamTestSuite,InvalidStreamType)58 TEST_F(RstreamTestSuite, InvalidStreamType) {
59 struct cras_rstream *s;
60 int rc;
61
62 config_.stream_type = (enum CRAS_STREAM_TYPE)7;
63 rc = cras_rstream_create(&config_, &s);
64 EXPECT_NE(0, rc);
65 }
66
TEST_F(RstreamTestSuite,InvalidBufferSize)67 TEST_F(RstreamTestSuite, InvalidBufferSize) {
68 struct cras_rstream *s;
69 int rc;
70
71 config_.buffer_frames = 3;
72 rc = cras_rstream_create(&config_, &s);
73 EXPECT_NE(0, rc);
74 }
75
TEST_F(RstreamTestSuite,InvalidCallbackThreshold)76 TEST_F(RstreamTestSuite, InvalidCallbackThreshold) {
77 struct cras_rstream *s;
78 int rc;
79
80 config_.cb_threshold = 3;
81 rc = cras_rstream_create(&config_, &s);
82 EXPECT_NE(0, rc);
83 }
84
TEST_F(RstreamTestSuite,InvalidStreamPointer)85 TEST_F(RstreamTestSuite, InvalidStreamPointer) {
86 int rc;
87
88 rc = cras_rstream_create(&config_, NULL);
89 EXPECT_NE(0, rc);
90 }
91
TEST_F(RstreamTestSuite,CreateOutput)92 TEST_F(RstreamTestSuite, CreateOutput) {
93 struct cras_rstream *s;
94 struct cras_audio_format fmt_ret;
95 struct cras_audio_shm *shm_ret;
96 struct cras_audio_shm shm_mapped;
97 int rc, fd_ret;
98 size_t shm_size;
99
100 rc = cras_rstream_create(&config_, &s);
101 EXPECT_EQ(0, rc);
102 EXPECT_NE((void *)NULL, s);
103 EXPECT_EQ(4096, cras_rstream_get_buffer_frames(s));
104 EXPECT_EQ(2048, cras_rstream_get_cb_threshold(s));
105 EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, cras_rstream_get_type(s));
106 EXPECT_EQ(CRAS_STREAM_OUTPUT, cras_rstream_get_direction(s));
107 EXPECT_NE((void *)NULL, cras_rstream_output_shm(s));
108 rc = cras_rstream_get_format(s, &fmt_ret);
109 EXPECT_EQ(0, rc);
110 EXPECT_TRUE(format_equal(&fmt_ret, &fmt_));
111
112 // Check if shm is really set up.
113 shm_ret = cras_rstream_output_shm(s);
114 ASSERT_NE((void *)NULL, shm_ret);
115 fd_ret = cras_rstream_output_shm_fd(s);
116 shm_size = cras_rstream_get_total_shm_size(s);
117 EXPECT_GT(shm_size, 4096);
118 shm_mapped.area = (struct cras_audio_shm_area *)mmap(
119 NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_ret, 0);
120 EXPECT_NE((void *)NULL, shm_mapped.area);
121 cras_shm_copy_shared_config(&shm_mapped);
122 EXPECT_EQ(cras_shm_used_size(&shm_mapped), cras_shm_used_size(shm_ret));
123 munmap(shm_mapped.area, shm_size);
124
125 cras_rstream_destroy(s);
126 }
127
TEST_F(RstreamTestSuite,CreateInput)128 TEST_F(RstreamTestSuite, CreateInput) {
129 struct cras_rstream *s;
130 struct cras_audio_format fmt_ret;
131 struct cras_audio_shm *shm_ret;
132 struct cras_audio_shm shm_mapped;
133 int rc, fd_ret;
134 size_t shm_size;
135
136 config_.direction = CRAS_STREAM_INPUT;
137 rc = cras_rstream_create(&config_, &s);
138 EXPECT_EQ(0, rc);
139 EXPECT_NE((void *)NULL, s);
140 EXPECT_EQ(4096, cras_rstream_get_buffer_frames(s));
141 EXPECT_EQ(2048, cras_rstream_get_cb_threshold(s));
142 EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, cras_rstream_get_type(s));
143 EXPECT_EQ(CRAS_STREAM_INPUT, cras_rstream_get_direction(s));
144 EXPECT_NE((void *)NULL, cras_rstream_input_shm(s));
145 rc = cras_rstream_get_format(s, &fmt_ret);
146 EXPECT_EQ(0, rc);
147 EXPECT_TRUE(format_equal(&fmt_ret, &fmt_));
148
149 // Check if shm is really set up.
150 shm_ret = cras_rstream_input_shm(s);
151 ASSERT_NE((void *)NULL, shm_ret);
152 fd_ret = cras_rstream_input_shm_fd(s);
153 shm_size = cras_rstream_get_total_shm_size(s);
154 EXPECT_GT(shm_size, 4096);
155 shm_mapped.area = (struct cras_audio_shm_area *)mmap(
156 NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_ret, 0);
157 EXPECT_NE((void *)NULL, shm_mapped.area);
158 cras_shm_copy_shared_config(&shm_mapped);
159 EXPECT_EQ(cras_shm_used_size(&shm_mapped), cras_shm_used_size(shm_ret));
160 munmap(shm_mapped.area, shm_size);
161
162 cras_rstream_destroy(s);
163 }
164
TEST_F(RstreamTestSuite,VerifyStreamTypes)165 TEST_F(RstreamTestSuite, VerifyStreamTypes) {
166 struct cras_rstream *s;
167 int rc;
168
169 config_.stream_type = CRAS_STREAM_TYPE_DEFAULT;
170 rc = cras_rstream_create(&config_, &s);
171 EXPECT_EQ(0, rc);
172 EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, cras_rstream_get_type(s));
173 EXPECT_NE(CRAS_STREAM_TYPE_MULTIMEDIA, cras_rstream_get_type(s));
174 cras_rstream_destroy(s);
175
176 config_.stream_type = CRAS_STREAM_TYPE_VOICE_COMMUNICATION;
177 rc = cras_rstream_create(&config_, &s);
178 EXPECT_EQ(0, rc);
179 EXPECT_EQ(CRAS_STREAM_TYPE_VOICE_COMMUNICATION, cras_rstream_get_type(s));
180 cras_rstream_destroy(s);
181
182 config_.direction = CRAS_STREAM_INPUT;
183 config_.stream_type = CRAS_STREAM_TYPE_SPEECH_RECOGNITION;
184 rc = cras_rstream_create(&config_, &s);
185 EXPECT_EQ(0, rc);
186 EXPECT_EQ(CRAS_STREAM_TYPE_SPEECH_RECOGNITION, cras_rstream_get_type(s));
187 cras_rstream_destroy(s);
188
189 config_.stream_type = CRAS_STREAM_TYPE_PRO_AUDIO;
190 rc = cras_rstream_create(&config_, &s);
191 EXPECT_EQ(0, rc);
192 EXPECT_EQ(CRAS_STREAM_TYPE_PRO_AUDIO, cras_rstream_get_type(s));
193 cras_rstream_destroy(s);
194 }
195
196 } // namespace
197
main(int argc,char ** argv)198 int main(int argc, char **argv) {
199 ::testing::InitGoogleTest(&argc, argv);
200 return RUN_ALL_TESTS();
201 }
202
203 /* stubs */
204 extern "C" {
205
cras_audio_area_create(int num_channels)206 struct cras_audio_area *cras_audio_area_create(int num_channels) {
207 return NULL;
208 }
209
cras_audio_area_destroy(struct cras_audio_area * area)210 void cras_audio_area_destroy(struct cras_audio_area *area) {
211 }
212
cras_audio_area_config_channels(struct cras_audio_area * area,const struct cras_audio_format * fmt)213 void cras_audio_area_config_channels(struct cras_audio_area *area,
214 const struct cras_audio_format *fmt) {
215 }
216
buffer_share_create(unsigned int buf_sz)217 struct buffer_share *buffer_share_create(unsigned int buf_sz) {
218 return NULL;
219 }
220
buffer_share_destroy(struct buffer_share * mix)221 void buffer_share_destroy(struct buffer_share *mix) {
222 }
223
buffer_share_offset_update(struct buffer_share * mix,unsigned int id,unsigned int frames)224 int buffer_share_offset_update(struct buffer_share *mix, unsigned int id,
225 unsigned int frames) {
226 return 0;
227 }
228
buffer_share_get_new_write_point(struct buffer_share * mix)229 unsigned int buffer_share_get_new_write_point(struct buffer_share *mix) {
230 return 0;
231 }
232
buffer_share_add_id(struct buffer_share * mix,unsigned int id)233 int buffer_share_add_id(struct buffer_share *mix, unsigned int id) {
234 return 0;
235 }
236
buffer_share_rm_id(struct buffer_share * mix,unsigned int id)237 int buffer_share_rm_id(struct buffer_share *mix, unsigned int id) {
238 return 0;
239 }
240
buffer_share_id_offset(const struct buffer_share * mix,unsigned int id)241 unsigned int buffer_share_id_offset(const struct buffer_share *mix,
242 unsigned int id)
243 {
244 return 0;
245 }
246
cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction)247 void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction) {
248 }
249
cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction)250 void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction) {
251 }
252
253 }
254