Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3HaltConstraint.c152 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Global test fixtures */7static sqlite3 *gDb = NULL;8static Parse gParse;9 10void setUp(void) {11  int rc = sqlite3_open(":memory:", &gDb);12  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);13 14  memset(&gParse, 0, sizeof(gParse));15  gParse.db = gDb;16 17  /* Create a VDBE for this Parse to satisfy the assert in sqlite3HaltConstraint */18  Vdbe *v = sqlite3GetVdbe(&gParse);19  TEST_ASSERT_NOT_NULL(v);20 21  /* Ensure known initial state */22  gParse.mayAbort = 0;23  gParse.nested = 0;24}25 26void tearDown(void) {27  if (gParse.pVdbe) {28    sqlite3VdbeDelete(gParse.pVdbe);29    gParse.pVdbe = NULL;30  }31  if (gDb) {32    sqlite3_close(gDb);33    gDb = NULL;34  }35}36 37/* Helper to fetch the last emitted op */38static VdbeOp* get_last_op(Vdbe *v){39  int addr = sqlite3VdbeCurrentAddr(v) - 1;40  TEST_ASSERT_TRUE(addr >= 0);41  return sqlite3VdbeGetOp(v, addr);42}43 44/* Test: onError==OE_Abort sets mayAbort and emits correct OP_Halt with P4_STATIC */45void test_sqlite3HaltConstraint_sets_mayAbort_on_OE_Abort(void) {46  Vdbe *v = gParse.pVdbe;47  TEST_ASSERT_NOT_NULL(v);48 49  char *msg = "constraint abort";50  int errCode = SQLITE_CONSTRAINT; /* low byte is SQLITE_CONSTRAINT */51  int onError = OE_Abort;52  u8 p5 = 55;53 54  sqlite3HaltConstraint(&gParse, errCode, onError, msg, P4_STATIC, p5);55 56  /* mayAbort should be set by sqlite3MayAbort */57  TEST_ASSERT_EQUAL_INT(1, gParse.mayAbort);58 59  /* Validate the last VDBE op */60  VdbeOp *op = get_last_op(v);61  TEST_ASSERT_NOT_NULL(op);62  TEST_ASSERT_EQUAL_UINT8(OP_Halt, op->opcode);63 64  TEST_ASSERT_EQUAL_INT(errCode, op->p1);65  TEST_ASSERT_EQUAL_INT(onError, op->p2);66  TEST_ASSERT_EQUAL_INT(0, op->p3);67 68  /* P4 should be the same pointer for P4_STATIC and content should match */69  TEST_ASSERT_EQUAL_INT(P4_STATIC, op->p4type);70  TEST_ASSERT_EQUAL_PTR(msg, op->p4.z);71  TEST_ASSERT_EQUAL_INT(0, strcmp(op->p4.z, msg));72 73  /* P5 set via sqlite3VdbeChangeP5 */74  TEST_ASSERT_EQUAL_UINT8(p5, op->p5);75}76 77/* Test: onError!=OE_Abort does not set mayAbort; P4_TRANSIENT copied and tagged as P4_DYNAMIC */78void test_sqlite3HaltConstraint_no_mayAbort_when_not_OE_Abort_and_transient_p4(void) {79  Vdbe *v = gParse.pVdbe;80  TEST_ASSERT_NOT_NULL(v);81 82  const char *msgConst = "transient message";83  int errCode = SQLITE_CONSTRAINT;84  int onError = OE_Fail;85  u8 p5 = 123;86 87  /* Ensure mayAbort starts clear */88  gParse.mayAbort = 0;89 90  sqlite3HaltConstraint(&gParse, errCode, onError, (char*)msgConst, P4_TRANSIENT, p5);91 92  /* mayAbort should remain 0 */93  TEST_ASSERT_EQUAL_INT(0, gParse.mayAbort);94 95  /* Validate the last VDBE op */96  VdbeOp *op = get_last_op(v);97  TEST_ASSERT_NOT_NULL(op);98  TEST_ASSERT_EQUAL_UINT8(OP_Halt, op->opcode);99 100  TEST_ASSERT_EQUAL_INT(errCode, op->p1);101  TEST_ASSERT_EQUAL_INT(onError, op->p2);102  TEST_ASSERT_EQUAL_INT(0, op->p3);103 104  /* P4 should have been copied; tagged as P4_DYNAMIC, content equal */105  TEST_ASSERT_EQUAL_INT(P4_DYNAMIC, op->p4type);106  TEST_ASSERT_NOT_NULL(op->p4.z);107  TEST_ASSERT_EQUAL_INT(0, strcmp(op->p4.z, msgConst));108 109  TEST_ASSERT_EQUAL_UINT8(p5, op->p5);110}111 112/* Test: In a nested parse, non-CONSTRAINT errCode is allowed by assert and still emits OP_Halt */113void test_sqlite3HaltConstraint_nested_allows_non_constraint_errcode(void) {114  Vdbe *v = gParse.pVdbe;115  TEST_ASSERT_NOT_NULL(v);116 117  gParse.nested = 1;    /* Satisfy the internal assert path */118  gParse.mayAbort = 0;  /* Start clear */119 120  const char *msg = "nested halt";121  int errCode = SQLITE_ERROR; /* low byte != SQLITE_CONSTRAINT */122  int onError = OE_Abort;     /* should set mayAbort */123  u8 p5 = 201;124 125  sqlite3HaltConstraint(&gParse, errCode, onError, (char*)msg, P4_STATIC, p5);126 127  /* mayAbort should be set due to OE_Abort, even in nested mode */128  TEST_ASSERT_EQUAL_INT(1, gParse.mayAbort);129 130  /* Validate the last VDBE op */131  VdbeOp *op = get_last_op(v);132  TEST_ASSERT_NOT_NULL(op);133  TEST_ASSERT_EQUAL_UINT8(OP_Halt, op->opcode);134 135  TEST_ASSERT_EQUAL_INT(errCode, op->p1);136  TEST_ASSERT_EQUAL_INT(onError, op->p2);137  TEST_ASSERT_EQUAL_INT(0, op->p3);138 139  TEST_ASSERT_EQUAL_INT(P4_STATIC, op->p4type);140  TEST_ASSERT_EQUAL_PTR(msg, op->p4.z);141  TEST_ASSERT_EQUAL_INT(0, strcmp(op->p4.z, msg));142 143  TEST_ASSERT_EQUAL_UINT8(p5, op->p5);144}145 146int main(void) {147  UNITY_BEGIN();148  RUN_TEST(test_sqlite3HaltConstraint_sets_mayAbort_on_OE_Abort);149  RUN_TEST(test_sqlite3HaltConstraint_no_mayAbort_when_not_OE_Abort_and_transient_p4);150  RUN_TEST(test_sqlite3HaltConstraint_nested_allows_non_constraint_errcode);151  return UNITY_END();152}