• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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