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 <stdio.h>
6 #include <stdlib.h>
7 #include <gtest/gtest.h>
8
9 #include "cras_dsp_ini.h"
10
11 #define FILENAME_TEMPLATE "DspIniTest.XXXXXX"
12
13 namespace {
14
15 class DspIniTestSuite : public testing::Test {
16 protected:
SetUp()17 virtual void SetUp() {
18 strcpy(filename, FILENAME_TEMPLATE);
19 int fd = mkstemp(filename);
20 fp = fdopen(fd, "w");
21 }
22
TearDown()23 virtual void TearDown() {
24 CloseFile();
25 unlink(filename);
26 }
27
CloseFile()28 virtual void CloseFile() {
29 if (fp) {
30 fclose(fp);
31 fp = NULL;
32 }
33 }
34
35 char filename[sizeof(FILENAME_TEMPLATE) + 1];
36 FILE *fp;
37 };
38
TEST_F(DspIniTestSuite,EmptyIni)39 TEST_F(DspIniTestSuite, EmptyIni) {
40 struct ini *ini = cras_dsp_ini_create(filename);
41 EXPECT_EQ(0, ARRAY_COUNT(&ini->plugins));
42 EXPECT_EQ(0, ARRAY_COUNT(&ini->flows));
43 cras_dsp_ini_free(ini);
44 }
45
TEST_F(DspIniTestSuite,NoLibraryOrLabel)46 TEST_F(DspIniTestSuite, NoLibraryOrLabel) {
47 fprintf(fp, "[Test]\n");
48 CloseFile();
49
50 struct ini *ini = cras_dsp_ini_create(filename);
51 /* NULL because a plugin doesn't have library or label */
52 EXPECT_EQ(NULL, ini);
53 }
54
TEST_F(DspIniTestSuite,OneSimplePlugin)55 TEST_F(DspIniTestSuite, OneSimplePlugin) {
56 fprintf(fp, "[Test]\n");
57 fprintf(fp, "library=foo.so\n");
58 fprintf(fp, "label=bar\n");
59 fprintf(fp, "disable=\"#f\"\n");
60 CloseFile();
61
62 struct ini *ini = cras_dsp_ini_create(filename);
63 EXPECT_EQ(1, ARRAY_COUNT(&ini->plugins));
64 EXPECT_EQ(0, ARRAY_COUNT(&ini->flows));
65
66 struct plugin *plugin = ARRAY_ELEMENT(&ini->plugins, 0);
67 EXPECT_STREQ("test", plugin->title);
68 EXPECT_STREQ("foo.so", plugin->library);
69 EXPECT_STREQ("bar", plugin->label);
70 EXPECT_TRUE(plugin->disable_expr);
71 EXPECT_EQ(0, ARRAY_COUNT(&plugin->ports));
72
73 cras_dsp_ini_free(ini);
74 }
75
TEST_F(DspIniTestSuite,BuiltinPlugin)76 TEST_F(DspIniTestSuite, BuiltinPlugin) {
77 fprintf(fp, "[foo]\n");
78 fprintf(fp, "library=builtin\n");
79 fprintf(fp, "label=source\n");
80 fprintf(fp, "purpose=playback\n");
81 fprintf(fp, "[bar]\n");
82 fprintf(fp, "library=builtin\n");
83 fprintf(fp, "label=sink\n");
84 fprintf(fp, "purpose=capture\n");
85 CloseFile();
86
87 struct ini *ini = cras_dsp_ini_create(filename);
88 EXPECT_EQ(2, ARRAY_COUNT(&ini->plugins));
89 EXPECT_EQ(0, ARRAY_COUNT(&ini->flows));
90 EXPECT_STREQ(ARRAY_ELEMENT(&ini->plugins, 0)->purpose, "playback");
91 EXPECT_STREQ(ARRAY_ELEMENT(&ini->plugins, 1)->purpose, "capture");
92 cras_dsp_ini_free(ini);
93 }
94
TEST_F(DspIniTestSuite,Ports)95 TEST_F(DspIniTestSuite, Ports) {
96 fprintf(fp, "[foo]\n");
97 fprintf(fp, "library=bar\n");
98 fprintf(fp, "label=baz\n");
99 fprintf(fp, "input_0=10\n");
100 CloseFile();
101
102 struct ini *ini = cras_dsp_ini_create(filename);
103 EXPECT_EQ(1, ARRAY_COUNT(&ini->plugins));
104 EXPECT_EQ(0, ARRAY_COUNT(&ini->flows));
105 struct plugin *plugin = ARRAY_ELEMENT(&ini->plugins, 0);
106 EXPECT_EQ(1, ARRAY_COUNT(&plugin->ports));
107 struct port *port = ARRAY_ELEMENT(&plugin->ports, 0);
108 EXPECT_EQ(PORT_INPUT, port->direction);
109 EXPECT_EQ(PORT_CONTROL, port->type);
110 EXPECT_EQ(INVALID_FLOW_ID, port->flow_id);
111 EXPECT_EQ(10, port->init_value);
112 cras_dsp_ini_free(ini);
113 }
114
TEST_F(DspIniTestSuite,Flows)115 TEST_F(DspIniTestSuite, Flows) {
116 fprintf(fp, "[foo]\n");
117 fprintf(fp, "library=foo\n");
118 fprintf(fp, "label=foo\n");
119 fprintf(fp, "output_0=<control>\n");
120 fprintf(fp, "output_1={audio}\n");
121 fprintf(fp, "[bar]\n");
122 fprintf(fp, "library=bar\n");
123 fprintf(fp, "label=bar\n");
124 fprintf(fp, "input_0={audio}\n");
125 fprintf(fp, "input_1=<control>\n");
126
127 CloseFile();
128
129 struct ini *ini = cras_dsp_ini_create(filename);
130 EXPECT_EQ(2, ARRAY_COUNT(&ini->plugins));
131 struct plugin *foo = ARRAY_ELEMENT(&ini->plugins, 0);
132 struct plugin *bar = ARRAY_ELEMENT(&ini->plugins, 1);
133 EXPECT_EQ(2, ARRAY_COUNT(&foo->ports));
134 EXPECT_EQ(2, ARRAY_COUNT(&bar->ports));
135
136 struct port *foo0 = ARRAY_ELEMENT(&foo->ports, 0);
137 struct port *foo1 = ARRAY_ELEMENT(&foo->ports, 1);
138 EXPECT_EQ(PORT_OUTPUT, foo0->direction);
139 EXPECT_EQ(PORT_CONTROL, foo0->type);
140 EXPECT_EQ(PORT_OUTPUT, foo1->direction);
141 EXPECT_EQ(PORT_AUDIO, foo1->type);
142 EXPECT_EQ(0, foo0->flow_id);
143 EXPECT_EQ(1, foo1->flow_id);
144
145 struct port *bar0 = ARRAY_ELEMENT(&bar->ports, 0);
146 struct port *bar1 = ARRAY_ELEMENT(&bar->ports, 1);
147 EXPECT_EQ(PORT_INPUT, bar0->direction);
148 EXPECT_EQ(PORT_AUDIO, bar0->type);
149 EXPECT_EQ(PORT_INPUT, bar1->direction);
150 EXPECT_EQ(PORT_CONTROL, bar1->type);
151 EXPECT_EQ(1, bar0->flow_id);
152 EXPECT_EQ(0, bar1->flow_id);
153
154 EXPECT_EQ(2, ARRAY_COUNT(&ini->flows));
155 struct flow *flow0 = ARRAY_ELEMENT(&ini->flows, 0);
156 struct flow *flow1 = ARRAY_ELEMENT(&ini->flows, 1);
157
158 EXPECT_EQ(PORT_CONTROL, flow0->type);
159 EXPECT_STREQ("<control>", flow0->name);
160
161 EXPECT_EQ(PORT_AUDIO, flow1->type);
162 EXPECT_STREQ("{audio}", flow1->name);
163
164 EXPECT_EQ(flow0->from, foo);
165 EXPECT_EQ(flow0->to, bar);
166 EXPECT_EQ(flow0->from_port, 0);
167 EXPECT_EQ(flow0->to_port, 1);
168
169 EXPECT_EQ(flow1->from, foo);
170 EXPECT_EQ(flow1->to, bar);
171 EXPECT_EQ(flow1->from_port, 1);
172 EXPECT_EQ(flow1->to_port, 0);
173
174 cras_dsp_ini_free(ini);
175 }
176
TEST_F(DspIniTestSuite,TwoChannelWithSwap)177 TEST_F(DspIniTestSuite, TwoChannelWithSwap) {
178
179 /*
180 * Stated in ini:
181 *
182 * m0 ==(a0, a1)== m1 ==(b0, b1)== m2
183 *
184 * After inserting swap_lr plugin:
185 *
186 * m0 ==(a0, a1)== m1 ==(b0, b1)== m_swap_lr ==(swap_lr_0, swap_lr_1)== m2
187 *
188 */
189
190 const char *content =
191 "[M0]\n"
192 "library=builtin\n"
193 "label=source\n"
194 "purpose=playback\n"
195 "output_0={a0}\n"
196 "output_1={a1}\n"
197 "[M1]\n"
198 "library=builtin\n"
199 "label=foo\n"
200 "purpose=playback\n"
201 "input_0={a0}\n"
202 "input_1={a1}\n"
203 "output_2={b0}\n"
204 "output_3={b1}\n"
205 "[M2]\n"
206 "library=builtin\n"
207 "label=sink\n"
208 "purpose=playback\n"
209 "input_0={b0}\n"
210 "input_1={b1}\n";
211 fprintf(fp, "%s", content);
212 CloseFile();
213
214 struct ini *ini = cras_dsp_ini_create(filename);
215
216 /* 3 plugins and 1 swap_lr plugin. */
217 EXPECT_EQ(4, ARRAY_COUNT(&ini->plugins));
218
219 struct plugin *m0= ARRAY_ELEMENT(&ini->plugins, 0);
220 struct plugin *m1 = ARRAY_ELEMENT(&ini->plugins, 1);
221 struct plugin *m2 = ARRAY_ELEMENT(&ini->plugins, 2);
222 struct plugin *m_swap_lr = ARRAY_ELEMENT(&ini->plugins, 3);
223
224 EXPECT_EQ(2, ARRAY_COUNT(&m0->ports));
225 EXPECT_EQ(4, ARRAY_COUNT(&m1->ports));
226 EXPECT_EQ(4, ARRAY_COUNT(&m_swap_lr->ports));
227 EXPECT_EQ(2, ARRAY_COUNT(&m2->ports));
228
229 struct port *m0_0 = ARRAY_ELEMENT(&m0->ports, 0);
230 struct port *m0_1 = ARRAY_ELEMENT(&m0->ports, 1);
231 struct port *m1_0 = ARRAY_ELEMENT(&m1->ports, 0);
232 struct port *m1_1 = ARRAY_ELEMENT(&m1->ports, 1);
233 struct port *m1_2 = ARRAY_ELEMENT(&m1->ports, 2);
234 struct port *m1_3 = ARRAY_ELEMENT(&m1->ports, 3);
235 struct port *m_swap_lr_0 = ARRAY_ELEMENT(&m_swap_lr->ports, 0);
236 struct port *m_swap_lr_1 = ARRAY_ELEMENT(&m_swap_lr->ports, 1);
237 struct port *m_swap_lr_2 = ARRAY_ELEMENT(&m_swap_lr->ports, 2);
238 struct port *m_swap_lr_3 = ARRAY_ELEMENT(&m_swap_lr->ports, 3);
239 struct port *m2_0 = ARRAY_ELEMENT(&m2->ports, 0);
240 struct port *m2_1 = ARRAY_ELEMENT(&m2->ports, 1);
241
242 /* flow flow_id from port to port
243 * ------------------------------------------------------------
244 * a0 0 m0_0 m1_0
245 * a1 1 m0_1 m1_1
246 * b0 2 m1_2 m_swap_lr_0
247 * b1 3 m1_3 m_swap_lr_1
248 * swap_lr_0 4 m_swap_lr_2 m2_0
249 * swap_lr_1 5 m_swap_lr_3 m2_1
250 */
251 EXPECT_EQ(0, m0_0->flow_id);
252 EXPECT_EQ(1, m0_1->flow_id);
253 EXPECT_EQ(0, m1_0->flow_id);
254 EXPECT_EQ(1, m1_1->flow_id);
255 EXPECT_EQ(2, m1_2->flow_id);
256 EXPECT_EQ(3, m1_3->flow_id);
257 EXPECT_EQ(2, m_swap_lr_0->flow_id);
258 EXPECT_EQ(3, m_swap_lr_1->flow_id);
259 EXPECT_EQ(4, m_swap_lr_2->flow_id);
260 EXPECT_EQ(5, m_swap_lr_3->flow_id);
261 EXPECT_EQ(4, m2_0->flow_id);
262 EXPECT_EQ(5, m2_1->flow_id);
263
264 struct flow *flow_a0 = ARRAY_ELEMENT(&ini->flows, 0);
265 struct flow *flow_a1 = ARRAY_ELEMENT(&ini->flows, 1);
266 struct flow *flow_b0 = ARRAY_ELEMENT(&ini->flows, 2);
267 struct flow *flow_b1 = ARRAY_ELEMENT(&ini->flows, 3);
268 struct flow *flow_swap_lr_0 = ARRAY_ELEMENT(&ini->flows, 4);
269 struct flow *flow_swap_lr_1 = ARRAY_ELEMENT(&ini->flows, 5);
270
271 EXPECT_EQ(flow_a0->from, m0);
272 EXPECT_EQ(flow_a0->from_port, 0);
273 EXPECT_EQ(flow_a0->to, m1);
274 EXPECT_EQ(flow_a0->to_port, 0);
275
276 EXPECT_EQ(flow_a1->from, m0);
277 EXPECT_EQ(flow_a1->from_port, 1);
278 EXPECT_EQ(flow_a1->to, m1);
279 EXPECT_EQ(flow_a1->to_port, 1);
280
281 EXPECT_EQ(flow_b0->from, m1);
282 EXPECT_EQ(flow_b0->from_port, 2);
283 EXPECT_EQ(flow_b0->to, m_swap_lr);
284 EXPECT_EQ(flow_b0->to_port, 0);
285
286 EXPECT_EQ(flow_b1->from, m1);
287 EXPECT_EQ(flow_b1->from_port, 3);
288 EXPECT_EQ(flow_b1->to, m_swap_lr);
289 EXPECT_EQ(flow_b1->to_port, 1);
290
291 EXPECT_EQ(flow_swap_lr_0->from, m_swap_lr);
292 EXPECT_EQ(flow_swap_lr_0->from_port, 2);
293 EXPECT_EQ(flow_swap_lr_0->to, m2);
294 EXPECT_EQ(flow_swap_lr_0->to_port, 0);
295
296 EXPECT_EQ(flow_swap_lr_1->from, m_swap_lr);
297 EXPECT_EQ(flow_swap_lr_1->from_port, 3);
298 EXPECT_EQ(flow_swap_lr_1->to, m2);
299 EXPECT_EQ(flow_swap_lr_1->to_port, 1);
300
301 cras_dsp_ini_free(ini);
302 }
303
304 } // namespace
305
main(int argc,char ** argv)306 int main(int argc, char **argv) {
307 ::testing::InitGoogleTest(&argc, argv);
308 return RUN_ALL_TESTS();
309 }
310