/* test_job_dispatch_fail_count.c — scheduler-dispatch-commit task 1.3 * * Proves job_t.dispatch_fail_count (xce/types.h) -- a new in-memory-only * uint32_t counter on the job_t wrapper ({xce_job_t job; uint64_t * submit_lsn;}), NOT on xce_job_t itself -- exists and behaves as a plain, * directly settable/readable/resettable scalar (Requirement 4.3, design.md * "Logical Data Model": "in-memory only... following submit_lsn's exact * precedent... recomputed... never serialized"). * * This task is the data-model addition ONLY. It does NOT wire any * increment/reset call site into dispatch_a_job_() (task 3.1/3.3's job) and * does NOT implement the bounded-retry threshold check (also task 3.3). * Every test here manipulates the field directly on a bare stack-local * job_t -- no jobmgr/RTTI/makeJob machinery -- mirroring * test_persist_types.c's test_slot_key_t_fields precedent for a plain * struct-field addition, since this is not a behavioral/dispatch-path test. */ #include #include #include #include #include "xce/types.h" static void test_dispatch_fail_count_default_zero(void) { job_t j; memset(&j, 0, sizeof(j)); TEST_ASSERT_EQUAL_UINT32(0, j.dispatch_fail_count); printf("test_dispatch_fail_count_default_zero: PASS\n"); } static void test_dispatch_fail_count_increments_independently(void) { job_t j; memset(&j, 0, sizeof(j)); /* Simulates 3 consecutive retryable dispatch failures with no * intervening successful dispatch (Requirement 4.3) -- incremented * directly, with no actual dispatch attempt involved. */ j.dispatch_fail_count++; TEST_ASSERT_EQUAL_UINT32(1, j.dispatch_fail_count); j.dispatch_fail_count++; j.dispatch_fail_count++; TEST_ASSERT_EQUAL_UINT32_MESSAGE(3, j.dispatch_fail_count, "counter must be incrementable directly, independent of any actual " "dispatch attempt (Observable completion)"); printf("test_dispatch_fail_count_increments_independently: PASS\n"); } static void test_dispatch_fail_count_resets_to_zero(void) { job_t j; memset(&j, 0, sizeof(j)); j.dispatch_fail_count = 7; TEST_ASSERT_EQUAL_UINT32(7, j.dispatch_fail_count); /* A successful dispatch resets the counter to zero -- task 3.1/3.3 wire * the real call site; this proves the field itself supports the * reset-to-zero operation the design requires, independent of any * actual dispatch attempt. */ j.dispatch_fail_count = 0; TEST_ASSERT_EQUAL_UINT32_MESSAGE(0, j.dispatch_fail_count, "counter must be independently resettable to zero, matching " "submit_lsn's in-memory-only precedent (no durability obligation, " "safe to lose across a controller failover)"); printf("test_dispatch_fail_count_resets_to_zero: PASS\n"); } static void test_dispatch_fail_count_does_not_alias_submit_lsn(void) { job_t j; memset(&j, 0, sizeof(j)); j.submit_lsn = 12345; j.dispatch_fail_count = 6; TEST_ASSERT_EQUAL_UINT64(12345, j.submit_lsn); TEST_ASSERT_EQUAL_UINT32_MESSAGE(6, j.dispatch_fail_count, "dispatch_fail_count must be its own field on job_t, distinct from " "submit_lsn (both in-memory-only siblings on the wrapper struct)"); printf("test_dispatch_fail_count_does_not_alias_submit_lsn: PASS\n"); } void test_job_dispatch_fail_count(void) { UnitySetTestFile(__FILE__); printf("\n>> job_t.dispatch_fail_count test\n\n"); RUN_TEST(test_dispatch_fail_count_default_zero); RUN_TEST(test_dispatch_fail_count_increments_independently); RUN_TEST(test_dispatch_fail_count_resets_to_zero); RUN_TEST(test_dispatch_fail_count_does_not_alias_submit_lsn); }