$treeview $search $mathjax
TraDemGen Logo  1.00.0
$projectbrief
$projectbrief
$searchbox

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/BookingRequestStruct.hpp>
00027 #include <stdair/service/Logger.hpp>
00028 // TraDemGen
00029 #include <trademgen/TRADEMGEN_Exceptions.hpp>
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 // //////////////////////////////////////////////////////////////////////
00065 void testDemandGenerationHelper (const unsigned short iTestFlag,
00066                                  const stdair::Filename_T& iDemandInputFilename,
00067                                  const stdair::DemandGenerationMethod& iDemandGenerationMethod,
00068                                  const bool isBuiltin) {
00069 
00070   // Seed for the random generation
00071   const stdair::RandomSeed_T lRandomSeed = stdair::DEFAULT_RANDOM_SEED;
00072   
00073   // Output log File
00074   std::ostringstream oStr;
00075   oStr << "DemandGenerationTestSuite_" << iTestFlag << ".log";
00076   const stdair::Filename_T lLogFilename (oStr.str());
00077 
00078   // Set the log parameters
00079   std::ofstream logOutputFile;
00080   // Open and clean the log outputfile
00081   logOutputFile.open (lLogFilename.c_str());
00082   logOutputFile.clear();
00083 
00084   // Initialise the TraDemGen service object
00085   const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00086   TRADEMGEN::TRADEMGEN_Service trademgenService (lLogParams, lRandomSeed);
00087 
00097   NbOfEventsByDemandStreamMap_T lNbOfEventsMap;
00098   
00099   // Total number of events
00100   stdair::Count_T lRefExpectedNbOfEvents (0);
00101   stdair::Count_T lRefActualNbOfEvents (0);
00102 
00103   // Check whether or not a (CSV) input file should be read
00104   if (isBuiltin == true) {
00105 
00106     // Build the default sample BOM tree (filled with demand streams) for TraDemGen
00107     trademgenService.buildSampleBom();
00108 
00109     lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00110                            value_type ("SIN-BKK 2010-Feb-08 Y",
00111                                        NbOfEventsPair_T (4, 60)));
00112     lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00113                            value_type ("BKK-HKG 2010-Feb-08 Y",
00114                                        NbOfEventsPair_T (4, 60)));
00115     lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00116                            value_type ("SIN-HKG 2010-Feb-08 Y",
00117                                        NbOfEventsPair_T (4, 60)));
00118 
00119     // Total number of events, for the 3 demand streams: 180
00120     lRefExpectedNbOfEvents = 180;
00121     lRefActualNbOfEvents = 186;
00122 
00123   } else {
00124 
00125     // Create the DemandStream objects, and insert them within the BOM tree
00126     const TRADEMGEN::DemandFilePath lDemandFilePath (iDemandInputFilename);
00127     trademgenService.parseAndLoad (lDemandFilePath);
00128 
00129     lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00130                            value_type ("SIN-HND 2010-Feb-08 Y",
00131                                        NbOfEventsPair_T (1, 10)));
00132     lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00133                            value_type ("SIN-HND 2010-Feb-09 Y",
00134                                        NbOfEventsPair_T (1, 10)));
00135     lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00136                            value_type ("SIN-BKK 2010-Feb-08 Y",
00137                                        NbOfEventsPair_T (1, 10)));
00138     lNbOfEventsMap.insert (NbOfEventsByDemandStreamMap_T::
00139                            value_type ("SIN-BKK 2010-Feb-09 Y",
00140                                        NbOfEventsPair_T (1, 10)));
00141 
00142     // Total number of events, for the 4 demand streams: 40
00143     lRefExpectedNbOfEvents = 40;
00144     lRefActualNbOfEvents = 40;
00145   }
00146   
00147   // Retrieve the expected (mean value of the) number of events to be
00148   // generated
00149   const stdair::Count_T& lExpectedNbOfEventsToBeGenerated =
00150     trademgenService.getExpectedTotalNumberOfRequestsToBeGenerated();
00151 
00152   BOOST_CHECK_EQUAL (lRefExpectedNbOfEvents,
00153                      std::floor (lExpectedNbOfEventsToBeGenerated));
00154   
00155   BOOST_CHECK_MESSAGE (lRefExpectedNbOfEvents ==
00156                        std::floor (lExpectedNbOfEventsToBeGenerated),
00157                        "Expected total number of requests to be generated: "
00158                        << lExpectedNbOfEventsToBeGenerated
00159                        << " (=> "
00160                        << std::floor (lExpectedNbOfEventsToBeGenerated)
00161                        << "). Reference value: " << lRefExpectedNbOfEvents);
00162 
00168   const stdair::Count_T& lActualNbOfEventsToBeGenerated =
00169     trademgenService.generateFirstRequests(iDemandGenerationMethod);
00170 
00171   // DEBUG
00172   STDAIR_LOG_DEBUG ("Expected number of events: "
00173                     << lExpectedNbOfEventsToBeGenerated << ", actual: "
00174                     << lActualNbOfEventsToBeGenerated);
00175   
00176   // Total number of events, for all the demand streams:
00177   BOOST_CHECK_EQUAL (lRefActualNbOfEvents, lActualNbOfEventsToBeGenerated);
00178   
00179   BOOST_CHECK_MESSAGE (lRefActualNbOfEvents == lActualNbOfEventsToBeGenerated,
00180                        "Actual total number of requests to be generated: "
00181                        << lExpectedNbOfEventsToBeGenerated
00182                        << " (=> "
00183                        << std::floor (lExpectedNbOfEventsToBeGenerated)
00184                        << "). Reference value: " << lRefActualNbOfEvents);
00185 
00187   const bool isQueueDone = trademgenService.isQueueDone();
00188   BOOST_REQUIRE_MESSAGE (isQueueDone == false,
00189                          "The event queue should not be empty.");
00190 
00198   stdair::Count_T idx = 1;
00199   while (trademgenService.isQueueDone() == false) {
00200 
00201     // Get the next event from the event queue
00202     stdair::EventStruct lEventStruct;
00203     stdair::ProgressStatusSet lPPS = trademgenService.popEvent (lEventStruct);
00204 
00205     // DEBUG
00206     STDAIR_LOG_DEBUG ("Poped event: '" << lEventStruct.describe() << "'.");
00207       
00208     // Extract the corresponding demand/booking request
00209     const stdair::BookingRequestStruct& lPoppedRequest =
00210       lEventStruct.getBookingRequest();
00211     
00212     // DEBUG
00213     STDAIR_LOG_DEBUG ("Poped booking request: '"
00214                       << lPoppedRequest.describe() << "'.");
00215     
00216     // Retrieve the corresponding demand stream
00217     const stdair::DemandGeneratorKey_T& lDemandStreamKey =
00218       lPoppedRequest.getDemandGeneratorKey();
00219 
00220     // Check that the number of booking requests to be generated are correct
00221     const NbOfEventsByDemandStreamMap_T::iterator itNbOfEventsMap =
00222       lNbOfEventsMap.find (lDemandStreamKey);
00223     BOOST_REQUIRE_MESSAGE (itNbOfEventsMap != lNbOfEventsMap.end(),
00224                            "The demand stream key '" << lDemandStreamKey
00225                            << "' is not expected in that test");
00226 
00236     const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
00237     stdair::Count_T lCurrentNbOfEvents = lNbOfEventsPair.first;
00238     const stdair::Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;
00239 
00240     // Assess whether more events should be generated for that demand stream
00241     const bool stillHavingRequestsToBeGenerated = trademgenService.
00242       stillHavingRequestsToBeGenerated (lDemandStreamKey, lPPS,
00243                                         iDemandGenerationMethod);
00244 
00251     if (lCurrentNbOfEvents == 1) {
00257       const stdair::ProgressStatus& lDemandStreamProgressStatus =
00258         lPPS.getSpecificGeneratorStatus();
00259       const stdair::Count_T& lNbOfRequests =
00260         lDemandStreamProgressStatus.getExpectedNb();
00261 
00262       BOOST_CHECK_EQUAL (lNbOfRequests, lExpectedTotalNbOfEvents);
00263       BOOST_CHECK_MESSAGE (lNbOfRequests == lExpectedTotalNbOfEvents,
00264                            "[" << lDemandStreamKey
00265                            << "] Total number of requests to be generated: "
00266                            << lNbOfRequests << "). Expected value: "
00267                            << lExpectedTotalNbOfEvents);
00268     }
00269 
00270     // DEBUG
00271     STDAIR_LOG_DEBUG ("=> [" << lDemandStreamKey << "][" << lCurrentNbOfEvents
00272                       << "/" << lExpectedTotalNbOfEvents
00273                       << "] is now processed. "
00274                       << "Still generate events for that demand stream? "
00275                       << stillHavingRequestsToBeGenerated);
00276 
00277     // If there are still events to be generated for that demand stream,
00278     // generate and add them to the event queue
00279     if (stillHavingRequestsToBeGenerated == true) {
00280       const stdair::BookingRequestPtr_T lNextRequest_ptr =
00281         trademgenService.generateNextRequest (lDemandStreamKey,
00282                                               iDemandGenerationMethod);
00283       assert (lNextRequest_ptr != NULL);
00284 
00290       const stdair::Duration_T lDuration =
00291         lNextRequest_ptr->getRequestDateTime()
00292         - lPoppedRequest.getRequestDateTime();
00293       BOOST_REQUIRE_GT (lDuration.total_milliseconds(), 0);
00294       BOOST_REQUIRE_MESSAGE (lDuration.total_milliseconds() > 0,
00295                              "[" << lDemandStreamKey
00296                              << "] The date-time of the generated event ("
00297                              << lNextRequest_ptr->getRequestDateTime()
00298                              << ") is lower than the date-time "
00299                              << "of the current event ("
00300                              << lPoppedRequest.getRequestDateTime() << ")");
00301       
00302       // DEBUG
00303       STDAIR_LOG_DEBUG ("[" << lDemandStreamKey << "][" << lCurrentNbOfEvents
00304                         << "/" << lExpectedTotalNbOfEvents
00305                         << "] Added request: '" << lNextRequest_ptr->describe()
00306                         << "'. Is queue done? "
00307                         << trademgenService.isQueueDone());
00308 
00309       // Keep, within the dedicated map, the current counters of events updated.
00310       ++lCurrentNbOfEvents;
00311       itNbOfEventsMap->second = NbOfEventsPair_T (lCurrentNbOfEvents,
00312                                                   lExpectedTotalNbOfEvents);
00313     }
00314     
00315     // Iterate
00316     ++idx;
00317   }
00318   // Compensate for the last iteration
00319   --idx;
00320 
00321   if (iDemandGenerationMethod == stdair::DemandGenerationMethod::STA_ORD) {
00322     //
00323     BOOST_CHECK_EQUAL (idx, lRefActualNbOfEvents);
00324     BOOST_CHECK_MESSAGE (idx == lRefActualNbOfEvents,
00325                          "The total actual number of events is "
00326                          << lRefActualNbOfEvents << ", but " << idx
00327                          << " events have been generated");
00328   }
00329   
00332   trademgenService.reset();
00333 
00334   // DEBUG
00335   STDAIR_LOG_DEBUG ("End of the simulation");
00336 
00337   // Close the log file
00338   logOutputFile.close();
00339 
00340 }
00341 
00342 
00343 // /////////////// Main: Unit Test Suite //////////////
00344 
00345 // Set the UTF configuration (re-direct the output to a specific file)
00346 BOOST_GLOBAL_FIXTURE (UnitTestConfig);
00347 
00348 // Start the test suite
00349 BOOST_AUTO_TEST_SUITE (master_test_suite)
00350 
00351 
00354 BOOST_AUTO_TEST_CASE (trademgen_simple_simulation_test) {
00355 
00356   // Input file name
00357   const stdair::Filename_T lInputFilename (STDAIR_SAMPLE_DIR "/demand01.csv");
00358 
00359   // Generate the date time of the requests with the statistic order method.
00360   const stdair::DemandGenerationMethod lDemandGenerationMethod (stdair::DemandGenerationMethod::STA_ORD);
00361   
00362   // State whether the BOM tree should be built-in or parsed from an input file
00363   const bool isBuiltin = false;
00364   BOOST_CHECK_NO_THROW (testDemandGenerationHelper(0,
00365                                                    lInputFilename,
00366                                                    lDemandGenerationMethod,
00367                                                    isBuiltin));
00368   
00369 }
00370 
00374 BOOST_AUTO_TEST_CASE (trademgen_missing_input_file_test) {
00375 
00376   // Input file name
00377   const stdair::Filename_T lInputFilename (STDAIR_SAMPLE_DIR "/missingFile.csv");
00378 
00379   // Generate the date time of the requests with the statistic order method.
00380   const stdair::DemandGenerationMethod lDemandGenerationMethod (stdair::DemandGenerationMethod::STA_ORD);
00381   
00382   // State whether the BOM tree should be built-in or parsed from an input file
00383   const bool isBuiltin = false;
00384   BOOST_CHECK_THROW (testDemandGenerationHelper(1,
00385                                                 lInputFilename,
00386                                                 lDemandGenerationMethod,
00387                                                 isBuiltin),
00388                      TRADEMGEN::DemandInputFileNotFoundException);
00389   
00390 }
00391 
00395 BOOST_AUTO_TEST_CASE (trademgen_default_bom_simulation_test) {
00396   
00397   // Generate the date time of the requests with the statistic order method.
00398   const stdair::DemandGenerationMethod lDemandGenerationMethod (stdair::DemandGenerationMethod::STA_ORD);
00399   
00400   // State whether the BOM tree should be built-in or parsed from an input file
00401   const bool isBuiltin = true;
00402   BOOST_CHECK_NO_THROW (testDemandGenerationHelper(2,
00403                                                    " " ,
00404                                                    lDemandGenerationMethod,
00405                                                    isBuiltin));
00406   
00407 }
00408 
00412 BOOST_AUTO_TEST_CASE (trademgen_poisson_process_test) {
00413   
00414   // Generate the date time of the requests with the poisson process.
00415   const stdair::DemandGenerationMethod lDemandGenerationMethod (stdair::DemandGenerationMethod::POI_PRO);
00416   
00417   // State whether the BOM tree should be built-in or parsed from an input file
00418   const bool isBuiltin = true;
00419   BOOST_CHECK_NO_THROW (testDemandGenerationHelper(3,
00420                                                    " " ,
00421                                                    lDemandGenerationMethod,
00422                                                    isBuiltin));
00423   
00424 }
00425 
00426 // End the test suite
00427 BOOST_AUTO_TEST_SUITE_END()
00428 
00429