diff options
-rw-r--r-- | src/Jamfile.jam | 5 | ||||
-rw-r--r-- | src/blob.cpp | 3 | ||||
-rw-r--r-- | src/dir.cpp | 3 | ||||
-rw-r--r-- | src/repo.cpp | 19 | ||||
-rw-r--r-- | src/repo.h | 5 | ||||
-rw-r--r-- | src/repoList.cpp | 20 | ||||
-rw-r--r-- | src/repoList.h | 7 | ||||
-rw-r--r-- | unittests/Jamfile.jam | 12 | ||||
-rw-r--r-- | unittests/config.cpp | 81 | ||||
-rw-r--r-- | unittests/core.cpp | 6 | ||||
-rw-r--r-- | unittests/mockDefs.cpp | 11 | ||||
-rw-r--r-- | unittests/service.cpp | 56 |
12 files changed, 195 insertions, 33 deletions
diff --git a/src/Jamfile.jam b/src/Jamfile.jam index d342134..afe5dc7 100644 --- a/src/Jamfile.jam +++ b/src/Jamfile.jam @@ -1,6 +1,3 @@ -# Testing -path-constant gitdir : ../.git ; - lib gitfs++11 : [ glob *.cpp ] : @@ -8,8 +5,6 @@ lib gitfs++11 : <library>..//icetray <library>..//git2 <library>..//netfs-api -# Testing - <define>ROOT=\"$(gitdir)\" : : <library>..//netfs-api ; diff --git a/src/blob.cpp b/src/blob.cpp index a3408b3..ed0e633 100644 --- a/src/blob.cpp +++ b/src/blob.cpp @@ -35,7 +35,8 @@ GitFS::Blob::fgetattr(ReqEnv, const ::Ice::Current&) { NetFS::Attr a; a << *blob << *entry << *repo->commit; - a.gid = a.uid = "root"; + a.gid = repo->gid; + a.uid = repo->uid; return a; } diff --git a/src/dir.cpp b/src/dir.cpp index c590450..98c05cb 100644 --- a/src/dir.cpp +++ b/src/dir.cpp @@ -61,7 +61,8 @@ GitFS::Directory::listdir(const ::Ice::Current&) auto blob = Git::BlobLookup(repo->repo, *git_tree_entry_id(entry)); a << *blob; } - a.gid = a.uid = "root"; + a.gid = repo->gid; + a.uid = repo->uid; list.emplace(git_tree_entry_name(entry), a); } return list; diff --git a/src/repo.cpp b/src/repo.cpp index 32fa401..4059897 100644 --- a/src/repo.cpp +++ b/src/repo.cpp @@ -4,13 +4,17 @@ #include "blob.h" #include "dir.h" -// Testing -#include <definedDirs.h> +std::string operator/(const std::string & a, const std::string & b) +{ + return a.empty() ? b : a; +} -GitFS::Repo::Repo() : - repo(Git::RepositoryOpenBare(rootDir)), - commit(Git::CommitLookup(repo, Git::OidParse("7a0ccb40084c3ab31d9856e7f689c0514c28c930"))), - tree(Git::TreeLookup(repo, *git_commit_tree_id(commit.get()))) +GitFS::Repo::Repo(const PropertyReader & properties) : + repo(Git::RepositoryOpenBare(properties("gitdir"))), + commit(Git::CommitLookup(repo, Git::OidParse(properties("commit")))), + tree(Git::TreeLookup(repo, *git_commit_tree_id(commit.get()))), + gid(properties("gid") / "root"), + uid(properties("uid") / "root") { } @@ -82,7 +86,8 @@ GitFS::Repo::getattr(ReqEnv, ::std::string path, const ::Ice::Current&) } } a << *commit; - a.gid = a.uid = "root"; + a.gid = gid; + a.uid = uid; return a; } @@ -1,14 +1,16 @@ #ifndef GITFS_REPO_H #define GITFS_REPO_H +#include <Ice/Properties.h> #include <volume.h> #include "git.h" namespace GitFS { using namespace NetFS; + using PropertyReader = std::function<std::string(const std::string_view &)>; class Repo : public Volume { public: - Repo(); + Repo(const PropertyReader &); void disconnect(const ::Ice::Current& current) override; DirectoryPrxPtr opendir(ReqEnv env, ::std::string path, const ::Ice::Current& current) override; @@ -36,6 +38,7 @@ namespace GitFS { Git::RepositoryPtr repo; Git::CommitPtr commit; Git::TreePtr tree; + const std::string gid, uid; }; } diff --git a/src/repoList.cpp b/src/repoList.cpp index 51eb6b2..9fc2848 100644 --- a/src/repoList.cpp +++ b/src/repoList.cpp @@ -1,15 +1,29 @@ #include <Ice/ObjectAdapter.h> +#include <Ice/Properties.h> #include "repoList.h" #include "repo.h" -GitFS::RepoList::RepoList(const Ice::PropertiesPtr &) +#include <compileTimeFormatter.h> + +GitFS::RepoList::RepoList(const Ice::PropertiesPtr & p) : properties(p) { } +AdHocFormatter(RepoPropertyName, "GitFS.%?.%?"); + NetFS::VolumePrxPtr -GitFS::RepoList::connect(const ::std::string, const ::std::string, +GitFS::RepoList::connect(const ::std::string volume, const ::std::string auth, const ::Ice::Current & ice) { - return Ice::uncheckedCast<NetFS::VolumePrx>(ice.adapter->addWithUUID(std::make_shared<Repo>())); + if (volume.empty()) throw NetFS::ConfigError(); + + const auto propReader = std::bind(&Ice::Properties::getProperty, properties, + std::bind((std::string(*)(const std::string_view &, const std::string_view &)) + (&RepoPropertyName::get), volume, std::placeholders::_1)); + + if (propReader("gitdir").empty()) throw NetFS::ConfigError(); + if (propReader("authkey") != auth) throw NetFS::AuthError(); + return Ice::uncheckedCast<NetFS::VolumePrx>( + ice.adapter->addWithUUID(std::make_shared<Repo>(propReader))); } diff --git a/src/repoList.h b/src/repoList.h index ac8b885..6929e5b 100644 --- a/src/repoList.h +++ b/src/repoList.h @@ -7,9 +7,12 @@ namespace GitFS { class RepoList : public NetFS::Service { public: - RepoList(const Ice::PropertiesPtr & ptr); + RepoList(const Ice::PropertiesPtr &); - virtual NetFS::VolumePrxPtr connect(const ::std::string volume, const ::std::string auth, const ::Ice::Current& current) override; + NetFS::VolumePrxPtr connect(const ::std::string volume, const ::std::string auth, const ::Ice::Current& current) override; + + private: + const Ice::PropertiesPtr properties; }; } diff --git a/unittests/Jamfile.jam b/unittests/Jamfile.jam index a44275f..830fd25 100644 --- a/unittests/Jamfile.jam +++ b/unittests/Jamfile.jam @@ -3,7 +3,7 @@ import testing ; lib boost_utf : : <name>boost_unit_test_framework ; lib dryice : : : : <library>..//icetray ; -path-constant me : . ; +path-constant gitdir : ../.git ; lib common : mockDefs.cpp @@ -12,17 +12,17 @@ lib common : <library>../src//gitfs++11 <library>..//adhocutil <library>boost_utf - <define>ROOT=\"$(me)\" + <define>ROOT=\"$(gitdir)\" : : <library>dryice <library>../src//gitfs++11 <library>boost_utf - <define>ROOT=\"$(me)\" + <define>ROOT=\"$(gitdir)\" <define>BOOST_TEST_DYN_LINK ; -run core.cpp : : : - <library>common - ; +run config.cpp : : : <library>common ; +run core.cpp : : : <library>common ; +run service.cpp : : : <library>common ; diff --git a/unittests/config.cpp b/unittests/config.cpp new file mode 100644 index 0000000..0cfc22c --- /dev/null +++ b/unittests/config.cpp @@ -0,0 +1,81 @@ +#define BOOST_TEST_MODULE GitFS_Config +#include <boost/test/unit_test.hpp> +#include <boost/test/data/test_case.hpp> + +#include <definedDirs.h> +#include <compileTimeFormatter.h> +#include "mockDefs.h" + +using namespace GitFS; +using namespace GitFS::Test; +using namespace AdHoc::literals; + +namespace btdata = boost::unit_test::data; + +class IdsIce : public IceTray::DryIce { + public: + IdsIce(const char * uid, const char * gid) : IceTray::DryIce({ + "--GitFS.testrepo.gitdir=%?"_fmt(rootDir.string()), + "--GitFS.testrepo.authkey=%?"_fmt("testauth"), + "--GitFS.testrepo.gid=%?"_fmt(gid), + "--GitFS.testrepo.uid=%?"_fmt(uid), + "--GitFS.testrepo.commit=7a0ccb40084c3ab31d9856e7f689c0514c28c930", + }) + {} +}; + +const auto USERS = btdata::make({ "root", "gituser", "www" }); +const auto GROUPS = btdata::make({ "root", "gitgroup", "www" }); +const auto DIRS = btdata::make({ "/", "/src", "/unittests/fixtures" }); +const auto FILES = btdata::make({ + "/Jamroot.jam", "/src/repo.cpp", "/unittests/fixtures/executable" }); +const auto LINKS = btdata::make({ "/unittests/fixtures/symlink" }); + +BOOST_DATA_TEST_CASE(uid_gid_override_getattr, + USERS * GROUPS * (DIRS + FILES + LINKS), + uid, gid, path) +{ + IdsIce s(uid, gid); + VolumeClient c; + BOOST_CHECK_NO_THROW(c.s->ice_ping()); + + auto attr = c.v->getattr(c.env, path); + BOOST_CHECK_EQUAL(attr.uid, uid); + BOOST_CHECK_EQUAL(attr.gid, gid); +} + +BOOST_DATA_TEST_CASE(uid_gid_override_fgetattr, + USERS * GROUPS * FILES, + uid, gid, path) +{ + IdsIce s(uid, gid); + VolumeClient c; + BOOST_CHECK_NO_THROW(c.s->ice_ping()); + + auto file = c.v->open(c.env, path, {}); + auto attr = file->fgetattr(c.env); + BOOST_CHECK_EQUAL(attr.uid, uid); + BOOST_CHECK_EQUAL(attr.gid, gid); + file->close(); +} + +BOOST_DATA_TEST_CASE(uid_gid_override_list, + USERS * GROUPS * DIRS, + uid, gid, path) +{ + IdsIce s(uid, gid); + VolumeClient c; + BOOST_CHECK_NO_THROW(c.s->ice_ping()); + + auto dir = c.v->opendir(c.env, path); + auto dir2 = Ice::checkedCast<NetFS::DirectoryV2Prx>(dir); + for (const auto & dirent : dir2->listdir()) { + BOOST_TEST_CONTEXT(dirent.first) { + BOOST_CHECK_EQUAL(dirent.second.uid, uid); + BOOST_CHECK_EQUAL(dirent.second.gid, gid); + } + } + dir->close(); +} + + diff --git a/unittests/core.cpp b/unittests/core.cpp index 78be8d7..6eef46a 100644 --- a/unittests/core.cpp +++ b/unittests/core.cpp @@ -43,12 +43,6 @@ namespace std { BOOST_TEST_GLOBAL_FIXTURE(Service); -BOOST_FIXTURE_TEST_SUITE(client, Client); - - // TODO - -BOOST_AUTO_TEST_SUITE_END(); - BOOST_FIXTURE_TEST_SUITE(volume, VolumeClient); BOOST_AUTO_TEST_CASE( unsupported_rofs_ops ) diff --git a/unittests/mockDefs.cpp b/unittests/mockDefs.cpp index 6d884d9..dff4cbc 100644 --- a/unittests/mockDefs.cpp +++ b/unittests/mockDefs.cpp @@ -1,7 +1,16 @@ #include <boost/test/test_tools.hpp> +#include <compileTimeFormatter.h> +#include <definedDirs.h> #include "mockDefs.h" -GitFS::Test::Service::Service() +using namespace AdHoc::literals; + +GitFS::Test::Service::Service() : + IceTray::DryIce({ + "--GitFS.testrepo.gitdir=%?"_fmt(rootDir.string()), + "--GitFS.testrepo.authkey=testauth", + "--GitFS.testrepo.commit=7a0ccb40084c3ab31d9856e7f689c0514c28c930", + }) { } diff --git a/unittests/service.cpp b/unittests/service.cpp new file mode 100644 index 0000000..aaa9d85 --- /dev/null +++ b/unittests/service.cpp @@ -0,0 +1,56 @@ +#define BOOST_TEST_MODULE GitFS_Service +#include <boost/test/unit_test.hpp> +#include <boost/test/data/test_case.hpp> + +#include <definedDirs.h> +#include <compileTimeFormatter.h> +#include "mockDefs.h" + +using namespace GitFS; +using namespace GitFS::Test; +using namespace AdHoc::literals; + +namespace btdata = boost::unit_test::data; + +BOOST_DATA_TEST_CASE(no_repos, + btdata::make({ "", "testrepo", "no repo" }) * + btdata::make({ "", "testauth", "badkey" }), + repo, key) +{ + IceTray::DryIce s; + Client c; + BOOST_CHECK_NO_THROW(c.s->ice_ping()); + + BOOST_CHECK_THROW(c.s->connect(repo, key), NetFS::ConfigError); +} + +BOOST_DATA_TEST_CASE(badauth, + btdata::make({ "", "testAuth", "badkey" }), + key) +{ + IceTray::DryIce s({ + "--GitFS.testrepo.gitdir=%?"_fmt(rootDir.string()), + "--GitFS.testrepo.authkey=testauth", + "--GitFS.testrepo.commit=7a0ccb40084c3ab31d9856e7f689c0514c28c930", + }); + Client c; + BOOST_CHECK_NO_THROW(c.s->ice_ping()); + + BOOST_CHECK_THROW(c.s->connect("testrepo", key), NetFS::AuthError); +} + +BOOST_AUTO_TEST_CASE(missing_repo) +{ + IceTray::DryIce s({ + "--GitFS.missing.gitdir=/not/here", + "--GitFS.missing.commit=7a0ccb40084c3ab31d9856e7f689c0514c28c930", + "--GitFS.testrepo.gitdir=%?"_fmt(rootDir.string()), + "--GitFS.testrepo.commit=7a0ccb40084c3ab31d9856e7f689c0514c28c931", + }); + Client c; + BOOST_CHECK_NO_THROW(c.s->ice_ping()); + + BOOST_CHECK_THROW(c.s->connect("missing", {}), NetFS::ConfigError); + BOOST_CHECK_THROW(c.s->connect("testrepo", {}), NetFS::ConfigError); +} + |