• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gtest/gtest.h>
6 #include <sys/socket.h>
7 #include <sys/types.h>
8 #include <unistd.h>
9 
10 #include <string>
11 #include <vector>
12 
13 #include "cras_util.h"
14 
15 namespace {
16 
17 static std::vector<struct timespec> time_now;
18 
TEST(Util,SendRecvTwoFileDescriptors)19 TEST(Util, SendRecvTwoFileDescriptors) {
20   int fd[2];
21   int fd2[2];
22   int send_fds[2];
23   int sock[2];
24   char buf[256] = {0};
25   int new_fds[2];
26   char msg[] = "multi-fd";
27   unsigned int num_fds = 2;
28 
29   /* Create a pipe and a pair of sockets. Then send the write end of
30    * the pipe (fd[1]) through the socket, and receive it as
31    * new_fd */
32   ASSERT_EQ(0, pipe(fd));
33   ASSERT_EQ(0, pipe(fd2));
34   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
35 
36   send_fds[0] = fd[1];
37   send_fds[1] = fd2[1];
38   ASSERT_GE(cras_send_with_fds(sock[0], msg, strlen(msg), send_fds, num_fds),
39             0);
40   ASSERT_GE(cras_recv_with_fds(sock[1], buf, strlen(msg), new_fds, &num_fds),
41             0);
42   ASSERT_STREQ(msg, buf);
43   ASSERT_EQ(2, num_fds);
44   ASSERT_NE(-1, new_fds[0]);
45   ASSERT_NE(-1, new_fds[1]);
46 
47   close(sock[0]);
48   close(sock[1]);
49   close(fd[1]);
50   close(fd2[1]);
51 
52   /* Send a character to the new_fd, and receive it from the read end
53    * of the pipe (fd[0]) */
54   ASSERT_EQ(1, write(new_fds[0], "a", 1));
55   ASSERT_EQ(1, read(fd[0], buf, 1));
56   ASSERT_EQ('a', buf[0]);
57   ASSERT_EQ(1, write(new_fds[1], "b", 1));
58   ASSERT_EQ(1, read(fd2[0], buf, 1));
59   ASSERT_EQ('b', buf[0]);
60 
61   close(fd[0]);
62   close(fd2[0]);
63   close(new_fds[0]);
64   close(new_fds[1]);
65 }
66 
TEST(Util,SendOneRecvTwoFileDescriptors)67 TEST(Util, SendOneRecvTwoFileDescriptors) {
68   int fd[2];
69   int sock[2];
70   char buf[256] = {0};
71   int new_fds[2];
72   char msg[] = "multi-fd";
73   unsigned int num_fds = 2;
74 
75   /* Create a pipe and a pair of sockets. Then send the write end of
76    * the pipe (fd[1]) through the socket, and receive it as
77    * new_fd */
78   ASSERT_EQ(0, pipe(fd));
79   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
80 
81   ASSERT_GE(cras_send_with_fds(sock[0], msg, strlen(msg), &fd[1], 1), 0);
82   ASSERT_GE(cras_recv_with_fds(sock[1], buf, strlen(msg), new_fds, &num_fds),
83             0);
84   ASSERT_STREQ(msg, buf);
85   ASSERT_EQ(1, num_fds);
86   ASSERT_NE(-1, new_fds[0]);
87   ASSERT_EQ(-1, new_fds[1]);
88 
89   close(sock[0]);
90   close(sock[1]);
91   close(fd[1]);
92 
93   /* Send a character to the new_fd, and receive it from the read end
94    * of the pipe (fd[0]) */
95   ASSERT_EQ(1, write(new_fds[0], "a", 1));
96   ASSERT_EQ(1, read(fd[0], buf, 1));
97   ASSERT_EQ('a', buf[0]);
98 
99   close(fd[0]);
100   close(new_fds[0]);
101   close(new_fds[1]);
102 }
103 
TEST(Util,SendRecvFileDescriptor)104 TEST(Util, SendRecvFileDescriptor) {
105   int fd[2];
106   int sock[2];
107   char buf[256] = {0};
108   int new_fd;
109   char msg[] = "hello";
110   unsigned int num_fds = 1;
111 
112   /* Create a pipe and a pair of sockets. Then send the write end of
113    * the pipe (fd[1]) through the socket, and receive it as
114    * new_fd */
115   ASSERT_EQ(0, pipe(fd));
116   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
117 
118   ASSERT_EQ(5, cras_send_with_fds(sock[0], msg, strlen(msg), &fd[1], num_fds));
119   ASSERT_EQ(5,
120             cras_recv_with_fds(sock[1], buf, strlen(msg), &new_fd, &num_fds));
121   ASSERT_STREQ(msg, buf);
122   ASSERT_EQ(1, num_fds);
123 
124   close(sock[0]);
125   close(sock[1]);
126   close(fd[1]);
127 
128   /* Send a character to the new_fd, and receive it from the read end
129    * of the pipe (fd[0]) */
130   ASSERT_EQ(1, write(new_fd, "a", 1));
131   ASSERT_EQ(1, read(fd[0], buf, 1));
132   ASSERT_EQ('a', buf[0]);
133 
134   close(fd[0]);
135   close(new_fd);
136 }
137 
TEST(Util,SendRecvNoDescriptors)138 TEST(Util, SendRecvNoDescriptors) {
139   char buf[256] = {0};
140   char msg[] = "no descriptors";
141   unsigned int num_fds = 0;
142   int sock[2];
143 
144   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
145 
146   ASSERT_GE(cras_send_with_fds(sock[0], msg, strlen(msg), NULL, num_fds), 0);
147   ASSERT_GE(cras_recv_with_fds(sock[1], buf, strlen(msg), NULL, &num_fds), 0);
148   ASSERT_STREQ(msg, buf);
149   ASSERT_EQ(0, num_fds);
150 
151   close(sock[0]);
152   close(sock[1]);
153 }
154 
TEST(Util,TimevalAfter)155 TEST(Util, TimevalAfter) {
156   struct timeval t0, t1;
157   t0.tv_sec = 0;
158   t0.tv_usec = 0;
159   t1.tv_sec = 0;
160   t1.tv_usec = 0;
161   ASSERT_FALSE(timeval_after(&t0, &t1));
162   ASSERT_FALSE(timeval_after(&t1, &t0));
163   t0.tv_usec = 1;
164   ASSERT_TRUE(timeval_after(&t0, &t1));
165   ASSERT_FALSE(timeval_after(&t1, &t0));
166   t1.tv_sec = 1;
167   ASSERT_FALSE(timeval_after(&t0, &t1));
168   ASSERT_TRUE(timeval_after(&t1, &t0));
169 }
170 
TEST(Util,FramesToTime)171 TEST(Util, FramesToTime) {
172   struct timespec t;
173 
174   cras_frames_to_time(24000, 48000, &t);
175   EXPECT_EQ(0, t.tv_sec);
176   EXPECT_EQ(500000000, t.tv_nsec);
177 
178   cras_frames_to_time(48000, 48000, &t);
179   EXPECT_EQ(1, t.tv_sec);
180   EXPECT_EQ(0, t.tv_nsec);
181 
182   cras_frames_to_time(60000, 48000, &t);
183   EXPECT_EQ(1, t.tv_sec);
184   EXPECT_EQ(250000000, t.tv_nsec);
185 
186   cras_frames_to_time(191999, 192000, &t);
187   EXPECT_EQ(0, t.tv_sec);
188   EXPECT_EQ(999994791, t.tv_nsec);
189 }
190 
TEST(Util,TimeToFrames)191 TEST(Util, TimeToFrames) {
192   struct timespec t;
193   unsigned int frames;
194 
195   t.tv_sec = 0;
196   t.tv_nsec = 500000000;
197   frames = cras_time_to_frames(&t, 48000);
198   EXPECT_EQ(24000, frames);
199 
200   t.tv_sec = 1;
201   t.tv_nsec = 500000000;
202   frames = cras_time_to_frames(&t, 48000);
203   EXPECT_EQ(72000, frames);
204 
205   t.tv_sec = 0;
206   t.tv_nsec = 0;
207   frames = cras_time_to_frames(&t, 48000);
208   EXPECT_EQ(0, frames);
209 }
210 
TEST(Util,FramesToMs)211 TEST(Util, FramesToMs) {
212   EXPECT_EQ(500, cras_frames_to_ms(24000, 48000));
213   EXPECT_EQ(0, cras_frames_to_ms(1, 48000));
214   EXPECT_EQ(10, cras_frames_to_ms(480, 48000));
215   EXPECT_EQ(10, cras_frames_to_ms(488, 48000));
216   EXPECT_EQ(50, cras_frames_to_ms(800, 16000));
217 }
218 
TEST(Util,TimespecToMs)219 TEST(Util, TimespecToMs) {
220   struct timespec ts;
221 
222   ts.tv_sec = 0;
223   ts.tv_nsec = 500000000;
224   EXPECT_EQ(500, timespec_to_ms(&ts));
225 
226   ts.tv_sec = 0;
227   ts.tv_nsec = 0;
228   EXPECT_EQ(0, timespec_to_ms(&ts));
229 
230   ts.tv_sec = 0;
231   ts.tv_nsec = 2;
232   EXPECT_EQ(1, timespec_to_ms(&ts));
233 
234   ts.tv_sec = 0;
235   ts.tv_nsec = 10000000;
236   EXPECT_EQ(10, timespec_to_ms(&ts));
237 
238   ts.tv_sec = 1;
239   ts.tv_nsec = 0;
240   EXPECT_EQ(1000, timespec_to_ms(&ts));
241 
242   ts.tv_sec = 1;
243   ts.tv_nsec = 1;
244   EXPECT_EQ(1001, timespec_to_ms(&ts));
245 }
246 
TEST(Util,FramesSinceTime)247 TEST(Util, FramesSinceTime) {
248   struct timespec t, tn;
249   uint64_t frames;
250 
251   t.tv_sec = 0;
252   t.tv_nsec = 500000000;
253 
254   tn.tv_sec = 2;
255   tn.tv_nsec = 0;
256   time_now.push_back(tn);
257   frames = cras_frames_since_time(&t, 48000);
258   EXPECT_EQ(72000, frames);
259 
260   tn.tv_sec = 0;
261   time_now.push_back(tn);
262   frames = cras_frames_since_time(&t, 48000);
263   EXPECT_EQ(0, frames);
264 }
265 
266 // Test cras_poll().
TEST(Util,CrasPoll)267 TEST(Util, CrasPoll) {
268   int pipe_fds[2];
269   struct pollfd poll_fd;
270   std::string output;
271   struct timespec timeout;
272   char buf[256];
273 
274   ASSERT_EQ(0, pipe(pipe_fds));
275   poll_fd.fd = pipe_fds[0];
276   poll_fd.events = POLLIN;
277   ASSERT_NE(0, poll_fd.fd >= 0);
278 
279   // Simple poll.
280   output = "Hello";
281   EXPECT_EQ(output.size() + 1,
282             write(pipe_fds[1], output.c_str(), output.size() + 1));
283   EXPECT_EQ(1, cras_poll(&poll_fd, 1, NULL, NULL));
284   ASSERT_EQ(static_cast<ssize_t>(output.size() + 1),
285             read(pipe_fds[0], buf, sizeof(buf)));
286   EXPECT_EQ(0, strcmp(output.c_str(), buf));
287 
288   // Negative time.
289   timeout.tv_sec = 0;
290   timeout.tv_nsec = -10000000;
291   EXPECT_EQ(-ETIMEDOUT, cras_poll(&poll_fd, 1, &timeout, NULL));
292   timeout.tv_sec = -1;
293   timeout.tv_nsec = 10000000;
294   EXPECT_EQ(-ETIMEDOUT, cras_poll(&poll_fd, 1, &timeout, NULL));
295 
296   // Timeout.
297   timeout.tv_sec = 0;
298   timeout.tv_nsec = 0;
299   time_now.push_back(timeout);
300   timeout.tv_nsec = 1100000;
301   time_now.push_back(timeout);
302   timeout.tv_nsec = 1000000;
303   EXPECT_EQ(-ETIMEDOUT, cras_poll(&poll_fd, 1, &timeout, NULL));
304   EXPECT_EQ(timeout.tv_nsec, -100000);
305 
306   EXPECT_EQ(0, close(pipe_fds[0]));
307   EXPECT_EQ(0, close(pipe_fds[1]));
308 }
309 
310 /* Stubs */
311 extern "C" {
312 
clock_gettime(clockid_t clk_id,struct timespec * tp)313 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
314   std::vector<struct timespec>::iterator i = time_now.begin();
315   if (i != time_now.end()) {
316     *tp = *i;
317     time_now.erase(i);
318   } else
319     memset(tp, 0, sizeof(*tp));
320   return 0;
321 }
322 
323 }  // extern "C"
324 
325 }  //  namespace
326 
main(int argc,char ** argv)327 int main(int argc, char** argv) {
328   ::testing::InitGoogleTest(&argc, argv);
329   return RUN_ALL_TESTS();
330 }
331