Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_prepare_sqlite3InitCallback.c259 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <string.h>5#include <stdlib.h>6 7/* Global database handle for each test */8static sqlite3 *gDb = NULL;9 10/* Convenience helpers to safely enter/leave the db mutex */11static void enterDbMutex(sqlite3 *db){12  if( db && db->mutex ) sqlite3_mutex_enter(db->mutex);13}14static void leaveDbMutex(sqlite3 *db){15  if( db && db->mutex ) sqlite3_mutex_leave(db->mutex);16}17 18/* Initialize an InitData struct with sensible defaults */19static void init_InitData(InitData *p, sqlite3 *db, int iDb, char **pzErr){20  memset(p, 0, sizeof(*p));21  p->db = db;22  p->iDb = iDb;23  p->mxPage = 0;        /* 0 disables the >mxPage extra check */24  p->pzErrMsg = pzErr;25  p->rc = SQLITE_OK;26  p->nInitRow = 0;27  p->mInitFlags = 0;28}29 30void setUp(void) {31  int rc = sqlite3_open(":memory:", &gDb);32  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);33  TEST_ASSERT_NOT_NULL(gDb);34}35 36void tearDown(void) {37  if( gDb ){38    int rc = sqlite3_close(gDb);39    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);40    gDb = NULL;41  }42}43 44/* Test: argv==NULL should return 0 and not increment nInitRow */45void test_sqlite3InitCallback_null_argv_returns0(void){46  InitData d;47  char *zErr = 0;48  init_InitData(&d, gDb, 0, &zErr);49 50  enterDbMutex(gDb);51  int rc = sqlite3InitCallback(&d, 5, NULL, NULL);52  leaveDbMutex(gDb);53 54  TEST_ASSERT_EQUAL_INT(0, rc);55  TEST_ASSERT_EQUAL_INT(0, d.nInitRow);56  TEST_ASSERT_EQUAL_INT(SQLITE_OK, d.rc);57  TEST_ASSERT_NULL(zErr);58}59 60/* Test: Successful CREATE TABLE processing builds schema object */61void test_sqlite3InitCallback_create_builds_schema(void){62  InitData d;63  char *zErr = 0;64  init_InitData(&d, gDb, 0, &zErr);65 66  const char *type = "table";67  const char *name = "cb_t1";68  const char *tbl  = "cb_t1";69  const char *root = "2";70  const char *sql  = "CREATE TABLE cb_t1(a)";71 72  char *argv[5];73  argv[0] = (char*)type;74  argv[1] = (char*)name;75  argv[2] = (char*)tbl;76  argv[3] = (char*)root;77  argv[4] = (char*)sql;78 79  /* Ensure init mode is set, and mutex is held */80  enterDbMutex(gDb);81  int savedBusy = gDb->init.busy;82  gDb->init.busy = 1;83 84  int cbRc = sqlite3InitCallback(&d, 5, argv, NULL);85 86  /* Restore busy and unlock */87  gDb->init.busy = savedBusy;88  leaveDbMutex(gDb);89 90  TEST_ASSERT_EQUAL_INT(0, cbRc);91  TEST_ASSERT_EQUAL_INT(1, d.nInitRow);92  TEST_ASSERT_EQUAL_INT(SQLITE_OK, d.rc);93  TEST_ASSERT_NULL(zErr);94 95  /* Verify the Table now exists in the schema */96  enterDbMutex(gDb);97  Table *pTab = sqlite3FindTable(gDb, name, "main");98  leaveDbMutex(gDb);99  TEST_ASSERT_NOT_NULL(pTab);100}101 102/* Test: NULL rootpage (argv[3]==NULL) triggers corruptSchema */103void test_sqlite3InitCallback_null_rootpage_triggers_corrupt(void){104  InitData d;105  char *zErr = 0;106  init_InitData(&d, gDb, 0, &zErr);107 108  char *argv[5];109  argv[0] = "table";110  argv[1] = "t_badroot";111  argv[2] = "t_badroot";112  argv[3] = NULL;                         /* NULL rootpage */113  argv[4] = "CREATE TABLE t_badroot(x)";114 115  enterDbMutex(gDb);116  int savedBusy = gDb->init.busy;117  gDb->init.busy = 1;118 119  int rc = sqlite3InitCallback(&d, 5, argv, NULL);120 121  gDb->init.busy = savedBusy;122  leaveDbMutex(gDb);123 124  TEST_ASSERT_EQUAL_INT(0, rc);125  TEST_ASSERT_NOT_EQUAL(SQLITE_OK, d.rc);126  TEST_ASSERT_NOT_NULL(zErr);127  /* Clean up error string */128  sqlite3DbFree(gDb, zErr); zErr = 0;129}130 131/* Test: Syntax error during CREATE triggers corruptSchema */132void test_sqlite3InitCallback_syntax_error_triggers_corrupt(void){133  InitData d;134  char *zErr = 0;135  init_InitData(&d, gDb, 0, &zErr);136 137  char *argv[5];138  argv[0] = "table";139  argv[1] = "t_syntax";140  argv[2] = "t_syntax";141  argv[3] = "7";142  argv[4] = "CREATE TABL t_syntax(a)";   /* deliberate syntax error */143 144  enterDbMutex(gDb);145  int savedBusy = gDb->init.busy;146  gDb->init.busy = 1;147 148  int rc = sqlite3InitCallback(&d, 5, argv, NULL);149 150  gDb->init.busy = savedBusy;151  leaveDbMutex(gDb);152 153  TEST_ASSERT_EQUAL_INT(0, rc);154  TEST_ASSERT_NOT_EQUAL(SQLITE_OK, d.rc);155  TEST_ASSERT_NOT_NULL(zErr);156  /* The message should reflect malformed database schema */157  TEST_ASSERT_NOT_EQUAL(NULL, strstr(zErr, "malformed database schema"));158  sqlite3DbFree(gDb, zErr); zErr = 0;159}160 161/* Test: Non-CREATE with non-empty SQL triggers corruptSchema */162void test_sqlite3InitCallback_noncreate_nonempty_sql_triggers_corrupt(void){163  InitData d;164  char *zErr = 0;165  init_InitData(&d, gDb, 0, &zErr);166 167  char *argv[5];168  argv[0] = "table";169  argv[1] = "t_misc";170  argv[2] = "t_misc";171  argv[3] = "10";172  argv[4] = "INSERT INTO t_misc VALUES(1)"; /* Not a CREATE statement */173 174  enterDbMutex(gDb);175  int rc = sqlite3InitCallback(&d, 5, argv, NULL);176  leaveDbMutex(gDb);177 178  TEST_ASSERT_EQUAL_INT(0, rc);179  TEST_ASSERT_NOT_EQUAL(SQLITE_OK, d.rc);180  TEST_ASSERT_NOT_NULL(zErr);181  sqlite3DbFree(gDb, zErr); zErr = 0;182}183 184/* Test: Blank-SQL index row sets the rootpage on an existing auto-index */185void test_sqlite3InitCallback_autoindex_blank_sql_sets_rootpage(void){186  /* First create a table with a PRIMARY KEY to ensure an auto-index exists */187  int rc = sqlite3_exec(gDb, "CREATE TABLE tidx(a PRIMARY KEY)", 0, 0, 0);188  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);189 190  /* Verify the auto-index exists */191  enterDbMutex(gDb);192  Index *pIdxPre = sqlite3FindIndex(gDb, "sqlite_autoindex_tidx_1", "main");193  leaveDbMutex(gDb);194  TEST_ASSERT_NOT_NULL(pIdxPre);195 196  InitData d;197  char *zErr = 0;198  init_InitData(&d, gDb, 0, &zErr);199 200  char *argv[5];201  argv[0] = "index";202  argv[1] = "sqlite_autoindex_tidx_1";203  argv[2] = "tidx";204  argv[3] = "42";      /* new rootpage to set */205  argv[4] = "";        /* blank SQL indicates auto-index row */206 207  enterDbMutex(gDb);208  rc = sqlite3InitCallback(&d, 5, argv, NULL);209  leaveDbMutex(gDb);210 211  TEST_ASSERT_EQUAL_INT(0, rc);212  TEST_ASSERT_EQUAL_INT(SQLITE_OK, d.rc);213  TEST_ASSERT_NULL(zErr);214 215  /* Confirm tnum was updated */216  enterDbMutex(gDb);217  Index *pIdxPost = sqlite3FindIndex(gDb, "sqlite_autoindex_tidx_1", "main");218  leaveDbMutex(gDb);219  TEST_ASSERT_NOT_NULL(pIdxPost);220  TEST_ASSERT_EQUAL_INT(42, (int)pIdxPost->tnum);221}222 223/* Test: Orphan index (blank SQL but index not found) triggers corruptSchema */224void test_sqlite3InitCallback_orphan_index_error(void){225  InitData d;226  char *zErr = 0;227  init_InitData(&d, gDb, 0, &zErr);228 229  char *argv[5];230  argv[0] = "index";231  argv[1] = "i_not_exist";232  argv[2] = "some_table";233  argv[3] = "99";234  argv[4] = "";        /* blank SQL => should look for existing index */235 236  enterDbMutex(gDb);237  int rc = sqlite3InitCallback(&d, 5, argv, NULL);238  leaveDbMutex(gDb);239 240  TEST_ASSERT_EQUAL_INT(0, rc);241  TEST_ASSERT_NOT_EQUAL(SQLITE_OK, d.rc);242  TEST_ASSERT_NOT_NULL(zErr);243  TEST_ASSERT_NOT_EQUAL(NULL, strstr(zErr, "orphan index"));244  sqlite3DbFree(gDb, zErr); zErr = 0;245}246 247int main(void) {248  UNITY_BEGIN();249 250  RUN_TEST(test_sqlite3InitCallback_null_argv_returns0);251  RUN_TEST(test_sqlite3InitCallback_create_builds_schema);252  RUN_TEST(test_sqlite3InitCallback_null_rootpage_triggers_corrupt);253  RUN_TEST(test_sqlite3InitCallback_syntax_error_triggers_corrupt);254  RUN_TEST(test_sqlite3InitCallback_noncreate_nonempty_sql_triggers_corrupt);255  RUN_TEST(test_sqlite3InitCallback_autoindex_blank_sql_sets_rootpage);256  RUN_TEST(test_sqlite3InitCallback_orphan_index_error);257 258  return UNITY_END();259}