diff --git a/src/cmd/flux-account-priority-update.py b/src/cmd/flux-account-priority-update.py index 10b21854..f9031b54 100755 --- a/src/cmd/flux-account-priority-update.py +++ b/src/cmd/flux-account-priority-update.py @@ -71,12 +71,14 @@ def bulk_update(path): data = {} bulk_user_data = [] bulk_q_data = [] + bulk_proj_data = [] # fetch all rows from association_table (will print out tuples) for row in cur.execute( """SELECT userid, bank, default_bank, fairshare, max_running_jobs, max_active_jobs, - queues, active FROM association_table""" + queues, active, projects, default_project + FROM association_table""" ): # create a JSON payload with the results of the query single_user_data = { @@ -88,6 +90,8 @@ def bulk_update(path): "max_active_jobs": int(row[5]), "queues": str(row[6]), "active": int(row[7]), + "projects": str(row[8]), + "def_project": str(row[9]), } bulk_user_data.append(single_user_data) @@ -111,6 +115,17 @@ def bulk_update(path): flux.Flux().rpc("job-manager.mf_priority.rec_q_update", json.dumps(data)).get() + # fetch all rows from project_table + for row in cur.execute("SELECT project FROM project_table"): + # create a JSON payload with the results of the query + single_project = { + "project": str(row[0]), + } + bulk_proj_data.append(single_project) + + data = {"data": bulk_proj_data} + flux.Flux().rpc("job-manager.mf_priority.rec_proj_update", data).get() + flux.Flux().rpc("job-manager.mf_priority.reprioritize") # close DB connection diff --git a/src/plugins/accounting.cpp b/src/plugins/accounting.cpp index 6282724c..070e1309 100644 --- a/src/plugins/accounting.cpp +++ b/src/plugins/accounting.cpp @@ -187,3 +187,23 @@ bool check_map_for_dne_only (std::map> return true; } + + +int get_project_info (const char *project, + std::vector &permissible_projects, + std::vector projects) +{ + auto it = std::find (projects.begin (), projects.end (), project); + if (it == projects.end ()) + // project is unknown to flux-accounting + return UNKNOWN_PROJECT; + + it = std::find (permissible_projects.begin (), + permissible_projects.end (), + project); + if (it == permissible_projects.end ()) + // association doesn't have access to submit jobs under this project + return INVALID_PROJECT; + + return 0; +} diff --git a/src/plugins/accounting.hpp b/src/plugins/accounting.hpp index 0b9bf2f7..1fe5f76c 100644 --- a/src/plugins/accounting.hpp +++ b/src/plugins/accounting.hpp @@ -32,16 +32,18 @@ extern "C" { class Association { public: // attributes - std::string bank_name; // name of bank - double fairshare; // fair share value - int max_run_jobs; // max number of running jobs - int cur_run_jobs; // current number of running jobs - int max_active_jobs; // max number of active jobs - int cur_active_jobs; // current number of active jobs - std::vector held_jobs; // list of currently held job ID's - std::vector queues; // list of accessible queues - int queue_factor; // priority factor associated with queue - int active; // active status + std::string bank_name; // name of bank + double fairshare; // fair share value + int max_run_jobs; // max number of running jobs + int cur_run_jobs; // current number of running jobs + int max_active_jobs; // max number of active jobs + int cur_active_jobs; // current number of active jobs + std::vector held_jobs; // list of currently held job ID's + std::vector queues; // list of accessible queues + int queue_factor; // priority factor associated with queue + int active; // active status + std::vector projects; // list of accessible projects + std::string def_project; // default project // methods json_t* to_json () const; // convert object to JSON string @@ -56,6 +58,12 @@ class Association { #define NO_QUEUE_SPECIFIED 0 #define INVALID_QUEUE -6 +// - UNKNOWN_PROJECT: a project that flux-accounting doesn't know about +// - INVALID_PROJECT: a project that the association doesn't have permission +// to charge jobs under +#define UNKNOWN_PROJECT -6 +#define INVALID_PROJECT -7 + // min_nodes_per_job, max_nodes_per_job, and max_time_per_job are not // currently used or enforced in this plugin, so their values have no // effect in queue limit enforcement. @@ -96,4 +104,9 @@ bool check_map_for_dne_only (std::map> &users, std::map &users_def_bank); +// validate a potentially passed-in project by an association +int get_project_info (const char *project, + std::vector &permissible_projects, + std::vector projects); + #endif // ACCOUNTING_H diff --git a/src/plugins/mf_priority.cpp b/src/plugins/mf_priority.cpp index 38971d0c..59907c62 100644 --- a/src/plugins/mf_priority.cpp +++ b/src/plugins/mf_priority.cpp @@ -40,6 +40,7 @@ extern "C" { std::map> users; std::map queues; std::map users_def_bank; +std::vector projects; /****************************************************************************** * * @@ -205,7 +206,7 @@ static void rec_update_cb (flux_t *h, const flux_msg_t *msg, void *arg) { - char *bank, *def_bank, *assoc_queues = NULL; + char *bank, *def_bank, *assoc_queues, *projects, *def_project = NULL; int uid, max_running_jobs, max_active_jobs = 0; double fshare = 0.0; json_t *data, *jtemp = NULL; @@ -232,7 +233,8 @@ static void rec_update_cb (flux_t *h, json_t *el = json_array_get(data, i); if (json_unpack_ex (el, &error, 0, - "{s:i, s:s, s:s, s:F, s:i, s:i, s:s, s:i}", + "{s:i, s:s, s:s, s:F, s:i," + " s:i, s:s, s:i, s:s, s:s}", "userid", &uid, "bank", &bank, "def_bank", &def_bank, @@ -240,7 +242,9 @@ static void rec_update_cb (flux_t *h, "max_running_jobs", &max_running_jobs, "max_active_jobs", &max_active_jobs, "queues", &assoc_queues, - "active", &active) < 0) + "active", &active, + "projects", &projects, + "def_project", &def_project) < 0) flux_log (h, LOG_ERR, "mf_priority unpack: %s", error.text); Association *b; @@ -251,10 +255,14 @@ static void rec_update_cb (flux_t *h, b->max_run_jobs = max_running_jobs; b->max_active_jobs = max_active_jobs; b->active = active; + b->def_project = def_project; // split queues comma-delimited string and add it to b->queues vector b->queues.clear (); split_string_and_push_back (assoc_queues, b->queues); + // do the same thing for the association's projects + b->projects.clear (); + split_string_and_push_back (projects, b->projects); users_def_bank[uid] = def_bank; } @@ -323,6 +331,53 @@ static void rec_q_cb (flux_t *h, } +/* + * Unpack a payload from an external bulk update service and place it in the + * "projects" vector. + */ +static void rec_proj_cb (flux_t *h, + flux_msg_handler_t *mh, + const flux_msg_t *msg, + void *arg) +{ + char *project = NULL; + json_t *data, *jtemp = NULL; + json_error_t error; + int num_data = 0; + size_t index; + json_t *el; + + if (flux_request_unpack (msg, NULL, "{s:o}", "data", &data) < 0) { + flux_log_error (h, "failed to unpack custom_priority.trigger msg"); + goto error; + } + + if (!data || !json_is_array (data)) { + flux_log (h, LOG_ERR, "mf_priority: invalid project info payload"); + goto error; + } + num_data = json_array_size (data); + + // clear the projects vector + projects.clear (); + + json_array_foreach (data, index, el) { + if (json_unpack_ex (el, &error, 0, "{s:s}", "project", &project) < 0) { + flux_log (h, LOG_ERR, "mf_priority unpack: %s", error.text); + goto error; + } + projects.push_back (project); + } + + if (flux_respond (h, msg, NULL) < 0) + flux_log_error (h, "flux_respond"); + + return; +error: + flux_respond_error (h, msg, errno, flux_msg_last_error (msg)); +} + + static void reprior_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, @@ -1005,9 +1060,11 @@ static const struct flux_plugin_handler tab[] = { extern "C" int flux_plugin_init (flux_plugin_t *p) { if (flux_plugin_register (p, "mf_priority", tab) < 0 - || flux_jobtap_service_register (p, "rec_update", rec_update_cb, p) - || flux_jobtap_service_register (p, "reprioritize", reprior_cb, p) - || flux_jobtap_service_register (p, "rec_q_update", rec_q_cb, p) < 0) + || flux_jobtap_service_register (p, "rec_update", rec_update_cb, p) < 0 + || flux_jobtap_service_register (p, "reprioritize", reprior_cb, p) < 0 + || flux_jobtap_service_register (p, "rec_q_update", rec_q_cb, p) < 0 + || flux_jobtap_service_register (p, "rec_proj_update", rec_proj_cb, p) + < 0) return -1; return 0; diff --git a/src/plugins/test/accounting_test01.cpp b/src/plugins/test/accounting_test01.cpp index 4ddff822..536fbbf8 100644 --- a/src/plugins/test/accounting_test01.cpp +++ b/src/plugins/test/accounting_test01.cpp @@ -28,6 +28,8 @@ std::map> users; std::map users_def_bank; // define a test queues map std::map queues; +// define a vector of chargeable projects +std::vector projects; /* @@ -50,7 +52,9 @@ void add_user_to_map ( a.held_jobs, a.queues, a.queue_factor, - a.active + a.active, + a.projects, + a.def_project }; } @@ -61,8 +65,8 @@ void add_user_to_map ( void initialize_map ( std::map> &users) { - Association user1 = {"bank_A", 0.5, 5, 0, 7, 0, {}, {}, 0, 1}; - Association user2 = {"bank_A", 0.5, 5, 0, 7, 0, {}, {}, 0, 1}; + Association user1 = {"bank_A", 0.5, 5, 0, 7, 0, {}, {}, 0, 1, {"*"}, "*"}; + Association user2 = {"bank_A", 0.5, 5, 0, 7, 0, {}, {}, 0, 1, {"*"}, "*"}; add_user_to_map (users, 1001, "bank_A", user1); users_def_bank[1001] = "bank_A"; @@ -82,6 +86,17 @@ void initialize_queues () { } +/* + * helper function to add test projects to the projects vector + */ +void initialize_projects () { + projects.push_back ("*"); + projects.push_back ("A"); + projects.push_back ("B"); + projects.push_back ("C"); +} + + // ensure we can access a user/bank in the users map static void test_direct_map_access ( std::map> &users) @@ -189,6 +204,54 @@ static void test_get_queue_info_invalid_queue () } +// ensure user has access to a default project +static void test_get_project_info_success_default () +{ + Association a = users[1001]["bank_A"]; + const char *p = "*"; + int result = get_project_info (p, a.projects, projects); + + ok (result == 0, "association has access to default project"); +} + + +// ensure we can access projects that we add to an association +static void test_get_project_info_success_specified () +{ + Association a = users[1001]["bank_A"]; + a.projects = {"*", "A"}; + const char *p = "A"; + + int result = get_project_info (p, a.projects, projects); + + ok (result == 0, "association has access to a specified project"); +} + + +// ensure UNKNOWN_PROJECT is returned when an unrecognized project is passed in +static void test_get_project_info_unknown_project () +{ + Association a = users[1001]["bank_A"]; + const char *p = "foo"; + int result = get_project_info (p, a.projects, projects); + + ok (result == UNKNOWN_PROJECT, + "UNKNOWN_PROJECT is returned when an unrecognized project is passed in"); +} + + +// ensure INVALID_PROJECT is returned when an invalid project is passed in +static void test_get_project_info_invalid_project () +{ + Association a = users[1001]["bank_A"]; + const char *p = "B"; + int result = get_project_info (p, a.projects, projects); + + ok (result == INVALID_PROJECT, + "INVALID_PROJECT is returned when an inaccessible project is passed in"); +} + + // ensure false is returned because we have valid flux-accounting data in map static void test_check_map_dne_false () { @@ -204,7 +267,7 @@ static void test_check_map_dne_true () users.clear (); users_def_bank.clear (); - Association tmp_user = {"DNE", 0.5, 5, 0, 7, 0, {}, {}, 0, 1}; + Association tmp_user = {"DNE", 0.5, 5, 0, 7, 0, {}, {}, 0, 1, {"*"}, "*"}; add_user_to_map (users, 9999, "DNE", tmp_user); users_def_bank[9999] = "DNE"; @@ -217,12 +280,14 @@ static void test_check_map_dne_true () int main (int argc, char* argv[]) { // declare the number of tests that we plan to run - plan (11); + plan (15); // add users to the test map initialize_map (users); // add queues to the test queues map initialize_queues (); + // add projects to the test projects vector + initialize_projects (); test_direct_map_access (users); test_get_association_success (); @@ -233,6 +298,10 @@ int main (int argc, char* argv[]) test_get_queue_info_no_queue_specified (); test_get_queue_info_unknown_queue (); test_get_queue_info_invalid_queue (); + test_get_project_info_success_default (); + test_get_project_info_success_specified (); + test_get_project_info_unknown_project (); + test_get_project_info_invalid_project (); test_check_map_dne_false (); test_check_map_dne_true (); diff --git a/t/expected/sample_payloads/same_fairshare.json b/t/expected/sample_payloads/same_fairshare.json index f43647a1..aa08f069 100644 --- a/t/expected/sample_payloads/same_fairshare.json +++ b/t/expected/sample_payloads/same_fairshare.json @@ -8,7 +8,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5012, @@ -18,7 +20,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5013, @@ -29,7 +33,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5021, @@ -39,7 +45,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5022, @@ -49,7 +57,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5031, @@ -59,7 +69,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5032, @@ -69,7 +81,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" } ] } diff --git a/t/expected/sample_payloads/small_no_tie.json b/t/expected/sample_payloads/small_no_tie.json index c7bacec7..a8ace2e3 100644 --- a/t/expected/sample_payloads/small_no_tie.json +++ b/t/expected/sample_payloads/small_no_tie.json @@ -8,7 +8,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5012, @@ -18,7 +20,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5013, @@ -28,7 +32,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5021, @@ -38,7 +44,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5022, @@ -48,7 +56,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5031, @@ -58,7 +68,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5032, @@ -68,7 +80,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" } ] } diff --git a/t/expected/sample_payloads/small_tie.json b/t/expected/sample_payloads/small_tie.json index d443d923..3f44f68e 100644 --- a/t/expected/sample_payloads/small_tie.json +++ b/t/expected/sample_payloads/small_tie.json @@ -8,7 +8,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5012, @@ -18,7 +20,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5013, @@ -28,7 +32,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5021, @@ -38,7 +44,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5022, @@ -48,7 +56,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5023, @@ -58,7 +68,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5031, @@ -68,7 +80,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5032, @@ -78,7 +92,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" } ] } diff --git a/t/expected/sample_payloads/small_tie_all.json b/t/expected/sample_payloads/small_tie_all.json index 4418b4b2..e2d638c5 100644 --- a/t/expected/sample_payloads/small_tie_all.json +++ b/t/expected/sample_payloads/small_tie_all.json @@ -8,7 +8,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5012, @@ -18,7 +20,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5013, @@ -28,7 +32,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5021, @@ -38,7 +44,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5022, @@ -48,7 +56,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5023, @@ -58,7 +68,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5031, @@ -68,7 +80,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5032, @@ -78,7 +92,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5033, @@ -88,7 +104,9 @@ "max_running_jobs": 5, "max_active_jobs": 7, "queues": "", - "active": 1 + "active": 1, + "projects": "*", + "def_project": "*" } ] } diff --git a/t/t1001-mf-priority-basic.t b/t/t1001-mf-priority-basic.t index 5e526697..dcbfedd9 100755 --- a/t/t1001-mf-priority-basic.t +++ b/t/t1001-mf-priority-basic.t @@ -51,7 +51,10 @@ test_expect_success 'create fake_payload.py' ' "fairshare": 0.45321, "max_running_jobs": 10, "max_active_jobs": 12, - "queues": "standby,special" + "queues": "standby,special", + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": userid, @@ -60,7 +63,10 @@ test_expect_success 'create fake_payload.py' ' "fairshare": 0.11345, "max_running_jobs": 10, "max_active_jobs": 12, - "queues": "standby" + "queues": "standby", + "active": 1, + "projects": "*", + "def_project": "*" } ] } @@ -167,7 +173,10 @@ test_expect_success 'pass special key to user/bank struct to nullify information "fairshare": 0.45321, "max_running_jobs": -1, "max_active_jobs": 12, - "queues": "standby,special" + "queues": "standby,special", + "active": 1, + "projects": "*", + "def_project": "*" } ] } @@ -195,7 +204,10 @@ test_expect_success 'resend user/bank information with valid data and successful "fairshare": 0.45321, "max_running_jobs": 2, "max_active_jobs": 4, - "queues": "standby,special" + "queues": "standby,special", + "active": 1, + "projects": "*", + "def_project": "*" } ] } diff --git a/t/t1005-max-jobs-limits.t b/t/t1005-max-jobs-limits.t index ea8cd0db..71c4e4b2 100755 --- a/t/t1005-max-jobs-limits.t +++ b/t/t1005-max-jobs-limits.t @@ -32,7 +32,10 @@ test_expect_success 'create fake_user.json' ' "fairshare": 0.45321, "max_running_jobs": 2, "max_active_jobs": 4, - "queues": "" + "queues": "", + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5011, @@ -41,7 +44,10 @@ test_expect_success 'create fake_user.json' ' "fairshare": 0.11345, "max_running_jobs": 1, "max_active_jobs": 2, - "queues": "" + "queues": "", + "active": 1, + "projects": "*", + "def_project": "*" } ] } @@ -123,7 +129,10 @@ test_expect_success 'increase the max jobs count of the user' ' "fairshare": 0.45321, "max_running_jobs": 3, "max_active_jobs": 4, - "queues": "" + "queues": "", + "active": 1, + "projects": "*", + "def_project": "*" } ] } @@ -172,7 +181,10 @@ test_expect_success 'update max_active_jobs limit' ' "fairshare": 0.45321, "max_running_jobs": 3, "max_active_jobs": 5, - "queues": "" + "queues": "", + "active": 1, + "projects": "*", + "def_project": "*" } ] } @@ -229,7 +241,10 @@ test_expect_success 'create another user with the same limits in multiple banks' "fairshare": 0.45321, "max_running_jobs": 1, "max_active_jobs": 2, - "queues": "" + "queues": "", + "active": 1, + "projects": "*", + "def_project": "*" }, { "userid": 5012, @@ -238,7 +253,10 @@ test_expect_success 'create another user with the same limits in multiple banks' "fairshare": 0.11345, "max_running_jobs": 1, "max_active_jobs": 2, - "queues": "" + "queues": "", + "active": 1, + "projects": "*", + "def_project": "*" } ] } diff --git a/t/t1012-mf-priority-load.t b/t/t1012-mf-priority-load.t index 9e01c382..869ffc8a 100755 --- a/t/t1012-mf-priority-load.t +++ b/t/t1012-mf-priority-load.t @@ -32,8 +32,30 @@ test_expect_success 'create fake_payload.py' ' # create an array of JSON payloads bulk_update_data = { "data" : [ - {"userid": userid, "bank": "account3", "def_bank": "account3", "fairshare": 0.45321, "max_running_jobs": 1, "max_active_jobs": 3}, - {"userid": userid, "bank": "account2", "def_bank": "account3", "fairshare": 0.11345, "max_running_jobs": 1, "max_active_jobs": 3} + { + "userid": userid, + "bank": "account3", + "def_bank": "account3", + "fairshare": 0.45321, + "max_running_jobs": 1, + "max_active_jobs": 3, + "queues": "", + "active": 1, + "projects": "*", + "def_project": "*" + }, + { + "userid": userid, + "bank": "account2", + "def_bank": "account3", + "fairshare": 0.11345, + "max_running_jobs": 1, + "max_active_jobs": 3, + "queues": "", + "active": 1, + "projects": "*", + "def_project": "*" + } ] } flux.Flux().rpc("job-manager.mf_priority.rec_update", json.dumps(bulk_update_data)).get() diff --git a/t/t1014-mf-priority-dne.t b/t/t1014-mf-priority-dne.t index a3ca34b1..978cb412 100755 --- a/t/t1014-mf-priority-dne.t +++ b/t/t1014-mf-priority-dne.t @@ -63,7 +63,10 @@ test_expect_success 'send the user/bank information to the plugin without reprio "fairshare": 0.45321, "max_running_jobs": 10, "max_active_jobs": 12, - "queues": "standby,special" + "queues": "standby,special", + "active": 1, + "projects": "*", + "def_project": "*" } ] }