Back to index

nordugrid-arc-nox  1.1.0~rc6
perftest_saml2sso.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 // perftest.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 #include <arc/client/ClientSAML2SSO.h>
00022 
00023 #include <arc/xmlsec/XmlSecUtils.h>
00024 
00025 // Some global shared variables...
00026 Glib::Mutex* mutex;
00027 bool run;
00028 int finishedThreads;
00029 unsigned long completedRequests;
00030 unsigned long failedRequests;
00031 unsigned long totalRequests;
00032 Glib::TimeVal completedTime;
00033 Glib::TimeVal failedTime;
00034 Glib::TimeVal totalTime;
00035 std::string url_str;
00036 std::string idp_name;
00037 std::string username;
00038 std::string password;
00039 
00040 // Round off a double to an integer.
00041 int Round(double x){
00042   return int(x+0.5);
00043 }
00044 
00045 // Send requests and collect statistics.
00046 void sendRequests(){
00047   // Some variables...
00048   unsigned long completedRequests = 0;
00049   unsigned long failedRequests = 0;
00050   Glib::TimeVal completedTime(0,0);
00051   Glib::TimeVal failedTime(0,0);
00052   Glib::TimeVal tBefore;
00053   Glib::TimeVal tAfter;
00054   bool connected;
00055 
00056   //std::string url_str("https://127.0.0.1:60000/echo");
00057   Arc::URL url(url_str);
00058 
00059   Arc::MCCConfig mcc_cfg;
00060   //mcc_cfg.AddPrivateKey("../echo/userkey-nopass.pem");
00061   //mcc_cfg.AddCertificate("../echo/usercert.pem");
00062   //mcc_cfg.AddCAFile("../echo/testcacert.pem");
00063   mcc_cfg.AddCAFile("../../services/slcs/cacert2.pem");
00064   mcc_cfg.AddCADir("../echo/certificates");
00065 
00066   Arc::NS echo_ns; echo_ns["echo"]="http://www.nordugrid.org/schemas/echo";
00067   
00068   while(run){
00069     
00070     // Create a Client.
00071     Arc::ClientSOAPwithSAML2SSO *client = NULL;
00072     client = new Arc::ClientSOAPwithSAML2SSO(mcc_cfg,url);
00073 
00074     connected=true;
00075     //while(run and connected){
00076       // Prepare the request.
00077       Arc::PayloadSOAP req(echo_ns);
00078       req.NewChild("echo").NewChild("say")="HELLO";
00079 
00080       // Send the request and time it.
00081       tBefore.assign_current_time();
00082       Arc::PayloadSOAP* resp = NULL;
00083 
00084       //std::string str;
00085       //req.GetXML(str);
00086       //std::cout<<"request: "<<str<<std::endl;
00087       Arc::MCC_Status status = client->process(&req,&resp, idp_name, username, password);
00088 
00089       tAfter.assign_current_time();
00090       
00091       if(!status) {
00092         // Request failed.
00093         failedRequests++;
00094         failedTime+=tAfter-tBefore;
00095            connected=false;
00096 
00097           std::cout<<"failure1: "<<std::endl;
00098 
00099       } else {
00100         if(resp == NULL) {
00101           // Response was not SOAP or no response at all.
00102           failedRequests++;
00103           failedTime+=tAfter-tBefore;
00104           connected=false;
00105 
00106           std::cout<<"failure2: "<<std::endl;
00107 
00108         } else {
00109           //std::string xml;
00110           //resp->GetXML(xml);
00111           //std::cout<<"reponse: "<<xml<<std::endl;
00112           if (std::string((*resp)["echoResponse"]["hear"]).size()==0){
00113             // The response was not what it should be.
00114             failedRequests++;
00115             failedTime+=tAfter-tBefore;
00116             connected=false;
00117           }
00118           else{
00119             // Everything worked just fine!
00120             completedRequests++;
00121             completedTime+=tAfter-tBefore;
00122           }
00123         }
00124       }
00125       if(resp) delete resp;
00126     //}
00127     if(client) delete client;
00128   }
00129 
00130   // Update global variables.
00131   Glib::Mutex::Lock lock(*mutex);
00132   ::completedRequests+=completedRequests;
00133   ::failedRequests+=failedRequests;
00134   ::completedTime+=completedTime;
00135   ::failedTime+=failedTime;
00136   finishedThreads++;
00137   std::cout << "Number of finished threads: " << finishedThreads << std::endl;
00138 }
00139 
00140 int main(int argc, char* argv[]){
00141   // Some variables...
00142   int numberOfThreads;
00143   int duration;
00144   int i;
00145   Glib::Thread** threads;
00146   const char* config_file = NULL;
00147   int debug_level = -1;
00148   Arc::LogStream logcerr(std::cerr);
00149 
00150   // Process options - quick hack, must use Glib options later
00151   while(argc >= 3) {
00152     if(strcmp(argv[1],"-c") == 0) {
00153       config_file = argv[2];
00154       argv[2]=argv[0]; argv+=2; argc-=2;
00155     } else if(strcmp(argv[1],"-d") == 0) {
00156       debug_level=Arc::string_to_level(argv[2]);
00157       argv[2]=argv[0]; argv+=2; argc-=2;
00158     } else {
00159       break;
00160     };
00161   } 
00162   if(debug_level >= 0) {
00163     Arc::Logger::getRootLogger().setThreshold((Arc::LogLevel)debug_level);
00164     Arc::Logger::getRootLogger().addDestination(logcerr);
00165   }
00166   // Extract command line arguments.
00167   if (argc!=7){
00168     std::cerr << "Wrong number of arguments!" << std::endl
00169              << std::endl
00170              << "Usage:" << std::endl
00171              << "perftest [-c config] [-d debug] url idpname username password threads duration" << std::endl
00172              << std::endl
00173              << "Arguments:" << std::endl
00174              << "url     The url of the service." << std::endl
00175               << "idpname   The name of the SP, e.g. https://squark.uio.no/idp/shibboleth" << std::endl
00176               << "username  The username to IdP " << std::endl
00177               << "password  The password to IdP   " << std::endl
00178              << "threads  The number of concurrent requests." << std::endl
00179              << "duration The duration of the test in seconds." << std::endl
00180              << "config   The file containing client chain XML configuration with " << std::endl
00181               << "         'soap' entry point and HOSTNAME, PORTNUMBER and PATH " << std::endl
00182               << "         keyword for hostname, port and HTTP path of 'echo' service." << std::endl
00183              << "debug    The textual representation of desired debug level. Available " << std::endl
00184               << "         levels: DEBUG, VERBOSE, INFO, WARNING, ERROR, FATAL." << std::endl;
00185     exit(EXIT_FAILURE);
00186   }
00187   url_str = std::string(argv[1]);
00188   idp_name = std::string(argv[2]);
00189   username = std::string(argv[3]);
00190   password = std::string(argv[4]);
00191   numberOfThreads = atoi(argv[5]);
00192   duration = atoi(argv[6]);
00193 
00194   Arc::init_xmlsec();
00195 
00196   // Start threads.
00197   run=true;
00198   finishedThreads=0;
00199   //Glib::thread_init();
00200   mutex=new Glib::Mutex;
00201   threads = new Glib::Thread*[numberOfThreads];
00202   for (i=0; i<numberOfThreads; i++) {
00203     threads[i]=Glib::Thread::create(sigc::ptr_fun(sendRequests),true);
00204     //Glib::usleep(1000000);
00205   }
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   Arc::final_xmlsec();
00253 
00254   return 0;
00255 }