From 51a439106355a9de64f62c5356465685d8cbc5bf Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 3 Jan 2021 20:14:24 +0000 Subject: Fixup memory leaks and race conditions in testFuse --- netfs/unittests/testFuse.cpp | 46 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/netfs/unittests/testFuse.cpp b/netfs/unittests/testFuse.cpp index 17095bb..1185a7f 100644 --- a/netfs/unittests/testFuse.cpp +++ b/netfs/unittests/testFuse.cpp @@ -18,30 +18,43 @@ class FuseMountPoint : public MockDaemonHost, public NetFS::FuseApp { public: FuseMountPoint() : MockDaemonHost(::testEndpoint, {"--NetFSD.ConfigPath=" + (rootDir / "defaultDaemon.xml").string()}), - NetFS::FuseApp({::testUri}) + NetFS::FuseApp({::testUri}), fargs {} { - std::filesystem::remove(mntpnt); + std::filesystem::remove_all(mntpnt); std::filesystem::create_directory(mntpnt); - fuse_args fargs {}; ::fuse_opt_add_arg(&fargs, selfExe.c_str()); ::fuse_opt_add_arg(&fargs, "-onoauto_cache"); ::fuse_opt_add_arg(&fargs, "-oattr_timeout=0"); ::fuse_opt_add_arg(&fargs, "-oac_attr_timeout=0"); fs = ::fuse_new(&fargs, &operations, sizeof(fuse_operations), this); - ::fuse_opt_free_args(&fargs); BOOST_REQUIRE(fs); + } + + void + start() + { + BOOST_REQUIRE(!th); BOOST_REQUIRE_EQUAL(0, ::fuse_mount(fs, mntpnt.c_str())); th = std::make_unique(::fuse_loop, fs); + BOOST_REQUIRE(th); } ~FuseMountPoint() override { - ::fuse_unmount(fs); + stop(); + std::filesystem::remove(mntpnt); + ::fuse_destroy(fs); + ::fuse_opt_free_args(&fargs); + } + + void + stop() + { if (th) { + ::fuse_unmount(fs); th->join(); + th.reset(); } - std::filesystem::remove(mntpnt); - ::fuse_destroy(fs); } SPECIAL_MEMBERS_DELETE(FuseMountPoint); @@ -69,6 +82,7 @@ public: } struct fuse * fs; + struct fuse_args fargs; std::unique_ptr th; }; @@ -100,13 +114,31 @@ get_lstat(const std::filesystem::path & p) BOOST_FIXTURE_TEST_SUITE(fmp, FuseMountPoint); +class Run { +public: + Run(FuseMountPoint * _p) : p {_p} + { + p->start(); + } + ~Run() + { + p->stop(); + } + SPECIAL_MEMBERS_DELETE(Run); + +private: + FuseMountPoint * p; +}; + BOOST_AUTO_TEST_CASE(fuse, *boost::unit_test::timeout(5)) { + Run r {this}; BOOST_REQUIRE(std::filesystem::is_directory(mntpnt)); } BOOST_AUTO_TEST_CASE(fuse_ls, *boost::unit_test::timeout(5)) { + Run r {this}; BOOST_REQUIRE(std::filesystem::is_directory(mntpnt)); BOOST_REQUIRE(std::filesystem::is_empty(mntpnt)); const auto rpath = mntpnt / "me"; -- cgit v1.2.3