/* * 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 #include #include #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(); }