forked from lei.chen/myxce
Adds test_capture_keys_int_kvmgr() to verify integer-keyed kvmgr path. Tests that kvmgr_capture_keys() correctly formats integer keys as decimal strings via snprintf (PRId64), and validates key_len == strlen(key) + 1. All 4 kvmgr_capture tests pass.
244 lines
8.3 KiB
C
244 lines
8.3 KiB
C
/*
|
|
* Test suite for kvmgr_capture_keys() — P0-14a.
|
|
*
|
|
* Tests follow TDD: written BEFORE implementation.
|
|
* All tests exercise the public API declared in kvmgr.h.
|
|
*/
|
|
|
|
#include <rtti.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <unity/unity.h>
|
|
|
|
#include "kv.h"
|
|
#include "kvmgr.h"
|
|
#include "persist.h"
|
|
#include "utils.h"
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
/* helpers */
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
static int find_key_in_captured(slot_key_t* keys, size_t n,
|
|
const char* target_key, int* index_out)
|
|
{
|
|
size_t i;
|
|
for (i = 0; i < n; i++) {
|
|
if (strcmp(keys[i].key, target_key) == 0) {
|
|
if (index_out != NULL) {
|
|
*index_out = keys[i].index;
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
/* test 1: capture from a string-keyed kvmgr with 3 entries */
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
static void test_capture_keys_string_kvmgr(void)
|
|
{
|
|
kvmgr_params_t params = { .key_type = KVMGR_KEY_STRING,
|
|
.nslots = 8,
|
|
.delta = 4,
|
|
.datakiller = NULL };
|
|
var kvmgr = makeInstance(&xkvmgr_type, ¶ms);
|
|
TEST_ASSERT_NOT_NULL(kvmgr);
|
|
|
|
/* Add 3 string-keyed entries whose values are arbitrary pointers;
|
|
the index returned by key_add is the slot index we capture. */
|
|
int idx_a = key_add(kvmgr, (void*)"alpha", (void*)"data_alpha");
|
|
int idx_b = key_add(kvmgr, (void*)"beta", (void*)"data_beta");
|
|
int idx_c = key_add(kvmgr, (void*)"gamma", (void*)"data_gamma");
|
|
TEST_ASSERT_TRUE(idx_a >= 0);
|
|
TEST_ASSERT_TRUE(idx_b >= 0);
|
|
TEST_ASSERT_TRUE(idx_c >= 0);
|
|
|
|
slot_key_t* keys = NULL;
|
|
size_t n_keys = 0;
|
|
int rc = kvmgr_capture_keys(kvmgr, &keys, &n_keys);
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, rc);
|
|
TEST_ASSERT_EQUAL_size_t(3, n_keys);
|
|
TEST_ASSERT_NOT_NULL(keys);
|
|
|
|
/* Every inserted key must appear exactly once with the correct index */
|
|
int found_idx = -1;
|
|
TEST_ASSERT_TRUE(find_key_in_captured(keys, n_keys, "alpha", &found_idx));
|
|
TEST_ASSERT_EQUAL_INT(idx_a, found_idx);
|
|
|
|
TEST_ASSERT_TRUE(find_key_in_captured(keys, n_keys, "beta", &found_idx));
|
|
TEST_ASSERT_EQUAL_INT(idx_b, found_idx);
|
|
|
|
TEST_ASSERT_TRUE(find_key_in_captured(keys, n_keys, "gamma", &found_idx));
|
|
TEST_ASSERT_EQUAL_INT(idx_c, found_idx);
|
|
|
|
/* key_len must equal strlen(key)+1 */
|
|
size_t i;
|
|
for (i = 0; i < n_keys; i++) {
|
|
TEST_ASSERT_EQUAL_size_t(strlen(keys[i].key) + 1, keys[i].key_len);
|
|
}
|
|
|
|
free(keys);
|
|
destroy(kvmgr);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
/* test 2: empty kvmgr returns 0 entries and NULL keys_out */
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
static void test_capture_keys_empty_kvmgr(void)
|
|
{
|
|
kvmgr_params_t params = { .key_type = KVMGR_KEY_STRING,
|
|
.nslots = 4,
|
|
.delta = 4,
|
|
.datakiller = NULL };
|
|
var kvmgr = makeInstance(&xkvmgr_type, ¶ms);
|
|
TEST_ASSERT_NOT_NULL(kvmgr);
|
|
|
|
slot_key_t* keys = (slot_key_t*)(uintptr_t)0xdeadbeef; /* sentinel */
|
|
size_t n_keys = 99;
|
|
|
|
int rc = kvmgr_capture_keys(kvmgr, &keys, &n_keys);
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, rc);
|
|
TEST_ASSERT_EQUAL_size_t(0, n_keys);
|
|
TEST_ASSERT_NULL(keys);
|
|
|
|
destroy(kvmgr);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
/* test 3: captured keys are deep copies — safe after kvmgr destroyed */
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
static void test_capture_keys_are_deep_copies(void)
|
|
{
|
|
kvmgr_params_t params = { .key_type = KVMGR_KEY_STRING,
|
|
.nslots = 4,
|
|
.delta = 4,
|
|
.datakiller = NULL };
|
|
var kvmgr = makeInstance(&xkvmgr_type, ¶ms);
|
|
TEST_ASSERT_NOT_NULL(kvmgr);
|
|
|
|
key_add(kvmgr, (void*)"keyA", (void*)"valA");
|
|
key_add(kvmgr, (void*)"keyB", (void*)"valB");
|
|
|
|
slot_key_t* keys = NULL;
|
|
size_t n_keys = 0;
|
|
int rc = kvmgr_capture_keys(kvmgr, &keys, &n_keys);
|
|
TEST_ASSERT_EQUAL_INT(0, rc);
|
|
TEST_ASSERT_EQUAL_size_t(2, n_keys);
|
|
|
|
/* Stash manual copies of the captured key strings */
|
|
char copy_a[256], copy_b[256];
|
|
int found_a = 0, found_b = 0;
|
|
size_t i;
|
|
for (i = 0; i < n_keys; i++) {
|
|
if (strcmp(keys[i].key, "keyA") == 0) {
|
|
strncpy(copy_a, keys[i].key, sizeof(copy_a) - 1);
|
|
copy_a[sizeof(copy_a) - 1] = '\0';
|
|
found_a = 1;
|
|
} else if (strcmp(keys[i].key, "keyB") == 0) {
|
|
strncpy(copy_b, keys[i].key, sizeof(copy_b) - 1);
|
|
copy_b[sizeof(copy_b) - 1] = '\0';
|
|
found_b = 1;
|
|
}
|
|
}
|
|
TEST_ASSERT_TRUE(found_a);
|
|
TEST_ASSERT_TRUE(found_b);
|
|
|
|
/* Destroy the kvmgr — this frees all kvtab entries including the
|
|
original key strings. Captured keys[] must remain valid. */
|
|
destroy(kvmgr);
|
|
|
|
TEST_ASSERT_EQUAL_STRING("keyA", copy_a);
|
|
TEST_ASSERT_EQUAL_STRING("keyB", copy_b);
|
|
|
|
/* Directly verify the captured keys array is still readable */
|
|
int still_a = 0, still_b = 0;
|
|
for (i = 0; i < n_keys; i++) {
|
|
if (strcmp(keys[i].key, "keyA") == 0) still_a = 1;
|
|
if (strcmp(keys[i].key, "keyB") == 0) still_b = 1;
|
|
}
|
|
TEST_ASSERT_TRUE(still_a);
|
|
TEST_ASSERT_TRUE(still_b);
|
|
|
|
free(keys);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
/* test 4: capture from an integer-keyed kvmgr with 3 entries */
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
static void test_capture_keys_int_kvmgr(void)
|
|
{
|
|
kvmgr_params_t params = { .key_type = KVMGR_KEY_INT,
|
|
.nslots = 8,
|
|
.delta = 4,
|
|
.datakiller = NULL };
|
|
var kvmgr = makeInstance(&xkvmgr_type, ¶ms);
|
|
TEST_ASSERT_NOT_NULL(kvmgr);
|
|
|
|
/* Add 3 integer-keyed entries; the integer keys are jobids.
|
|
For integer-keyed kvmgrs, key_add expects a (void*)(long)intval. */
|
|
int64_t jobid_1001 = 1001;
|
|
int64_t jobid_1002 = 1002;
|
|
int64_t jobid_1003 = 1003;
|
|
|
|
int idx_1001 =
|
|
key_add(kvmgr, (void*)(long)jobid_1001, (void*)"data_1001");
|
|
int idx_1002 =
|
|
key_add(kvmgr, (void*)(long)jobid_1002, (void*)"data_1002");
|
|
int idx_1003 =
|
|
key_add(kvmgr, (void*)(long)jobid_1003, (void*)"data_1003");
|
|
TEST_ASSERT_TRUE(idx_1001 >= 0);
|
|
TEST_ASSERT_TRUE(idx_1002 >= 0);
|
|
TEST_ASSERT_TRUE(idx_1003 >= 0);
|
|
|
|
slot_key_t* keys = NULL;
|
|
size_t n_keys = 0;
|
|
int rc = kvmgr_capture_keys(kvmgr, &keys, &n_keys);
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, rc);
|
|
TEST_ASSERT_EQUAL_size_t(3, n_keys);
|
|
TEST_ASSERT_NOT_NULL(keys);
|
|
|
|
/* Every inserted integer key must appear as a decimal string with the
|
|
correct index */
|
|
int found_idx = -1;
|
|
TEST_ASSERT_TRUE(find_key_in_captured(keys, n_keys, "1001", &found_idx));
|
|
TEST_ASSERT_EQUAL_INT(idx_1001, found_idx);
|
|
|
|
TEST_ASSERT_TRUE(find_key_in_captured(keys, n_keys, "1002", &found_idx));
|
|
TEST_ASSERT_EQUAL_INT(idx_1002, found_idx);
|
|
|
|
TEST_ASSERT_TRUE(find_key_in_captured(keys, n_keys, "1003", &found_idx));
|
|
TEST_ASSERT_EQUAL_INT(idx_1003, found_idx);
|
|
|
|
/* key_len must equal strlen(key)+1 */
|
|
size_t i;
|
|
for (i = 0; i < n_keys; i++) {
|
|
TEST_ASSERT_EQUAL_size_t(strlen(keys[i].key) + 1, keys[i].key_len);
|
|
}
|
|
|
|
free(keys);
|
|
destroy(kvmgr);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
/* entry point called from test.c */
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
void test_kvmgr_capture(void)
|
|
{
|
|
printf("\n>> kvmgr_capture_keys test\n");
|
|
RUN_TEST(test_capture_keys_string_kvmgr);
|
|
RUN_TEST(test_capture_keys_empty_kvmgr);
|
|
RUN_TEST(test_capture_keys_are_deep_copies);
|
|
RUN_TEST(test_capture_keys_int_kvmgr);
|
|
}
|