int main(int argc, char *argv[]) { void *context = NULL; int rc = -1; tc_res res; tc_file *tcf; /* Locate and use the default config file. Please update the config * file to the correct NFS server. */ readlink("/proc/self/exe", exe_path, PATH_MAX); snprintf(tc_config_path, PATH_MAX, "%s/../../../config/vfs.proxy.conf", dirname(exe_path)); fprintf(stderr, "using config file: %s\n", tc_config_path); /* Initialize TC services and daemons */ context = tc_init(tc_config_path, DEFAULT_LOG_FILE, 77); if (context == NULL) { NFS4_ERR("Error while initializing tc_client using config " "file: %s; see log at %s", tc_config_path, DEFAULT_LOG_FILE); return EIO; } /* Read the file; nfs4_readv() will open it first if needed. */ tcf = tc_open(TC_TEST_NFS_FILE0, O_RDWR, 0); if (tcf->fd < 0) { NFS4_DEBUG("Cannot open %s", TC_TEST_NFS_FILE0); } rc = tc_close(tcf); if (rc < 0) { NFS4_DEBUG("Cannot close %d", tcf->fd); } tcf = tc_open(TC_TEST_NFS_FILE1, O_WRONLY | O_CREAT, 0); if (tcf->fd < 0) { NFS4_DEBUG("Cannot open %s", TC_TEST_NFS_FILE1); } rc = tc_close(tcf); if (rc < 0) { NFS4_DEBUG("Cannot close %d", tcf->fd); } tc_deinit(context); return res.err_no; }
TYPED_TEST_P(TcTest, SuccessiveWrites) { const char *path = "SuccesiveWrites.dat"; char *data = (char *)getRandomBytes(16_KB); /** * open file one for actual writing * other descriptor to verify */ tc_file *tcf = tc_open(path, O_RDWR | O_CREAT, 0755); EXPECT_NOTNULL(tcf); tc_file *tcf2 = tc_open(path, O_RDONLY, 0); EXPECT_NE(tcf->fd, tcf2->fd); struct tc_iovec iov; tc_iov2file(&iov, tcf, TC_OFFSET_CUR, 4_KB, data); EXPECT_OK(tc_writev(&iov, 1, false)); tc_iov2file(&iov, tcf, TC_OFFSET_CUR, 4_KB, data + 4_KB); EXPECT_OK(tc_writev(&iov, 1, false)); char *readbuf = (char *)malloc(16_KB); tc_iov2file(&iov, tcf2, 0, 8_KB, readbuf); EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(iov.length, 8_KB); EXPECT_EQ(0, memcmp(data, readbuf, 8_KB)); tc_iov2file(&iov, tcf, TC_OFFSET_CUR, 8_KB, data + 8_KB); EXPECT_OK(tc_writev(&iov, 1, false)); tc_iov2file(&iov, tcf2, 0, 16_KB, readbuf); EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(iov.length, 16_KB); EXPECT_EQ(0, memcmp(data, readbuf, 16_KB)); tc_close(tcf); tc_close(tcf2); free(data); free(readbuf); }
TYPED_TEST_P(TcTest, SuccessiveReads) { const char *path = "TcTest-SuccesiveReads.txt"; struct tc_iovec iov; const int N = 4096; char *data; char *read; tc_file *tcf; Removev(&path, 1); data = (char *)getRandomBytes(5 * N); tc_iov4creation(&iov, path, 5 * N, data); EXPECT_OK(tc_writev(&iov, 1, false)); read = (char *)malloc(5 * N); EXPECT_NOTNULL(read); tcf = tc_open(path, O_RDONLY, 0); EXPECT_EQ(0, tc_fseek(tcf, 0, SEEK_CUR)); EXPECT_NOTNULL(tcf); tc_iov2file(&iov, tcf, TC_OFFSET_CUR, N, read); EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(N, tc_fseek(tcf, 0, SEEK_CUR)); iov.data = read + N; EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(2 * N, tc_fseek(tcf, 0, SEEK_CUR)); EXPECT_EQ(3 * N, tc_fseek(tcf, N, SEEK_CUR)); iov.data = read + 3 * N; EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(2 * N, tc_fseek(tcf, 2 * N, SEEK_SET)); iov.data = read + 2 * N; EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(4 * N, tc_fseek(tcf, -N, SEEK_END)); iov.data = read + 4 * N; EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_TRUE(iov.is_eof); EXPECT_EQ(0, memcmp(data, read, 5 * N)); free(data); free(read); tc_close(tcf); }
struct db_conn *db_open(enum backend_type type, const char *name, int flags) { switch (type) { case BE_QDBM: return qdbm_open(name, flags); case BE_BDB: return bdb_open(name, flags); case BE_TC: return tc_open(name, flags); case BE_TDB: return xtdb_open(name, flags); case BE_LEVELDB: return xleveldb_open(name, flags); case BE_NULL: return null_open(name, flags); default: return NULL; } }
TYPED_TEST_P(TcTest, RequestDoesNotFitIntoOneCompound) { const int NFILES = 64; // 64 * 8 == 512 const char *paths[NFILES]; int flags[NFILES]; struct tc_attrs attrs[NFILES]; const char *new_paths[NFILES]; struct tc_file_pair pairs[NFILES]; const char *ROOTDIR = "DontFit"; EXPECT_TRUE(tc_rm_recursive(ROOTDIR)); for (int i = 0; i < NFILES; ++i) { paths[i] = new_auto_path("DontFit/a%03d/b/c/d/e/f/g/h/file", i); tc_ensure_parent_dir(paths[i]); flags[i] = O_WRONLY | O_CREAT; attrs[i].file = tc_file_from_path(paths[i]); new_paths[i] = new_auto_path("DontFit/file-%d", i); pairs[i].src_file = tc_file_from_path(paths[i]); pairs[i].dst_file = tc_file_from_path(new_paths[i]); } tc_file *files = tc_openv(paths, NFILES, flags, NULL); EXPECT_NOTNULL(files); EXPECT_OK(tc_closev(files, NFILES)); EXPECT_OK(tc_getattrsv(attrs, NFILES, false)); struct tc_attrs_masks listdir_mask = { .has_mode = true }; std::set<std::string> objs; EXPECT_OK(tc_listdirv(&ROOTDIR, 1, listdir_mask, 0, true, listdir_test_cb, &objs, false)); std::set<std::string> expected; for (int i = 0; i < NFILES; ++i) { std::string p(paths[i]); size_t n = p.length(); while (n != std::string::npos) { expected.emplace(p.data(), n); n = p.find_last_of('/', n - 1); } } expected.erase("DontFit"); EXPECT_THAT(objs, testing::ContainerEq(expected)); EXPECT_OK(tc_renamev(pairs, NFILES, false)); EXPECT_OK(tc_unlinkv(new_paths, NFILES)); } static bool is_same_stat(const struct stat *st1, const struct stat *st2) { return st1->st_ino == st2->st_ino && st1->st_mode == st2->st_mode && st1->st_nlink == st2->st_nlink && st1->st_uid == st2->st_uid && st1->st_gid == st2->st_gid && st1->st_rdev == st2->st_rdev && st1->st_size == st2->st_size && st1->st_mtime == st2->st_mtime && st1->st_ctime == st2->st_ctime; //&& st1->st_dev == st2->st_dev //&& st1->st_blksize == st2->st_blksize //&& st1->st_blocks == st2->st_blocks } TYPED_TEST_P(TcTest, TcStatBasics) { const char *FPATH = "TcTest-TcStatFile.txt"; const char *LPATH = "TcTest-TcStatLink.txt"; tc_unlink(FPATH); tc_unlink(LPATH); tc_touch(FPATH, 4_KB); EXPECT_EQ(0, tc_symlink(FPATH, LPATH)); struct stat st1; EXPECT_EQ(0, tc_stat(LPATH, &st1)); struct stat st2; tc_file *tcf = tc_open(FPATH, O_RDONLY, 0); EXPECT_EQ(0, tc_fstat(tcf, &st2)); EXPECT_TRUE(is_same_stat(&st1, &st2)); tc_close(tcf); struct stat st3; EXPECT_EQ(0, tc_lstat(LPATH, &st3)); EXPECT_TRUE(S_ISLNK(st3.st_mode)); EXPECT_FALSE(is_same_stat(&st1, &st3)); } TYPED_TEST_P(TcTest, TcRmBasic) { #define TCRM_PREFIX "/vfs0/tc_nfs4_test/TcRmBasic" EXPECT_OK(tc_ensure_dir(TCRM_PREFIX "/dir-a/subdir-a1", 0755, NULL)); EXPECT_OK(tc_ensure_dir(TCRM_PREFIX "/dir-a/subdir-a2", 0755, NULL)); EXPECT_OK(tc_ensure_dir(TCRM_PREFIX "/dir-b/subdir-b1", 0755, NULL)); tc_touch(TCRM_PREFIX "/dir-a/subdir-a1/a1-file1", 4_KB); tc_touch(TCRM_PREFIX "/dir-a/subdir-a1/a1-file2", 4_KB); tc_touch(TCRM_PREFIX "/dir-a/subdir-a1/a1-file3", 4_KB); tc_touch(TCRM_PREFIX "/dir-a/subdir-a2/a2-file1", 4_KB); tc_touch(TCRM_PREFIX "/dir-a/subdir-a2/a2-file2", 4_KB); tc_touch(TCRM_PREFIX "/dir-b/subdir-b1/b1-file1", 4_KB); tc_touch(TCRM_PREFIX "/dir-b/subdir-b1/b1-file2", 4_KB); tc_touch(TCRM_PREFIX "/dir-b/subdir-b1/b1-file3", 4_KB); tc_touch(TCRM_PREFIX "/file1", 4_KB); tc_touch(TCRM_PREFIX "/file2", 4_KB); const char *objs[4] = { TCRM_PREFIX "/dir-a", TCRM_PREFIX "/dir-b", TCRM_PREFIX "/file1", TCRM_PREFIX "/file2", }; EXPECT_OK(tc_rm(objs, 4, true)); #undef TCRM_PREFIX }