/* * bug-1882 regression, scheduler side: sched_make_allocs() (scheduler.c) * must return NULL when make_alloc() cannot build one of the records, * instead of an array with a NULL entry that the allocator plugins would * hand on as a host allocation silently missing a resource. * * Links the real scheduler_srcs (same technique as * sched_scheduler_connect_test) plus `-Wl,--wrap=strdup` (bug-1843's * `--wrap=realloc` idiom), so a chosen strdup() inside make_alloc() fails. */ #include #include #include #include #include "resobj.h" #include "scheduler.h" #include "xcealloc.h" extern char* __real_strdup(const char* s); static int g_strdup_fail_at = -1; /* -1 == disabled */ static int g_strdup_calls = 0; char* __wrap_strdup(const char* s) { if (g_strdup_fail_at >= 0) { int this_call = g_strdup_calls++; if (this_call == g_strdup_fail_at) { return NULL; } } return __real_strdup(s); } void setUp(void) { g_strdup_fail_at = -1; g_strdup_calls = 0; } void tearDown(void) { g_strdup_fail_at = -1; } static void test_sched_make_allocs_returns_null_when_a_record_fails(void) { xce_scheduler_t sched; xce_resource_t res; xce_resource_t* slots; xce_alloc_t** allocs; int idxs[2]; float vals[2] = { 1.0f, 2.0f }; memset(&sched, 0, sizeof(sched)); TEST_ASSERT_EQUAL_INT(0, xce_sched_core_init(&(sched.core))); memset(&res, 0, sizeof(res)); res.name = strdup("slots"); slots = makeResource(sched.core.resmgr, &res); TEST_ASSERT_NOT_NULL(slots); idxs[0] = slots->idx; idxs[1] = slots->idx; /* Control: both records built. */ allocs = sched_make_allocs(&sched, (char*)"", 2, idxs, vals, NULL); TEST_ASSERT_NOT_NULL(allocs); TEST_ASSERT_NOT_NULL(allocs[0]); TEST_ASSERT_NOT_NULL(allocs[1]); free_ResAlloc_list(2, allocs); /* strdup() calls: record 0 resname = 0, reserve = 1; record 1 * resname = 2. Fail record 1's resname. */ g_strdup_calls = 0; g_strdup_fail_at = 2; errno = 0; allocs = sched_make_allocs(&sched, (char*)"", 2, idxs, vals, NULL); g_strdup_fail_at = -1; TEST_ASSERT_NULL_MESSAGE(allocs, "a record that cannot be built must fail the " "whole array, not leave a NULL entry"); TEST_ASSERT_EQUAL_INT(ENOMEM, errno); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_sched_make_allocs_returns_null_when_a_record_fails); return UNITY_END(); }