This source file includes following definitions.
- MakeStringMap
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST
- TEST
- TEST
- TEST
- TEST
#include <fcntl.h>
#include <gmock/gmock.h>
#include <ppapi/c/ppb_file_io.h>
#include <ppapi/c/pp_errors.h>
#include <ppapi/c/pp_instance.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "fake_ppapi/fake_pepper_interface_url_loader.h"
#include "nacl_io/dir_node.h"
#include "nacl_io/httpfs/http_fs.h"
#include "nacl_io/kernel_handle.h"
#include "nacl_io/kernel_intercept.h"
#include "nacl_io/osdirent.h"
#include "nacl_io/osunistd.h"
using namespace nacl_io;
namespace {
class HttpFsForTesting : public HttpFs {
public:
HttpFsForTesting(StringMap_t map, PepperInterface* ppapi) {
FsInitArgs args(1);
args.string_map = map;
args.ppapi = ppapi;
EXPECT_EQ(0, Init(args));
}
using HttpFs::GetNodeCacheForTesting;
using HttpFs::ParseManifest;
using HttpFs::FindOrCreateDir;
};
enum {
kStringMapParamCacheNone = 0,
kStringMapParamCacheContent = 1,
kStringMapParamCacheStat = 2,
kStringMapParamCacheContentStat =
kStringMapParamCacheContent | kStringMapParamCacheStat,
};
typedef uint32_t StringMapParam;
StringMap_t MakeStringMap(StringMapParam param) {
StringMap_t smap;
if (param & kStringMapParamCacheContent)
smap["cache_content"] = "true";
else
smap["cache_content"] = "false";
if (param & kStringMapParamCacheStat)
smap["cache_stat"] = "true";
else
smap["cache_stat"] = "false";
return smap;
}
class HttpFsTest : public ::testing::TestWithParam<StringMapParam> {
public:
HttpFsTest();
protected:
FakePepperInterfaceURLLoader ppapi_;
HttpFsForTesting fs_;
};
HttpFsTest::HttpFsTest() : fs_(MakeStringMap(GetParam()), &ppapi_) {}
}
TEST_P(HttpFsTest, Access) {
ASSERT_TRUE(ppapi_.server_template()->AddEntity("foo", "", NULL));
ASSERT_EQ(0, fs_.Access(Path("/foo"), R_OK));
ASSERT_EQ(EACCES, fs_.Access(Path("/foo"), W_OK));
ASSERT_EQ(EACCES, fs_.Access(Path("/foo"), X_OK));
ASSERT_EQ(ENOENT, fs_.Access(Path("/bar"), F_OK));
}
TEST_P(HttpFsTest, OpenAndCloseServerError) {
EXPECT_TRUE(ppapi_.server_template()->AddError("file", 500));
ScopedNode node;
ASSERT_EQ(EIO, fs_.Open(Path("/file"), O_RDONLY, &node));
}
TEST_P(HttpFsTest, ReadPartial) {
const char contents[] = "0123456789abcdefg";
ASSERT_TRUE(ppapi_.server_template()->AddEntity("file", contents, NULL));
ppapi_.server_template()->set_allow_partial(true);
int result_bytes = 0;
char buf[10];
memset(&buf[0], 0, sizeof(buf));
ScopedNode node;
ASSERT_EQ(0, fs_.Open(Path("/file"), O_RDONLY, &node));
HandleAttr attr;
EXPECT_EQ(0, node->Read(attr, buf, sizeof(buf) - 1, &result_bytes));
EXPECT_EQ(sizeof(buf) - 1, result_bytes);
EXPECT_STREQ("012345678", &buf[0]);
attr.offs = 10;
ASSERT_EQ(0, node->Read(attr, buf, sizeof(buf) - 1, &result_bytes));
ASSERT_EQ(strlen("abcdefg"), result_bytes);
buf[result_bytes] = 0;
EXPECT_STREQ("abcdefg", &buf[0]);
attr.offs = 100;
EXPECT_EQ(0, node->Read(attr, &buf[0], sizeof(buf), &result_bytes));
EXPECT_EQ(0, result_bytes);
}
TEST_P(HttpFsTest, ReadPartialNoServerSupport) {
const char contents[] = "0123456789abcdefg";
ASSERT_TRUE(ppapi_.server_template()->AddEntity("file", contents, NULL));
ppapi_.server_template()->set_allow_partial(false);
int result_bytes = 0;
char buf[10];
memset(&buf[0], 0, sizeof(buf));
ScopedNode node;
ASSERT_EQ(0, fs_.Open(Path("/file"), O_RDONLY, &node));
HandleAttr attr;
EXPECT_EQ(0, node->Read(attr, buf, sizeof(buf) - 1, &result_bytes));
EXPECT_EQ(sizeof(buf) - 1, result_bytes);
EXPECT_STREQ("012345678", &buf[0]);
attr.offs = 10;
ASSERT_EQ(0, node->Read(attr, buf, sizeof(buf) - 1, &result_bytes));
ASSERT_EQ(strlen("abcdefg"), result_bytes);
buf[result_bytes] = 0;
EXPECT_STREQ("abcdefg", &buf[0]);
attr.offs = 100;
EXPECT_EQ(0, node->Read(attr, &buf[0], sizeof(buf), &result_bytes));
EXPECT_EQ(0, result_bytes);
}
TEST_P(HttpFsTest, Write) {
const char contents[] = "contents";
ASSERT_TRUE(ppapi_.server_template()->AddEntity("file", contents, NULL));
ScopedNode node;
ASSERT_EQ(0, fs_.Open(Path("/file"), O_WRONLY, &node));
HandleAttr attr;
attr.offs = 3;
int bytes_written = 1;
EXPECT_EQ(EACCES, node->Write(attr, "struct", 6, &bytes_written));
EXPECT_EQ(0, bytes_written);
}
TEST_P(HttpFsTest, GetStat) {
const char contents[] = "contents";
ASSERT_TRUE(ppapi_.server_template()->AddEntity("file", contents, NULL));
ScopedNode node;
ASSERT_EQ(0, fs_.Open(Path("/file"), O_RDONLY, &node));
struct stat statbuf;
EXPECT_EQ(0, node->GetStat(&statbuf));
EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
statbuf.st_mode);
EXPECT_EQ(strlen(contents), statbuf.st_size);
EXPECT_EQ(0, statbuf.st_atime);
EXPECT_EQ(0, statbuf.st_ctime);
EXPECT_EQ(0, statbuf.st_mtime);
}
TEST_P(HttpFsTest, FTruncate) {
const char contents[] = "contents";
ASSERT_TRUE(ppapi_.server_template()->AddEntity("file", contents, NULL));
ScopedNode node;
ASSERT_EQ(0, fs_.Open(Path("/file"), O_RDWR, &node));
EXPECT_EQ(EACCES, node->FTruncate(4));
}
INSTANTIATE_TEST_CASE_P(
Default,
HttpFsTest,
::testing::Values((uint32_t)kStringMapParamCacheNone,
(uint32_t)kStringMapParamCacheContent,
(uint32_t)kStringMapParamCacheStat,
(uint32_t)kStringMapParamCacheContentStat));
TEST(HttpFsDirTest, Mkdir) {
StringMap_t args;
HttpFsForTesting fs(args, NULL);
char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
ASSERT_EQ(0, fs.ParseManifest(manifest));
EXPECT_EQ(EEXIST, fs.Mkdir(Path("/"), 0));
EXPECT_EQ(EEXIST, fs.Mkdir(Path("/mydir"), 0));
EXPECT_EQ(EACCES, fs.Mkdir(Path("/non_existent"), 0));
}
TEST(HttpFsDirTest, Rmdir) {
StringMap_t args;
HttpFsForTesting fs(args, NULL);
char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
ASSERT_EQ(0, fs.ParseManifest(manifest));
EXPECT_EQ(EACCES, fs.Rmdir(Path("/")));
EXPECT_EQ(EACCES, fs.Rmdir(Path("/mydir")));
EXPECT_EQ(ENOTDIR, fs.Rmdir(Path("/mydir/foo")));
EXPECT_EQ(ENOENT, fs.Rmdir(Path("/non_existent")));
}
TEST(HttpFsDirTest, Unlink) {
StringMap_t args;
HttpFsForTesting fs(args, NULL);
char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
ASSERT_EQ(0, fs.ParseManifest(manifest));
EXPECT_EQ(EACCES, fs.Unlink(Path("/mydir/foo")));
EXPECT_EQ(EISDIR, fs.Unlink(Path("/mydir")));
EXPECT_EQ(ENOENT, fs.Unlink(Path("/non_existent")));
}
TEST(HttpFsDirTest, Remove) {
StringMap_t args;
HttpFsForTesting fs(args, NULL);
char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
ASSERT_EQ(0, fs.ParseManifest(manifest));
EXPECT_EQ(EACCES, fs.Remove(Path("/mydir/foo")));
EXPECT_EQ(EACCES, fs.Remove(Path("/mydir")));
EXPECT_EQ(ENOENT, fs.Remove(Path("/non_existent")));
}
TEST(HttpFsDirTest, ParseManifest) {
StringMap_t args;
size_t result_size = 0;
HttpFsForTesting fs(args, NULL);
char manifest[] = "-r-- 123 /mydir/foo\n\n-rw- 234 /thatdir/bar\n";
ASSERT_EQ(0, fs.ParseManifest(manifest));
ScopedNode root;
EXPECT_EQ(0, fs.FindOrCreateDir(Path("/"), &root));
ASSERT_NE((Node*)NULL, root.get());
EXPECT_EQ(2, root->ChildCount());
ScopedNode dir;
EXPECT_EQ(0, fs.FindOrCreateDir(Path("/mydir"), &dir));
ASSERT_NE((Node*)NULL, dir.get());
EXPECT_EQ(1, dir->ChildCount());
Node* node = (*fs.GetNodeCacheForTesting())["/mydir/foo"].get();
EXPECT_NE((Node*)NULL, node);
EXPECT_EQ(0, node->GetSize(&result_size));
EXPECT_EQ(123, result_size);
ScopedNode foo;
ASSERT_EQ(0, fs.Open(Path("/mydir/foo"), O_RDONLY, &foo));
ScopedNode bar;
ASSERT_EQ(0, fs.Open(Path("/thatdir/bar"), O_RDWR, &bar));
struct stat sfoo;
struct stat sbar;
EXPECT_FALSE(foo->GetStat(&sfoo));
EXPECT_FALSE(bar->GetStat(&sbar));
EXPECT_EQ(123, sfoo.st_size);
EXPECT_EQ(S_IFREG | S_IRALL, sfoo.st_mode);
EXPECT_EQ(234, sbar.st_size);
EXPECT_EQ(S_IFREG | S_IRALL | S_IWALL, sbar.st_mode);
}