kernel_wrap_test.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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, fcntl) { 155 char buffer[] = "fcntl"; 156 EXPECT_CALL(mock, fcntl(012, 345, StrEq("fcntl"))).Times(1); 157 fcntl(012, 345, buffer); 158} 159 160TEST_F(KernelWrapTest, fstat) { 161 struct stat in_statbuf; 162 MakeDummyStatbuf(&in_statbuf); 163 EXPECT_CALL(mock, fstat(DUMMY_FD, _)) 164 .Times(1) 165 .WillOnce(SetStat(&in_statbuf)); 166 struct stat out_statbuf; 167 fstat(DUMMY_FD, &out_statbuf); 168 EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf)); 169} 170 171TEST_F(KernelWrapTest, ftruncate) { 172 EXPECT_CALL(mock, ftruncate(456, 0)).Times(1); 173 ftruncate(456, 0); 174} 175 176TEST_F(KernelWrapTest, fsync) { 177 EXPECT_CALL(mock, fsync(345)).Times(1); 178 fsync(345); 179} 180 181TEST_F(KernelWrapTest, getcwd) { 182 EXPECT_CALL(mock, getcwd(StrEq("getcwd"), 1)).Times(1); 183 char buffer[] = "getcwd"; 184 getcwd(buffer, 1); 185} 186 187TEST_F(KernelWrapTest, getdents) { 188#ifndef __GLIBC__ 189 // TODO(sbc): Find a way to test the getdents wrapper under glibc. 190 // It looks like the only way to excerside it is to call readdir(2). 191 // There is an internal glibc function __getdents that will call the 192 // IRT but that cannot be accessed from here as glibc does not export it. 193 EXPECT_CALL(mock, getdents(456, NULL, 567)).WillOnce(Return(678)); 194 EXPECT_EQ(getdents(456, NULL, 567), 678); 195#endif 196} 197 198// gcc gives error: getwd is deprecated. 199#if defined(__GNUC__) 200#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 201#endif 202TEST_F(KernelWrapTest, getwd) { 203 EXPECT_CALL(mock, getwd(StrEq("getwd"))).Times(1); 204 char buffer[] = "getwd"; 205 getwd(buffer); 206} 207#if defined(__GNUC__) 208#pragma GCC diagnostic warning "-Wdeprecated-declarations" 209#endif 210 211TEST_F(KernelWrapTest, ioctl) { 212 char buffer[] = "ioctl"; 213 EXPECT_CALL(mock, ioctl(012, 345, StrEq("ioctl"))).Times(1); 214 ioctl(012, 345, buffer); 215} 216 217TEST_F(KernelWrapTest, isatty) { 218 EXPECT_CALL(mock, isatty(678)).Times(1); 219 isatty(678); 220} 221 222TEST_F(KernelWrapTest, kill) { 223 EXPECT_CALL(mock, kill(22, 33)).Times(1); 224 kill(22, 33); 225} 226 227TEST_F(KernelWrapTest, lchown) { 228 uid_t uid = kDummyUid; 229 gid_t gid = kDummyGid; 230 EXPECT_CALL(mock, lchown(StrEq("lchown"), uid, gid)).Times(1); 231 lchown("lchown", uid, gid); 232} 233 234TEST_F(KernelWrapTest, lseek) { 235 EXPECT_CALL(mock, lseek(789, 891, 912)).Times(1); 236 lseek(789, 891, 912); 237} 238 239TEST_F(KernelWrapTest, mkdir) { 240#if defined(WIN32) 241 EXPECT_CALL(mock, mkdir(StrEq("mkdir"), 0777)).Times(1); 242 mkdir("mkdir"); 243#else 244 EXPECT_CALL(mock, mkdir(StrEq("mkdir"), 1234)).Times(1); 245 mkdir("mkdir", 1234); 246#endif 247} 248 249TEST_F(KernelWrapTest, mount) { 250 EXPECT_CALL(mock, 251 mount(StrEq("mount1"), StrEq("mount2"), StrEq("mount3"), 2345, NULL)) 252 .Times(1); 253 mount("mount1", "mount2", "mount3", 2345, NULL); 254} 255 256TEST_F(KernelWrapTest, open) { 257 EXPECT_CALL(mock, open(StrEq("open"), 3456)).Times(1); 258 open("open", 3456); 259} 260 261TEST_F(KernelWrapTest, pipe) { 262 int fds[2] = { 1, 2 }; 263 264 EXPECT_CALL(mock, pipe(fds)).Times(1); 265 pipe(fds); 266} 267 268TEST_F(KernelWrapTest, read) { 269 EXPECT_CALL(mock, read(4567, NULL, 5678)).Times(1); 270 read(4567, NULL, 5678); 271} 272 273#ifdef __GLIBC__ 274TEST_F(KernelWrapTest, remove) { 275 EXPECT_CALL(mock, remove(StrEq("remove"))).Times(1); 276 remove("remove"); 277} 278#endif 279 280TEST_F(KernelWrapTest, rmdir) { 281 EXPECT_CALL(mock, rmdir(StrEq("rmdir"))).Times(1); 282 rmdir("rmdir"); 283} 284 285static void handler(int) { 286} 287 288TEST_F(KernelWrapTest, sigset) { 289 EXPECT_CALL(mock, sigset(22, handler)).Times(1); 290 sigset(22, handler); 291} 292 293TEST_F(KernelWrapTest, signal) { 294 EXPECT_CALL(mock, sigset(22, handler)).Times(1); 295 signal(22, handler); 296} 297 298TEST_F(KernelWrapTest, stat) { 299 struct stat in_statbuf; 300 MakeDummyStatbuf(&in_statbuf); 301 EXPECT_CALL(mock, stat(StrEq("stat"), _)) 302 .Times(1) 303 .WillOnce(SetStat(&in_statbuf)); 304 struct stat out_statbuf; 305 stat("stat", &out_statbuf); 306 EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf)); 307} 308 309TEST_F(KernelWrapTest, tcgetattr) { 310 struct termios term; 311 EXPECT_CALL(mock, tcgetattr(DUMMY_FD, &term)).Times(1); 312 tcgetattr(DUMMY_FD, &term); 313} 314 315TEST_F(KernelWrapTest, tcsetattr) { 316 struct termios term; 317 EXPECT_CALL(mock, tcsetattr(DUMMY_FD, 0, &term)).Times(1); 318 tcsetattr(DUMMY_FD, 0, &term); 319} 320 321TEST_F(KernelWrapTest, umount) { 322 EXPECT_CALL(mock, umount(StrEq("umount"))).Times(1); 323 umount("umount"); 324} 325 326TEST_F(KernelWrapTest, unlink) { 327 EXPECT_CALL(mock, unlink(StrEq("unlink"))).Times(1); 328 unlink("unlink"); 329} 330 331TEST_F(KernelWrapTest, utime) { 332 const struct utimbuf* times = NULL; 333 EXPECT_CALL(mock, utime(StrEq("utime"), times)); 334 utime("utime", times); 335} 336 337TEST_F(KernelWrapTest, write) { 338 EXPECT_CALL(mock, write(6789, NULL, 7891)).Times(1); 339 write(6789, NULL, 7891); 340} 341 342#ifdef PROVIDES_SOCKET_API 343TEST_F(KernelWrapTest, poll) { 344 EXPECT_CALL(mock, poll(NULL, 5, -1)); 345 poll(NULL, 5, -1); 346} 347 348TEST_F(KernelWrapTest, select) { 349 EXPECT_CALL(mock, select(123, NULL, NULL, NULL, NULL)); 350 select(123, NULL, NULL, NULL, NULL); 351} 352 353// Socket Functions 354TEST_F(KernelWrapTest, accept) { 355 EXPECT_CALL(mock, accept(DUMMY_FD, NULL, NULL)).Times(1); 356 accept(DUMMY_FD, NULL, NULL); 357} 358 359TEST_F(KernelWrapTest, bind) { 360 EXPECT_CALL(mock, bind(DUMMY_FD, NULL, 456)).Times(1); 361 bind(DUMMY_FD, NULL, 456); 362} 363 364TEST_F(KernelWrapTest, connect) { 365 EXPECT_CALL(mock, connect(DUMMY_FD, NULL, 456)).Times(1); 366 connect(DUMMY_FD, NULL, 456); 367} 368 369TEST_F(KernelWrapTest, gethostbyname) { 370 EXPECT_CALL(mock, gethostbyname(NULL)).Times(1); 371 gethostbyname(NULL); 372} 373 374TEST_F(KernelWrapTest, getpeername) { 375 EXPECT_CALL(mock, getpeername(DUMMY_FD, NULL, NULL)).Times(1); 376 getpeername(DUMMY_FD, NULL, NULL); 377} 378 379TEST_F(KernelWrapTest, getsockname) { 380 EXPECT_CALL(mock, getsockname(DUMMY_FD, NULL, NULL)).Times(1); 381 getsockname(DUMMY_FD, NULL, NULL); 382} 383 384TEST_F(KernelWrapTest, getsockopt) { 385 EXPECT_CALL(mock, getsockopt(DUMMY_FD, 456, 789, NULL, NULL)).Times(1); 386 getsockopt(DUMMY_FD, 456, 789, NULL, NULL); 387} 388 389TEST_F(KernelWrapTest, listen) { 390 EXPECT_CALL(mock, listen(DUMMY_FD, 456)).Times(1); 391 listen(DUMMY_FD, 456); 392} 393 394TEST_F(KernelWrapTest, recv) { 395 EXPECT_CALL(mock, recv(DUMMY_FD, NULL, 456, 789)).Times(1); 396 recv(DUMMY_FD, NULL, 456, 789); 397} 398 399TEST_F(KernelWrapTest, recvfrom) { 400 EXPECT_CALL(mock, recvfrom(DUMMY_FD, NULL, 456, 789, NULL, NULL)).Times(1); 401 recvfrom(DUMMY_FD, NULL, 456, 789, NULL, NULL); 402} 403 404TEST_F(KernelWrapTest, recvmsg) { 405 EXPECT_CALL(mock, recvmsg(DUMMY_FD, NULL, 456)).Times(1); 406 recvmsg(DUMMY_FD, NULL, 456); 407} 408 409TEST_F(KernelWrapTest, send) { 410 EXPECT_CALL(mock, send(DUMMY_FD, NULL, 456, 789)).Times(1); 411 send(DUMMY_FD, NULL, 456, 789); 412} 413 414TEST_F(KernelWrapTest, sendto) { 415 EXPECT_CALL(mock, sendto(DUMMY_FD, NULL, 456, 789, NULL, 314)).Times(1); 416 sendto(DUMMY_FD, NULL, 456, 789, NULL, 314); 417} 418 419TEST_F(KernelWrapTest, sendmsg) { 420 EXPECT_CALL(mock, sendmsg(DUMMY_FD, NULL, 456)).Times(1); 421 sendmsg(DUMMY_FD, NULL, 456); 422} 423 424TEST_F(KernelWrapTest, setsockopt) { 425 EXPECT_CALL(mock, setsockopt(DUMMY_FD, 456, 789, NULL, 314)).Times(1); 426 setsockopt(DUMMY_FD, 456, 789, NULL, 314); 427} 428 429TEST_F(KernelWrapTest, shutdown) { 430 EXPECT_CALL(mock, shutdown(DUMMY_FD, 456)).Times(1); 431 shutdown(DUMMY_FD, 456); 432} 433 434TEST_F(KernelWrapTest, socket) { 435 EXPECT_CALL(mock, socket(DUMMY_FD, 456, 789)).Times(1); 436 socket(DUMMY_FD, 456, 789); 437} 438 439TEST_F(KernelWrapTest, socketpair) { 440 EXPECT_CALL(mock, socketpair(DUMMY_FD, 456, 789, NULL)).Times(1); 441 socketpair(DUMMY_FD, 456, 789, NULL); 442} 443 444#endif // PROVIDES_SOCKET_API 445