support limit

This commit is contained in:
Rongsong Shen 2026-01-12 15:20:51 +08:00
parent bef32ace38
commit ecf1916d78
33 changed files with 3036 additions and 243 deletions

View file

@ -1,3 +1,4 @@
#include <argp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -16,26 +17,94 @@ extern void test_preason(void);
extern void test_ordq(void);
extern void test_delay(void);
extern void test_kvmgr(void);
extern void test_group(void);
extern void test_xlist(void);
extern void test_limit(void);
void setUp(void) { return; }
void tearDown(void) { return; }
static char doc[] = "xcelib_test";
static char args_doc[] = "";
#define MAX_TESTS (256)
struct arguments {
int ntests;
char* tests[MAX_TESTS];
};
static struct argp_option options[] = {
{ "run", 't', "STR", 0, "run test" },
{ 0 }
};
static error_t parse_opt(int key, char* arg, struct argp_state* state)
{
struct arguments* arguments = state->input;
switch (key) {
case 't':
if (arguments->ntests >= MAX_TESTS) {
fprintf(stderr, "Too many tests\n");
exit(-1);
}
arguments->tests[arguments->ntests] = arg;
arguments->ntests++;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp argp = { options, parse_opt, args_doc, doc };
struct arguments arguments;
static int check_test(struct arguments* args, char* x)
{
int i;
if (args->ntests == 0) {
return 1;
}
for (i = 0; i < args->ntests; i++) {
if (strcmp(x, args->tests[i]) == 0) {
return 1;
}
}
return 0;
}
#define TEST(x) \
do { \
if (check_test(&arguments, #x)) { \
x(); \
} \
} while (0)
int main(int argc, char* argv[])
{
argp_parse(&argp, argc, argv, 0, 0, &arguments);
UNITY_BEGIN();
test_config();
test_idgen();
test_ht_string();
test_ht_int();
test_zarray();
test_xstrings();
test_error();
test_utils();
test_preason();
test_ordq();
test_delay();
test_kvmgr();
TEST(test_config);
TEST(test_idgen);
TEST(test_ht_string);
TEST(test_ht_int);
TEST(test_zarray);
TEST(test_xstrings);
TEST(test_error);
TEST(test_utils);
TEST(test_preason);
TEST(test_ordq);
TEST(test_delay);
TEST(test_kvmgr);
TEST(test_group);
TEST(test_xlist);
TEST(test_limit);
return UNITY_END();
}

View file

@ -0,0 +1,271 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unity.h>
#include "group.h"
#include "utils.h"
static void test_all(void)
{
groupmgr_t mgr;
xce_group_t* all = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
all = get_group(&mgr, "all");
TEST_ASSERT_TRUE(all != NULL);
rc = is_in_group(all, "rshen");
TEST_ASSERT_TRUE(rc > 0);
groupmgr_fini(&mgr);
}
static void test_empty(void)
{
groupmgr_t mgr;
xce_group_t* empty = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
empty = get_group(&mgr, "empty");
TEST_ASSERT_TRUE(empty != NULL);
rc = is_in_group(empty, "rshen");
TEST_ASSERT_TRUE(rc == 0);
groupmgr_fini(&mgr);
}
static void test_all_1(void)
{
groupmgr_t mgr;
xce_group_config_t gdata = {
.name = "g1",
.members = { .count = 1, .data = (char*[]) { "all" } }
};
xce_group_t* g = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
g = build_group(&mgr, &gdata, NULL);
TEST_ASSERT_TRUE(g != NULL);
rc = is_in_group(g, "rshen");
TEST_ASSERT_TRUE(rc > 0);
groupmgr_fini(&mgr);
}
static void test_all_2(void)
{
groupmgr_t mgr;
xce_group_config_t gdata = {
.name = "g1",
.members = { .count = 2, .data = (char*[]) { "g2", "all" } }
};
xce_group_t* g = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
g = build_group(&mgr, &gdata, NULL);
TEST_ASSERT_TRUE(g != NULL);
rc = is_in_group(g, "rshen");
TEST_ASSERT_TRUE(rc > 0);
groupmgr_fini(&mgr);
}
static void test_empty_1(void)
{
groupmgr_t mgr;
xce_group_config_t gdata = {
.name = "g1",
.ex_members = { .count = 1, .data = (char*[]) { "all" } }
};
xce_group_t* g = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
g = build_group(&mgr, &gdata, NULL);
TEST_ASSERT_TRUE(g != NULL);
rc = is_in_group(g, "rshen");
TEST_ASSERT_TRUE(rc == 0);
groupmgr_fini(&mgr);
}
static void test_empty_2(void)
{
groupmgr_t mgr;
xce_group_config_t gdata = {
.name = "g1",
.members = { .count = 1, .data = (char*[]) { "empty" } }
};
xce_group_t* g = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
g = build_group(&mgr, &gdata, NULL);
TEST_ASSERT_TRUE(g != NULL);
rc = is_in_group(g, "rshen");
TEST_ASSERT_TRUE(rc == 0);
groupmgr_fini(&mgr);
}
static void test_include(void)
{
groupmgr_t mgr;
xce_group_config_t gdata = {
.name = "g1",
.members = { .count = 1, .data = (char*[]) { "rshen" } }
};
xce_group_t* g = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
g = build_group(&mgr, &gdata, NULL);
TEST_ASSERT_TRUE(g != NULL);
rc = is_in_group(g, "rshen");
TEST_ASSERT_TRUE(rc > 0);
groupmgr_fini(&mgr);
}
static void test_exclude(void)
{
groupmgr_t mgr;
xce_group_config_t gdata = {
.name = "g1",
.members = { .count = 1, .data = (char*[]) { "all" } },
.ex_members = { .count = 1, .data = (char*[]) { "rshen" } }
};
xce_group_t* g = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
g = build_group(&mgr, &gdata, NULL);
TEST_ASSERT_TRUE(g != NULL);
rc = is_in_group(g, "rshen");
TEST_ASSERT_TRUE(rc == 0);
groupmgr_fini(&mgr);
}
static void test_nest(void)
{
groupmgr_t mgr;
xce_group_config_t gdata1 = {
.name = "g1",
.members = { .count = 1, .data = (char*[]) { "rshen" } }
};
xce_group_config_t gdata2 = {
.name = "g2",
.members = { .count = 1, .data = (char*[]) { "g1" } }
};
xce_group_t* g = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
g = build_group(&mgr, &gdata1, NULL);
TEST_ASSERT_TRUE(g != NULL);
g = build_group(&mgr, &gdata2, NULL);
TEST_ASSERT_TRUE(g != NULL);
rc = is_in_group(g, "rshen");
TEST_ASSERT_TRUE(rc != 0);
groupmgr_fini(&mgr);
}
static void test_nest2(void)
{
groupmgr_t mgr;
xce_group_config_t gdata1 = {
.name = "g1",
.members = { .count = 1, .data = (char*[]) { "rshen" } }
};
xce_group_config_t gdata2 = {
.name = "g2",
.members = { .count = 1, .data = (char*[]) { "all" } },
.ex_members = { .count = 1, .data = (char*[]) { "g1" } }
};
xce_group_t* g = NULL;
int rc = 0;
groupmgr_init(&mgr, 16, 16);
g = build_group(&mgr, &gdata1, NULL);
TEST_ASSERT_TRUE(g != NULL);
g = build_group(&mgr, &gdata2, NULL);
TEST_ASSERT_TRUE(g != NULL);
rc = is_in_group(g, "rshen");
TEST_ASSERT_TRUE(rc == 0);
groupmgr_fini(&mgr);
}
void test_group(void)
{
printf("\n>> group test\n\n");
RUN_TEST(test_all);
RUN_TEST(test_empty);
RUN_TEST(test_all_1);
RUN_TEST(test_all_2);
RUN_TEST(test_empty_1);
RUN_TEST(test_empty_2);
RUN_TEST(test_include);
RUN_TEST(test_exclude);
RUN_TEST(test_nest);
RUN_TEST(test_nest2);
}

View file

@ -0,0 +1,324 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unity.h>
#include "group.h"
#include "xce/types.h"
#include "xcelimit.h"
static void test_build_consumer1(void)
{
xce_consumer_t* c = NULL;
groupmgr_t mgr;
xce_group_config_t gdata = {
.members = { .count = 2, .data = (char*[]) { "rshen", "jsxing" } }
};
int rc = 0;
char buf[1024];
groupmgr_init(&mgr, 4, 4);
rc = build_consumer(&c, &mgr, CONSUMER_USER, 1, &gdata, "user_group1");
TEST_ASSERT_TRUE(rc == 1);
rc = fmt_consumer(buf, sizeof(buf) - 1, c);
TEST_ASSERT_TRUE(rc > 0);
printf("\n >>> consumer: %s\n", buf);
kill_consumer(c);
groupmgr_fini(&mgr);
return;
}
static void test_build_consumer2(void)
{
xce_consumer_t* c = NULL;
groupmgr_t mgr;
xce_group_config_t gdata = {
.members = { .count = 1, .data = (char*[]) { "all" } },
.ex_members = { .count = 2, .data = (char*[]) { "rshen", "jsxing" } }
};
int rc = 0;
char buf[1024];
groupmgr_init(&mgr, 4, 4);
rc = build_consumer(&c, &mgr, CONSUMER_USER, 1, &gdata, "user_group1");
TEST_ASSERT_TRUE(rc == 1);
rc = fmt_consumer(buf, sizeof(buf) - 1, c);
TEST_ASSERT_TRUE(rc > 0);
printf("\n >>> consumer: %s\n", buf);
kill_consumer(c);
groupmgr_fini(&mgr);
return;
}
static void test_build_limit_ok1(void)
{
groupmgr_t umgr, qmgr, hmgr, pmgr;
xce_limit_t* limit;
int rc;
xce_limit_config_t limit_config = {
.name = "limit1",
.per_user = 0,
.per_queue = 0,
.per_project = 0,
.per_host = 0,
.users
= &(xce_group_config_t) { .members = { .count = 1,
.data = (char*[]) { "u1" } } },
.queues = NULL,
.hosts = NULL,
.projects = NULL,
.val
= &(xce_limit_val_t) { .resname = "mem", .percent = 1, .val = 80.0 }
};
char buf[1024];
groupmgr_init(&umgr, 4, 4);
groupmgr_init(&qmgr, 4, 4);
groupmgr_init(&hmgr, 4, 4);
groupmgr_init(&pmgr, 4, 4);
rc = build_limit(&limit, &umgr, &qmgr, &hmgr, &pmgr, &limit_config);
TEST_ASSERT_TRUE(rc == 1);
memset(buf, 0x0, sizeof(buf));
rc = fmt_limit(buf, sizeof(buf) - 1, limit);
TEST_ASSERT_TRUE(rc > 0);
printf("%s\n", buf);
kill_limit(limit);
groupmgr_fini(&pmgr);
groupmgr_fini(&hmgr);
groupmgr_fini(&qmgr);
groupmgr_fini(&umgr);
}
static void test_match_limit_ok1(void)
{
groupmgr_t umgr, qmgr, hmgr, pmgr;
xce_limit_t* limit;
int rc;
xce_limit_config_t limit_config = {
.name = "limit1",
.per_user = 0,
.per_queue = 0,
.per_project = 0,
.per_host = 0,
.users
= &(xce_group_config_t) { .members = { .count = 1,
.data = (char*[]) { "all" } } },
.queues
= &(xce_group_config_t) { .members = { .count = 1,
.data = (char*[]) { "all" } } },
.hosts = NULL,
.projects
= &(xce_group_config_t) { .members = { .count = 1,
.data = (char*[]) { "all" } } },
.val
= &(xce_limit_val_t) { .resname = "mem", .percent = 1, .val = 80.0 }
};
char buf[1024];
groupmgr_init(&umgr, 4, 4);
groupmgr_init(&qmgr, 4, 4);
groupmgr_init(&hmgr, 4, 4);
groupmgr_init(&pmgr, 4, 4);
rc = build_limit(&limit, &umgr, &qmgr, &hmgr, &pmgr, &limit_config);
TEST_ASSERT_TRUE(rc == 1);
memset(buf, 0x0, sizeof(buf));
rc = fmt_limit(buf, sizeof(buf) - 1, limit);
TEST_ASSERT_TRUE(rc > 0);
printf("%s\n", buf);
rc = match_limit(limit, 1, "rshen", "xce", "project1");
TEST_ASSERT_TRUE(rc > 0);
kill_limit(limit);
groupmgr_fini(&pmgr);
groupmgr_fini(&hmgr);
groupmgr_fini(&qmgr);
groupmgr_fini(&umgr);
}
static void test_match_limit_ok2(void)
{
groupmgr_t umgr, qmgr, hmgr, pmgr;
xce_limit_t* limit;
int rc;
xce_limit_config_t limit_config = {
.name = "limit1",
.per_user = 0,
.per_queue = 0,
.per_project = 0,
.per_host = 0,
.users = NULL,
.queues = NULL,
.hosts = NULL,
.projects = NULL,
.val
= &(xce_limit_val_t) { .resname = "mem", .percent = 1, .val = 80.0 }
};
char buf[1024];
groupmgr_init(&umgr, 4, 4);
groupmgr_init(&qmgr, 4, 4);
groupmgr_init(&hmgr, 4, 4);
groupmgr_init(&pmgr, 4, 4);
rc = build_limit(&limit, &umgr, &qmgr, &hmgr, &pmgr, &limit_config);
TEST_ASSERT_TRUE(rc == 1);
memset(buf, 0x0, sizeof(buf));
rc = fmt_limit(buf, sizeof(buf) - 1, limit);
TEST_ASSERT_TRUE(rc > 0);
printf("%s\n", buf);
rc = match_limit(limit, 1, "rshen", "xce", "project1");
TEST_ASSERT_TRUE(rc > 0);
kill_limit(limit);
groupmgr_fini(&pmgr);
groupmgr_fini(&hmgr);
groupmgr_fini(&qmgr);
groupmgr_fini(&umgr);
}
static void test_match_limit1(void)
{
groupmgr_t umgr, qmgr, hmgr, pmgr;
xce_limit_t* limit;
int rc;
xce_limit_config_t limit_config = {
.name = "limit1",
.per_user = 0,
.per_queue = 0,
.per_project = 0,
.per_host = 0,
.users
= &(xce_group_config_t) { .members
= { .count = 1, .data = (char*[]) { "all" } },
.ex_members
= { .count = 1,
.data = (char*[]) { "rshen" } } },
.queues
= &(xce_group_config_t) { .members = { .count = 1,
.data = (char*[]) { "all" } } },
.hosts = NULL,
.projects
= &(xce_group_config_t) { .members = { .count = 1,
.data = (char*[]) { "all" } } },
.val
= &(xce_limit_val_t) { .resname = "mem", .percent = 1, .val = 80.0 }
};
char buf[1024];
groupmgr_init(&umgr, 4, 4);
groupmgr_init(&qmgr, 4, 4);
groupmgr_init(&hmgr, 4, 4);
groupmgr_init(&pmgr, 4, 4);
rc = build_limit(&limit, &umgr, &qmgr, &hmgr, &pmgr, &limit_config);
TEST_ASSERT_TRUE(rc == 1);
memset(buf, 0x0, sizeof(buf));
rc = fmt_limit(buf, sizeof(buf) - 1, limit);
TEST_ASSERT_TRUE(rc > 0);
printf("%s\n", buf);
rc = match_limit(limit, 1, "rshen", "xce", "project1");
TEST_ASSERT_TRUE(rc == 0);
kill_limit(limit);
groupmgr_fini(&pmgr);
groupmgr_fini(&hmgr);
groupmgr_fini(&qmgr);
groupmgr_fini(&umgr);
}
static void test_match_limit2(void)
{
groupmgr_t umgr, qmgr, hmgr, pmgr;
xce_limit_t* limit;
int rc;
xce_limit_config_t limit_config = {
.name = "limit1",
.per_user = 0,
.per_queue = 0,
.per_project = 0,
.per_host = 0,
.users
= &(xce_group_config_t) { .members
= { .count = 1, .data = (char*[]) { "all" } },
.ex_members
= { .count = 1,
.data = (char*[]) { "rshen" } } },
.queues = NULL,
.hosts = NULL,
.projects = NULL,
.val
= &(xce_limit_val_t) { .resname = "slots", .percent = 0, .val = 3.0 }
};
char buf[1024];
groupmgr_init(&umgr, 4, 4);
groupmgr_init(&qmgr, 4, 4);
groupmgr_init(&hmgr, 4, 4);
groupmgr_init(&pmgr, 4, 4);
rc = build_limit(&limit, &umgr, &qmgr, &hmgr, &pmgr, &limit_config);
TEST_ASSERT_TRUE(rc == 1);
memset(buf, 0x0, sizeof(buf));
rc = fmt_limit(buf, sizeof(buf) - 1, limit);
TEST_ASSERT_TRUE(rc > 0);
printf("%s\n", buf);
rc = match_limit(limit, 1, "rshen", "normal", "default");
TEST_ASSERT_TRUE(rc == 0);
kill_limit(limit);
groupmgr_fini(&pmgr);
groupmgr_fini(&hmgr);
groupmgr_fini(&qmgr);
groupmgr_fini(&umgr);
}
void test_limit(void)
{
printf("\n>> limit test\n\n");
RUN_TEST(test_build_consumer1);
RUN_TEST(test_build_consumer2);
RUN_TEST(test_build_limit_ok1);
RUN_TEST(test_match_limit_ok1);
RUN_TEST(test_match_limit_ok2);
RUN_TEST(test_match_limit1);
RUN_TEST(test_match_limit2);
}

View file

@ -58,6 +58,27 @@ static void test_add_res_reason(void)
erase_job_preason(&reason);
}
static void test_add_shared_res_reason(void)
{
xce_job_preason_t reason;
memset(&reason, 0x0, sizeof(reason));
add_job_preason(&reason, 1, NULL, "res1");
TEST_ASSERT_TRUE(reason.main_reason == 0);
TEST_ASSERT_TRUE((reason.nres_reasons == 1)
&& (reason.res_based_reasons != NULL)
&& (reason.res_based_reasons[0] != NULL));
TEST_ASSERT_TRUE(
(reason.res_based_reasons[0]->reason == 1)
&& (strcmp(reason.res_based_reasons[0]->host, "") == 0)
&& (strcmp(reason.res_based_reasons[0]->resource, "res1") == 0));
TEST_ASSERT_TRUE((reason.nhost_reasons == 0)
&& (reason.host_based_reasons == NULL));
erase_job_preason(&reason);
}
static void test_add_res_host_reason(void)
{
xce_job_preason_t reason;
@ -161,6 +182,7 @@ void test_preason(void)
RUN_TEST(test_main_reason);
RUN_TEST(test_add_host_reason);
RUN_TEST(test_add_res_reason);
RUN_TEST(test_add_shared_res_reason);
RUN_TEST(test_add_res_host_reason);
RUN_TEST(test_add_main_reset_other);
RUN_TEST(test_add_more_host_reason);

View file

@ -0,0 +1,139 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unity.h>
#include "utils.h"
#include "xlist.h"
static void test_xlist1(void)
{
xlist_t lst;
char* hello = "Hello";
void* p = NULL;
int idx;
xlist_init(&lst, 2);
idx = xlist_store(&lst, (void*)hello);
TEST_ASSERT_TRUE(idx >= 0);
p = xlist_get(&lst, idx);
TEST_ASSERT_TRUE(p == hello);
xlist_fini(&lst);
}
static int find_check_(void* data, va_list ap)
{
char* p = va_arg(ap, char*);
if (data == p) {
return 1;
}
if (p == NULL) {
return 0;
}
if (data == NULL) {
return 0;
}
if (strcmp((char*)data, p) == 0) {
return 1;
}
return 0;
}
static void test_xlist_find(void)
{
xlist_t lst;
char* hello = "Hello";
void* p = NULL;
int idx;
xlist_init(&lst, 2);
idx = xlist_store(&lst, (void*)hello);
TEST_ASSERT_TRUE(idx >= 0);
p = xlist_find(&lst, (xlist_find_fn_t)find_check_, "Hello");
TEST_ASSERT_TRUE(p != NULL);
TEST_ASSERT_TRUE(strcmp((char*)p, "Hello") == 0);
xlist_fini(&lst);
}
static void test_xlist_del(void)
{
xlist_t lst;
char* hello = "Hello";
void* p = NULL;
int idx;
int i;
xlist_init(&lst, 2);
for (i = 0; i < 5; i++) {
idx = xlist_store(&lst, (void*)hello);
TEST_ASSERT_TRUE(idx >= 0);
}
p = xlist_find(&lst, (xlist_find_fn_t)find_check_, "Hello");
TEST_ASSERT_TRUE(p != NULL);
TEST_ASSERT_TRUE(strcmp((char*)p, "Hello") == 0);
xlist_del(&lst, (void*)hello);
p = xlist_find(&lst, (xlist_find_fn_t)find_check_, "Hello");
TEST_ASSERT_TRUE(p == NULL);
TEST_ASSERT_TRUE(lst.count == 0);
xlist_fini(&lst);
}
static int do_iter_(void* arg1, void* arg2)
{
int* count = (int*)arg2;
int i = (int)(long)arg1;
(*count) += i;
return 0;
}
static void test_xlist_iter(void)
{
xlist_t lst;
int idx;
int i;
int count = 0;
xlist_init(&lst, 2);
for (i = 0; i < 5; i++) {
idx = xlist_store(&lst, (void*)(long)i);
TEST_ASSERT_TRUE(idx >= 0);
}
xlist_iter(&lst, (xlist_iter_fn_t)do_iter_, &count);
TEST_ASSERT_TRUE(count == 10);
xlist_fini(&lst);
}
void test_xlist(void)
{
printf("\n>> xlist test\n\n");
RUN_TEST(test_xlist1);
RUN_TEST(test_xlist_find);
RUN_TEST(test_xlist_del);
RUN_TEST(test_xlist_iter);
}