diff --git a/src/modules/job-list/Makefile.am b/src/modules/job-list/Makefile.am index 6e01d49f5c24..7278d7b9f812 100644 --- a/src/modules/job-list/Makefile.am +++ b/src/modules/job-list/Makefile.am @@ -110,6 +110,7 @@ EXTRA_DIST = \ test/jobspec/1slot.jobspec \ test/jobspec/1slot_4core.jobspec \ test/jobspec/1slot_perresourcecore4.jobspec \ + test/jobspec/1slot_project_bank.jobspec \ test/jobspec/4node.jobspec \ test/jobspec/4node_1slot_nonexclusive.jobspec \ test/jobspec/4node_4slot_nonexclusive.jobspec \ diff --git a/src/modules/job-list/job-list.c b/src/modules/job-list/job-list.c index c84ea2d923b2..d794b0cbea31 100644 --- a/src/modules/job-list/job-list.c +++ b/src/modules/job-list/job-list.c @@ -25,7 +25,8 @@ static const char *attrs[] = { "userid", "urgency", "priority", "t_submit", "t_depend", "t_run", "t_cleanup", "t_inactive", - "state", "name", "cwd", "queue", "ntasks", "ncores", "duration", "nnodes", + "state", "name", "cwd", "queue", "project", "bank", + "ntasks", "ncores", "duration", "nnodes", "ranks", "nodelist", "success", "exception_occurred", "exception_type", "exception_severity", "exception_note", "result", "expiration", diff --git a/src/modules/job-list/job_data.c b/src/modules/job-list/job_data.c index 95901d8a90c1..1222e68a62b7 100644 --- a/src/modules/job-list/job_data.c +++ b/src/modules/job-list/job_data.c @@ -197,12 +197,14 @@ static int parse_attributes_dict (struct job *job) job->cwd = NULL; job->queue = NULL; if (json_unpack_ex (job->jobspec, &error, 0, - "{s:{s?{s?s s?s s:F}}}", + "{s:{s?{s?s s?s s:F s?s s?s}}}", "attributes", "system", "cwd", &job->cwd, "queue", &job->queue, - "duration", &job->duration) < 0) { + "duration", &job->duration, + "project", &job->project, + "bank", &job->bank) < 0) { flux_log (job->h, LOG_ERR, "%s: job %s invalid jobspec: %s", __FUNCTION__, idf58 (job->id), error.text); diff --git a/src/modules/job-list/job_data.h b/src/modules/job-list/job_data.h index 4970dbb6035b..713efd5a8e8d 100644 --- a/src/modules/job-list/job_data.h +++ b/src/modules/job-list/job_data.h @@ -45,6 +45,8 @@ struct job { const char *name; const char *queue; const char *cwd; + const char *project; + const char *bank; int ntasks; int ntasks_per_core_on_node_count; /* flag for ntasks calculation */ int ncores; diff --git a/src/modules/job-list/job_util.c b/src/modules/job-list/job_util.c index 2d26d6ef0e11..9d505352097f 100644 --- a/src/modules/job-list/job_util.c +++ b/src/modules/job-list/job_util.c @@ -110,6 +110,18 @@ static int store_attr (struct job *job, return 0; val = json_string (job->queue); } + else if (streq (attr, "project")) { + /* job->project potentially NULL, usually set via jobspec-update event */ + if (!job->project) + return 0; + val = json_string (job->project); + } + else if (streq (attr, "bank")) { + /* job->bank potentially NULL, usually set via jobspec-update event */ + if (!job->bank) + return 0; + val = json_string (job->bank); + } else if (streq (attr, "ntasks")) { /* job->ntasks potentially < 0 if jobspec invalid */ if (job->ntasks < 0) diff --git a/src/modules/job-list/test/job_data.c b/src/modules/job-list/test/job_data.c index be529aded00c..9ca287a5ab04 100644 --- a/src/modules/job-list/test/job_data.c +++ b/src/modules/job-list/test/job_data.c @@ -76,6 +76,24 @@ struct test_jobspec_queue { { NULL, 0 }, }; +struct test_jobspec_project_bank { + const char *filename; + const char *project; + const char *bank; +} jobspec_project_bank_tests[] = { + { + TEST_SRCDIR "/jobspec/1slot.jobspec", + NULL, + NULL, + }, + { + TEST_SRCDIR "/jobspec/1slot_project_bank.jobspec", + "myproject", + "mybank", + }, + { NULL, NULL, NULL}, +}; + struct test_jobspec_duration { const char *filename; double duration; @@ -425,6 +443,47 @@ static void test_jobspec_queue (void) } } +static void test_jobspec_project_bank (void) +{ + struct test_jobspec_project_bank *test; + + test = jobspec_project_bank_tests; + while (test->filename) { + struct job *job = job_create (NULL, FLUX_JOBID_ANY); + const char *filename = test->filename; + const char *project = test->project; + const char *bank = test->bank; + int ret; + + if (!job) + BAIL_OUT ("job_create failed"); + + ret = parse_jobspec (job, filename); + ok (ret == 0, "job_parse_jobspec parsed %s", filename); + if (project) { + ok (streq (project, job->project), + "job_parse_jobspec correctly parsed job project %s=%s", + project, job->project); + } + else { + ok (job->project == NULL, + "job_parse_jobspec correctly parsed no job project"); + } + if (bank) { + ok (streq (bank, job->bank), + "job_parse_jobspec correctly parsed job bank %s=%s", + bank, job->bank); + } + else { + ok (job->bank == NULL, + "job_parse_jobspec correctly parsed no job bank"); + } + + job_destroy (job); + test++; + } +} + static void test_jobspec_duration (void) { struct test_jobspec_duration *test; @@ -755,6 +814,7 @@ int main (int argc, char *argv[]) test_jobspec_job_name (); test_jobspec_cwd (); test_jobspec_queue (); + test_jobspec_project_bank (); test_jobspec_duration (); test_R_corner_case (); test_R_ranks (); diff --git a/src/modules/job-list/test/jobspec/1slot_project_bank.jobspec b/src/modules/job-list/test/jobspec/1slot_project_bank.jobspec new file mode 100644 index 000000000000..9a7bcf1d22b5 --- /dev/null +++ b/src/modules/job-list/test/jobspec/1slot_project_bank.jobspec @@ -0,0 +1,35 @@ +{ + "resources": [ + { + "type": "slot", + "count": 1, + "with": [ + { + "type": "core", + "count": 1 + } + ], + "label": "task" + } + ], + "tasks": [ + { + "command": [ + "hostname" + ], + "slot": "task", + "count": { + "per_slot": 1 + } + } + ], + "attributes": { + "system": { + "duration": 0, + "cwd": "/tmp/job", + "project": "myproject", + "bank": "mybank" + } + }, + "version": 1 +}