RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
core/banker/testing/redis_banker_test.cc
00001 /* redis_banker_test.cc
00002    Sunil Rottoo, 4th April 2012
00003    Copyright (c) 2012 Datacratic.  All rights reserved.
00004    
00005    Test for the banker class.
00006 */
00007 
00008 #define BOOST_TEST_MAIN
00009 #define BOOST_TEST_DYN_LINK
00010 
00011 #include <boost/test/unit_test.hpp>
00012 #include "jml/arch/format.h"
00013 #include "jml/arch/exception_handler.h"
00014 #include "jml/utils/guard.h"
00015 #include "rtbkit/plugins/bidding_agent/bidding_agent.h"
00016 #include "rtbkit/core/banker/redis_banker.h"
00017 #include "rtbkit/common/auction.h"
00018 #include "rtbkit/core/router/router.h"
00019 #include "jml/utils/environment.h"
00020 #include "jml/arch/timers.h"
00021 #include "dataflow/work_scheduler.h"
00022 #include <future>
00023 #include "soa/service/testing/redis_temporary_server.h"
00024 #include <boost/thread/thread.hpp>
00025 
00026 
00027 using namespace std;
00028 using namespace ML;
00029 using namespace Datacratic;
00030 using namespace RTBKIT;
00031 using namespace Redis;
00032 
00033 const StrategyInfo & getStrategyInfo(const RedisBanker &theBanker,
00034         const std::string &campaign, const std::string &strategy)
00035 {
00036     const Campaigns &theCampaigns = theBanker.getCampaigns();
00037     Campaigns::const_iterator found = theCampaigns.find(campaign);
00038     BOOST_CHECK(found != theCampaigns.end());
00039 
00040     const Strategies &memStrategies =
00041             theCampaigns.find(campaign)->second.strategies_;
00042     const StrategyInfo &stratinfo = memStrategies.find(strategy)->second;
00043     return stratinfo;
00044 }
00045 
00046 BOOST_AUTO_TEST_CASE( test_banker_new_campaign )
00047 {
00048     auto s = std::make_shared<ServiceProxies>();
00049     RedisTemporaryServer redis;
00050     RedisBanker banker("bankerTest", "b", s, redis);
00051     RedisBudgetController controller("bankerTest", redis);
00052 
00053     auto campaign = banker.getCampaignStatusJson("hello", "");
00054     cerr << campaign << endl;
00055 
00056     auto strategy = banker.getCampaignStatusJson("hello", "world");
00057     cerr << strategy << endl;
00058     
00059     BOOST_CHECK_EQUAL(banker.authorizeBid("hello", "world", "one", MicroUSD(1)),
00060                       false);
00061     
00062     controller.topupTransferSync("hello", "world", MicroUSD(10));
00063 }
00064 
00065 BOOST_AUTO_TEST_CASE( test_transfer_all_remaining )
00066 {
00067     // Test for ADGR-188
00068     // When we try to transfer more to a strategy than is available, we
00069     // should not simply fail, but transfer all that we can
00070 
00071     auto s = std::make_shared<ServiceProxies>();
00072     RedisTemporaryServer redis;
00073     RedisBudgetController controller("bankerTest", redis);
00074     controller.addCampaignSync("testCampaign");
00075     controller.addStrategySync("testCampaign", "testStrategy");
00076     controller.setBudgetSync("testCampaign", MicroUSD(1000));
00077     controller.topupTransferSync("testCampaign", "testStrategy",
00078                                            MicroUSD(10000));
00079 
00080     RedisBanker banker("bankerTest", "b", s, redis);
00081 
00082     banker.sync();
00083     Json::Value status = banker.getCampaignStatusJson("testCampaign", "");
00084 
00085     cerr << status << endl;
00086 
00087     BOOST_CHECK_EQUAL(status["available"]["micro-USD"].asInt(), 0);
00088     BOOST_CHECK_EQUAL(status["strategies"][0]["available"]["micro-USD"].asInt(), 1000);
00089     BOOST_CHECK_EQUAL(status["strategies"][0]["transferred"]["micro-USD"].asInt(), 1000);
00090 }
00091 
00092 #if 1
00093 BOOST_AUTO_TEST_CASE( test_banker_basic )
00094 {
00095     {
00096         std::string campaignName = "TestCampaign";
00097         std::string campaign2 = "TestCampaign2";
00098         std::string campaign3 = "TestCampaign3";
00099         std::string campaign4 = "TestCampaign4";
00100         std::string campaign5 = "TestCampaign5";
00101         std::string campaign6 = "TestCampaign6";
00102         std::string campaign7 = "TestCampaign7";
00103         std::string strategy1 = "strategy1";
00104         std::string strategy2 = "strategy2";
00105 
00106         string campaignPrefix = "bankerTest";
00107 
00108         RedisTemporaryServer redis;
00109 
00110         Redis::AsyncConnection dbConn(redis);
00111 
00112         auto REDIS_CHECK_CAMPAIGN_EQUAL = [&](const string &key, const string &hash,
00113                 uint64_t value)
00114         {
00115             Reply reply = dbConn.exec(HGET(campaignPrefix + ":" + key, key)).reply();
00116             if (reply.type() != ARRAY)
00117             {
00118                 return false;
00119             }
00120             if (reply.length() == 0)
00121             {
00122                 return false;
00123             }
00124             cerr << "reply is " << reply << endl;
00125             //uint64_t readValue = boost::lexical_cast<uint64_t>(reply[])
00126             return true;
00127         };
00128         
00129         unsigned testNum = 1;
00130 
00131         auto s = std::make_shared<ServiceProxies>();
00132         {
00133             // add two campaigns - one with no strategies and one with 2 strategies
00134             // and make sure they load property
00135             auto runCommand = [&] (Redis::Command command)
00136                 {
00137                     Reply reply1 = dbConn.exec(command).reply();
00138                     //cerr << "command = " << command << endl;
00139                     //cerr << "reply1.type() = " << reply1.type() << endl;
00140                     //cerr << "reply1.asJson() = " << reply1.asJson() << endl;
00141                     //cerr << "reply1 = " << reply1 << endl;
00142                     BOOST_CHECK_EQUAL(reply1.asString(), "OK");
00143                 };
00144 
00145             auto setCampaign = [&] (std::string campaign,
00146                                     uint64_t available)
00147                 {
00148                     runCommand(HMSET(campaignPrefix + ":" + campaign,
00149                                      "available:micro-USD", available));
00150                 };
00151             
00152             auto setStrategy = [&] (std::string campaign, std::string strategy,
00153                                     uint64_t available,
00154                                     uint64_t spent,
00155                                     uint64_t transferred)
00156                 {
00157                     runCommand(HMSET(campaignPrefix + ":" + campaign
00158                                      + ":" + strategy,
00159                                      "available:micro-USD", available,
00160                                      "spent:micro-USD", spent,
00161                                      "transferred:micro-USD", transferred));
00162                 };
00163 
00164             setCampaign("TestCampaign6", 1000000);
00165 
00166             setCampaign("TestCampaign7", 2000000);
00167             setStrategy("TestCampaign7", "strategy1", 100000, 100000, 200000);
00168             setStrategy("TestCampaign7", "strategy2",      0, 200000, 200000);
00169 
00170             setCampaign("TestCampaign4", 1000000);
00171             setStrategy("TestCampaign4", "strategy1",  90000,  10000, 100000);
00172         }
00173 
00174         // Check that if we supply the wrong redis port we fail to connect
00175         BOOST_CHECK_THROW(RedisBanker("xxx", "b", s,
00176                                       Redis::Address::tcp("dev2", 6377)),
00177                           ML::Exception);
00178         // Check that if we supply the wrong redis hostname we fail to connect
00179         BOOST_CHECK_THROW(RedisBanker("xxx", "b", s,
00180                                       Redis::Address::tcp("fred", 6379)),
00181                           ML::Exception);
00182         
00183         // Now create a valid banker
00184         cerr <<"Creating banker and loading all campaigns" << endl;
00185 
00186         RedisBanker theBanker("bankerTest", "b", s, redis);
00187         RedisBudgetController theController("bankerTest", redis);
00188         cerr << "done creating banker" << endl;
00189         {
00190             Json::Value result = theBanker.dumpAllCampaignsJson();
00191 
00192             BOOST_CHECK_EQUAL(result.isMember(campaign6), true);
00193 
00194             cerr << "All Campaigns: " << result << endl;
00195             cerr << "\t" << testNum++ << ". Checking that campaign 6 was loaded correctly."
00196                  << endl;
00197             theController.addCampaignSync(campaign6);
00198 
00199             // Make sure that we have the correct values
00200             CampaignInfo campaign = theBanker.getCampaignDebug(campaign6);
00201             BOOST_CHECK_EQUAL(campaign.available_,MicroUSD(1000000));
00202             REDIS_CHECK_CAMPAIGN_EQUAL(campaign6, "available_", 1000000);
00203             BOOST_CHECK(campaign.transferred_.empty());
00204             // Make sure that there are no strategies
00205             const Strategies &strats = campaign.strategies_;
00206             BOOST_CHECK_EQUAL(strats.size(), 0);
00207         }
00208         {
00209             cerr << "\t" << testNum++ << ". Checking that campaign7 was loaded correctly."
00210                  << endl;
00211             theController.addCampaignSync(campaign7);
00212             CampaignInfo campaign = theBanker.getCampaignDebug(campaign7);
00213 
00214             // Make sure that we have the correct values
00215             BOOST_CHECK_EQUAL(campaign.available_,MicroUSD(2000000));
00216             BOOST_CHECK_EQUAL(campaign.transferred_,MicroUSD(400000));
00217             // Make sure that both strategies are in there
00218             const Strategies &strats = campaign.strategies_;
00219             BOOST_CHECK_EQUAL(strats.size(), 2);
00220             Strategies::const_iterator found1 = strats.find(strategy1);
00221             BOOST_CHECK(found1 != strats.end());
00222             if(found1 != strats.end())
00223             {
00224                 BOOST_CHECK_EQUAL(found1->second.available_, MicroUSD(100000));
00225                 BOOST_CHECK_EQUAL(found1->second.spent_, MicroUSD(100000));
00226                 BOOST_CHECK_EQUAL(found1->second.transferred_, MicroUSD(200000));
00227             }
00228             Strategies::const_iterator found2 = strats.find(strategy2);
00229             BOOST_CHECK(found2 != strats.end());
00230             if(found2 != strats.end())
00231             {
00232                 BOOST_CHECK_EQUAL(found2->second.available_, MicroUSD(0));
00233                 BOOST_CHECK_EQUAL(found2->second.spent_, MicroUSD(200000));
00234                 BOOST_CHECK_EQUAL(found2->second.transferred_, MicroUSD(200000));
00235             }
00236             BOOST_CHECK_EQUAL(campaign.spent_,
00237                               found1->second.spent_ + found2->second.spent_);
00238         }
00239         // Check that we do not accept a campaign that is an empty string
00240         auto addCampaign1 = [&]()
00241         {
00242             theController.addCampaignSync("");
00243         };
00244         BOOST_CHECK_THROW(addCampaign1(), BankerException);
00245 
00246         // Now add a valid campaign
00247         {
00248             theController.addCampaignSync(campaignName);
00249             CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00250             cerr << "\t" << testNum++ << ". Added TestCampaign got the result: "
00251                     << campaign << endl;
00252             BOOST_CHECK(campaign.available_.empty());
00253         }
00254         // Now add a budget to an existing campaign
00255         {
00256             // create a $500 campaign
00257             theController.setBudgetSync(campaignName, USD(500));
00258             theBanker.sync();
00259             CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00260             cerr << "\t" << testNum++ << ". Set the budget for : " << campaign
00261                     << endl;
00262             BOOST_CHECK_EQUAL(campaign.available_, USD(500));
00263         }
00264         // Now add a strategy 1 to a campaign
00265         {
00266             theController.addStrategySync(campaignName, strategy1);
00267             CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00268             cerr << "\t" << testNum++ << ". Added strategy : " << strategy1
00269                     << " to campaign " << campaign << endl;
00270             BOOST_CHECK_EQUAL(campaign.available_, USD(500));
00271             // The strategy isn't there yet as we haven't yet transferred
00272             // any money into it.
00273         }
00274         // Next add a strategy to a campaign that is not known.  This should
00275         // not fail, but we don't expect to see it there until we transfer
00276         // some budget to it.
00277         {
00278             theController.addStrategySync(campaign2, strategy1);
00279         }
00280         // Set the budget for a non-existing campaign we expect the campaign
00281         // to be added
00282         {
00283             // create a $600 campaign
00284             theController.setBudgetSync(campaign3, USD(600));
00285             theBanker.sync();
00286             CampaignInfo campaign = theBanker.getCampaignDebug(campaign3);
00287             cerr << "\t" << testNum++
00288                     << ". Set the budget for previously non-existing campaign: "
00289                     << campaign3 << endl;
00290             BOOST_CHECK_EQUAL(campaign.available_, USD(600));
00291         }
00292         // Add another strategy to campaign1
00293         {
00294             theController.addStrategySync(campaignName, strategy2);
00295             CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00296             cerr << "\t" << testNum++ << ". Added strategy : " << strategy2
00297                     << " to campaign " << campaign << endl;
00298             BOOST_CHECK_EQUAL(campaign.available_, USD(500));
00299         }
00300         {
00301             // Top up strategy 1 to $20
00302             {
00303                 std::promise<CampaignInfo> thePromise;
00304                 auto onTopupDone = [&] (std::exception_ptr exc)
00305                     {
00306                         cerr << "called onTopupDone" << endl;
00307                         if (exc)
00308                             thePromise.set_exception(exc);
00309                         else {
00310                             cerr << "getting debug campaign" << endl;
00311                             theBanker.sync();
00312                             thePromise.set_value(theBanker.getCampaignDebug(campaignName));
00313                         }
00314                         cerr << "finished onTopupDone" << endl;
00315                     };
00316 
00317                 cerr << "performing topup to strategy" << endl;
00318                 theController.topupTransfer(campaignName, strategy1,
00319                                                       MicroUSD(20000000),
00320                                                       onTopupDone);
00321 
00322                 CampaignInfo campaign = thePromise.get_future().get();
00323                 cerr << "\t " << testNum++ << ". topped up strategy : " << strategy1
00324                         << " to campaign " << campaign << endl;
00325                 BOOST_CHECK_EQUAL(campaign.transferred_, USD(20));
00326                 // Make sure that the campaign now has $480
00327                 BOOST_CHECK_EQUAL(campaign.available_, USD(480));
00328                 BOOST_CHECK_GE(campaign.strategies_.size(), 1);
00329                 const Strategies &strategies = campaign.strategies_;
00330                 // Make sure the strategies are there in-memory
00331                 Strategies::const_iterator foundStrat1 = strategies.find(strategy1);
00332                 BOOST_CHECK(foundStrat1 != strategies.end());
00333 
00334                 // Make sure that the strategy 1 has $20 available
00335                 BOOST_CHECK_EQUAL(foundStrat1->second.available_, USD(20));
00336                 //..and 20$ transferred
00337                 BOOST_CHECK_EQUAL(foundStrat1->second.transferred_, USD(20));
00338             }
00339             // topup strategy2 to $20
00340             {
00341                 std::promise<CampaignInfo> thePromise;
00342                 auto onTopupDone = [&] (std::exception_ptr exc)
00343                     {
00344                         cerr << "onTopupDone callback with exc " << (bool)exc
00345                         << endl;
00346                         if (exc)
00347                             thePromise.set_exception(exc);
00348                         else {
00349                             theBanker.sync();
00350                             thePromise.set_value(theBanker.getCampaignDebug(campaignName));
00351                         }
00352                         cerr << "onTopupDone callback finished" << endl;
00353                     };
00354 
00355                 theController.topupTransfer(campaignName, strategy2,
00356                                                       USD(20), onTopupDone);
00357 
00358                 CampaignInfo campaign = thePromise.get_future().get();
00359 
00360                  cerr << "\t " << testNum++ << ". Added strategy : " << strategy2
00361                          << " to campaign " << campaign << endl;
00362                  BOOST_CHECK_EQUAL(campaign.transferred_, USD(40));
00363                  // Make sure that the campaign now has $480
00364                  BOOST_CHECK_EQUAL(campaign.available_, USD(460));
00365                  BOOST_CHECK_EQUAL(campaign.strategies_.size(), 2);
00366                  const Strategies &strategies = campaign.strategies_;
00367                  // Make sure the strategies are there in-memory
00368                  Strategies::const_iterator foundStrat1 = strategies.find(strategy1);
00369                  BOOST_CHECK(foundStrat1 != strategies.end());
00370                  Strategies::const_iterator foundStrat2 = strategies.find(strategy2);
00371                  BOOST_CHECK(foundStrat2 != strategies.end());
00372                  // Make sure that the strategy 2 has $20 available
00373                  BOOST_CHECK_EQUAL(foundStrat2->second.available_, USD(20));
00374                  //..and 20$ transferred
00375                  BOOST_CHECK_EQUAL(foundStrat2->second.transferred_, USD(20));
00376 
00377             }
00378         }
00379         cerr << "\t" << testNum++
00380                 << ". Trying to add 100 000 to campaign. Exceeds maximum test"
00381                 << endl;
00382         // Now try to add 50000$ to the campaign. It should throw an exception since this is
00383         // the current limit
00384 
00385         BOOST_CHECK_THROW(theController.addBudgetSync(campaignName,USD(100000)),
00386                           BankerException);
00387         cerr << "finished adding too much" << endl;
00388 
00389         {
00390             // Top up strategy 1 to $20
00391             // Now add $30 to the campaign this should be fine and we should
00392             // have $510 available
00393             cerr << "\t" << testNum++
00394                     << ". Add $30 to the budget for campaign: " << campaignName
00395                     << endl;
00396             theController.addBudgetSync(campaignName, USD(30));
00397             theBanker.sync();
00398             CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00399             BOOST_CHECK_EQUAL(campaign.available_, USD(490));
00400             cerr << "The campaign is " << campaign << endl;
00401         }
00402         // Now we want a test where we set the budget to an absolute value.
00403         // We first try to set the budget to a value that is less than the
00404         // amount transferred. We should get an exception
00405         cerr << "\t" << testNum++
00406                 << ". Testing that we cannot set the campaign budget to less than transferred amount"
00407                 << endl;
00408         BOOST_CHECK_THROW(theController.setBudgetSync(campaignName, MicroUSD(15000000)),
00409                           BankerException);
00410         {
00411             // Now we set the budget to $300 which should be okay. We expect the
00412             // available amount to now be $280 since $20 has already been transferred
00413             cerr << "\t" << testNum++ << ". Set the budget to $300: "
00414                     << campaignName << endl;
00415             theController.setBudgetSync(campaignName, USD(300));
00416             theBanker.sync();
00417             CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00418             BOOST_CHECK_EQUAL(campaign.available_, USD(260));
00419             BOOST_CHECK_EQUAL(campaign.transferred_, USD(40));
00420             const Strategies &memStrategies = campaign.strategies_;
00421             const StrategyInfo &stratinfo =
00422                     memStrategies.find(strategy1)->second;
00423             BOOST_CHECK_EQUAL(stratinfo.commitments_.size(), 0);
00424         }
00425         {
00426             // Test - Simple Bid
00427             // Now bid on something for a value of $19 for strategy 1
00428             {
00429                 cerr << "\t" << testNum++ << ". Bid on something for $19: "
00430                         << campaignName << endl;
00431 
00432 
00433                 BOOST_CHECK(theBanker.authorizeBid(campaignName, strategy1, "bid1", MicroUSD(19000000)));
00434                 theBanker.sync();
00435                 CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00436 
00437                 const Strategies &memStrategies = campaign.strategies_;
00438                 const StrategyInfo &stratinfo =
00439                         memStrategies.find(strategy1)->second;
00440                 BOOST_CHECK_EQUAL(stratinfo.available_, MicroUSD(1000000));
00441                 BOOST_CHECK_EQUAL(stratinfo.committed_, MicroUSD(19000000));
00442                 BOOST_CHECK_EQUAL(stratinfo.commitments_.size(), 1);
00443             }
00444             {
00445                 // Bid something for a value of $15 for strategy2
00446                 cerr << "\t" << testNum++ << ". Bid on something for $15: "
00447                         << campaignName << " strategy : " << strategy2 << endl;
00448                 theBanker.authorizeBid(campaignName, strategy2, "bid1", MicroUSD(15000000));
00449                 theBanker.sync();
00450                 CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00451 
00452                 const Strategies &memStrategies = campaign.strategies_;
00453                 const StrategyInfo &stratinfo =
00454                         memStrategies.find(strategy2)->second;
00455                 BOOST_CHECK_EQUAL(stratinfo.available_, MicroUSD(5000000));
00456                 BOOST_CHECK_EQUAL(stratinfo.committed_, MicroUSD(15000000));
00457                 BOOST_CHECK_EQUAL(stratinfo.commitments_.size(), 1);
00458                 // And win the bid
00459                 cerr << "\t" << testNum++ << ". Win the bid for $15: "
00460                         << campaignName << " strategy : " << strategy2 << endl;
00461 
00462                 theBanker.winBid(campaignName, strategy2, "bid1", MicroUSD(15000000));
00463                 theBanker.sync();
00464                 CampaignInfo wincampaign = theBanker.getCampaignDebug(campaignName);
00465                 // Now make sure we have the right accounting
00466                 const Strategies &winStrategies = wincampaign.strategies_;
00467                 const StrategyInfo &winStratInfo =
00468                          winStrategies.find(strategy2)->second;
00469                 BOOST_CHECK_EQUAL(winStratInfo.available_, MicroUSD(5000000));
00470                 BOOST_CHECK_EQUAL(winStratInfo.committed_, USD(0));
00471                 BOOST_CHECK_EQUAL(winStratInfo.spent_, MicroUSD(15000000));
00472                 BOOST_CHECK_EQUAL(winStratInfo.commitments_.size(), 0);
00473                 BOOST_CHECK_EQUAL(wincampaign.spent_, MicroUSD(15000000));
00474             }
00475         }
00476         {
00477             // Test - Cancel
00478             // cancel a bid we want to be back to the original
00479             cerr << "\t" << testNum++ << ". Cancel previous bid: "
00480                     << campaignName << endl;
00481             theBanker.cancelBid(campaignName, strategy1, "bid1");
00482             theBanker.sync();
00483             CampaignInfo campaign = theBanker.getCampaignDebug(campaignName);
00484 
00485             const Strategies &memStrategies = campaign.strategies_;
00486             const StrategyInfo &stratinfo =
00487                     memStrategies.find(strategy1)->second;
00488             BOOST_CHECK_EQUAL(stratinfo.available_, MicroUSD(20000000));
00489             BOOST_CHECK_EQUAL(stratinfo.committed_, MicroUSD(0));
00490             BOOST_CHECK_EQUAL(stratinfo.commitments_.size(), 0);
00491         }
00492         {
00493             // Test - win a bid and pay a lower price
00494             // Did on something for a value of $19
00495             cerr << "\t" << testNum++ << ". Win a bid but pay a lower price: "
00496                     << campaignName << endl;
00497             theBanker.authorizeBid(campaignName, strategy1, "bid1", MicroUSD(19000000));
00498             theBanker.winBid(campaignName, strategy1, "bid1", MicroUSD(15000000));
00499             theBanker.sync();
00500             CampaignInfo wincampaign = theBanker.getCampaignDebug(campaignName);
00501 
00502             const Strategies &memStrategies = wincampaign.strategies_;
00503             const StrategyInfo &stratinfo =
00504                     memStrategies.find(strategy1)->second;
00505             BOOST_CHECK_EQUAL(stratinfo.available_, MicroUSD(5000000));
00506             BOOST_CHECK_EQUAL(stratinfo.committed_, MicroUSD(0));
00507             BOOST_CHECK_EQUAL(stratinfo.spent_, MicroUSD(15000000));
00508             BOOST_CHECK_EQUAL(stratinfo.commitments_.size(), 0);
00509             BOOST_CHECK_EQUAL(wincampaign.spent_, MicroUSD(30000000));
00510         }
00511         Json::Value campaignStatus = theBanker.dumpAllCampaignsJson();
00512         cerr << "campaign status : " << campaignStatus << endl;
00513         {
00514             cerr << "\t" << testNum++
00515                     << ". submit a bit for a certain amount but pay more than available: "
00516                     << campaignName << endl;
00517             // **
00518             // Test - win a bid but pay more for it than is available. At this point we have $5
00519             // Bid $4.90
00520             BOOST_CHECK(theBanker.authorizeBid(campaignName, strategy1, "bid1", MicroUSD(4900000)));
00521 
00522             // We also make sure we cannot submit the same bid twice
00523             BOOST_CHECK_THROW(
00524                               theBanker.authorizeBid(campaignName, strategy1, "bid1", MicroUSD(4900000)),
00525                     ML::Exception);
00526 
00527             // Now win the bid at a higher price
00528             theBanker.winBid(campaignName, strategy1, "bid1", MicroUSD(5100000));
00529             CampaignInfo winCampaign = theBanker.getCampaignDebug(campaignName);
00530             const Strategies &memStrategies = winCampaign.strategies_;
00531             const StrategyInfo &stratinfo =
00532                     memStrategies.find(strategy1)->second;
00533             BOOST_CHECK_EQUAL(stratinfo.available_, MicroUSD(-100000));
00534             BOOST_CHECK_EQUAL(stratinfo.committed_, MicroUSD(0));
00535             BOOST_CHECK_EQUAL(stratinfo.commitments_.size(), 0);
00536             // we should have spent $20.10
00537             BOOST_CHECK_EQUAL(stratinfo.spent_, USD(20.10));
00538         }
00539         {
00540             cerr << "\t" << testNum++
00541                     << ". submit a bit with no funds available: "
00542                     << campaignName << endl;
00543             // Test. Submit a bid with no funds available. This is synchronous
00544             // so we don't use a promise
00545             bool result = theBanker.authorizeBid(campaignName, strategy1, "bid1",
00546                                                  MicroUSD(4900000));
00547             BOOST_CHECK_EQUAL(result, false);
00548             theBanker.sync();
00549         }
00550         {
00551             // simulate the case where we have a campaign already in the database
00552             // when we add the campaign we expect it to be loaded
00553             theController.addCampaignSync(campaign4);
00554             CampaignInfo campaign = theBanker.getCampaignDebug(campaign4);
00555             cerr << "\t" << testNum++
00556                     << ". Added TestCampaign4 and got the result: "
00557                     << campaign << endl;
00558             BOOST_CHECK_EQUAL(campaign.available_, MicroUSD(1000000));
00559             BOOST_CHECK_EQUAL(campaign.transferred_, MicroUSD(100000));
00560         }
00561         {
00562             // simulate the case where we have a campaign and its associated strategy
00563             // already in the database. When we add a strategy to the
00564             // campaign we expect them both to be loaded.
00565             theController.addStrategySync(campaign4, strategy1);
00566             CampaignInfo campaign = theBanker.getCampaignDebug(campaign4);
00567             cerr << "\t" << testNum++ << ". Added strategy : " << strategy1
00568                     << " to campaign " << campaign4 << endl;
00569             BOOST_CHECK_EQUAL(campaign.available_, MicroUSD(1000000));
00570             BOOST_CHECK_EQUAL(campaign.transferred_, MicroUSD(100000));
00571             BOOST_CHECK_EQUAL(campaign.spent_, MicroUSD(10000));
00572 
00573             const Strategies &memStrategies = campaign.strategies_;
00574             const StrategyInfo &stratinfo =
00575                     memStrategies.find(strategy1)->second;
00576             BOOST_CHECK_EQUAL(stratinfo.available_, MicroUSD(90000));
00577             BOOST_CHECK_EQUAL(stratinfo.transferred_, MicroUSD(100000));
00578             BOOST_CHECK_EQUAL(stratinfo.spent_, MicroUSD(10000));
00579             BOOST_CHECK_EQUAL(stratinfo.commitments_.size(), 0);
00580         }
00581         cerr << "campaign status at the end : " << theBanker.dumpAllCampaignsJson();
00582     }
00583 }
00584 
00585 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator