CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TestHelper.cc
Go to the documentation of this file.
1 //------------------------------------------------------------
2 //------------------------------------------------------------
3 #include <cerrno>
4 #include <cstdlib>
5 #include <exception>
6 #include <iostream>
7 #include <string>
8 
9 #include <sys/wait.h>
10 #include <unistd.h>
11 #include <cstring>
12 
13 #include "boost/version.hpp"
14 #include "boost/filesystem/convenience.hpp"
15 
20 
21 namespace bf = boost::filesystem;
22 
23 int run_script(std::string const& shell, std::string const& script) {
24  pid_t pid = 0;
25  int status = 0;
26 
27  if((pid = fork()) < 0) {
28  std::cerr << "fork failed, to run " << script << std::endl;;
29  return -1;
30  }
31 
32  if(pid == 0) { // child
33  execlp(shell.c_str(), "sh", "-c", script.c_str(), static_cast<char const*>(0));
34  std::cerr << "child failed becuase '" << strerror(errno) << "'\n";
35  _exit(127); // signal parent and children processes
36  } else { // parent
37  while(waitpid(pid, &status, 0) < 0) {
38  if(errno != EINTR) {
39  std::cerr << "child process failed " << strerror(errno) << "\n";
40  status = -1;
41  break;
42  } else {
43  if(WIFSIGNALED(status)) {
44  std::cerr << "child existed because of a signal " << WTERMSIG(status) << "\n";
45  }
46  }
47  }
48  if(WIFSIGNALED(status)) {
49  std::cerr << "child existed because of a signal " << WTERMSIG(status) << "\n";
50  }
51  if(WIFEXITED(status)) {
52  }
53  }
54  return status;
55 }
56 
57 int do_work(int argc, char* argv[], char** env) {
58  bf::path currentPath(bf::initial_path().string());
59 
60  if(argc < 4) {
61  std::cout << "Usage: " << argv[0] << " shell subdir script1 script2 ... scriptN\n\n"
62  << "where shell is the path+shell (e.g., /bin/bash) intended to run the scripts\n"
63  << "and subdir is the subsystem/package/subdir in which the scripts are found\n"
64  << "(e.g., FWCore/Utilities/test)\n"
65  << std::endl;
66 
67  std::cout << "Current directory is: " << currentPath.string() << '\n';
68  std::cout << "Current environment:\n";
69  std::cout << "---------------------\n";
70  for(int i = 0; env[i] != 0; ++i) std::cout << env[i] << '\n';
71  std::cout << "---------------------\n";
72  std::cout << "Executable name: " << argv[0] << '\n';
73  return -1;
74  }
75 
76  char const* goodDirectory = "[A-Za-z0-9/_.-]+";
77 
78  for(int i = 0; i < argc; ++i) {
79  std::cout << "argument " << i << ": " << argv[i] << '\n';
80  }
81 
82  std::string shell(argv[1]);
83  std::cerr << "shell is: " << shell << '\n';
84 
85  std::cout << "Current directory is: " << currentPath.string() << '\n';
86  // It is unclear about which of these environment variables should
87  // be used.
88  char const* topdir = getenv("SCRAMRT_LOCALRT");
89  if(!topdir) topdir = getenv("LOCALRT");
90  try {
91  if(!edm::untaintString(topdir, goodDirectory)) {
92  std::cerr << "Invalid top directory '" << topdir << "'" << std::endl;;
93  return -1;
94  }
95  }
96  catch(std::runtime_error const& e) {
97  std::cerr << "Invalid top directory '" << topdir << "'" << std::endl;;
98  std::cerr << "e.what" << std::endl;;
99  return -1;
100  }
101 
102  char const* arch = getenv("SCRAM_ARCH");
103 
104  if(!arch) {
105  // Try to synthesize SCRAM_ARCH value.
106  bf::path exepath(argv[0]);
107 #if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 47
108  std::string maybe_arch = exepath.parent_path().filename().string();
109 #else
110  std::string maybe_arch = exepath.branch_path().leaf();
111 #endif
112  if(setenv("SCRAM_ARCH", maybe_arch.c_str(), 1) != 0) {
113  std::cerr << "SCRAM_ARCH not set and attempt to set it failed\n";
114  return -1;
115  }
116  arch = getenv("SCRAM_ARCH");
117  }
118 
119  int rc = 0;
120 
121  if(!topdir) {
122  std::cerr << "Neither SCRAMRT_LOCALRT nor LOCALRT is defined" << std::endl;;
123  return -1;
124  }
125 
126  try {
127  if(!edm::untaintString(argv[2], goodDirectory)) {
128  std::cerr << "Invalid test directory '" << argv[2] << "'" << std::endl;;
129  return -1;
130  }
131  }
132  catch(std::runtime_error const& e) {
133  std::cerr << "Invalid test directory '" << argv[2] << "'" << std::endl;;
134  std::cerr << "e.what" << std::endl;;
135  return -1;
136  }
137 
138  std::string testdir(topdir); testdir += "/src/"; testdir += argv[2];
139  std::string tmpdir(topdir); tmpdir += "/tmp/"; tmpdir += arch;
140  std::string testbin(topdir); testbin += "/test/"; testbin += arch;
141 
142  std::cout << "topdir is: " << topdir << '\n';
143  std::cout << "testdir is: " << testdir << '\n';
144  std::cout << "tmpdir is: " << tmpdir << '\n';
145  std::cout << "testbin is: " << testbin << '\n';
146 
147  if(setenv("LOCAL_TEST_DIR", testdir.c_str(),1) != 0) {
148  std::cerr << "Could not set LOCAL_TEST_DIR to " << testdir << std::endl;;
149  return -1;
150  }
151  if(setenv("LOCAL_TMP_DIR", tmpdir.c_str(),1) != 0) {
152  std::cerr << "Could not set LOCAL_TMP_DIR to " << tmpdir << std::endl;;
153  return -1;
154  }
155  if(setenv("LOCAL_TOP_DIR", topdir,1) != 0) {
156  std::cerr << "Could not set LOCAL_TOP_DIR to " << topdir << std::endl;;
157  return -1;
158  }
159  if(setenv("LOCAL_TEST_BIN", testbin.c_str(),1) != 0) {
160  std::cerr << "Could not set LOCAL_TEST_BIN to " << testbin << std::endl;;
161  return -1;
162  }
163 
164  testdir += "/";
165 
166  for(int i = 3; i < argc && rc == 0; ++i) {
167  std::string scriptname(testdir);
168  scriptname += argv[i];
169  std::cout << "Running script: " << scriptname << std::endl;
170  rc = run_script(shell, scriptname);
171  }
172 
173  std::cout << "status = " << rc << std::endl;
174  return rc == 0 ? 0 : -1;
175 }
176 
177 int ptomaine(int argc, char* argv[], char** env) {
178  int rc = 1;
179  try {
180  rc = do_work(argc, argv, env);
181  }
182  catch(edm::Exception& x) {
183  std::cerr << "Caught an edm::Exception in "
184  << argv[0] << '\n'
185  << x;
186  }
187  catch(cms::Exception& x) {
188  std::cerr << "Caught a cms::Exception in "
189  << argv[0] << '\n'
190  << x;
191  }
192  catch(std::exception& x) {
193  std::cerr << "Caught a std::exception in "
194  << argv[0] << '\n'
195  << x.what();
196  }
197  catch(...) {
198  std::cerr << "Caught an unknown exception in "
199  << argv[0];
200  }
201  return rc;
202 }
int i
Definition: DBlmapReader.cc:9
int do_work(int argc, char *argv[], char **env)
Definition: TestHelper.cc:57
tuple path
else: Piece not in the list, fine.
bool untaintString(char const *pattern, char const *regexp)
Definition: RegexMatch.cc:13
int run_script(std::string const &shell, std::string const &script)
Definition: TestHelper.cc:23
tuple pid
Definition: sysUtil.py:22
tuple argc
Definition: dir2webdir.py:38
string const
Definition: compareJSON.py:14
int ptomaine(int argc, char *argv[], char **env)
Definition: TestHelper.cc:177
tuple cout
Definition: gather_cfg.py:121
Definition: DDAxes.h:10
tuple status
Definition: ntuplemaker.py:245