Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_btree_accessPayloadChecked.c96 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* The static function under test has a global wrapper named test_accessPayloadChecked */6extern int test_accessPayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf);7 8static sqlite3 *gDb = NULL;9 10void setUp(void) {11  /* Open an in-memory database for tests that need real Btree/BtShared */12  /* For tests that do not need it, this being open is harmless */13  if( gDb==NULL ){14    int rc = sqlite3_open(":memory:", &gDb);15    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);16  }17}18 19void tearDown(void) {20  if( gDb ){21    sqlite3_close(gDb);22    gDb = NULL;23  }24}25 26/* Helper: obtain the main database Btree from the opened connection */27static Btree* helperGetMainBtree(sqlite3 *db){28  /* aDb[0] is main db */29  TEST_ASSERT_NOT_NULL(db);30  TEST_ASSERT_TRUE(db->nDb>0);31  TEST_ASSERT_NOT_NULL(db->aDb);32  return db->aDb[0].pBt;33}34 35/* Test 1: When the cursor is CURSOR_INVALID, the function must return SQLITE_ABORT,36           and not modify the output buffer. */37void test_accessPayloadChecked_returns_abort_on_invalid(void) {38  BtCursor cur;39  memset(&cur, 0, sizeof(cur));40  cur.eState = CURSOR_INVALID; /* Immediate return path */41 42  unsigned char buf[16];43  memset(buf, 0xAA, sizeof(buf));44 45  int rc = test_accessPayloadChecked(&cur, /*offset=*/0, /*amt=*/8, buf);46  TEST_ASSERT_EQUAL_INT(SQLITE_ABORT, rc);47 48  /* Buffer must remain unchanged since accessPayload() is never called */49  for(size_t i=0; i<sizeof(buf); i++){50    TEST_ASSERT_EQUAL_UINT8(0xAA, buf[i]);51  }52}53 54/* Test 2: When the cursor is not invalid and is in CURSOR_FAULT, the wrapper should:55           - assert cursor owns BtShared (so we must satisfy mutex/db equality)56           - call btreeRestoreCursorPosition(), which returns cur.skipNext for CURSOR_FAULT57           - return that code and not touch the buffer58*/59void test_accessPayloadChecked_propagates_restorecode_on_fault(void) {60  /* Acquire a real Btree and BtShared to satisfy asserts (cursorOwnsBtShared) */61  Btree *pBtree = helperGetMainBtree(gDb);62  TEST_ASSERT_NOT_NULL(pBtree);63  BtShared *pBt = pBtree->pBt;64  TEST_ASSERT_NOT_NULL(pBt);65 66  /* Enter the Btree mutex so that cursorHoldsMutex() assertion passes */67  sqlite3BtreeEnter(pBtree);68 69  BtCursor cur;70  memset(&cur, 0, sizeof(cur));71  cur.pBtree = pBtree;72  cur.pBt = pBt;73  cur.eState = CURSOR_FAULT;  /* >= CURSOR_REQUIRESEEK and trips early return in restore */74  cur.skipNext = 37;          /* Expected rc from btreeRestoreCursorPosition */75 76  unsigned char out[8];77  memset(out, 0xBB, sizeof(out));78 79  int rc = test_accessPayloadChecked(&cur, 4, 4, out);80  TEST_ASSERT_EQUAL_INT(37, rc);81  /* The cursor should still be in FAULT state after the call (no change in early return) */82  TEST_ASSERT_EQUAL_INT(CURSOR_FAULT, cur.eState);83  /* The buffer should be untouched */84  for(size_t i=0; i<sizeof(out); i++){85    TEST_ASSERT_EQUAL_UINT8(0xBB, out[i]);86  }87 88  sqlite3BtreeLeave(pBtree);89}90 91int main(void) {92  UNITY_BEGIN();93  RUN_TEST(test_accessPayloadChecked_returns_abort_on_invalid);94  RUN_TEST(test_accessPayloadChecked_propagates_restorecode_on_fault);95  return UNITY_END();96}