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