コード例 #1
0
    def test_classify_blocks(self):

        gid = 'g000640000000123'

        g = BlockGroup(block_group_id=gid,
                       idcs=['a', 'b', 'c'],
                       config=_ec_config)

        blks = g.classify_blocks(0, only_primary=True)
        self.assertEqual([], blks['ec'] + blks['replica'] + blks['mark_del'])

        base_blk = BlockDesc({
            'size': 1000,
            'range': ['0a', '0b'],
            'is_del': 0
        })

        ec_blk_idxes = ['0000', '0001']
        replica_blk_idxes = ['0002', '0008', '0012']
        mark_del_idxes = ['0003', '0004']

        for i, idx in enumerate(ec_blk_idxes + replica_blk_idxes +
                                mark_del_idxes):

            typ = g.get_block_type(idx)

            blkid = BlockID(typ, gid, idx, DriveID('idc000'
                                                   'c62d8736c7280002'), i)

            blk = copy.deepcopy(base_blk)

            blk['block_id'] = blkid

            if idx in mark_del_idxes:
                blk['is_del'] = 1

            g.add_block(blk)

        for only_primary in (True, False):

            blks = g.classify_blocks(0, only_primary)

            blk_idxes = []

            for blk in blks['ec'] + blks['replica'] + blks['mark_del']:
                idx = BlockID(blk['block_id']).block_index
                blk_idxes.append(idx)

            expect_ids = copy.deepcopy(ec_blk_idxes)

            #'0004' in ec_blk_idxes is parity, so should not in mark_del
            if only_primary is True:
                expect_ids += replica_blk_idxes[:1] + mark_del_idxes[:1]
            else:
                expect_ids += replica_blk_idxes + mark_del_idxes[:1]

            self.assertEqual(expect_ids, blk_idxes)
コード例 #2
0
ファイル: test_block_desc.py プロジェクト: bsc-s2/ops
    def test_blockdesc(self):

        block_id = 'd1g0006300000001230101idc000c62d8736c72800020000000001'
        cases = ((None, {
            'block_id': None,
            'size': 0,
            'range': None,
            'ts_range': None,
            'ref_num': 0,
            'is_del': 0
        }), ({
            'block_id': block_id,
            'range': ['a', 'b'],
            'ts_range': ["124", None],
            'ref_num': 0,
            'size': 34,
            'mtime': 1,
            'is_del': 0
        }, {
            'block_id': BlockID(block_id),
            'range': rangeset.Range('a', 'b'),
            'ts_range': ["124", None],
            'ref_num': 0,
            'size': 34,
            'mtime': 1,
            'is_del': 0
        }), ({
            'block_id': BlockID(block_id),
            'range': rangeset.Range('b', 'bb'),
            'ts_range': ["1235", "456"],
            'ref_num': 0,
            'mtime': 1
        }, {
            'block_id': BlockID(block_id),
            'range': rangeset.Range('b', 'bb'),
            'ts_range': ["1235", "456"],
            'ref_num': 0,
            'size': 0,
            'mtime': 1,
            'is_del': 0,
        }))

        for b, expected in cases:
            if b is None:
                blk = BlockDesc()
                expected['mtime'] = blk["mtime"]
            else:
                blk = BlockDesc(b)

            self.assertEqual(expected, blk)

        self.assertRaises(ValueError, BlockDesc, is_del='a')
        self.assertRaises(ValueError, BlockDesc, size='a')
        self.assertRaises(KeyError, BlockDesc, a=3)
コード例 #3
0
    def test_json(self):
        region = Region({
            'range': ['a', 'z'],
            'levels':
            [[['a', 'b', BlockDesc()],
              [
                  'b', 'c',
                  BlockDesc(
                      size=2,
                      block_id=BlockID(
                          'd1g0006300000001230101idc000c62d8736c72800020000000001'
                      ))
              ]]]
        })
        rst = utfjson.dump(region)
        expected = (
            '{"range": ["a", "z"], "levels": [[["a", "b", '
            '{"is_del": 0, "range": null, "block_id": null, "size": 0}], '
            '["b", "c", {"is_del": 0, "range": null, '
            '"block_id": "d1g0006300000001230101idc000c62d8736c72800020000000001", "size": 2}]]], "idc": ""}'
        )
        self.assertEqual(expected, rst)

        loaded = Region(utfjson.load(rst))
        self.assertEqual(region, loaded)
