RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
core/monitor/testing/monitor_behaviour_test.cc
00001 /* monitor_behaviour_test.cc
00002    Wolfgang Sourdeau, Janyary 2013
00003    Copyright (c) 2013 Datacratic.  All rights reserved.
00004    
00005    Functional tests for the Monitor classes
00006 */
00007 
00008 #define BOOST_TEST_MAIN
00009 #define BOOST_TEST_DYN_LINK
00010 
00011 #include <memory>
00012 #include "boost/shared_ptr.hpp"
00013 #include "boost/test/unit_test.hpp"
00014 
00015 #include "soa/jsoncpp/value.h"
00016 
00017 #include "jml/arch/timers.h"
00018 #include "jml/utils/testing/watchdog.h"
00019 #include "jml/utils/pair_utils.h" // ostream << pair
00020 
00021 #include "soa/service/service_base.h"
00022 #include "soa/service/testing/zookeeper_temporary_server.h"
00023 
00024 #include "rtbkit/core/monitor/monitor_client.h"
00025 #include "rtbkit/core/monitor/monitor_endpoint.h"
00026 #include "rtbkit/core/monitor/monitor_provider.h"
00027 
00028 #include "mock_monitor_provider.h"
00029 
00030 using namespace std;
00031 using namespace Datacratic;
00032 using namespace RTBKIT;
00033 
00034 /* test the MonitorEndpoint/MonitorProviderClient pair
00035    using 2 mock monitor providers */
00036 BOOST_AUTO_TEST_CASE( test_monitor_endpoint )
00037 {
00038     ML::Watchdog watchdog(30.0);
00039 
00040     auto proxies = std::make_shared<ServiceProxies>();
00041 
00042     MonitorEndpoint endpoint(proxies);
00043     endpoint.init({"parentservice1", "parentservice2"});
00044     endpoint.bindTcp();
00045     endpoint.start();
00046     auto waitUpdate = [&] (bool initialStatus) {
00047         for (auto & it: endpoint.providersStatus_) {
00048             auto & providerStatus = it.second;
00049             providerStatus.lastStatus = initialStatus;
00050             Date initialCheck = providerStatus.lastCheck;
00051             while (providerStatus.lastCheck == initialCheck) {
00052                 ML::sleep(1);
00053             }
00054         }
00055     };
00056 
00057     MockMonitorProvider provider1;
00058     provider1.providerName_ = "parentservice1";
00059     ServiceBase parentService1("parentservice1", proxies);
00060     MonitorProviderClient providerClient1(proxies->zmqContext, provider1);
00061     providerClient1.init(proxies->config);
00062     providerClient1.start();
00063 
00064     MockMonitorProvider provider2;
00065     provider2.providerName_ = "parentservice2";
00066     ServiceBase parentService2("parentservice2", proxies);
00067     MonitorProviderClient providerClient2(proxies->zmqContext, provider2);
00068     providerClient2.init(proxies->config);
00069     providerClient2.start();
00070 
00071     /* provider1 status is false and provider2's is false
00072        => proxy status is false */
00073     cerr << ("test: "
00074              "provider1 status is false and provider2's is false\n"
00075              "=> proxy status is false\n");
00076     provider1.status_ = false;
00077     provider2.status_ = false;
00078     waitUpdate(true);
00079     BOOST_CHECK_EQUAL(endpoint.getMonitorStatus(), false);
00080 
00081     /* provider1 status is true but provider2's is false
00082        => proxy status is false */
00083     cerr << ("test: "
00084              "provider1 status is true but provider2's is false\n"
00085              "=> proxy status is false\n");
00086     provider1.status_ = true;
00087     waitUpdate(true);
00088     BOOST_CHECK_EQUAL(endpoint.getMonitorStatus(), false);
00089 
00090     /* provider1 status is true and provider2's is true
00091        => proxy status is true */
00092     cerr << ("test: "
00093              "provider1 status is true and provider2's is true\n"
00094              "=> proxy status is true\n");
00095     provider2.status_ = true;
00096     waitUpdate(false);
00097     BOOST_CHECK_EQUAL(endpoint.getMonitorStatus(), true);
00098 
00099     /* all providers send updates with a delay of one second
00100        => proxy status is true */
00101     cerr << ("test: "
00102              "all providers answer with a delay of one second\n"
00103              "=> proxy status is true\n");
00104     provider1.delay_ = 1;
00105     provider2.delay_ = 1;
00106     waitUpdate(false);
00107     BOOST_CHECK_EQUAL(endpoint.getMonitorStatus(), true);
00108 
00109     /* one providers sends updates with a delay of three seconds
00110        => proxy status is false */
00111     cerr << ("test: "
00112              "one provider answers with a delay of three seconds\n"
00113              "=> proxy status is false\n");
00114     provider2.delay_ = 3;
00115     waitUpdate(true);
00116     BOOST_CHECK_EQUAL(endpoint.getMonitorStatus(), false);
00117 }
00118 
00119 /* test the ability of a MonitorClient to update itself via http, using a
00120  * Monitor endpoint and zookeeper */
00121 BOOST_AUTO_TEST_CASE( test_monitor_client )
00122 {
00123     ML::Watchdog watchdog(30.0);
00124 
00125     ZooKeeper::TemporaryServer zookeeper;
00126     zookeeper.start();
00127 
00128     auto proxies = std::make_shared<ServiceProxies>();
00129     proxies->useZookeeper(ML::format("localhost:%d", zookeeper.getPort()));
00130 
00131     MonitorEndpoint endpoint(proxies);
00132     endpoint.init({"tim"});
00133     endpoint.bindTcp();
00134     endpoint.start();
00135 
00136     MonitorClient client(proxies->zmqContext);
00137     client.init(proxies->config);
00138     client.start();
00139 
00140     cerr << "test: expect computed status to be TRUE"
00141          << " after quering the Monitor" << endl;
00142     client.lastStatus = false;
00143     endpoint.providersStatus_["tim"].lastCheck = Date::now();
00144     endpoint.providersStatus_["tim"].lastStatus = true;
00145     Date initialCheck = client.lastCheck;
00146     while (client.lastCheck == initialCheck) {
00147         /* make sure the monitor does not return false */
00148         endpoint.providersStatus_["tim"].lastCheck = Date::now();
00149         ML::sleep(1);
00150     }
00151     BOOST_CHECK_EQUAL(client.getStatus(), true);
00152 
00153     cerr << "test: expect computed status to be FALSE"
00154          << " after quering the Monitor" << endl;
00155     client.lastStatus = true;
00156     endpoint.providersStatus_["tim"].lastStatus = false;
00157     initialCheck = client.lastCheck;
00158     while (client.lastCheck == initialCheck) {
00159         /* make sure the endpoint does not return false */
00160         endpoint.providersStatus_["tim"].lastCheck = Date::now();
00161         ML::sleep(1);
00162     }
00163     BOOST_CHECK_EQUAL(client.getStatus(), false);
00164 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator