AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <limits.h>6 7/* Wrapper for the static function provided by the module for testing. */8extern int test_sampleIsBetterPost(StatAccum *pAccum, StatSample *pNew, StatSample *pOld);9 10void setUp(void) {11 /* Setup code here, or leave empty */12}13 14void tearDown(void) {15 /* Cleanup code here, or leave empty */16}17 18/* Helper to zero-init samples and set common fields */19static void initSamples(StatAccum *pAcc, StatSample *pNew, StatSample *pOld,20 int nCol, int iCol, unsigned int newHash, unsigned int oldHash){21 memset(pAcc, 0, sizeof(*pAcc));22 memset(pNew, 0, sizeof(*pNew));23 memset(pOld, 0, sizeof(*pOld));24 pAcc->nCol = nCol;25 pNew->iCol = iCol;26 pOld->iCol = iCol;27 pNew->iHash = newHash;28 pOld->iHash = oldHash;29}30 31/* 1) Prefer due to greater value at the first trailing anEq column */32void test_sampleIsBetterPost_prefers_on_first_trailing_anEq(void) {33 StatAccum acc;34 StatSample sNew, sOld;35 int nCol = 5, iCol = 1;36 37 initSamples(&acc, &sNew, &sOld, nCol, iCol, 10, 999); /* hashes shouldn't matter here */38 39 /* Fill preceding and equal trailing up to the point of difference */40 for(int i=0; i<nCol; i++){ sNew.anEq[i] = 100; sOld.anEq[i] = 100; }41 /* First trailing index is iCol+1 == 2 */42 sNew.anEq[2] = 200; /* greater than old */43 sOld.anEq[2] = 150;44 45 int rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);46 TEST_ASSERT_EQUAL_INT(1, rc);47}48 49/* 2) Reject due to lesser value at the first trailing anEq column, even if hash is larger */50void test_sampleIsBetterPost_rejects_on_first_trailing_anEq_even_if_hash_larger(void) {51 StatAccum acc;52 StatSample sNew, sOld;53 int nCol = 4, iCol = 1;54 55 initSamples(&acc, &sNew, &sOld, nCol, iCol, 10000, 1); /* new hash larger, but should be ignored */56 57 for(int i=0; i<nCol; i++){ sNew.anEq[i] = 50; sOld.anEq[i] = 50; }58 sNew.anEq[2] = 20; /* less than old */59 sOld.anEq[2] = 30;60 61 int rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);62 TEST_ASSERT_EQUAL_INT(0, rc);63}64 65/* 3) Prefer due to a later trailing column when earlier trailing columns are equal */66void test_sampleIsBetterPost_prefers_on_later_trailing_anEq(void) {67 StatAccum acc;68 StatSample sNew, sOld;69 int nCol = 5, iCol = 1;70 71 initSamples(&acc, &sNew, &sOld, nCol, iCol, 5, 6);72 73 for(int i=0; i<nCol; i++){ sNew.anEq[i] = 1000; sOld.anEq[i] = 1000; }74 /* First trailing (2) equal, second trailing (3) equal, third trailing (4) differs */75 sNew.anEq[4] = 1235;76 sOld.anEq[4] = 1234;77 78 int rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);79 TEST_ASSERT_EQUAL_INT(1, rc);80}81 82/* 4) All trailing equal; decide by hash: new hash greater => prefer */83void test_sampleIsBetterPost_tie_trailing_prefers_on_hash_greater(void) {84 StatAccum acc;85 StatSample sNew, sOld;86 int nCol = 3, iCol = 1;87 88 initSamples(&acc, &sNew, &sOld, nCol, iCol, 100, 99);89 90 for(int i=0; i<nCol; i++){ sNew.anEq[i] = 77; sOld.anEq[i] = 77; }91 92 int rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);93 TEST_ASSERT_EQUAL_INT(1, rc);94}95 96/* 5) All trailing equal; decide by hash: new hash smaller => do not prefer */97void test_sampleIsBetterPost_tie_trailing_rejects_on_hash_smaller(void) {98 StatAccum acc;99 StatSample sNew, sOld;100 int nCol = 4, iCol = 2;101 102 initSamples(&acc, &sNew, &sOld, nCol, iCol, 7, 8);103 104 for(int i=0; i<nCol; i++){ sNew.anEq[i] = 5; sOld.anEq[i] = 5; }105 106 int rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);107 TEST_ASSERT_EQUAL_INT(0, rc);108}109 110/* 6) No trailing columns (iCol+1 == nCol): decision based solely on hash */111void test_sampleIsBetterPost_no_trailing_columns_uses_hash_only(void) {112 StatAccum acc;113 StatSample sNew, sOld;114 int nCol = 2, iCol = 1; /* iCol+1 == nCol => no loop */115 116 initSamples(&acc, &sNew, &sOld, nCol, iCol, 42, 1);117 118 /* anEq contents shouldn't matter; set some values anyway */119 sNew.anEq[0] = 10; sNew.anEq[1] = 10;120 sOld.anEq[0] = 20; sOld.anEq[1] = 20;121 122 int rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);123 TEST_ASSERT_EQUAL_INT(1, rc);124 125 /* Equal hash => do not prefer */126 initSamples(&acc, &sNew, &sOld, nCol, iCol, 1000, 1000);127 sNew.anEq[0] = 1; sNew.anEq[1] = 1;128 sOld.anEq[0] = 2; sOld.anEq[1] = 2;129 130 rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);131 TEST_ASSERT_EQUAL_INT(0, rc);132}133 134/* 7) Preceding columns are ignored */135void test_sampleIsBetterPost_ignores_preceding_columns(void) {136 StatAccum acc;137 StatSample sNew, sOld;138 int nCol = 4, iCol = 2; /* trailing indices: 3 only */139 140 initSamples(&acc, &sNew, &sOld, nCol, iCol, 500, 500); /* equal hash => final tiebreaker 0 */141 142 for(int i=0; i<nCol; i++){ sNew.anEq[i] = 0; sOld.anEq[i] = 0; }143 /* Make preceding columns (<= iCol) differ wildly */144 sNew.anEq[0] = 99999; sOld.anEq[0] = 1;145 sNew.anEq[1] = 88888; sOld.anEq[1] = 2;146 sNew.anEq[2] = 77777; sOld.anEq[2] = 3;147 /* Trailing column equal */148 sNew.anEq[3] = 123;149 sOld.anEq[3] = 123;150 151 int rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);152 TEST_ASSERT_EQUAL_INT(0, rc);153}154 155/* 8) Large values near integer limits to ensure relational comparisons work */156void test_sampleIsBetterPost_handles_large_values(void) {157 StatAccum acc;158 StatSample sNew, sOld;159 int nCol = 5, iCol = 1;160 161 initSamples(&acc, &sNew, &sOld, nCol, iCol, 0U, 0U);162 163 for(int i=0; i<nCol; i++){ sNew.anEq[i] = 0; sOld.anEq[i] = 0; }164 /* Make a later trailing column differ with large values */165 sNew.anEq[4] = (tRowcnt)INT_MAX; /* use max 32-bit int cast to tRowcnt */166 sOld.anEq[4] = (tRowcnt)INT_MAX - 1;167 168 int rc = test_sampleIsBetterPost(&acc, &sNew, &sOld);169 TEST_ASSERT_EQUAL_INT(1, rc);170}171 172int main(void) {173 UNITY_BEGIN();174 RUN_TEST(test_sampleIsBetterPost_prefers_on_first_trailing_anEq);175 RUN_TEST(test_sampleIsBetterPost_rejects_on_first_trailing_anEq_even_if_hash_larger);176 RUN_TEST(test_sampleIsBetterPost_prefers_on_later_trailing_anEq);177 RUN_TEST(test_sampleIsBetterPost_tie_trailing_prefers_on_hash_greater);178 RUN_TEST(test_sampleIsBetterPost_tie_trailing_rejects_on_hash_smaller);179 RUN_TEST(test_sampleIsBetterPost_no_trailing_columns_uses_hash_only);180 RUN_TEST(test_sampleIsBetterPost_ignores_preceding_columns);181 RUN_TEST(test_sampleIsBetterPost_handles_large_values);182 return UNITY_END();183}