コード例 #4
0
ファイル: test_block_group.py プロジェクト: drmingdrmer/pykit
    def test_get_replica_blocks(self):
        ec_blk_idxes = ['0000', '0001', '0003']
        replica_blk_idxes = ['0002', '0008', '0012']

        bg = self.make_test_block_group(ec_blk_idxes + replica_blk_idxes)

        replica_blks = bg.indexes_to_blocks(replica_blk_idxes)

        for blk in replica_blks:
            bid = blk['block_id']

            act_replica_blks = bg.get_replica_blocks(bid)
            self.assertListEqual(replica_blks, act_replica_blks)

            _replica_blks = copy.deepcopy(replica_blks)
            _replica_blks.remove(blk)

            act_replica_blks = bg.get_replica_blocks(bid, include_me=False)
            self.assertListEqual(_replica_blks, act_replica_blks)

        fake_bid = BlockID('d0', 'g000640000000125', '0000',
                           DriveID('idc000'
                                   'c62d8736c7280002'), 1)

        self.assertIsNone(bg.get_replica_blocks(fake_bid, raise_error=False))
        self.assertRaises(BlockNotFoundError,
                          bg.get_replica_blocks,
                          fake_bid,
                          raise_error=True)
        self.assertRaises(BlockNotFoundError, bg.get_replica_blocks, fake_bid)
コード例 #5
0
    def make_test_block_group(self, blk_idxes, config=None):
        gid = 'g000640000000123'

        base_blk = BlockDesc({
            'size': 1000,
            'range': ['0a', '0b'],
            'is_del': 0
        })

        if config is None:
            config = _ec_config

        num_idcs = sum(config['cross_idc'])
        idcs = ['idc' + (str(i).rjust(3, '0')) for i in range(num_idcs)]

        bg = BlockGroup(block_group_id=gid, idcs=idcs, config=config)

        for i, bi in enumerate(blk_idxes):
            bi = BlockIndex(bi)
            typ = bg.get_block_type(bi)

            drive_id = DriveID(idcs[int(bi[0])] + 'c62d8736c7280002')
            blkid = BlockID(typ, gid, bi, drive_id, i)

            blk = copy.deepcopy(base_blk)
            blk['block_id'] = blkid
            bg.add_block(blk)

        return bg
コード例 #6
0
ファイル: test_block_group.py プロジェクト: drmingdrmer/pykit
    def test_mark_delete_block_byid(self):
        g = BlockGroup(block_group_id='g000640000000123',
                       idcs=['a', 'b', 'c'],
                       config=_ec_config)

        g.add_block(self.foo_block)

        self.foo_block.add_ref()
        self.assertEqual(2, self.foo_block['ref_num'])
        self.assertEqual(0, self.foo_block['is_del'])

        del_blk = g.mark_delete_block_byid(self.foo_block['block_id'])
        self.assertIsNone(del_blk)
        self.assertEqual(1, self.foo_block['ref_num'])
        self.assertEqual(0, self.foo_block['is_del'])

        self.assertDictEqual(self.foo_block,
                             g.get_block_byid(self.foo_block['block_id']))

        del_blk = g.mark_delete_block_byid(self.foo_block['block_id'])
        self.assertEqual(del_blk['ref_num'], 0)
        self.assertEqual(1, del_blk['is_del'])
        self.assertDictEqual(del_blk,
                             g.get_block_byid(self.foo_block['block_id']))

        self.assertTrue(int(time.time()) - del_blk["mtime"] < 3)

        fake_bid = BlockID('d0', 'g000640000000125', '0000',
                           DriveID('idc000'
                                   'c62d8736c7280002'), 1)

        self.assertRaises(BlockNotFoundError, g.mark_delete_block_byid,
                          fake_bid)
コード例 #7
0
    def test_is_ec_block(self):
        idc_idx = 0
        ec_blk_idxes = ['0000', '0001', '0005']
        replica_blk_idxes = ['0002', '0008', '0012']

        bg = self.make_test_block_group(ec_blk_idxes + replica_blk_idxes)

        with self.assertRaises(BlockNotFoundError):
            gid = 'g000640000000123'
            bid = BlockID('dp', gid, '0001',
                          DriveID('idc000'
                                  'ab2d8736c7280002'), 0)
            bg.is_ec_block(bid)

        act_ec_blk_idxes = []

        nr_data, nr_parity = bg['config']['in_idc']
        for i in range(0, nr_data + nr_parity):
            bi = BlockIndex(idc_idx, i)
            blk = bg.get_block(bi)
            if blk is None:
                continue

            if bg.is_ec_block(blk['block_id']):
                act_ec_blk_idxes.append(bi)

        self.assertListEqual(ec_blk_idxes, act_ec_blk_idxes)
