Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_backup_sqlite3_backup_finish.c131 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Unity setup/teardown */7void setUp(void) {8  /* No-op */9}10void tearDown(void) {11  /* No-op */12}13 14/* Helper: execute SQL and assert SQLITE_OK */15static void exec_ok(sqlite3 *db, const char *sql){16  char *errmsg = NULL;17  int rc = sqlite3_exec(db, sql, 0, 0, &errmsg);18  if( rc!=SQLITE_OK ){19    const char *em = errmsg ? errmsg : "(null)";20    /* Provide context if it fails */21    TEST_FAIL_MESSAGE(em);22  }23  sqlite3_free(errmsg);24}25 26/* Helper: prepare a statement, step once, return int result (column 0) */27static int query_int(sqlite3 *db, const char *sql){28  sqlite3_stmt *stmt = NULL;29  int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);30  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "prepare failed");31  rc = sqlite3_step(stmt);32  TEST_ASSERT_TRUE_MESSAGE(rc==SQLITE_ROW || rc==SQLITE_DONE, "step not ROW/DONE");33  int v = (rc==SQLITE_ROW) ? sqlite3_column_int(stmt, 0) : 0;34  sqlite3_finalize(stmt);35  return v;36}37 38/* Test 1: NULL pointer returns SQLITE_OK */39void test_sqlite3_backup_finish_null_returns_ok(void){40  int rc = sqlite3_backup_finish(NULL);41  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);42}43 44/* Test 2: finish immediately after init without stepping returns OK and dest usable */45void test_sqlite3_backup_finish_without_stepping(void){46  sqlite3 *src = NULL, *dst = NULL;47  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &src));48  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &dst));49 50  sqlite3_backup *b = sqlite3_backup_init(dst, "main", src, "main");51  TEST_ASSERT_NOT_NULL(b);52 53  int rc_finish = sqlite3_backup_finish(b);54  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc_finish);55  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_errcode(dst));56 57  /* Dest should be usable after finish (no lingering locks/transactions) */58  exec_ok(dst, "CREATE TABLE t_dest(x); INSERT INTO t_dest VALUES(1);");59  int cnt = query_int(dst, "SELECT COUNT(*) FROM t_dest;");60  TEST_ASSERT_EQUAL_INT(1, cnt);61 62  sqlite3_close(dst);63  sqlite3_close(src);64}65 66/* Test 3: If step hits SQLITE_BUSY (src in write txn), finish returns SQLITE_BUSY and sets dest errcode */67void test_sqlite3_backup_finish_propagates_busy_error(void){68  sqlite3 *src = NULL, *dst = NULL;69  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &src));70  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &dst));71 72  /* Put source into a write transaction so backup_step will see TRANS_WRITE */73  exec_ok(src, "BEGIN IMMEDIATE;");74 75  sqlite3_backup *b = sqlite3_backup_init(dst, "main", src, "main");76  TEST_ASSERT_NOT_NULL(b);77 78  /* Attempt a step - should return SQLITE_BUSY due to src write txn */79  int rc_step = sqlite3_backup_step(b, 1);80  TEST_ASSERT_EQUAL_INT(SQLITE_BUSY, rc_step);81 82  /* Now finish - should return SQLITE_BUSY and set dest error code */83  int rc_finish = sqlite3_backup_finish(b);84  TEST_ASSERT_EQUAL_INT(SQLITE_BUSY, rc_finish);85  TEST_ASSERT_EQUAL_INT(SQLITE_BUSY, sqlite3_errcode(dst));86 87  /* Cleanup src transaction */88  exec_ok(src, "ROLLBACK;");89 90  sqlite3_close(dst);91  sqlite3_close(src);92}93 94/* Test 4: After a complete backup (DONE), finish returns SQLITE_OK and dest contains copied data */95void test_sqlite3_backup_finish_after_done_returns_ok_and_data_copied(void){96  sqlite3 *src = NULL, *dst = NULL;97  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &src));98  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &dst));99 100  /* Populate source */101  exec_ok(src, "CREATE TABLE t(a);"102               "INSERT INTO t VALUES(1),(2),(3);");103 104  sqlite3_backup *b = sqlite3_backup_init(dst, "main", src, "main");105  TEST_ASSERT_NOT_NULL(b);106 107  /* Copy all pages in one call */108  int rc_step = sqlite3_backup_step(b, -1);109  TEST_ASSERT_EQUAL_INT(SQLITE_DONE, rc_step);110 111  /* Finish should map SQLITE_DONE -> SQLITE_OK */112  int rc_finish = sqlite3_backup_finish(b);113  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc_finish);114  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_errcode(dst));115 116  /* Verify data exists in destination */117  int cnt_dst = query_int(dst, "SELECT COUNT(*) FROM t;");118  TEST_ASSERT_EQUAL_INT(3, cnt_dst);119 120  sqlite3_close(dst);121  sqlite3_close(src);122}123 124int main(void){125  UNITY_BEGIN();126  RUN_TEST(test_sqlite3_backup_finish_null_returns_ok);127  RUN_TEST(test_sqlite3_backup_finish_without_stepping);128  RUN_TEST(test_sqlite3_backup_finish_propagates_busy_error);129  RUN_TEST(test_sqlite3_backup_finish_after_done_returns_ok_and_data_copied);130  return UNITY_END();131}