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_real(self): name = 'cloud6-1429' c = Crush() c.parse('tests/test_crush_filter.json') crushmap = c.get_crushmap() optimize = sorted(crushmap['choose_args']['optimize'], key=lambda v: v['bucket_id']) assert 3 == len(optimize) assert -1 == optimize[2]['bucket_id'] assert 7 == len(optimize[2]['weight_set'][0]) bucket = c.find_bucket(name) assert name == bucket['name'] c.filter(lambda x: x.get('name') != name, crushmap['trees'][0]) optimize = crushmap['choose_args']['optimize'] assert 2 == len(optimize) assert -1 == optimize[1]['bucket_id'] assert 6 == len(optimize[1]['weight_set'][0]) assert c.find_bucket(name) is None
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