Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

Commit

Permalink
test coverage on monitor
Browse files Browse the repository at this point in the history
  • Loading branch information
isabelsavannah committed Feb 28, 2019
1 parent 0e66b53 commit 438799d
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 1 deletion.
2 changes: 1 addition & 1 deletion monitor/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(test_srcs monitor_test.cpp)
set(test_libs monitor)
set(test_libs monitor options)

add_gmock_test(monitor)
187 changes: 187 additions & 0 deletions monitor/test/monitor_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
// Copyright (C) 2018 Bluzelle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include <monitor/monitor.hpp>
#include <mocks/mock_system_clock.hpp>
#include <include/boost_asio_beast.hpp>
#include <mocks/mock_system_clock.hpp>
#include <mocks/mock_boost_asio_beast.hpp>
#include <options/options.hpp>

#include <regex>
#include <gmock/gmock.h>
#include <mocks/mock_options_base.hpp>

using namespace ::testing;

class monitor_test : public Test
{
public:
std::shared_ptr<bzn::asio::Mockio_context_base> io_context = std::make_shared<bzn::asio::Mockio_context_base>();
std::shared_ptr<bzn::mock_system_clock> clock = std::make_shared<bzn::mock_system_clock>();
std::shared_ptr<bzn::mock_options_base> options = std::make_shared<bzn::mock_options_base>();
std::shared_ptr<bzn::monitor> monitor;

uint64_t current_time = 0;
std::vector<std::string> sent_messages;

boost::asio::ip::udp::endpoint ep;
bool send_works = true;

monitor_test()
{
EXPECT_CALL(*(this->options), get_uuid()).WillRepeatedly(Return("uuid"));
EXPECT_CALL(*(this->options), get_monitor_endpoint(_)).WillRepeatedly(Invoke([&](auto){return this->ep;}));

EXPECT_CALL(*(this->clock), microseconds_since_epoch()).WillRepeatedly(Invoke(
[&]()
{
return this->current_time;
}
));

EXPECT_CALL(*(this->io_context), make_unique_udp_socket()).WillRepeatedly(Invoke(
[&]()
{
auto socket = std::make_unique<bzn::asio::Mockudp_socket_base>();
EXPECT_CALL(*socket, async_send_to(_, _, _)).WillRepeatedly(Invoke(
[&](auto buffer, auto /*endpoint*/, auto handler)
{
sent_messages.emplace_back(reinterpret_cast<const char*>(buffer.data()), buffer.size());
if(this->send_works)
{
handler(boost::system::error_code{}, buffer.size());
}
else
{
handler(boost::asio::error::connection_refused, 0);
}
}
));
return socket;
}
));

this->monitor = std::make_shared<bzn::monitor>(this->options, this->io_context, this->clock);
}

std::pair<std::string, uint64_t> parse_counter(const std::string& message)
{
std::regex counter_regex("^(.*):(\\d*)\\|(.*)$");
std::smatch result;

EXPECT_TRUE(std::regex_match(message, result, counter_regex));
EXPECT_EQ(result[3].str(), "c");

return std::pair(result[1].str(), std::stoull(result[2].str()));
};

std::pair<std::string, uint64_t> parse_timer(const std::string& message)
{
std::regex timer_regex("^(.*):(\\d*)\\|(.*)$");
std::smatch result;

EXPECT_TRUE(std::regex_match(message, result, timer_regex));
EXPECT_EQ(result[3].str(), "us");

return std::pair(result[1].str(), std::stoull(result[2].str()));
};
};

TEST_F(monitor_test, test_that_counters_emit_metric)
{
this->monitor->send_counter(bzn::statistic::message_sent);
this->monitor->send_counter(bzn::statistic::message_sent_bytes, 15u);

EXPECT_EQ(this->parse_counter(this->sent_messages.at(0)).second, 1u);
EXPECT_EQ(this->parse_counter(this->sent_messages.at(1)).second, 15u);
}

TEST_F(monitor_test, test_that_timers_emit_metric)
{
this->monitor->start_timer("hash");
this->current_time = 10;
this->monitor->finish_timer(bzn::statistic::request_latency, "hash");

auto res = this->parse_timer(this->sent_messages.at(0));

EXPECT_EQ(res.second, 10u);
}

TEST_F(monitor_test, test_concurrent_timers)
{
this->current_time = 10;
this->monitor->start_timer("A");
this->current_time = 20;
this->monitor->start_timer("B");

this->current_time = 100;
this->monitor->finish_timer(bzn::statistic::request_latency, "A");
this->current_time = 1000;
this->monitor->finish_timer(bzn::statistic::request_latency, "B");

EXPECT_EQ(this->parse_timer(this->sent_messages.at(0)).second, 100u - 10u);
EXPECT_EQ(this->parse_timer(this->sent_messages.at(1)).second, 1000u - 20u);
}

TEST_F(monitor_test, test_timer_with_duplicate_triggers)
{
this->current_time = 10;
this->monitor->start_timer("A");
this->current_time = 21;
this->monitor->start_timer("A");

this->current_time = 30;
this->monitor->finish_timer(bzn::statistic::request_latency, "A");
this->current_time = 43;
this->monitor->finish_timer(bzn::statistic::request_latency, "A");

EXPECT_EQ(this->parse_timer(this->sent_messages.at(0)).second, 30u - 10u);
EXPECT_EQ(this->sent_messages.size(), 1u);
}

TEST_F(monitor_test, test_no_endpoint)
{
auto options2 = std::make_shared<bzn::mock_options_base>();
EXPECT_CALL(*options2, get_monitor_endpoint(_)).WillRepeatedly(Return(std::nullopt));
auto monitor2 = std::make_shared<bzn::monitor>(options2, io_context, clock);

monitor2->send_counter(bzn::statistic::message_sent);
monitor2->start_timer("a");
monitor2->finish_timer(bzn::statistic::request_latency, "a");

EXPECT_EQ(this->sent_messages.size(), 0u);
}

TEST_F(monitor_test, test_timers_cleanup)
{
for(int i=0; i<12000; /*more than we remember at once*/ i++)
{
this->monitor->start_timer(std::to_string(i));
}

this->monitor->finish_timer(bzn::statistic::request_latency, std::to_string(0));

EXPECT_EQ(this->sent_messages.size(), 0u);
}

TEST_F(monitor_test, test_send_fails)
{
this->send_works = false;
monitor->send_counter(bzn::statistic::message_sent);
monitor->start_timer("a");
monitor->finish_timer(bzn::statistic::request_latency, "a");

// just testing for no crash
}

0 comments on commit 438799d

Please sign in to comment.