From e19f638172112579c1aa29835ca539bdbd4ac8b1 Mon Sep 17 00:00:00 2001 From: xcnick Date: Thu, 26 Dec 2024 10:15:42 +0000 Subject: [PATCH] [V1] Add kv cache utils tests. --- tests/v1/core/test_kv_cache_utils.py | 88 ++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tests/v1/core/test_kv_cache_utils.py diff --git a/tests/v1/core/test_kv_cache_utils.py b/tests/v1/core/test_kv_cache_utils.py new file mode 100644 index 0000000000000..4cc4c8fde20fc --- /dev/null +++ b/tests/v1/core/test_kv_cache_utils.py @@ -0,0 +1,88 @@ +import pytest + +from vllm.v1.core.kv_cache_utils import FreeKVCacheBlockQueue, KVCacheBlock + + +def test_free_kv_cache_block_queue_initialization(): + # Test with a single block + block = KVCacheBlock(block_id=0) + queue = FreeKVCacheBlockQueue([block]) + assert queue.num_free_blocks == 1 + assert queue.free_list_head == block + assert queue.free_list_tail == block + + # Test with an empty list + with pytest.raises(IndexError): + queue = FreeKVCacheBlockQueue([]) + + +def test_free_kv_cache_block_queue_operations(): + # Create a list of KVCacheBlock objects + blocks = [KVCacheBlock(block_id=i) for i in range(5)] + + # Create a FreeKVCacheBlockQueue with these blocks + queue = FreeKVCacheBlockQueue(blocks) + + # Check initial state + assert queue.num_free_blocks == 5 + assert queue.free_list_head == blocks[0] + assert queue.free_list_tail == blocks[4] + + # Pop the first block + block1 = queue.popleft() + assert block1 == blocks[0] + assert queue.num_free_blocks == 4 + assert queue.free_list_head == blocks[1] + assert queue.free_list_tail == blocks[4] + + # Remove a block from the middle + block_to_remove = blocks[2] + queue.remove(block_to_remove) + assert queue.num_free_blocks == 3 + assert blocks[1].next_free_block == blocks[3] + assert blocks[3].prev_free_block == blocks[1] + + # Append a block back + queue.append(block_to_remove) + assert queue.num_free_blocks == 4 + assert queue.free_list_tail == block_to_remove + assert block_to_remove.prev_free_block == blocks[4] + assert block_to_remove.next_free_block is None + + # Pop blocks until empty + for _ in range(4): + queue.popleft() + assert queue.num_free_blocks == 0 + assert queue.free_list_head is None + assert queue.free_list_tail is None + + # Attempt to pop from an empty queue + with pytest.raises(ValueError) as e: + queue.popleft() + assert str(e.value) == "No free blocks available" + + +def test_free_kv_cache_block_queue_get_all_free_blocks(): + # Create a list of KVCacheBlock objects + blocks = [KVCacheBlock(block_id=i) for i in range(5)] + + # Create a FreeKVCacheBlockQueue with these blocks + queue = FreeKVCacheBlockQueue(blocks) + + # Check all blocks are correctly retrieved + assert queue.get_all_free_blocks() == blocks + + # Pop a block and check again + queue.popleft() + assert queue.get_all_free_blocks() == blocks[1:] + + # Remove a block and check again + block_to_remove = blocks[2] + queue.remove(block_to_remove) + assert queue.get_all_free_blocks() == blocks[1:2] + blocks[3:] + + # Append a block back and check again + queue.append(block_to_remove) + assert queue.get_all_free_blocks() == blocks[1:2] + blocks[3:] + [ + block_to_remove + ]