Skip to content

Commit

Permalink
Qt: bug fixes and enhancement to traffic graph widget (#1429)
Browse files Browse the repository at this point in the history
* clear trafficgraph on clear button click

* set default sample height

set default sample height so after clearing traffic graph have some
scale

* reduce available traffic graph ranges, add optimized graph data storage

reduce available traffic graph ranges to 10
(5m,10m,15m,30m,1h,2h,3h,6h,12h,24h),
store graph data so range change is possible,
data storage contains only necessary data to create graphs for all
supported ranges
eg. for 10m range storage only half of 10m samples - the second half is
calculated from 5m range samples,
encapsulate all traffic graph related data into one class

* code formatting corrections
  • Loading branch information
krychlicki authored and UdjinM6 committed May 28, 2017
1 parent 28a1d0e commit 18c83f5
Show file tree
Hide file tree
Showing 12 changed files with 619 additions and 85 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ BITCOIN_QT_H = \
qt/sendcoinsentry.h \
qt/signverifymessagedialog.h \
qt/splashscreen.h \
qt/trafficgraphdata.h \
qt/trafficgraphwidget.h \
qt/transactiondesc.h \
qt/transactiondescdialog.h \
Expand Down Expand Up @@ -379,6 +380,7 @@ BITCOIN_QT_CPP = \
qt/qvaluecombobox.cpp \
qt/rpcconsole.cpp \
qt/splashscreen.cpp \
qt/trafficgraphdata.cpp \
qt/trafficgraphwidget.cpp \
qt/utilitydialog.cpp

Expand Down
7 changes: 5 additions & 2 deletions src/Makefile.qttest.include
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ TESTS += qt/test/test_dash-qt

TEST_QT_MOC_CPP = \
qt/test/moc_compattests.cpp \
qt/test/moc_uritests.cpp
qt/test/moc_trafficgraphdatatests.cpp \
qt/test/moc_uritests.cpp

if ENABLE_WALLET
TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
Expand All @@ -13,7 +14,8 @@ TEST_QT_H = \
qt/test/compattests.h \
qt/test/uritests.h \
qt/test/paymentrequestdata.h \
qt/test/paymentservertests.h
qt/test/paymentservertests.h \
qt/test/trafficgraphdatatests.h

qt_test_test_dash_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
Expand All @@ -22,6 +24,7 @@ qt_test_test_dash_qt_SOURCES = \
qt/test/compattests.cpp \
qt/test/test_main.cpp \
qt/test/uritests.cpp \
qt/test/trafficgraphdatatests.cpp \
$(TEST_QT_H)
if ENABLE_WALLET
qt_test_test_dash_qt_SOURCES += \
Expand Down
8 changes: 4 additions & 4 deletions src/qt/forms/debugwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -524,16 +524,16 @@
<item>
<widget class="QSlider" name="sldGraphRange">
<property name="minimum">
<number>1</number>
<number>0</number>
</property>
<property name="maximum">
<number>288</number>
<number>9</number>
</property>
<property name="pageStep">
<number>12</number>
<number>1</number>
</property>
<property name="value">
<number>6</number>
<number>3</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
Expand Down
14 changes: 6 additions & 8 deletions src/qt/rpcconsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
const int CONSOLE_HISTORY = 50;
const QSize ICON_SIZE(24, 24);

const int INITIAL_TRAFFIC_GRAPH_MINS = 30;
const TrafficGraphData::GraphRange INITIAL_TRAFFIC_GRAPH_SETTING = TrafficGraphData::Range_30m;

// Repair parameters
const QString SALVAGEWALLET("-salvagewallet");
Expand Down Expand Up @@ -298,7 +298,7 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) :
RPCRegisterTimerInterface(rpcTimerInterface);

startExecutor();
setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS);
setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_SETTING);

ui->peerHeading->setText(tr("Select a peer to view detailed information."));

Expand Down Expand Up @@ -732,9 +732,7 @@ void RPCConsole::scrollToEnd()

void RPCConsole::on_sldGraphRange_valueChanged(int value)
{
const int multiplier = 5; // each position on the slider represents 5 min
int mins = value * multiplier;
setTrafficGraphRange(mins);
setTrafficGraphRange(static_cast<TrafficGraphData::GraphRange>(value));
}

QString RPCConsole::FormatBytes(quint64 bytes)
Expand All @@ -749,10 +747,10 @@ QString RPCConsole::FormatBytes(quint64 bytes)
return QString(tr("%1 GB")).arg(bytes / 1024 / 1024 / 1024);
}

void RPCConsole::setTrafficGraphRange(int mins)
void RPCConsole::setTrafficGraphRange(TrafficGraphData::GraphRange range)
{
ui->trafficGraph->setGraphRangeMins(mins);
ui->lblGraphRange->setText(GUIUtil::formatDurationStr(mins * 60));
ui->trafficGraph->setGraphRangeMins(range);
ui->lblGraphRange->setText(GUIUtil::formatDurationStr(TrafficGraphData::RangeMinutes[range] * 60));
}

