From 162df4189980f3b3888d1275596e36b3a890405e Mon Sep 17 00:00:00 2001 From: Hedi Ben Fradj Date: Wed, 27 Apr 2022 12:22:42 +0200 Subject: [PATCH] dird: bconsole: changed list jobs jobstatus to support multiple commas seperated values --- core/src/cats/cats.h | 2 +- core/src/cats/sql_list.cc | 8 +++-- core/src/dird/ua_output.cc | 14 ++++----- core/src/dird/ua_select.cc | 48 ++++++++++++++++++------------ core/src/dird/ua_select.h | 2 +- core/src/tests/select_functions.cc | 34 +++++---------------- 6 files changed, 50 insertions(+), 58 deletions(-) diff --git a/core/src/cats/cats.h b/core/src/cats/cats.h index 3794fba12b2..25cb455893d 100644 --- a/core/src/cats/cats.h +++ b/core/src/cats/cats.h @@ -789,7 +789,7 @@ class BareosDb : public BareosDbQueryEnum { JobDbRecord* jr, const char* range, const char* clientname, - int jobstatus, + std::vector jobstatusarray, int joblevel, std::vector jobtypes, const char* volumename, diff --git a/core/src/cats/sql_list.cc b/core/src/cats/sql_list.cc index 23d6af875fe..9a46f8b6586 100644 --- a/core/src/cats/sql_list.cc +++ b/core/src/cats/sql_list.cc @@ -507,7 +507,7 @@ void BareosDb::ListJobRecords(JobControlRecord* jcr, JobDbRecord* jr, const char* range, const char* clientname, - int jobstatus, + std::vector jobstatuslist, int joblevel, std::vector jobtypes, const char* volumename, @@ -539,8 +539,10 @@ void BareosDb::ListJobRecords(JobControlRecord* jcr, PmStrcat(selection, temp.c_str()); } - if (jobstatus) { - temp.bsprintf("AND Job.JobStatus = '%c' ", jobstatus); + if (!jobstatuslist.empty()) { + std::string jobStatuses + = CreateDelimitedStringForSqlQueries(jobstatuslist, ','); + temp.bsprintf("AND Job.JobStatus in (%s) ", jobStatuses.c_str()); PmStrcat(selection, temp.c_str()); } diff --git a/core/src/dird/ua_output.cc b/core/src/dird/ua_output.cc index 665dfab04b6..4b995e576d0 100644 --- a/core/src/dird/ua_output.cc +++ b/core/src/dird/ua_output.cc @@ -676,9 +676,9 @@ static bool DoListCmd(UaContext* ua, const char* cmd, e_list_type llist) } - // jobstatus=X - int jobstatus = 0; - if (!GetUserJobStatusSelection(ua, &jobstatus)) { + // jobstatus=X,Y,Z.... + std::vector jobstatuslist; + if (!GetUserJobStatusSelection(ua, jobstatuslist)) { ua->ErrorMsg(_("invalid jobstatus parameter\n")); return false; } @@ -756,9 +756,9 @@ static bool DoListCmd(UaContext* ua, const char* cmd, e_list_type llist) SetQueryRange(query_range, ua, &jr); ua->db->ListJobRecords(ua->jcr, &jr, query_range.c_str(), clientname, - jobstatus, joblevel, jobtypes, volumename, poolname, - schedtime, optionslist.last, optionslist.count, - ua->send, llist); + jobstatuslist, joblevel, jobtypes, volumename, + poolname, schedtime, optionslist.last, + optionslist.count, ua->send, llist); } else if (Bstrcasecmp(ua->argk[1], NT_("jobtotals"))) { // List JOBTOTALS ua->db->ListJobTotals(ua->jcr, &jr, ua->send); @@ -807,7 +807,7 @@ static bool DoListCmd(UaContext* ua, const char* cmd, e_list_type llist) SetQueryRange(query_range, ua, &jr); ua->db->ListJobRecords(ua->jcr, &jr, query_range.c_str(), clientname, - jobstatus, joblevel, jobtypes, volumename, + jobstatuslist, joblevel, jobtypes, volumename, poolname, schedtime, optionslist.last, optionslist.count, ua->send, llist); } diff --git a/core/src/dird/ua_select.cc b/core/src/dird/ua_select.cc index 3f1daa3035e..12e276691b0 100644 --- a/core/src/dird/ua_select.cc +++ b/core/src/dird/ua_select.cc @@ -994,8 +994,9 @@ PoolResource* get_pool_resource(UaContext* ua) // List all jobs and ask user to select one int SelectJobDbr(UaContext* ua, JobDbRecord* jr) { - ua->db->ListJobRecords(ua->jcr, jr, "", NULL, 0, 0, std::vector{}, NULL, - NULL, 0, 0, 0, ua->send, HORZ_LIST); + ua->db->ListJobRecords(ua->jcr, jr, "", NULL, std::vector{}, 0, + std::vector{}, NULL, NULL, 0, 0, 0, ua->send, + HORZ_LIST); if (!GetPint(ua, _("Enter the JobId to select: "))) { return 0; } jr->JobId = ua->int64_val; @@ -1952,28 +1953,37 @@ bool GetUserJobTypeListSelection(UaContext* ua, return true; } -bool GetUserJobStatusSelection(UaContext* ua, int* jobstatus) +bool GetUserJobStatusSelection(UaContext* ua, std::vector& jobstatuslist) { int i; if ((i = FindArgWithValue(ua, NT_("jobstatus"))) >= 0) { - if (strlen(ua->argv[i]) == 1 && ua->argv[i][0] >= 'A' - && ua->argv[i][0] <= 'z') { - *jobstatus = ua->argv[i][0]; - } else if (Bstrcasecmp(ua->argv[i], "terminated")) { - *jobstatus = JS_Terminated; - } else if (Bstrcasecmp(ua->argv[i], "warnings")) { - *jobstatus = JS_Warnings; - } else if (Bstrcasecmp(ua->argv[i], "canceled")) { - *jobstatus = JS_Canceled; - } else if (Bstrcasecmp(ua->argv[i], "running")) { - *jobstatus = JS_Running; - } else if (Bstrcasecmp(ua->argv[i], "error")) { - *jobstatus = JS_ErrorTerminated; - } else if (Bstrcasecmp(ua->argv[i], "fatal")) { - *jobstatus = JS_FatalError; + if (strlen(ua->argv[i]) > 0) { + std::vector jobstatusinput_list; + jobstatusinput_list = split_string(ua->argv[i], ','); + + for (auto& jobstatus : jobstatusinput_list) { + if (strlen(jobstatus.c_str()) == 1 && jobstatus.c_str()[0] >= 'A' + && jobstatus.c_str()[0] <= 'z') { + jobstatuslist.push_back(jobstatus[0]); + } else if (Bstrcasecmp(jobstatus.c_str(), "terminated")) { + jobstatuslist.push_back(JS_Terminated); + } else if (Bstrcasecmp(jobstatus.c_str(), "warnings")) { + jobstatuslist.push_back(JS_Warnings); + } else if (Bstrcasecmp(jobstatus.c_str(), "canceled")) { + jobstatuslist.push_back(JS_Canceled); + } else if (Bstrcasecmp(jobstatus.c_str(), "running")) { + jobstatuslist.push_back(JS_Running); + } else if (Bstrcasecmp(jobstatus.c_str(), "error")) { + jobstatuslist.push_back(JS_ErrorTerminated); + } else if (Bstrcasecmp(jobstatus.c_str(), "fatal")) { + jobstatuslist.push_back(JS_FatalError); + } else { + /* invalid jobstatus */ + return false; + } + } } else { - /* invalid jobstatus */ return false; } } diff --git a/core/src/dird/ua_select.h b/core/src/dird/ua_select.h index 4e10eeaa287..1b56df9f3cd 100644 --- a/core/src/dird/ua_select.h +++ b/core/src/dird/ua_select.h @@ -92,7 +92,7 @@ bool GetUserSlotList(UaContext* ua, bool GetUserJobTypeListSelection(UaContext* ua, std::vector& passed_jobtypes, bool ask_user); -bool GetUserJobStatusSelection(UaContext* ua, int* jobstatus); +bool GetUserJobStatusSelection(UaContext* ua, std::vector& jobstatus); bool GetUserJobLevelSelection(UaContext* ua, int* joblevel); int FindArgKeyword(UaContext* ua, const char** list); diff --git a/core/src/tests/select_functions.cc b/core/src/tests/select_functions.cc index 65932626824..3dbf8c54191 100644 --- a/core/src/tests/select_functions.cc +++ b/core/src/tests/select_functions.cc @@ -27,14 +27,13 @@ # include "include/bareos.h" #endif +#include + #include "dird/ua_select.h" #include "dird/ua.h" #include "include/jcr.h" #include "dird/dird_conf.h" #include "include/job_types.h" -#include "lib/util.h" - -#include namespace directordaemon { bool DoReloadConfig() { return false; } @@ -214,7 +213,7 @@ class JobStatusSelection : public testing::Test { JobControlRecord jcr{}; directordaemon::UaContext* ua{nullptr}; - std::unordered_map jobstatuses{ + std::unordered_map allowed_jobstatuses{ {JS_Terminated, "terminated"}, {JS_Warnings, "warnings"}, {JS_Canceled, "canceled"}, {JS_Running, "running"}, {JS_ErrorTerminated, "error"}, {JS_FatalError, "fatal"}}; @@ -239,7 +238,7 @@ TEST_F(JobStatusSelection, ErrorWhenJobtatusArgumentSpecifiedButNoneGiven) TEST_F(JobStatusSelection, ReturnOnlyOneJobStatusIfOnlyOneIsEntered) { - for (const auto& jobstatus : jobstatuses) { + for (const auto& jobstatus : allowed_jobstatuses) { std::vector jobstatuslist{}; std::string argument{jobstatus.first}; FakeListJobStatusCommand(argument); @@ -251,7 +250,7 @@ TEST_F(JobStatusSelection, ReturnOnlyOneJobStatusIfOnlyOneIsEntered) TEST_F(JobStatusSelection, ReturnOnlyOneShortJobStatusIfOnlyOneLongJobStatusIsEntered) { - for (const auto& jobstatus : jobstatuses) { + for (const auto& jobstatus : allowed_jobstatuses) { std::vector jobstatuslist{}; std::string argument{jobstatus.second}; FakeListJobStatusCommand(argument); @@ -280,13 +279,13 @@ TEST_F(JobStatusSelection, } TEST_F(JobStatusSelection, - ReturnMultipleParsedJobStatusIfMultipleParsedAndUnparsedEntered) + ReturnMultipleShortJobStatusIfMultipleLongAndShortJobstatusesEntered) { std::vector jobstatuslist{}; std::vector expectedJobStatusList{}; std::string argumentForMultipleLongAndShortJobstatus; int i = 0; - for (const auto& jobstatus : jobstatuses) { + for (const auto& jobstatus : allowed_jobstatuses) { if (i % 2 == 0) { argumentForMultipleLongAndShortJobstatus += jobstatus.first; // short jobstatus @@ -305,22 +304,3 @@ TEST_F(JobStatusSelection, EXPECT_TRUE(GetUserJobStatusSelection(ua, jobstatuslist)); EXPECT_EQ(jobstatuslist, expectedJobStatusList); } - - -TEST_F(JobStatusSelection, ReturnSelectJobsWithCorrectJobStatusArgumentString) -{ // takes in ['A','T','E'..] returns : "'A','T','E',..] for sql query - std::vector jobStatusInputArray{}; - std::string expectedJobStatusesString; - for (const auto& jobstatus : jobstatuses) { - jobStatusInputArray.push_back(jobstatus.first); - expectedJobStatusesString += "'"; - expectedJobStatusesString.push_back(jobstatus.first); - expectedJobStatusesString += "',"; - } - expectedJobStatusesString.pop_back(); - - std::string jobStatusString - = CreateDelimitedStringForSqlQueries(jobStatusInputArray, ','); - - EXPECT_EQ(jobStatusString, expectedJobStatusesString); -}