AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* The wrapper for the static function under test is provided in the module: */6void test_statResetCsr(StatCursor *pCsr);7 8static void alloc_page_with_cells(StatPage *p, int nCell, int nOvflPerCell){9 int i;10 /* Simulate an allocated page buffer */11 p->aPg = (u8*)sqlite3_malloc(512);12 TEST_ASSERT_NOT_NULL(p->aPg);13 memset(p->aPg, 0xAB, 512);14 15 /* Per-page path string */16 p->zPath = sqlite3_mprintf("/testpage");17 TEST_ASSERT_NOT_NULL(p->zPath);18 19 /* Simulate cell array and nested overflow arrays */20 p->nCell = nCell;21 if( nCell>0 ){22 p->aCell = (StatCell*)sqlite3_malloc64((nCell) * sizeof(StatCell));23 TEST_ASSERT_NOT_NULL(p->aCell);24 memset(p->aCell, 0, (nCell) * sizeof(StatCell));25 for(i=0; i<nCell; i++){26 p->aCell[i].nOvfl = nOvflPerCell;27 if( nOvflPerCell>0 ){28 p->aCell[i].aOvfl = (u32*)sqlite3_malloc64(sizeof(u32)*nOvflPerCell);29 TEST_ASSERT_NOT_NULL(p->aCell[i].aOvfl);30 memset(p->aCell[i].aOvfl, 0, sizeof(u32)*nOvflPerCell);31 }else{32 p->aCell[i].aOvfl = 0;33 }34 }35 }else{36 p->aCell = 0;37 }38}39 40void setUp(void) {41 /* No global setup required */42}43 44void tearDown(void) {45 /* No global teardown required */46}47 48static sqlite3_stmt* prepare_and_step(sqlite3 *db){49 sqlite3_stmt *pStmt = 0;50 /* A simple two-row query so we can verify reset brings it back to first row */51 const char *zSql = "SELECT 1 AS x UNION ALL SELECT 2";52 int rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);53 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);54 /* Advance once so the statement is no longer at the initial state */55 rc = sqlite3_step(pStmt);56 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);57 TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(pStmt, 0));58 return pStmt;59}60 61void test_statResetCsr_resets_and_clears(void) {62 sqlite3 *db = 0;63 int rc = sqlite3_open(":memory:", &db);64 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);65 66 sqlite3_stmt *pStmt = prepare_and_step(db);67 68 /* Initialize a StatCursor with various allocations */69 StatCursor csr;70 memset(&csr, 0, sizeof(csr));71 csr.pStmt = pStmt;72 csr.iPage = 5;73 csr.isEof = 1;74 csr.zPath = sqlite3_mprintf("/overall/path");75 TEST_ASSERT_NOT_NULL(csr.zPath);76 77 /* Fill a couple of pages in the aPage array */78 alloc_page_with_cells(&csr.aPage[0], 2, 2);79 alloc_page_with_cells(&csr.aPage[3], 1, 1);80 81 /* Call the function under test via the provided wrapper */82 test_statResetCsr(&csr);83 84 /* Verify cursor-level fields reset */85 TEST_ASSERT_EQUAL_INT(0, csr.iPage);86 TEST_ASSERT_EQUAL_UINT8(0, csr.isEof);87 TEST_ASSERT_NULL(csr.zPath);88 89 /* Verify pages were cleared and buffers freed/nullified */90 TEST_ASSERT_NULL(csr.aPage[0].aPg);91 TEST_ASSERT_NULL(csr.aPage[0].zPath);92 TEST_ASSERT_EQUAL_INT(0, csr.aPage[0].nCell);93 TEST_ASSERT_NULL(csr.aPage[0].aCell);94 95 TEST_ASSERT_NULL(csr.aPage[3].aPg);96 TEST_ASSERT_NULL(csr.aPage[3].zPath);97 TEST_ASSERT_EQUAL_INT(0, csr.aPage[3].nCell);98 TEST_ASSERT_NULL(csr.aPage[3].aCell);99 100 /* Verify the prepared statement has been reset (first row visible again) */101 rc = sqlite3_step(pStmt);102 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);103 TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(pStmt, 0));104 105 /* Cleanup */106 sqlite3_finalize(pStmt);107 sqlite3_close(db);108}109 110void test_statResetCsr_idempotent_and_stmt_usable(void) {111 sqlite3 *db = 0;112 int rc = sqlite3_open(":memory:", &db);113 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);114 115 sqlite3_stmt *pStmt = prepare_and_step(db);116 117 StatCursor csr;118 memset(&csr, 0, sizeof(csr));119 csr.pStmt = pStmt;120 csr.iPage = 12;121 csr.isEof = 1;122 123 /* First reset: also include allocations to be freed */124 alloc_page_with_cells(&csr.aPage[1], 3, 0);125 csr.zPath = sqlite3_mprintf("/first/reset");126 TEST_ASSERT_NOT_NULL(csr.zPath);127 test_statResetCsr(&csr);128 129 /* After first reset, statement should be reset to start */130 rc = sqlite3_step(pStmt);131 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);132 TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(pStmt, 0));133 134 /* Modify cursor fields again (no new allocations) and call reset again */135 csr.iPage = 7;136 csr.isEof = 1;137 test_statResetCsr(&csr);138 139 TEST_ASSERT_EQUAL_INT(0, csr.iPage);140 TEST_ASSERT_EQUAL_UINT8(0, csr.isEof);141 TEST_ASSERT_NULL(csr.zPath);142 143 /* Statement still usable and reset again */144 rc = sqlite3_step(pStmt);145 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);146 TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(pStmt, 0));147 148 sqlite3_finalize(pStmt);149 sqlite3_close(db);150}151 152int main(void) {153 UNITY_BEGIN();154 RUN_TEST(test_statResetCsr_resets_and_clears);155 RUN_TEST(test_statResetCsr_idempotent_and_stmt_usable);156 return UNITY_END();157}