From 26868ed4a2b2204db24fb7aa1e84dabe7d9c8a74 Mon Sep 17 00:00:00 2001 From: Noah Watkins Date: Sun, 26 Jun 2016 18:10:22 -0700 Subject: [PATCH] objclass: implement 'osd class default list' Signed-off-by: Noah Watkins --- src/common/config_opts.h | 2 + src/osd/ClassHandler.cc | 1 + src/osd/ClassHandler.h | 2 + src/osd/OSD.cc | 1 + src/osd/OSDCap.cc | 40 +- src/osd/OSDCap.h | 8 +- src/osd/OpRequest.cc | 21 +- src/osd/OpRequest.h | 24 +- src/osd/PG.cc | 6 +- src/test/osd/osdcap.cc | 916 ++++++++++++++++++++++++++++----------- src/vstart.sh | 1 + 11 files changed, 747 insertions(+), 275 deletions(-) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 21a9d378a1e..ec870a4c2da 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -777,6 +777,8 @@ OPTION(osd_class_dir, OPT_STR, CEPH_LIBDIR "/rados-classes") // where rados plug OPTION(osd_open_classes_on_start, OPT_BOOL, true) OPTION(osd_class_load_list, OPT_STR, "cephfs hello journal lock log numops " "rbd refcount replica_log rgw statelog timeindex user version") // list of object classes allowed to be loaded (allow all: *) +OPTION(osd_class_default_list, OPT_STR, "cephfs hello journal lock log numops " + "rbd refcount replica_log rgw statelog timeindex user version") // list of object classes with default execute perm (allow all: *) OPTION(osd_check_for_log_corruption, OPT_BOOL, false) OPTION(osd_use_stale_snap, OPT_BOOL, false) OPTION(osd_rollback_to_cluster_snap, OPT_STR, "") diff --git a/src/osd/ClassHandler.cc b/src/osd/ClassHandler.cc index d116f75ad89..46ba48d19e6 100644 --- a/src/osd/ClassHandler.cc +++ b/src/osd/ClassHandler.cc @@ -125,6 +125,7 @@ ClassHandler::ClassData *ClassHandler::_get_class(const string& cname, dout(10) << "_get_class adding new class name " << cname << " " << cls << dendl; cls->name = cname; cls->handler = this; + cls->whitelisted = in_class_list(cname, cct->_conf->osd_class_default_list); } return cls; } diff --git a/src/osd/ClassHandler.h b/src/osd/ClassHandler.h index 6bdf6705052..f0e09422fce 100644 --- a/src/osd/ClassHandler.h +++ b/src/osd/ClassHandler.h @@ -57,6 +57,8 @@ public: ClassHandler *handler; void *handle; + bool whitelisted; + map methods_map; map filters_map; diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index f5ec2c505b5..b06953c1296 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -9246,6 +9246,7 @@ int OSD::init_op_flags(OpRequestRef& op) op->set_class_write(); if (is_promote) op->set_promote(); + op->add_class(cname, is_read, is_write, cls->whitelisted); break; } diff --git a/src/osd/OSDCap.cc b/src/osd/OSDCap.cc index b9944e57e54..c8cfbfab1f3 100644 --- a/src/osd/OSDCap.cc +++ b/src/osd/OSDCap.cc @@ -130,20 +130,46 @@ void OSDCap::set_allow_all() } bool OSDCap::is_capable(const string& pool_name, const string& ns, int64_t pool_auid, - const string& object, bool op_may_read, - bool op_may_write, bool op_may_class_read, - bool op_may_class_write) const + const string& object, bool op_may_read, bool op_may_write, + const std::vector& classes) const { + const size_t num_classes = classes.size(); + std::vector class_allowed(num_classes, false); osd_rwxa_t allow = 0; for (vector::const_iterator p = grants.begin(); p != grants.end(); ++p) { if (p->match.is_match(pool_name, ns, pool_auid, object)) { allow = allow | p->spec.allow; if ((op_may_read && !(allow & OSD_CAP_R)) || - (op_may_write && !(allow & OSD_CAP_W)) || - (op_may_class_read && !(allow & OSD_CAP_CLS_R)) || - (op_may_class_write && !(allow & OSD_CAP_CLS_W))) - continue; + (op_may_write && !(allow & OSD_CAP_W))) + continue; + if (num_classes) { + // check 'allow *' + if (p->spec.allow_all()) + return true; + // compare this grant to each class in the operation + for (size_t i = 0; i < num_classes; i++) { + // check 'allow class foo' + if (classes[i].name == p->spec.class_name && + !p->spec.class_name.empty()) { + class_allowed[i] = true; + continue; + } + // check 'allow x | class-{rw}': must be on whitelist + if (!classes[i].whitelisted) + continue; + if ((classes[i].read && !(allow & OSD_CAP_CLS_R)) || + (classes[i].write && !(allow & OSD_CAP_CLS_W))) { + continue; + } + class_allowed[i] = true; + } + if (std::all_of(class_allowed.cbegin(), class_allowed.cend(), + [](bool v) { return v; })) + return true; + else + continue; + } return true; } } diff --git a/src/osd/OSDCap.h b/src/osd/OSDCap.h index 2a1eb0d4916..3a1a722aaa7 100644 --- a/src/osd/OSDCap.h +++ b/src/osd/OSDCap.h @@ -31,6 +31,7 @@ using std::ostream; #include "include/types.h" +#include "OpRequest.h" static const __u8 OSD_CAP_R = (1 << 1); // read static const __u8 OSD_CAP_W = (1 << 2); // write @@ -140,15 +141,12 @@ struct OSDCap { * @param object name of the object we are accessing * @param op_may_read whether the operation may need to read * @param op_may_write whether the operation may need to write - * @param op_may_class_read whether the operation needs to call a - * read class method - * @param op_may_class_write whether the operation needs to call a - * write class method + * @param classes (class-name, rd, wr, whitelisted-flag) tuples * @return true if the operation is allowed, false otherwise */ bool is_capable(const string& pool_name, const string& ns, int64_t pool_auid, const string& object, bool op_may_read, bool op_may_write, - bool op_may_class_read, bool op_may_class_write) const; + const std::vector& classes) const; }; static inline ostream& operator<<(ostream& out, const OSDCap& cap) diff --git a/src/osd/OpRequest.cc b/src/osd/OpRequest.cc index 9bad447b69f..746f8efc9b3 100644 --- a/src/osd/OpRequest.cc +++ b/src/osd/OpRequest.cc @@ -89,8 +89,12 @@ bool OpRequest::check_rmw(int flag) { assert(rmw_flags != 0); return rmw_flags & flag; } -bool OpRequest::may_read() { return need_read_cap() || need_class_read_cap(); } -bool OpRequest::may_write() { return need_write_cap() || need_class_write_cap(); } +bool OpRequest::may_read() { + return need_read_cap() || check_rmw(CEPH_OSD_RMW_FLAG_CLASS_READ); +} +bool OpRequest::may_write() { + return need_write_cap() || check_rmw(CEPH_OSD_RMW_FLAG_CLASS_WRITE); +} bool OpRequest::may_cache() { return check_rmw(CEPH_OSD_RMW_FLAG_CACHE); } bool OpRequest::includes_pg_op() { return check_rmw(CEPH_OSD_RMW_FLAG_PGOP); } bool OpRequest::need_read_cap() { @@ -99,12 +103,6 @@ bool OpRequest::need_read_cap() { bool OpRequest::need_write_cap() { return check_rmw(CEPH_OSD_RMW_FLAG_WRITE); } -bool OpRequest::need_class_read_cap() { - return check_rmw(CEPH_OSD_RMW_FLAG_CLASS_READ); -} -bool OpRequest::need_class_write_cap() { - return check_rmw(CEPH_OSD_RMW_FLAG_CLASS_WRITE); -} bool OpRequest::need_promote() { return check_rmw(CEPH_OSD_RMW_FLAG_FORCE_PROMOTE); } @@ -147,3 +145,10 @@ void OpRequest::mark_flag_point(uint8_t flag, const string& s) { reqid.name._num, reqid.tid, reqid.inc, rmw_flags, flag, s.c_str(), old_flags, hit_flag_points); } + +ostream& operator<<(ostream& out, const OpRequest::ClassInfo& i) +{ + out << "class " << i.name << " rd " << i.read + << " wr " << i.write << " wl " << i.whitelisted; + return out; +} diff --git a/src/osd/OpRequest.h b/src/osd/OpRequest.h index c8649b8500a..7982e1a44b4 100644 --- a/src/osd/OpRequest.h +++ b/src/osd/OpRequest.h @@ -63,8 +63,6 @@ struct OpRequest : public TrackedOp { bool includes_pg_op(); bool need_read_cap(); bool need_write_cap(); - bool need_class_read_cap(); - bool need_class_write_cap(); bool need_promote(); bool need_skip_handle_cache(); bool need_skip_promote(); @@ -78,6 +76,24 @@ struct OpRequest : public TrackedOp { void set_skip_handle_cache(); void set_skip_promote(); + struct ClassInfo { + ClassInfo(const std::string& name, bool read, bool write, + bool whitelisted) : + name(name), read(read), write(write), whitelisted(whitelisted) + {} + const std::string name; + const bool read, write, whitelisted; + }; + + void add_class(const std::string& name, bool read, bool write, + bool whitelisted) { + classes_.emplace_back(name, read, write, whitelisted); + } + + std::vector classes() const { + return classes_; + } + void _dump(utime_t now, Formatter *f) const; bool has_feature(uint64_t f) const { @@ -97,6 +113,8 @@ private: static const uint8_t flag_sub_op_sent = 1 << 4; static const uint8_t flag_commit_sent = 1 << 5; + std::vector classes_; + OpRequest(Message *req, OpTracker *tracker); protected: @@ -176,4 +194,6 @@ private: typedef OpRequest::Ref OpRequestRef; +ostream& operator<<(ostream& out, const OpRequest::ClassInfo& i); + #endif /* OPREQUEST_H_ */ diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 9f4136f5666..228cb1b397b 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -1869,16 +1869,14 @@ bool PG::op_has_sufficient_caps(OpRequestRef& op) pool.auid, key, op->need_read_cap(), op->need_write_cap(), - op->need_class_read_cap(), - op->need_class_write_cap()); + op->classes()); dout(20) << "op_has_sufficient_caps pool=" << pool.id << " (" << pool.name << " " << req->get_object_locator().nspace << ") owner=" << pool.auid << " need_read_cap=" << op->need_read_cap() << " need_write_cap=" << op->need_write_cap() - << " need_class_read_cap=" << op->need_class_read_cap() - << " need_class_write_cap=" << op->need_class_write_cap() + << " classes=" << op->classes() << " -> " << (cap ? "yes" : "NO") << dendl; return cap; diff --git a/src/test/osd/osdcap.cc b/src/test/osd/osdcap.cc index a9aefd729e3..95dc40ba556 100644 --- a/src/test/osd/osdcap.cc +++ b/src/test/osd/osdcap.cc @@ -150,10 +150,16 @@ TEST(OSDCap, AllowAll) { ASSERT_TRUE(cap.parse("allow *", NULL)); ASSERT_TRUE(cap.allow_all()); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "asdf", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "anamespace", 0, "asdf", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "asdf", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "anamespace", 0, "asdf", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "asdf", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "anamespace", 0, "asdf", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "asdf", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "anamespace", 0, "asdf", true, true, {{"cls", true, true, true}})); + + // 'allow *' overrides whitelist + ASSERT_TRUE(cap.is_capable("foo", "", 0, "asdf", true, true, {{"cls", true, true, false}})); + ASSERT_TRUE(cap.is_capable("foo", "anamespace", 0, "asdf", true, true, {{"cls", true, true, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "asdf", true, true, {{"cls", true, true, false}})); + ASSERT_TRUE(cap.is_capable("bar", "anamespace", 0, "asdf", true, true, {{"cls", true, true, false}})); } TEST(OSDCap, AllowPool) { @@ -161,10 +167,14 @@ TEST(OSDCap, AllowPool) { bool r = cap.parse("allow rwx pool foo", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, {{"cls", true, true, true}})); + // true->false for classes not on whitelist + ASSERT_FALSE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "", true, true, {{"cls", true, true, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, {{"cls", true, true, true}})); } TEST(OSDCap, AllowPools) { @@ -172,14 +182,20 @@ TEST(OSDCap, AllowPools) { bool r = cap.parse("allow rwx pool foo, allow r pool bar", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("baz", "ns", 0, "", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, {{"cls", true, true, true}})); + // true-false for classes not on whitelist + ASSERT_FALSE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "", true, true, {{"cls", true, true, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "", true, false, {})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, {{"cls", true, true, true}})); + + ASSERT_FALSE(cap.is_capable("baz", "", 0, "", true, false, {})); + ASSERT_FALSE(cap.is_capable("baz", "ns", 0, "", true, false, {})); } TEST(OSDCap, AllowPools2) { @@ -187,9 +203,12 @@ TEST(OSDCap, AllowPools2) { bool r = cap.parse("allow r, allow rwx pool foo", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, true}})); + // true-false for classes not on whitelist + ASSERT_FALSE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, {{"cls", true, true, true}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, {})); } TEST(OSDCap, ObjectPrefix) { @@ -197,13 +216,17 @@ TEST(OSDCap, ObjectPrefix) { bool r = cap.parse("allow rwx object_prefix foo", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, true, true)); - - ASSERT_FALSE(cap.is_capable("bar", "", 0, "_foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, " foo ", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "fo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, {{"cls", true, true, true}})); + // true-false for classes not on whitelist + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "food", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo_bar", true, true, {{"cls", true, true, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "_foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, " foo ", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "fo", true, true, {{"cls", true, true, true}})); } TEST(OSDCap, ObjectPoolAndPrefix) { @@ -211,324 +234,412 @@ TEST(OSDCap, ObjectPoolAndPrefix) { bool r = cap.parse("allow rwx pool bar object_prefix foo", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, true, true)); - - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "food", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "fo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, {{"cls", true, true, true}})); + // true-false for classes not on whitelist + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "food", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo_bar", true, true, {{"cls", true, true, false}})); + + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "food", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "fo", true, true, {{"cls", true, true, true}})); } TEST(OSDCap, BasicR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow r", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {})); } TEST(OSDCap, BasicW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow w", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {})); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {})); } TEST(OSDCap, BasicX) { OSDCap cap; ASSERT_TRUE(cap.parse("allow x", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); - - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}})); + // true->false when class not on whitelist + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {})); } TEST(OSDCap, BasicRW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow rw", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {})); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); } TEST(OSDCap, BasicRX) { OSDCap cap; ASSERT_TRUE(cap.parse("allow rx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, true)); - - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, true, true}})); + // true->false for class not on whitelist + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, true, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {})); } TEST(OSDCap, BasicWX) { OSDCap cap; ASSERT_TRUE(cap.parse("allow wx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); - - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}})); + // true->false for class not on whitelist + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {})); } TEST(OSDCap, BasicRWX) { OSDCap cap; ASSERT_TRUE(cap.parse("allow rwx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, true}})); + // true->false for class not on whitelist + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, false}})); } TEST(OSDCap, BasicRWClassRClassW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow rw class-read class-write", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, false}})); } TEST(OSDCap, ClassR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow class-read", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}})); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); } TEST(OSDCap, ClassW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow class-write", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, false}})); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); } TEST(OSDCap, ClassRW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow class-read class-write", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); - - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); } TEST(OSDCap, BasicRClassR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow r class-read", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); - - ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {})); + + ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, {})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, false, {{"cls", true, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, {})); } TEST(OSDCap, PoolClassR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow pool bar r class-read, allow pool foo rwx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); - - ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, false, false)); - - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, false)); - - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, false)); - - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, false, false)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, false, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {})); + + ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, {})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, {{"cls", true, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, {})); + + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, {})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, false}})); + + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, {})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, false, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", false, false, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", false, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, false, false}})); + + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, {})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, false, true}})); } TEST(OSDCap, PoolClassRNS) { OSDCap cap; ASSERT_TRUE(cap.parse("allow pool bar namespace='' r class-read, allow pool foo namespace=ns rwx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, false, false)); - - ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, false, false)); - ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, true, true)); - ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, false, true)); - ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, false, true)); - ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, true, false)); - - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, false)); - - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, false, false)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, false, true)); - ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {})); + + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, {})); + + ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, {})); + + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, {})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, true}})); + + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, {})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, false, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", false, false, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", false, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, false, false}})); + + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, {})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, false, true}})); } TEST(OSDCap, NSClassR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow namespace '' rw class-read class-write, allow namespace test r", NULL)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false)); - - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, false)); - - ASSERT_TRUE(cap.is_capable("bar", "test", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, false, false)); - - ASSERT_TRUE(cap.is_capable("foo", "test", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, false, false)); - - ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, true, false)); - ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, false}})); + + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, {})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, {})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, true}})); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, true}})); + // true->false when class not whitelisted + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, false}})); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "test", 0, "foo", true, false, {})); + + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, {})); + + ASSERT_TRUE(cap.is_capable("foo", "test", 0, "foo", true, false, {})); + + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, {{"cls", true, true, true}})); + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, {{"cls", false, true, true}})); + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, {})); + + ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", true, false, {})); + ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, true, {})); + ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, {{"cls", true, false, true}})); + ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, {{"cls", false, true, true}})); } TEST(OSDCap, OutputParsed) @@ -588,3 +699,310 @@ TEST(OSDCap, OutputParsed) ASSERT_EQ(test_values[i].output, stringify(cap)); } } + +TEST(OSDCap, AllowClass) { + OSDCap cap; + ASSERT_TRUE(cap.parse("allow class foo", NULL)); + + // can call any method on class foo regardless of whitelist status + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}})); + + // does not permit invoking class bar + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, false}})); +} + +TEST(OSDCap, AllowClass2) { + OSDCap cap; + ASSERT_TRUE(cap.parse("allow class foo, allow class bar", NULL)); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, false}})); +} + +TEST(OSDCap, AllowClassRWX) { + OSDCap cap; + ASSERT_TRUE(cap.parse("allow rwx, allow class foo", NULL)); + + // can call any method on class foo regardless of whitelist status + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}})); + + // does not permit invoking class bar + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, false}})); + + // allows class bar if it is whitelisted + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, true}})); +} + +TEST(OSDCap, AllowClassMulti) { + OSDCap cap; + ASSERT_TRUE(cap.parse("allow class foo", NULL)); + + // can call any method on foo, but not bar, so the entire op is rejected + // bar with whitelist is rejected because it still needs rwx/class-read,write + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, false}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, true}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, false}})); + + // these are OK because 'bar' is on the whitelist BUT the calls don't read or write + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, true}})); + + // can call any method on foo or bar regardless of whitelist status + OSDCap cap2; + ASSERT_TRUE(cap2.parse("allow class foo, allow class bar", NULL)); + + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, false}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, true}})); + ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, false}})); +} + +TEST(OSDCap, AllowClassMultiRWX) { + OSDCap cap; + ASSERT_TRUE(cap.parse("allow rwx, allow class foo", NULL)); + + // can call anything on foo, but only whitelisted methods on bar + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, true}})); + + // fails because bar not whitelisted + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, true}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, true}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, true}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, true}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, true}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, true}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, false}})); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, true}})); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, true}})); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, false}})); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, false}})); +} diff --git a/src/vstart.sh b/src/vstart.sh index 5f06abde559..d217e626dda 100755 --- a/src/vstart.sh +++ b/src/vstart.sh @@ -525,6 +525,7 @@ $DAEMONOPTS osd class tmp = out osd class dir = $OBJCLASS_PATH osd class load list = * + osd class default list = * osd scrub load threshold = 2000.0 osd debug op order = true filestore wbthrottle xfs ios start flusher = 10 -- 2.39.5