502 lines
16 KiB
C
502 lines
16 KiB
C
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <unity/unity.h>
|
|
|
|
#include "resreq.h"
|
|
#include "utils.h"
|
|
|
|
void test_parse_section1(void)
|
|
{
|
|
char* resreq = "type == any";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_data_t data;
|
|
|
|
rc = parse_section(&data, (char*)resreq, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
TEST_ASSERT_TRUE(data.selectString != NULL);
|
|
TEST_ASSERT_TRUE((data.rusageString == NULL) && (data.spanString == NULL)
|
|
&& (data.sameString == NULL)
|
|
&& (data.affinityString == NULL));
|
|
TEST_ASSERT_TRUE(errmsg == NULL);
|
|
|
|
printf("select: %s\n", data.selectString);
|
|
FREEUP(data.selectString);
|
|
}
|
|
|
|
void test_parse_section2(void)
|
|
{
|
|
char* resreq = "select[type == any]";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_data_t data;
|
|
|
|
rc = parse_section(&data, (char*)resreq, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
TEST_ASSERT_TRUE(data.selectString != NULL);
|
|
TEST_ASSERT_TRUE((data.rusageString == NULL) && (data.spanString == NULL)
|
|
&& (data.sameString == NULL)
|
|
&& (data.affinityString == NULL));
|
|
TEST_ASSERT_TRUE(errmsg == NULL);
|
|
|
|
printf("select: %s\n", data.selectString);
|
|
FREEUP(data.selectString);
|
|
}
|
|
|
|
void test_parse_section_fail(void)
|
|
{
|
|
char* resreq = "select[type == any] rusage[mem=20:lic=55] span[ptile=1] "
|
|
"same[type] same[abcd] affinity[core(20)]";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_data_t data = {0};
|
|
|
|
rc = parse_section(&data, (char*)resreq, &errmsg);
|
|
TEST_ASSERT_TRUE(rc < 0);
|
|
TEST_ASSERT_TRUE(data.selectString == NULL);
|
|
TEST_ASSERT_TRUE((data.rusageString == NULL) && (data.spanString == NULL)
|
|
&& (data.sameString == NULL)
|
|
&& (data.affinityString == NULL));
|
|
TEST_ASSERT_TRUE(errmsg != NULL);
|
|
|
|
printf("Parse Error:\n%s\n", errmsg);
|
|
FREEUP(errmsg);
|
|
}
|
|
|
|
void test_parse_section3(void)
|
|
{
|
|
char* resreq = "type == any span[ptile=1]";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_data_t data;
|
|
|
|
rc = parse_section(&data, (char*)resreq, &errmsg);
|
|
if (rc < 0) {
|
|
if (errmsg != NULL) {
|
|
printf("%s", errmsg);
|
|
FREEUP(errmsg);
|
|
}
|
|
}
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
TEST_ASSERT_TRUE(data.selectString != NULL);
|
|
TEST_ASSERT_TRUE((data.rusageString == NULL) && (data.spanString != NULL)
|
|
&& (data.sameString == NULL)
|
|
&& (data.affinityString == NULL));
|
|
TEST_ASSERT_TRUE(errmsg == NULL);
|
|
|
|
printf("select: %s\n", data.selectString);
|
|
printf("span: %s\n", data.spanString);
|
|
|
|
FREEUP(data.selectString);
|
|
FREEUP(data.spanString);
|
|
}
|
|
|
|
|
|
void test_parse_rusage1(void)
|
|
{
|
|
char* rusageString
|
|
= "mem=20:duration=300:decay=1,lic=55:duration=20m:decay=0";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xlist_t rusages;
|
|
|
|
xlist_init(&rusages, 8);
|
|
|
|
rc = parse_rusage(&rusages, rusageString, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
|
|
if (rc >= 0) {
|
|
int i;
|
|
|
|
for (i = 0; i < rusages.count; i++) {
|
|
rusage_value_t* v = (rusage_value_t*)xlist_get(&rusages, i);
|
|
|
|
TEST_ASSERT_TRUE(v != NULL);
|
|
switch (i) {
|
|
case 0:
|
|
TEST_ASSERT_TRUE(strcmp(v->res, "mem") == 0);
|
|
TEST_ASSERT_TRUE(fabs(v->value - 20.0) < 0.001);
|
|
TEST_ASSERT_TRUE(fabs(v->duration - 18000) < 0.001);
|
|
TEST_ASSERT_TRUE(v->per_flag == PER_DEFAULT);
|
|
TEST_ASSERT_TRUE(v->decay_flag == 1);
|
|
break;
|
|
case 1:
|
|
TEST_ASSERT_TRUE(strcmp(v->res, "lic") == 0);
|
|
TEST_ASSERT_TRUE(fabs(v->value - 55.0) < 0.001);
|
|
TEST_ASSERT_TRUE(fabs(v->duration - 1200) < 0.001);
|
|
TEST_ASSERT_TRUE(v->per_flag == PER_DEFAULT);
|
|
TEST_ASSERT_TRUE(v->decay_flag == 0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
printf("rusage: %s %f %d %f %d\n", v->res, v->value, v->per_flag,
|
|
v->duration, v->decay_flag);
|
|
|
|
kill_rusage_value(v);
|
|
free(v);
|
|
}
|
|
|
|
xlist_fini(&rusages);
|
|
}
|
|
}
|
|
|
|
void test_parse_rusage2(void)
|
|
{
|
|
char* rusageString
|
|
= "mem=20/host:duration=300:decay=1,lic=55/job:duration=20m:decay=0";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xlist_t rusages;
|
|
|
|
xlist_init(&rusages, 8);
|
|
|
|
rc = parse_rusage(&rusages, rusageString, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
|
|
if (rc >= 0) {
|
|
int i;
|
|
|
|
for (i = 0; i < rusages.count; i++) {
|
|
rusage_value_t* v = (rusage_value_t*)xlist_get(&rusages, i);
|
|
|
|
TEST_ASSERT_TRUE(v != NULL);
|
|
switch (i) {
|
|
case 0:
|
|
TEST_ASSERT_TRUE(strcmp(v->res, "mem") == 0);
|
|
TEST_ASSERT_TRUE(fabs(v->value - 20.0) < 0.001);
|
|
TEST_ASSERT_TRUE(fabs(v->duration - 18000) < 0.001);
|
|
TEST_ASSERT_TRUE(v->per_flag == PER_HOST);
|
|
TEST_ASSERT_TRUE(v->decay_flag == 1);
|
|
break;
|
|
case 1:
|
|
TEST_ASSERT_TRUE(strcmp(v->res, "lic") == 0);
|
|
TEST_ASSERT_TRUE(fabs(v->value - 55.0) < 0.001);
|
|
TEST_ASSERT_TRUE(fabs(v->duration - 1200) < 0.001);
|
|
TEST_ASSERT_TRUE(v->per_flag == PER_JOB);
|
|
TEST_ASSERT_TRUE(v->decay_flag == 0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
printf("rusage: %s %f %d %f %d\n", v->res, v->value, v->per_flag,
|
|
v->duration, v->decay_flag);
|
|
|
|
kill_rusage_value(v);
|
|
free(v);
|
|
}
|
|
|
|
xlist_fini(&rusages);
|
|
}
|
|
}
|
|
|
|
void test_resreq_primary(void)
|
|
{
|
|
char* resreqString
|
|
= "select[type==any] "
|
|
"rusage[mem=20:duration=300:decay=1,lic=55:duration=20m:decay=0]";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_primary_resreq_t resreq;
|
|
|
|
rc = parse_resreq_primary(&resreq, resreqString, NULL, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
if (rc >= 0) {
|
|
int i;
|
|
xlist_t* rusages = &(resreq.rusages);
|
|
|
|
for (i = 0; i < rusages->count; i++) {
|
|
rusage_value_t* v = (rusage_value_t*)xlist_get(rusages, i);
|
|
|
|
TEST_ASSERT_TRUE(v != NULL);
|
|
switch (i) {
|
|
case 0:
|
|
TEST_ASSERT_TRUE(strcmp(v->res, "mem") == 0);
|
|
TEST_ASSERT_TRUE(fabs(v->value - 20.0) < 0.001);
|
|
TEST_ASSERT_TRUE(fabs(v->duration - 18000) < 0.001);
|
|
TEST_ASSERT_TRUE(v->per_flag == PER_DEFAULT);
|
|
TEST_ASSERT_TRUE(v->decay_flag == 1);
|
|
break;
|
|
case 1:
|
|
TEST_ASSERT_TRUE(strcmp(v->res, "lic") == 0);
|
|
TEST_ASSERT_TRUE(fabs(v->value - 55.0) < 0.001);
|
|
TEST_ASSERT_TRUE(fabs(v->duration - 1200) < 0.001);
|
|
TEST_ASSERT_TRUE(v->per_flag == PER_DEFAULT);
|
|
TEST_ASSERT_TRUE(v->decay_flag == 0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
printf("rusage: %s %f %d %f %d\n", v->res, v->value, v->per_flag,
|
|
v->duration, v->decay_flag);
|
|
|
|
kill_rusage_value(v);
|
|
free(v);
|
|
}
|
|
|
|
xlist_fini(rusages);
|
|
}
|
|
}
|
|
|
|
void test_resreq_primary2(void)
|
|
{
|
|
char* resreqString
|
|
= "select[type==any] ";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_primary_resreq_t resreq;
|
|
|
|
rc = parse_resreq_primary(&resreq, resreqString, NULL, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
if (rc >= 0) {
|
|
int i;
|
|
xlist_t* rusages = &(resreq.rusages);
|
|
|
|
TEST_ASSERT_TRUE(rusages->count == 0);
|
|
|
|
xlist_fini(rusages);
|
|
}
|
|
}
|
|
|
|
void test_resreq1(void)
|
|
{
|
|
char* resreqString
|
|
= "select[type==any] "
|
|
"rusage[mem=20:duration=300:decay=1,lic=55:duration=20m:decay=0]";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_t resreq;
|
|
|
|
rc = parse_resreq(&resreq, resreqString, NULL, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
if (rc >= 0) {
|
|
int i;
|
|
xlist_t* rusages = NULL;
|
|
char* buf = NULL;
|
|
|
|
TEST_ASSERT_TRUE(resreq.tag == XCE_RESREQ_PRIMARY);
|
|
|
|
rusages = &(resreq.u.primary->rusages);
|
|
|
|
for (i = 0; i < rusages->count; i++) {
|
|
rusage_value_t* v = (rusage_value_t*)xlist_get(rusages, i);
|
|
|
|
TEST_ASSERT_TRUE(v != NULL);
|
|
switch (i) {
|
|
case 0:
|
|
TEST_ASSERT_TRUE(strcmp(v->res, "mem") == 0);
|
|
TEST_ASSERT_TRUE(fabs(v->value - 20.0) < 0.001);
|
|
TEST_ASSERT_TRUE(fabs(v->duration - 18000) < 0.001);
|
|
TEST_ASSERT_TRUE(v->per_flag == PER_DEFAULT);
|
|
TEST_ASSERT_TRUE(v->decay_flag == 1);
|
|
break;
|
|
case 1:
|
|
TEST_ASSERT_TRUE(strcmp(v->res, "lic") == 0);
|
|
TEST_ASSERT_TRUE(fabs(v->value - 55.0) < 0.001);
|
|
TEST_ASSERT_TRUE(fabs(v->duration - 1200) < 0.001);
|
|
TEST_ASSERT_TRUE(v->per_flag == PER_DEFAULT);
|
|
TEST_ASSERT_TRUE(v->decay_flag == 0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
printf("rusage: %s %f %d %f %d\n", v->res, v->value, v->per_flag,
|
|
v->duration, v->decay_flag);
|
|
}
|
|
|
|
rc = format_resreq(&buf, &resreq);
|
|
if (rc >= 0) {
|
|
printf("%s\n", buf);
|
|
}
|
|
|
|
FREEUP(buf);
|
|
kill_resreq(&resreq);
|
|
}
|
|
}
|
|
|
|
void test_resreq2(void)
|
|
{
|
|
char* resreqString = "2*{rusage[mem=100:duration=20:decay=1]} + "
|
|
"4*{rusage[mem=80:duration=30:decay=1]}";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_t resreq;
|
|
|
|
memset(&resreq, 0x0, sizeof(resreq));
|
|
|
|
rc = parse_resreq(&resreq, resreqString, NULL, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
if (rc >= 0) {
|
|
char* buf = NULL;
|
|
|
|
TEST_ASSERT_TRUE(resreq.tag == XCE_RESREQ_COMPOUND);
|
|
|
|
rc = format_resreq(&buf, &resreq);
|
|
if (rc >= 0) {
|
|
printf("%s\n", buf);
|
|
}
|
|
|
|
FREEUP(buf);
|
|
kill_resreq(&resreq);
|
|
}
|
|
}
|
|
|
|
void test_resreq3(void)
|
|
{
|
|
char* resreqString = "{2*{rusage[mem=100:duration=20:decay=1]} + "
|
|
"4*{rusage[mem=80:duration=30:decay=1]}} || "
|
|
"{3*{rusage[mem=150:duration=15:decay=1]} + "
|
|
"6*{rusage[mem=120:duration=20:decay=1]}} ";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_t resreq;
|
|
|
|
memset(&resreq, 0x0, sizeof(resreq));
|
|
|
|
rc = parse_resreq(&resreq, resreqString, NULL, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
if (rc >= 0) {
|
|
char* buf = NULL;
|
|
|
|
TEST_ASSERT_TRUE(resreq.tag == XCE_RESREQ_ALTER);
|
|
|
|
rc = format_resreq(&buf, &resreq);
|
|
if (rc >= 0) {
|
|
printf("%s\n", buf);
|
|
}
|
|
|
|
if (buf != NULL) {
|
|
free(buf);
|
|
}
|
|
|
|
kill_resreq(&resreq);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Boundary tests for the P0-2 span-bleed fix in section.peg.
|
|
*
|
|
* Before the fix line 50 read: !("span[]" / "]")
|
|
* After the fix line 50 reads: !("span[" / "]")
|
|
*
|
|
* With the old grammar the negative lookahead would only suppress
|
|
* consumption of the literal token "span[]", so any span clause
|
|
* with content (e.g. "span[ptile=1]") was silently absorbed into
|
|
* selectString. These tests verify the corrected boundary.
|
|
*/
|
|
|
|
/* Test 1: explicit select[...] with a non-empty span[...] clause. */
|
|
void test_parse_section_explicit_select_with_span(void)
|
|
{
|
|
char* resreq = "select[type==linux] span[ptile=1]";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_data_t data = {0};
|
|
|
|
rc = parse_section(&data, (char*)resreq, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
|
|
printf("select: %s\n", data.selectString ? data.selectString : "(null)");
|
|
printf("span: %s\n", data.spanString ? data.spanString : "(null)");
|
|
|
|
/* select must contain the predicate, not bleed into the span keyword */
|
|
TEST_ASSERT_TRUE(data.selectString != NULL);
|
|
TEST_ASSERT_TRUE(strstr(data.selectString, "type==linux") != NULL);
|
|
|
|
/* span must be parsed separately and hold only its content */
|
|
TEST_ASSERT_TRUE(data.spanString != NULL);
|
|
TEST_ASSERT_TRUE(strstr(data.spanString, "ptile=1") != NULL);
|
|
|
|
/* unrelated clauses must be absent */
|
|
TEST_ASSERT_TRUE(data.rusageString == NULL);
|
|
TEST_ASSERT_TRUE(data.sameString == NULL);
|
|
TEST_ASSERT_TRUE(data.affinityString == NULL);
|
|
|
|
FREEUP(data.selectString);
|
|
FREEUP(data.spanString);
|
|
FREEUP(errmsg);
|
|
}
|
|
|
|
/* Test 2: all three major clauses — select, rusage, span — in one string. */
|
|
void test_parse_section_explicit_select_rusage_span(void)
|
|
{
|
|
char* resreq = "select[a&&b] rusage[mem=100] span[ptile=2]";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_data_t data = {0};
|
|
|
|
rc = parse_section(&data, (char*)resreq, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
|
|
printf("select: %s\n", data.selectString ? data.selectString : "(null)");
|
|
printf("rusage: %s\n", data.rusageString ? data.rusageString : "(null)");
|
|
printf("span: %s\n", data.spanString ? data.spanString : "(null)");
|
|
|
|
TEST_ASSERT_TRUE(data.selectString != NULL);
|
|
TEST_ASSERT_TRUE(strstr(data.selectString, "a&&b") != NULL);
|
|
|
|
TEST_ASSERT_TRUE(data.rusageString != NULL);
|
|
TEST_ASSERT_TRUE(strstr(data.rusageString, "mem=100") != NULL);
|
|
|
|
TEST_ASSERT_TRUE(data.spanString != NULL);
|
|
TEST_ASSERT_TRUE(strstr(data.spanString, "ptile=2") != NULL);
|
|
|
|
FREEUP(data.selectString);
|
|
FREEUP(data.rusageString);
|
|
FREEUP(data.spanString);
|
|
FREEUP(errmsg);
|
|
}
|
|
|
|
/*
|
|
* Test 3: the core regression guard — selectString must NOT contain the
|
|
* substring "span" when a span clause is present. With the old buggy
|
|
* grammar the span clause text would bleed into selectString.
|
|
*/
|
|
void test_parse_section_span_not_in_select(void)
|
|
{
|
|
char* resreq = "select[gpu] span[ptile=4]";
|
|
char* errmsg = NULL;
|
|
int rc = 0;
|
|
xce_resreq_data_t data = {0};
|
|
|
|
rc = parse_section(&data, (char*)resreq, &errmsg);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
|
|
printf("select: %s\n", data.selectString ? data.selectString : "(null)");
|
|
printf("span: %s\n", data.spanString ? data.spanString : "(null)");
|
|
|
|
/* selectString must not contain the span keyword (bleed check) */
|
|
TEST_ASSERT_TRUE(data.selectString != NULL);
|
|
TEST_ASSERT_TRUE(strstr(data.selectString, "span") == NULL);
|
|
|
|
/* span content must be correctly isolated */
|
|
TEST_ASSERT_TRUE(data.spanString != NULL);
|
|
TEST_ASSERT_TRUE(strstr(data.spanString, "ptile=4") != NULL);
|
|
|
|
FREEUP(data.selectString);
|
|
FREEUP(data.spanString);
|
|
FREEUP(errmsg);
|
|
}
|
|
|
|
void test_resreq(void)
|
|
{
|
|
printf("\n>> resreq test\n\n");
|
|
|
|
RUN_TEST(test_parse_section1);
|
|
RUN_TEST(test_parse_section2);
|
|
RUN_TEST(test_parse_section_fail);
|
|
RUN_TEST(test_parse_section3);
|
|
RUN_TEST(test_parse_rusage1);
|
|
RUN_TEST(test_parse_rusage2);
|
|
RUN_TEST(test_resreq_primary);
|
|
RUN_TEST(test_resreq_primary2);
|
|
RUN_TEST(test_resreq1);
|
|
RUN_TEST(test_resreq2);
|
|
RUN_TEST(test_resreq3);
|
|
RUN_TEST(test_parse_section_explicit_select_with_span);
|
|
RUN_TEST(test_parse_section_explicit_select_rusage_span);
|
|
RUN_TEST(test_parse_section_span_not_in_select);
|
|
}
|