TraDemGen Logo  0.2.2
C++ Simulated Travel Demand Generation Library
DemandGenerationTestSuite.cpp
Go to the documentation of this file.
00001 
00005 // //////////////////////////////////////////////////////////////////////
00006 // Import section
00007 // //////////////////////////////////////////////////////////////////////
00008 // STL
00009 #include <sstream>
00010 #include <fstream>
00011 #include <map>
00012 #include <cmath>
00013 // Boost Unit Test Framework (UTF)
00014 #define BOOST_TEST_DYN_LINK
00015 #define BOOST_TEST_MAIN
00016 #define BOOST_TEST_MODULE DemandGenerationTest
00017 #include <boost/test/unit_test.hpp>
00018 // StdAir
00019 #include <stdair/stdair_basic_types.hpp>
00020 #include <stdair/basic/BasConst_General.hpp>
00021 #include <stdair/basic/BasLogParams.hpp>
00022 #include <stdair/basic/BasDBParams.hpp>
00023 #include <stdair/basic/BasFileMgr.hpp>
00024 #include <stdair/basic/ProgressStatusSet.hpp>
00025 #include <stdair/bom/EventStruct.hpp>
00026 #include <stdair/bom/EventQueue.hpp>
00027 #include <stdair/bom/BookingRequestStruct.hpp>
00028 #include <stdair/service/Logger.hpp>
00029 // TraDemGen
00030 #include <trademgen/TRADEMGEN_Service.hpp>
00031 #include <trademgen/bom/DemandStreamKey.hpp>
00032 #include <trademgen/config/trademgen-paths.hpp>
00033 
00034 namespace boost_utf = boost::unit_test;
00035 
00036 // (Boost) Unit Test XML Report
00037 std::ofstream utfReportStream ("DemandGenerationTestSuite_utfresults.xml");
00038 
00042 struct UnitTestConfig {
00044   UnitTestConfig() {
00045     boost_utf::unit_test_log.set_stream (utfReportStream);
00046     boost_utf::unit_test_log.set_format (boost_utf::XML);
00047     boost_utf::unit_test_log.set_threshold_level (boost_utf::log_test_units);
00048     //boost_utf::unit_test_log.set_threshold_level (boost_utf::log_successful_tests);
00049   }
00050   
00052   ~UnitTestConfig() {
00053   }
00054 };
00055 
00056 // Specific type definitions
00057 typedef std::pair<stdair::Count_T, stdair::Count_T> NbOfEventsPair_T;
00058 typedef std::map<const stdair::DemandStreamKeyStr_T,
00059                  NbOfEventsPair_T> NbOfEventsByDemandStreamMap_T;
00060 
00061 
00062 // /////////////// Main: Unit Test Suite //////////////
00063 
00064 // Set the UTF configuration (re-direct the output to a specific file)
00065 BOOST_GLOBAL_FIXTURE (UnitTestConfig);
00066 
00067 // Start the test suite
00068 BOOST_AUTO_TEST_SUITE (master_test_suite)
00069 
00070 
00073 BOOST_AUTO_TEST_CASE (trademgen_simple_simulation_test) {
00074 
00075   // Seed for the random generation
00076   const stdair::RandomSeed_T lRandomSeed = stdair::DEFAULT_RANDOM_SEED;  
00077 
00078 // Input file name
00079   const stdair::Filename_T lInputFilename (STDAIR_SAMPLE_DIR "/demand01.csv");
00080 
00081   // Check that the file path given as input corresponds to an actual file
00082   const bool doesExistAndIsReadable =
00083     stdair::BasFileMgr::doesExistAndIsReadable (lInputFilename);
00084   BOOST_CHECK_MESSAGE (doesExistAndIsReadable == true,
00085                        "The '" << lInputFilename
00086                        << "' input file can not be open and read");
00087   
00088   // Output log File
00089   const stdair::Filename_T lLogFilename ("DemandGenerationTestSuite.log");
00090   
00091   // Set the log parameters
00092   std::ofstream logOutputFile;
00093   // open and clean the log outputfile
00094   logOutputFile.open (lLogFilename.c_str());
00095   logOutputFile.clear();
00096   
00097   // Initialise the TraDemGen service object
00098   const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00099   TRADEMGEN::TRADEMGEN_Service trademgenService (lLogParams, lRandomSeed);
00100 
00101   // Create the DemandStream objects, and insert them within the BOM tree
00102   BOOST_CHECK_NO_THROW (trademgenService.parseAndLoad (lInputFilename));
00103 
00113   NbOfEventsByDemandStreamMap_T lNbOfEventsMap;
00114   lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00115                          value_type ("SIN-HND 2010-Feb-08 Y",
00116                                      NbOfEventsPair_T (1, 10)));
00117   lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00118                          value_type ("SIN-HND 2010-Feb-09 Y",
00119                                      NbOfEventsPair_T (1, 10)));
00120   lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00121                          value_type ("SIN-BKK 2010-Feb-08 Y",
00122                                      NbOfEventsPair_T (1, 10)));
00123   lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00124                          value_type ("SIN-BKK 2010-Feb-09 Y",
00125                                      NbOfEventsPair_T (1, 10)));
00126   // Total number of events, for all the demand streams: 3
00127   stdair::Count_T lRefExpectedNbOfEvents (40);
00128   
00129   // Retrieve the expected (mean value of the) number of events to be
00130   // generated
00131   const stdair::Count_T& lExpectedNbOfEventsToBeGenerated =
00132     trademgenService.getExpectedTotalNumberOfRequestsToBeGenerated();
00133 
00134   BOOST_CHECK_EQUAL (lRefExpectedNbOfEvents,
00135                      std::floor (lExpectedNbOfEventsToBeGenerated));
00136   
00137   BOOST_CHECK_MESSAGE (lRefExpectedNbOfEvents ==
00138                        std::floor (lExpectedNbOfEventsToBeGenerated),
00139                        "Expected total number of requests to be generated: "
00140                        << lExpectedNbOfEventsToBeGenerated
00141                        << " (=> "
00142                        << std::floor (lExpectedNbOfEventsToBeGenerated)
00143                        << "). Reference value: " << lRefExpectedNbOfEvents);
00144 
00145   // Generate the date time of the requests with the statistic order method.
00146   stdair::DemandGenerationMethod lDemandGenerationMethod (stdair::DemandGenerationMethod::STA_ORD);
00147 
00157   const stdair::Count_T& lActualNbOfEventsToBeGenerated =
00158     trademgenService.generateFirstRequests(lDemandGenerationMethod);
00159 
00160   // DEBUG
00161   STDAIR_LOG_DEBUG ("Expected number of events: "
00162                     << lExpectedNbOfEventsToBeGenerated << ", actual: "
00163                     << lActualNbOfEventsToBeGenerated);
00164   
00165   // Total number of events, for all the demand streams: 40
00166   const stdair::Count_T lRefActualNbOfEvents (40);
00167   BOOST_CHECK_EQUAL (lRefActualNbOfEvents, lActualNbOfEventsToBeGenerated);
00168   
00169   BOOST_CHECK_MESSAGE (lRefActualNbOfEvents == lActualNbOfEventsToBeGenerated,
00170                        "Actual total number of requests to be generated: "
00171                        << lExpectedNbOfEventsToBeGenerated
00172                        << " (=> "
00173                        << std::floor (lExpectedNbOfEventsToBeGenerated)
00174                        << "). Reference value: " << lRefActualNbOfEvents);
00175 
00177   const bool isQueueDone = trademgenService.isQueueDone();
00178   BOOST_REQUIRE_MESSAGE (isQueueDone == false,
00179                          "The event queue should not be empty. You may check "
00180                          << "the input file: '" << lInputFilename << "'");
00181 
00189   stdair::Count_T idx = 1;
00190   while (trademgenService.isQueueDone() == false) {
00191 
00192     // Get the next event from the event queue
00193     stdair::EventStruct lEventStruct;
00194     stdair::ProgressStatusSet lPPS = trademgenService.popEvent (lEventStruct);
00195 
00196     // DEBUG
00197     STDAIR_LOG_DEBUG ("Poped event: '" << lEventStruct.describe() << "'.");
00198       
00199     // Extract the corresponding demand/booking request
00200     const stdair::BookingRequestStruct& lPoppedRequest =
00201       lEventStruct.getBookingRequest();
00202     
00203     // DEBUG
00204     STDAIR_LOG_DEBUG ("Poped booking request: '"
00205                       << lPoppedRequest.describe() << "'.");
00206     
00207     // Retrieve the corresponding demand stream
00208     const stdair::DemandGeneratorKey_T& lDemandStreamKey =
00209       lPoppedRequest.getDemandGeneratorKey();
00210 
00211     // Check that the number of booking requests to be generated are correct
00212     const NbOfEventsByDemandStreamMap_T::iterator itNbOfEventsMap =
00213       lNbOfEventsMap.find (lDemandStreamKey);
00214     BOOST_REQUIRE_MESSAGE (itNbOfEventsMap != lNbOfEventsMap.end(),
00215                            "The demand stream key '" << lDemandStreamKey
00216                            << "' is not expected in that test");
00217 
00227     const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
00228     stdair::Count_T lCurrentNbOfEvents = lNbOfEventsPair.first;
00229     const stdair::Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;
00230 
00231     // Assess whether more events should be generated for that demand stream
00232     const bool stillHavingRequestsToBeGenerated = trademgenService.
00233       stillHavingRequestsToBeGenerated (lDemandStreamKey, lPPS,
00234                                         lDemandGenerationMethod);
00235 
00242     if (lCurrentNbOfEvents == 1) {
00248       const stdair::ProgressStatus& lDemandStreamProgressStatus =
00249         lPPS.getSpecificGeneratorStatus();
00250       const stdair::Count_T& lNbOfRequests =
00251         lDemandStreamProgressStatus.getExpectedNb();
00252 
00253       BOOST_CHECK_EQUAL (lNbOfRequests, lExpectedTotalNbOfEvents);
00254       BOOST_CHECK_MESSAGE (lNbOfRequests == lExpectedTotalNbOfEvents,
00255                            "[" << lDemandStreamKey
00256                            << "] Total number of requests to be generated: "
00257                            << lNbOfRequests << "). Expected value: "
00258                            << lExpectedTotalNbOfEvents);
00259     }
00260 
00261     // DEBUG
00262     STDAIR_LOG_DEBUG ("=> [" << lDemandStreamKey << "][" << lCurrentNbOfEvents
00263                       << "/" << lExpectedTotalNbOfEvents
00264                       << "] is now processed. "
00265                       << "Still generate events for that demand stream? "
00266                       << stillHavingRequestsToBeGenerated);
00267 
00268     // If there are still events to be generated for that demand stream,
00269     // generate and add them to the event queue
00270     if (stillHavingRequestsToBeGenerated == true) {
00271       const stdair::BookingRequestPtr_T lNextRequest_ptr =
00272         trademgenService.generateNextRequest (lDemandStreamKey,
00273                                               lDemandGenerationMethod);
00274       assert (lNextRequest_ptr != NULL);
00275 
00281       const stdair::Duration_T lDuration =
00282         lNextRequest_ptr->getRequestDateTime()
00283         - lPoppedRequest.getRequestDateTime();
00284       BOOST_REQUIRE_GT (lDuration.total_milliseconds(), 0);
00285       BOOST_REQUIRE_MESSAGE (lDuration.total_milliseconds() > 0,
00286                              "[" << lDemandStreamKey
00287                              << "] The date-time of the generated event ("
00288                              << lNextRequest_ptr->getRequestDateTime()
00289                              << ") is lower than the date-time "
00290                              << "of the current event ("
00291                              << lPoppedRequest.getRequestDateTime() << ")");
00292       
00293       // DEBUG
00294       STDAIR_LOG_DEBUG ("[" << lDemandStreamKey << "][" << lCurrentNbOfEvents
00295                         << "/" << lExpectedTotalNbOfEvents
00296                         << "] Added request: '" << lNextRequest_ptr->describe()
00297                         << "'. Is queue done? "
00298                         << trademgenService.isQueueDone());
00299 
00300       // Keep, within the dedicated map, the current counters of events updated.
00301       ++lCurrentNbOfEvents;
00302       itNbOfEventsMap->second = NbOfEventsPair_T (lCurrentNbOfEvents,
00303                                                   lExpectedTotalNbOfEvents);
00304     }
00305     
00306     // Iterate
00307     ++idx;
00308   }
00309   // Compensate for the last iteration
00310   --idx;
00311   //
00312   BOOST_CHECK_EQUAL (idx, lRefActualNbOfEvents);
00313   BOOST_CHECK_MESSAGE (idx == lRefActualNbOfEvents,
00314                        "The total actual number of events is "
00315                        << lRefActualNbOfEvents << ", but " << idx
00316                        << " events have been generated");
00317   
00320   trademgenService.reset();
00321 
00322   // DEBUG
00323   STDAIR_LOG_DEBUG ("End of the simulation");
00324 
00325   // Close the log file
00326   logOutputFile.close();
00327 }
00328 
00329 // End the test suite
00330 BOOST_AUTO_TEST_SUITE_END()
00331 
00332 
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines