kernel_wrap_test.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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// The linux host build of nacl_io can't do wrapping of syscalls so all
6// these tests must be disabled.
7#if !defined(__linux__)
8
9#include <unistd.h>
10
11#include <string>
12#include <vector>
13
14#include "gtest/gtest.h"
15#include "mock_kernel_proxy.h"
16#include "nacl_io/kernel_intercept.h"
17#include "nacl_io/kernel_wrap.h"
18#include "nacl_io/kernel_wrap_real.h"
19#include "nacl_io/osmman.h"
20#include "nacl_io/ossocket.h"
21#include "nacl_io/ostermios.h"
22#include "nacl_io/ostime.h"
23#include "ppapi_simple/ps.h"
24
25#if defined(__native_client__) && !defined(__GLIBC__)
26extern "C" {
27// TODO(sbc): remove once this gets added to the newlib toolchain headers.
28int fchdir(int fd);
29}
30#endif
31
32using namespace nacl_io;
33
34using ::testing::_;
35using ::testing::AnyNumber;
36using ::testing::DoAll;
37using ::testing::Invoke;
38using ::testing::Return;
39using ::testing::StrEq;
40
41namespace {
42
43#define COMPARE_FIELD(actual, expected, f)                                 \
44  if (actual != expected) {                                                \
45    *result_listener << "mismatch of field \"" f                           \
46                        "\". "                                             \
47                        "expected: " << expected << " actual: " << actual; \
48    return false;                                                          \
49  }
50
51#define COMPARE_FIELD_SIMPLE(f) COMPARE_FIELD(arg->f, other->f, #f)
52
53MATCHER_P(IsEqualToStatbuf, other, "") {
54  COMPARE_FIELD_SIMPLE(st_dev);
55  COMPARE_FIELD_SIMPLE(st_ino);
56  COMPARE_FIELD_SIMPLE(st_mode);
57  COMPARE_FIELD_SIMPLE(st_nlink);
58  COMPARE_FIELD_SIMPLE(st_uid);
59  COMPARE_FIELD_SIMPLE(st_gid);
60  COMPARE_FIELD_SIMPLE(st_rdev);
61  COMPARE_FIELD_SIMPLE(st_size);
62  COMPARE_FIELD_SIMPLE(st_atime);
63  COMPARE_FIELD_SIMPLE(st_mtime);
64  COMPARE_FIELD_SIMPLE(st_ctime);
65  return true;
66}
67
68MATCHER_P(IsEqualToUtimbuf, other, "") {
69  COMPARE_FIELD(arg[0].tv_sec, other->actime, "actime");
70  COMPARE_FIELD(arg[1].tv_sec, other->modtime, "modtime");
71  return true;
72}
73
74MATCHER_P(IsEqualToTimeval, other, "") {
75  COMPARE_FIELD(arg[0].tv_sec, other[0].tv_sec, "[0].tv_sec");
76  COMPARE_FIELD(arg[0].tv_nsec, other[0].tv_usec * 1000, "[0].tv_usec");
77  COMPARE_FIELD(arg[1].tv_sec, other[1].tv_sec, "[1].tv_sec");
78  COMPARE_FIELD(arg[1].tv_nsec, other[1].tv_usec * 1000, "[1].tv_usec");
79  return true;
80}
81
82#undef COMPARE_FIELD
83#undef COMPARE_FIELD_SIMPLE
84
85
86ACTION_P(SetErrno, value) {
87  errno = value;
88}
89
90ACTION_P2(SetString, target, source) {
91  strcpy(target, source);
92}
93
94ACTION_P(SetStat, statbuf) {
95  memset(arg1, 0, sizeof(struct stat));
96  arg1->st_dev = statbuf->st_dev;
97  arg1->st_ino = statbuf->st_ino;
98  arg1->st_mode = statbuf->st_mode;
99  arg1->st_nlink = statbuf->st_nlink;
100  arg1->st_uid = statbuf->st_uid;
101  arg1->st_gid = statbuf->st_gid;
102  arg1->st_rdev = statbuf->st_rdev;
103  arg1->st_size = statbuf->st_size;
104  arg1->st_atime = statbuf->st_atime;
105  arg1->st_mtime = statbuf->st_mtime;
106  arg1->st_ctime = statbuf->st_ctime;
107}
108
109void MakeDummyStatbuf(struct stat* statbuf) {
110  memset(&statbuf[0], 0, sizeof(struct stat));
111  statbuf->st_dev = 1;
112  statbuf->st_ino = 2;
113  statbuf->st_mode = 3;
114  statbuf->st_nlink = 4;
115  statbuf->st_uid = 5;
116  statbuf->st_gid = 6;
117  statbuf->st_rdev = 7;
118  statbuf->st_size = 8;
119  statbuf->st_atime = 9;
120  statbuf->st_mtime = 10;
121  statbuf->st_ctime = 11;
122}
123
124const mode_t kDummyMode = 0xbeef;
125const int kDummyErrno = 0xfeeb;
126const int kDummyInt = 0xdedbeef;
127const int kDummyInt2 = 0xcabba6e;
128const int kDummyInt3 = 0xf00ba4;
129const int kDummyInt4 = 0xabacdba;
130const size_t kDummySizeT = 0x60067e;
131const char* kDummyConstChar = "foobar";
132const char* kDummyConstChar2 = "g00gl3";
133const char* kDummyConstChar3 = "fr00gl3";
134const void* kDummyVoidPtr = "blahblah";
135const uid_t kDummyUid = 1001;
136const gid_t kDummyGid = 1002;
137
138class KernelWrapTest : public ::testing::Test {
139 public:
140  KernelWrapTest() {}
141
142  virtual void SetUp() {
143    // Initialize the global errno value to a consistent value rather than
144    // relying on its value from previous test runs.
145    errno = 0;
146
147    // Initializing the KernelProxy opens stdin/stdout/stderr.
148    EXPECT_CALL(mock, open(_, _, _))
149        .WillOnce(Return(0))
150        .WillOnce(Return(1))
151        .WillOnce(Return(2));
152
153    ASSERT_EQ(0, ki_push_state_for_testing());
154    ASSERT_EQ(0, ki_init(&mock));
155
156    // We allow write to be called any number of times, and it forwards to
157    // _real_write. This prevents an infinite loop writing output if there is a
158    // failure.
159    ON_CALL(mock, write(_, _, _))
160        .WillByDefault(Invoke(this, &KernelWrapTest::DefaultWrite));
161    EXPECT_CALL(mock, write(_, _, _)).Times(AnyNumber());
162  }
163
164  void TearDown() {
165    // Uninitialize the kernel proxy so wrapped functions passthrough to their
166    // unwrapped versions.
167    ki_uninit();
168  }
169
170  MockKernelProxy mock;
171
172 private:
173  ssize_t DefaultWrite(int fd, const void* buf, size_t count) {
174   assert(fd <= 2);
175   size_t nwrote;
176   int rtn = _real_write(fd, buf, count, &nwrote);
177   if (rtn != 0) {
178     errno = rtn;
179     return -1;
180   }
181   return nwrote;
182  }
183};
184
185}  // namespace
186
187TEST_F(KernelWrapTest, access) {
188  EXPECT_CALL(mock, access(kDummyConstChar, kDummyInt)) .WillOnce(Return(0));
189  EXPECT_EQ(0, access(kDummyConstChar, kDummyInt));
190
191  EXPECT_CALL(mock, access(kDummyConstChar, kDummyInt))
192      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
193  EXPECT_EQ(-1, access(kDummyConstChar, kDummyInt));
194  EXPECT_EQ(kDummyErrno, errno);
195
196}
197
198TEST_F(KernelWrapTest, chdir) {
199  EXPECT_CALL(mock, chdir(kDummyConstChar)).WillOnce(Return(0));
200  EXPECT_EQ(0, chdir(kDummyConstChar));
201
202  EXPECT_CALL(mock, chdir(kDummyConstChar))
203    .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
204  EXPECT_EQ(-1, chdir(kDummyConstChar));
205  ASSERT_EQ(kDummyErrno, errno);
206}
207
208TEST_F(KernelWrapTest, chmod) {
209  EXPECT_CALL(mock, chmod(kDummyConstChar, kDummyMode))
210      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
211  EXPECT_EQ(-1, chmod(kDummyConstChar, kDummyMode));
212  ASSERT_EQ(kDummyErrno, errno);
213}
214
215TEST_F(KernelWrapTest, chown) {
216  EXPECT_CALL(mock, chown(kDummyConstChar, kDummyUid, kDummyGid))
217      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
218  EXPECT_EQ(-1, chown(kDummyConstChar, kDummyUid, kDummyGid));
219  ASSERT_EQ(kDummyErrno, errno);
220}
221
222TEST_F(KernelWrapTest, close) {
223  // The way we wrap close does not support returning arbitrary values, so we
224  // test 0 and -1.
225  EXPECT_CALL(mock, close(kDummyInt))
226      .WillOnce(Return(0));
227
228  EXPECT_EQ(0, close(kDummyInt));
229
230  EXPECT_CALL(mock, close(kDummyInt))
231      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
232  EXPECT_EQ(-1, close(kDummyInt));
233  ASSERT_EQ(kDummyErrno, errno);
234}
235
236TEST_F(KernelWrapTest, dup) {
237  EXPECT_CALL(mock, dup(kDummyInt)).WillOnce(Return(kDummyInt2));
238  EXPECT_EQ(kDummyInt2, dup(kDummyInt));
239}
240
241TEST_F(KernelWrapTest, dup2) {
242  // The way we wrap dup2 does not support returning aribtrary values, only -1
243  // or the value of the new fd.
244  EXPECT_CALL(mock, dup2(kDummyInt, kDummyInt2))
245      .WillOnce(Return(kDummyInt2))
246      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
247
248  EXPECT_EQ(kDummyInt2, dup2(kDummyInt, kDummyInt2));
249  EXPECT_EQ(-1, dup2(kDummyInt, kDummyInt2));
250  ASSERT_EQ(kDummyErrno, errno);
251}
252
253TEST_F(KernelWrapTest, fchdir) {
254  EXPECT_CALL(mock, fchdir(kDummyInt))
255      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
256
257  EXPECT_EQ(-1, fchdir(kDummyInt));
258  ASSERT_EQ(kDummyErrno, errno);
259}
260
261TEST_F(KernelWrapTest, fchmod) {
262  EXPECT_CALL(mock, fchmod(kDummyInt, kDummyMode))
263      .WillOnce(Return(0))
264      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
265
266  EXPECT_EQ(0, fchmod(kDummyInt, kDummyMode));
267  EXPECT_EQ(-1, fchmod(kDummyInt, kDummyMode));
268  ASSERT_EQ(kDummyErrno, errno);
269}
270
271TEST_F(KernelWrapTest, fchown) {
272  EXPECT_CALL(mock, fchown(kDummyInt, kDummyUid, kDummyGid))
273      .WillOnce(Return(kDummyInt));
274  EXPECT_EQ(kDummyInt, fchown(kDummyInt, kDummyUid, kDummyGid));
275}
276
277TEST_F(KernelWrapTest, fcntl) {
278  char buffer[] = "fcntl";
279  EXPECT_CALL(mock, fcntl(kDummyInt, kDummyInt2, _))
280      .WillOnce(Return(kDummyInt3));
281  EXPECT_EQ(kDummyInt3, fcntl(kDummyInt, kDummyInt2, buffer));
282}
283
284TEST_F(KernelWrapTest, fdatasync) {
285  EXPECT_CALL(mock, fdatasync(kDummyInt)).WillOnce(Return(0))
286      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
287
288  EXPECT_EQ(0, fdatasync(kDummyInt));
289  EXPECT_EQ(-1, fdatasync(kDummyInt));
290  ASSERT_EQ(kDummyErrno, errno);
291}
292
293TEST_F(KernelWrapTest, fstat) {
294  // The way we wrap fstat does not support returning aribtrary values, only 0
295  // or -1.
296  struct stat in_statbuf;
297  MakeDummyStatbuf(&in_statbuf);
298  EXPECT_CALL(mock, fstat(kDummyInt, _))
299      .WillOnce(DoAll(SetStat(&in_statbuf), Return(0)))
300      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
301  struct stat out_statbuf;
302
303  EXPECT_EQ(0, fstat(kDummyInt, &out_statbuf));
304  EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf));
305
306  EXPECT_EQ(-1, fstat(kDummyInt, &out_statbuf));
307  ASSERT_EQ(kDummyErrno, errno);
308}
309
310TEST_F(KernelWrapTest, ftruncate) {
311  EXPECT_CALL(mock, ftruncate(kDummyInt, kDummyInt2))
312      .WillOnce(Return(kDummyInt3));
313  EXPECT_EQ(kDummyInt3, ftruncate(kDummyInt, kDummyInt2));
314}
315
316TEST_F(KernelWrapTest, fsync) {
317  EXPECT_CALL(mock, fsync(kDummyInt))
318      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
319  EXPECT_EQ(-1, fsync(kDummyInt));
320  ASSERT_EQ(kDummyErrno, errno);
321}
322
323TEST_F(KernelWrapTest, futimes) {
324  struct timeval times[2] = {{123, 234}, {345, 456}};
325  EXPECT_CALL(mock, futimens(kDummyInt, IsEqualToTimeval(times)))
326      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
327  EXPECT_EQ(-1, futimes(kDummyInt, times));
328  ASSERT_EQ(kDummyErrno, errno);
329}
330
331TEST_F(KernelWrapTest, getcwd) {
332  char buffer[PATH_MAX];
333  char result[PATH_MAX];
334  memset(buffer, 0, PATH_MAX);
335  strcpy(result, "getcwd_result");
336  EXPECT_CALL(mock, getcwd(buffer, kDummySizeT))
337       .WillOnce(DoAll(SetString(buffer, result), Return(buffer)));
338  EXPECT_STREQ(result, getcwd(buffer, kDummySizeT));
339}
340
341TEST_F(KernelWrapTest, getdents) {
342#if !defined( __GLIBC__) && !defined(__BIONIC__)
343  // TODO(sbc): Find a way to test the getdents wrapper under glibc.
344  // It looks like the only way to exercise it is to call readdir(2).
345  // There is an internal glibc function __getdents that will call the
346  // IRT but that cannot be accessed from here as glibc does not export it.
347  int dummy_val;
348  void* void_ptr = &dummy_val;
349  EXPECT_CALL(mock, getdents(kDummyInt, void_ptr, kDummyInt2))
350      .WillOnce(Return(kDummyInt2));
351  EXPECT_EQ(kDummyInt2, getdents(kDummyInt, void_ptr, kDummyInt2));
352#endif
353}
354
355// gcc gives error: getwd is deprecated.
356#if defined(__GNUC__)
357#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
358#endif
359TEST_F(KernelWrapTest, getwd) {
360  char result[] = "getwd_result";
361  char buffer[] = "getwd";
362  EXPECT_CALL(mock, getwd(buffer)).WillOnce(Return(result));
363  EXPECT_EQ(result, getwd(buffer));
364}
365#if defined(__GNUC__)
366#pragma GCC diagnostic warning "-Wdeprecated-declarations"
367#endif
368
369TEST_F(KernelWrapTest, ioctl) {
370  char buffer[] = "ioctl";
371  EXPECT_CALL(mock, ioctl(kDummyInt, kDummyInt2, _))
372      .WillOnce(Return(kDummyInt3));
373  EXPECT_EQ(kDummyInt3, ioctl(kDummyInt, kDummyInt2, buffer));
374}
375
376#if !defined(__BIONIC__)
377TEST_F(KernelWrapTest, isatty) {
378  EXPECT_CALL(mock, isatty(kDummyInt)).WillOnce(Return(kDummyInt2));
379  EXPECT_EQ(kDummyInt2, isatty(kDummyInt));
380
381  // This test verifies that the IRT interception wrapper for isatty
382  // ignores the value of errno when isatty() returns 1.  We had a bug
383  // where returning 1 from ki_isatty resulted in errno being returned
384  // by the IRT interface.
385  errno = kDummyInt3;
386  EXPECT_CALL(mock, isatty(kDummyInt)).WillOnce(Return(1));
387  EXPECT_EQ(1, isatty(kDummyInt));
388}
389#endif
390
391TEST_F(KernelWrapTest, kill) {
392  EXPECT_CALL(mock, kill(kDummyInt, kDummyInt2)).WillOnce(Return(kDummyInt3));
393  EXPECT_EQ(kDummyInt3, kill(kDummyInt, kDummyInt2));
394}
395
396TEST_F(KernelWrapTest, lchown) {
397  EXPECT_CALL(mock, lchown(kDummyConstChar, kDummyUid, kDummyGid))
398      .WillOnce(Return(kDummyInt));
399  EXPECT_EQ(kDummyInt, lchown(kDummyConstChar, kDummyUid, kDummyGid));
400}
401
402TEST_F(KernelWrapTest, link) {
403  EXPECT_CALL(mock, link(kDummyConstChar, kDummyConstChar2))
404      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
405  EXPECT_EQ(-1, link(kDummyConstChar, kDummyConstChar2));
406  ASSERT_EQ(kDummyErrno, errno);
407}
408
409TEST_F(KernelWrapTest, lseek) {
410  EXPECT_CALL(mock, lseek(kDummyInt, kDummyInt2, kDummyInt3))
411      .WillOnce(Return(kDummyInt4));
412  EXPECT_EQ(kDummyInt4, lseek(kDummyInt, kDummyInt2, kDummyInt3));
413}
414
415TEST_F(KernelWrapTest, mkdir) {
416#if defined(WIN32)
417  EXPECT_CALL(mock, mkdir(kDummyConstChar, 0777)).WillOnce(Return(kDummyInt2));
418  EXPECT_EQ(kDummyInt2, mkdir(kDummyConstChar));
419#else
420  EXPECT_CALL(mock, mkdir(kDummyConstChar, kDummyMode))
421      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
422  EXPECT_EQ(-1, mkdir(kDummyConstChar, kDummyMode));
423  ASSERT_EQ(kDummyErrno, errno);
424#endif
425}
426
427TEST_F(KernelWrapTest, mmap) {
428  // We only wrap mmap if |flags| has the MAP_ANONYMOUS bit unset.
429  int flags = kDummyInt2 & ~MAP_ANONYMOUS;
430
431  const size_t kDummySizeT2 = 0xbadf00d;
432  int dummy1 = 123;
433  int dummy2 = 456;
434  void* kDummyVoidPtr1 = &dummy1;
435  void* kDummyVoidPtr2 = &dummy2;
436  EXPECT_CALL(mock,
437              mmap(kDummyVoidPtr1,
438                   kDummySizeT,
439                   kDummyInt,
440                   flags,
441                   kDummyInt3,
442                   kDummySizeT2)).WillOnce(Return(kDummyVoidPtr2));
443  EXPECT_EQ(kDummyVoidPtr2,
444            mmap(kDummyVoidPtr1,
445                 kDummySizeT,
446                 kDummyInt,
447                 flags,
448                 kDummyInt3,
449                 kDummySizeT2));
450}
451
452TEST_F(KernelWrapTest, mount) {
453  EXPECT_CALL(mock,
454              mount(kDummyConstChar,
455                    kDummyConstChar2,
456                    kDummyConstChar3,
457                    kDummyInt,
458                    kDummyVoidPtr)).WillOnce(Return(kDummyInt2));
459  EXPECT_EQ(kDummyInt2,
460            mount(kDummyConstChar,
461                  kDummyConstChar2,
462                  kDummyConstChar3,
463                  kDummyInt,
464                  kDummyVoidPtr));
465}
466
467TEST_F(KernelWrapTest, munmap) {
468  // The way we wrap munmap, calls the "real" mmap as well as the intercepted
469  // one. The result returned is from the "real" mmap.
470  int dummy1 = 123;
471  void* kDummyVoidPtr = &dummy1;
472  size_t kDummySizeT = sizeof(kDummyVoidPtr);
473  EXPECT_CALL(mock, munmap(kDummyVoidPtr, kDummySizeT));
474  munmap(kDummyVoidPtr, kDummySizeT);
475}
476
477TEST_F(KernelWrapTest, open) {
478  // We pass O_RDONLY because we do not want an error in flags translation
479  EXPECT_CALL(mock, open(kDummyConstChar, 0, 0))
480      .WillOnce(Return(kDummyInt2))
481      .WillOnce(Return(kDummyInt2));
482
483  EXPECT_EQ(kDummyInt2, open(kDummyConstChar, 0, 0));
484  EXPECT_EQ(kDummyInt2, open(kDummyConstChar, 0, 0));
485}
486
487TEST_F(KernelWrapTest, pipe) {
488  int fds[] = {1, 2};
489  EXPECT_CALL(mock, pipe(fds)).WillOnce(Return(kDummyInt));
490  EXPECT_EQ(kDummyInt, pipe(fds));
491}
492
493TEST_F(KernelWrapTest, read) {
494  int dummy_value;
495  void* dummy_void_ptr = &dummy_value;
496  EXPECT_CALL(mock, read(kDummyInt, dummy_void_ptr, kDummyInt2))
497      .WillOnce(Return(kDummyInt3));
498  EXPECT_EQ(kDummyInt3, read(kDummyInt, dummy_void_ptr, kDummyInt2));
499}
500
501TEST_F(KernelWrapTest, readlink) {
502  char buf[10];
503
504  EXPECT_CALL(mock, readlink(kDummyConstChar, buf, 10))
505      .WillOnce(Return(kDummyInt))
506      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
507
508  EXPECT_EQ(kDummyInt, readlink(kDummyConstChar, buf, 10));
509  EXPECT_EQ(-1, readlink(kDummyConstChar, buf, 10));
510  ASSERT_EQ(kDummyErrno, errno);
511}
512
513#ifdef __GLIBC__
514// Under newlib there is no remove syscall.  Instead it is implemented
515// in terms of unlink()/rmdir().
516TEST_F(KernelWrapTest, remove) {
517  EXPECT_CALL(mock, remove(kDummyConstChar)).WillOnce(Return(-1));
518  EXPECT_EQ(-1, remove(kDummyConstChar));
519}
520#endif
521
522TEST_F(KernelWrapTest, rename) {
523  EXPECT_CALL(mock, rename(kDummyConstChar, kDummyConstChar2))
524      .WillOnce(Return(0))
525      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
526
527  EXPECT_EQ(0, rename(kDummyConstChar, kDummyConstChar2));
528  EXPECT_EQ(-1, rename(kDummyConstChar, kDummyConstChar2));
529  ASSERT_EQ(kDummyErrno, errno);
530}
531
532TEST_F(KernelWrapTest, rmdir) {
533  EXPECT_CALL(mock, rmdir(kDummyConstChar))
534      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
535  EXPECT_EQ(-1, rmdir(kDummyConstChar));
536  ASSERT_EQ(kDummyErrno, errno);
537}
538
539static void new_handler(int) {}
540
541TEST_F(KernelWrapTest, sigaction) {
542  struct sigaction action;
543  struct sigaction oaction;
544  EXPECT_CALL(mock, sigaction(kDummyInt, &action, &oaction))
545      .WillOnce(Return(0));
546  EXPECT_EQ(0, sigaction(kDummyInt, &action, &oaction));
547}
548
549TEST_F(KernelWrapTest, sigset) {
550  EXPECT_CALL(mock, sigaction(kDummyInt, _, _))
551      .WillOnce(Return(0));
552  EXPECT_EQ(NULL, sigset(kDummyInt, new_handler));
553}
554
555TEST_F(KernelWrapTest, signal) {
556  // KernelIntercept forwards calls to signal to KernelProxy::sigset.
557  EXPECT_CALL(mock, sigaction(kDummyInt, _, _))
558      .WillOnce(Return(0));
559  EXPECT_EQ(NULL, signal(kDummyInt, new_handler));
560}
561
562TEST_F(KernelWrapTest, stat) {
563  // The way we wrap stat does not support returning aribtrary values, only 0
564  // or -1.
565  struct stat in_statbuf;
566  MakeDummyStatbuf(&in_statbuf);
567  EXPECT_CALL(mock, stat(StrEq(kDummyConstChar), _))
568      .WillOnce(DoAll(SetStat(&in_statbuf), Return(0)))
569      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
570  struct stat out_statbuf;
571
572  EXPECT_EQ(0, stat(kDummyConstChar, &out_statbuf));
573  EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf));
574
575  EXPECT_EQ(-1, stat(kDummyConstChar, &out_statbuf));
576  ASSERT_EQ(kDummyErrno, errno);
577}
578
579TEST_F(KernelWrapTest, symlink) {
580  EXPECT_CALL(mock, symlink(kDummyConstChar, kDummyConstChar2))
581      .WillOnce(Return(kDummyInt));
582  EXPECT_EQ(kDummyInt, symlink(kDummyConstChar, kDummyConstChar2));
583}
584
585#ifndef __BIONIC__
586TEST_F(KernelWrapTest, tcflush) {
587  EXPECT_CALL(mock, tcflush(kDummyInt, kDummyInt2))
588      .WillOnce(Return(kDummyInt3));
589  EXPECT_EQ(kDummyInt3, tcflush(kDummyInt, kDummyInt2));
590}
591
592TEST_F(KernelWrapTest, tcgetattr) {
593  struct termios term;
594  EXPECT_CALL(mock, tcgetattr(kDummyInt, &term)).WillOnce(Return(kDummyInt2));
595  EXPECT_EQ(kDummyInt2, tcgetattr(kDummyInt, &term));
596}
597
598TEST_F(KernelWrapTest, tcsetattr) {
599  struct termios term;
600  EXPECT_CALL(mock, tcsetattr(kDummyInt, kDummyInt2, &term))
601      .WillOnce(Return(kDummyInt3));
602  EXPECT_EQ(kDummyInt3, tcsetattr(kDummyInt, kDummyInt2, &term));
603}
604#endif
605
606TEST_F(KernelWrapTest, umount) {
607  EXPECT_CALL(mock, umount(kDummyConstChar)).WillOnce(Return(kDummyInt));
608  EXPECT_EQ(kDummyInt, umount(kDummyConstChar));
609}
610
611TEST_F(KernelWrapTest, truncate) {
612  EXPECT_CALL(mock, truncate(kDummyConstChar, kDummyInt3))
613      .WillOnce(Return(0))
614      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
615
616  EXPECT_EQ(0, truncate(kDummyConstChar, kDummyInt3));
617
618  EXPECT_EQ(-1, truncate(kDummyConstChar, kDummyInt3));
619}
620
621TEST_F(KernelWrapTest, lstat) {
622  struct stat in_statbuf;
623  MakeDummyStatbuf(&in_statbuf);
624  EXPECT_CALL(mock, lstat(StrEq(kDummyConstChar), _))
625      .WillOnce(DoAll(SetStat(&in_statbuf), Return(0)))
626      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
627  struct stat out_statbuf;
628
629  EXPECT_EQ(0, lstat(kDummyConstChar, &out_statbuf));
630  EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf));
631
632  EXPECT_EQ(-1, lstat(kDummyConstChar, &out_statbuf));
633  ASSERT_EQ(kDummyErrno, errno);
634}
635
636TEST_F(KernelWrapTest, unlink) {
637  EXPECT_CALL(mock, unlink(kDummyConstChar))
638      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
639  EXPECT_EQ(-1, unlink(kDummyConstChar));
640  ASSERT_EQ(kDummyErrno, errno);
641}
642
643TEST_F(KernelWrapTest, utime) {
644  const struct utimbuf times = {123, 456};
645  EXPECT_CALL(mock, utimens(kDummyConstChar, IsEqualToUtimbuf(&times)))
646      .WillOnce(Return(kDummyInt));
647  EXPECT_EQ(kDummyInt, utime(kDummyConstChar, &times));
648}
649
650TEST_F(KernelWrapTest, utimes) {
651  struct timeval times[2] = {{123, 234}, {345, 456}};
652  EXPECT_CALL(mock, utimens(kDummyConstChar, IsEqualToTimeval(times)))
653      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
654  EXPECT_EQ(-1, utimes(kDummyConstChar, times));
655  ASSERT_EQ(kDummyErrno, errno);
656}
657
658TEST_F(KernelWrapTest, write) {
659  EXPECT_CALL(mock, write(kDummyInt, kDummyVoidPtr, kDummyInt2))
660      .WillOnce(Return(kDummyInt3));
661  EXPECT_EQ(kDummyInt3, write(kDummyInt, kDummyVoidPtr, kDummyInt2));
662}
663
664class KernelWrapTestUninit : public ::testing::Test {
665  void SetUp() {
666    ASSERT_EQ(0, ki_push_state_for_testing());
667    kernel_wrap_uninit();
668  }
669
670  void TearDown() {
671    kernel_wrap_init();
672    ki_pop_state_for_testing();
673  }
674};
675
676TEST_F(KernelWrapTestUninit, Mkdir_Uninitialised) {
677  // If we are running within chrome we can't use these calls without
678  // nacl_io initialized.
679  if (PSGetInstanceId() != 0)
680    return;
681  EXPECT_EQ(0, mkdir("./foo", S_IREAD | S_IWRITE));
682  EXPECT_EQ(0, rmdir("./foo"));
683}
684
685TEST_F(KernelWrapTestUninit, Getcwd_Uninitialised) {
686  // If we are running within chrome we can't use these calls without
687  // nacl_io initialized.
688  if (PSGetInstanceId() != 0)
689    return;
690  char dir[PATH_MAX];
691  ASSERT_NE((char*)NULL, getcwd(dir, PATH_MAX));
692  // Verify that the CWD ends with 'nacl_io_test'
693  const char* suffix = "nacl_io_test";
694  ASSERT_GT(strlen(dir), strlen(suffix));
695  ASSERT_EQ(0, strcmp(dir+strlen(dir)-strlen(suffix), suffix));
696}
697
698#if defined(PROVIDES_SOCKET_API) and !defined(__BIONIC__)
699TEST_F(KernelWrapTest, poll) {
700  struct pollfd fds;
701  EXPECT_CALL(mock, poll(&fds, kDummyInt, kDummyInt2))
702      .WillOnce(Return(kDummyInt3));
703  EXPECT_EQ(kDummyInt3, poll(&fds, kDummyInt, kDummyInt2));
704}
705
706TEST_F(KernelWrapTest, select) {
707  fd_set readfds;
708  fd_set writefds;
709  fd_set exceptfds;
710  EXPECT_CALL(mock, select(kDummyInt, &readfds, &writefds, &exceptfds, NULL))
711      .WillOnce(Return(kDummyInt2));
712  EXPECT_EQ(kDummyInt2,
713            select(kDummyInt, &readfds, &writefds, &exceptfds, NULL));
714}
715
716// Socket Functions
717TEST_F(KernelWrapTest, accept) {
718  struct sockaddr addr;
719  socklen_t len;
720  EXPECT_CALL(mock, accept(kDummyInt, &addr, &len))
721      .WillOnce(Return(kDummyInt2));
722  EXPECT_EQ(kDummyInt2, accept(kDummyInt, &addr, &len));
723}
724
725TEST_F(KernelWrapTest, bind) {
726  // The way we wrap bind does not support returning arbitrary values, so we
727  // test 0 and -1.
728  struct sockaddr addr;
729  EXPECT_CALL(mock, bind(kDummyInt, &addr, kDummyInt2))
730      .WillOnce(Return(0))
731      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
732  EXPECT_EQ(0, bind(kDummyInt, &addr, kDummyInt2));
733  EXPECT_EQ(-1, bind(kDummyInt, &addr, kDummyInt2));
734  EXPECT_EQ(kDummyErrno, errno);
735}
736
737TEST_F(KernelWrapTest, connect) {
738  // The way we wrap connect does not support returning arbitrary values, so we
739  // test 0 and -1.
740  struct sockaddr addr;
741  EXPECT_CALL(mock, connect(kDummyInt, &addr, kDummyInt2))
742      .WillOnce(Return(0))
743      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
744  EXPECT_EQ(0, connect(kDummyInt, &addr, kDummyInt2));
745  EXPECT_EQ(-1, connect(kDummyInt, &addr, kDummyInt2));
746  EXPECT_EQ(kDummyErrno, errno);
747}
748
749TEST_F(KernelWrapTest, gethostbyname) {
750  struct hostent result;
751  EXPECT_CALL(mock, gethostbyname(kDummyConstChar)).WillOnce(Return(&result));
752  EXPECT_EQ(&result, gethostbyname(kDummyConstChar));
753}
754
755TEST_F(KernelWrapTest, getpeername) {
756  // The way we wrap getpeername does not support returning arbitrary values,
757  // so we test 0 and -1.
758  struct sockaddr addr;
759  socklen_t len;
760  EXPECT_CALL(mock, getpeername(kDummyInt, &addr, &len))
761      .WillOnce(Return(0))
762      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
763  EXPECT_EQ(0, getpeername(kDummyInt, &addr, &len));
764  EXPECT_EQ(-1, getpeername(kDummyInt, &addr, &len));
765  EXPECT_EQ(kDummyErrno, errno);
766}
767
768TEST_F(KernelWrapTest, getsockname) {
769  // The way we wrap getsockname does not support returning arbitrary values,
770  // so we test 0 and -1.
771  struct sockaddr addr;
772  socklen_t len;
773
774  EXPECT_CALL(mock, getsockname(kDummyInt, &addr, &len))
775      .WillOnce(Return(0))
776      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
777  EXPECT_EQ(0, getsockname(kDummyInt, &addr, &len));
778  EXPECT_EQ(-1, getsockname(kDummyInt, &addr, &len));
779  EXPECT_EQ(kDummyErrno, errno);
780}
781
782TEST_F(KernelWrapTest, getsockopt) {
783  // The way we wrap getsockname does not support returning arbitrary values,
784  // so we test 0 and -1.
785  int dummy_val;
786  void* dummy_void_ptr = &dummy_val;
787  socklen_t len;
788  EXPECT_CALL(
789      mock, getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len))
790      .WillOnce(Return(0))
791      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
792  EXPECT_EQ(
793      0,
794      getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len));
795  EXPECT_EQ(
796      -1,
797      getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len));
798  EXPECT_EQ(kDummyErrno, errno);
799}
800
801TEST_F(KernelWrapTest, listen) {
802  // The way we wrap listen does not support returning arbitrary values, so we
803  // test 0 and -1.
804  EXPECT_CALL(mock, listen(kDummyInt, kDummyInt2))
805      .WillOnce(Return(0))
806      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
807  EXPECT_EQ(0, listen(kDummyInt, kDummyInt2));
808  EXPECT_EQ(-1, listen(kDummyInt, kDummyInt2));
809  EXPECT_EQ(kDummyErrno, errno);
810}
811
812TEST_F(KernelWrapTest, recv) {
813  int dummy_val;
814  void* dummy_void_ptr = &dummy_val;
815  EXPECT_CALL(mock, recv(kDummyInt, dummy_void_ptr, kDummySizeT, kDummyInt2))
816      .WillOnce(Return(kDummyInt3));
817  EXPECT_EQ(kDummyInt3,
818            recv(kDummyInt, dummy_void_ptr, kDummySizeT, kDummyInt2));
819}
820
821TEST_F(KernelWrapTest, recvfrom) {
822  int dummy_val;
823  void* dummy_void_ptr = &dummy_val;
824  struct sockaddr addr;
825  socklen_t len;
826  EXPECT_CALL(
827      mock,
828      recvfrom(kDummyInt, dummy_void_ptr, kDummyInt2, kDummyInt3, &addr, &len))
829      .WillOnce(Return(kDummyInt4));
830  EXPECT_EQ(
831      kDummyInt4,
832      recvfrom(kDummyInt, dummy_void_ptr, kDummyInt2, kDummyInt3, &addr, &len));
833}
834
835#ifndef __BIONIC__
836TEST_F(KernelWrapTest, recvmsg) {
837  struct msghdr msg;
838  EXPECT_CALL(mock, recvmsg(kDummyInt, &msg, kDummyInt2))
839      .WillOnce(Return(kDummyInt3));
840  EXPECT_EQ(kDummyInt3, recvmsg(kDummyInt, &msg, kDummyInt2));
841}
842#endif
843
844TEST_F(KernelWrapTest, send) {
845  EXPECT_CALL(mock, send(kDummyInt, kDummyVoidPtr, kDummySizeT, kDummyInt2))
846      .WillOnce(Return(kDummyInt3));
847  EXPECT_EQ(kDummyInt3,
848            send(kDummyInt, kDummyVoidPtr, kDummySizeT, kDummyInt2));
849}
850
851TEST_F(KernelWrapTest, sendto) {
852  const socklen_t kDummySockLen = 0x50cc5;
853  struct sockaddr addr;
854  EXPECT_CALL(mock,
855              sendto(kDummyInt,
856                     kDummyVoidPtr,
857                     kDummyInt2,
858                     kDummyInt3,
859                     &addr,
860                     kDummySockLen)).WillOnce(Return(kDummyInt4));
861  EXPECT_EQ(kDummyInt4,
862            sendto(kDummyInt,
863                   kDummyVoidPtr,
864                   kDummyInt2,
865                   kDummyInt3,
866                   &addr,
867                   kDummySockLen));
868}
869
870TEST_F(KernelWrapTest, sendmsg) {
871  struct msghdr msg;
872  EXPECT_CALL(mock, sendmsg(kDummyInt, &msg, kDummyInt2))
873      .WillOnce(Return(kDummyInt3));
874  EXPECT_EQ(kDummyInt3, sendmsg(kDummyInt, &msg, kDummyInt2));
875}
876
877TEST_F(KernelWrapTest, setsockopt) {
878  // The way we wrap setsockopt does not support returning arbitrary values, so
879  // we test 0 and -1.
880  const socklen_t kDummySockLen = 0x50cc5;
881  EXPECT_CALL(
882      mock,
883      setsockopt(
884          kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen))
885      .WillOnce(Return(0))
886      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
887  EXPECT_EQ(
888      0,
889      setsockopt(
890          kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen));
891  EXPECT_EQ(
892      -1,
893      setsockopt(
894          kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen));
895  EXPECT_EQ(kDummyErrno, errno);
896}
897
898TEST_F(KernelWrapTest, shutdown) {
899  // The way we wrap shutdown does not support returning arbitrary values, so we
900  // test 0 and -1.
901  EXPECT_CALL(mock, shutdown(kDummyInt, kDummyInt2))
902      .WillOnce(Return(0))
903      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
904  EXPECT_EQ(0, shutdown(kDummyInt, kDummyInt2));
905  EXPECT_EQ(-1, shutdown(kDummyInt, kDummyInt2));
906  EXPECT_EQ(kDummyErrno, errno);
907}
908
909TEST_F(KernelWrapTest, socket) {
910  EXPECT_CALL(mock, socket(kDummyInt, kDummyInt2, kDummyInt3))
911      .WillOnce(Return(kDummyInt4));
912  EXPECT_EQ(kDummyInt4, socket(kDummyInt, kDummyInt2, kDummyInt3));
913}
914
915TEST_F(KernelWrapTest, socketpair) {
916  // The way we wrap socketpair does not support returning arbitrary values,
917  // so we test 0 and -1.
918  int dummy_val;
919  EXPECT_CALL(mock, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val))
920      .WillOnce(Return(0))
921      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
922  EXPECT_EQ(0, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val));
923  EXPECT_EQ(-1, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val));
924  EXPECT_EQ(kDummyErrno, errno);
925}
926
927#endif  // PROVIDES_SOCKET_API
928
929#endif  // __linux__
930