#include <iostream> // std::cout
#include <math.h> // ceil
#include <climits>
+#include <unistd.h> // chdir
// Project
#include <anna/timex/Engine.hpp>
#include <TestCase.hpp>
-#define SIGUSR2_TASKS_INPUT_FILENAME "./sigusr2.in"
-#define SIGUSR2_TASKS_OUTPUT_FILENAME "./sigusr2.out"
+#define SIGUSR2_TASKS_INPUT_FILENAME "sigusr2.in"
+#define SIGUSR2_TASKS_OUTPUT_FILENAME "sigusr2.out"
const char *ServicesDTD = "\
}
+std::string Launcher::getSignalUSR2InputFile() const throw() {
+ return (a_initialWorkingDirectory + "/" + SIGUSR2_TASKS_INPUT_FILENAME);
+}
+
+std::string Launcher::getSignalUSR2OutputFile() const throw() {
+ return (a_initialWorkingDirectory + "/" + SIGUSR2_TASKS_OUTPUT_FILENAME);
+}
void Launcher::servicesFromXML(const anna::xml::Node* servicesNode, bool eventOperation) throw(anna::RuntimeException) {
// Start time:
a_start_time.setNow();
+
+ // Initial working directory:
+ char cwd[1024];
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ throw anna::RuntimeException("Cannot retrieve initial working directory !!", ANNA_FILE_LOCATION);
+ a_initialWorkingDirectory = cwd;
+
// Statistics:
anna::statistics::Engine::instantiate().enable();
}
void Launcher::signalUSR2() throw(anna::RuntimeException) {
+
+ std::string inputFile = getSignalUSR2InputFile();
+ std::string outputFile = getSignalUSR2OutputFile();
+
LOGNOTICE(
std::string msg = "Captured signal SIGUSR2. Reading tasks at '";
- msg += SIGUSR2_TASKS_INPUT_FILENAME;
+ msg += inputFile;
msg += "' (results will be written at '";
- msg += SIGUSR2_TASKS_OUTPUT_FILENAME;
+ msg += outputFile;
msg += "')";
anna::Logger::notice(msg, ANNA_FILE_LOCATION);
);
// Operation:
std::string line;
std::string response_content;
- std::ifstream in_file(SIGUSR2_TASKS_INPUT_FILENAME);
- std::ofstream out_file(SIGUSR2_TASKS_OUTPUT_FILENAME);
+ std::ifstream in_file(inputFile);
+ std::ofstream out_file(outputFile);
if(!in_file.is_open()) throw RuntimeException("Unable to read tasks", ANNA_FILE_LOCATION);
if(!out_file.is_open()) throw RuntimeException("Unable to write tasks", ANNA_FILE_LOCATION);
while(getline(in_file, line)) {
+
+ // Ignore comments and blank lines:
+ if (line[0] == '#') continue;
+ if (std::string::npos == line.find_first_not_of(" \t")) continue;
+
LOGDEBUG(
std::string msg = "Processing line: ";
msg += line;
result += "\n This operation applies over all the registered host nodes";
result += "\n except if one specific working node has been set.";
result += "\nforceCountersRecord Forces dump to file the current counters of the process.";
+ result += "\nchange-dir[|directory] Changes the execution point which could be fine to ease some";
+ result += "\n file system interaction tasks. Be care about some requirements";
+ result += "\n (for example if you have a user defined counters directory as";
+ result += "\n relative path this must exists from the new execution directory).";
+ result += "\n If nothing provided, initial working directory will be restored.";
result += "\nshow-oam Dumps current counters of the process. This is also done at";
result += "\n process context dump.";
result += "\nshow-stats Dumps statistics of the process. This is also done at process";
result += "\n steps margin, which could be useful to 'freeze' a test in the middle of its execution.";
result += "\n You could also provide -1 to make it non-interactive resuming it from the current step.";
result += "\n";
- result += "\n test|reset|<soft/hard>[|id] Reset the test case for id provided, all the tests when missing. It could be hard/soft:";
+ result += "\n test|reset|<[soft]/hard>[|id] Reset the test case for id provided, all the tests when missing. It could be hard/soft:";
result += "\n - hard: you probably may need to stop the load rate before. This operation initializes";
result += "\n all test cases regardless their states.";
result += "\n - soft: only for finished cases (those with 'Success' or 'Failed' states). It does not";
result += "\n enabled because the programmed test cases dumps could be heavy (anyway you could enable the";
result += "\n dumps separately, for any of the possible states: Initialized, InProgress, Failed, Success).";
result += "\n";
- result += "\n test|report|<initialized/in-progress/failed/success/all/none>[|[yes]|no]";
+ result += "\n test|report|<initialized/in-progress/failed/success/[all]/none>[|[yes]|no]";
result += "\n";
result += "\n Enables/disables report generation for a certain test case state: initialized, in-progress,";
result += "\n failed or success (also 'all' and 'none' reserved words could be used). This applies to report";
result += "\n";
result += "\nThe alternative using SIGUSR2 signal requires the creation of the task(s) file which will be read at";
result += "\n signal event:";
- result += "\n echo \"<<operation>\" > "; result += SIGUSR2_TASKS_INPUT_FILENAME;
+ result += "\n echo \"<<operation>\" > "; result += getSignalUSR2InputFile();
result += "\n then";
result += "\n kill -12 <pid>";
result += "\n or";
result += "\n kill -s SIGUSR2 <pid>";
result += "\n and then see the results:";
- result += "\n cat "; result += SIGUSR2_TASKS_OUTPUT_FILENAME;
+ result += "\n cat "; result += getSignalUSR2OutputFile();
result += "\n";
result += "\n (this file is ended with EOF final line, useful managing huge batch files to ensure the job completion)";
result += "\n";
LOGDEBUG(anna::Logger::debug(operation, ANNA_FILE_LOCATION));
// Default response:
- response_content = "Operation processed with exception (see traces): ";
+ response_content = "Operation processed with exception: ";
response_content += operation;
std::string opt_response_content = ""; // aditional response content
anna::DataBlock db_aux(true);
// Check the number of parameters:
bool wrongBody = false;
+ if((opType == "change-dir") && (numParams > 1)) wrongBody = true;
if((opType == "node") && (numParams > 1)) wrongBody = true;
+
if((opType == "node_auto") && (numParams > 0)) wrongBody = true;
if(((opType == "code") || (opType == "decode")) && (numParams != 2)) wrongBody = true;
return;
}
+ // Change execution directory:
+ if(opType == "change-dir") {
+ if (param1 == "") param1 = a_initialWorkingDirectory;
+ if (chdir(param1.c_str()) == 0)
+ response_content = "New execution directory configured: ";
+ else
+ response_content = "Cannot assign provided execution directory: ";
+
+ response_content += param1;
+ return;
+ }
+
if(opType == "services") {
std::string servicesFile = ((numParams == 1) ? param1 : "services.xml");
try {
// test|next[|<sync-amount>] Forces the execution of the next test case(s) without waiting for test manager tick ...
// test|ip-limit[|amount] In-progress limit of test cases. No new test cases will be launched over this value ...
// test|repeats|<amount> Restarts the whole programmed test list when finished the amount number of times ...
- // test|report|<initialized/in-progress/failed/success/all/none>[|[yes]|no]
+ // test|report|<initialized/in-progress/failed/success/[all]/none>[|[yes]|no]
// Enables/disables report generation for a certain test case state: initialized, in-progress ...
// test|report-hex[|[yes]|no] Reports could include the diameter messages in hexadecimal format. Disabled by default.
// test|goto|<id> Updates current test pointer position.
// test|look[|id] Show programmed test case for id provided, current when missing ...
// test|interact|amount|id Makes interactive a specific test case id. The amount is the margin of execution steps ...
- // test|reset|<soft/hard>[|id] Reset the test case for id provided, all the tests when missing ...
+ // test|reset|<[soft]/hard>[|id] Reset the test case for id provided, all the tests when missing ...
// test|clear Clears all the programmed test cases.
// test|summary Test manager general report (number of test cases, counts by state ...
if (numParams > 3)
throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+ if(param2 == "") param2 = "all";
if(param3 == "") param3 = "yes";
bool enable = (param3 == "yes");
if (numParams > 3)
throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
- if (param2 != "soft" && param2 != "hard")
+ if(param2 == "") param2 = "soft";
+ if (param2 != "soft" && param2 != "hard")
throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
int id = ((param3 != "") ? atoi(param3.c_str()) : -1);
else {
if (id == -1) {
bool anyReset = testManager.resetPool((param2 == "hard") ? true:false);
- opt_response_content = "reset have been sent to all programmed tests: "; opt_response_content += anyReset ? "some/all have been reset" : "nothing was reset";
+ opt_response_content = param2; opt_response_content += " reset have been sent to all programmed tests: "; opt_response_content += anyReset ? "some/all have been reset" : "nothing was reset";
}
else {
opt_response_content = "cannot found test id (";
anna::comm::Application::asXML(result);
// Timming:
result->createAttribute("StartTime", a_start_time.asString());
+ result->createAttribute("InitialWorkingDirectory", a_initialWorkingDirectory);
result->createAttribute("SecondsLifeTime", anna::time::functions::lapsedMilliseconds() / 1000);
// Diameter:
for (origin_hosts_it it = a_originHosts.begin(); it != a_originHosts.end(); it++) {