00001 #ifndef ANALYSISTESTFRAMEWORK_H
00002 #define ANALYSISTESTFRAMEWORK_H
00003
00004 #include <vector>
00005 #include <string>
00006 #include <algorithm>
00007 #include <is/info.h>
00008 #include <boost/shared_ptr.hpp>
00009 #include <iostream>
00010 #include <TTree.h>
00011 #include <TApplication.h>
00012 #include <TFile.h>
00013 #include <TROOT.h>
00014
00015 #include "Sct/IS/IOManagerIS.h"
00016 #include "Sct/Env.h"
00017 #include "Sct/SctNames.h"
00018 #include "Sct/OmniMarshalling.h"
00019
00020 #include "../SCTTestAPI/ModuleData.h"
00021 #include "../SCTTestAPI/XmlSummaryFile.h"
00022 #include "../SCTTestAPI/SctTestApi.hh"
00023
00024 using namespace Sct::IS;
00025
00026 class TApplication;
00027 class TFile;
00028 class TTree;
00029
00030 template<typename T>
00031 class AnalysisTestFramework {
00032 public:
00038 AnalysisTestFramework(string isFilter=".*TestResult", string isServer="TestData");
00039 virtual ~AnalysisTestFramework(){}
00040
00041 void analyzeAll(int argc, char** argv);
00042
00046 void printHelp();
00047
00051 int getExitCode() {return exitCode;}
00052
00053 protected:
00059 virtual int handleArg(int argc, int i, char** argv);
00060
00064 virtual void printAdditionalArgs() {}
00065
00069 virtual void printHelpHeader();
00070
00071 virtual void summaryOutput() {}
00072
00078 virtual void doModule(string serialNumber);
00079
00084 virtual vector<boost::shared_ptr<T> > readData(string serialNumber);
00085
00089 virtual void publishData() {}
00090
00094 virtual void downloadData(string serialNumber) {}
00095
00096 virtual void compare(const T& t) {}
00097
00098 virtual void setup() {}
00099
00100 virtual void tearDown();
00101
00102 int exitCode;
00103 bool readOnly;
00104 bool debug;
00105 SctTestApi::HighLevelApi_var highLevelApi;
00106 unsigned int nModules;
00107 unsigned int nSkip;
00108 list<string> modules;
00109 TFile* file;
00110 TTree* tree;
00111 SctTest::ModuleData moduleData;
00112 unsigned int maxModules;
00113 unsigned int nData;
00114 string isFilter;
00115 string isServer;
00116 list<string> ignoreModules;
00117 string ignoreFile;
00118
00119 private:
00120 void loadIgnoreFile();
00121 void handleArgs(int argc, char** argv);
00122 static void getRootApp();
00123 };
00124
00125 template<typename T>
00126 vector<shared_ptr<T> > AnalysisTestFramework<T>::readData(string serialNumber) {
00127 string filter = isFilter + ".*" + serialNumber;
00128 while (true) {
00129 ISInfoIterator it(SctNames::getPartition(), isServer.c_str(), filter.c_str() );
00130 ISInfoDictionary dict(SctNames::getPartition());
00131
00132 if (it.entries() == nData) {
00133 vector<shared_ptr<T> > data;
00134 while (it()) {
00135 boost::shared_ptr<Serializable> ob = IOManagerIS::instance().read(it);
00136 boost::shared_ptr<T> result = boost::dynamic_pointer_cast<T>(ob);
00137 if (!result)
00138 throw IllegalStateError(string("Failed to read test: ") + it.name(), __FILE__, __LINE__);
00139 data.push_back(result);
00140 }
00141 return data;
00142 }
00143 sleep(1);
00144 }
00145 }
00146
00150 template<typename T>
00151 void AnalysisTestFramework<T>::tearDown() {
00152 file->Write();
00153 file->Close();
00154 delete file;
00155 }
00156
00157 template<typename T>
00158 void AnalysisTestFramework<T>::doModule(string serialNumber) {
00159 highLevelApi->setModuleSerial(copyStringToCorba(serialNumber));
00160 try {
00161 if (!readOnly) publishData();
00162 } catch (...) {
00163 std::cout << "LESTERDEBUGWARNING 9274 in " << __FILE__ << std::endl;
00164 cerr << "Error publishing data" <<endl;
00165 return;
00166 }
00167
00168
00169 try {
00170 downloadData(serialNumber);
00171 vector<shared_ptr<T> > ob = readData(serialNumber);
00172 for (unsigned int i=0; i<ob.size(); ++i) {
00173 compare(*ob[i]);
00174 }
00175 } catch(Throwable& e) {
00176 e.sendToMrs(MRS_ERROR);
00177 }
00178 }
00179
00180
00181 template<typename T>
00182 void AnalysisTestFramework<T>::printHelpHeader() {
00183 cout << "RetrieveAndCompare [-n <num>] [-r] [-s <serials>] [-h/--help]" << endl;
00184 cout << "Compares SCTDAQ and SctRodDaq analyses" << endl;
00185 cout << "Arguments: " << endl;
00186 }
00187
00188 template<typename T>
00189 void AnalysisTestFramework<T>::printHelp() {
00190 printHelpHeader();
00191 cout << "-n <num>: Do up to <num> modules only, otherwise do all" << endl;
00192 cout << "-r: Read only - Useful for a re-run" << endl;
00193 cout << "-j <num>: Skip the first <num> modules in the config files" << endl;
00194 cout << "-h/--help: Print this help" << endl;
00195 cout << "-i <file>: Ignore file - a file with serial numbers, 1 per line, that will be ignored - useful for 'problem' modules" << endl;
00196 cout << "-s <serials>: All arguments after -s are assumed to be module serial numbers" << endl;
00197 printAdditionalArgs();
00198
00199 exit(0);
00200 }
00201
00202 template<typename T>
00203 int AnalysisTestFramework<T>::handleArg(int argc, int i, char** argv) {
00204 printHelp();
00205 return i;
00206 }
00207
00208
00209 template<typename T>
00210 void AnalysisTestFramework<T>::handleArgs(int argc, char** argv) {
00211 for (int i=1; i<argc; ++i) {
00212 if (string(argv[i]) == "-s") {
00213 for (int j=i+1; j<argc; ++j) {
00214 modules.push_back(argv[j]);
00215 ++nModules;
00216 }
00217 return;
00218 }
00219
00220 if (string(argv[i]) == "-n") {
00221 if (i+1 == argc) printHelp();
00222 istringstream iss(argv[++i]);
00223 iss >> maxModules;
00224 } else if (string(argv[i]) == "-r") {
00225 readOnly = true;
00226 } else if (string(argv[i]) == "-j") {
00227 if (i+1 == argc) printHelp();
00228 istringstream iss(argv[++i]);
00229 iss >> nSkip;
00230 } else if (string(argv[i]) == "-i") {
00231 if (i+1 == argc) printHelp();
00232 ignoreFile = argv[++i];
00233 } else {
00234 i = handleArg(argc, i, argv);
00235 }
00236
00237 }
00238 }
00239
00240
00241 template<typename T>
00242 void AnalysisTestFramework<T>::getRootApp() {
00243
00244
00245 gROOT->SetBatch(false);
00246
00247 }
00248
00249 template<typename T>
00250 void AnalysisTestFramework<T>::loadIgnoreFile() {
00251 if (ignoreFile.length()==0) return;
00252 ifstream file(ignoreFile.c_str());
00253 if (!file.is_open() || !file.good()) {
00254 cerr << "Unable to open ignore file: " << ignoreFile << endl;
00255 return;
00256 }
00257 string serial;
00258 while (file.good()) {
00259 file >> serial;
00260 if (serial[0] != '#' && serial.length() == 14 && count(ignoreModules.begin(), ignoreModules.end(), serial)==0) {
00261 ignoreModules.push_back(serial);
00262 }
00263 file.ignore(256, '\n');
00264 }
00265 }
00266
00267
00268 static inline SctTestApi::HighLevelApi_var getHighLevelApi() {
00269
00270 IPCPartition p = Sct::SctNames::getPartition();
00271 SctTestApi::HighLevelApi_var hla = p.lookup < ::SctTestApi::HighLevelApi > ( ::SctTestApi::HighLevelApi::instanceName );
00272 return hla;
00273 }
00274
00275 template<typename T>
00276 void AnalysisTestFramework<T>::analyzeAll(int argc, char** argv) {
00277 Sct::setExceptionHandlers(argv[0]);
00278 getRootApp();
00279
00280 try {
00281 handleArgs(argc, argv);
00282
00283
00284 highLevelApi = getHighLevelApi();
00285 if (CORBA::is_nil(highLevelApi))
00286 throw IllegalStateError("Couldn't get HighLevelApi", __FILE__, __LINE__);
00287
00288
00289 string dataFile = highLevelApi->getDataFile();
00290 moduleData.load(Sct::Env::substituteVariables(dataFile));
00291
00292 loadIgnoreFile();
00293 setup();
00294
00295
00296 if (modules.size() == 0) {
00297 string summaryFile = highLevelApi->getXmlSummaryFile();
00298 SctTest::XmlSummaryFile file(summaryFile);
00299
00300 while (file.hasMoreRecords() && nModules < maxModules) {
00301 SctTest::XmlSummaryRecord xsr = file.getNextRecord();
00302 if (xsr.serialNumber.length() == 0)
00303 continue;
00304 if (count(ignoreModules.begin(), ignoreModules.end(), xsr.serialNumber) != 0) {
00305 cout << "Ignoring module: " << xsr.serialNumber << endl;
00306 continue;
00307 }
00308 modules.push_back(xsr.serialNumber);
00309 ++nModules;
00310 }
00311 }
00312
00313
00314 for (list<string>::iterator it=modules.begin(); it!=modules.end(); ++it) {
00315
00316 if (count(ignoreModules.begin(), ignoreModules.end(), *it) == 0)
00317 doModule(*it);
00318 else
00319 cout << "Ignoring module: " << *it << endl;
00320 }
00321 nModules = modules.size();
00322
00323 file->cd();
00324 summaryOutput();
00325 } catch (Throwable& e) {
00326 e.sendToMrs(MRS_FATAL);
00327 exitCode = -1;
00328 }
00329 tearDown();
00330 }
00331
00332 template<typename T>
00333 AnalysisTestFramework<T>::AnalysisTestFramework(string isFilter, string isServer) : isFilter(isFilter), isServer(isServer) {
00334 debug = false;
00335 maxModules = 1000;
00336 file = 0;
00337 tree = 0;
00338 readOnly = false;
00339 exitCode = 0;
00340 nModules = 0;
00341 nSkip = 0;
00342 nData = 1;
00343 }
00344
00345
00346 #endif //ANALYSISTESTFRAMEWORK_H