CMS 3D CMS Logo

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