コード例 #8
0
ファイル: test_block_desc.py プロジェクト: bsc-s2/ops
    def test_json(self):
        blk = BlockDesc({
            'block_id':
            BlockID('d0', 'g000640000000123', '0000',
                    DriveID('idc000'
                            'c62d8736c7280002'), 1),
            'size':
            1000,
            'range': ['0a', '0b'],
            'ts_range': ["1235", "456"],
            'ref_num':
            1,
            'is_del':
            0,
            'mtime':
            1,
        })

        rst = utfjson.dump(blk)

        expected = (
            '{"block_id": "d0g0006400000001230000idc000c62d8736c72800020000000001", "is_del": 0, "ref_num": 1, "range": ["0a", "0b"], "mtime": 1, "ts_range": ["1235", "456"], "size": 1000}'
        )

        self.assertEqual(expected, rst)
        loaded = BlockDesc(utfjson.load(rst))
        self.assertEqual(blk, loaded)
コード例 #9
0
ファイル: test_idbase.py プロジェクト: bsc-s2/ops
    def setUp(self):

        self.block_group_id = BlockGroupID('g000640000000123')
        self.block_id = BlockID(
            'd1g0006300000001230101idc000c62d8736c72800020000000001')
        self.block_index = BlockIndex('1234')
        self.drive_id = DriveID('idc000' '1122334455660001')
コード例 #10
0
ファイル: test_block_id.py プロジェクト: wenbobuaa/pykit
    def test_tostr(self):

        block_id = 'd1g0006300000001230101c62d8736c72800020000000001'

        bid = BlockID(block_id)

        self.assertEqual(block_id, str(bid))
        self.assertEqual(block_id, '{0}'.format(bid))
        self.assertEqual("'d1g0006300000001230101c62d8736c72800020000000001'", repr(bid))
コード例 #11
0
ファイル: test_block_id.py プロジェクト: wenbobuaa/pykit
    def test_new(self):
        block_id = 'd1g0006300000001230101c62d8736c72800020000000001'

        _bid = BlockID('d1', 'g000630000000123', '0101',
                               DriveID('c62d8736c7280002'), 1)
        self.assertEqual(block_id, str(_bid))

        self.assertEqual(_bid, BlockID(block_id))
        self.assertEqual(_bid, BlockID(_bid))

        bid = BlockID(block_id)

        self.assertEqual('d1', bid.type)
        self.assertEqual('g000630000000123', str(bid.block_group_id))
        self.assertEqual((1, 1), bid.block_index.as_tuple())
        self.assertEqual('0101', str(bid.block_index))
        self.assertEqual('c62d8736c7280002', bid.drive_id)
        self.assertEqual(1, bid.block_id_seq)
コード例 #12
0
 def setUp(self):
     self.foo_block = BlockDesc({
         'block_id':
         BlockID('d0', 'g000640000000123', '0000',
                 DriveID('c62d8736c7280002'), 1),
         'size':
         1000,
         'range': ['0a', '0b'],
         'is_del':
         0
     })
コード例 #13
0
ファイル: test_block_group.py プロジェクト: bsc-s2/ops
    def test_get_idc_block_ids(self):
        idc0 = ['0000', '0001', '0002', '0003', '0004', '0005', '0006', '0011']
        idc1 = ['0103', '0108', '0112']
        idc2 = ['0200', '0201', '0202', '0203', '0204', '0205']

        blk_idxes = idc0 + idc1 + idc2

        bg = self.make_test_block_group(blk_idxes)

        idc0_blks = bg.indexes_to_blocks(
            ['0000', '0001', '0002', '0003', '0004', '0005'])
        idc0_bids = [BlockID(b['block_id']) for b in idc0_blks]
        act_idc0_bids = bg.get_idc_block_ids_no_replica(0)
        self.assertListEqual(idc0_bids, act_idc0_bids)

        idc2_blks = bg.indexes_to_blocks(
            ['0200', '0201', '0202', '0203', '0204', '0205'])
        idc2_bids = [BlockID(b['block_id']) for b in idc2_blks]
        act_idc2_bids = bg.get_idc_block_ids_no_replica(2)
        self.assertListEqual(idc2_bids, act_idc2_bids)
