Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_main_sqlite3InvokeBusyHandler.c232 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <stdio.h>6 7/* Forward declaration of the function under test (ensure prototype is visible) */8extern int sqlite3InvokeBusyHandler(BusyHandler *p);9 10/* Globals to observe handler behavior */11static void *g_lastArg = NULL;12static int g_lastCount = -1;13static int g_callCount = 0;14 15/* Return sequence configuration for the test handler */16#define RET_SEQ_MAX 1617static int g_returnSequence[RET_SEQ_MAX];18static int g_returnSeqLen = 0;19static int g_returnSeqIndex = 0;20 21/* Test busy handler: records calls and returns configured values */22static int seqBusyHandler(void *arg, int n){23  g_callCount++;24  g_lastArg = arg;25  g_lastCount = n;26 27  if( g_returnSeqLen > 0 ){28    int idx = g_returnSeqIndex < g_returnSeqLen ? g_returnSeqIndex : (g_returnSeqLen - 1);29    int ret = g_returnSequence[idx];30    if( g_returnSeqIndex < g_returnSeqLen ) g_returnSeqIndex++;31    return ret;32  }33  /* Default behavior if no sequence configured: return non-zero (retry) */34  return 1;35}36 37/* Helper to configure the return sequence (does not reset call counters) */38static void handler_set_sequence(const int *vals, int len){39  if( len < 0 ) len = 0;40  if( len > RET_SEQ_MAX ) len = RET_SEQ_MAX;41  memset(g_returnSequence, 0, sizeof(g_returnSequence));42  if( vals && len > 0 ){43    memcpy(g_returnSequence, vals, sizeof(int)*len);44  }45  g_returnSeqLen = len;46  g_returnSeqIndex = 0;47}48 49void setUp(void) {50  g_lastArg = NULL;51  g_lastCount = -1;52  g_callCount = 0;53  memset(g_returnSequence, 0, sizeof(g_returnSequence));54  g_returnSeqLen = 0;55  g_returnSeqIndex = 0;56}57 58void tearDown(void) {59  /* Nothing to cleanup */60}61 62/* Test: xBusyHandler is NULL -> early return 0, nBusy unchanged, no call */63void test_sqlite3InvokeBusyHandler_null_handler_returns0_and_does_not_change_nBusy(void) {64  BusyHandler bh;65  memset(&bh, 0, sizeof(bh));66  bh.xBusyHandler = 0;67  bh.pBusyArg = &bh;68  bh.nBusy = 5;69 70  int rc = sqlite3InvokeBusyHandler(&bh);71  TEST_ASSERT_EQUAL_INT(0, rc);72  TEST_ASSERT_EQUAL_INT(5, bh.nBusy);73  TEST_ASSERT_EQUAL_INT(0, g_callCount);74}75 76/* Test: nBusy < 0 -> early return 0, handler not called, nBusy unchanged */77void test_sqlite3InvokeBusyHandler_negative_nBusy_early_return(void) {78  BusyHandler bh;79  memset(&bh, 0, sizeof(bh));80  bh.xBusyHandler = seqBusyHandler;81  bh.pBusyArg = &bh;82  bh.nBusy = -3;83 84  int rc = sqlite3InvokeBusyHandler(&bh);85  TEST_ASSERT_EQUAL_INT(0, rc);86  TEST_ASSERT_EQUAL_INT(-3, bh.nBusy);87  TEST_ASSERT_EQUAL_INT(0, g_callCount);88}89 90/* Test: handler returns 0 -> nBusy set to -1 and function returns 0 */91void test_sqlite3InvokeBusyHandler_handler_returns0_sets_nBusy_minus1(void) {92  BusyHandler bh;93  memset(&bh, 0, sizeof(bh));94  bh.xBusyHandler = seqBusyHandler;95  bh.pBusyArg = &bh;96  bh.nBusy = 0;97 98  int seq[] = {0};99  handler_set_sequence(seq, 1);100 101  int rc = sqlite3InvokeBusyHandler(&bh);102  TEST_ASSERT_EQUAL_INT(0, rc);103  TEST_ASSERT_EQUAL_INT(-1, bh.nBusy);104  TEST_ASSERT_EQUAL_INT(1, g_callCount);105  TEST_ASSERT_EQUAL_PTR(&bh, g_lastArg);106  TEST_ASSERT_EQUAL_INT(0, g_lastCount);107}108 109/* Test: handler returns non-zero -> nBusy increments and return value is propagated */110void test_sqlite3InvokeBusyHandler_handler_returns_nonzero_increments_and_returns_value(void) {111  BusyHandler bh;112  memset(&bh, 0, sizeof(bh));113  bh.xBusyHandler = seqBusyHandler;114  bh.pBusyArg = &bh;115  bh.nBusy = 2;116 117  int seq[] = {7};118  handler_set_sequence(seq, 1);119 120  int rc = sqlite3InvokeBusyHandler(&bh);121  TEST_ASSERT_EQUAL_INT(7, rc);122  TEST_ASSERT_EQUAL_INT(3, bh.nBusy); /* incremented from 2 to 3 */123  TEST_ASSERT_EQUAL_INT(1, g_callCount);124  TEST_ASSERT_EQUAL_PTR(&bh, g_lastArg);125  TEST_ASSERT_EQUAL_INT(2, g_lastCount);126}127 128/* Test: multiple invocations with non-zero returns increment nBusy and pass correct counts */129void test_sqlite3InvokeBusyHandler_multiple_retries_increment_nBusy_correctly(void) {130  BusyHandler bh;131  memset(&bh, 0, sizeof(bh));132  bh.xBusyHandler = seqBusyHandler;133  bh.pBusyArg = &bh;134  bh.nBusy = 4;135 136  int seq[] = {1,1,1};137  handler_set_sequence(seq, 3);138 139  int rc;140 141  rc = sqlite3InvokeBusyHandler(&bh);142  TEST_ASSERT_EQUAL_INT(1, rc);143  TEST_ASSERT_EQUAL_INT(5, bh.nBusy);144  TEST_ASSERT_EQUAL_INT(4, g_lastCount);145 146  rc = sqlite3InvokeBusyHandler(&bh);147  TEST_ASSERT_EQUAL_INT(1, rc);148  TEST_ASSERT_EQUAL_INT(6, bh.nBusy);149  TEST_ASSERT_EQUAL_INT(5, g_lastCount);150 151  rc = sqlite3InvokeBusyHandler(&bh);152  TEST_ASSERT_EQUAL_INT(1, rc);153  TEST_ASSERT_EQUAL_INT(7, bh.nBusy);154  TEST_ASSERT_EQUAL_INT(6, g_lastCount);155 156  TEST_ASSERT_EQUAL_INT(3, g_callCount);157}158 159/* Test: after a 0 return sets nBusy to -1, subsequent calls do not invoke handler and return 0 */160void test_sqlite3InvokeBusyHandler_after_zero_return_no_more_calls(void) {161  BusyHandler bh;162  memset(&bh, 0, sizeof(bh));163  bh.xBusyHandler = seqBusyHandler;164  bh.pBusyArg = &bh;165  bh.nBusy = 1;166 167  int seq0[] = {0};168  handler_set_sequence(seq0, 1);169 170  int rc = sqlite3InvokeBusyHandler(&bh);171  TEST_ASSERT_EQUAL_INT(0, rc);172  TEST_ASSERT_EQUAL_INT(-1, bh.nBusy);173  TEST_ASSERT_EQUAL_INT(1, g_callCount);174 175  /* Change the sequence; the handler should not be called again due to nBusy < 0 */176  int seq1[] = {1};177  handler_set_sequence(seq1, 1);178 179  rc = sqlite3InvokeBusyHandler(&bh);180  TEST_ASSERT_EQUAL_INT(0, rc);181  TEST_ASSERT_EQUAL_INT(-1, bh.nBusy);182  TEST_ASSERT_EQUAL_INT(1, g_callCount); /* still 1, no additional calls */183}184 185/* Test: verify pBusyArg and initial nBusy are passed to the handler correctly */186void test_sqlite3InvokeBusyHandler_handler_receives_correct_arguments(void) {187  BusyHandler bh;188  memset(&bh, 0, sizeof(bh));189  bh.xBusyHandler = seqBusyHandler;190  bh.pBusyArg = (void*)&bh; /* sentinel */191  bh.nBusy = 0;192 193  int seq[] = {1};194  handler_set_sequence(seq, 1);195 196  int rc = sqlite3InvokeBusyHandler(&bh);197  TEST_ASSERT_EQUAL_INT(1, rc);198  TEST_ASSERT_EQUAL_PTR(&bh, g_lastArg);199  TEST_ASSERT_EQUAL_INT(0, g_lastCount);200  TEST_ASSERT_EQUAL_INT(1, bh.nBusy); /* incremented after non-zero return */201}202 203/* Optional: handler returns 0 regardless of initial nBusy > 0: nBusy becomes -1 */204void test_sqlite3InvokeBusyHandler_zero_return_from_nonzero_initial_nBusy_sets_minus1(void) {205  BusyHandler bh;206  memset(&bh, 0, sizeof(bh));207  bh.xBusyHandler = seqBusyHandler;208  bh.pBusyArg = &bh;209  bh.nBusy = 10;210 211  int seq[] = {0};212  handler_set_sequence(seq, 1);213 214  int rc = sqlite3InvokeBusyHandler(&bh);215  TEST_ASSERT_EQUAL_INT(0, rc);216  TEST_ASSERT_EQUAL_INT(-1, bh.nBusy);217  TEST_ASSERT_EQUAL_INT(1, g_callCount);218  TEST_ASSERT_EQUAL_INT(10, g_lastCount);219}220 221int main(void) {222  UNITY_BEGIN();223  RUN_TEST(test_sqlite3InvokeBusyHandler_null_handler_returns0_and_does_not_change_nBusy);224  RUN_TEST(test_sqlite3InvokeBusyHandler_negative_nBusy_early_return);225  RUN_TEST(test_sqlite3InvokeBusyHandler_handler_returns0_sets_nBusy_minus1);226  RUN_TEST(test_sqlite3InvokeBusyHandler_handler_returns_nonzero_increments_and_returns_value);227  RUN_TEST(test_sqlite3InvokeBusyHandler_multiple_retries_increment_nBusy_correctly);228  RUN_TEST(test_sqlite3InvokeBusyHandler_after_zero_return_no_more_calls);229  RUN_TEST(test_sqlite3InvokeBusyHandler_handler_receives_correct_arguments);230  RUN_TEST(test_sqlite3InvokeBusyHandler_zero_return_from_nonzero_initial_nBusy_sets_minus1);231  return UNITY_END();232}