15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <fcntl.h> 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <gtest/gtest.h> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string> 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector> 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/fuse.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/fusefs/fuse_fs.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/kernel_handle.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/kernel_intercept.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/kernel_proxy.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "nacl_io/ostime.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using namespace nacl_io; 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FuseFsForTesting : public FuseFs { 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit FuseFsForTesting(fuse_operations* fuse_ops) { 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsInitArgs args; 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.fuse_ops = fuse_ops; 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, Init(args)); 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Implementation of a simple flat memory filesystem. 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct File { 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci File() : mode(0666) { memset(×, 0, sizeof(times)); } 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string name; 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<uint8_t> data; 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mode_t mode; 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci timespec times[2]; 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef std::vector<File> Files; 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Files g_files; 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsValidPath(const char* path) { 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (path == NULL) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (strlen(path) <= 1) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (path[0] != '/') 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)File* FindFile(const char* path) { 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsValidPath(path)) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (Files::iterator iter = g_files.begin(); iter != g_files.end(); ++iter) { 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter->name == &path[1]) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return &*iter; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int testfs_getattr(const char* path, struct stat* stbuf) { 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(stbuf, 0, sizeof(struct stat)); 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (strcmp(path, "/") == 0) { 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stbuf->st_mode = S_IFDIR | 0755; 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File* file = FindFile(path); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (file == NULL) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -ENOENT; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stbuf->st_mode = S_IFREG | file->mode; 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stbuf->st_size = file->data.size(); 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stbuf->st_atime = file->times[0].tv_sec; 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stbuf->st_atimensec = file->times[0].tv_nsec; 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stbuf->st_mtime = file->times[1].tv_sec; 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stbuf->st_mtimensec = file->times[1].tv_nsec; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int testfs_readdir(const char* path, 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void* buf, 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fuse_fill_dir_t filler, 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) off_t offset, 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct fuse_file_info*) { 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (strcmp(path, "/") != 0) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -ENOENT; 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) filler(buf, ".", NULL, 0); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) filler(buf, "..", NULL, 0); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (Files::iterator iter = g_files.begin(); iter != g_files.end(); ++iter) { 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) filler(buf, iter->name.c_str(), NULL, 0); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint testfs_create(const char* path, mode_t mode, struct fuse_file_info* fi) { 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsValidPath(path)) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -ENOENT; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File* file = FindFile(path); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (file != NULL) { 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fi->flags & O_EXCL) 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -EEXIST; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_files.push_back(File()); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file = &g_files.back(); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file->name = &path[1]; // Skip initial / 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file->mode = mode; 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int testfs_open(const char* path, struct fuse_file_info*) { 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // open is only called to open an existing file, otherwise create is 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // called. We don't need to do any additional work here, the path will be 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // passed to any other operations. 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return FindFile(path) != NULL; 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int testfs_read(const char* path, 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char* buf, 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t size, 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) off_t offset, 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct fuse_file_info* fi) { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File* file = FindFile(path); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (file == NULL) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -ENOENT; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t filesize = file->data.size(); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Trying to read past the end of the file. 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (offset >= filesize) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (offset + size > filesize) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size = filesize - offset; 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(buf, file->data.data() + offset, size); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return size; 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int testfs_write(const char* path, 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* buf, 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t size, 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) off_t offset, 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct fuse_file_info*) { 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File* file = FindFile(path); 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (file == NULL) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -ENOENT; 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t filesize = file->data.size(); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (offset + size > filesize) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file->data.resize(offset + size); 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(file->data.data() + offset, buf, size); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return size; 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint testfs_utimens(const char* path, const struct timespec times[2]) { 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci File* file = FindFile(path); 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (file == NULL) 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return -ENOENT; 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file->times[0] = times[0]; 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file->times[1] = times[1]; 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return 0; 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint testfs_chmod(const char* path, mode_t mode) { 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci File* file = FindFile(path); 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (file == NULL) 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return -ENOENT; 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file->mode = mode; 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return 0; 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char hello_world[] = "Hello, World!\n"; 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)fuse_operations g_fuse_operations = { 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0, // flag_nopath 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0, // flag_reserved 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testfs_getattr, // getattr 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // readlink 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // mknod 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // mkdir 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // unlink 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // rmdir 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // symlink 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // rename 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // link 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testfs_chmod, // chmod 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // chown 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // truncate 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testfs_open, // open 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testfs_read, // read 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testfs_write, // write 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // statfs 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // flush 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // release 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // fsync 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // setxattr 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // getxattr 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // listxattr 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // removexattr 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // opendir 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testfs_readdir, // readdir 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // releasedir 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // fsyncdir 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // init 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // destroy 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // access 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testfs_create, // create 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // ftruncate 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // fgetattr 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // lock 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testfs_utimens, // utimens 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // bmap 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // ioctl 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // poll 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // write_buf 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // read_buf 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // flock 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, // fallocate 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FuseFsTest : public ::testing::Test { 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FuseFsTest(); 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetUp(); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FuseFsForTesting fs_; 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FuseFsTest::FuseFsTest() : fs_(&g_fuse_operations) {} 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FuseFsTest::SetUp() { 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Reset the filesystem. 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_files.clear(); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add a built-in file. 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t hello_len = strlen(hello_world); 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File hello; 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hello.name = "hello"; 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hello.data.resize(hello_len); 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(hello.data.data(), hello_world, hello_len); 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_files.push_back(hello); 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FuseFsTest, OpenAndRead) { 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs_.Open(Path("/hello"), O_RDONLY, &node)); 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char buffer[15] = {0}; 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int bytes_read = 0; 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HandleAttr attr; 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(strlen(hello_world), bytes_read); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_STREQ(hello_world, buffer); 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Try to read past the end of the file. 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci attr.offs = strlen(hello_world) - 7; 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(7, bytes_read); 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_STREQ("World!\n", buffer); 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(FuseFsTest, CreateWithMode) { 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedNode node; 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct stat statbuf; 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, fs_.OpenWithMode(Path("/hello"), 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci O_RDWR | O_CREAT, 0723, &node)); 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, node->GetStat(&statbuf)); 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(S_IFREG, statbuf.st_mode & S_IFMT); 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0723, statbuf.st_mode & ~S_IFMT); 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FuseFsTest, CreateAndWrite) { 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs_.Open(Path("/foobar"), O_RDWR | O_CREAT, &node)); 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HandleAttr attr; 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char message[] = "Something interesting"; 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int bytes_written; 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, node->Write(attr, &message[0], strlen(message), &bytes_written)); 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(bytes_written, strlen(message)); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Now try to read the data back. 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char buffer[40] = {0}; 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int bytes_read = 0; 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(strlen(message), bytes_read); 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_STREQ(message, buffer); 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FuseFsTest, GetStat) { 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct stat statbuf; 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs_.Open(Path("/hello"), O_RDONLY, &node)); 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, node->GetStat(&statbuf)); 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(S_IFREG, statbuf.st_mode & S_IFMT); 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0666, statbuf.st_mode & ~S_IFMT); 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(strlen(hello_world), statbuf.st_size); 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs_.Open(Path("/"), O_RDONLY, &node)); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, node->GetStat(&statbuf)); 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(S_IFDIR, statbuf.st_mode & S_IFMT); 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0755, statbuf.st_mode & ~S_IFMT); 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Create a file and stat. 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs_.Open(Path("/foobar"), O_RDWR | O_CREAT, &node)); 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, node->GetStat(&statbuf)); 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(S_IFREG, statbuf.st_mode & S_IFMT); 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0666, statbuf.st_mode & ~S_IFMT); 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, statbuf.st_size); 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FuseFsTest, GetDents) { 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode root; 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs_.Open(Path("/"), O_RDONLY, &root)); 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct dirent entries[4]; 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int bytes_read; 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try reading everything. 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, root->GetDents(0, &entries[0], sizeof(entries), &bytes_read)); 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(3 * sizeof(dirent), bytes_read); 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ(".", entries[0].d_name); 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ("..", entries[1].d_name); 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ("hello", entries[2].d_name); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try reading from an offset. 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(&entries, 0, sizeof(entries)); 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, root->GetDents(sizeof(dirent), &entries[0], 2 * sizeof(dirent), 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &bytes_read)); 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(2 * sizeof(dirent), bytes_read); 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ("..", entries[0].d_name); 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ("hello", entries[1].d_name); 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add a file and read again. 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs_.Open(Path("/foobar"), O_RDWR | O_CREAT, &node)); 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, root->GetDents(0, &entries[0], sizeof(entries), &bytes_read)); 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(4 * sizeof(dirent), bytes_read); 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ(".", entries[0].d_name); 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ("..", entries[1].d_name); 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ("hello", entries[2].d_name); 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ("foobar", entries[3].d_name); 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(FuseFsTest, Utimens) { 3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct stat statbuf; 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedNode node; 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct timespec times[2]; 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci times[0].tv_sec = 1000; 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci times[0].tv_nsec = 2000; 3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci times[1].tv_sec = 3000; 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci times[1].tv_nsec = 4000; 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, fs_.Open(Path("/hello"), O_RDONLY, &node)); 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, node->Futimens(times)); 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, node->GetStat(&statbuf)); 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(times[0].tv_sec, statbuf.st_atime); 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(times[0].tv_nsec, statbuf.st_atimensec); 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(times[1].tv_sec, statbuf.st_mtime); 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(times[1].tv_nsec, statbuf.st_mtimensec); 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(FuseFsTest, Fchmod) { 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct stat statbuf; 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedNode node; 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, fs_.Open(Path("/hello"), O_RDONLY, &node)); 3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, node->GetStat(&statbuf)); 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0666, statbuf.st_mode & ~S_IFMT); 3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, node->Fchmod(0777)); 4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, node->GetStat(&statbuf)); 4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0777, statbuf.st_mode & ~S_IFMT); 4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class KernelProxyFuseTest : public ::testing::Test { 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) KernelProxyFuseTest() {} 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetUp(); 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void TearDown(); 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) KernelProxy kp_; 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KernelProxyFuseTest::SetUp() { 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_EQ(0, ki_push_state_for_testing()); 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_EQ(0, ki_init(&kp_)); 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Register a fuse filesystem. 423effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch nacl_io_register_fs_type("flatfs", &g_fuse_operations); 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Unmount the passthrough FS and mount our fuse filesystem. 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, kp_.umount("/")); 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, kp_.mount("", "/", "flatfs", 0, NULL)); 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KernelProxyFuseTest::TearDown() { 431effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch nacl_io_unregister_fs_type("flatfs"); 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ki_uninit(); 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(KernelProxyFuseTest, Basic) { 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Write a file. 4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int fd = ki_open("/hello", O_WRONLY | O_CREAT, 0777); 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_GT(fd, -1); 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(sizeof(hello_world), 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ki_write(fd, hello_world, sizeof(hello_world))); 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, ki_close(fd)); 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Then read it back in. 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fd = ki_open("/hello", O_RDONLY, 0); 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_GT(fd, -1); 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char buffer[30]; 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(buffer, 0, sizeof(buffer)); 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(sizeof(hello_world), ki_read(fd, buffer, sizeof(buffer))); 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_STREQ(hello_world, buffer); 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, ki_close(fd)); 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 455