More work on metadata_checker_t
This commit is contained in:
parent
647cb68b76
commit
3832fd5952
@ -101,7 +101,8 @@ namespace {
|
||||
metadata::ptr md(new metadata(bm_, metadata::CREATE, 128, 10240));
|
||||
emitter::ptr restorer = create_restore_emitter(md);
|
||||
|
||||
restorer->begin_superblock("test-generated", 0, 0, 128, 10240, boost::optional<uint64_t>());
|
||||
restorer->begin_superblock("test-generated", 0, 0, 128, 10240,
|
||||
boost::optional<uint64_t>());
|
||||
|
||||
list<uint32_t>::const_iterator it, end = devices_.end();
|
||||
for (it = devices_.begin(); it != end; ++it) {
|
||||
@ -122,6 +123,70 @@ namespace {
|
||||
list<uint32_t> devices_;
|
||||
};
|
||||
|
||||
class devices_visitor : public detail_tree::visitor {
|
||||
public:
|
||||
struct node_info {
|
||||
bool leaf;
|
||||
unsigned level;
|
||||
block_address b;
|
||||
range<uint64_t> keys;
|
||||
};
|
||||
|
||||
typedef btree_detail::node_location node_location;
|
||||
typedef boost::shared_ptr<devices_visitor> ptr;
|
||||
|
||||
virtual bool visit_internal(node_location const &loc,
|
||||
detail_tree::internal_node const &n) {
|
||||
record_node(false, loc.level, loc.key, n);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool visit_internal_leaf(node_location const &loc,
|
||||
detail_tree::internal_node const &n) {
|
||||
record_node(true, loc.level, loc.key, n);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
virtual bool visit_leaf(node_location const &loc,
|
||||
detail_tree::leaf_node const &n) {
|
||||
record_node(true, loc.level, loc.key, n);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void visit_complete() {
|
||||
}
|
||||
|
||||
list<node_info> const &get_nodes() const {
|
||||
return nodes_;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename N>
|
||||
void record_node(bool leaf, unsigned level,
|
||||
boost::optional<uint64_t> key,
|
||||
N const &n) {
|
||||
node_info ni;
|
||||
|
||||
ni.leaf = leaf;
|
||||
ni.level = level;
|
||||
ni.b = n.get_location();
|
||||
|
||||
if (n.get_nr_entries())
|
||||
ni.keys = range<uint64_t>(n.key_at(0));
|
||||
else {
|
||||
if (key)
|
||||
ni.keys = range<uint64_t>(*key);
|
||||
else
|
||||
ni.keys = range<uint64_t>();
|
||||
}
|
||||
|
||||
nodes_.push_back(ni);
|
||||
}
|
||||
|
||||
list<node_info> nodes_;
|
||||
};
|
||||
|
||||
//--------------------------------
|
||||
|
||||
class damage_visitor_mock : public metadata_damage_visitor {
|
||||
@ -141,7 +206,7 @@ namespace {
|
||||
class MetadataCheckerTests : public Test {
|
||||
public:
|
||||
MetadataCheckerTests()
|
||||
: bm_(create_bm<BLOCK_SIZE>()),
|
||||
: bm_(create_bm<BLOCK_SIZE>(NR_BLOCKS)),
|
||||
builder_(bm_) {
|
||||
}
|
||||
|
||||
@ -264,4 +329,28 @@ TEST_F(DeviceCheckerTests, fails_with_corrupt_root)
|
||||
(*damage->begin())->visit(v);
|
||||
}
|
||||
|
||||
TEST_F(DeviceCheckerTests, damaging_some_btree_nodes_results_in_the_correct_devices_being_flagged_as_missing)
|
||||
{
|
||||
metadata_builder &b = get_builder();
|
||||
|
||||
for (unsigned i = 0; i < 1000; i++)
|
||||
b.add_device(i);
|
||||
|
||||
b.build();
|
||||
|
||||
devices_visitor::ptr scanner(new devices_visitor);
|
||||
transaction_manager::ptr tm = open_temporary_tm(bm_);
|
||||
detail_tree::ptr devices(new detail_tree(tm, devices_root(),
|
||||
device_details_traits::ref_counter()));
|
||||
devices->visit_depth_first(scanner);
|
||||
|
||||
list<devices_visitor::node_info>::const_iterator it, end = scanner->get_nodes().end();
|
||||
for (it = scanner->get_nodes().begin(); it != end; ++it) {
|
||||
cerr << "block " << it->b << ", keys" << it->keys << endl;
|
||||
}
|
||||
|
||||
damage_list_ptr damage = mk_checker()->check();
|
||||
ASSERT_THAT(damage->size(), Eq(1u));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user