void RPCConsole::updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut)
Expand Down
3 changes: 2 additions & 1 deletion src/qt/rpcconsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "guiutil.h"
#include "peertablemodel.h"
#include "trafficgraphdata.h"

#include "net.h"

Expand Down Expand Up @@ -126,7 +127,7 @@ public Q_SLOTS:
private:
static QString FormatBytes(quint64 bytes);
void startExecutor();
void setTrafficGraphRange(int mins);
void setTrafficGraphRange(TrafficGraphData::GraphRange range);
/** Build parameter list for restart */
void buildParameterlist(QString arg);
/** show detailed information on ui about selected node */
Expand Down
5 changes: 5 additions & 0 deletions src/qt/test/test_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "util.h"
#include "uritests.h"
#include "compattests.h"
#include "trafficgraphdatatests.h"

#ifdef ENABLE_WALLET
#include "paymentservertests.h"
Expand Down Expand Up @@ -54,5 +55,9 @@ int main(int argc, char *argv[])
if (QTest::qExec(&test4) != 0)
fInvalid = true;

TrafficGraphDataTests test5;
if (QTest::qExec(&test5) != 0)
fInvalid = true;

return fInvalid;
}
174 changes: 174 additions & 0 deletions src/qt/test/trafficgraphdatatests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#include "trafficgraphdatatests.h"
#include "../trafficgraphdata.h"
#include <algorithm>
#include <sstream>
#include <QTime>

void TrafficGraphDataTests::simpleCurrentSampleQueueTests()
{
TrafficGraphData trafficGraphData(TrafficGraphData::Range_5m);
for (int i = 0; i < TrafficGraphData::DESIRED_DATA_SAMPLES; i++)
QVERIFY(trafficGraphData.update(TrafficSample(i, i)));

TrafficGraphData::SampleQueue queue = trafficGraphData.getCurrentRangeQueue();
QCOMPARE(queue.size(), TrafficGraphData::DESIRED_DATA_SAMPLES);
for (int i = 0; i < TrafficGraphData::DESIRED_DATA_SAMPLES; i++){
QCOMPARE((int)queue.at(i).in, TrafficGraphData::DESIRED_DATA_SAMPLES - i - 1);
QCOMPARE((int)queue.at(i).out, TrafficGraphData::DESIRED_DATA_SAMPLES - i - 1);
}

QVERIFY(trafficGraphData.update(TrafficSample(0, 0)));
queue = trafficGraphData.getCurrentRangeQueue();
QCOMPARE(queue.size(), TrafficGraphData::DESIRED_DATA_SAMPLES);
QCOMPARE((int)queue.at(0).in, 0);
QCOMPARE((int)queue.at(0).out, 0);
}

namespace
{
void checkQueue(const TrafficGraphData::SampleQueue& queue, int value)
{
for (int i = 0; i < queue.size(); i++){
std::ostringstream oss;
oss<< "i:" << i << " value:" << value << " actual:" << queue.at(i).in;
QVERIFY2(value == (int)queue.at(i).in, oss.str().c_str());
QVERIFY2(value == (int)queue.at(i).out, oss.str().c_str());
}
}

void testQueueFill(TrafficGraphData::GraphRange range, int multiplier)
{
int size = 10000;
TrafficGraphData trafficGraphData(range);
for (int i = 1; i <= size; i++){
bool result = trafficGraphData.update(TrafficSample(1, 1));
std::ostringstream oss;
oss<< "result:" << result << " multiplier:" << multiplier << " i:" << i << " range:" << range;
if (i == 1){
if (range == TrafficGraphData::Range_5m)
QVERIFY2(result, oss.str().c_str());
else
QVERIFY2(!result, oss.str().c_str());
}
else if (i % multiplier == 0){
QVERIFY2(result, oss.str().c_str());
}
else {
QVERIFY2(!result, oss.str().c_str());
}
}
TrafficGraphData::SampleQueue queue = trafficGraphData.getCurrentRangeQueue();
QCOMPARE(queue.size(), std::min(size / multiplier, TrafficGraphData::DESIRED_DATA_SAMPLES));
checkQueue(queue, multiplier);
}
}

void TrafficGraphDataTests::accumulationCurrentSampleQueueTests()
{
testQueueFill(TrafficGraphData::Range_10m, 2);
testQueueFill(TrafficGraphData::Range_15m, 3);
testQueueFill(TrafficGraphData::Range_30m, 6);
testQueueFill(TrafficGraphData::Range_1h, 12);
testQueueFill(TrafficGraphData::Range_2h, 24);
testQueueFill(TrafficGraphData::Range_3h, 36);
testQueueFill(TrafficGraphData::Range_6h, 72);
testQueueFill(TrafficGraphData::Range_12h, 144);
testQueueFill(TrafficGraphData::Range_24h, 288);
}

