mirror of
https://github.com/emqx/neuron.git
synced 2026-10-18 13:41:22 +08:00
feat: add memory cache unit test
This commit is contained in:
+2
-1
@@ -73,7 +73,8 @@ set(NEURON_BASE_SOURCES
|
||||
src/utils/json.c
|
||||
src/utils/neu_jwt.c
|
||||
src/utils/base64.c
|
||||
src/utils/async_queue.c)
|
||||
src/utils/async_queue.c
|
||||
src/utils/mem_cache.c)
|
||||
|
||||
add_library(neuron-base SHARED)
|
||||
target_sources(neuron-base PRIVATE ${NEURON_BASE_SOURCES} ${NEURON_SRC_PARSE})
|
||||
|
||||
@@ -35,6 +35,7 @@ extern "C" {
|
||||
|
||||
#include "utils/base64.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/mem_cache.h"
|
||||
#include "utils/zlog.h"
|
||||
|
||||
#include "utils/neu_jwt.h"
|
||||
|
||||
@@ -39,12 +39,13 @@ typedef struct {
|
||||
typedef void (*cache_dump)(cache_item_t *item, void *ctx);
|
||||
|
||||
neu_mem_cache_t *neu_mem_cache_create(const size_t max_bytes,
|
||||
const size_t max_msgs);
|
||||
const size_t max_items);
|
||||
int neu_mem_cache_add(neu_mem_cache_t *cache, cache_item_t *item);
|
||||
cache_item_t neu_mem_cache_earliest(neu_mem_cache_t *cache);
|
||||
cache_item_t neu_mem_cache_latest(neu_mem_cache_t *cache);
|
||||
void neu_mem_cache_used(neu_mem_cache_t *cache, size_t *bytes, size_t *msgs);
|
||||
int neu_mem_cache_dump(neu_mem_cache_t *cache, void *callback, void *ctx);
|
||||
void neu_mem_cache_used(neu_mem_cache_t *cache, size_t *used_bytes,
|
||||
size_t *used_items);
|
||||
int neu_mem_cache_dump(neu_mem_cache_t *cache, cache_dump callback, void *ctx);
|
||||
int neu_mem_cache_clear(neu_mem_cache_t *cache);
|
||||
void neu_mem_cache_destroy(neu_mem_cache_t *cache);
|
||||
|
||||
@@ -9,7 +9,6 @@ file(COPY ${CMAKE_SOURCE_DIR}/plugins/mqtt/mqtt.json DESTINATION ${CMAKE_BINARY_
|
||||
set(src
|
||||
mqtt_plugin.c
|
||||
mqtt_util.c
|
||||
neu_mem_cache.c
|
||||
command/read_write.c
|
||||
command/heartbeat.c
|
||||
command/command.c)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <neuron.h>
|
||||
|
||||
#include "neu_mem_cache.h"
|
||||
#include "utils/mem_cache.h"
|
||||
|
||||
typedef struct element {
|
||||
cache_item_t item;
|
||||
@@ -12,14 +12,14 @@ typedef struct element {
|
||||
|
||||
struct neu_mem_cache {
|
||||
size_t max_bytes; // 0 no limit
|
||||
size_t max_msgs; // 0 no limit
|
||||
size_t max_items; // 0 no limit
|
||||
size_t used_bytes;
|
||||
size_t used_msgs;
|
||||
size_t used_items;
|
||||
element *head;
|
||||
};
|
||||
|
||||
neu_mem_cache_t *neu_mem_cache_create(const size_t max_bytes,
|
||||
const size_t max_msgs)
|
||||
const size_t max_items)
|
||||
{
|
||||
neu_mem_cache_t *cache = calloc(1, sizeof(neu_mem_cache_t));
|
||||
if (NULL == cache) {
|
||||
@@ -27,9 +27,9 @@ neu_mem_cache_t *neu_mem_cache_create(const size_t max_bytes,
|
||||
}
|
||||
|
||||
cache->max_bytes = max_bytes;
|
||||
cache->max_msgs = max_msgs;
|
||||
cache->max_items = max_items;
|
||||
cache->used_bytes = 0;
|
||||
cache->used_msgs = 0;
|
||||
cache->used_items = 0;
|
||||
cache->head = NULL;
|
||||
return cache;
|
||||
}
|
||||
@@ -43,11 +43,22 @@ int neu_mem_cache_add(neu_mem_cache_t *cache, cache_item_t *item)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((0 != cache->used_bytes) &&
|
||||
(item->size + cache->used_bytes) > cache->max_bytes) {
|
||||
free(el);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((0 != cache->used_items) && (cache->used_items >= cache->max_bytes)) {
|
||||
free(el);
|
||||
return -1;
|
||||
}
|
||||
|
||||
el->item = *item;
|
||||
DL_PREPEND(cache->head, el);
|
||||
|
||||
cache->used_bytes += item->size;
|
||||
cache->used_msgs += 1;
|
||||
cache->used_items += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -63,8 +74,10 @@ cache_item_t neu_mem_cache_earliest(neu_mem_cache_t *cache)
|
||||
|
||||
item = elm->item;
|
||||
DL_DELETE(cache->head, elm);
|
||||
free(elm);
|
||||
|
||||
cache->used_bytes -= item.size;
|
||||
cache->used_msgs -= 1;
|
||||
cache->used_items -= 1;
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -80,8 +93,10 @@ cache_item_t neu_mem_cache_latest(neu_mem_cache_t *cache)
|
||||
|
||||
item = elm->item;
|
||||
DL_DELETE(cache->head, elm);
|
||||
free(elm);
|
||||
|
||||
cache->used_bytes -= item.size;
|
||||
cache->used_msgs -= 1;
|
||||
cache->used_items -= 1;
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -90,15 +105,27 @@ void neu_mem_cache_used(neu_mem_cache_t *cache, size_t *bytes, size_t *msgs)
|
||||
assert(NULL != cache);
|
||||
|
||||
*bytes = cache->used_bytes;
|
||||
*msgs = cache->used_msgs;
|
||||
*msgs = cache->used_items;
|
||||
}
|
||||
|
||||
int neu_mem_cache_dump(neu_mem_cache_t *cache, void *callback, void *ctx)
|
||||
int neu_mem_cache_dump(neu_mem_cache_t *cache, cache_dump callback, void *ctx)
|
||||
{
|
||||
assert(NULL != cache);
|
||||
|
||||
(void) callback;
|
||||
(void) ctx;
|
||||
if (NULL != callback) {
|
||||
element *el = NULL;
|
||||
element *tmp = NULL;
|
||||
DL_FOREACH_SAFE(cache->head, el, tmp)
|
||||
{
|
||||
callback(&el->item, ctx);
|
||||
|
||||
if (NULL != el->item.release) {
|
||||
el->item.release(&el->item);
|
||||
}
|
||||
|
||||
LL_DELETE(cache->head, el);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -116,6 +143,7 @@ int neu_mem_cache_clear(neu_mem_cache_t *cache)
|
||||
}
|
||||
|
||||
LL_DELETE(cache->head, el);
|
||||
free(el);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -52,6 +52,14 @@ target_include_directories(tag_sort_test PRIVATE
|
||||
target_link_libraries(tag_sort_test neuron-base gtest_main gtest)
|
||||
#target_link_directories(modbus_point_test PRIVATE /usr/local/lib)
|
||||
|
||||
add_executable(cache_test cache_test.cc
|
||||
${CMAKE_SOURCE_DIR}/src/utils/mem_cache.c)
|
||||
target_include_directories(cache_test PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(cache_test neuron-base gtest_main gtest)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(json_test)
|
||||
gtest_discover_tests(http_test)
|
||||
@@ -59,3 +67,4 @@ gtest_discover_tests(mqtt_test)
|
||||
gtest_discover_tests(jwt_test)
|
||||
gtest_discover_tests(base64_test)
|
||||
gtest_discover_tests(tag_sort_test)
|
||||
gtest_discover_tests(cache_test)
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <neuron.h>
|
||||
|
||||
zlog_category_t *neuron = NULL;
|
||||
|
||||
TEST(CacheTest, neu_mem_cache_create)
|
||||
{
|
||||
const size_t max_bytes = 1024 * 1024;
|
||||
const size_t max_items = 1024;
|
||||
neu_mem_cache_t *cache = neu_mem_cache_create(max_bytes, max_items);
|
||||
EXPECT_NE(nullptr, cache);
|
||||
neu_mem_cache_destroy(cache);
|
||||
}
|
||||
|
||||
TEST(CacheTest, neu_mem_cache_add)
|
||||
{
|
||||
const size_t max_bytes = 1024 * 1024;
|
||||
const size_t max_items = 1024;
|
||||
neu_mem_cache_t *cache = neu_mem_cache_create(max_bytes, max_items);
|
||||
EXPECT_NE(nullptr, cache);
|
||||
|
||||
const char * str = "hello,world!";
|
||||
cache_item_t item = {
|
||||
.size = strlen(str) + 1,
|
||||
.data = (void *) str,
|
||||
.release = NULL,
|
||||
};
|
||||
|
||||
int rc = neu_mem_cache_add(cache, &item);
|
||||
EXPECT_EQ(0, rc);
|
||||
|
||||
neu_mem_cache_destroy(cache);
|
||||
}
|
||||
|
||||
TEST(CacheTest, neu_mem_cache_used)
|
||||
{
|
||||
const size_t max_bytes = 1024 * 1024;
|
||||
const size_t max_items = 1024;
|
||||
neu_mem_cache_t *cache = neu_mem_cache_create(max_bytes, max_items);
|
||||
EXPECT_NE(nullptr, cache);
|
||||
|
||||
size_t used_bytes = 0;
|
||||
size_t used_msgs = 0;
|
||||
neu_mem_cache_used(cache, &used_bytes, &used_msgs);
|
||||
EXPECT_EQ(0, used_bytes);
|
||||
EXPECT_EQ(0, used_msgs);
|
||||
|
||||
const char * str = "hello,world!";
|
||||
cache_item_t item = {
|
||||
.size = strlen(str) + 1,
|
||||
.data = (void *) str,
|
||||
.release = NULL,
|
||||
};
|
||||
|
||||
int rc = neu_mem_cache_add(cache, &item);
|
||||
EXPECT_EQ(0, rc);
|
||||
|
||||
neu_mem_cache_used(cache, &used_bytes, &used_msgs);
|
||||
EXPECT_EQ(strlen(str) + 1, used_bytes);
|
||||
EXPECT_EQ(1, used_msgs);
|
||||
|
||||
cache_item_t item1 = neu_mem_cache_earliest(cache);
|
||||
EXPECT_NE(nullptr, item1.data);
|
||||
EXPECT_STREQ((char *) item1.data, str);
|
||||
EXPECT_EQ(item1.size, strlen(str) + 1);
|
||||
|
||||
neu_mem_cache_used(cache, &used_bytes, &used_msgs);
|
||||
EXPECT_EQ(0, used_bytes);
|
||||
EXPECT_EQ(0, used_msgs);
|
||||
|
||||
neu_mem_cache_destroy(cache);
|
||||
}
|
||||
|
||||
TEST(CacheTest, neu_mem_cache_latest)
|
||||
{
|
||||
const size_t max_bytes = 1024 * 1024;
|
||||
const size_t max_items = 1024;
|
||||
neu_mem_cache_t *cache = neu_mem_cache_create(max_bytes, max_items);
|
||||
EXPECT_NE(nullptr, cache);
|
||||
|
||||
size_t used_bytes = 0;
|
||||
size_t used_items = 0;
|
||||
neu_mem_cache_used(cache, &used_bytes, &used_items);
|
||||
EXPECT_EQ(0, used_bytes);
|
||||
EXPECT_EQ(0, used_items);
|
||||
|
||||
const char * str = "hello,world!";
|
||||
cache_item_t item = {
|
||||
.size = strlen(str) + 1,
|
||||
.data = (void *) str,
|
||||
.release = NULL,
|
||||
};
|
||||
|
||||
int rc = neu_mem_cache_add(cache, &item);
|
||||
EXPECT_EQ(0, rc);
|
||||
|
||||
neu_mem_cache_used(cache, &used_bytes, &used_items);
|
||||
EXPECT_EQ(strlen(str) + 1, used_bytes);
|
||||
EXPECT_EQ(1, used_items);
|
||||
|
||||
cache_item_t item1 = neu_mem_cache_latest(cache);
|
||||
EXPECT_NE(nullptr, item1.data);
|
||||
EXPECT_STREQ((char *) item1.data, str);
|
||||
EXPECT_EQ(item1.size, strlen(str) + 1);
|
||||
|
||||
neu_mem_cache_used(cache, &used_bytes, &used_items);
|
||||
EXPECT_EQ(0, used_bytes);
|
||||
EXPECT_EQ(0, used_items);
|
||||
|
||||
neu_mem_cache_destroy(cache);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
zlog_init("./config/dev.conf");
|
||||
neuron = zlog_get_category("neuron");
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user