/* * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "util/keyed_circular_cache.h" #include "util/size.h" #include "clar.h" #include #define TEST_BUFFER_SIZE (3) typedef struct { uint32_t data[4]; } TestCacheItem; typedef struct { uint32_t key; TestCacheItem item; } TestCacheDefinition; static KeyedCircularCache s_test_cache; static KeyedCircularCacheKey s_cache_keys[TEST_BUFFER_SIZE]; static TestCacheItem s_cache_buffer[TEST_BUFFER_SIZE]; static TestCacheItem ZERO_ITEM = {}; static const TestCacheDefinition s_test_data[] = { { .key = 0x12345678, .item = { .data = { 0xDEADCAFE, 0xBEEFBABE, 0xF00DD00D, 0xDEFACED1, }, }, }, { .key = 0x9ABCDEF0, .item = { .data = { 0x13579BDF, 0x02468ACE, 0xFEDCBA98, 0x76543210, }, }, }, { .key = 0x01238ACE, .item = { .data = { 0x012389AB, 0x4567CDEF, 0x014589CD, 0x2367ABEF, }, }, }, { .key = 0x45679BDF, .item = { .data = { 0xFEDC7654, 0xBA983210, 0xFEBA7632, 0xDC985410, }, }, }, }; // setup and teardown void test_keyed_circular_cache__initialize(void) { memset(s_cache_buffer, 0, sizeof(s_cache_buffer)); memset(s_cache_keys, 0, sizeof(s_cache_keys)); keyed_circular_cache_init(&s_test_cache, s_cache_keys, s_cache_buffer, sizeof(TestCacheItem), TEST_BUFFER_SIZE); } void test_keyed_circular_cache__cleanup(void) { } // tests static void prv_push(int index) { keyed_circular_cache_push(&s_test_cache, s_test_data[index].key, &s_test_data[index].item); } static TestCacheItem *prv_get(KeyedCircularCacheKey key) { return keyed_circular_cache_get(&s_test_cache, key); } static void prv_test_backing_data(int cache_idx, int data_idx) { cl_assert_equal_i(s_cache_keys[cache_idx], s_test_data[data_idx].key); cl_assert_equal_m(&s_cache_buffer[cache_idx], &s_test_data[data_idx].item, sizeof(TestCacheItem)); } static void prv_test_backing_data_empty(int cache_idx) { cl_assert_equal_i(s_cache_keys[cache_idx], 0); cl_assert_equal_m(&s_cache_buffer[cache_idx], &ZERO_ITEM, sizeof(TestCacheItem)); } static void prv_test_get_miss(int data_idx) { cl_assert(!prv_get(s_test_data[data_idx].key)); } static void prv_test_get_hit(int data_idx, int cache_idx) { TestCacheItem *data = prv_get(s_test_data[data_idx].key); cl_assert(data); cl_assert_equal_m(data, &s_test_data[data_idx].item, sizeof(TestCacheItem)); cl_assert(data == &s_cache_buffer[cache_idx]); } void test_keyed_circular_cache__push(void) { prv_push(0); prv_test_backing_data(0, 0); prv_test_backing_data_empty(1); prv_test_backing_data_empty(2); prv_push(1); prv_test_backing_data(0, 0); prv_test_backing_data(1, 1); prv_test_backing_data_empty(2); prv_push(2); prv_test_backing_data(0, 0); prv_test_backing_data(1, 1); prv_test_backing_data(2, 2); prv_push(3); prv_test_backing_data(0, 3); prv_test_backing_data(1, 1); prv_test_backing_data(2, 2); prv_push(0); prv_test_backing_data(0, 3); prv_test_backing_data(1, 0); prv_test_backing_data(2, 2); prv_push(1); prv_test_backing_data(0, 3); prv_test_backing_data(1, 0); prv_test_backing_data(2, 1); } void test_circular_cache__get(void) { prv_test_get_miss(0); prv_test_get_miss(1); prv_test_get_miss(2); prv_test_get_miss(3); prv_push(0); prv_test_get_hit(0, 0); prv_test_get_miss(1); prv_test_get_miss(2); prv_test_get_miss(3); prv_push(1); prv_test_get_hit(0, 0); prv_test_get_hit(1, 1); prv_test_get_miss(2); prv_test_get_miss(3); prv_push(2); prv_test_get_hit(0, 0); prv_test_get_hit(1, 1); prv_test_get_hit(2, 2); prv_test_get_miss(3); prv_push(3); prv_test_get_miss(0); prv_test_get_hit(1, 1); prv_test_get_hit(2, 2); prv_test_get_hit(3, 0); prv_push(2); prv_test_get_miss(0); prv_test_get_miss(1); prv_test_get_hit(2, 1); prv_test_get_hit(3, 0); prv_push(0); prv_test_get_hit(0, 2); prv_test_get_miss(1); prv_test_get_hit(2, 1); prv_test_get_hit(3, 0); prv_push(1); prv_test_get_hit(0, 2); prv_test_get_hit(1, 0); prv_test_get_hit(2, 1); prv_test_get_miss(3); prv_push(3); prv_test_get_hit(0, 2); prv_test_get_hit(1, 0); prv_test_get_miss(2); prv_test_get_hit(3, 1); }