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