* Fix FuseTest

* Refactor Fuse: shorter functions, and factor out common functionality of adding a fuse option into own method
This commit is contained in:
Sebastian Messmer 2016-06-04 00:45:49 -07:00
parent 93927e76d6
commit 1bb38f39b4
3 changed files with 30 additions and 19 deletions

View File

@ -234,29 +234,37 @@ void Fuse::run(const bf::path &mountdir, const vector<string> &fuseOptions) {
ASSERT(_argv.size() == 0, "Filesystem already started"); ASSERT(_argv.size() == 0, "Filesystem already started");
_argv.reserve(2 + fuseOptions.size()); _argv = _build_argv(mountdir, fuseOptions);
_argv.push_back(_create_c_string(_fstype)); // The first argument is the file system name
fuse_main(_argv.size(), _argv.data(), operations(), (void*)this);
}
vector<char *> Fuse::_build_argv(const bf::path &mountdir, const vector<string> &fuseOptions) {
vector<char *> argv;
_argv.reserve(6 + fuseOptions.size()); // fuseOptions + executable name + mountdir + 2x fuse options (subtype, fsname), each taking 2 entries ("-o", "key=value").
_argv.push_back(_create_c_string(_fstype)); // The first argument (executable name) is the file system type
_argv.push_back(_create_c_string(mountdir.native())); // The second argument is the mountdir _argv.push_back(_create_c_string(mountdir.native())); // The second argument is the mountdir
for (const string &option : fuseOptions) { for (const string &option : fuseOptions) {
_argv.push_back(_create_c_string(option)); _argv.push_back(_create_c_string(option));
} }
if(_fsname != boost::none) { _add_fuse_option_if_not_exists(&_argv, "subtype", _fstype);
auto hasNoOption = [&](const char *opt) { _add_fuse_option_if_not_exists(&_argv, "fsname", _fsname.get_value_or(_fstype));
for (const string& it : fuseOptions) { return argv;
if (std::strncmp(it.c_str(), opt, std::strlen(opt))) { }
return false;
void Fuse::_add_fuse_option_if_not_exists(vector<char *> *argv, const string &key, const string &value) {
if(!_has_option(*argv, key)) {
argv->push_back(_create_c_string("-o"));
argv->push_back(_create_c_string(key + "=" + value));
} }
} }
return true;
}; bool Fuse::_has_option(const vector<char *> &vec, const string &key) {
if (hasNoOption("subtype=") && hasNoOption("fsname=")) { string key_with_prefix = key + "+";
_argv.push_back(_create_c_string("-o")); auto found = std::find_if(vec.begin(), vec.end(), [&key_with_prefix](const char *entry) {
_argv.push_back(_create_c_string("fsname="+*_fsname)); return std::strncmp(key_with_prefix.c_str(), entry, key_with_prefix.size());
_argv.push_back(_create_c_string("-o")); });
_argv.push_back(_create_c_string("subtype="+_fstype)); return found != vec.end();
}
}
fuse_main(_argv.size(), _argv.data(), operations(), (void*)this);
} }
char *Fuse::_create_c_string(const string &str) { char *Fuse::_create_c_string(const string &str) {

View File

@ -61,6 +61,9 @@ private:
static void _logException(const std::exception &e); static void _logException(const std::exception &e);
static void _logUnknownException(); static void _logUnknownException();
static char *_create_c_string(const std::string &str); static char *_create_c_string(const std::string &str);
static bool _has_option(const std::vector<char *> &vec, const std::string &key);
std::vector<char *> _build_argv(const boost::filesystem::path &mountdir, const std::vector<std::string> &fuseOptions);
void _add_fuse_option_if_not_exists(std::vector<char *> *argv, const std::string &key, const std::string &value);
Filesystem *_fs; Filesystem *_fs;
boost::filesystem::path _mountdir; boost::filesystem::path _mountdir;

View File

@ -53,7 +53,7 @@ unique_ref<FuseTest::TempTestFS> FuseTest::TestFS() {
return make_unique_ref<TempTestFS>(&fsimpl); return make_unique_ref<TempTestFS>(&fsimpl);
} }
FuseTest::TempTestFS::TempTestFS(MockFilesystem *fsimpl): _mountDir(), _fuse(fsimpl), _fuse_thread(&_fuse) { FuseTest::TempTestFS::TempTestFS(MockFilesystem *fsimpl): _mountDir(), _fuse(fsimpl, "fusetest", boost::none), _fuse_thread(&_fuse) {
_fuse_thread.start(_mountDir.path(), {"-f"}); _fuse_thread.start(_mountDir.path(), {"-f"});
} }