#define BOOST_TEST_MODULE TestNetFSCore #include #include #include #include #include #include #include "mockDaemon.h" #include #include #ifndef ROOT #error "ROOT needs to be defined at compilation time" #endif #define XSTR(s) STR(s) #define STR(s) #s const boost::filesystem::path RootDir(XSTR(ROOT)); const std::string testEndpoint("tcp -h localhost -p 12012"); char * argv[] = { strdup((RootDir / ":testvol").string().c_str()), strdup((RootDir / "test").string().c_str()) }; class FuseMock : public NetFS::FuseApp { public: FuseMock(int & argc, char ** argv) : NetFS::FuseApp(argc, argv) { ::memset(&context, 0, sizeof(fuse_context)); context.pid = getpid(); context.uid = getuid(); context.gid = getgid(); } struct fuse_context * fuse_get_context() override { return &context; } int fuse_opt_parse(struct fuse_args * args, void * data, const struct fuse_opt [], fuse_opt_proc_t proc) override { for (int n = 0; n < args->argc; n += 1) { proc(data, args->argv[n], n, args); } return 0; } int main(int &, char **, const struct fuse_operations * o) override { o->init(NULL); ops = *o; return 0; } fuse_operations ops; protected: virtual NetFS::Client::ConfigurationPtr ReadConfiguration(const std::string &) const override { return new NetFS::Client::Configuration( { { "testvol", new NetFS::Client::Resource("testvol", "Service", { testEndpoint }) } }); } private: fuse_context context; }; class FuseMockHost { public: FuseMockHost() : argc(2), app(new FuseMock(argc, argv)), fuse(&app->ops) { char ** a = argv; FuseAppBase::run(argc, a, app); } FuseMockHost(int c, char ** v) : argc(c), app(new FuseMock(c, v)), fuse(&app->ops) { FuseAppBase::run(argc, v, app); } ~FuseMockHost() { delete app; } int argc; FuseMock * app; fuse_operations * fuse; }; class Core { public: Core() : daemonHost(testEndpoint), ic(daemonHost.ic), fuse(fuseHost.fuse) { } protected: MockDaemonHost daemonHost; FuseMockHost fuseHost; Ice::CommunicatorPtr ic; fuse_operations * fuse;; }; BOOST_FIXTURE_TEST_SUITE( NetfsCore, Core ) BOOST_AUTO_TEST_CASE ( daemonInitialised ) { auto service = NetFS::ServicePrx::checkedCast(ic->stringToProxy("Service")); BOOST_REQUIRE(service); service->ice_ping(); } BOOST_AUTO_TEST_CASE ( clientInitialised ) { struct statvfs s; BOOST_REQUIRE_EQUAL(0, fuse->statfs("/", &s)); } BOOST_AUTO_TEST_SUITE_END(); BOOST_AUTO_TEST_CASE ( createAndDaemonRestart ) { MockDaemonHost daemon(testEndpoint); FuseMockHost fuse; struct statvfs s; BOOST_REQUIRE_EQUAL(0, fuse.fuse->statfs("/", &s)); const char * fileName = "/createMe"; BOOST_CHECKPOINT("Create a new file"); struct fuse_file_info fh; memset(&fh, 0, sizeof(fh)); fh.flags = O_WRONLY | O_CREAT | O_APPEND; BOOST_REQUIRE_EQUAL(0, fuse.fuse->create(fileName, 0100644, &fh)); BOOST_REQUIRE(fh.fh); BOOST_CHECKPOINT("Fetch file attributes"); struct stat st; BOOST_REQUIRE_EQUAL(0, fuse.fuse->fgetattr(fileName, &st, &fh)); BOOST_REQUIRE_EQUAL(st.st_size, 0); BOOST_REQUIRE_EQUAL(st.st_uid, getuid()); BOOST_REQUIRE_EQUAL(st.st_gid, getgid()); BOOST_CHECKPOINT("Write some data"); char someData[890]; BOOST_REQUIRE_EQUAL(sizeof(someData), fuse.fuse->write(fileName, someData, sizeof(someData), 0, &fh)); BOOST_REQUIRE_EQUAL(0, fuse.fuse->fgetattr(fileName, &st, &fh)); BOOST_REQUIRE_EQUAL(st.st_size, sizeof(someData)); BOOST_CHECKPOINT("Restart daemon object"); daemon.restart(); BOOST_CHECKPOINT("Fetch file attributes again"); BOOST_REQUIRE_EQUAL(0, fuse.fuse->fgetattr(fileName, &st, &fh)); BOOST_CHECKPOINT("Close file"); BOOST_REQUIRE_EQUAL(0, fuse.fuse->release(fileName, &fh)); } BOOST_AUTO_TEST_CASE ( withRouter ) { BOOST_REQUIRE_EQUAL(0, system("/usr/bin/glacier2router --Glacier2.Client.Endpoints='tcp -p 4063' --Glacier2.PermissionsVerifier=Glacier2/NullPermissionsVerifier --daemon --pidfile /tmp/glacier.pid")); sleep(1); BOOST_SCOPE_EXIT(void) { system("kill $(cat /tmp/glacier.pid)"); } BOOST_SCOPE_EXIT_END; { char * argv[] = { strdup((RootDir / ":testvol").string().c_str()), strdup((RootDir / "test").string().c_str()), strdup("--Ice.Default.Router=Glacier2/router:tcp -h localhost -p 4063") }; MockDaemonHost daemon(testEndpoint); FuseMockHost fuse(3, argv); struct statvfs s; BOOST_REQUIRE_EQUAL(0, fuse.fuse->statfs("/", &s)); } }