def analyze_failures(self, c, take, failure_domain): if failure_domain == 0: # failure domain == device is a border case return None root = c.find_bucket(take) worst = pd.DataFrame() available_buckets = c.collect_buckets_by_type([root], failure_domain) if len(available_buckets) <= self.args.replication_count: log.error("there are not enough " + failure_domain + " to sustain failure") return None for may_fail in available_buckets: f = Crush(verbose=self.args.debug, backward_compatibility=self.args.backward_compatibility) f.crushmap = copy.deepcopy(c.get_crushmap()) root = f.find_bucket(take) f.filter(lambda x: x.get('name') != may_fail.get('name'), root) f.parse(f.crushmap) try: a = self.run_simulation(f, take, failure_domain) a['~over filled %~'] = a['~over/under filled %~'] a = a[['~type~', '~over filled %~']] worst = pd.concat([worst, a]).groupby(['~type~']).max().reset_index() except BadMapping: log.error("mapping failed when removing {}".format(may_fail)) return worst.set_index('~type~')
def test_filter_basic(self): root = { 'name': 'root', 'id': -5, 'children': [ { 'name': 'bucket2', 'id': -3 }, { 'name': 'bucket1', 'id': -2, 'children': [{ 'id': 1 }, { 'id': 2 }, { 'id': 4 }] }, { 'name': 'bucket3', 'id': -1, 'children': [{ 'id': 5 }, { 'id': 6 }, { 'id': 7 }] }, ] } expected_root = { 'name': 'root', 'id': -5, 'children': [ { 'name': 'bucket2', 'id': -3 }, { 'name': 'bucket1', 'id': -2, 'children': [{ 'id': 1 }] }, { 'name': 'bucket3', 'id': -1, 'children': [{ 'id': 5 }, { 'id': 7 }] }, ] } choose_args = [ { 'bucket_id': -2, 'ids': [11, 12, 14], 'weight_set': [[11.0, 12.0, 14.0]] }, { 'bucket_id': -1, 'ids': [15, 16, 17] }, ] expected_choose_args = [ { 'bucket_id': -2, 'ids': [11], 'weight_set': [[11.0]] }, { 'bucket_id': -1, 'ids': [15, 17] }, ] c = Crush() c.crushmap = {} c.crushmap['trees'] = [root] c.crushmap['choose_args'] = {"one": choose_args} def fun(x): if x.get('id') in (2, 4, 6): return False return True c.filter(fun, root) assert expected_root == root assert expected_choose_args == choose_args
def test_merge_split_choose_args(self): c = Crush() split = { 'choose_args': { 'a': [ { 'bucket_id': -3 }, { 'bucket_id': -2 }, { 'bucket_id': -1 }, ], 'b': [ { 'bucket_id': -1 }, ] }, 'trees': [ { 'id': -1, 'children': [{ 'id': -3, 'children': [{ 'id': -4 }] }], }, { 'id': -2 }, ] } merged = { 'trees': [{ 'id': -1, 'children': [{ 'id': -3, 'children': [{ 'id': -4 }], 'choose_args': { 'a': { 'bucket_id': -3 } }, }], 'choose_args': { 'a': { 'bucket_id': -1 }, 'b': { 'bucket_id': -1 } }, }, { 'id': -2, 'choose_args': { 'a': { 'bucket_id': -2 } } }] } c.crushmap = copy.deepcopy(split) assert c._merge_choose_args() assert merged == c.crushmap # do nothing if no choose_args assert c._merge_choose_args() is False c._split_choose_args() assert split == c.crushmap