void remove_object() {
ASSERT_EQ(0, rados_remove(ioctx, obj));
}
+ int cmp_xattr(const char *xattr, const char *value, size_t value_len,
+ uint8_t cmp_op)
+ {
+ rados_read_op_t op = rados_create_read_op();
+ rados_read_op_cmpxattr(op, xattr, cmp_op, value, value_len);
+ int r = rados_read_op_operate(op, ioctx, obj, 0);
+ rados_release_read_op(op);
+ return r;
+ }
+
+
+ void compare_xattrs(char const* const* keys,
+ char const* const* vals,
+ const size_t *lens,
+ size_t len,
+ rados_xattrs_iter_t iter)
+ {
+ size_t i = 0;
+ char *key = NULL;
+ char *val = NULL;
+ size_t val_len = 0;
+ while (i < len) {
+ ASSERT_EQ(0, rados_getxattrs_next(iter, (const char**) &key,
+ (const char**) &val, &val_len));
+ if (len == 0 && key == NULL && val == NULL)
+ break;
+ EXPECT_EQ(std::string(keys[i]), std::string(key));
+ EXPECT_EQ(0, memcmp(vals[i], val, val_len));
+ EXPECT_EQ(lens[i], val_len);
+ ++i;
+ }
+ ASSERT_EQ(i, len);
+ ASSERT_EQ(0, rados_getxattrs_next(iter, (const char**)&key,
+ (const char**)&val, &val_len));
+ ASSERT_EQ((char*)NULL, key);
+ ASSERT_EQ((char*)NULL, val);
+ ASSERT_EQ(0u, val_len);
+ rados_getxattrs_end(iter);
+ }
};
TEST_F(CReadOpsTest, NewDelete) {
remove_object();
}
+TEST_F(CReadOpsTest, CmpXattr) {
+ write_object();
+
+ char buf[len];
+ memset(buf, 0xcc, sizeof(buf));
+
+ const char *xattr = "test";
+ rados_setxattr(ioctx, obj, xattr, buf, sizeof(buf));
+
+ // equal value
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_EQ));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_NE));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_GT));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_GTE));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_LT));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_LTE));
+
+ // < value
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf) - 1, LIBRADOS_CMPXATTR_OP_EQ));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf) - 1, LIBRADOS_CMPXATTR_OP_NE));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf) - 1, LIBRADOS_CMPXATTR_OP_GT));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf) - 1, LIBRADOS_CMPXATTR_OP_GTE));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf) - 1, LIBRADOS_CMPXATTR_OP_LT));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf) - 1, LIBRADOS_CMPXATTR_OP_LTE));
+
+ // > value
+ memset(buf, 0xcd, sizeof(buf));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_EQ));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_NE));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_GT));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_GTE));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_LT));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, sizeof(buf), LIBRADOS_CMPXATTR_OP_LTE));
+
+ // it compares C strings, so NUL at the beginning is the same
+ // regardless of the following data
+ rados_setxattr(ioctx, obj, xattr, "\0\0", 1);
+ buf[0] = '\0';
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_EQ));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_NE));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_GT));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_GTE));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_LT));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_LTE));
+
+ buf[1] = '\0';
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_EQ));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_NE));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_GT));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_GTE));
+ EXPECT_EQ(-ECANCELED, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_LT));
+ EXPECT_EQ(1, cmp_xattr(xattr, buf, 2, LIBRADOS_CMPXATTR_OP_LTE));
+
+ remove_object();
+}
+
TEST_F(CReadOpsTest, Read) {
write_object();
EXPECT_EQ(-ENOENT, rados_read_op_operate(op, ioctx, obj, 0));
rados_release_read_op(op);
}
+
+TEST_F(CReadOpsTest, GetXattrs) {
+ write_object();
+
+ char *keys[] = {(char*)"bar",
+ (char*)"foo",
+ (char*)"test1",
+ (char*)"test2"};
+ char *vals[] = {(char*)"",
+ (char*)"\0",
+ (char*)"abc",
+ (char*)"va\0lue"};
+ size_t lens[] = {0, 1, 3, 6};
+
+ int rval = 1;
+ rados_read_op_t op = rados_create_read_op();
+ rados_xattrs_iter_t it;
+ rados_read_op_getxattrs(op, &it, &rval);
+ EXPECT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
+ EXPECT_EQ(0, rval);
+ rados_release_read_op(op);
+ compare_xattrs(keys, vals, lens, 0, it);
+
+ for (int i = 0; i < 4; ++i)
+ rados_setxattr(ioctx, obj, keys[i], vals[i], lens[i]);
+
+ rval = 1;
+ op = rados_create_read_op();
+ rados_read_op_getxattrs(op, &it, &rval);
+ EXPECT_EQ(0, rados_read_op_operate(op, ioctx, obj, 0));
+ EXPECT_EQ(0, rval);
+ rados_release_read_op(op);
+ compare_xattrs(keys, vals, lens, 4, it);
+
+ remove_object();
+}