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