CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/FWCore/Utilities/src/TestHelper.cc

Go to the documentation of this file.
00001 //------------------------------------------------------------
00002 //------------------------------------------------------------
00003 #include <cerrno>
00004 #include <cstdlib>
00005 #include <exception>
00006 #include <iostream>
00007 #include <string>
00008 
00009 #include <sys/wait.h>
00010 #include <unistd.h>
00011 #include <cstring>
00012 
00013 #include "boost/version.hpp"
00014 #include "boost/filesystem/convenience.hpp"
00015 
00016 #include "FWCore/Utilities/interface/EDMException.h"
00017 #include "FWCore/Utilities/interface/Exception.h"
00018 #include "FWCore/Utilities/interface/RegexMatch.h"
00019 #include "FWCore/Utilities/interface/TestHelper.h"
00020 
00021 namespace bf = boost::filesystem;
00022 
00023 int run_script(std::string const& shell, std::string const& script) {
00024   pid_t pid = 0;
00025   int status = 0;
00026 
00027   if((pid = fork()) < 0) {
00028       std::cerr << "fork failed, to run " << script << std::endl;;
00029       return -1;
00030   }
00031 
00032   if(pid == 0) { // child
00033     execlp(shell.c_str(), "sh", "-c", script.c_str(), static_cast<char const*>(0));
00034     std::cerr << "child failed becuase '" << strerror(errno) << "'\n";
00035     _exit(127); // signal parent and children processes
00036   } else { // parent
00037     while(waitpid(pid, &status, 0) < 0) {
00038       if(errno != EINTR) {
00039         std::cerr << "child process failed " << strerror(errno) << "\n";
00040         status = -1;
00041         break;
00042       } else {
00043         if(WIFSIGNALED(status)) {
00044           std::cerr << "child existed because of a signal " << WTERMSIG(status) << "\n";
00045         }
00046       }
00047     }
00048     if(WIFSIGNALED(status)) {
00049       std::cerr << "child existed because of a signal " << WTERMSIG(status) << "\n";
00050     }
00051     if(WIFEXITED(status)) {
00052     }
00053   }
00054   return status;
00055 }
00056 
00057 int do_work(int argc, char* argv[], char** env) {
00058   bf::path currentPath(bf::initial_path().string());
00059 
00060   if(argc < 4) {
00061     std::cout << "Usage: " << argv[0] << " shell subdir script1 script2 ... scriptN\n\n"
00062               << "where shell is the path+shell (e.g., /bin/bash) intended to run the scripts\n"
00063               << "and subdir is the subsystem/package/subdir in which the scripts are found\n"
00064               << "(e.g., FWCore/Utilities/test)\n"
00065               << std::endl;
00066 
00067     std::cout << "Current directory is: " << currentPath.string() << '\n';
00068     std::cout << "Current environment:\n";
00069     std::cout << "---------------------\n";
00070     for(int i = 0; env[i] != 0; ++i) std::cout << env[i] << '\n';
00071     std::cout << "---------------------\n";
00072     std::cout << "Executable name: " << argv[0] << '\n';
00073     return -1;
00074   }
00075 
00076   char const* goodDirectory = "[A-Za-z0-9/_.-]+";
00077 
00078   for(int i = 0; i < argc; ++i) {
00079     std::cout << "argument " << i << ": " << argv[i] << '\n';
00080   }
00081 
00082   std::string shell(argv[1]);
00083   std::cerr << "shell is: " << shell << '\n';
00084 
00085   std::cout << "Current directory is: " << currentPath.string() << '\n';
00086   // It is unclear about which of these environment variables should
00087   // be used.
00088   char const* topdir = getenv("SCRAMRT_LOCALRT");
00089   if(!topdir) topdir = getenv("LOCALRT");
00090   try {
00091     if(!edm::untaintString(topdir, goodDirectory)) {
00092       std::cerr << "Invalid top directory '" << topdir << "'" << std::endl;;
00093       return -1;
00094     }
00095   }
00096   catch(std::runtime_error const& e) {
00097     std::cerr << "Invalid top directory '" << topdir << "'" << std::endl;;
00098     std::cerr << "e.what" << std::endl;;
00099     return -1;
00100   }
00101 
00102   char const* arch = getenv("SCRAM_ARCH");
00103 
00104   if(!arch) {
00105     // Try to synthesize SCRAM_ARCH value.
00106     bf::path exepath(argv[0]);
00107 #if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 47
00108     std::string maybe_arch = exepath.parent_path().filename().string();
00109 #else
00110     std::string maybe_arch = exepath.branch_path().leaf();
00111 #endif
00112     if(setenv("SCRAM_ARCH", maybe_arch.c_str(), 1) != 0) {
00113       std::cerr << "SCRAM_ARCH not set and attempt to set it failed\n";
00114       return -1;
00115     }
00116     arch = getenv("SCRAM_ARCH");
00117   }
00118 
00119   int rc = 0;
00120 
00121   if(!topdir) {
00122     std::cerr << "Neither SCRAMRT_LOCALRT nor LOCALRT is defined" << std::endl;;
00123     return -1;
00124   }
00125 
00126   try {
00127     if(!edm::untaintString(argv[2], goodDirectory)) {
00128       std::cerr << "Invalid test directory '" << argv[2] << "'" << std::endl;;
00129       return -1;
00130     }
00131   }
00132   catch(std::runtime_error const& e) {
00133     std::cerr << "Invalid test directory '" << argv[2] << "'" << std::endl;;
00134     std::cerr << "e.what" << std::endl;;
00135     return -1;
00136   }
00137 
00138   std::string testdir(topdir); testdir += "/src/"; testdir += argv[2];
00139   std::string tmpdir(topdir);  tmpdir += "/tmp/";   tmpdir += arch;
00140   std::string testbin(topdir); testbin += "/test/"; testbin += arch;
00141 
00142   std::cout << "topdir is: " << topdir << '\n';
00143   std::cout << "testdir is: " << testdir << '\n';
00144   std::cout << "tmpdir is: " << tmpdir << '\n';
00145   std::cout << "testbin is: " << testbin << '\n';
00146 
00147   if(setenv("LOCAL_TEST_DIR", testdir.c_str(),1) != 0) {
00148     std::cerr << "Could not set LOCAL_TEST_DIR to " << testdir << std::endl;;
00149     return -1;
00150   }
00151   if(setenv("LOCAL_TMP_DIR", tmpdir.c_str(),1) != 0) {
00152     std::cerr << "Could not set LOCAL_TMP_DIR to " << tmpdir << std::endl;;
00153     return -1;
00154   }
00155   if(setenv("LOCAL_TOP_DIR", topdir,1) != 0) {
00156     std::cerr << "Could not set LOCAL_TOP_DIR to " << topdir << std::endl;;
00157     return -1;
00158   }
00159   if(setenv("LOCAL_TEST_BIN", testbin.c_str(),1) != 0) {
00160     std::cerr << "Could not set LOCAL_TEST_BIN to " << testbin << std::endl;;
00161     return -1;
00162   }
00163 
00164   testdir += "/";
00165 
00166   for(int i = 3; i < argc && rc == 0; ++i) {
00167     std::string scriptname(testdir);
00168     scriptname += argv[i];
00169     std::cout << "Running script: " << scriptname << std::endl;
00170     rc = run_script(shell, scriptname);
00171   }
00172 
00173   std::cout << "status = " << rc << std::endl;
00174   return rc == 0 ? 0 : -1;
00175 }
00176 
00177 int ptomaine(int argc, char* argv[], char** env) {
00178   int rc = 1;
00179   try {
00180     rc = do_work(argc, argv, env);
00181   }
00182   catch(edm::Exception& x) {
00183     std::cerr << "Caught an edm::Exception in "
00184               << argv[0] << '\n'
00185               << x;
00186   }
00187   catch(cms::Exception& x) {
00188     std::cerr << "Caught a cms::Exception in "
00189               << argv[0] << '\n'
00190               << x;
00191     }
00192   catch(std::exception& x) {
00193     std::cerr << "Caught a std::exception in "
00194               << argv[0] << '\n'
00195               << x.what();
00196   }
00197   catch(...) {
00198     std::cerr << "Caught an unknown exception in "
00199               << argv[0];
00200   }
00201   return rc;
00202 }