namespace
{
void checkRange(TrafficGraphData& trafficGraphData, int size, TrafficGraphData::GraphRange toRange, int multiplier)
{
TrafficGraphData::SampleQueue queue = trafficGraphData.getRangeQueue(toRange);
QCOMPARE(queue.size(), std::min(size / multiplier, TrafficGraphData::DESIRED_DATA_SAMPLES));
checkQueue(queue,multiplier);
}

void testQueueFillAndCheckRangesForSize(int size)
{
TrafficGraphData trafficGraphData(TrafficGraphData::Range_5m);
for (int i = 1; i <= size; i++){
trafficGraphData.update(TrafficSample(1, 1));
}

checkRange(trafficGraphData, size, TrafficGraphData::Range_10m, 2);
checkRange(trafficGraphData, size, TrafficGraphData::Range_15m, 3);
checkRange(trafficGraphData, size, TrafficGraphData::Range_30m, 6);
checkRange(trafficGraphData, size, TrafficGraphData::Range_1h, 12);
checkRange(trafficGraphData, size, TrafficGraphData::Range_2h, 24);
checkRange(trafficGraphData, size, TrafficGraphData::Range_3h, 36);
checkRange(trafficGraphData, size, TrafficGraphData::Range_6h, 72);
checkRange(trafficGraphData, size, TrafficGraphData::Range_12h, 144);
checkRange(trafficGraphData, size, TrafficGraphData::Range_24h, 288);
}
}

void TrafficGraphDataTests::getRangeTests()
{
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 2);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 3);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 6);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 12);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 24);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 36);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 72);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 144);
testQueueFillAndCheckRangesForSize(TrafficGraphData::DESIRED_DATA_SAMPLES * 288);
}

namespace
{
void compareQueues(const TrafficGraphData::SampleQueue& expected, const TrafficGraphData::SampleQueue& actual)
{
QCOMPARE(expected.size(), actual.size());
for (int i = 0; i < expected.size(); i++){
std::ostringstream oss;
oss<< "i:" << i << " expected:" << expected.at(i).in << " actual:" << actual.at(i).in;
QVERIFY2((int)expected.at(i).in == (int)actual.at(i).in, oss.str().c_str());
QVERIFY2((int)expected.at(i).out == (int)actual.at(i).out, oss.str().c_str());
}
}

void testRangeSwitch(TrafficGraphData::GraphRange baseRange, TrafficGraphData::GraphRange toRange,int size)
{
QTime time = QTime::currentTime();
qsrand((uint)time.msec());
TrafficGraphData trafficGraphDataBase(baseRange);
TrafficGraphData trafficGraphData(toRange);
for (int i = 1; i <= size; i++){
int in = qrand() % 1000;
int out = qrand() % 1000;
trafficGraphData.update(TrafficSample(in, out));
trafficGraphDataBase.update(TrafficSample(in, out));
}
trafficGraphDataBase.switchRange(toRange);
compareQueues(trafficGraphData.getCurrentRangeQueue(),trafficGraphDataBase.getCurrentRangeQueue());
}
}

void TrafficGraphDataTests::switchRangeTests()
{
testRangeSwitch(TrafficGraphData::Range_5m, TrafficGraphData::Range_10m, 10000);
testRangeSwitch(TrafficGraphData::Range_5m, TrafficGraphData::Range_30m, 20000);
testRangeSwitch(TrafficGraphData::Range_5m, TrafficGraphData::Range_15m, 8000 * 2 - 1);
testRangeSwitch(TrafficGraphData::Range_5m, TrafficGraphData::Range_24h, 8000 * 288 - 1);
}



void TrafficGraphDataTests::clearTests()
{
TrafficGraphData trafficGraphData(TrafficGraphData::Range_5m);
for (int i = 1; i <= TrafficGraphData::DESIRED_DATA_SAMPLES; i++){
trafficGraphData.update(TrafficSample(1, 1));
}
QCOMPARE(trafficGraphData.getCurrentRangeQueue().size(),TrafficGraphData::DESIRED_DATA_SAMPLES);
trafficGraphData.clear();
QCOMPARE(trafficGraphData.getCurrentRangeQueue().size(), 0);
for (int i = 1; i <= TrafficGraphData::DESIRED_DATA_SAMPLES; i++){
trafficGraphData.update(TrafficSample(1, 1));
}
QCOMPARE(trafficGraphData.getCurrentRangeQueue().size(), TrafficGraphData::DESIRED_DATA_SAMPLES);
}
20 changes: 20 additions & 0 deletions src/qt/test/trafficgraphdatatests.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef TRAFFICGRAPHDATATESTS_H
#define TRAFFICGRAPHDATATESTS_H

#include <QObject>
#include <QTest>

class TrafficGraphDataTests : public QObject
{
Q_OBJECT

private Q_SLOTS:
void simpleCurrentSampleQueueTests();
void accumulationCurrentSampleQueueTests();
void getRangeTests();
void switchRangeTests();
void clearTests();
};


#endif // TRAFFICGRAPHDATATESTS_H
Loading

0 comments on commit 18c83f5

Please sign in to comment.