Back to index

nordugrid-arc-nox  1.1.0~rc6
perftest_deleg_bysechandler.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 // perftest_deleg_bysechandler.cpp
00006 
00007 #include <iostream>
00008 #include <fstream>
00009 #include <string>
00010 #include <stdlib.h>
00011 #include <glibmm/thread.h>
00012 #include <glibmm/timer.h>
00013 
00014 #include <arc/GUID.h>
00015 #include <arc/ArcConfig.h>
00016 #include <arc/Logger.h>
00017 #include <arc/URL.h>
00018 #include <arc/message/PayloadSOAP.h>
00019 #include <arc/message/MCC.h>
00020 #include <arc/client/ClientInterface.h>
00021 
00022 // Some global shared variables...
00023 Glib::Mutex* mutex;
00024 bool run;
00025 int finishedThreads;
00026 unsigned long completedRequests;
00027 unsigned long failedRequests;
00028 unsigned long totalRequests;
00029 Glib::TimeVal completedTime;
00030 Glib::TimeVal failedTime;
00031 Glib::TimeVal totalTime;
00032 std::string url_str;
00033 
00034 Arc::XMLNode sechanlder_nd("\
00035   <SecHandler name='delegation.handler' id='delegation' event='outgoing'>\
00036     <Type>x509</Type>\
00037     <Role>client</Role>\
00038     <!--DelegationServiceEndpoint>https://127.0.0.1:60000/delegation</DelegationServiceEndpoint-->\
00039     <DelegationServiceEndpoint>https://glueball.uio.no:60000/delegation</DelegationServiceEndpoint>\
00040     <PeerServiceEndpoint>https://squark.uio.no:60000/echo</PeerServiceEndpoint>\
00041     <KeyPath>../echo/userkey-nopass.pem</KeyPath>\
00042     <CertificatePath>../echo/usercert.pem</CertificatePath>\
00043     <!--ProxyPath>/tmp/5612d050.pem</ProxyPath-->\
00044     <!--DelegationCredIdentity>/O=KnowARC/OU=UiO/CN=squark.uio.no</DelegationCredIdentity-->\
00045     <CACertificatePath>../echo/testcacert.pem</CACertificatePath>\
00046     <CACertificatesDir>../echo/certificates</CACertificatesDir>\
00047   </SecHandler>");
00048 
00049 
00050 // Round off a double to an integer.
00051 int Round(double x){
00052   return int(x+0.5);
00053 }
00054 
00055 // Send requests and collect statistics.
00056 void sendRequests(){
00057   // Some variables...
00058   unsigned long completedRequests = 0;
00059   unsigned long failedRequests = 0;
00060   Glib::TimeVal completedTime(0,0);
00061   Glib::TimeVal failedTime(0,0);
00062   Glib::TimeVal tBefore;
00063   Glib::TimeVal tAfter;
00064   bool connected;
00065 
00066   //std::string url_str("https://127.0.0.1:60000/echo");
00067   Arc::URL url(url_str);
00068 
00069   Arc::MCCConfig mcc_cfg;
00070   mcc_cfg.AddPrivateKey("../echo/userkey-nopass.pem");
00071   mcc_cfg.AddCertificate("../echo/usercert.pem");
00072   mcc_cfg.AddCAFile("../echo/testcacert.pem");
00073   mcc_cfg.AddCADir("../echo/certificates");
00074 
00075   Arc::NS echo_ns; echo_ns["echo"]="http://www.nordugrid.org/schemas/echo";
00076   
00077   while(run){
00078     
00079     // Create a Client.
00080     Arc::ClientSOAP *client = NULL;
00081     client = new Arc::ClientSOAP(mcc_cfg,url,60);
00082     client->AddSecHandler(sechanlder_nd, "arcshc");
00083 
00084     connected=true;
00085     //while(run and connected){
00086       // Prepare the request.
00087       Arc::PayloadSOAP req(echo_ns);
00088       req.NewChild("echo").NewChild("say")="HELLO";
00089 
00090       // Send the request and time it.
00091       tBefore.assign_current_time();
00092       Arc::PayloadSOAP* resp = NULL;
00093 
00094       //std::string str;
00095       //req.GetXML(str);
00096       //std::cout<<"request: "<<str<<std::endl;
00097       Arc::MCC_Status status = client->process(&req,&resp);
00098 
00099       tAfter.assign_current_time();
00100       
00101       if(!status) {
00102         // Request failed.
00103         failedRequests++;
00104         failedTime+=tAfter-tBefore;
00105            connected=false;
00106 
00107           std::cout<<"failure1: "<<std::endl;
00108 
00109       } else {
00110         if(resp == NULL) {
00111           // Response was not SOAP or no response at all.
00112           failedRequests++;
00113           failedTime+=tAfter-tBefore;
00114           connected=false;
00115 
00116           std::cout<<"failure2: "<<std::endl;
00117 
00118         } else {
00119           std::string xml;
00120           resp->GetXML(xml);
00121           std::cout<<"reponse: "<<xml<<std::endl;
00122           if (std::string((*resp)["echoResponse"]["hear"]).size()==0){
00123             // The response was not what it should be.
00124             failedRequests++;
00125             failedTime+=tAfter-tBefore;
00126             connected=false;
00127           }
00128           else{
00129             // Everything worked just fine!
00130             completedRequests++;
00131             completedTime+=tAfter-tBefore;
00132           }
00133         }
00134       }
00135       if(resp) delete resp;
00136     //}
00137     if(client) delete client;
00138   }
00139 
00140   // Update global variables.
00141   Glib::Mutex::Lock lock(*mutex);
00142   ::completedRequests+=completedRequests;
00143   ::failedRequests+=failedRequests;
00144   ::completedTime+=completedTime;
00145   ::failedTime+=failedTime;
00146   finishedThreads++;
00147   std::cout << "Number of finished threads: " << finishedThreads << std::endl;
00148 }
00149 
00150 int main(int argc, char* argv[]){
00151   // Some variables...
00152   int numberOfThreads;
00153   int duration;
00154   int i;
00155   Glib::Thread** threads;
00156   const char* config_file = NULL;
00157   int debug_level = -1;
00158   Arc::LogStream logcerr(std::cerr);
00159 
00160   // Process options - quick hack, must use Glib options later
00161   while(argc >= 3) {
00162     if(strcmp(argv[1],"-c") == 0) {
00163       config_file = argv[2];
00164       argv[2]=argv[0]; argv+=2; argc-=2;
00165     } else if(strcmp(argv[1],"-d") == 0) {
00166       debug_level=Arc::string_to_level(argv[2]);
00167       argv[2]=argv[0]; argv+=2; argc-=2;
00168     } else {
00169       break;
00170     };
00171   } 
00172   if(debug_level >= 0) {
00173     Arc::Logger::getRootLogger().setThreshold((Arc::LogLevel)debug_level);
00174     Arc::Logger::getRootLogger().addDestination(logcerr);
00175   }
00176   // Extract command line arguments.
00177   if (argc!=4){
00178     std::cerr << "Wrong number of arguments!" << std::endl
00179              << std::endl
00180              << "Usage:" << std::endl
00181              << "perftest_deleg_bysechandler [-c config] [-d debug] url threads duration" << std::endl
00182              << std::endl
00183              << "Arguments:" << std::endl
00184              << "url     The url of the service." << std::endl
00185              << "threads  The number of concurrent requests." << std::endl
00186              << "duration The duration of the test in seconds." << std::endl
00187              << "config   The file containing client chain XML configuration with " << std::endl
00188               << "         'soap' entry point and HOSTNAME, PORTNUMBER and PATH " << std::endl
00189               << "         keyword for hostname, port and HTTP path of 'echo' service." << std::endl
00190              << "debug    The textual representation of desired debug level. Available " << std::endl
00191               << "         levels: DEBUG, VERBOSE, INFO, WARNING, ERROR, FATAL." << std::endl;
00192     exit(EXIT_FAILURE);
00193   }
00194   url_str = std::string(argv[1]);
00195   numberOfThreads = atoi(argv[2]);
00196   duration = atoi(argv[3]);
00197 
00198   // Start threads.
00199   run=true;
00200   finishedThreads=0;
00201   //Glib::thread_init();
00202   mutex=new Glib::Mutex;
00203   threads = new Glib::Thread*[numberOfThreads];
00204   for (i=0; i<numberOfThreads; i++)
00205     threads[i]=Glib::Thread::create(sigc::ptr_fun(sendRequests),true);
00206 
00207   // Sleep while the threads are working.
00208   Glib::usleep(duration*1000000);
00209 
00210   // Stop the threads
00211   run=false;
00212   while(finishedThreads<numberOfThreads)
00213     Glib::usleep(100000);
00214 
00215   // Print the result of the test.
00216   Glib::Mutex::Lock lock(*mutex);
00217   totalRequests = completedRequests+failedRequests;
00218   totalTime = completedTime+failedTime;
00219   std::cout << "========================================" << std::endl;
00220   std::cout << "URL: "
00221            << url_str << std::endl;
00222   std::cout << "Number of threads: "
00223            << numberOfThreads << std::endl;
00224   std::cout << "Duration: "
00225            << duration << " s" << std::endl;
00226   std::cout << "Number of requests: "
00227            << totalRequests << std::endl;
00228   std::cout << "Completed requests: "
00229            << completedRequests << " ("
00230            << Round(completedRequests*100.0/totalRequests)
00231            << "%)" << std::endl;
00232   std::cout << "Failed requests: "
00233            << failedRequests << " ("
00234            << Round(failedRequests*100.0/totalRequests)
00235            << "%)" << std::endl;
00236   std::cout << "Completed requests per min: "
00237             << Round(((double)completedRequests)/duration*60)
00238             << std::endl;
00239   std::cout << "Average response time for all requests: "
00240            << Round(1000*totalTime.as_double()/totalRequests)
00241            << " ms" << std::endl;
00242   if (completedRequests!=0)
00243     std::cout << "Average response time for completed requests: "
00244              << Round(1000*completedTime.as_double()/completedRequests)
00245              << " ms" << std::endl;
00246   if (failedRequests!=0)
00247     std::cout << "Average response time for failed requests: "
00248              << Round(1000*failedTime.as_double()/failedRequests)
00249              << " ms" << std::endl;
00250   std::cout << "========================================" << std::endl;
00251 
00252   return 0;
00253 }