feat(scheduler-sim-decision-trace): trace record model foundation
Task 1.3: trace types and constants, per-record arena, job selection matching, no-decision record finishing; empty capture module; both sources scanned by the core isolation test with a no-stdio check. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7f40ff27dc
commit
7d3c71fc34
8 changed files with 1234 additions and 1 deletions
432
src/scheduler/testsuite/test_trace_model.c
Normal file
432
src/scheduler/testsuite/test_trace_model.c
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* test_trace_model.c - unit tests for the decision trace record model
|
||||
* (scheduler-sim-decision-trace spec, task 1.3; design.md "TraceModel").
|
||||
*
|
||||
* Covers the model foundation:
|
||||
* - job selection matching: all jobs, a plain job, an array element, and
|
||||
* a whole array including elements that did not exist when the
|
||||
* selector was made (Requirements 1.2, 1.3);
|
||||
* - the record header copied from the settings snapshot and the
|
||||
* per-record arena: every string and number is copied, so a record
|
||||
* never points into scheduler (or REPL) memory, and the record reports
|
||||
* its own byte size (Requirement 9.1, design "Invariants");
|
||||
* - finishing a record as a no-decision kind (Requirement 2.4);
|
||||
* - freeing a NULL record is a no-op.
|
||||
*
|
||||
* Links only src/sched_trace.c (plus libxce for the jobid helpers).
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unity/unity.h>
|
||||
|
||||
#include "sched/trace.h"
|
||||
#include "utils.h"
|
||||
|
||||
/* A plain job, and an array block whose elements are tagged TAG_JOB_ARRAY
|
||||
* and numbered from 1 within the block (job-array-one-based-index). */
|
||||
#define PLAIN_ID(seq) MAKE_JOBID(1, 2, 1000, 0x0, (uint64_t)(seq))
|
||||
#define ARRAY_BASE(blk) \
|
||||
MAKE_JOBID(1, 2, 1000, 0x0, ((uint64_t)(blk)) << N_ARRAY_IDX_BITS)
|
||||
#define ARRAY_ELEM(blk, k) \
|
||||
MAKE_JOBID(1, 2, 1000, TAG_JOB_ARRAY, \
|
||||
(((uint64_t)(blk)) << N_ARRAY_IDX_BITS) | (uint64_t)(k))
|
||||
|
||||
void setUp(void) { return; }
|
||||
void tearDown(void) { return; }
|
||||
|
||||
static xce_sched_trace_ctl_t make_ctl(xce_sched_trace_sel_t* sel, int nsel)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl;
|
||||
|
||||
memset(&ctl, 0, sizeof(ctl));
|
||||
ctl.all = false;
|
||||
ctl.nsel = nsel;
|
||||
ctl.sel = sel;
|
||||
ctl.level = XCE_TRACE_LEVEL_SUMMARY;
|
||||
ctl.line_bound = XCE_TRACE_LINE_BOUND_DEFAULT;
|
||||
ctl.session_no = 7;
|
||||
ctl.policy_name = "fcfs";
|
||||
ctl.position = 3;
|
||||
return ctl;
|
||||
}
|
||||
|
||||
/* ---- constants ------------------------------------------------------- */
|
||||
|
||||
static void test_constants_match_requirements(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(1000, XCE_TRACE_LINE_BOUND_DEFAULT);
|
||||
TEST_ASSERT_EQUAL_INT(50, XCE_TRACE_LINE_BOUND_MIN);
|
||||
TEST_ASSERT_EQUAL_INT(100000, XCE_TRACE_LINE_BOUND_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(50, XCE_TRACE_OUTCOME_HOSTS);
|
||||
TEST_ASSERT_EQUAL_INT(XCE_TRACE_LEVEL_SUMMARY, 0);
|
||||
TEST_ASSERT_EQUAL_INT(XCE_TRACE_REC_DECISION, 0);
|
||||
/* verdict kinds are distinct single bits, one per counter slot */
|
||||
TEST_ASSERT_EQUAL_HEX(0x3f, XCE_TRACE_V_ACCEPTED | XCE_TRACE_V_SELECT
|
||||
| XCE_TRACE_V_SHORTFALL | XCE_TRACE_V_LIMIT
|
||||
| XCE_TRACE_V_CLAIMED
|
||||
| XCE_TRACE_V_INTERNAL);
|
||||
TEST_ASSERT_EQUAL_INT(6, XCE_TRACE_V_NKINDS);
|
||||
}
|
||||
|
||||
/* ---- selection matching (1.2, 1.3) ----------------------------------- */
|
||||
|
||||
static void test_wants_null_ctl_is_false(void)
|
||||
{
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(NULL, PLAIN_ID(5)));
|
||||
}
|
||||
|
||||
static void test_wants_all_matches_every_job(void)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
|
||||
ctl.all = true;
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, PLAIN_ID(5)));
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 1)));
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 400)));
|
||||
}
|
||||
|
||||
static void test_wants_empty_selection_matches_nothing(void)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, PLAIN_ID(5)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 1)));
|
||||
}
|
||||
|
||||
static void test_wants_plain_job_matches_only_that_job(void)
|
||||
{
|
||||
xce_sched_trace_sel_t sel[] = {
|
||||
{ PLAIN_ID(5), false }
|
||||
};
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(sel, 1);
|
||||
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, PLAIN_ID(5)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, PLAIN_ID(6)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 5)));
|
||||
}
|
||||
|
||||
static void test_wants_element_matches_only_that_element(void)
|
||||
{
|
||||
xce_sched_trace_sel_t sel[] = {
|
||||
{ ARRAY_ELEM(3, 2), false }
|
||||
};
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(sel, 1);
|
||||
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 2)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 1)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 3)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(4, 2)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_BASE(3)));
|
||||
}
|
||||
|
||||
static void test_wants_whole_array_matches_every_element(void)
|
||||
{
|
||||
xce_sched_trace_sel_t sel[] = {
|
||||
{ ARRAY_BASE(3), true }
|
||||
};
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(sel, 1);
|
||||
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 1)));
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, 2)));
|
||||
/* elements created later (any index in the block) also match (1.3) */
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(3, MAX_ARRAY_IDX)));
|
||||
/* another array, and a plain job that happens to share the base id's
|
||||
* bit pattern, do not */
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(4, 1)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_BASE(3)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, PLAIN_ID(7)));
|
||||
}
|
||||
|
||||
static void test_wants_unknown_yet_future_ids(void)
|
||||
{
|
||||
/* Selectors naming jobs that do not exist yet are kept as plain keys:
|
||||
* the predicate is a pure function of the id, so the job matches once
|
||||
* it appears (1.3). */
|
||||
xce_sched_trace_sel_t sel[] = {
|
||||
{ PLAIN_ID(900), false },
|
||||
{ ARRAY_ELEM(8, 4), false },
|
||||
{ ARRAY_BASE(9), true }
|
||||
};
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(sel, 3);
|
||||
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, PLAIN_ID(900)));
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(8, 4)));
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(9, 1)));
|
||||
TEST_ASSERT_TRUE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(9, 77)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, ARRAY_ELEM(8, 5)));
|
||||
TEST_ASSERT_FALSE(sched_trace_ctl_wants(&ctl, PLAIN_ID(901)));
|
||||
}
|
||||
|
||||
/* ---- record header and arena ----------------------------------------- */
|
||||
|
||||
static void test_rec_new_null_ctl_returns_null(void)
|
||||
{
|
||||
TEST_ASSERT_NULL(
|
||||
sched_trace_rec_new(NULL, PLAIN_ID(5), XCE_TRACE_REC_DECISION));
|
||||
}
|
||||
|
||||
static void test_rec_new_copies_header_from_ctl(void)
|
||||
{
|
||||
char policy[] = "priority-fcfs";
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
xce_sched_trace_rec_t* rec;
|
||||
|
||||
ctl.level = XCE_TRACE_LEVEL_FULL;
|
||||
ctl.line_bound = 75;
|
||||
ctl.policy_name = policy;
|
||||
|
||||
rec = sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_DECISION);
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
|
||||
/* change every source the record was built from */
|
||||
ctl.level = XCE_TRACE_LEVEL_SUMMARY;
|
||||
ctl.line_bound = 9999;
|
||||
ctl.session_no = 99;
|
||||
ctl.position = 42;
|
||||
memset(policy, 'x', sizeof(policy) - 1);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT64(PLAIN_ID(5), rec->jobid);
|
||||
TEST_ASSERT_EQUAL_INT(XCE_TRACE_REC_DECISION, rec->kind);
|
||||
TEST_ASSERT_EQUAL_INT(0, rec->err);
|
||||
TEST_ASSERT_EQUAL_INT(XCE_TRACE_LEVEL_FULL, rec->level);
|
||||
TEST_ASSERT_EQUAL_INT(75, rec->line_bound);
|
||||
TEST_ASSERT_EQUAL_UINT64(7, rec->session_no);
|
||||
TEST_ASSERT_EQUAL_INT(3, rec->position);
|
||||
TEST_ASSERT_FALSE(rec->incomplete);
|
||||
TEST_ASSERT_NOT_NULL(rec->policy_name);
|
||||
TEST_ASSERT_TRUE(rec->policy_name != policy);
|
||||
TEST_ASSERT_EQUAL_STRING("priority-fcfs", rec->policy_name);
|
||||
TEST_ASSERT_EQUAL_INT(0, rec->path.depth);
|
||||
TEST_ASSERT_EQUAL_INT(0, rec->counters.plans_tried);
|
||||
TEST_ASSERT_EQUAL_INT(0, rec->counters.omitted_lines);
|
||||
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
static void test_rec_new_null_policy_stays_null(void)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
xce_sched_trace_rec_t* rec;
|
||||
|
||||
ctl.policy_name = NULL;
|
||||
rec = sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_RECONSTRUCTED);
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
TEST_ASSERT_NULL(rec->policy_name);
|
||||
TEST_ASSERT_EQUAL_INT(XCE_TRACE_REC_RECONSTRUCTED, rec->kind);
|
||||
TEST_ASSERT_FALSE(rec->incomplete);
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
static void test_rec_new_does_not_keep_ctl_selection(void)
|
||||
{
|
||||
/* The record keeps nothing that points into the ctl: freeing the
|
||||
* ctl's selector array and policy string must leave it intact. */
|
||||
xce_sched_trace_sel_t* sel = calloc(1, sizeof(*sel));
|
||||
char* policy = strdup("fcfs");
|
||||
xce_sched_trace_ctl_t ctl;
|
||||
xce_sched_trace_rec_t* rec;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(sel);
|
||||
TEST_ASSERT_NOT_NULL(policy);
|
||||
sel[0].key = PLAIN_ID(5);
|
||||
ctl = make_ctl(sel, 1);
|
||||
ctl.policy_name = policy;
|
||||
rec = sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_DECISION);
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
free(sel);
|
||||
free(policy);
|
||||
/* ASAN would flag a read of either freed block here */
|
||||
TEST_ASSERT_EQUAL_STRING("fcfs", rec->policy_name);
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
static void test_arena_strdup_copies_string(void)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
xce_sched_trace_rec_t* rec
|
||||
= sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_DECISION);
|
||||
char* src = strdup("host-n01");
|
||||
char* cp;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
TEST_ASSERT_NOT_NULL(src);
|
||||
cp = sched_trace_arena_strdup(rec, src);
|
||||
TEST_ASSERT_NOT_NULL(cp);
|
||||
TEST_ASSERT_TRUE(cp != src);
|
||||
free(src);
|
||||
TEST_ASSERT_EQUAL_STRING("host-n01", cp);
|
||||
|
||||
/* empty string is a real copy, NULL is NULL without marking the
|
||||
* record incomplete */
|
||||
cp = sched_trace_arena_strdup(rec, "");
|
||||
TEST_ASSERT_NOT_NULL(cp);
|
||||
TEST_ASSERT_EQUAL_STRING("", cp);
|
||||
TEST_ASSERT_NULL(sched_trace_arena_strdup(rec, NULL));
|
||||
TEST_ASSERT_FALSE(rec->incomplete);
|
||||
TEST_ASSERT_NULL(sched_trace_arena_strdup(NULL, "x"));
|
||||
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
static void test_arena_memdup_copies_numbers(void)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
xce_sched_trace_rec_t* rec
|
||||
= sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_DECISION);
|
||||
float* src = malloc(4 * sizeof(float));
|
||||
float* cp;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
TEST_ASSERT_NOT_NULL(src);
|
||||
src[0] = 1.5f;
|
||||
src[1] = 2.0f;
|
||||
src[2] = -3.25f;
|
||||
src[3] = 1e9f;
|
||||
cp = sched_trace_arena_memdup(rec, src, 4 * sizeof(float));
|
||||
TEST_ASSERT_NOT_NULL(cp);
|
||||
TEST_ASSERT_TRUE(cp != src);
|
||||
src[0] = 0.0f;
|
||||
free(src);
|
||||
TEST_ASSERT_EQUAL_FLOAT(1.5f, cp[0]);
|
||||
TEST_ASSERT_EQUAL_FLOAT(2.0f, cp[1]);
|
||||
TEST_ASSERT_EQUAL_FLOAT(-3.25f, cp[2]);
|
||||
TEST_ASSERT_EQUAL_FLOAT(1e9f, cp[3]);
|
||||
/* storage is suitably aligned for any scalar */
|
||||
TEST_ASSERT_EQUAL_UINT(0, ((uintptr_t)cp) % _Alignof(max_align_t));
|
||||
|
||||
TEST_ASSERT_NULL(sched_trace_arena_memdup(rec, NULL, 8));
|
||||
TEST_ASSERT_FALSE(rec->incomplete);
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
static void test_arena_alloc_is_zeroed_and_aligned(void)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
xce_sched_trace_rec_t* rec
|
||||
= sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_DECISION);
|
||||
unsigned char* p;
|
||||
size_t i;
|
||||
int k;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
for (k = 0; k < 50; k++) {
|
||||
size_t n = (size_t)(k * 37 + 1);
|
||||
|
||||
p = sched_trace_arena_alloc(rec, n);
|
||||
TEST_ASSERT_NOT_NULL(p);
|
||||
TEST_ASSERT_EQUAL_UINT(0, ((uintptr_t)p) % _Alignof(max_align_t));
|
||||
for (i = 0; i < n; i++) {
|
||||
TEST_ASSERT_EQUAL_UINT8(0, p[i]);
|
||||
}
|
||||
memset(p, 0xa5, n); /* ASAN flags any overlap with a neighbour */
|
||||
}
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
static void test_rec_bytes_reports_record_and_arena(void)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
xce_sched_trace_rec_t* rec;
|
||||
size_t b0, b1, b2;
|
||||
int k;
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT(0, sched_trace_rec_bytes(NULL));
|
||||
|
||||
rec = sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_DECISION);
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
b0 = sched_trace_rec_bytes(rec);
|
||||
TEST_ASSERT_TRUE(b0 >= sizeof(*rec) + strlen("fcfs") + 1);
|
||||
TEST_ASSERT_EQUAL_UINT(sizeof(*rec) + rec->arena_bytes, b0);
|
||||
|
||||
/* a large copy grows the arena by at least its own size */
|
||||
TEST_ASSERT_NOT_NULL(sched_trace_arena_alloc(rec, 1 << 20));
|
||||
b1 = sched_trace_rec_bytes(rec);
|
||||
TEST_ASSERT_TRUE(b1 >= b0 + (1 << 20));
|
||||
|
||||
/* many small copies: size never shrinks and covers everything copied */
|
||||
for (k = 0; k < 1000; k++) {
|
||||
TEST_ASSERT_NOT_NULL(sched_trace_arena_strdup(rec, "0123456789"));
|
||||
}
|
||||
b2 = sched_trace_rec_bytes(rec);
|
||||
TEST_ASSERT_TRUE(b2 >= b1 + 1000 * 11);
|
||||
TEST_ASSERT_EQUAL_UINT(sizeof(*rec) + rec->arena_bytes, b2);
|
||||
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
static void test_rec_free_null_is_noop(void)
|
||||
{
|
||||
sched_trace_rec_free(NULL);
|
||||
TEST_PASS();
|
||||
}
|
||||
|
||||
/* ---- record finishing (2.4) ------------------------------------------ */
|
||||
|
||||
static void finish_and_check(xce_sched_trace_rec_kind_t kind, int err)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
xce_sched_trace_rec_t* rec
|
||||
= sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_DECISION);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
sched_trace_rec_finish(rec, kind, err);
|
||||
TEST_ASSERT_EQUAL_INT(kind, rec->kind);
|
||||
TEST_ASSERT_EQUAL_INT(err, rec->err);
|
||||
/* the header is otherwise untouched */
|
||||
TEST_ASSERT_EQUAL_UINT64(PLAIN_ID(5), rec->jobid);
|
||||
TEST_ASSERT_EQUAL_INT(3, rec->position);
|
||||
TEST_ASSERT_EQUAL_UINT64(7, rec->session_no);
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
static void test_finish_records_kind_and_error(void)
|
||||
{
|
||||
finish_and_check(XCE_TRACE_REC_NOT_FOUND, -2 /* -ENOENT */);
|
||||
finish_and_check(XCE_TRACE_REC_NO_SCHEDOBJ, 0);
|
||||
finish_and_check(XCE_TRACE_REC_INTERNAL_ERROR, -5 /* -EIO */);
|
||||
finish_and_check(XCE_TRACE_REC_INTERNAL_ERROR, -12 /* -ENOMEM */);
|
||||
finish_and_check(XCE_TRACE_REC_PEND_NO_REASON, 0);
|
||||
}
|
||||
|
||||
static void test_finish_rejects_non_no_decision_kinds(void)
|
||||
{
|
||||
xce_sched_trace_ctl_t ctl = make_ctl(NULL, 0);
|
||||
xce_sched_trace_rec_t* rec
|
||||
= sched_trace_rec_new(&ctl, PLAIN_ID(5), XCE_TRACE_REC_DECISION);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(rec);
|
||||
sched_trace_rec_finish(rec, XCE_TRACE_REC_RECONSTRUCTED, -5);
|
||||
TEST_ASSERT_EQUAL_INT(XCE_TRACE_REC_DECISION, rec->kind);
|
||||
TEST_ASSERT_EQUAL_INT(0, rec->err);
|
||||
sched_trace_rec_finish(rec, XCE_TRACE_REC_DECISION, -5);
|
||||
TEST_ASSERT_EQUAL_INT(XCE_TRACE_REC_DECISION, rec->kind);
|
||||
TEST_ASSERT_EQUAL_INT(0, rec->err);
|
||||
sched_trace_rec_finish(NULL, XCE_TRACE_REC_NOT_FOUND, -2); /* no crash */
|
||||
sched_trace_rec_free(rec);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_constants_match_requirements);
|
||||
RUN_TEST(test_wants_null_ctl_is_false);
|
||||
RUN_TEST(test_wants_all_matches_every_job);
|
||||
RUN_TEST(test_wants_empty_selection_matches_nothing);
|
||||
RUN_TEST(test_wants_plain_job_matches_only_that_job);
|
||||
RUN_TEST(test_wants_element_matches_only_that_element);
|
||||
RUN_TEST(test_wants_whole_array_matches_every_element);
|
||||
RUN_TEST(test_wants_unknown_yet_future_ids);
|
||||
RUN_TEST(test_rec_new_null_ctl_returns_null);
|
||||
RUN_TEST(test_rec_new_copies_header_from_ctl);
|
||||
RUN_TEST(test_rec_new_null_policy_stays_null);
|
||||
RUN_TEST(test_rec_new_does_not_keep_ctl_selection);
|
||||
RUN_TEST(test_arena_strdup_copies_string);
|
||||
RUN_TEST(test_arena_memdup_copies_numbers);
|
||||
RUN_TEST(test_arena_alloc_is_zeroed_and_aligned);
|
||||
RUN_TEST(test_rec_bytes_reports_record_and_arena);
|
||||
RUN_TEST(test_rec_free_null_is_noop);
|
||||
RUN_TEST(test_finish_records_kind_and_error);
|
||||
RUN_TEST(test_finish_rejects_non_no_decision_kinds);
|
||||
return UNITY_END();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue