kernel_wrap_test.cc revision 3551c9c881056c480085172ff9840cab31610854
1// Copyright (c) 2013 The Chromium 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 <string>
6#include <vector>
7
8#include "gtest/gtest.h"
9#include "kernel_proxy_mock.h"
10#include "nacl_io/kernel_intercept.h"
11#include "nacl_io/kernel_wrap.h"
12#include "nacl_io/ossocket.h"
13#include "nacl_io/ostermios.h"
14
15using namespace nacl_io;
16
17using ::testing::_;
18using ::testing::Return;
19using ::testing::StrEq;
20
21namespace {
22
23static const int DUMMY_FD = 5678;
24
25#define COMPARE_FIELD(f) \
26  if (arg->f != statbuf->f) { \
27    *result_listener << "mismatch of field \""#f"\". " \
28      "expected: " << statbuf->f << \
29      " actual: " << arg->f; \
30    return false; \
31  }
32
33MATCHER_P(IsEqualToStatbuf, statbuf, "") {
34  COMPARE_FIELD(st_dev);
35  COMPARE_FIELD(st_ino);
36  COMPARE_FIELD(st_mode);
37  COMPARE_FIELD(st_nlink);
38  COMPARE_FIELD(st_uid);
39  COMPARE_FIELD(st_gid);
40  COMPARE_FIELD(st_rdev);
41  COMPARE_FIELD(st_size);
42  COMPARE_FIELD(st_atime);
43  COMPARE_FIELD(st_mtime);
44  COMPARE_FIELD(st_ctime);
45  return true;
46}
47
48#undef COMPARE_FIELD
49
50ACTION_P(SetStat, statbuf) {
51  memset(arg1, 0, sizeof(struct stat));
52  arg1->st_dev = statbuf->st_dev;
53  arg1->st_ino = statbuf->st_ino;
54  arg1->st_mode = statbuf->st_mode;
55  arg1->st_nlink = statbuf->st_nlink;
56  arg1->st_uid = statbuf->st_uid;
57  arg1->st_gid = statbuf->st_gid;
58  arg1->st_rdev = statbuf->st_rdev;
59  arg1->st_size = statbuf->st_size;
60  arg1->st_atime = statbuf->st_atime;
61  arg1->st_mtime = statbuf->st_mtime;
62  arg1->st_ctime = statbuf->st_ctime;
63  return 0;
64}
65
66void MakeDummyStatbuf(struct stat* statbuf) {
67  memset(&statbuf[0], 0, sizeof(struct stat));
68  statbuf->st_dev = 1;
69  statbuf->st_ino = 2;
70  statbuf->st_mode = 3;
71  statbuf->st_nlink = 4;
72  statbuf->st_uid = 5;
73  statbuf->st_gid = 6;
74  statbuf->st_rdev = 7;
75  statbuf->st_size = 8;
76  statbuf->st_atime = 9;
77  statbuf->st_mtime = 10;
78  statbuf->st_ctime = 11;
79}
80
81const uid_t kDummyUid = 1001;
82const gid_t kDummyGid = 1002;
83
84class KernelWrapTest : public ::testing::Test {
85 public:
86  KernelWrapTest() {
87    // Initializing the KernelProxy opens stdin/stdout/stderr.
88    EXPECT_CALL(mock, open(_, _))
89      .WillOnce(Return(0))
90      .WillOnce(Return(1))
91      .WillOnce(Return(2));
92    // And will call mount / and /dev.
93    EXPECT_CALL(mock, mount(_, _, _, _, _))
94      .WillOnce(Return(0))
95      .WillOnce(Return(0));
96
97    ki_init(&mock);
98  }
99
100  ~KernelWrapTest() {
101    ki_uninit();
102  }
103
104  KernelProxyMock mock;
105};
106
107}  // namespace
108
109
110TEST_F(KernelWrapTest, access) {
111  EXPECT_CALL(mock, access(StrEq("access"), 12)).Times(1);
112  access("access", 12);
113}
114
115TEST_F(KernelWrapTest, chdir) {
116  EXPECT_CALL(mock, chdir(StrEq("chdir"))).Times(1);
117  chdir("chdir");
118}
119
120TEST_F(KernelWrapTest, chmod) {
121  EXPECT_CALL(mock, chmod(StrEq("chmod"), 23)).Times(1);
122  chmod("chmod", 23);
123}
124
125TEST_F(KernelWrapTest, chown) {
126  uid_t uid = kDummyUid;
127  gid_t gid = kDummyGid;
128  EXPECT_CALL(mock, chown(StrEq("chown"), uid, gid)).Times(1);
129  chown("chown", uid, gid);
130}
131
132TEST_F(KernelWrapTest, close) {
133  EXPECT_CALL(mock, close(34)).Times(1);
134  close(34);
135}
136
137TEST_F(KernelWrapTest, dup) {
138  EXPECT_CALL(mock, dup(DUMMY_FD)).Times(1);
139  dup(DUMMY_FD);
140}
141
142TEST_F(KernelWrapTest, dup2) {
143  EXPECT_CALL(mock, dup2(DUMMY_FD, 234)).Times(1);
144  dup2(DUMMY_FD, 234);
145}
146
147TEST_F(KernelWrapTest, fchown) {
148  uid_t uid = kDummyUid;
149  gid_t gid = kDummyGid;
150  EXPECT_CALL(mock, fchown(DUMMY_FD, uid, gid)).Times(1);
151  fchown(DUMMY_FD, uid, gid);
152}
153
154TEST_F(KernelWrapTest, fstat) {
155  struct stat in_statbuf;
156  MakeDummyStatbuf(&in_statbuf);
157  EXPECT_CALL(mock, fstat(DUMMY_FD, _))
158      .Times(1)
159      .WillOnce(SetStat(&in_statbuf));
160  struct stat out_statbuf;
161  fstat(DUMMY_FD, &out_statbuf);
162  EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf));
163}
164
165TEST_F(KernelWrapTest, ftruncate) {
166  EXPECT_CALL(mock, ftruncate(456, 0)).Times(1);
167  ftruncate(456, 0);
168}
169
170TEST_F(KernelWrapTest, fsync) {
171  EXPECT_CALL(mock, fsync(345)).Times(1);
172  fsync(345);
173}
174
175TEST_F(KernelWrapTest, getcwd) {
176  EXPECT_CALL(mock, getcwd(StrEq("getcwd"), 1)).Times(1);
177  char buffer[] = "getcwd";
178  getcwd(buffer, 1);
179}
180
181TEST_F(KernelWrapTest, getdents) {
182#ifndef __GLIBC__
183  // TODO(sbc): Find a way to test the getdents wrapper under glibc.
184  // It looks like the only way to excerside it is to call readdir(2).
185  // There is an internal glibc function __getdents that will call the
186  // IRT but that cannot be accessed from here as glibc does not export it.
187  EXPECT_CALL(mock, getdents(456, NULL, 567)).WillOnce(Return(678));
188  EXPECT_EQ(getdents(456, NULL, 567), 678);
189#endif
190}
191
192// gcc gives error: getwd is deprecated.
193#if defined(__GNUC__)
194#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
195#endif
196TEST_F(KernelWrapTest, getwd) {
197  EXPECT_CALL(mock, getwd(StrEq("getwd"))).Times(1);
198  char buffer[] = "getwd";
199  getwd(buffer);
200}
201#if defined(__GNUC__)
202#pragma GCC diagnostic warning "-Wdeprecated-declarations"
203#endif
204
205TEST_F(KernelWrapTest, ioctl) {
206  char buffer[] = "ioctl";
207  EXPECT_CALL(mock, ioctl(012, 345, StrEq("ioctl"))).Times(1);
208  ioctl(012, 345, buffer);
209}
210
211TEST_F(KernelWrapTest, isatty) {
212  EXPECT_CALL(mock, isatty(678)).Times(1);
213  isatty(678);
214}
215
216TEST_F(KernelWrapTest, kill) {
217  EXPECT_CALL(mock, kill(22, 33)).Times(1);
218  kill(22, 33);
219}
220
221TEST_F(KernelWrapTest, lchown) {
222  uid_t uid = kDummyUid;
223  gid_t gid = kDummyGid;
224  EXPECT_CALL(mock, lchown(StrEq("lchown"), uid, gid)).Times(1);
225  lchown("lchown", uid, gid);
226}
227
228TEST_F(KernelWrapTest, lseek) {
229  EXPECT_CALL(mock, lseek(789, 891, 912)).Times(1);
230  lseek(789, 891, 912);
231}
232
233TEST_F(KernelWrapTest, mkdir) {
234#if defined(WIN32)
235  EXPECT_CALL(mock, mkdir(StrEq("mkdir"), 0777)).Times(1);
236  mkdir("mkdir");
237#else
238  EXPECT_CALL(mock, mkdir(StrEq("mkdir"), 1234)).Times(1);
239  mkdir("mkdir", 1234);
240#endif
241}
242
243TEST_F(KernelWrapTest, mount) {
244  EXPECT_CALL(mock,
245      mount(StrEq("mount1"), StrEq("mount2"), StrEq("mount3"), 2345, NULL))
246      .Times(1);
247  mount("mount1", "mount2", "mount3", 2345, NULL);
248}
249
250TEST_F(KernelWrapTest, open) {
251  EXPECT_CALL(mock, open(StrEq("open"), 3456)).Times(1);
252  open("open", 3456);
253}
254
255TEST_F(KernelWrapTest, read) {
256  EXPECT_CALL(mock, read(4567, NULL, 5678)).Times(1);
257  read(4567, NULL, 5678);
258}
259
260TEST_F(KernelWrapTest, remove) {
261  EXPECT_CALL(mock, remove(StrEq("remove"))).Times(1);
262  remove("remove");
263}
264
265TEST_F(KernelWrapTest, rmdir) {
266  EXPECT_CALL(mock, rmdir(StrEq("rmdir"))).Times(1);
267  rmdir("rmdir");
268}
269
270static void handler(int) {
271}
272
273TEST_F(KernelWrapTest, sigset) {
274  EXPECT_CALL(mock, sigset(22, handler)).Times(1);
275  sigset(22, handler);
276}
277
278TEST_F(KernelWrapTest, signal) {
279  EXPECT_CALL(mock, sigset(22, handler)).Times(1);
280  signal(22, handler);
281}
282
283TEST_F(KernelWrapTest, stat) {
284  struct stat in_statbuf;
285  MakeDummyStatbuf(&in_statbuf);
286  EXPECT_CALL(mock, stat(StrEq("stat"), _))
287      .Times(1)
288      .WillOnce(SetStat(&in_statbuf));
289  struct stat out_statbuf;
290  stat("stat", &out_statbuf);
291  EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf));
292}
293
294TEST_F(KernelWrapTest, tcgetattr) {
295  struct termios term;
296  EXPECT_CALL(mock, tcgetattr(DUMMY_FD, &term)).Times(1);
297  tcgetattr(DUMMY_FD, &term);
298}
299
300TEST_F(KernelWrapTest, tcsetattr) {
301  struct termios term;
302  EXPECT_CALL(mock, tcsetattr(DUMMY_FD, 0, &term)).Times(1);
303  tcsetattr(DUMMY_FD, 0, &term);
304}
305
306TEST_F(KernelWrapTest, umount) {
307  EXPECT_CALL(mock, umount(StrEq("umount"))).Times(1);
308  umount("umount");
309}
310
311TEST_F(KernelWrapTest, unlink) {
312  EXPECT_CALL(mock, unlink(StrEq("unlink"))).Times(1);
313  unlink("unlink");
314}
315
316TEST_F(KernelWrapTest, utime) {
317  const struct utimbuf* times = NULL;
318  EXPECT_CALL(mock, utime(StrEq("utime"), times));
319  utime("utime", times);
320}
321
322TEST_F(KernelWrapTest, write) {
323  EXPECT_CALL(mock, write(6789, NULL, 7891)).Times(1);
324  write(6789, NULL, 7891);
325}
326
327#ifdef PROVIDES_SOCKET_API
328TEST_F(KernelWrapTest, poll) {
329  EXPECT_CALL(mock, poll(NULL, 5, -1));
330  poll(NULL, 5, -1);
331}
332
333TEST_F(KernelWrapTest, select) {
334  EXPECT_CALL(mock, select(123, NULL, NULL, NULL, NULL));
335  select(123, NULL, NULL, NULL, NULL);
336}
337
338// Socket Functions
339TEST_F(KernelWrapTest, accept) {
340  EXPECT_CALL(mock, accept(DUMMY_FD, NULL, NULL)).Times(1);
341  accept(DUMMY_FD, NULL, NULL);
342}
343
344TEST_F(KernelWrapTest, bind) {
345  EXPECT_CALL(mock, bind(DUMMY_FD, NULL, 456)).Times(1);
346  bind(DUMMY_FD, NULL, 456);
347}
348
349TEST_F(KernelWrapTest, connect) {
350  EXPECT_CALL(mock, connect(DUMMY_FD, NULL, 456)).Times(1);
351  connect(DUMMY_FD, NULL, 456);
352}
353
354TEST_F(KernelWrapTest, gethostbyname) {
355  EXPECT_CALL(mock, gethostbyname(NULL)).Times(1);
356  gethostbyname(NULL);
357}
358
359TEST_F(KernelWrapTest, getpeername) {
360  EXPECT_CALL(mock, getpeername(DUMMY_FD, NULL, NULL)).Times(1);
361  getpeername(DUMMY_FD, NULL, NULL);
362}
363
364TEST_F(KernelWrapTest, getsockname) {
365  EXPECT_CALL(mock, getsockname(DUMMY_FD, NULL, NULL)).Times(1);
366  getsockname(DUMMY_FD, NULL, NULL);
367}
368
369TEST_F(KernelWrapTest, getsockopt) {
370  EXPECT_CALL(mock, getsockopt(DUMMY_FD, 456, 789, NULL, NULL)).Times(1);
371  getsockopt(DUMMY_FD, 456, 789, NULL, NULL);
372}
373
374TEST_F(KernelWrapTest, listen) {
375  EXPECT_CALL(mock, listen(DUMMY_FD, 456)).Times(1);
376  listen(DUMMY_FD, 456);
377}
378
379TEST_F(KernelWrapTest, recv) {
380  EXPECT_CALL(mock, recv(DUMMY_FD, NULL, 456, 789)).Times(1);
381  recv(DUMMY_FD, NULL, 456, 789);
382}
383
384TEST_F(KernelWrapTest, recvfrom) {
385  EXPECT_CALL(mock, recvfrom(DUMMY_FD, NULL, 456, 789, NULL, NULL)).Times(1);
386  recvfrom(DUMMY_FD, NULL, 456, 789, NULL, NULL);
387}
388
389TEST_F(KernelWrapTest, recvmsg) {
390  EXPECT_CALL(mock, recvmsg(DUMMY_FD, NULL, 456)).Times(1);
391  recvmsg(DUMMY_FD, NULL, 456);
392}
393
394TEST_F(KernelWrapTest, send) {
395  EXPECT_CALL(mock, send(DUMMY_FD, NULL, 456, 789)).Times(1);
396  send(DUMMY_FD, NULL, 456, 789);
397}
398
399TEST_F(KernelWrapTest, sendto) {
400  EXPECT_CALL(mock, sendto(DUMMY_FD, NULL, 456, 789, NULL, 314)).Times(1);
401  sendto(DUMMY_FD, NULL, 456, 789, NULL, 314);
402}
403
404TEST_F(KernelWrapTest, sendmsg) {
405  EXPECT_CALL(mock, sendmsg(DUMMY_FD, NULL, 456)).Times(1);
406  sendmsg(DUMMY_FD, NULL, 456);
407}
408
409TEST_F(KernelWrapTest, setsockopt) {
410  EXPECT_CALL(mock, setsockopt(DUMMY_FD, 456, 789, NULL, 314)).Times(1);
411  setsockopt(DUMMY_FD, 456, 789, NULL, 314);
412}
413
414TEST_F(KernelWrapTest, shutdown) {
415  EXPECT_CALL(mock, shutdown(DUMMY_FD, 456)).Times(1);
416  shutdown(DUMMY_FD, 456);
417}
418
419TEST_F(KernelWrapTest, socket) {
420  EXPECT_CALL(mock, socket(DUMMY_FD, 456, 789)).Times(1);
421  socket(DUMMY_FD, 456, 789);
422}
423
424TEST_F(KernelWrapTest, socketpair) {
425  EXPECT_CALL(mock, socketpair(DUMMY_FD, 456, 789, NULL)).Times(1);
426  socketpair(DUMMY_FD, 456, 789, NULL);
427}
428
429#endif // PROVIDES_SOCKET_API
430