AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* The CellArray struct is internal to btree.c. We mirror it here so that7** we can construct inputs for the test wrapper. This must match the layout8** used by the target function. */9typedef struct CellArray CellArray;10struct CellArray {11 int nCell; /* Number of cells in apCell[] */12 MemPage *pRef; /* Reference page */13 u8 **apCell; /* Cell pointers */14 u16 *szCell; /* Local size of all cells in apCell[] */15 u8 *apEnd[3*2]; /* Not used by populateCellCache() */16 int ixNx[3*2]; /* Not used by populateCellCache() */17};18 19/* The test wrapper provided by the module under test. */20extern void test_populateCellCache(CellArray *p, int idx, int N);21 22/* Global counter to verify number of xCellSize calls */23static int g_xCellSize_calls = 0;24 25/* xCellSize stub: return the first byte of the cell buffer as size,26 and increment a counter to record invocations. */27static u16 test_xCellSize(MemPage *pPage, u8 *pCell){28 (void)pPage;29 g_xCellSize_calls++;30 return (u16)(pCell ? pCell[0] : 0);31}32 33/* Helper to initialize a MemPage with our xCellSize stub */34static void init_mempage_with_stub(MemPage *pPage){35 memset(pPage, 0, sizeof(*pPage));36 pPage->xCellSize = test_xCellSize;37}38 39/* Reset between tests */40void setUp(void) {41 g_xCellSize_calls = 0;42}43void tearDown(void) {44 /* nothing */45}46 47/* Test 1: populate a subset range and verify sizes and call counts */48void test_populateCellCache_basic_subset(void){49 MemPage mp;50 init_mempage_with_stub(&mp);51 52 enum { N = 5 };53 u8 c0 = 10, c1 = 20, c2 = 30, c3 = 40, c4 = 50;54 u8 *apCell[N] = { &c0, &c1, &c2, &c3, &c4 };55 u16 szCell[N] = { 0, 0, 0, 0, 0 };56 57 CellArray arr;58 memset(&arr, 0, sizeof(arr));59 arr.nCell = N;60 arr.pRef = ∓61 arr.apCell = apCell;62 arr.szCell = szCell;63 64 /* Populate indices 1..3 (3 entries) */65 test_populateCellCache(&arr, 1, 3);66 67 TEST_ASSERT_EQUAL_INT(0, arr.szCell[0]);68 TEST_ASSERT_EQUAL_INT(20, arr.szCell[1]);69 TEST_ASSERT_EQUAL_INT(30, arr.szCell[2]);70 TEST_ASSERT_EQUAL_INT(40, arr.szCell[3]);71 TEST_ASSERT_EQUAL_INT(0, arr.szCell[4]);72 73 TEST_ASSERT_EQUAL_INT(3, g_xCellSize_calls);74}75 76/* Test 2: ensure precomputed size is preserved and xCellSize not called for it */77void test_populateCellCache_preserves_precomputed(void){78 MemPage mp;79 init_mempage_with_stub(&mp);80 81 enum { N = 5 };82 u8 c0 = 10, c1 = 20, c2 = 30, c3 = 40, c4 = 50;83 u8 *apCell[N] = { &c0, &c1, &c2, &c3, &c4 };84 u16 szCell[N] = { 0, 0, 30, 0, 0 }; /* precompute index 2 with the expected size */85 86 CellArray arr;87 memset(&arr, 0, sizeof(arr));88 arr.nCell = N;89 arr.pRef = ∓90 arr.apCell = apCell;91 arr.szCell = szCell;92 93 test_populateCellCache(&arr, 1, 3);94 95 TEST_ASSERT_EQUAL_INT(0, arr.szCell[0]);96 TEST_ASSERT_EQUAL_INT(20, arr.szCell[1]);97 TEST_ASSERT_EQUAL_INT(30, arr.szCell[2]); /* preserved */98 TEST_ASSERT_EQUAL_INT(40, arr.szCell[3]);99 TEST_ASSERT_EQUAL_INT(0, arr.szCell[4]);100 101 /* Only indexes 1 and 3 required xCellSize; index 2 was precomputed */102 TEST_ASSERT_EQUAL_INT(2, g_xCellSize_calls);103}104 105/* Test 3: N==0 is a no-op */106void test_populateCellCache_zero_N_noop(void){107 MemPage mp;108 init_mempage_with_stub(&mp);109 110 enum { N = 3 };111 u8 c0 = 11, c1 = 22, c2 = 33;112 u8 *apCell[N] = { &c0, &c1, &c2 };113 u16 szCell[N] = { 0, 0, 0 };114 115 CellArray arr;116 memset(&arr, 0, sizeof(arr));117 arr.nCell = N;118 arr.pRef = ∓119 arr.apCell = apCell;120 arr.szCell = szCell;121 122 test_populateCellCache(&arr, 1, 0);123 124 TEST_ASSERT_EQUAL_INT(0, arr.szCell[0]);125 TEST_ASSERT_EQUAL_INT(0, arr.szCell[1]);126 TEST_ASSERT_EQUAL_INT(0, arr.szCell[2]);127 TEST_ASSERT_EQUAL_INT(0, g_xCellSize_calls);128}129 130/* Test 4: Populate the full range */131void test_populateCellCache_full_range(void){132 MemPage mp;133 init_mempage_with_stub(&mp);134 135 enum { N = 4 };136 u8 c0 = 5, c1 = 6, c2 = 7, c3 = 8;137 u8 *apCell[N] = { &c0, &c1, &c2, &c3 };138 u16 szCell[N] = { 0, 0, 0, 0 };139 140 CellArray arr;141 memset(&arr, 0, sizeof(arr));142 arr.nCell = N;143 arr.pRef = ∓144 arr.apCell = apCell;145 arr.szCell = szCell;146 147 test_populateCellCache(&arr, 0, N);148 149 TEST_ASSERT_EQUAL_INT(5, arr.szCell[0]);150 TEST_ASSERT_EQUAL_INT(6, arr.szCell[1]);151 TEST_ASSERT_EQUAL_INT(7, arr.szCell[2]);152 TEST_ASSERT_EQUAL_INT(8, arr.szCell[3]);153 154 TEST_ASSERT_EQUAL_INT(N, g_xCellSize_calls);155}156 157int main(void){158 UNITY_BEGIN();159 RUN_TEST(test_populateCellCache_basic_subset);160 RUN_TEST(test_populateCellCache_preserves_precomputed);161 RUN_TEST(test_populateCellCache_zero_N_noop);162 RUN_TEST(test_populateCellCache_full_range);163 return UNITY_END();164}