コード例 #14
0
    def test_get_parities(self):

        gid = 'g000640000000123'

        g = BlockGroup(block_group_id=gid,
                       idcs=['a', 'b', 'c'],
                       config=_ec_config)

        parities = g.get_parities(idc_index=0)
        self.assertEqual([], parities)

        base_parity = BlockDesc({
            'size': 1000,
            'range': ['0a', '0b'],
            'is_del': 0
        })

        parity_idxes = ['0004', '0005']

        for i, idx in enumerate(parity_idxes):

            blkid = BlockID('dp', gid, idx, DriveID('idc000'
                                                    'c62d8736c7280002'), i)

            parity = copy.deepcopy(base_parity)

            parity['block_id'] = blkid

            g.add_block(parity)

        idxes = g.get_parity_indexes(idc_index=0)
        self.assertEqual(parity_idxes, idxes)

        parities = g.get_parities(idc_index=0)

        idxes = []
        for p in parities:
            idx = BlockID(p['block_id']).block_index
            idxes.append(idx)

        self.assertEqual(parity_idxes, idxes)
コード例 #15
0
ファイル: test_region.py プロジェクト: liurongLori/pykit
    def test_list_block_ids(self):

        bid1 = BlockID('d1g0006300000001230101c62d8736c72800020000000001')
        bid2 = BlockID('d1g0006300000001230101c62d8736c72800020000000002')
        bid3 = BlockID('d1g0006300000001230101c62d8736c72800020000000003')
        bid4 = BlockID('d1g0006300000001230101c62d8736c72800020000000004')
        bid5 = BlockID('d1g0006300000001230101c62d8736c72800020000000005')
        bid6 = BlockID('d1g0006300000001230101c62d8736c72800020000000006')

        region_levels = [
            [
                ['aa', 'ee', {'block_id': bid1}],
                ['hh', 'zz', {'block_id': bid2}]
            ],
            [
                ['ea', 'ff', {'block_id': bid4}],
                ['mm', 'yy', {'block_id': bid5}]
            ],
        ]

        cases = (
                (None, [bid1, bid2, bid4, bid5]),
                (bid3, [bid4, bid5]),
                (bid5, [bid5]),
                (bid6, []),
        )

        region = Region(levels=region_levels)

        for bid, excepted in cases:
            block_ids = region.list_block_ids(start_block_id=bid)
            self.assertEqual(excepted, block_ids)
コード例 #16
0
ファイル: test_region.py プロジェクト: liurongLori/pykit
    def test_replace_block_id(self):

        bid1 = BlockID('d1g0006300000001230101c62d8736c72800020000000001')
        bid2 = BlockID('d1g0006300000001230101c62d8736c72800020000000002')
        bid3 = BlockID('d1g0006300000001230101c62d8736c72800020000000003')
        bid4 = BlockID('d1g0006300000001230101c62d8736c72800020000000004')
        bid5 = BlockID('d1g0006300000001230101c62d8736c72800020000000005')
        bid6 = BlockID('d1g0006300000001230101c62d8736c72800020000000006')

        region_levels = [
            [['aa', 'ee', {'block_id': bid1}], ['hh', 'zz', {'block_id': bid2}]],
            [['ea', 'ff', {'block_id': bid4}], ['mm', 'yy', {'block_id': bid5}]],
        ]

        excepted_region_levels = [
            [['aa', 'ee', BlockDesc({'block_id': bid1})], ['hh', 'zz', BlockDesc({'block_id': bid2})]],
            [['ea', 'ff', BlockDesc({'block_id': bid3})], ['mm', 'yy', BlockDesc({'block_id': bid5})]],
        ]

        region = Region(levels=region_levels)

        region.replace_block_id(bid4, bid3)
        self.assertEqual(excepted_region_levels, region['levels'])

        self.assertRaises(BlockNotInRegion, region.replace_block_id, bid6, bid1)
