Back to index

nordugrid-arc-nox  1.1.0~rc6
perftest_cmd_duration.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 // perftest_cmd.cpp
00006 
00007 #include <unistd.h>
00008 #include <errno.h>
00009 #include <iostream>
00010 #include <fstream>
00011 #include <string>
00012 #include <stdlib.h>
00013 #include <glibmm/thread.h>
00014 #include <glibmm/timer.h>
00015 #include <vector>
00016 
00017 #ifndef WIN32
00018 #include <sys/wait.h>
00019 #else
00020 #include <windows.h>
00021 #endif
00022 
00023 // Some global shared variables...
00024 Glib::Mutex* mutex;
00025 int finishedProcesses;
00026 unsigned long completedCommands;
00027 unsigned long failedCommands;
00028 unsigned long totalCommands;
00029 Glib::TimeVal completedTime;
00030 Glib::TimeVal failedTime;
00031 Glib::TimeVal totalTime;
00032 
00033 int duration;
00034 std::string cmd_str;
00035 std::vector<std::string> arglist;
00036 
00037 // Round off a double to an integer.
00038 int Round(double x){
00039   return int(x+0.5);
00040 }
00041 
00042 // Execute a command line
00043 void execCommand() {
00044   // Some variables...
00045   Glib::TimeVal tBefore;
00046   Glib::TimeVal tAfter;
00047   char **list;
00048   int pid;
00049 
00050   list = (char **)malloc (sizeof(char *) * (arglist.size() + 1));
00051   for (int i = 0;i < arglist.size();i++)
00052     list[i] = (char *)arglist[i].c_str();
00053   list[arglist.size()] = NULL;
00054 
00055 
00056   while(Round(::completedTime.as_double() * 1000000) < (duration * 1000000)){
00057     tBefore.assign_current_time();
00058 
00059 #ifdef WIN32
00060     STARTUPINFO si = {0};
00061     si.cb = sizeof(si);
00062     PROCESS_INFORMATION pi;
00063     if(CreateProcess(cmd_str.c_str(),NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) {
00064       std::cout << "Create process failed: "<<GetLastError()<<std::endl;
00065       exit(1);
00066     };
00067 
00068     int status;
00069     status = WaitForSingleObject(pi.hProcess, INFINITE);
00070     CloseHandle(pi.hProcess);
00071     CloseHandle(pi.hThread);
00072 
00073     tAfter.assign_current_time();
00074 
00075     if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED) {
00076       std::cout << "ERROR: " << cmd_str << " returns code " << status
00077  << std::endl;
00078       Glib::Mutex::Lock lock(*mutex);
00079       ::failedCommands++;
00080       ::failedTime+=tAfter-tBefore;
00081       finishedProcesses++;
00082     }
00083     else {
00084       Glib::Mutex::Lock lock(*mutex);
00085       ::completedCommands++;
00086       ::completedTime+=tAfter-tBefore;
00087       finishedProcesses++;
00088     }
00089 #else
00090     pid = fork();
00091     if(pid == 0) {
00092       int e = execvp(cmd_str.c_str(), list);
00093       //If execvp returns, it must have failed.
00094       std::cout << "[child] error " << e << " errno: " << errno << std::endl;
00095       exit(1);
00096     }
00097     else if(pid == -1) {
00098       std::cout << "Fork failed. Exiting." << std::endl;
00099       exit(1);
00100     }
00101     else {
00102       int child_status, child_pid;
00103       child_pid = wait(&child_status);
00104 
00105       tAfter.assign_current_time();
00106 
00107       if(child_status != 0) {
00108         std::cout << "ERROR: " << cmd_str << " returns code " << child_status << std::endl;
00109         Glib::Mutex::Lock lock(*mutex);
00110         ::failedCommands++;
00111         ::failedTime+=tAfter-tBefore;
00112         finishedProcesses++;
00113       }
00114       else {
00115         Glib::Mutex::Lock lock(*mutex);
00116         ::completedCommands++;
00117         ::completedTime+=tAfter-tBefore;
00118         finishedProcesses++;
00119       }
00120     }
00121 #endif
00122   } 
00123 
00124   std::cout << "Number of finished processes: " << finishedProcesses << std::endl;
00125 
00126   free(list);
00127 }
00128 
00129 int main(int argc, char* argv[]){
00130   // Extract command line arguments.
00131   if (argc<3){
00132     std::cerr << "Wrong number of arguments!" << std::endl
00133              << std::endl
00134              << "Usage:" << std::endl
00135              << "perftest_cmd_duration duration" << std::endl
00136              << std::endl
00137              << "Arguments:" << std::endl
00138              << "duration The duration of the test in seconds." << std::endl;
00139     exit(EXIT_FAILURE);
00140   }
00141   duration = atoi(argv[1]);
00142 
00143   cmd_str = std::string(argv[2]);
00144   std::cout<<"cmd_str "<<cmd_str<<std::endl;
00145 
00146   //Parse the arguments of command line
00147   for (int i = 0;i < (argc -2);i++) {
00148     arglist.push_back((char *)argv[i+2]);
00149     std::cout<<"argv: "<<arglist[i]<<std::endl;
00150   }
00151 
00152   // Start processes.
00153   finishedProcesses=0;
00154   mutex=new Glib::Mutex;
00155 
00156   execCommand();
00157 
00158   // Print the result of the test.
00159   Glib::Mutex::Lock lock(*mutex);
00160   totalCommands = completedCommands+failedCommands;
00161   totalTime = completedTime+failedTime;
00162   std::cout << "========================================" << std::endl;
00163   std::cout << "Duration: "
00164            << duration << " s" << std::endl;
00165   std::cout << "Number of commands: "
00166            << totalCommands << std::endl;
00167   std::cout << "Completed commands: "
00168            << completedCommands << " ("
00169            << Round(completedCommands*100.0/totalCommands)
00170            << "%)" << std::endl;
00171   std::cout << "Failed commands: "
00172            << failedCommands << " ("
00173            << Round(failedCommands*100.0/totalCommands)
00174            << "%)" << std::endl;
00175   std::cout << "Completed requests per min: "
00176             << Round(((double)completedCommands)/duration*60)
00177             << std::endl;
00178   std::cout << "Average response time for all commands: "
00179            << Round(1000*totalTime.as_double()/totalCommands)
00180            << " ms" << std::endl;
00181   if (completedCommands!=0)
00182     std::cout << "Average response time for completed commands: "
00183              << Round(1000*completedTime.as_double()/completedCommands)
00184              << " ms" << std::endl;
00185   if (failedCommands!=0)
00186     std::cout << "Average response time for failed commands: "
00187              << Round(1000*failedTime.as_double()/failedCommands)
00188              << " ms" << std::endl;
00189   std::cout << "========================================" << std::endl;
00190 
00191   return 0;
00192 }