set<string> object_name_space;
map<string, map<string, string> > omap;
map<string, string > hmap;
+ map<string, map<string, string> > xattrs;
CollectionIndex::IndexedPath def_collection;
unsigned seq;
key, value);
}
+ void set_xattr(const string &objname, const string &key, const string &value) {
+ set_xattr(hobject_t(sobject_t(objname, CEPH_NOSNAP)), def_collection,
+ key, value);
+ }
+
void set_key(hobject_t hoid, CollectionIndex::IndexedPath path,
string key, string value) {
map<string, bufferlist> to_write;
db->set_keys(hoid, path, to_write);
}
+ void set_xattr(hobject_t hoid, CollectionIndex::IndexedPath path,
+ string key, string value) {
+ map<string, bufferlist> to_write;
+ bufferptr bp(value.c_str(), value.size());
+ bufferlist bl;
+ bl.append(bp);
+ to_write.insert(make_pair(key, bl));
+ db->set_xattrs(hoid, path, to_write);
+ }
+
void set_header(const string &objname, const string &value) {
set_header(hobject_t(sobject_t(objname, CEPH_NOSNAP)), def_collection,
value);
return 0;
}
+ int get_xattr(const string &objname, const string &key, string *value) {
+ return get_xattr(hobject_t(sobject_t(objname, CEPH_NOSNAP)), def_collection,
+ key, value);
+ }
+
+ int get_xattr(hobject_t hoid, CollectionIndex::IndexedPath path,
+ string key, string *value) {
+ set<string> to_get;
+ to_get.insert(key);
+ map<string, bufferlist> got;
+ db->get_xattrs(hoid, path, to_get, &got);
+ if (got.size()) {
+ *value = string(got.begin()->second.c_str(),
+ got.begin()->second.length());
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
int get_key(const string &objname, const string &key, string *value) {
return get_key(hobject_t(sobject_t(objname, CEPH_NOSNAP)), def_collection,
key, value);
db->rm_keys(hoid, path, to_remove);
}
+ void remove_xattr(const string &objname, const string &key) {
+ remove_xattr(hobject_t(sobject_t(objname, CEPH_NOSNAP)), def_collection,
+ key);
+ }
+
+ void remove_xattr(hobject_t hoid, CollectionIndex::IndexedPath path,
+ string key) {
+ set<string> to_remove;
+ to_remove.insert(key);
+ db->remove_xattrs(hoid, path, to_remove);
+ }
+
void clone(const string &objname, const string &target) {
clone(hobject_t(sobject_t(objname, CEPH_NOSNAP)), def_collection,
hobject_t(sobject_t(target, CEPH_NOSNAP)), def_collection);
"/" + coll_name, coll_t(coll_name));
}
+ void auto_set_xattr(ostream &out) {
+ set<string>::iterator key = rand_choose(key_space);
+ set<string>::iterator object = rand_choose(object_name_space);
+
+ string value = val_from_key(*object, *key);
+
+ xattrs[*object][*key] = value;
+ set_xattr(*object, *key, value);
+
+ out << "auto_set_xattr " << *object << ": " << *key << " -> "
+ << value << std::endl;
+ }
+
void auto_set_key(ostream &out) {
set<string>::iterator key = rand_choose(key_space);
set<string>::iterator object = rand_choose(object_name_space);
<< value << std::endl;
}
+ void xattrs_on_object(const string &object, set<string> *out) {
+ if (!xattrs.count(object))
+ return;
+ const map<string, string> &xmap = xattrs.find(object)->second;
+ for (map<string, string>::const_iterator i = xmap.begin();
+ i != xmap.end();
+ ++i) {
+ out->insert(i->first);
+ }
+ }
+
void keys_on_object(const string &object, set<string> *out) {
if (!omap.count(object))
return;
}
}
+ void xattrs_off_object(const string &object, set<string> *out) {
+ *out = key_space;
+ set<string> xspace;
+ xattrs_on_object(object, &xspace);
+ for (set<string>::iterator i = xspace.begin();
+ i != xspace.end();
+ ++i) {
+ out->erase(*i);
+ }
+ }
+
void keys_off_object(const string &object, set<string> *out) {
*out = key_space;
set<string> kspace;
}
}
+ int auto_check_present_xattr(ostream &out) {
+ set<string>::iterator object = rand_choose(object_name_space);
+ set<string> xspace;
+ xattrs_on_object(*object, &xspace);
+ set<string>::iterator key = rand_choose(xspace);
+ if (key == xspace.end()) {
+ return 1;
+ }
+
+ string result;
+ int r = get_xattr(*object, *key, &result);
+ if (!r) {
+ out << "auto_check_present_key: failed to find key "
+ << *key << " on object " << *object << std::endl;
+ return 0;
+ }
+
+ if (result != xattrs[*object][*key]) {
+ out << "auto_check_present_key: for key "
+ << *key << " on object " << *object
+ << " found value " << result << " where we should have found "
+ << xattrs[*object][*key] << std::endl;
+ return 0;
+ }
+
+ out << "auto_check_present_key: for key "
+ << *key << " on object " << *object
+ << " found value " << result << " where we should have found "
+ << xattrs[*object][*key] << std::endl;
+ return 1;
+ }
+
+
int auto_check_present_key(ostream &out) {
set<string>::iterator object = rand_choose(object_name_space);
set<string> kspace;
return 1;
}
+ int auto_check_absent_xattr(ostream &out) {
+ set<string>::iterator object = rand_choose(object_name_space);
+ set<string> xspace;
+ xattrs_off_object(*object, &xspace);
+ set<string>::iterator key = rand_choose(xspace);
+ if (key == xspace.end()) {
+ return 1;
+ }
+
+ string result;
+ int r = get_xattr(*object, *key, &result);
+ if (!r) {
+ out << "auto_check_absent_key: did not find key "
+ << *key << " on object " << *object << std::endl;
+ return 1;
+ }
+
+ out << "auto_check_basent_key: for key "
+ << *key << " on object " << *object
+ << " found value " << result << " where we should have found nothing"
+ << std::endl;
+ return 0;
+ }
+
int auto_check_absent_key(ostream &out) {
set<string>::iterator object = rand_choose(object_name_space);
set<string> kspace;
out << " hmap source present." << std::endl;
hmap[*target] = hmap[*object];
}
+ if (!xattrs.count(*object)) {
+ out << " hmap source missing." << std::endl;
+ xattrs.erase(*target);
+ } else {
+ out << " hmap source present." << std::endl;
+ xattrs[*target] = xattrs[*object];
+ }
}
void auto_remove_key(ostream &out) {
remove_key(*object, *key);
}
+ void auto_remove_xattr(ostream &out) {
+ set<string>::iterator object = rand_choose(object_name_space);
+ set<string> kspace;
+ xattrs_on_object(*object, &kspace);
+ set<string>::iterator key = rand_choose(kspace);
+ if (key == kspace.end()) {
+ return;
+ }
+ out << "removing xattr " << *key << " from " << *object << std::endl;
+ xattrs[*object].erase(*key);
+ remove_xattr(*object, *key);
+ }
+
void auto_delete_object(ostream &out) {
set<string>::iterator object = rand_choose(object_name_space);
out << "auto_delete_object " << *object << std::endl;
clear(*object);
omap.erase(*object);
hmap.erase(*object);
+ xattrs.erase(*object);
}
void auto_write_header(ostream &out) {
TEST_F(ObjectMapTest, RandomTest) {
def_init();
- for (unsigned i = 0; i < 1000; ++i) {
+ for (unsigned i = 0; i < 5000; ++i) {
unsigned val = rand();
val <<= 8;
val %= 100;
ASSERT_TRUE(auto_verify_header(std::cerr));
} else if (val < 30) {
auto_set_key(std::cerr);
+ } else if (val < 42) {
+ auto_set_xattr(std::cerr);
} else if (val < 55) {
ASSERT_TRUE(auto_check_present_key(std::cerr));
+ } else if (val < 62) {
+ ASSERT_TRUE(auto_check_present_xattr(std::cerr));
} else if (val < 70) {
ASSERT_TRUE(auto_check_absent_key(std::cerr));
+ } else if (val < 73) {
+ ASSERT_TRUE(auto_check_absent_xattr(std::cerr));
} else if (val < 76) {
auto_delete_object(std::cerr);
} else if (val < 85) {
auto_clone_key(std::cerr);
+ } else if (val < 92) {
+ auto_remove_xattr(std::cerr);
} else {
auto_remove_key(std::cerr);
}