コード例 #17
0
ファイル: test_block_id.py プロジェクト: bsc-s2/ops
    def test_block_id_block_id(self):

        block_id = 'd1g0006300000001230101idc000c62d8736c72800020000000001'
        bid = BlockID('d1', 'g000630000000123', '0101',
                      DriveID('idc000'
                              'c62d8736c728'
                              '0002'), 1)

        self.assertEqual(
            'd1g0006300000001230101idc000c62d8736c72800020000000001',
            bid.block_id)
        self.assertEqual(block_id, bid.block_id)
        self.assertIs(bid, bid.block_id)
コード例 #18
0
    def test_blockdesc(self):

        block_id = 'd1g0006300000001230101c62d8736c72800020000000001'
        cases = ((None,
                  {'block_id': None,
                   'size': 0,
                   'range': None,
                   'is_del': 0}),

                 ({'block_id': block_id,
                   'range': ['a', 'b'],
                   'size': 34,
                   'is_del': 0},
                  {'block_id': BlockID(block_id),
                   'range': rangeset.Range('a', 'b'),
                   'size': 34,
                   'is_del': 0}),

                 ({'block_id': BlockID(block_id),
                   'range': rangeset.Range('b', 'bb')},
                  {'block_id': BlockID(block_id),
                   'range': rangeset.Range('b', 'bb'),
                   'size': 0,
                   'is_del': 0, })
                 )

        for b, expected in cases:
            if b is None:
                blk = BlockDesc()
            else:
                blk = BlockDesc(b)

            self.assertEqual(expected, blk)

        self.assertRaises(ValueError, BlockDesc, is_del='a')
        self.assertRaises(ValueError, BlockDesc, size='a')
        self.assertRaises(KeyError, BlockDesc, a=3)
コード例 #19
0
    def test_json(self):
        blk = BlockDesc({
            'block_id': BlockID('d0', 'g000640000000123', '0000',
                                    DriveID('c62d8736c7280002'), 1),
            'size': 1000,
            'range': ['0a', '0b'],
            'is_del': 0
        })

        rst = utfjson.dump(blk)
        expected = ('{"is_del": 0, "range": ["0a", "0b"], "block_id": '
                    '"d0g0006400000001230000c62d8736c72800020000000001", "size": 1000}')

        self.assertEqual(expected, rst)
        loaded = BlockDesc(utfjson.load(rst))
        self.assertEqual(blk, loaded)
コード例 #20
0
ファイル: test_block_id.py プロジェクト: bsc-s2/ops
    def test_block_id_embed(self):

        block_id = 'd1g0006300000001230101idc000c62d8736c72800020000000001'
        bid = BlockID('d1', 'g000630000000123', '0101',
                      DriveID('idc000'
                              'c62d8736c728'
                              '0002'), 1)

        # embedded drive_id attrs
        self.assertEqual('idc000' 'c62d8736c728', bid.server_id)
        self.assertEqual('002', bid.mountpoint_index)
        self.assertEqual(6002, bid.port)

        # embedded server_id attrs
        self.assertEqual('idc000', bid.idc_id)
        self.assertEqual('c62d8736c728', bid.mac_addr)
コード例 #21
0
    def test_get_block_idc(self):
        g = BlockGroup(block_group_id='g000640000000123',
                       idcs=['a', 'b', 'c'],
                       config=_ec_config)

        self.assertEqual('a', g.get_block_idc('0000'))
        self.assertEqual('b', g.get_block_idc('0100'))
        self.assertEqual('c', g.get_block_idc('0200'))

        d0 = BlockDesc({
            'block_id':
            BlockID('d0', 'g000640000000123', '0000',
                    DriveID('c62d8736c7280002'), 1),
            'size':
            1000,
            'range': ['0a', '0b'],
            'is_del':
            0
        })
        g.add_block(d0)
        self.assertEqual('a', g.get_block_idc('0000'))
コード例 #22
0
ファイル: test_block_group.py プロジェクト: drmingdrmer/pykit
    def test_get_block_byid(self):
        blk_idxes = ['0000', '0001', '0002', '0003', '0008', '0012']

        bg = self.make_test_block_group(blk_idxes)

        blks = bg.indexes_to_blocks(blk_idxes)
        bids = [blk['block_id'] for blk in blks]

        act_blks = []
        for bid in bids:
            act_blks.append(bg.get_block_byid(bid))

        self.assertListEqual(blks, act_blks)

        fake_bid = BlockID('d0', 'g000640000000125', '0000',
                           DriveID('idc000'
                                   'c62d8736c7280002'), 1)

        self.assertIsNone(bg.get_block_byid(fake_bid, raise_error=False))

        self.assertRaises(BlockNotFoundError, bg.get_block_byid, fake_bid,
                          True)
        self.assertRaises(BlockNotFoundError, bg.get_block_byid, fake_bid)
