1 // Copyright 2016 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 <gtest/gtest.h>
6 #include <stdio.h>
7
8 #include <vector>
9
10 extern "C" {
11 #include "cras_main_message.h"
12 #include "cras_rstream.h"
13 #include "cras_server_metrics.c"
14 }
15
16 static enum CRAS_MAIN_MESSAGE_TYPE type_set;
17 static struct timespec clock_gettime_retspec;
18 std::vector<struct cras_server_metrics_message> sent_msgs;
19
ResetStubData()20 void ResetStubData() {
21 type_set = (enum CRAS_MAIN_MESSAGE_TYPE)0;
22 sent_msgs.clear();
23 }
24
25 namespace {
26
TEST(ServerMetricsTestSuite,Init)27 TEST(ServerMetricsTestSuite, Init) {
28 ResetStubData();
29
30 cras_server_metrics_init();
31
32 EXPECT_EQ(type_set, CRAS_MAIN_METRICS);
33 }
34
TEST(ServerMetricsTestSuite,SetMetricsDeviceRuntime)35 TEST(ServerMetricsTestSuite, SetMetricsDeviceRuntime) {
36 ResetStubData();
37 struct cras_iodev iodev;
38 struct cras_ionode active_node;
39
40 clock_gettime_retspec.tv_sec = 200;
41 clock_gettime_retspec.tv_nsec = 0;
42 iodev.info.idx = MAX_SPECIAL_DEVICE_IDX;
43 iodev.open_ts.tv_sec = 100;
44 iodev.open_ts.tv_nsec = 0;
45 iodev.direction = CRAS_STREAM_INPUT;
46 iodev.active_node = &active_node;
47 active_node.type = CRAS_NODE_TYPE_USB;
48
49 cras_server_metrics_device_runtime(&iodev);
50
51 EXPECT_EQ(sent_msgs.size(), 1);
52 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
53 EXPECT_EQ(sent_msgs[0].header.length,
54 sizeof(struct cras_server_metrics_message));
55 EXPECT_EQ(sent_msgs[0].metrics_type, DEVICE_RUNTIME);
56 EXPECT_EQ(sent_msgs[0].data.device_data.type, CRAS_METRICS_DEVICE_USB);
57 EXPECT_EQ(sent_msgs[0].data.device_data.direction, CRAS_STREAM_INPUT);
58 EXPECT_EQ(sent_msgs[0].data.device_data.runtime.tv_sec, 100);
59
60 sent_msgs.clear();
61
62 clock_gettime_retspec.tv_sec = 300;
63 clock_gettime_retspec.tv_nsec = 0;
64 iodev.open_ts.tv_sec = 100;
65 iodev.open_ts.tv_nsec = 0;
66 iodev.direction = CRAS_STREAM_OUTPUT;
67 iodev.active_node = &active_node;
68 active_node.type = CRAS_NODE_TYPE_HEADPHONE;
69
70 cras_server_metrics_device_runtime(&iodev);
71
72 EXPECT_EQ(sent_msgs.size(), 1);
73 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
74 EXPECT_EQ(sent_msgs[0].header.length,
75 sizeof(struct cras_server_metrics_message));
76 EXPECT_EQ(sent_msgs[0].metrics_type, DEVICE_RUNTIME);
77 EXPECT_EQ(sent_msgs[0].data.device_data.type, CRAS_METRICS_DEVICE_HEADPHONE);
78 EXPECT_EQ(sent_msgs[0].data.device_data.direction, CRAS_STREAM_OUTPUT);
79 EXPECT_EQ(sent_msgs[0].data.device_data.runtime.tv_sec, 200);
80 }
81
TEST(ServerMetricsTestSuite,SetMetricsHighestDeviceDelay)82 TEST(ServerMetricsTestSuite, SetMetricsHighestDeviceDelay) {
83 ResetStubData();
84 unsigned int hw_level = 1000;
85 unsigned int largest_cb_level = 500;
86
87 cras_server_metrics_highest_device_delay(hw_level, largest_cb_level,
88 CRAS_STREAM_INPUT);
89
90 EXPECT_EQ(sent_msgs.size(), 1);
91 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
92 EXPECT_EQ(sent_msgs[0].header.length,
93 sizeof(struct cras_server_metrics_message));
94 EXPECT_EQ(sent_msgs[0].metrics_type, HIGHEST_DEVICE_DELAY_INPUT);
95 EXPECT_EQ(sent_msgs[0].data.value, 2000);
96
97 sent_msgs.clear();
98
99 cras_server_metrics_highest_device_delay(hw_level, largest_cb_level,
100 CRAS_STREAM_OUTPUT);
101
102 EXPECT_EQ(sent_msgs.size(), 1);
103 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
104 EXPECT_EQ(sent_msgs[0].header.length,
105 sizeof(struct cras_server_metrics_message));
106 EXPECT_EQ(sent_msgs[0].metrics_type, HIGHEST_DEVICE_DELAY_OUTPUT);
107 EXPECT_EQ(sent_msgs[0].data.value, 2000);
108 }
109
TEST(ServerMetricsTestSuite,SetMetricHighestHardwareLevel)110 TEST(ServerMetricsTestSuite, SetMetricHighestHardwareLevel) {
111 ResetStubData();
112 unsigned int hw_level = 1000;
113
114 cras_server_metrics_highest_hw_level(hw_level, CRAS_STREAM_INPUT);
115
116 EXPECT_EQ(sent_msgs.size(), 1);
117 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
118 EXPECT_EQ(sent_msgs[0].header.length,
119 sizeof(struct cras_server_metrics_message));
120 EXPECT_EQ(sent_msgs[0].metrics_type, HIGHEST_INPUT_HW_LEVEL);
121 EXPECT_EQ(sent_msgs[0].data.value, hw_level);
122
123 sent_msgs.clear();
124
125 cras_server_metrics_highest_hw_level(hw_level, CRAS_STREAM_OUTPUT);
126
127 EXPECT_EQ(sent_msgs.size(), 1);
128 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
129 EXPECT_EQ(sent_msgs[0].header.length,
130 sizeof(struct cras_server_metrics_message));
131 EXPECT_EQ(sent_msgs[0].metrics_type, HIGHEST_OUTPUT_HW_LEVEL);
132 EXPECT_EQ(sent_msgs[0].data.value, hw_level);
133 }
134
TEST(ServerMetricsTestSuite,SetMetricsNumUnderruns)135 TEST(ServerMetricsTestSuite, SetMetricsNumUnderruns) {
136 ResetStubData();
137 unsigned int underrun = 10;
138
139 cras_server_metrics_num_underruns(underrun);
140
141 EXPECT_EQ(sent_msgs.size(), 1);
142 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
143 EXPECT_EQ(sent_msgs[0].header.length,
144 sizeof(struct cras_server_metrics_message));
145 EXPECT_EQ(sent_msgs[0].metrics_type, NUM_UNDERRUNS);
146 EXPECT_EQ(sent_msgs[0].data.value, underrun);
147 }
148
TEST(ServerMetricsTestSuite,SetMetricsMissedCallbackEventInputStream)149 TEST(ServerMetricsTestSuite, SetMetricsMissedCallbackEventInputStream) {
150 ResetStubData();
151 struct cras_rstream stream;
152 struct timespec diff_ts;
153
154 stream.flags = 0;
155 stream.start_ts.tv_sec = 0;
156 stream.start_ts.tv_nsec = 0;
157 stream.num_missed_cb = 0;
158 stream.direction = CRAS_STREAM_INPUT;
159
160 clock_gettime_retspec.tv_sec = 100;
161 clock_gettime_retspec.tv_nsec = 0;
162 cras_server_metrics_missed_cb_event(&stream);
163
164 subtract_timespecs(&clock_gettime_retspec, &stream.start_ts, &diff_ts);
165 EXPECT_EQ(sent_msgs.size(), 1);
166 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
167 EXPECT_EQ(sent_msgs[0].header.length,
168 sizeof(struct cras_server_metrics_message));
169 EXPECT_EQ(sent_msgs[0].metrics_type, MISSED_CB_FIRST_TIME_INPUT);
170 EXPECT_EQ(sent_msgs[0].data.value, diff_ts.tv_sec);
171 EXPECT_EQ(stream.num_missed_cb, 1);
172 EXPECT_EQ(stream.first_missed_cb_ts.tv_sec, clock_gettime_retspec.tv_sec);
173 EXPECT_EQ(stream.first_missed_cb_ts.tv_nsec, clock_gettime_retspec.tv_nsec);
174
175 clock_gettime_retspec.tv_sec = 200;
176 clock_gettime_retspec.tv_nsec = 0;
177 cras_server_metrics_missed_cb_event(&stream);
178
179 subtract_timespecs(&clock_gettime_retspec, &stream.first_missed_cb_ts,
180 &diff_ts);
181 EXPECT_EQ(sent_msgs.size(), 2);
182 EXPECT_EQ(sent_msgs[1].header.type, CRAS_MAIN_METRICS);
183 EXPECT_EQ(sent_msgs[1].header.length,
184 sizeof(struct cras_server_metrics_message));
185 EXPECT_EQ(sent_msgs[1].metrics_type, MISSED_CB_SECOND_TIME_INPUT);
186 EXPECT_EQ(sent_msgs[1].data.value, diff_ts.tv_sec);
187 EXPECT_EQ(stream.num_missed_cb, 2);
188 }
189
TEST(ServerMetricsTestSuite,SetMetricsMissedCallbackEventOutputStream)190 TEST(ServerMetricsTestSuite, SetMetricsMissedCallbackEventOutputStream) {
191 ResetStubData();
192 struct cras_rstream stream;
193 struct timespec diff_ts;
194
195 stream.flags = 0;
196 stream.start_ts.tv_sec = 0;
197 stream.start_ts.tv_nsec = 0;
198 stream.num_missed_cb = 0;
199 stream.direction = CRAS_STREAM_OUTPUT;
200
201 clock_gettime_retspec.tv_sec = 100;
202 clock_gettime_retspec.tv_nsec = 0;
203 cras_server_metrics_missed_cb_event(&stream);
204
205 subtract_timespecs(&clock_gettime_retspec, &stream.start_ts, &diff_ts);
206 EXPECT_EQ(sent_msgs.size(), 1);
207 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
208 EXPECT_EQ(sent_msgs[0].header.length,
209 sizeof(struct cras_server_metrics_message));
210 EXPECT_EQ(sent_msgs[0].metrics_type, MISSED_CB_FIRST_TIME_OUTPUT);
211 EXPECT_EQ(sent_msgs[0].data.value, diff_ts.tv_sec);
212 EXPECT_EQ(stream.num_missed_cb, 1);
213 EXPECT_EQ(stream.first_missed_cb_ts.tv_sec, clock_gettime_retspec.tv_sec);
214 EXPECT_EQ(stream.first_missed_cb_ts.tv_nsec, clock_gettime_retspec.tv_nsec);
215
216 clock_gettime_retspec.tv_sec = 200;
217 clock_gettime_retspec.tv_nsec = 0;
218 cras_server_metrics_missed_cb_event(&stream);
219
220 subtract_timespecs(&clock_gettime_retspec, &stream.first_missed_cb_ts,
221 &diff_ts);
222 EXPECT_EQ(sent_msgs.size(), 2);
223 EXPECT_EQ(sent_msgs[1].header.type, CRAS_MAIN_METRICS);
224 EXPECT_EQ(sent_msgs[1].header.length,
225 sizeof(struct cras_server_metrics_message));
226 EXPECT_EQ(sent_msgs[1].metrics_type, MISSED_CB_SECOND_TIME_OUTPUT);
227 EXPECT_EQ(sent_msgs[1].data.value, diff_ts.tv_sec);
228 EXPECT_EQ(stream.num_missed_cb, 2);
229 }
230
TEST(ServerMetricsTestSuite,SetMetricsStreamCreate)231 TEST(ServerMetricsTestSuite, SetMetricsStreamCreate) {
232 ResetStubData();
233 struct cras_rstream_config config;
234 struct cras_audio_format format;
235
236 config.direction = CRAS_STREAM_INPUT;
237 config.cb_threshold = 1024;
238 config.flags = BULK_AUDIO_OK;
239 format.format = SND_PCM_FORMAT_S16_LE;
240 format.frame_rate = 48000;
241 config.client_type = CRAS_CLIENT_TYPE_TEST;
242 config.format = &format;
243 cras_server_metrics_stream_create(&config);
244
245 // Log stream config.
246 EXPECT_EQ(sent_msgs.size(), 1);
247 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
248 EXPECT_EQ(sent_msgs[0].header.length,
249 sizeof(struct cras_server_metrics_message));
250 EXPECT_EQ(sent_msgs[0].metrics_type, STREAM_CONFIG);
251 EXPECT_EQ(sent_msgs[0].data.stream_config.direction, CRAS_STREAM_INPUT);
252 EXPECT_EQ(sent_msgs[0].data.stream_config.cb_threshold, 1024);
253 EXPECT_EQ(sent_msgs[0].data.stream_config.flags, BULK_AUDIO_OK);
254 EXPECT_EQ(sent_msgs[0].data.stream_config.format, SND_PCM_FORMAT_S16_LE);
255 EXPECT_EQ(sent_msgs[0].data.stream_config.rate, 48000);
256 EXPECT_EQ(sent_msgs[0].data.stream_config.client_type, CRAS_CLIENT_TYPE_TEST);
257 }
258
TEST(ServerMetricsTestSuite,SetMetricsStreamDestroy)259 TEST(ServerMetricsTestSuite, SetMetricsStreamDestroy) {
260 ResetStubData();
261 struct cras_rstream stream;
262 struct timespec diff_ts;
263
264 stream.flags = 0;
265 stream.start_ts.tv_sec = 0;
266 stream.start_ts.tv_nsec = 0;
267 clock_gettime_retspec.tv_sec = 1000;
268 clock_gettime_retspec.tv_nsec = 0;
269 stream.num_missed_cb = 5;
270 stream.first_missed_cb_ts.tv_sec = 100;
271 stream.first_missed_cb_ts.tv_nsec = 0;
272 stream.longest_fetch_interval.tv_sec = 1;
273 stream.longest_fetch_interval.tv_nsec = 0;
274 stream.sleep_interval_ts.tv_sec = 0;
275 stream.sleep_interval_ts.tv_nsec = 5000000;
276
277 stream.direction = CRAS_STREAM_INPUT;
278 stream.client_type = CRAS_CLIENT_TYPE_TEST;
279 stream.stream_type = CRAS_STREAM_TYPE_DEFAULT;
280 cras_server_metrics_stream_destroy(&stream);
281
282 subtract_timespecs(&clock_gettime_retspec, &stream.start_ts, &diff_ts);
283 EXPECT_EQ(sent_msgs.size(), 4);
284
285 // Log missed cb frequency.
286 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
287 EXPECT_EQ(sent_msgs[0].header.length,
288 sizeof(struct cras_server_metrics_message));
289 EXPECT_EQ(sent_msgs[0].metrics_type, MISSED_CB_FREQUENCY_INPUT);
290 EXPECT_EQ(sent_msgs[0].data.value,
291 stream.num_missed_cb * 86400 / diff_ts.tv_sec);
292
293 // Log missed cb frequency after rescheduling.
294 subtract_timespecs(&clock_gettime_retspec, &stream.first_missed_cb_ts,
295 &diff_ts);
296 EXPECT_EQ(sent_msgs[1].header.type, CRAS_MAIN_METRICS);
297 EXPECT_EQ(sent_msgs[1].header.length,
298 sizeof(struct cras_server_metrics_message));
299 EXPECT_EQ(sent_msgs[1].metrics_type,
300 MISSED_CB_FREQUENCY_AFTER_RESCHEDULING_INPUT);
301 EXPECT_EQ(sent_msgs[1].data.value,
302 (stream.num_missed_cb - 1) * 86400 / diff_ts.tv_sec);
303
304 // Log stream runtime.
305 EXPECT_EQ(sent_msgs[2].header.type, CRAS_MAIN_METRICS);
306 EXPECT_EQ(sent_msgs[2].header.length,
307 sizeof(struct cras_server_metrics_message));
308 EXPECT_EQ(sent_msgs[2].metrics_type, STREAM_RUNTIME);
309 EXPECT_EQ(sent_msgs[2].data.stream_data.client_type, CRAS_CLIENT_TYPE_TEST);
310 EXPECT_EQ(sent_msgs[2].data.stream_data.stream_type,
311 CRAS_STREAM_TYPE_DEFAULT);
312 EXPECT_EQ(sent_msgs[2].data.stream_data.direction, CRAS_STREAM_INPUT);
313 EXPECT_EQ(sent_msgs[2].data.stream_data.runtime.tv_sec, 1000);
314
315 // Log longest fetch delay.
316 EXPECT_EQ(sent_msgs[3].header.type, CRAS_MAIN_METRICS);
317 EXPECT_EQ(sent_msgs[3].header.length,
318 sizeof(struct cras_server_metrics_message));
319 EXPECT_EQ(sent_msgs[3].metrics_type, LONGEST_FETCH_DELAY);
320 EXPECT_EQ(sent_msgs[3].data.stream_data.client_type, CRAS_CLIENT_TYPE_TEST);
321 EXPECT_EQ(sent_msgs[3].data.stream_data.stream_type,
322 CRAS_STREAM_TYPE_DEFAULT);
323 EXPECT_EQ(sent_msgs[3].data.stream_data.direction, CRAS_STREAM_INPUT);
324 EXPECT_EQ(sent_msgs[3].data.stream_data.runtime.tv_sec, 0);
325 EXPECT_EQ(sent_msgs[3].data.stream_data.runtime.tv_nsec, 995000000);
326 }
327
TEST(ServerMetricsTestSuite,SetMetricsBusyloop)328 TEST(ServerMetricsTestSuite, SetMetricsBusyloop) {
329 ResetStubData();
330 struct timespec time = {40, 0};
331 unsigned count = 3;
332
333 cras_server_metrics_busyloop(&time, count);
334
335 EXPECT_EQ(sent_msgs.size(), 1);
336 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
337 EXPECT_EQ(sent_msgs[0].header.length,
338 sizeof(struct cras_server_metrics_message));
339 EXPECT_EQ(sent_msgs[0].metrics_type, BUSYLOOP);
340 EXPECT_EQ(sent_msgs[0].data.timespec_data.runtime.tv_sec, 40);
341 EXPECT_EQ(sent_msgs[0].data.timespec_data.runtime.tv_nsec, 0);
342 EXPECT_EQ(sent_msgs[0].data.timespec_data.count, 3);
343 }
344
TEST(ServerMetricsTestSuite,SetMetricsBusyloopLength)345 TEST(ServerMetricsTestSuite, SetMetricsBusyloopLength) {
346 ResetStubData();
347 unsigned length = 5;
348
349 cras_server_metrics_busyloop_length(length);
350
351 EXPECT_EQ(sent_msgs.size(), 1);
352 EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
353 EXPECT_EQ(sent_msgs[0].header.length,
354 sizeof(struct cras_server_metrics_message));
355 EXPECT_EQ(sent_msgs[0].metrics_type, BUSYLOOP_LENGTH);
356 EXPECT_EQ(sent_msgs[0].data.value, 5);
357 }
358
359 extern "C" {
360
cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,cras_message_callback callback,void * callback_data)361 int cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,
362 cras_message_callback callback,
363 void* callback_data) {
364 type_set = type;
365 return 0;
366 }
367
cras_metrics_log_histogram(const char * name,int sample,int min,int max,int nbuckets)368 void cras_metrics_log_histogram(const char* name,
369 int sample,
370 int min,
371 int max,
372 int nbuckets) {}
373
cras_metrics_log_sparse_histogram(const char * name,int sample)374 void cras_metrics_log_sparse_histogram(const char* name, int sample) {}
375
cras_main_message_send(struct cras_main_message * msg)376 int cras_main_message_send(struct cras_main_message* msg) {
377 // Copy the sent message so we can examine it in the test later.
378 struct cras_server_metrics_message sent_msg;
379 memcpy(&sent_msg, msg, sizeof(sent_msg));
380 sent_msgs.push_back(sent_msg);
381 return 0;
382 }
383
cras_system_state_in_main_thread()384 int cras_system_state_in_main_thread() {
385 return 0;
386 }
387
388 // From librt.
clock_gettime(clockid_t clk_id,struct timespec * tp)389 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
390 tp->tv_sec = clock_gettime_retspec.tv_sec;
391 tp->tv_nsec = clock_gettime_retspec.tv_nsec;
392 return 0;
393 }
394
395 } // extern "C"
396 } // namespace
397
main(int argc,char ** argv)398 int main(int argc, char** argv) {
399 ::testing::InitGoogleTest(&argc, argv);
400 int rc = RUN_ALL_TESTS();
401
402 return rc;
403 }
404