TransportStatsProvider

This commit is contained in:
Pavel Kirienko 2014-03-27 03:13:25 +04:00
parent 851e984e35
commit 0dff5b36e4
5 changed files with 154 additions and 2 deletions

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#pragma once
#include <uavcan/node/service_server.hpp>
#include <uavcan/util/method_binder.hpp>
#include <uavcan/protocol/GetTransportStats.hpp>
namespace uavcan
{
class TransportStatsProvider : Noncopyable
{
typedef MethodBinder<const TransportStatsProvider*,
void (TransportStatsProvider::*)(const protocol::GetTransportStats::Request&,
protocol::GetTransportStats::Response&) const>
GetTransportStatsCallback;
ServiceServer<protocol::GetTransportStats, GetTransportStatsCallback> srv_;
void handleGetTransportStats(const protocol::GetTransportStats::Request&,
protocol::GetTransportStats::Response& resp) const;
public:
explicit TransportStatsProvider(INode& node)
: srv_(node)
{ }
int start();
};
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#include <uavcan/protocol/transport_stats_provider.hpp>
namespace uavcan
{
void TransportStatsProvider::handleGetTransportStats(const protocol::GetTransportStats::Request&,
protocol::GetTransportStats::Response& resp) const
{
const TransferPerfCounter& perf = srv_.getNode().getDispatcher().getTransferPerfCounter();
resp.transfer_errors = perf.getErrorCount();
resp.transfers_tx = perf.getTxTransferCount();
resp.transfers_rx = perf.getRxTransferCount();
const CanIOManager& canio = srv_.getNode().getDispatcher().getCanIOManager();
for (int i = 0; i < canio.getNumIfaces(); i++)
{
const CanIfacePerfCounters can_perf = canio.getIfacePerfCounters(i);
protocol::CanIfaceStats stats;
stats.errors = can_perf.errors;
stats.frames_tx = can_perf.frames_tx;
stats.frames_rx = can_perf.frames_rx;
resp.can_iface_stats.push_back(stats);
}
}
int TransportStatsProvider::start()
{
return srv_.start(GetTransportStatsCallback(this, &TransportStatsProvider::handleGetTransportStats));
}
}

View File

@ -8,7 +8,7 @@
#include <uavcan/FigureOfMerit.hpp>
#include <uavcan/mavlink/Message.hpp>
#include <uavcan/protocol/ComputeAggregateTypeSignature.hpp>
#include <uavcan/protocol/GetProtocolStatistics.hpp>
#include <uavcan/protocol/GetTransportStats.hpp>
#include <uavcan/protocol/Panic.hpp>
#include <uavcan/protocol/RestartNode.hpp>
#include <uavcan/protocol/GlobalTimeSync.hpp>

View File

@ -43,10 +43,12 @@ struct PairableCanDriver : public uavcan::ICanDriver, public uavcan::ICanIface
PairableCanDriver* other;
std::queue<uavcan::CanFrame> read_queue;
std::queue<uavcan::CanFrame> loopback_queue;
uint64_t error_count;
PairableCanDriver(uavcan::ISystemClock& clock)
: clock(clock)
, other(NULL)
, error_count(0)
{ }
void linkTogether(PairableCanDriver* with)
@ -122,7 +124,7 @@ struct PairableCanDriver : public uavcan::ICanDriver, public uavcan::ICanIface
int configureFilters(const uavcan::CanFilterConfig*, int) { return -1; }
int getNumFilters() const { return 0; }
uint64_t getErrorCount() const { return 0; }
uint64_t getErrorCount() const { return error_count; }
};

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#include <gtest/gtest.h>
#include <uavcan/protocol/transport_stats_provider.hpp>
#include "helpers.hpp"
TEST(TransportStatsProvider, Basic)
{
InterlinkedTestNodesWithSysClock nodes;
uavcan::TransportStatsProvider tsp(nodes.a);
uavcan::GlobalDataTypeRegistry::instance().reset();
uavcan::DefaultDataTypeRegistrator<uavcan::protocol::GetTransportStats> _reg1;
ASSERT_LE(0, tsp.start());
ServiceClientWithCollector<uavcan::protocol::GetTransportStats> tsp_cln(nodes.b);
/*
* First request
*/
ASSERT_LE(0, tsp_cln.call(1, uavcan::protocol::GetTransportStats::Request()));
ASSERT_LE(0, nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1)));
ASSERT_TRUE(tsp_cln.collector.result->isSuccessful());
ASSERT_EQ(0, tsp_cln.collector.result->response.transfer_errors);
ASSERT_EQ(1, tsp_cln.collector.result->response.transfers_rx);
ASSERT_EQ(0, tsp_cln.collector.result->response.transfers_tx);
ASSERT_EQ(1, tsp_cln.collector.result->response.can_iface_stats.size());
ASSERT_EQ(0, tsp_cln.collector.result->response.can_iface_stats[0].errors);
ASSERT_EQ(1, tsp_cln.collector.result->response.can_iface_stats[0].frames_rx);
ASSERT_EQ(0, tsp_cln.collector.result->response.can_iface_stats[0].frames_tx);
/*
* Second request
*/
ASSERT_LE(0, tsp_cln.call(1, uavcan::protocol::GetTransportStats::Request()));
ASSERT_LE(0, nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1)));
ASSERT_EQ(0, tsp_cln.collector.result->response.transfer_errors);
ASSERT_EQ(2, tsp_cln.collector.result->response.transfers_rx);
ASSERT_EQ(1, tsp_cln.collector.result->response.transfers_tx);
ASSERT_EQ(1, tsp_cln.collector.result->response.can_iface_stats.size());
ASSERT_EQ(0, tsp_cln.collector.result->response.can_iface_stats[0].errors);
ASSERT_EQ(2, tsp_cln.collector.result->response.can_iface_stats[0].frames_rx);
ASSERT_EQ(8, tsp_cln.collector.result->response.can_iface_stats[0].frames_tx);
/*
* Sending a malformed frame, it must be registered as tranfer error
*/
uavcan::Frame frame(uavcan::protocol::GetTransportStats::DefaultDataTypeID, uavcan::TransferTypeServiceRequest,
2, 1, 0, 0, true);
uavcan::CanFrame can_frame;
ASSERT_TRUE(frame.compile(can_frame));
nodes.can_a.read_queue.push(can_frame);
ASSERT_LE(0, nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1)));
/*
* Introducing a CAN driver error
*/
nodes.can_a.error_count = 72;
/*
* Third request
*/
ASSERT_LE(0, tsp_cln.call(1, uavcan::protocol::GetTransportStats::Request()));
ASSERT_LE(0, nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1)));
ASSERT_EQ(1, tsp_cln.collector.result->response.transfer_errors); // That broken frame
ASSERT_EQ(3, tsp_cln.collector.result->response.transfers_rx);
ASSERT_EQ(2, tsp_cln.collector.result->response.transfers_tx);
ASSERT_EQ(1, tsp_cln.collector.result->response.can_iface_stats.size());
ASSERT_EQ(72, tsp_cln.collector.result->response.can_iface_stats[0].errors);
ASSERT_EQ(4, tsp_cln.collector.result->response.can_iface_stats[0].frames_rx); // Same here
ASSERT_EQ(16, tsp_cln.collector.result->response.can_iface_stats[0].frames_tx);
}