コード例 #23
0
ファイル: test_region.py プロジェクト: bsc-s2/ops
#!/usr/bin/env python2
# coding: utf-8

import unittest

from pykit import utfjson
from pykit import ututil
from pykit.ectypes import BlockID
from pykit.ectypes import BlockNotInRegion
from pykit.ectypes import BlockAreadyInRegion
from pykit.ectypes import LevelOutOfBound
from pykit.ectypes import Region

dd = ututil.dd

tbid0 = BlockID('d0g0006300000001230101idc000c62d8736c72800020000000000')
tbid1 = BlockID('d0g0006300000001230101idc000c62d8736c72800020000000001')
tbid2 = BlockID('d0g0006300000001230101idc000c62d8736c72800020000000002')
tbid3 = BlockID('d0g0006300000001230101idc000c62d8736c72800020000000003')
tbid4 = BlockID('d0g0006300000001230101idc000c62d8736c72800020000000004')
tbid5 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000005')
tbid6 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000006')
tbid7 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000007')
tbid8 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000008')
tbid9 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000009')
tbid10 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000010')
tbid11 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000011')
tbid12 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000012')
tbid13 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000013')
tbid14 = BlockID('d1g0006300000001230101idc000c62d8736c72800020000000014')
コード例 #24
0
    def test_get_block_ids_by_needle_id(self):

        bid1 = BlockID(
            'd1g0006300000001230101idc000c62d8736c72800020000000001')
        bid2 = BlockID(
            'd1g0006300000001230101idc000c62d8736c72800020000000002')

        # each tuple in region_cases consists of
        # region
        # needle_id
        # result

        region_cases = [
            (
                {},
                'a',
                [],
            ),
            (
                {
                    'range': ['a', 'e'],
                    'levels': [[['a', 'b', {
                        'block_id': bid1
                    }], ['c', 'z', {
                        'block_id': bid2
                    }]]]
                },
                'a',
                [bid1],
            ),
            (
                {
                    'range': ['a', 'e'],
                    'levels': [[['a', 'b', {
                        'block_id': bid1
                    }], ['c', 'z', {
                        'block_id': bid2
                    }]]]
                },
                'b',
                [],
            ),
            (
                {
                    'range': ['a', None],
                    'levels': [[['a', 'b', {
                        'block_id': bid1
                    }], ['c', 'z', {
                        'block_id': bid2
                    }]]]
                },
                'c',
                [bid2],
            ),
            (
                {
                    'range': [None, 'e'],
                    'levels': [[['a', 'b', {
                        'block_id': bid1
                    }], ['c', 'z', {
                        'block_id': bid2
                    }]]]
                },
                'c',
                [bid2],
            ),
            (
                {
                    'range': [None, None],
                    'levels': [[['a', 'b', {
                        'block_id': bid1
                    }], ['c', 'z', {
                        'block_id': bid2
                    }]]]
                },
                'a',
                [bid1],
            ),
            (
                {
                    'range': ['a', 'e'],
                    'levels': [[['a', 'b', {
                        'block_id': bid1
                    }], ['b', 'e', {
                        'block_id': bid2
                    }]]]
                },
                'x',
                [],
            ),
            (
                {
                    'range': ['a', 'e'],
                    'levels': [[['a', 'b', {
                        'block_id': bid1
                    }], ['c', 'z', {
                        'block_id': bid2
                    }]]]
                },
                'x',
                [],
            ),
            ({
                'range': ['a', 'z'],
                'levels': [[['a', 'b', {
                    'block_id': bid1
                }]], [['a', 'z', {
                    'block_id': bid2
                }]]]
            }, 'a', [bid2, bid1]),
        ]

        for region_meta, needle_id, block_ids in region_cases:

            region = Region(region_meta)
            result = region.get_block_ids_by_needle_id(needle_id)
            self.assertEqual(block_ids, result)