Task 1.7: xce_decision_t gains a trace pointer (NULL from every existing constructor) and XCE_DECISION_TRACE with make_trace_decision(); the live driver skips trace-only decisions and frees any attached trace. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
130 lines
3.8 KiB
C
130 lines
3.8 KiB
C
/*
|
|
* test_decision_trace.c - the decision transport's trace attachment and
|
|
* trace-only op (scheduler-sim-decision-trace spec, task 1.7; design.md
|
|
* "DecisionTransport"; Requirements 2.4, 10.1, 11.4).
|
|
*
|
|
* - every existing constructor (pend, dispatch, preempt) leaves the trace
|
|
* attachment NULL;
|
|
* - the existing op values are unchanged and the trace-only op is
|
|
* appended after XCE_DECISION_PREEMPT;
|
|
* - make_trace_decision() builds a trace-only decision: op TRACE, zeroed
|
|
* union, the record attached.
|
|
*
|
|
* The live driver's handling of both is covered in
|
|
* test_driver_session_ordering.c.
|
|
*
|
|
* White-box #include of src/decision.c; links src/sched_trace.c for the
|
|
* record constructor and free.
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <unity/unity.h>
|
|
|
|
#include "sched/trace.h"
|
|
|
|
#include "../src/decision.c"
|
|
|
|
void setUp(void) { return; }
|
|
void tearDown(void) { return; }
|
|
|
|
static xce_sched_trace_ctl_t make_ctl(void)
|
|
{
|
|
xce_sched_trace_ctl_t ctl;
|
|
|
|
memset(&ctl, 0, sizeof(ctl));
|
|
ctl.all = true;
|
|
ctl.level = XCE_TRACE_LEVEL_SUMMARY;
|
|
ctl.line_bound = XCE_TRACE_LINE_BOUND_DEFAULT;
|
|
ctl.session_no = 1;
|
|
ctl.policy_name = "fcfs";
|
|
return ctl;
|
|
}
|
|
|
|
static void test_existing_op_values_unchanged(void)
|
|
{
|
|
TEST_ASSERT_EQUAL_INT(0, XCE_DECISION_NONE);
|
|
TEST_ASSERT_EQUAL_INT(1, XCE_DECISION_DISPATCH);
|
|
TEST_ASSERT_EQUAL_INT(2, XCE_DECISION_PEND);
|
|
TEST_ASSERT_EQUAL_INT(3, XCE_DECISION_NEW_SESSION);
|
|
TEST_ASSERT_EQUAL_INT(4, XCE_DECISION_PREEMPT);
|
|
TEST_ASSERT_EQUAL_INT(5, XCE_DECISION_TRACE);
|
|
}
|
|
|
|
static void test_existing_constructors_leave_trace_null(void)
|
|
{
|
|
xce_pendreason_t reason;
|
|
xce_job_alloc_t alloc;
|
|
xce_preempt_t preempt;
|
|
xce_decision_t* d;
|
|
|
|
memset(&reason, 0, sizeof(reason));
|
|
memset(&alloc, 0, sizeof(alloc));
|
|
memset(&preempt, 0, sizeof(preempt));
|
|
|
|
d = make_pend_decision(&reason);
|
|
TEST_ASSERT_NOT_NULL(d);
|
|
TEST_ASSERT_EQUAL_INT(XCE_DECISION_PEND, d->op);
|
|
TEST_ASSERT_EQUAL_PTR(&reason, d->u.reason);
|
|
TEST_ASSERT_NULL(d->trace);
|
|
free(d);
|
|
|
|
d = make_dispatch_decision(&alloc);
|
|
TEST_ASSERT_NOT_NULL(d);
|
|
TEST_ASSERT_EQUAL_INT(XCE_DECISION_DISPATCH, d->op);
|
|
TEST_ASSERT_EQUAL_PTR(&alloc, d->u.alloc);
|
|
TEST_ASSERT_NULL(d->trace);
|
|
free(d);
|
|
|
|
d = make_preempt_decision(&preempt);
|
|
TEST_ASSERT_NOT_NULL(d);
|
|
TEST_ASSERT_EQUAL_INT(XCE_DECISION_PREEMPT, d->op);
|
|
TEST_ASSERT_EQUAL_PTR(&preempt, d->u.preempt);
|
|
TEST_ASSERT_NULL(d->trace);
|
|
free(d);
|
|
}
|
|
|
|
static void test_make_trace_decision_attaches_record(void)
|
|
{
|
|
xce_sched_trace_ctl_t ctl = make_ctl();
|
|
xce_sched_trace_rec_t* rec;
|
|
xce_decision_t* d;
|
|
|
|
rec = sched_trace_rec_new(&ctl, 42, XCE_TRACE_REC_DECISION);
|
|
TEST_ASSERT_NOT_NULL(rec);
|
|
sched_trace_rec_finish(rec, XCE_TRACE_REC_NO_SCHEDOBJ, 0);
|
|
|
|
d = make_trace_decision(rec);
|
|
TEST_ASSERT_NOT_NULL(d);
|
|
TEST_ASSERT_EQUAL_INT(XCE_DECISION_TRACE, d->op);
|
|
TEST_ASSERT_NULL(d->u.alloc);
|
|
TEST_ASSERT_NULL(d->u.reason);
|
|
TEST_ASSERT_NULL(d->u.preempt);
|
|
TEST_ASSERT_EQUAL_PTR(rec, d->trace);
|
|
TEST_ASSERT_EQUAL_INT(XCE_TRACE_REC_NO_SCHEDOBJ, d->trace->kind);
|
|
TEST_ASSERT_EQUAL_UINT64(42, d->trace->jobid);
|
|
|
|
/* the receiver owns d->trace: free it, then the decision */
|
|
sched_trace_rec_free(d->trace);
|
|
free(d);
|
|
}
|
|
|
|
static void test_make_trace_decision_accepts_null_record(void)
|
|
{
|
|
xce_decision_t* d = make_trace_decision(NULL);
|
|
|
|
TEST_ASSERT_NOT_NULL(d);
|
|
TEST_ASSERT_EQUAL_INT(XCE_DECISION_TRACE, d->op);
|
|
TEST_ASSERT_NULL(d->trace);
|
|
free(d);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_existing_op_values_unchanged);
|
|
RUN_TEST(test_existing_constructors_leave_trace_null);
|
|
RUN_TEST(test_make_trace_decision_attaches_record);
|
|
RUN_TEST(test_make_trace_decision_accepts_null_record);
|
|
return UNITY_END();
|
|
}
|