feat(xce-harness-component): relocate xce_test into standalone harness component

Move xce_test's 15 production sources + headers from src/controller/testsuite/
into a new src/harness/ component with its own meson.build, and strip every
now-dangling controller-side reference (11 controller_unit_test_src entries,
4 standalone test-binary blocks, 11 controller_test.c extern/RUN_TEST lines)
so the controller build is never left broken.

Fixes a broken relative-symlink bridge (xce_test_controller_link) added to
keep two controller-embedded tests (test_test_cli.c, test_xcetest_process_entry.c)
finding the relocated xce_test binary until task 2.1 moves them too.

Discovered and documented in design.md: four controller-domain regression
tests call functions directly from four of xce_test's own files, requiring
controller_unit_test to permanently recompile them from src/harness/ — a
real dependency neither the original discovery nor design audit caught.

controller_unit_test: 1228 Tests 0 Failures 0 Ignored (verified via the
Unity binary's own printed summary line, not just meson's aggregate count).

Task 1.1 of xce-harness-component.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
Rongsong Shen 2026-09-14 05:08:15 +00:00
parent b8ef82c1b2
commit cf55d691de
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
36 changed files with 550 additions and 180 deletions

View file

@ -1,99 +0,0 @@
/* joblist_display.c -- xce-test-cli-ux task 2.5 remediation (bug-1711 fixes)
*
* See joblist_display.h for the full rationale. Verbatim extraction of
* test.c's worker_status_str()/job_state_str()/format_job_time() -- no
* behavior change from the pre-extraction versions.
*/
#include "joblist_display.h"
#include <stdio.h> /* snprintf */
#include "ctrlstatus_fmt.h" /* ctrlstatus_format_time_ms */
#include "xce/types.h" /* XCE_WORKER_*, JOB_STAT_* bit definitions */
char* worker_status_str(uint32_t status)
{
/* Admin-set CLOSED takes priority over the dynamic UNAVAIL bit: the
* config-upgrade-snapshot soak (task 8.6) needs to assert a host's
* administratively-set status specifically, and a host closed via
* hostctrl that later disconnects (e.g. its xce_test `worker`/`join`
* connection exits after the script ends) would otherwise print only
* "UNAVAIL", masking the admin bit this check exists to verify. */
if ((status & XCE_WORKER_CLOSED) != 0) {
return "CLOSED";
} else if ((status & XCE_WORKER_UNAVAIL) != 0) {
return "UNAVAIL";
} else if ((status & XCE_WORKER_LOCKEDU) != 0) {
return "LOCKU";
} else if ((status & XCE_WORKER_LOCKEDW) != 0) {
return "LOCKW";
} else if ((status & XCE_WORKER_BUSY) != 0) {
return "BUSY";
} else if (status == 0) {
return "OK";
}
return "UNKNOWN";
}
char* job_state_str(int state)
{
/* bug-1711 (Requirement 11.7): raw-state fallback mirroring
* print_jobinfo's existing state_raw guard against the same ambiguity
* (see print_jobinfo's comment above its "state_raw: 0x%x" print) -- a
* job that is simultaneously RUN and EXIT (e.g. a worker-reported FAIL
* received without a prior FINISH; apply_job_fail_transition ORs in
* EXIT|PERR without clearing RUN) would otherwise silently print as
* plain "RUN" via the if/else-if priority ordering below, hiding the
* EXIT bit. Unlike print_jobinfo (which always has room for a separate
* state_raw line), job_state_str's result is a single cmd_joblist table
* cell, so the raw state is folded into the same string only for this
* specific ambiguous case. */
static char ambiguous_buf[32];
if ((state & JOB_STAT_PEND) != 0) {
if ((state & JOB_STAT_PSUSP) != 0) {
return "PSUSP";
}
return "PEND";
} else if ((state & JOB_STAT_RUN) != 0) {
if ((state & JOB_STAT_USUSP) != 0) {
return "USUSP";
} else if ((state & JOB_STAT_SSUSP) != 0) {
return "SSUSP";
} else if ((state & JOB_STAT_EXIT) != 0) {
snprintf(ambiguous_buf, sizeof(ambiguous_buf), "RUN(0x%x)", state);
return ambiguous_buf;
}
return "RUN";
} else if ((state & JOB_STAT_EXIT) != 0) {
return "EXIT";
} else if ((state & JOB_STAT_DONE) != 0) {
return "DONE";
} else if ((state & JOB_STAT_ERR) != 0) {
return "ERROR";
}
return "UNKNOWN";
}
/* bug-1711 (Requirement 11.5): format a job time_t field (epoch seconds) using
* ctrlstatus_fmt.h's ctrlstatus_format_time_ms human-readable formatter
* (which takes epoch milliseconds), instead of printing the raw epoch-seconds
* value directly as cmd_joblist did before. A job time of 0 means the
* corresponding event has not happened yet (e.g. an unstarted job's
* start_time/finish_time) -- print "-" rather than a misleading 1970-01-01
* epoch date. */
const char* format_job_time(time_t t, char* buf, size_t bufsize)
{
if (t == 0) {
return "-";
}
if (ctrlstatus_format_time_ms((uint64_t)t * 1000u, buf, bufsize) == NULL) {
return "-";
}
return buf;
}