Update management tests for WO (Write-only) cache mode
Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
		@@ -74,8 +74,17 @@ class CacheMode(IntEnum):
 | 
				
			|||||||
    WA = 2
 | 
					    WA = 2
 | 
				
			||||||
    PT = 3
 | 
					    PT = 3
 | 
				
			||||||
    WI = 4
 | 
					    WI = 4
 | 
				
			||||||
 | 
					    WO = 5
 | 
				
			||||||
    DEFAULT = WT
 | 
					    DEFAULT = WT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def lazy_write(self):
 | 
				
			||||||
 | 
					        return self.value in [CacheMode.WB, CacheMode.WO]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def write_insert(self):
 | 
				
			||||||
 | 
					        return self.value not in [CacheMode.PT, CacheMode.WA, CacheMode.WI]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def read_insert(self):
 | 
				
			||||||
 | 
					        return self.value not in [CacheMode.PT, CacheMode.WO]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EvictionPolicy(IntEnum):
 | 
					class EvictionPolicy(IntEnum):
 | 
				
			||||||
    LRU = 0
 | 
					    LRU = 0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -180,7 +180,7 @@ def test_stop(pyocf_ctx, mode: CacheMode, cls: CacheLineSize, with_flush: bool):
 | 
				
			|||||||
    run_io_and_cache_data_if_possible(core_exported, mode, cls)
 | 
					    run_io_and_cache_data_if_possible(core_exported, mode, cls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stats = cache.get_stats()
 | 
					    stats = cache.get_stats()
 | 
				
			||||||
    assert int(stats["conf"]["dirty"]) == (1 if mode == CacheMode.WB else 0), "Dirty data before MD5"
 | 
					    assert int(stats["conf"]["dirty"]) == (1 if mode.lazy_write() else 0), "Dirty data before MD5"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    md5_exported_core = core_exported.exp_obj_md5()
 | 
					    md5_exported_core = core_exported.exp_obj_md5()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -188,7 +188,7 @@ def test_stop(pyocf_ctx, mode: CacheMode, cls: CacheLineSize, with_flush: bool):
 | 
				
			|||||||
        cache.flush()
 | 
					        cache.flush()
 | 
				
			||||||
    cache.stop()
 | 
					    cache.stop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if mode == CacheMode.WB and not with_flush:
 | 
					    if mode.lazy_write() and not with_flush:
 | 
				
			||||||
        pytest.xfail("MD5 sums equal without flush with dirty data")  # TODO: remove after WB fixed
 | 
					        pytest.xfail("MD5 sums equal without flush with dirty data")  # TODO: remove after WB fixed
 | 
				
			||||||
        assert core_device.md5() != md5_exported_core, \
 | 
					        assert core_device.md5() != md5_exported_core, \
 | 
				
			||||||
            "MD5 check: core device vs exported object with dirty data"
 | 
					            "MD5 check: core device vs exported object with dirty data"
 | 
				
			||||||
@@ -393,38 +393,39 @@ def io_from_exported_object(exported_obj: Core, buffer_size: int, offset: int):
 | 
				
			|||||||
def check_stats_read_empty(exported_obj: Core, mode: CacheMode, cls: CacheLineSize):
 | 
					def check_stats_read_empty(exported_obj: Core, mode: CacheMode, cls: CacheLineSize):
 | 
				
			||||||
    stats = exported_obj.cache.get_stats()
 | 
					    stats = exported_obj.cache.get_stats()
 | 
				
			||||||
    assert stats["conf"]["cache_mode"] == mode, "Cache mode"
 | 
					    assert stats["conf"]["cache_mode"] == mode, "Cache mode"
 | 
				
			||||||
    assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == (0 if mode == CacheMode.PT else 1), \
 | 
					    assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == (1 if mode.read_insert() else 0), \
 | 
				
			||||||
        "Writes to cache device"
 | 
					        "Writes to cache device"
 | 
				
			||||||
    assert exported_obj.device.get_stats()[IoDir.READ] == 1, "Reads from core device"
 | 
					    assert exported_obj.device.get_stats()[IoDir.READ] == 1, "Reads from core device"
 | 
				
			||||||
    assert stats["req"]["rd_full_misses"]["value"] == (0 if mode == CacheMode.PT else 1), \
 | 
					    assert stats["req"]["rd_full_misses"]["value"] == (0 if mode == CacheMode.PT else 1), \
 | 
				
			||||||
        "Read full misses"
 | 
					        "Read full misses"
 | 
				
			||||||
    assert stats["usage"]["occupancy"]["value"] == \
 | 
					    assert stats["usage"]["occupancy"]["value"] == \
 | 
				
			||||||
        (0 if mode == CacheMode.PT else (cls / CacheLineSize.LINE_4KiB)), "Occupancy"
 | 
					        ((cls / CacheLineSize.LINE_4KiB) if mode.read_insert() else 0), "Occupancy"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_stats_write_empty(exported_obj: Core, mode: CacheMode, cls: CacheLineSize):
 | 
					def check_stats_write_empty(exported_obj: Core, mode: CacheMode, cls: CacheLineSize):
 | 
				
			||||||
    stats = exported_obj.cache.get_stats()
 | 
					    stats = exported_obj.cache.get_stats()
 | 
				
			||||||
    assert stats["conf"]["cache_mode"] == mode, "Cache mode"
 | 
					    assert stats["conf"]["cache_mode"] == mode, "Cache mode"
 | 
				
			||||||
 | 
					    # TODO(ajrutkow): why 1 for WT ??
 | 
				
			||||||
    assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
 | 
					    assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
 | 
				
			||||||
        (2 if mode == CacheMode.WB else (1 if mode == CacheMode.WT else 0)), \
 | 
					        (2 if mode.lazy_write() else (1 if mode == CacheMode.WT else 0)), \
 | 
				
			||||||
        "Writes to cache device"
 | 
					        "Writes to cache device"
 | 
				
			||||||
    assert exported_obj.device.get_stats()[IoDir.WRITE] == (0 if mode == CacheMode.WB else 1), \
 | 
					    assert exported_obj.device.get_stats()[IoDir.WRITE] == (0 if mode.lazy_write() else 1), \
 | 
				
			||||||
        "Writes to core device"
 | 
					        "Writes to core device"
 | 
				
			||||||
    assert stats["req"]["wr_full_misses"]["value"] == (1 if mode in {CacheMode.WT, CacheMode.WB} else 0), \
 | 
					    assert stats["req"]["wr_full_misses"]["value"] == (1 if mode.write_insert() else 0), \
 | 
				
			||||||
        "Write full misses"
 | 
					        "Write full misses"
 | 
				
			||||||
    assert stats["usage"]["occupancy"]["value"] == \
 | 
					    assert stats["usage"]["occupancy"]["value"] == \
 | 
				
			||||||
        ((cls / CacheLineSize.LINE_4KiB) if mode in {CacheMode.WB, CacheMode.WT} else 0), \
 | 
					        ((cls / CacheLineSize.LINE_4KiB) if mode.write_insert() else 0), \
 | 
				
			||||||
        "Occupancy"
 | 
					        "Occupancy"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_stats_write_after_read(exported_obj: Core, mode: CacheMode, cls: CacheLineSize, read_from_empty=False):
 | 
					def check_stats_write_after_read(exported_obj: Core, mode: CacheMode, cls: CacheLineSize, read_from_empty=False):
 | 
				
			||||||
    stats = exported_obj.cache.get_stats()
 | 
					    stats = exported_obj.cache.get_stats()
 | 
				
			||||||
    assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
 | 
					    assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
 | 
				
			||||||
        (0 if mode in {CacheMode.WI, CacheMode.PT} else (2 if read_from_empty and mode == CacheMode.WB else 1)), \
 | 
					        (0 if mode in {CacheMode.WI, CacheMode.PT} else (2 if read_from_empty and mode.lazy_write() else 1)), \
 | 
				
			||||||
        "Writes to cache device"
 | 
					        "Writes to cache device"
 | 
				
			||||||
    assert exported_obj.device.get_stats()[IoDir.WRITE] == (0 if mode == CacheMode.WB else 1), \
 | 
					    assert exported_obj.device.get_stats()[IoDir.WRITE] == (0 if mode.lazy_write() else 1), \
 | 
				
			||||||
        "Writes to core device"
 | 
					        "Writes to core device"
 | 
				
			||||||
    assert stats["req"]["wr_hits"]["value"] == (0 if mode in {CacheMode.WI, CacheMode.PT} else 1), \
 | 
					    assert stats["req"]["wr_hits"]["value"] == (1 if (mode.read_insert() and mode != CacheMode.WI) or (mode.write_insert() and not read_from_empty) else 0), \
 | 
				
			||||||
        "Write hits"
 | 
					        "Write hits"
 | 
				
			||||||
    assert stats["usage"]["occupancy"]["value"] == \
 | 
					    assert stats["usage"]["occupancy"]["value"] == \
 | 
				
			||||||
        (0 if mode in {CacheMode.WI, CacheMode.PT} else (cls / CacheLineSize.LINE_4KiB)), \
 | 
					        (0 if mode in {CacheMode.WI, CacheMode.PT} else (cls / CacheLineSize.LINE_4KiB)), \
 | 
				
			||||||
@@ -434,26 +435,26 @@ def check_stats_write_after_read(exported_obj: Core, mode: CacheMode, cls: Cache
 | 
				
			|||||||
def check_stats_read_after_write(exported_obj, mode, cls, write_to_empty=False):
 | 
					def check_stats_read_after_write(exported_obj, mode, cls, write_to_empty=False):
 | 
				
			||||||
    stats = exported_obj.cache.get_stats()
 | 
					    stats = exported_obj.cache.get_stats()
 | 
				
			||||||
    assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
 | 
					    assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
 | 
				
			||||||
        (2 if mode == CacheMode.WB else (0 if mode == CacheMode.PT else 1)), \
 | 
					        (2 if mode.lazy_write() else (0 if mode == CacheMode.PT else 1)), \
 | 
				
			||||||
        "Writes to cache device"
 | 
					        "Writes to cache device"
 | 
				
			||||||
    assert exported_obj.cache.device.get_stats()[IoDir.READ] == \
 | 
					    assert exported_obj.cache.device.get_stats()[IoDir.READ] == \
 | 
				
			||||||
        (1 if mode in {CacheMode.WT, CacheMode.WB} or (mode == CacheMode.WA and not write_to_empty) else 0), \
 | 
					        (1 if mode in {CacheMode.WT, CacheMode.WB, CacheMode.WO} or (mode == CacheMode.WA and not write_to_empty) else 0), \
 | 
				
			||||||
        "Reads from cache device"
 | 
					        "Reads from cache device"
 | 
				
			||||||
    assert exported_obj.device.get_stats()[IoDir.READ] == \
 | 
					    assert exported_obj.device.get_stats()[IoDir.READ] == \
 | 
				
			||||||
        (0 if mode in {CacheMode.WB, CacheMode.WT} or (mode == CacheMode.WA and not write_to_empty) else 1), \
 | 
					        (0 if mode in {CacheMode.WB, CacheMode.WO, CacheMode.WT} or (mode == CacheMode.WA and not write_to_empty) else 1), \
 | 
				
			||||||
        "Reads from core device"
 | 
					        "Reads from core device"
 | 
				
			||||||
    assert stats["req"]["rd_full_misses"]["value"] == (1 if mode in {CacheMode.WA, CacheMode.WI} else 0) \
 | 
					    assert stats["req"]["rd_full_misses"]["value"] == (1 if mode in {CacheMode.WA, CacheMode.WI} else 0) \
 | 
				
			||||||
        + (0 if write_to_empty or mode in {CacheMode.PT, CacheMode.WA} else 1), \
 | 
					        + (0 if write_to_empty or mode in {CacheMode.PT, CacheMode.WA} else 1), \
 | 
				
			||||||
        "Read full misses"
 | 
					        "Read full misses"
 | 
				
			||||||
    assert stats["req"]["rd_hits"]["value"] == \
 | 
					    assert stats["req"]["rd_hits"]["value"] == \
 | 
				
			||||||
        (1 if mode in {CacheMode.WT, CacheMode.WB} or (mode == CacheMode.WA and not write_to_empty) else 0), \
 | 
					        (1 if mode in {CacheMode.WT, CacheMode.WB, CacheMode.WO} or (mode == CacheMode.WA and not write_to_empty) else 0), \
 | 
				
			||||||
        "Read hits"
 | 
					        "Read hits"
 | 
				
			||||||
    assert stats["usage"]["occupancy"]["value"] == \
 | 
					    assert stats["usage"]["occupancy"]["value"] == \
 | 
				
			||||||
        (0 if mode == CacheMode.PT else (cls / CacheLineSize.LINE_4KiB)), "Occupancy"
 | 
					        (0 if mode == CacheMode.PT else (cls / CacheLineSize.LINE_4KiB)), "Occupancy"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_md5_sums(exported_obj: Core, mode: CacheMode):
 | 
					def check_md5_sums(exported_obj: Core, mode: CacheMode):
 | 
				
			||||||
    if mode == CacheMode.WB:
 | 
					    if mode.lazy_write():
 | 
				
			||||||
        assert exported_obj.device.md5() != exported_obj.exp_obj_md5(), \
 | 
					        assert exported_obj.device.md5() != exported_obj.exp_obj_md5(), \
 | 
				
			||||||
            "MD5 check: core device vs exported object without flush"
 | 
					            "MD5 check: core device vs exported object without flush"
 | 
				
			||||||
        exported_obj.cache.flush()
 | 
					        exported_obj.cache.flush()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user