コード例 #1
0
def test_start_read_first_and_check_mode(pyocf_ctx, mode: CacheMode,
                                         cls: CacheLineSize):
    """Starting cache in different modes with different cache line sizes.
    After start check proper cache mode behaviour, starting with read operation.
    """

    cache_device = RamVolume(Size.from_MiB(50))
    core_device = RamVolume(Size.from_MiB(5))
    cache = Cache.start_on_device(cache_device,
                                  cache_mode=mode,
                                  cache_line_size=cls)
    core = Core.using_device(core_device)

    cache.add_core(core)
    front_vol = CoreVolume(core, open=True)
    bottom_vol = core.get_volume()
    queue = cache.get_default_queue()

    logger.info("[STAGE] Initial write to core device")
    test_data = Data.from_string("This is test data")
    io_to_core(bottom_vol, queue, test_data, Size.from_sector(1).B)

    cache_device.reset_stats()
    core_device.reset_stats()

    logger.info("[STAGE] Initial read from exported object")
    io_from_exported_object(front_vol, queue, test_data.size,
                            Size.from_sector(1).B)
    check_stats_read_empty(core, mode, cls)

    logger.info("[STAGE] Write to exported object after initial read")
    cache_device.reset_stats()
    core_device.reset_stats()

    test_data = Data.from_string("Changed test data")

    io_to_core(front_vol, queue, test_data, Size.from_sector(1).B)

    check_stats_write_after_read(core, mode, cls, True)

    logger.info("[STAGE] Read from exported object after write")
    io_from_exported_object(front_vol, queue, test_data.size,
                            Size.from_sector(1).B)
    check_stats_read_after_write(core, mode, cls)

    check_md5_sums(core, mode)
コード例 #2
0
ファイル: test_pyocf.py プロジェクト: Open-CAS/ocf
def test_simple_wt_write(pyocf_ctx):
    cache_device = RamVolume(S.from_MiB(50))
    core_device = RamVolume(S.from_MiB(50))

    cache = Cache.start_on_device(cache_device)
    core = Core.using_device(core_device)
    queue = cache.get_default_queue()

    cache.add_core(core)
    vol = CoreVolume(core, open=True)

    cache_device.reset_stats()
    core_device.reset_stats()

    r = Rio().target(vol).readwrite(ReadWrite.WRITE).size(
        S.from_sector(1)).run([queue])
    assert cache_device.get_stats()[IoDir.WRITE] == 1
    cache.settle()
    stats = cache.get_stats()
    assert stats["req"]["wr_full_misses"]["value"] == 1
    assert stats["usage"]["occupancy"]["value"] == 1

    assert vol.md5() == core_device.md5()
    cache.stop()
