00001 #ifndef ANALYSISTESTFRAMEWORK_H
00002 #define ANALYSISTESTFRAMEWORK_H
00003
00004 #include <vector>
00005 #include <string>
00006 #include <algorithm>
00007 #include <is/isinfo.h>
00008 #include <boost/shared_ptr.hpp>
00009 #include <iostream>
00010 #include <fstream>
00011 #include <TTree.h>
00012 #include <TApplication.h>
00013 #include <TFile.h>
00014 #include <TROOT.h>
00015
00016 #include "Sct/IS/IOManagerIS.h"
00017 #include "Sct/Exception.h"
00018 #include "Sct/Env.h"
00019 #include "Sct/LogicErrors.h"
00020 #include "Sct/SctNames.h"
00021 #include "Sct/ILUMarshalling.h"
00022 #include "Sct/SctParameters.h"
00023
00024 #include "SctData/DefectList.h"
00025 #include "SctData/Defect.h"
00026 #include "SctData/StandardDefects.h"
00027 #include "SctData/ModuleElement.h"
00028 #include "../SCTTestAPI/ModuleData.h"
00029 #include "../SCTTestAPI/XmlSummaryFile.h"
00030 #include "../SCTTestAPI/SctTestApi.hh"
00031
00032 using namespace Sct;
00033 using namespace Sct::IS;
00034 using namespace SctData;
00035 using namespace SctTest;
00036 using namespace boost;
00037 using namespace std;
00038
00039 template<typename T>
00040 class AnalysisTestFramework {
00041 public:
00047 AnalysisTestFramework(string isFilter=".*TestResult", string isServer="TestData");
00048 virtual ~AnalysisTestFramework(){}
00049
00050 void analyzeAll(int argc, char** argv);
00051
00055 void printHelp();
00056
00060 int getExitCode() {return exitCode;}
00061
00062 protected:
00068 virtual int handleArg(int argc, int i, char** argv);
00069
00073 virtual void printAdditionalArgs() {}
00074
00078 virtual void printHelpHeader();
00079
00080 virtual void summaryOutput() {}
00081
00087 virtual void doModule(string serialNumber);
00088
00093 virtual vector<shared_ptr<T> > readData(string serialNumber);
00094
00098 virtual void publishData(SctTestApiStatus* status) {}
00099
00103 virtual void downloadData(string serialNumber) {}
00104
00105 virtual void compare(const T& t) {}
00106
00107 virtual void setup() {}
00108
00109 virtual void tearDown();
00110
00111 int exitCode;
00112 bool readOnly;
00113 bool debug;
00114 IPCObjectVar<SctTestApi_T_HighLevelApi> highLevelApi;
00115 unsigned int nModules;
00116 unsigned int nSkip;
00117 list<string> modules;
00118 TFile* file;
00119 TTree* tree;
00120 ModuleData moduleData;
00121 unsigned int maxModules;
00122 unsigned int nData;
00123 string isFilter;
00124 string isServer;
00125 list<string> ignoreModules;
00126 string ignoreFile;
00127
00128 private:
00129 void loadIgnoreFile();
00130 void handleArgs(int argc, char** argv);
00131 static void getRootApp();
00132 };
00133
00134 template<typename T>
00135 vector<shared_ptr<T> > AnalysisTestFramework<T>::readData(string serialNumber) {
00136 string filter = isFilter + ".*" + serialNumber;
00137 while (true) {
00138 ISInfoIterator it(SctNames::getPartition(), isServer.c_str(), filter.c_str() );
00139 ISInfoDictionary dict(SctNames::getPartition());
00140
00141 if (it.entries() == nData) {
00142 vector<shared_ptr<T> > data;
00143 while (it()) {
00144 shared_ptr<Serializable> ob = IOManagerIS::instance().read(it);
00145 shared_ptr<T> result = dynamic_pointer_cast<T>(ob);
00146 if (!result)
00147 throw IllegalStateError(string("Failed to read test: ") + it.name(), __FILE__, __LINE__);
00148 data.push_back(result);
00149 }
00150 return data;
00151 }
00152 sleep(1);
00153 }
00154 }
00155
00159 template<typename T>
00160 void AnalysisTestFramework<T>::tearDown() {
00161 file->Write();
00162 file->Close();
00163 delete file;
00164 }
00165
00166 template<typename T>
00167 void AnalysisTestFramework<T>::doModule(string serialNumber) {
00168 SctTestApiStatus status;
00169 status.returnCode = 0;
00170
00171 highLevelApi->setModuleSerial(&status, copyStringToILU(serialNumber));
00172 if (!readOnly) publishData(&status);
00173 if (!readOnly && status.returnCode != 0) {
00174 cerr << "Error publishing data: " << status.returnCode << endl;
00175 return;
00176 }
00177 try {
00178 downloadData(serialNumber);
00179 vector<shared_ptr<T> > ob = readData(serialNumber);
00180 for (unsigned int i=0; i<ob.size(); ++i) {
00181 compare(*ob[i]);
00182 }
00183 } catch(Throwable& e) {
00184 e.sendToMrs(MRS_ERROR);
00185 }
00186 }
00187
00188
00189 template<typename T>
00190 void AnalysisTestFramework<T>::printHelpHeader() {
00191 cout << "RetrieveAndCompare [-n <num>] [-r] [-s <serials>] [-h/--help]" << endl;
00192 cout << "Compares SCTDAQ and SctRodDaq analyses" << endl;
00193 cout << "Arguments: " << endl;
00194 }
00195
00196 template<typename T>
00197 void AnalysisTestFramework<T>::printHelp() {
00198 printHelpHeader();
00199 cout << "-n <num>: Do up to <num> modules only, otherwise do all" << endl;
00200 cout << "-r: Read only - Useful for a re-run" << endl;
00201 cout << "-j <num>: Skip the first <num> modules in the config files" << endl;
00202 cout << "-h/--help: Print this help" << endl;
00203 cout << "-i <file>: Ignore file - a file with serial numbers, 1 per line, that will be ignored - useful for 'problem' modules" << endl;
00204 cout << "-s <serials>: All arguments after -s are assumed to be module serial numbers" << endl;
00205 printAdditionalArgs();
00206
00207 exit(0);
00208 }
00209
00210 template<typename T>
00211 int AnalysisTestFramework<T>::handleArg(int argc, int i, char** argv) {
00212 printHelp();
00213 return i;
00214 }
00215
00216
00217 template<typename T>
00218 void AnalysisTestFramework<T>::handleArgs(int argc, char** argv) {
00219 for (int i=1; i<argc; ++i) {
00220 if (string(argv[i]) == "-s") {
00221 for (int j=i+1; j<argc; ++j) {
00222 modules.push_back(argv[j]);
00223 ++nModules;
00224 }
00225 return;
00226 }
00227
00228 if (string(argv[i]) == "-n") {
00229 if (i+1 == argc) printHelp();
00230 istringstream iss(argv[++i]);
00231 iss >> maxModules;
00232 } else if (string(argv[i]) == "-r") {
00233 readOnly = true;
00234 } else if (string(argv[i]) == "-j") {
00235 if (i+1 == argc) printHelp();
00236 istringstream iss(argv[++i]);
00237 iss >> nSkip;
00238 } else if (string(argv[i]) == "-i") {
00239 if (i+1 == argc) printHelp();
00240 ignoreFile = argv[++i];
00241 } else {
00242 i = handleArg(argc, i, argv);
00243 }
00244
00245 }
00246 }
00247
00248
00249 template<typename T>
00250 void AnalysisTestFramework<T>::getRootApp() {
00251
00252
00253 gROOT->SetBatch(false);
00254
00255 }
00256
00257 template<typename T>
00258 void AnalysisTestFramework<T>::loadIgnoreFile() {
00259 if (ignoreFile.length()==0) return;
00260 ifstream file(ignoreFile.c_str());
00261 if (!file.is_open() || !file.good()) {
00262 cerr << "Unable to open ignore file: " << ignoreFile << endl;
00263 return;
00264 }
00265 string serial;
00266 while (file.good()) {
00267 file >> serial;
00268 if (serial[0] != '#' && serial.length() == 14 && count(ignoreModules.begin(), ignoreModules.end(), serial)==0) {
00269 ignoreModules.push_back(serial);
00270 }
00271 file.ignore(256, '\n');
00272 }
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 = SctNames::getPartition().lookup(SctTestApi_C_HighLevelApi_serverName, SctTestApi_C_HighLevelApi_instanceName, SctTestApi_T_HighLevelApi::ILUClassRecord);
00285 if (highLevelApi == 0)
00286 throw IllegalStateError("Couldn't get HighLevelApi", __FILE__, __LINE__);
00287
00288 SctTestApiStatus status;
00289 string dataFile = highLevelApi->getDataFile(&status);
00290 moduleData.load(Env::substituteVariables(dataFile));
00291
00292 loadIgnoreFile();
00293 setup();
00294
00295
00296 if (modules.size() == 0) {
00297 string summaryFile = highLevelApi->getXmlSummaryFile(&status);
00298 XmlSummaryFile file(summaryFile);
00299
00300 while (file.hasMoreRecords() && nModules < maxModules) {
00301 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