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 15 using namespace nacl_io; 16 17 using ::testing::_; 18 using ::testing::Return; 19 using ::testing::StrEq; 20 21 namespace { 22 23 static 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 33 MATCHER_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 50 ACTION_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 66 void 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 81 const uid_t kDummyUid = 1001; 82 const gid_t kDummyGid = 1002; 83 84 class 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 110 TEST_F(KernelWrapTest, access) { 111 EXPECT_CALL(mock, access(StrEq("access"), 12)).Times(1); 112 access("access", 12); 113 } 114 115 TEST_F(KernelWrapTest, chdir) { 116 EXPECT_CALL(mock, chdir(StrEq("chdir"))).Times(1); 117 chdir("chdir"); 118 } 119 120 TEST_F(KernelWrapTest, chmod) { 121 EXPECT_CALL(mock, chmod(StrEq("chmod"), 23)).Times(1); 122 chmod("chmod", 23); 123 } 124 125 TEST_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 132 TEST_F(KernelWrapTest, close) { 133 EXPECT_CALL(mock, close(34)).Times(1); 134 close(34); 135 } 136 137 TEST_F(KernelWrapTest, dup) { 138 EXPECT_CALL(mock, dup(DUMMY_FD)).Times(1); 139 dup(DUMMY_FD); 140 } 141 142 TEST_F(KernelWrapTest, dup2) { 143 EXPECT_CALL(mock, dup2(DUMMY_FD, 234)).Times(1); 144 dup2(DUMMY_FD, 234); 145 } 146 147 TEST_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 154 TEST_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 165 TEST_F(KernelWrapTest, ftruncate) { 166 EXPECT_CALL(mock, ftruncate(456, 0)).Times(1); 167 ftruncate(456, 0); 168 } 169 170 TEST_F(KernelWrapTest, fsync) { 171 EXPECT_CALL(mock, fsync(345)).Times(1); 172 fsync(345); 173 } 174 175 TEST_F(KernelWrapTest, getcwd) { 176 EXPECT_CALL(mock, getcwd(StrEq("getcwd"), 1)).Times(1); 177 char buffer[] = "getcwd"; 178 getcwd(buffer, 1); 179 } 180 181 TEST_F(KernelWrapTest, getdents) { 182 EXPECT_CALL(mock, getdents(456, NULL, 567)).Times(1); 183 getdents(456, NULL, 567); 184 } 185 186 // gcc gives error: getwd is deprecated. 187 #if defined(__GNUC__) 188 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 189 #endif 190 TEST_F(KernelWrapTest, getwd) { 191 EXPECT_CALL(mock, getwd(StrEq("getwd"))).Times(1); 192 char buffer[] = "getwd"; 193 getwd(buffer); 194 } 195 #if defined(__GNUC__) 196 #pragma GCC diagnostic warning "-Wdeprecated-declarations" 197 #endif 198 199 TEST_F(KernelWrapTest, ioctl) { 200 char buffer[] = "ioctl"; 201 EXPECT_CALL(mock, ioctl(012, 345, StrEq("ioctl"))).Times(1); 202 ioctl(012, 345, buffer); 203 } 204 205 TEST_F(KernelWrapTest, isatty) { 206 EXPECT_CALL(mock, isatty(678)).Times(1); 207 isatty(678); 208 } 209 210 TEST_F(KernelWrapTest, lchown) { 211 uid_t uid = kDummyUid; 212 gid_t gid = kDummyGid; 213 EXPECT_CALL(mock, lchown(StrEq("lchown"), uid, gid)).Times(1); 214 lchown("lchown", uid, gid); 215 } 216 217 TEST_F(KernelWrapTest, lseek) { 218 EXPECT_CALL(mock, lseek(789, 891, 912)).Times(1); 219 lseek(789, 891, 912); 220 } 221 222 TEST_F(KernelWrapTest, mkdir) { 223 #if defined(WIN32) 224 EXPECT_CALL(mock, mkdir(StrEq("mkdir"), 0777)).Times(1); 225 mkdir("mkdir"); 226 #else 227 EXPECT_CALL(mock, mkdir(StrEq("mkdir"), 1234)).Times(1); 228 mkdir("mkdir", 1234); 229 #endif 230 } 231 232 TEST_F(KernelWrapTest, mount) { 233 EXPECT_CALL(mock, 234 mount(StrEq("mount1"), StrEq("mount2"), StrEq("mount3"), 2345, NULL)) 235 .Times(1); 236 mount("mount1", "mount2", "mount3", 2345, NULL); 237 } 238 239 TEST_F(KernelWrapTest, open) { 240 EXPECT_CALL(mock, open(StrEq("open"), 3456)).Times(1); 241 open("open", 3456); 242 } 243 244 TEST_F(KernelWrapTest, read) { 245 EXPECT_CALL(mock, read(4567, NULL, 5678)).Times(1); 246 read(4567, NULL, 5678); 247 } 248 249 TEST_F(KernelWrapTest, remove) { 250 EXPECT_CALL(mock, remove(StrEq("remove"))).Times(1); 251 remove("remove"); 252 } 253 254 TEST_F(KernelWrapTest, rmdir) { 255 EXPECT_CALL(mock, rmdir(StrEq("rmdir"))).Times(1); 256 rmdir("rmdir"); 257 } 258 259 TEST_F(KernelWrapTest, stat) { 260 struct stat in_statbuf; 261 MakeDummyStatbuf(&in_statbuf); 262 EXPECT_CALL(mock, stat(StrEq("stat"), _)) 263 .Times(1) 264 .WillOnce(SetStat(&in_statbuf)); 265 struct stat out_statbuf; 266 stat("stat", &out_statbuf); 267 EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf)); 268 } 269 270 TEST_F(KernelWrapTest, tcgetattr) { 271 struct termios term; 272 EXPECT_CALL(mock, tcgetattr(DUMMY_FD, &term)).Times(1); 273 tcgetattr(DUMMY_FD, &term); 274 } 275 276 TEST_F(KernelWrapTest, tcsetattr) { 277 struct termios term; 278 EXPECT_CALL(mock, tcsetattr(DUMMY_FD, 0, &term)).Times(1); 279 tcsetattr(DUMMY_FD, 0, &term); 280 } 281 282 TEST_F(KernelWrapTest, umount) { 283 EXPECT_CALL(mock, umount(StrEq("umount"))).Times(1); 284 umount("umount"); 285 } 286 287 TEST_F(KernelWrapTest, unlink) { 288 EXPECT_CALL(mock, unlink(StrEq("unlink"))).Times(1); 289 unlink("unlink"); 290 } 291 292 TEST_F(KernelWrapTest, utime) { 293 const struct utimbuf* times = NULL; 294 EXPECT_CALL(mock, utime(StrEq("utime"), times)); 295 utime("utime", times); 296 } 297 298 TEST_F(KernelWrapTest, write) { 299 EXPECT_CALL(mock, write(6789, NULL, 7891)).Times(1); 300 write(6789, NULL, 7891); 301 } 302 303 #ifdef PROVIDES_SOCKET_API 304 TEST_F(KernelWrapTest, poll) { 305 EXPECT_CALL(mock, poll(NULL, 5, -1)); 306 poll(NULL, 5, -1); 307 } 308 309 TEST_F(KernelWrapTest, select) { 310 EXPECT_CALL(mock, select(123, NULL, NULL, NULL, NULL)); 311 select(123, NULL, NULL, NULL, NULL); 312 } 313 314 // Socket Functions 315 TEST_F(KernelWrapTest, accept) { 316 EXPECT_CALL(mock, accept(DUMMY_FD, NULL, NULL)).Times(1); 317 accept(DUMMY_FD, NULL, NULL); 318 } 319 320 TEST_F(KernelWrapTest, bind) { 321 EXPECT_CALL(mock, bind(DUMMY_FD, NULL, 456)).Times(1); 322 bind(DUMMY_FD, NULL, 456); 323 } 324 325 TEST_F(KernelWrapTest, connect) { 326 EXPECT_CALL(mock, connect(DUMMY_FD, NULL, 456)).Times(1); 327 connect(DUMMY_FD, NULL, 456); 328 } 329 330 TEST_F(KernelWrapTest, gethostbyname) { 331 EXPECT_CALL(mock, gethostbyname(NULL)).Times(1); 332 gethostbyname(NULL); 333 } 334 335 TEST_F(KernelWrapTest, getpeername) { 336 EXPECT_CALL(mock, getpeername(DUMMY_FD, NULL, NULL)).Times(1); 337 getpeername(DUMMY_FD, NULL, NULL); 338 } 339 340 TEST_F(KernelWrapTest, getsockname) { 341 EXPECT_CALL(mock, getsockname(DUMMY_FD, NULL, NULL)).Times(1); 342 getsockname(DUMMY_FD, NULL, NULL); 343 } 344 345 TEST_F(KernelWrapTest, getsockopt) { 346 EXPECT_CALL(mock, getsockopt(DUMMY_FD, 456, 789, NULL, NULL)).Times(1); 347 getsockopt(DUMMY_FD, 456, 789, NULL, NULL); 348 } 349 350 TEST_F(KernelWrapTest, listen) { 351 EXPECT_CALL(mock, listen(DUMMY_FD, 456)).Times(1); 352 listen(DUMMY_FD, 456); 353 } 354 355 TEST_F(KernelWrapTest, recv) { 356 EXPECT_CALL(mock, recv(DUMMY_FD, NULL, 456, 789)).Times(1); 357 recv(DUMMY_FD, NULL, 456, 789); 358 } 359 360 TEST_F(KernelWrapTest, recvfrom) { 361 EXPECT_CALL(mock, recvfrom(DUMMY_FD, NULL, 456, 789, NULL, NULL)).Times(1); 362 recvfrom(DUMMY_FD, NULL, 456, 789, NULL, NULL); 363 } 364 365 TEST_F(KernelWrapTest, recvmsg) { 366 EXPECT_CALL(mock, recvmsg(DUMMY_FD, NULL, 456)).Times(1); 367 recvmsg(DUMMY_FD, NULL, 456); 368 } 369 370 TEST_F(KernelWrapTest, send) { 371 EXPECT_CALL(mock, send(DUMMY_FD, NULL, 456, 789)).Times(1); 372 send(DUMMY_FD, NULL, 456, 789); 373 } 374 375 TEST_F(KernelWrapTest, sendto) { 376 EXPECT_CALL(mock, sendto(DUMMY_FD, NULL, 456, 789, NULL, 314)).Times(1); 377 sendto(DUMMY_FD, NULL, 456, 789, NULL, 314); 378 } 379 380 TEST_F(KernelWrapTest, sendmsg) { 381 EXPECT_CALL(mock, sendmsg(DUMMY_FD, NULL, 456)).Times(1); 382 sendmsg(DUMMY_FD, NULL, 456); 383 } 384 385 TEST_F(KernelWrapTest, setsockopt) { 386 EXPECT_CALL(mock, setsockopt(DUMMY_FD, 456, 789, NULL, 314)).Times(1); 387 setsockopt(DUMMY_FD, 456, 789, NULL, 314); 388 } 389 390 TEST_F(KernelWrapTest, shutdown) { 391 EXPECT_CALL(mock, shutdown(DUMMY_FD, 456)).Times(1); 392 shutdown(DUMMY_FD, 456); 393 } 394 395 TEST_F(KernelWrapTest, socket) { 396 EXPECT_CALL(mock, socket(DUMMY_FD, 456, 789)).Times(1); 397 socket(DUMMY_FD, 456, 789); 398 } 399 400 TEST_F(KernelWrapTest, socketpair) { 401 EXPECT_CALL(mock, socketpair(DUMMY_FD, 456, 789, NULL)).Times(1); 402 socketpair(DUMMY_FD, 456, 789, NULL); 403 } 404 405 #endif // PROVIDES_SOCKET_API 406