コード例 #3
0
ファイル: test_read.py プロジェクト: Open-CAS/ocf
def test_read_data_consistency(pyocf_ctx, cacheline_size, cache_mode,
                               rand_seed):
    CACHELINE_COUNT = 9
    SECTOR_SIZE = Size.from_sector(1).B
    CLS = cacheline_size // SECTOR_SIZE
    WORKSET_SIZE = CACHELINE_COUNT * cacheline_size
    WORKSET_OFFSET = 128 * cacheline_size
    SECTOR_COUNT = int(WORKSET_SIZE / SECTOR_SIZE)
    ITRATION_COUNT = 50

    random.seed(rand_seed)

    # start sector for each region (positions of '*' on the above diagram)
    region_start = ([0, 3 * CLS, 4 * CLS - 1] +
                    [4 * CLS + i
                     for i in range(CLS)] + [5 * CLS, 5 * CLS + 1, 6 * CLS])
    num_regions = len(region_start)
    # possible IO start sectors for test iteration  (positions of '>' on the above diagram)
    start_sec = [0, CLS, 2 * CLS, 3 * CLS, 4 * CLS - 2, 4 * CLS - 1
                 ] + [4 * CLS + i for i in range(CLS)]
    # possible IO end sectors for test iteration (positions o '<' on the above diagram)
    end_sec = ([3 * CLS - 1] + [4 * CLS + i for i in range(CLS)] + [
        5 * CLS, 5 * CLS + 1, 6 * CLS - 1, 7 * CLS - 1, 8 * CLS - 1,
        9 * CLS - 1
    ])

    data = {}
    # memset n-th sector of core data with n << 2
    data[SectorStatus.INVALID] = bytes([
        get_byte(((x // SECTOR_SIZE) << 2) + 0, x % 4)
        for x in range(WORKSET_SIZE)
    ])
    # memset n-th sector of clean data with n << 2 + 1
    data[SectorStatus.CLEAN] = bytes([
        get_byte(((x // SECTOR_SIZE) << 2) + 1, x % 4)
        for x in range(WORKSET_SIZE)
    ])
    # memset n-th sector of dirty data with n << 2 + 2
    data[SectorStatus.DIRTY] = bytes([
        get_byte(((x // SECTOR_SIZE) << 2) + 2, x % 4)
        for x in range(WORKSET_SIZE)
    ])

    result_b = bytes(WORKSET_SIZE)

    cache_device = RamVolume(Size.from_MiB(50))
    core_device = RamVolume(Size.from_MiB(50))

    cache = Cache.start_on_device(cache_device,
                                  cache_mode=CacheMode.WO,
                                  cache_line_size=cacheline_size)

    core = Core.using_device(core_device)
    cache.add_core(core)
    queue = cache.get_default_queue()
    vol = CoreVolume(core, open=True)

    insert_order = list(range(CACHELINE_COUNT))

    # set fixed generated sector statuses
    region_statuses = [
        [I, I, I] + [I for i in range(CLS)] + [I, I, I],
        [I, I, I] + [D for i in range(CLS)] + [I, I, I],
        [I, I, I] + [C for i in range(CLS)] + [I, I, I],
        [I, I, I] + [D for i in range(CLS // 2 - 1)] + [I] +
        [D for i in range(CLS // 2)] + [I, I, I],
        [I, I, I] + [D for i in range(CLS // 2 - 1)] + [I, I] +
        [D for i in range(CLS // 2 - 1)] + [I, I, I],
        [I, I, I] + [D for i in range(CLS // 2 - 2)] + [I, I, D, C] +
        [D for i in range(CLS // 2 - 2)] + [I, I, I],
        [I, I, D] + [D for i in range(CLS)] + [D, I, I],
        [I, I, D] + [D for i in range(CLS // 2 - 1)] + [I] +
        [D for i in range(CLS // 2)] + [D, I, I],
    ]

    # add randomly generated sector statuses
    for _ in range(ITRATION_COUNT - len(region_statuses)):
        region_statuses.append(
            [random.choice(list(SectorStatus)) for _ in range(num_regions)])

    # iterate over generated status combinations and perform the test
    for region_state in region_statuses:
        # write data to core and invalidate all CL and write data pattern to core
        cache.change_cache_mode(cache_mode=CacheMode.PT)
        io_to_exp_obj(
            vol,
            queue,
            WORKSET_OFFSET,
            len(data[SectorStatus.INVALID]),
            data[SectorStatus.INVALID],
            0,
            IoDir.WRITE,
        )

        # randomize cacheline insertion order to exercise different
        # paths with regard to cache I/O physical addresses continuousness
        random.shuffle(insert_order)
        sectors = [
            insert_order[i // CLS] * CLS + (i % CLS)
            for i in range(SECTOR_COUNT)
        ]

        # insert clean sectors - iterate over cachelines in @insert_order order
        cache.change_cache_mode(cache_mode=CacheMode.WT)
        for sec in sectors:
            region = sector_to_region(sec, region_start)
            if region_state[region] != SectorStatus.INVALID:
                io_to_exp_obj(
                    vol,
                    queue,
                    WORKSET_OFFSET + SECTOR_SIZE * sec,
                    SECTOR_SIZE,
                    data[SectorStatus.CLEAN],
                    sec * SECTOR_SIZE,
                    IoDir.WRITE,
                )

        # write dirty sectors
        cache.change_cache_mode(cache_mode=CacheMode.WB)
        for sec in sectors:
            region = sector_to_region(sec, region_start)
            if region_state[region] == SectorStatus.DIRTY:
                io_to_exp_obj(
                    vol,
                    queue,
                    WORKSET_OFFSET + SECTOR_SIZE * sec,
                    SECTOR_SIZE,
                    data[SectorStatus.DIRTY],
                    sec * SECTOR_SIZE,
                    IoDir.WRITE,
                )

        cache.change_cache_mode(cache_mode=cache_mode)

        core_device.reset_stats()

        # get up to 32 randomly selected pairs of (start,end) sectors
        # 32 is enough to cover all combinations for 4K and 8K cacheline size
        io_ranges = [(s, e) for s, e in product(start_sec, end_sec) if s < e]
        random.shuffle(io_ranges)
        io_ranges = io_ranges[:32]

        # run the test for each selected IO range for currently set up region status
        for start, end in io_ranges:
            print_test_case(region_start, region_state, start, end,
                            SECTOR_COUNT, CLS)

            # issue read
            START = start * SECTOR_SIZE
            END = end * SECTOR_SIZE
            size = (end - start + 1) * SECTOR_SIZE
            assert 0 == io_to_exp_obj(
                vol, queue, WORKSET_OFFSET + START, size, result_b, START,
                IoDir.READ
            ), "error reading in {}: region_state={}, start={}, end={}, insert_order={}".format(
                cache_mode, region_state, start, end, insert_order)

            # verify read data
            for sec in range(start, end + 1):
                # just check the first 32bits of sector (this is the size of fill pattern)
                region = sector_to_region(sec, region_start)
                start_byte = sec * SECTOR_SIZE
                expected_data = bytes_to_uint32(
                    data[region_state[region]][start_byte + 0],
                    data[region_state[region]][start_byte + 1],
                    data[region_state[region]][start_byte + 2],
                    data[region_state[region]][start_byte + 3],
                )
                actual_data = bytes_to_uint32(
                    result_b[start_byte + 0],
                    result_b[start_byte + 1],
                    result_b[start_byte + 2],
                    result_b[start_byte + 3],
                )

                assert (
                    actual_data == expected_data
                ), "unexpected data in sector {}, region_state={}, start={}, end={}, insert_order={}\n".format(
                    sec, region_state, start, end, insert_order)

            if cache_mode == CacheMode.WO:
                # WO is not supposed to clean dirty data
                assert (
                    core_device.get_stats()[IoDir.WRITE] == 0
                ), "unexpected write to core device, region_state={}, start={}, end={}, insert_order = {}\n".format(
                    region_state, start, end, insert_order)