Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-23 00:28:19

0001 /*
0002 */
0003 
0004 #include "FWCore/Framework/test/MockEventProcessor.h"
0005 #include "FWCore/Framework/interface/InputSource.h"
0006 #include <cassert>
0007 #include <sstream>
0008 #include <exception>
0009 
0010 namespace {
0011   // As each data item is read from the mock data it is
0012   // stored in one of these:
0013   struct token {
0014     int value;
0015     char id;
0016   };
0017 
0018   std::istream& operator>>(std::istream& is, token& t) {
0019     if (is >> t.id)
0020       is >> t.value;
0021     return is;
0022   }
0023 
0024   //The TransitionProcessors.icc uses the class name
0025   // EventProcessor (with no namespace) as the type
0026   // to which it interacts.
0027   using EventProcessor = edm::MockEventProcessor;
0028 
0029   class WaitingTaskHolder;
0030 }  // namespace
0031 
0032 namespace edm {
0033   class LuminosityBlockPrincipal {
0034   public:
0035     LuminosityBlockPrincipal(int iRun, int iLumi) : run_(iRun), lumi_(iLumi) {}
0036     int run_;
0037     int lumi_;
0038   };
0039 }  // namespace edm
0040 
0041 #define TEST_NO_FWD_DECL
0042 #include "FWCore/Framework/src/LuminosityBlockProcessingStatus.h"
0043 
0044 namespace {
0045 #include "FWCore/Framework/src/TransitionProcessors.icc"
0046 }
0047 
0048 namespace edm {
0049 
0050   MockEventProcessor::MockEventProcessor(std::string const& mockData, std::ostream& output, bool iDoNotMerge)
0051       : mockData_(mockData),
0052         output_(output),
0053         input_(mockData_),
0054         run_(0),
0055         lumi_(0),
0056         doNotMerge_(iDoNotMerge),
0057         shouldWeCloseOutput_(true),
0058         shouldWeEndLoop_(true),
0059         shouldWeStop_(false),
0060         eventProcessed_(false),
0061         reachedEndOfInput_(false),
0062         shouldThrow_(false) {}
0063 
0064   InputSource::ItemType MockEventProcessor::nextTransitionType() {
0065     token t;
0066     if (not(input_ >> t)) {
0067       reachedEndOfInput_ = true;
0068       return lastTransition_ = InputSource::IsStop;
0069     }
0070 
0071     char ch = t.id;
0072 
0073     eventProcessed_ = false;
0074     if (ch == 'r') {
0075       output_ << "    *** nextItemType: Run " << t.value << " ***\n";
0076       run_ = t.value;
0077       return lastTransition_ = InputSource::IsRun;
0078     } else if (ch == 'l') {
0079       output_ << "    *** nextItemType: Lumi " << t.value << " ***\n";
0080       lumi_ = t.value;
0081       return lastTransition_ = InputSource::IsLumi;
0082     } else if (ch == 'e') {
0083       output_ << "    *** nextItemType: Event ***\n";
0084       // a special value for test purposes only
0085       if (t.value == 7) {
0086         shouldWeStop_ = true;
0087         output_ << "    *** shouldWeStop will return true this event ***\n";
0088       } else {
0089         shouldWeStop_ = false;
0090       }
0091       return lastTransition_ = InputSource::IsEvent;
0092     } else if (ch == 'f') {
0093       output_ << "    *** nextItemType: File " << t.value << " ***\n";
0094       // a special value for test purposes only
0095       if (t.value == 0)
0096         shouldWeCloseOutput_ = false;
0097       else
0098         shouldWeCloseOutput_ = true;
0099       return lastTransition_ = InputSource::IsFile;
0100     } else if (ch == 's') {
0101       output_ << "    *** nextItemType: Stop " << t.value << " ***\n";
0102       // a special value for test purposes only
0103       if (t.value == 0)
0104         shouldWeEndLoop_ = false;
0105       else
0106         shouldWeEndLoop_ = true;
0107       return lastTransition_ = InputSource::IsStop;
0108     } else if (ch == 'x') {
0109       output_ << "    *** nextItemType: Restart " << t.value << " ***\n";
0110       shouldWeEndLoop_ = t.value;
0111       return lastTransition_ = InputSource::IsStop;
0112     } else if (ch == 't') {
0113       output_ << "    *** nextItemType: Throw " << t.value << " ***\n";
0114       shouldThrow_ = true;
0115       return nextTransitionType();
0116     }
0117     return lastTransition_ = InputSource::IsInvalid;
0118   }
0119 
0120   InputSource::ItemType MockEventProcessor::lastTransitionType() const { return lastTransition_; }
0121 
0122   std::pair<edm::ProcessHistoryID, edm::RunNumber_t> MockEventProcessor::nextRunID() {
0123     return std::make_pair(edm::ProcessHistoryID{}, run_);
0124   }
0125 
0126   edm::LuminosityBlockNumber_t MockEventProcessor::nextLuminosityBlockID() { return lumi_; }
0127 
0128   InputSource::ItemType MockEventProcessor::readAndProcessEvents() {
0129     bool first = true;
0130     do {
0131       if (first) {
0132         first = false;
0133       } else {
0134         shouldWeStop();
0135       }
0136       readAndProcessEvent();
0137       if (shouldWeStop()) {
0138         return InputSource::IsEvent;
0139       }
0140     } while (nextTransitionType() == InputSource::IsEvent);
0141 
0142     return lastTransitionType();
0143   }
0144 
0145   void MockEventProcessor::runToCompletion() {
0146     do {
0147       FilesProcessor fp(doNotMerge_);
0148 
0149       bool firstTime = true;
0150       do {
0151         if (not firstTime) {
0152           prepareForNextLoop();
0153           rewindInput();
0154         } else {
0155           firstTime = false;
0156         }
0157         startingNewLoop();
0158 
0159         auto trans = fp.processFiles(*this);
0160 
0161         fp.normalEnd();
0162 
0163         if (trans != InputSource::IsStop) {
0164           //problem with the source
0165           doErrorStuff();
0166           break;
0167         }
0168       } while (not endOfLoop());
0169       output_ << "Left processing loop.\n";
0170     } while (not reachedEndOfInput_ and not input_.eof());
0171 
0172     return;
0173   }
0174 
0175   void MockEventProcessor::readFile() {
0176     output_ << " \treadFile\n";
0177     throwIfNeeded();
0178   }
0179 
0180   void MockEventProcessor::closeInputFile(bool /*cleaningUpAfterException*/) { output_ << "\tcloseInputFile\n"; }
0181 
0182   void MockEventProcessor::openOutputFiles() { output_ << "\topenOutputFiles\n"; }
0183 
0184   void MockEventProcessor::closeOutputFiles() { output_ << "\tcloseOutputFiles\n"; }
0185 
0186   void MockEventProcessor::respondToOpenInputFile() { output_ << "\trespondToOpenInputFile\n"; }
0187 
0188   void MockEventProcessor::respondToCloseInputFile() { output_ << "\trespondToCloseInputFile\n"; }
0189 
0190   void MockEventProcessor::startingNewLoop() { output_ << "\tstartingNewLoop\n"; }
0191 
0192   bool MockEventProcessor::endOfLoop() {
0193     output_ << "\tendOfLoop\n";
0194     return shouldWeEndLoop_;
0195   }
0196 
0197   void MockEventProcessor::rewindInput() { output_ << "\trewind\n"; }
0198 
0199   void MockEventProcessor::prepareForNextLoop() { output_ << "\tprepareForNextLoop\n"; }
0200 
0201   bool MockEventProcessor::shouldWeCloseOutput() const {
0202     output_ << "\tshouldWeCloseOutput\n";
0203     return shouldWeCloseOutput_;
0204   }
0205 
0206   void MockEventProcessor::doErrorStuff() { output_ << "\tdoErrorStuff\n"; }
0207 
0208   void MockEventProcessor::beginProcessBlock(bool& beginProcessBlockSucceeded) {}
0209   void MockEventProcessor::inputProcessBlocks() {}
0210   void MockEventProcessor::endProcessBlock(bool cleaningUpAfterException, bool beginProcessBlockSucceeded) {}
0211 
0212   void MockEventProcessor::beginRun(ProcessHistoryID const& phid,
0213                                     RunNumber_t run,
0214                                     bool& globalTransitionSucceeded,
0215                                     bool& eventSetupForInstanceSucceeded) {
0216     output_ << "\tbeginRun " << run << "\n";
0217     eventSetupForInstanceSucceeded = true;
0218     throwIfNeeded();
0219     globalTransitionSucceeded = true;
0220   }
0221 
0222   void MockEventProcessor::endRun(ProcessHistoryID const& phid,
0223                                   RunNumber_t run,
0224                                   bool globalTransitionSucceeded,
0225                                   bool /*cleaningUpAfterException*/) {
0226     auto postfix = globalTransitionSucceeded ? "\n" : " global failed\n";
0227     output_ << "\tendRun " << run << postfix;
0228   }
0229 
0230   void MockEventProcessor::endUnfinishedRun(ProcessHistoryID const& phid,
0231                                             RunNumber_t run,
0232                                             bool globalTransitionSucceeded,
0233                                             bool cleaningUpAfterException,
0234                                             bool eventSetupForInstanceSucceeded) {
0235     if (eventSetupForInstanceSucceeded) {
0236       endRun(phid, run, globalTransitionSucceeded, cleaningUpAfterException);
0237       if (globalTransitionSucceeded) {
0238         writeRun(phid, run);
0239       }
0240     }
0241     deleteRunFromCache(phid, run);
0242   }
0243 
0244   InputSource::ItemType MockEventProcessor::processLumis(std::shared_ptr<void> iRunResource) {
0245     if (lumiStatus_ and lumiStatus_->runResource() == iRunResource and lumiStatus_->lumiPrincipal()->lumi_ == lumi_) {
0246       readAndMergeLumi(*lumiStatus_);
0247 
0248       if (nextTransitionType() == InputSource::IsEvent) {
0249         readAndProcessEvents();
0250         if (shouldWeStop()) {
0251           return edm::InputSource::IsStop;
0252         }
0253       }
0254     } else {
0255       endUnfinishedLumi();
0256       lumiStatus_ = std::make_shared<LuminosityBlockProcessingStatus>(this, 1, iRunResource);
0257       auto lumi = readLuminosityBlock(*lumiStatus_);
0258       output_ << "\tbeginLumi " << run_ << "/" << lumi << "\n";
0259       throwIfNeeded();
0260       lumiStatus_->globalBeginDidSucceed();
0261       //Need to do event processing here
0262       if (nextTransitionType() == InputSource::IsEvent) {
0263         readAndProcessEvents();
0264         if (shouldWeStop()) {
0265           return edm::InputSource::IsStop;
0266         }
0267       }
0268     }
0269     return lastTransitionType();
0270   }
0271 
0272   void MockEventProcessor::endUnfinishedLumi() {
0273     if (lumiStatus_) {
0274       auto tmp = lumiStatus_;
0275       endLumi();
0276       if (tmp->didGlobalBeginSucceed()) {
0277         writeLumi(*tmp);
0278       }
0279       deleteLumiFromCache(*tmp);
0280     }
0281   }
0282 
0283   void MockEventProcessor::endLumi() {
0284     auto postfix = lumiStatus_->didGlobalBeginSucceed() ? "\n" : " global failed\n";
0285     output_ << "\tendLumi " << lumiStatus_->lumiPrincipal()->run_ << "/" << lumiStatus_->lumiPrincipal()->lumi_
0286             << postfix;
0287     lumiStatus_.reset();
0288   }
0289 
0290   std::pair<ProcessHistoryID, RunNumber_t> MockEventProcessor::readRun() {
0291     output_ << "\treadRun " << run_ << "\n";
0292     return std::make_pair(ProcessHistoryID(), run_);
0293   }
0294 
0295   std::pair<ProcessHistoryID, RunNumber_t> MockEventProcessor::readAndMergeRun() {
0296     output_ << "\treadAndMergeRun " << run_ << "\n";
0297     return std::make_pair(ProcessHistoryID(), run_);
0298   }
0299 
0300   int MockEventProcessor::readLuminosityBlock(LuminosityBlockProcessingStatus& iStatus) {
0301     output_ << "\treadLuminosityBlock " << lumi_ << "\n";
0302     iStatus.lumiPrincipal() = std::make_shared<LuminosityBlockPrincipal>(run_, lumi_);
0303     return lumi_;
0304   }
0305 
0306   int MockEventProcessor::readAndMergeLumi(LuminosityBlockProcessingStatus& iStatus) {
0307     output_ << "\treadAndMergeLumi " << lumi_ << "\n";
0308     return lumi_;
0309   }
0310 
0311   void MockEventProcessor::writeRun(ProcessHistoryID const& phid, RunNumber_t run) {
0312     output_ << "\twriteRun " << run << "\n";
0313   }
0314 
0315   void MockEventProcessor::deleteRunFromCache(ProcessHistoryID const& phid, RunNumber_t run) {
0316     output_ << "\tdeleteRunFromCache " << run << "\n";
0317   }
0318 
0319   void MockEventProcessor::writeLumi(LuminosityBlockProcessingStatus& iStatus) {
0320     output_ << "\twriteLumi " << iStatus.lumiPrincipal()->run_ << "/" << iStatus.lumiPrincipal()->lumi_ << "\n";
0321   }
0322 
0323   void MockEventProcessor::deleteLumiFromCache(LuminosityBlockProcessingStatus& iStatus) {
0324     output_ << "\tdeleteLumiFromCache " << iStatus.lumiPrincipal()->run_ << "/" << iStatus.lumiPrincipal()->lumi_
0325             << "\n";
0326   }
0327 
0328   void MockEventProcessor::readAndProcessEvent() {
0329     output_ << "\treadEvent\n";
0330     output_ << "\tprocessEvent\n";
0331     eventProcessed_ = true;
0332     throwIfNeeded();
0333   }
0334 
0335   bool MockEventProcessor::shouldWeStop() const {
0336     output_ << "\tshouldWeStop\n";
0337     return eventProcessed_ and shouldWeStop_;
0338   }
0339 
0340   void MockEventProcessor::throwIfNeeded() {
0341     if (shouldThrow_) {
0342       shouldThrow_ = false;
0343       output_ << "\tthrowing\n";
0344       throw TestException();
0345     }
0346   }
0347 
0348   void MockEventProcessor::setExceptionMessageFiles(std::string&) {}
0349   void MockEventProcessor::setExceptionMessageRuns() {}
0350   void MockEventProcessor::setExceptionMessageLumis() {}
0351 
0352   bool MockEventProcessor::setDeferredException(std::exception_ptr) { return true; }
0353 
0354 }  // namespace edm