RTBKit
0.9
Open-source framework to create real-time ad bidding systems.
|
00001 /* redis_banker_race_test.cc 00002 Jeremy Barnes, 2 November 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 #include <boost/test/unit_test.hpp> 00011 #include "jml/arch/format.h" 00012 #include "jml/arch/exception_handler.h" 00013 #include "jml/utils/guard.h" 00014 #include "rtbkit/plugins/bidding_agent/bidding_agent.h" 00015 #include "rtbkit/core/banker/redis_banker.h" 00016 #include "rtbkit/common/auction.h" 00017 #include "rtbkit/core/router/router.h" 00018 #include "jml/utils/environment.h" 00019 #include "jml/arch/timers.h" 00020 #include "dataflow/work_scheduler.h" 00021 #include <future> 00022 #include "soa/service/testing/redis_temporary_server.h" 00023 #include <boost/thread/thread.hpp> 00024 00025 00026 using namespace std; 00027 using namespace ML; 00028 using namespace Datacratic; 00029 using namespace RTBKIT; 00030 using namespace Redis; 00031 00032 00033 BOOST_AUTO_TEST_CASE( test_topup_transfer_race ) 00034 { 00035 auto s = std::make_shared<ServiceProxies>(); 00036 RedisTemporaryServer redis; 00037 00038 // Create a campaign with a budget 00039 { 00040 RedisBudgetController controller("bankerTest", redis); 00041 controller.addCampaignSync("testCampaign"); 00042 controller.addStrategySync("testCampaign", "testStrategy"); 00043 controller.setBudgetSync("testCampaign", MicroUSD(1000000)); 00044 } 00045 00046 // Do 1,000 topup transfers of one micro 00047 00048 int nTopupThreads = 2; 00049 int nAddBudgetThreads = 2; 00050 int nBidThreads = 1; // for the moment, we don't support multiple2; 00051 int numTransfersPerThread = 10000; 00052 int numAddBudgetsPerThread = 1000; 00053 00054 auto runTopupThread = [&] () 00055 { 00056 RedisBudgetController controller("bankerTest", redis); 00057 00058 for (unsigned i = 0; i < numTransfersPerThread; ++i) { 00059 controller.topupTransferSync("testCampaign", 00060 "testStrategy", 00061 MicroUSD(1)); 00062 } 00063 }; 00064 00065 auto runAddBudgetThread = [&] () 00066 { 00067 RedisBudgetController controller("bankerTest", redis); 00068 00069 for (unsigned i = 0; i < numAddBudgetsPerThread; ++i) { 00070 controller.addBudgetSync("testCampaign", MicroUSD(1)); 00071 } 00072 }; 00073 00074 uint64_t numBidsCommitted = 0; 00075 volatile bool finished = false; 00076 00077 auto runBidThread = [&] (int threadNum) 00078 { 00079 RedisBanker banker("bankerTest", "b", s, redis); 00080 00081 string item = "thread" + to_string(threadNum); 00082 00083 while (!finished) { 00084 // Authorize 10 00085 if (!banker.authorizeBid("testCampaign", "testStrategy", item, 00086 MicroUSD(1))) { 00087 banker.sync(); 00088 continue; 00089 } 00090 00091 // Commit 1 00092 banker.commitBid("testCampaign", "testStrategy", item, 00093 MicroUSD(1)); 00094 00095 ML::atomic_inc(numBidsCommitted); 00096 } 00097 00098 banker.sync(); 00099 }; 00100 00101 boost::thread_group topupThreads; 00102 for (unsigned i = 0; i < nTopupThreads; ++i) 00103 topupThreads.create_thread(runTopupThread); 00104 00105 for (unsigned i = 0; i < nAddBudgetThreads; ++i) 00106 topupThreads.create_thread(runAddBudgetThread); 00107 00108 boost::thread_group bidThreads; 00109 for (unsigned i = 0; i < nBidThreads; ++i) 00110 bidThreads.create_thread(std::bind(runBidThread, i)); 00111 00112 00113 topupThreads.join_all(); 00114 00115 finished = true; 00116 00117 bidThreads.join_all(); 00118 00119 RedisBanker banker("bankerTest", "b", s, redis); 00120 banker.sync(); 00121 Json::Value status = banker.getCampaignStatusJson("testCampaign", ""); 00122 00123 cerr << status << endl; 00124 00125 uint32_t amountAdded = nAddBudgetThreads * numAddBudgetsPerThread; 00126 uint32_t amountTransferred = nTopupThreads * numTransfersPerThread; 00127 00128 cerr << "numBidsCommitted = " << numBidsCommitted << endl; 00129 cerr << "amountTransferred = " << amountTransferred << endl; 00130 cerr << "amountAdded = " << amountAdded << endl; 00131 00132 00133 00134 BOOST_CHECK_EQUAL(status["available"]["micro-USD"].asInt(), 1000000 - amountTransferred + amountAdded); 00135 BOOST_CHECK_EQUAL(status["strategies"][0]["available"]["micro-USD"].asInt(), 00136 amountTransferred - numBidsCommitted); 00137 BOOST_CHECK_EQUAL(status["strategies"][0]["transferred"]["micro-USD"].asInt(), 00138 amountTransferred); 00139 BOOST_CHECK_EQUAL(status["strategies"][0]["spent"]["micro-USD"].asInt(), 00140 numBidsCommitted); 00141 BOOST_CHECK_EQUAL(status["spent"]["micro-USD"].asInt(), numBidsCommitted); 00142 00143 //BOOST_CHECK_EQUAL(status["available"]. 00144 }