AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Prototype for the global test wrapper of the static function */6extern int test_btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags);7 8static sqlite3 *gDb = NULL;9 10/* Helper: open an in-memory Btree and begin a write transaction */11static Btree* open_btree_in_memory(void){12 int rc;13 Btree *pBtree = NULL;14 sqlite3_vfs *pVfs = sqlite3_vfs_find(0);15 TEST_ASSERT_NOT_NULL_MESSAGE(pVfs, "Default VFS not found");16 17 rc = sqlite3_open(":memory:", &gDb);18 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");19 20 /* Open a btree on the in-memory database. */21 rc = sqlite3BtreeOpen(22 pVfs,23 ":memory:",24 gDb,25 &pBtree,26 0, /* flags */27 SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE28 );29 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3BtreeOpen failed");30 TEST_ASSERT_NOT_NULL(pBtree);31 32 /* Begin a write transaction */33 rc = sqlite3BtreeBeginTrans(pBtree, 1, 0);34 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3BtreeBeginTrans failed");35 36 return pBtree;37}38 39/* Helper: close Btree and sqlite3 */40static void close_btree_and_db(Btree *pBtree){41 if( pBtree ){42 /* Commit write transaction if any */43 (void)sqlite3BtreeCommit(pBtree);44 (void)sqlite3BtreeClose(pBtree);45 }46 if( gDb ){47 (void)sqlite3_close(gDb);48 gDb = NULL;49 }50}51 52void setUp(void){53 /* nothing */54}55void tearDown(void){56 /* nothing; each test cleans up its own resources */57}58 59/* Test: create a table (INTKEY|LEAFDATA) and verify page header flags and basics */60void test_btreeCreateTable_creates_table_leaf_intkey(void){61 int rc;62 Btree *pBtree = open_btree_in_memory();63 BtShared *pBt = pBtree->pBt;64 Pgno pgno = 0;65 DbPage *pDbPage = NULL;66 u8 *aData = NULL;67 68 /* Hold the Btree mutex as asserted by the callee */69 sqlite3BtreeEnter(pBtree);70 71 rc = test_btreeCreateTable(pBtree, &pgno, BTREE_INTKEY|BTREE_LEAFDATA);72 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);73 TEST_ASSERT_TRUE_MESSAGE(pgno >= 2, "Root page should be >= 2");74 75 /* Inspect header of the created root page */76 rc = sqlite3PagerGet(pBt->pPager, pgno, &pDbPage, PAGER_GET_READONLY);77 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);78 aData = (u8*)sqlite3PagerGetData(pDbPage);79 80 /* Header offset is 0 for pages other than page 1 */81 TEST_ASSERT_EQUAL_HEX8((u8)(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF), aData[0]);82 /* number of cells at offset 3..4 is 0 */83 TEST_ASSERT_EQUAL_UINT16(0, (u16)get2byte(&aData[3]));84 /* start of cell content area at offset 5..6 equals usableSize */85 TEST_ASSERT_EQUAL_UINT16((u16)pBt->usableSize, (u16)get2byte(&aData[5]));86 87 sqlite3PagerUnref(pDbPage);88 sqlite3BtreeLeave(pBtree);89 90 close_btree_and_db(pBtree);91}92 93/* Test: create an index (ZERODATA) and verify page header flags */94void test_btreeCreateTable_creates_index_leaf_zerodata(void){95 int rc;96 Btree *pBtree = open_btree_in_memory();97 BtShared *pBt = pBtree->pBt;98 Pgno pgno = 0;99 DbPage *pDbPage = NULL;100 u8 *aData = NULL;101 102 sqlite3BtreeEnter(pBtree);103 104 rc = test_btreeCreateTable(pBtree, &pgno, BTREE_ZERODATA);105 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);106 TEST_ASSERT_TRUE(pgno >= 2);107 108 rc = sqlite3PagerGet(pBt->pPager, pgno, &pDbPage, PAGER_GET_READONLY);109 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);110 aData = (u8*)sqlite3PagerGetData(pDbPage);111 112 TEST_ASSERT_EQUAL_HEX8((u8)(PTF_ZERODATA|PTF_LEAF), aData[0]);113 TEST_ASSERT_EQUAL_UINT16(0, (u16)get2byte(&aData[3]));114 TEST_ASSERT_EQUAL_UINT16((u16)pBt->usableSize, (u16)get2byte(&aData[5]));115 116 sqlite3PagerUnref(pDbPage);117 sqlite3BtreeLeave(pBtree);118 119 close_btree_and_db(pBtree);120}121 122/* Test: two successive creates yield increasing root page numbers (distinct) */123void test_btreeCreateTable_returns_incrementing_root_pages(void){124 int rc;125 Btree *pBtree = open_btree_in_memory();126 Pgno pgno1 = 0, pgno2 = 0;127 128 sqlite3BtreeEnter(pBtree);129 130 rc = test_btreeCreateTable(pBtree, &pgno1, BTREE_INTKEY|BTREE_LEAFDATA);131 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);132 rc = test_btreeCreateTable(pBtree, &pgno2, BTREE_ZERODATA);133 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);134 135 TEST_ASSERT_TRUE_MESSAGE(pgno2 != pgno1, "Root pages should be distinct");136 TEST_ASSERT_TRUE_MESSAGE(pgno2 > pgno1, "Second root page should be larger");137 138 sqlite3BtreeLeave(pBtree);139 close_btree_and_db(pBtree);140}141 142/* Test: verify cell content offset is set to usableSize by zeroPage() */143void test_btreeCreateTable_sets_cell_content_offset_to_usableSize(void){144 int rc;145 Btree *pBtree = open_btree_in_memory();146 BtShared *pBt = pBtree->pBt;147 Pgno pgno = 0;148 DbPage *pDbPage = NULL;149 u8 *aData = NULL;150 151 sqlite3BtreeEnter(pBtree);152 rc = test_btreeCreateTable(pBtree, &pgno, BTREE_INTKEY|BTREE_LEAFDATA);153 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);154 155 rc = sqlite3PagerGet(pBt->pPager, pgno, &pDbPage, PAGER_GET_READONLY);156 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);157 aData = (u8*)sqlite3PagerGetData(pDbPage);158 159 TEST_ASSERT_EQUAL_UINT16((u16)pBt->usableSize, (u16)get2byte(&aData[5]));160 161 sqlite3PagerUnref(pDbPage);162 sqlite3BtreeLeave(pBtree);163 close_btree_and_db(pBtree);164}165 166int main(void){167 UNITY_BEGIN();168 RUN_TEST(test_btreeCreateTable_creates_table_leaf_intkey);169 RUN_TEST(test_btreeCreateTable_creates_index_leaf_zerodata);170 RUN_TEST(test_btreeCreateTable_returns_incrementing_root_pages);171 RUN_TEST(test_btreeCreateTable_sets_cell_content_offset_to_usableSize);172 return UNITY_END();173}