Only 21 of 86 test_*.c group functions called their own nested UNITY_BEGIN()/UNITY_END(). Each nested call reset Unity's global NumberOfTests/TestFailures counters, so controller_test.c's final `return UNITY_END();` -- the value meson test actually gates on -- only ever reflected whichever small window of tests ran since the LAST nested reset, silently discarding pass/fail evidence for everything before it (measured: 16 of 972 total tests in one run). The same nested-BEGIN calls also caused PASS/FAIL banners to show the wrong source file for tests in files that don't reset it themselves (Unity.TestFile just carries over from whichever group last called UNITY_BEGIN()). Fix: replace every nested UNITY_BEGIN() with UnitySetTestFile(__FILE__) (sets file attribution only, no counter reset) and drop the matching UNITY_END(); add the same UnitySetTestFile(__FILE__) as the first statement to the other group functions that had neither. The 2 genuinely standalone binaries (test_job_array_sched_push.c, test_job_array_apiserver_push.c -- each has its own int main(), not registered via controller_test.c's TEST() macro) are untouched. Verified: single consolidated summary now reads "972 Tests 0 Failures 0 Ignored OK", exactly matching the ground-truth RUN_TEST call-site count across all 83 registered group files (976 total minus 4 belonging to the 2 standalone binaries). Every PASS/FAIL banner now names its own true source file. Full xce-build.sh all regression pass clean (Ok: 9, Fail: 0). No production code touched -- test-harness plumbing only.
133 lines
3.8 KiB
C
133 lines
3.8 KiB
C
#define _GNU_SOURCE
|
|
#include <errno.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <unity/unity.h>
|
|
|
|
#include "snapdiff.h"
|
|
|
|
static char g_dir[256];
|
|
|
|
static void fresh_dir(void)
|
|
{
|
|
strcpy(g_dir, "/tmp/xce_snapdiff_XXXXXX");
|
|
TEST_ASSERT_NOT_NULL(mkdtemp(g_dir));
|
|
}
|
|
|
|
static void cleanup_dir(void)
|
|
{
|
|
char cmd[512];
|
|
snprintf(cmd, sizeof(cmd), "rm -rf %s", g_dir);
|
|
system(cmd);
|
|
}
|
|
|
|
static void write_file(const char* path, size_t size, uint8_t fill,
|
|
size_t flip_at, uint8_t flip_to)
|
|
{
|
|
uint8_t* buf = malloc(size);
|
|
memset(buf, fill, size);
|
|
if (flip_at < size)
|
|
buf[flip_at] = flip_to;
|
|
FILE* fp = fopen(path, "wb");
|
|
TEST_ASSERT_NOT_NULL(fp);
|
|
fwrite(buf, 1, size, fp);
|
|
fclose(fp);
|
|
free(buf);
|
|
}
|
|
|
|
static void test_identical_files(void)
|
|
{
|
|
fresh_dir();
|
|
char p1[512], p2[512];
|
|
snprintf(p1, sizeof(p1), "%s/a.bin", g_dir);
|
|
snprintf(p2, sizeof(p2), "%s/b.bin", g_dir);
|
|
write_file(p1, 1000, 0x42, 2000 /* no flip */, 0);
|
|
write_file(p2, 1000, 0x42, 2000, 0);
|
|
|
|
snapdiff_report_t rep;
|
|
int rc = snapdiff_paths(p1, p2, stdout, &rep);
|
|
TEST_ASSERT_EQUAL_INT(0, rc);
|
|
TEST_ASSERT_EQUAL_INT(1, rep.identical);
|
|
TEST_ASSERT_EQUAL_INT(-1, (int)rep.diff_offset);
|
|
cleanup_dir();
|
|
}
|
|
|
|
static void test_size_mismatch(void)
|
|
{
|
|
fresh_dir();
|
|
char p1[512], p2[512];
|
|
snprintf(p1, sizeof(p1), "%s/a.bin", g_dir);
|
|
snprintf(p2, sizeof(p2), "%s/b.bin", g_dir);
|
|
write_file(p1, 1000, 0x42, 2000, 0);
|
|
write_file(p2, 999, 0x42, 2000, 0);
|
|
|
|
snapdiff_report_t rep;
|
|
int rc = snapdiff_paths(p1, p2, stdout, &rep);
|
|
TEST_ASSERT_EQUAL_INT(1, rc);
|
|
TEST_ASSERT_EQUAL_INT(1, rep.size_mismatch);
|
|
TEST_ASSERT_EQUAL_INT(0, rep.identical);
|
|
cleanup_dir();
|
|
}
|
|
|
|
/* bug-1389 regression shape: two SNAPDIFF_CHUNK_SIZE-sized chunks, content
|
|
* diverges starting at the exact first byte of chunk index 1 — the OPCode_
|
|
* snapshotTransfer chunk-boundary corruption signature. */
|
|
static void test_diff_at_chunk_boundary_is_flagged(void)
|
|
{
|
|
fresh_dir();
|
|
char p1[512], p2[512];
|
|
snprintf(p1, sizeof(p1), "%s/a.bin", g_dir);
|
|
snprintf(p2, sizeof(p2), "%s/b.bin", g_dir);
|
|
size_t size = SNAPDIFF_CHUNK_SIZE * 2;
|
|
write_file(p1, size, 0x11, size, 0);
|
|
write_file(p2, size, 0x11, SNAPDIFF_CHUNK_SIZE /* flip first byte of chunk 1 */,
|
|
0x22);
|
|
|
|
snapdiff_report_t rep;
|
|
int rc = snapdiff_paths(p1, p2, stdout, &rep);
|
|
TEST_ASSERT_EQUAL_INT(1, rc);
|
|
TEST_ASSERT_EQUAL_INT(0, rep.identical);
|
|
TEST_ASSERT_EQUAL_INT(SNAPDIFF_CHUNK_SIZE, (int)rep.diff_offset);
|
|
TEST_ASSERT_EQUAL_INT(1, rep.at_chunk_boundary);
|
|
TEST_ASSERT_EQUAL_INT(1, (int)rep.chunk_index);
|
|
cleanup_dir();
|
|
}
|
|
|
|
static void test_diff_mid_chunk_is_not_flagged_as_boundary(void)
|
|
{
|
|
fresh_dir();
|
|
char p1[512], p2[512];
|
|
snprintf(p1, sizeof(p1), "%s/a.bin", g_dir);
|
|
snprintf(p2, sizeof(p2), "%s/b.bin", g_dir);
|
|
write_file(p1, 1000, 0x11, 2000, 0);
|
|
write_file(p2, 1000, 0x11, 500 /* mid-file, not a chunk boundary */, 0x22);
|
|
|
|
snapdiff_report_t rep;
|
|
int rc = snapdiff_paths(p1, p2, stdout, &rep);
|
|
TEST_ASSERT_EQUAL_INT(1, rc);
|
|
TEST_ASSERT_EQUAL_INT(500, (int)rep.diff_offset);
|
|
TEST_ASSERT_EQUAL_INT(0, rep.at_chunk_boundary);
|
|
cleanup_dir();
|
|
}
|
|
|
|
static void test_missing_path_errors(void)
|
|
{
|
|
snapdiff_report_t rep;
|
|
int rc = snapdiff_paths("/tmp/xce_snapdiff_missing_a_zzz",
|
|
"/tmp/xce_snapdiff_missing_b_zzz", stdout, &rep);
|
|
TEST_ASSERT_LESS_THAN_INT(0, rc);
|
|
}
|
|
|
|
void test_snapdiff(void)
|
|
{
|
|
UnitySetTestFile(__FILE__);
|
|
RUN_TEST(test_identical_files);
|
|
RUN_TEST(test_size_mismatch);
|
|
RUN_TEST(test_diff_at_chunk_boundary_is_flagged);
|
|
RUN_TEST(test_diff_mid_chunk_is_not_flagged_as_boundary);
|
|
RUN_TEST(test_missing_path_errors);
|
|
}
|