mirror of https://github.com/qTox/qTox.git
Browse Source
* Refactor/test ToxFileProgress to ensure that when it's moved it behaves well * Notice problems with speed averaging. We were average speeds without keeping track of the times they were over. Adding samples of different lengths would result in incorrect speeds. Refactor whole class to correct * Move ToxFileProgress to be a member of ToxFile * Remove duplicated members between ToxFile and ToxFileProgress * Move sample addition into CoreFilereviewable/pr6386/r9
14 changed files with 552 additions and 164 deletions
@ -1,93 +0,0 @@ |
|||||||
/*
|
|
||||||
Copyright © 2018-2019 by The qTox Project Contributors |
|
||||||
|
|
||||||
This file is part of qTox, a Qt-based graphical interface for Tox. |
|
||||||
|
|
||||||
qTox is libre software: you can redistribute it and/or modify |
|
||||||
it under the terms of the GNU General Public License as published by |
|
||||||
the Free Software Foundation, either version 3 of the License, or |
|
||||||
(at your option) any later version. |
|
||||||
|
|
||||||
qTox 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 General Public License for more details. |
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License |
|
||||||
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/ |
|
||||||
|
|
||||||
#include "toxfileprogress.h" |
|
||||||
|
|
||||||
#include "src/core/toxfile.h" |
|
||||||
|
|
||||||
bool ToxFileProgress::needsUpdate() const |
|
||||||
{ |
|
||||||
QTime now = QTime::currentTime(); |
|
||||||
qint64 dt = lastTick.msecsTo(now); // ms
|
|
||||||
|
|
||||||
if (dt < 1000) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void ToxFileProgress::addSample(ToxFile const& file) |
|
||||||
{ |
|
||||||
QTime now = QTime::currentTime(); |
|
||||||
qint64 dt = lastTick.msecsTo(now); // ms
|
|
||||||
|
|
||||||
if (dt < 1000) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
// ETA, speed
|
|
||||||
qreal deltaSecs = dt / 1000.0; |
|
||||||
|
|
||||||
// (can't use ::abs or ::max on unsigned types substraction, they'd just overflow)
|
|
||||||
quint64 deltaBytes = file.bytesSent > lastBytesSent ? file.bytesSent - lastBytesSent |
|
||||||
: lastBytesSent - file.bytesSent; |
|
||||||
qreal bytesPerSec = static_cast<int>(static_cast<qreal>(deltaBytes) / deltaSecs); |
|
||||||
|
|
||||||
// Update member variables
|
|
||||||
meanIndex = meanIndex % TRANSFER_ROLLING_AVG_COUNT; |
|
||||||
meanData[meanIndex++] = bytesPerSec; |
|
||||||
|
|
||||||
double meanBytesPerSec = 0.0; |
|
||||||
for (size_t i = 0; i < TRANSFER_ROLLING_AVG_COUNT; ++i) { |
|
||||||
meanBytesPerSec += meanData[i]; |
|
||||||
} |
|
||||||
meanBytesPerSec /= static_cast<qreal>(TRANSFER_ROLLING_AVG_COUNT); |
|
||||||
|
|
||||||
lastTick = now; |
|
||||||
|
|
||||||
progress = static_cast<double>(file.bytesSent) / static_cast<double>(file.filesize); |
|
||||||
speedBytesPerSecond = meanBytesPerSec; |
|
||||||
timeLeftSeconds = (file.filesize - file.bytesSent) / getSpeed(); |
|
||||||
|
|
||||||
lastBytesSent = file.bytesSent; |
|
||||||
} |
|
||||||
|
|
||||||
void ToxFileProgress::resetSpeed() |
|
||||||
{ |
|
||||||
meanIndex = 0; |
|
||||||
for (auto& item : meanData) { |
|
||||||
item = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
double ToxFileProgress::getProgress() const |
|
||||||
{ |
|
||||||
return progress; |
|
||||||
} |
|
||||||
|
|
||||||
double ToxFileProgress::getSpeed() const |
|
||||||
{ |
|
||||||
return speedBytesPerSecond; |
|
||||||
} |
|
||||||
|
|
||||||
double ToxFileProgress::getTimeLeftSeconds() const |
|
||||||
{ |
|
||||||
return timeLeftSeconds; |
|
||||||
} |
|
||||||
@ -0,0 +1,137 @@ |
|||||||
|
/*
|
||||||
|
Copyright © 2021 by The qTox Project Contributors |
||||||
|
|
||||||
|
This file is part of qTox, a Qt-based graphical interface for Tox. |
||||||
|
|
||||||
|
qTox is libre software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
qTox 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 General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#include "toxfileprogress.h" |
||||||
|
|
||||||
|
#include <limits> |
||||||
|
|
||||||
|
ToxFileProgress::ToxFileProgress(uint64_t filesize, int samplePeriodMs) |
||||||
|
: filesize(filesize) |
||||||
|
, samplePeriodMs(samplePeriodMs) |
||||||
|
{ |
||||||
|
if (samplePeriodMs < 0) { |
||||||
|
qWarning("Invalid sample rate, healing to 1000ms"); |
||||||
|
this->samplePeriodMs = 1000; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QTime ToxFileProgress::lastSampleTime() const |
||||||
|
{ |
||||||
|
return samples[activeSample].timestamp; |
||||||
|
} |
||||||
|
|
||||||
|
bool ToxFileProgress::addSample(uint64_t bytesSent, QTime now) |
||||||
|
{ |
||||||
|
if (bytesSent > filesize) { |
||||||
|
qWarning("Bytes sent exceeds file size, ignoring sample"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
auto* active = &samples[activeSample]; |
||||||
|
auto* inactive = &samples[!activeSample]; |
||||||
|
|
||||||
|
if (bytesSent < active->bytesSent || bytesSent < inactive->bytesSent) { |
||||||
|
qWarning("Bytes sent has decreased since last sample, ignoring sample"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (now < active->timestamp || now < inactive->timestamp) { |
||||||
|
qWarning("Sample time has gone backwards, clearing progress buffer"); |
||||||
|
resetSpeed(); |
||||||
|
} |
||||||
|
|
||||||
|
// Ensure both samples are initialized
|
||||||
|
if (inactive->timestamp == QTime()) { |
||||||
|
inactive->bytesSent = bytesSent; |
||||||
|
inactive->timestamp = now; |
||||||
|
} |
||||||
|
|
||||||
|
if (active->timestamp == QTime()) { |
||||||
|
active->bytesSent = bytesSent; |
||||||
|
active->timestamp = now; |
||||||
|
} |
||||||
|
|
||||||
|
if (active->timestamp.msecsTo(now) >= samplePeriodMs) { |
||||||
|
// Swap samples and set the newly active sample
|
||||||
|
activeSample = !activeSample; |
||||||
|
std::swap(active, inactive); |
||||||
|
} |
||||||
|
|
||||||
|
active->bytesSent = bytesSent; |
||||||
|
active->timestamp = now; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void ToxFileProgress::resetSpeed() |
||||||
|
{ |
||||||
|
for (auto& sample : samples) { |
||||||
|
sample.timestamp = QTime(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
uint64_t ToxFileProgress::getBytesSent() const |
||||||
|
{ |
||||||
|
return samples[activeSample].bytesSent; |
||||||
|
} |
||||||
|
|
||||||
|
double ToxFileProgress::getProgress() const |
||||||
|
{ |
||||||
|
return double(samples[activeSample].bytesSent) / filesize; |
||||||
|
} |
||||||
|
|
||||||
|
double ToxFileProgress::getSpeed() const |
||||||
|
{ |
||||||
|
if (samples.size() > 0 |
||||||
|
&& samples[activeSample].bytesSent == filesize) { |
||||||
|
return 0.0f; |
||||||
|
} |
||||||
|
|
||||||
|
const auto sampleTimeInvalid = [](const Sample& sample) { |
||||||
|
return sample.timestamp == QTime(); |
||||||
|
}; |
||||||
|
|
||||||
|
if (std::any_of(samples.cbegin(), samples.cend(), sampleTimeInvalid)) { |
||||||
|
return 0.0f; |
||||||
|
} |
||||||
|
|
||||||
|
if (samples[0].timestamp == samples[1].timestamp) { |
||||||
|
return 0.0f; |
||||||
|
} |
||||||
|
|
||||||
|
const auto& active = samples[activeSample]; |
||||||
|
const auto& inactive = samples[!activeSample]; |
||||||
|
|
||||||
|
return (active.bytesSent - inactive.bytesSent) / double(inactive.timestamp.msecsTo(active.timestamp)) * 1000.0; |
||||||
|
} |
||||||
|
|
||||||
|
double ToxFileProgress::getTimeLeftSeconds() const |
||||||
|
{ |
||||||
|
if (samples.size() > 0 |
||||||
|
&& samples[activeSample].bytesSent == filesize) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
const auto speed = getSpeed(); |
||||||
|
if (speed == 0.0f) { |
||||||
|
return std::numeric_limits<float>::infinity(); |
||||||
|
} |
||||||
|
|
||||||
|
return double(filesize - samples[activeSample].bytesSent) / getSpeed(); |
||||||
|
} |
||||||
@ -0,0 +1,341 @@ |
|||||||
|
/*
|
||||||
|
Copyright © 2021 by The qTox Project Contributors |
||||||
|
|
||||||
|
This file is part of qTox, a Qt-based graphical interface for Tox. |
||||||
|
|
||||||
|
qTox is libre software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
qTox 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 General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#include "src/core/toxfileprogress.h" |
||||||
|
|
||||||
|
#include <QTest> |
||||||
|
#include <limits> |
||||||
|
|
||||||
|
class TestFileProgress : public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
private slots: |
||||||
|
void testSpeed(); |
||||||
|
void testSpeedReset(); |
||||||
|
void testDiscardedSample(); |
||||||
|
void testProgress(); |
||||||
|
void testRemainingTime(); |
||||||
|
void testBytesSentPersistence(); |
||||||
|
void testFileSizePersistence(); |
||||||
|
void testNoSamples(); |
||||||
|
void testSpeedUnevenIntervals(); |
||||||
|
void testDefaultTimeLessThanNow(); |
||||||
|
void testTimeChange(); |
||||||
|
void testFinishedSpeed(); |
||||||
|
void testSamplePeriod(); |
||||||
|
void testInvalidSamplePeriod(); |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that our speeds are sane while we're on our first few samples |
||||||
|
*/ |
||||||
|
void TestFileProgress::testSpeed() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 1000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(0, nextSampleTime)); |
||||||
|
// 1 sample has no speed
|
||||||
|
QCOMPARE(progress.getSpeed(), 0.0); |
||||||
|
|
||||||
|
// Swap buffers. Time should be valid
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(500); |
||||||
|
// 10 bytes over 0.5s
|
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getSpeed(), 20.0); |
||||||
|
|
||||||
|
// This should evict the first sample, so our time should be relative to the
|
||||||
|
// first 10 bytes
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(20, nextSampleTime)); |
||||||
|
// 10 bytes over 1s
|
||||||
|
QCOMPARE(progress.getSpeed(), 10.0); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that resetting our speed puts us back into a sane default state |
||||||
|
*/ |
||||||
|
void TestFileProgress::testSpeedReset() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 1000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(0, nextSampleTime)); |
||||||
|
|
||||||
|
// Push enough samples that all samples are initialized
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(20, nextSampleTime)); |
||||||
|
|
||||||
|
QCOMPARE(progress.getSpeed(), 10.0); |
||||||
|
|
||||||
|
progress.resetSpeed(); |
||||||
|
QCOMPARE(progress.getSpeed(), 0.0); |
||||||
|
QCOMPARE(progress.lastSampleTime(), QTime()); |
||||||
|
QCOMPARE(progress.getBytesSent(), uint64_t(20)); |
||||||
|
QCOMPARE(progress.getProgress(), 0.2); |
||||||
|
|
||||||
|
// Ensure that pushing new samples after reset works correectly
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(30, nextSampleTime)); |
||||||
|
|
||||||
|
// 1 sample has no speed
|
||||||
|
QCOMPARE(progress.getSpeed(), 0.0); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(40, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getSpeed(), 10.0); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that invalid samples are discarded |
||||||
|
*/ |
||||||
|
void TestFileProgress::testDiscardedSample() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 1000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(0, nextSampleTime)); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(20, nextSampleTime)); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
|
||||||
|
// Sample should be discarded because it's too large
|
||||||
|
QVERIFY(!progress.addSample(300, nextSampleTime)); |
||||||
|
QCOMPARE(progress.lastSampleTime(), QTime(1, 0, 1)); |
||||||
|
|
||||||
|
// Sample should be discarded because we're going backwards
|
||||||
|
QVERIFY(!progress.addSample(10, nextSampleTime)); |
||||||
|
QCOMPARE(progress.lastSampleTime(), QTime(1, 0, 1)); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that progress is reported correctly |
||||||
|
*/ |
||||||
|
void TestFileProgress::testProgress() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 4000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(0, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getProgress(), 0.0); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getProgress(), 0.1); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(100, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getProgress(), 1.0); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that remaining time is predicted reasonably |
||||||
|
*/ |
||||||
|
void TestFileProgress::testRemainingTime() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 2000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(0, nextSampleTime)); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
|
||||||
|
// 10% over 1s, 90% should take 9 more seconds
|
||||||
|
QCOMPARE(progress.getTimeLeftSeconds(), 9.0); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(10000); |
||||||
|
QVERIFY(progress.addSample(100, nextSampleTime)); |
||||||
|
// Even with a slow final sample, we should have 0 seconds remaining when we
|
||||||
|
// are complete
|
||||||
|
QCOMPARE(progress.getTimeLeftSeconds(), 0.0); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that the sent bytes keeps the last sample |
||||||
|
*/ |
||||||
|
void TestFileProgress::testBytesSentPersistence() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 1000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
|
||||||
|
// First sample
|
||||||
|
QCOMPARE(progress.getBytesSent(), uint64_t(10)); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(20, nextSampleTime)); |
||||||
|
// Second sample
|
||||||
|
QCOMPARE(progress.getBytesSent(), uint64_t(20)); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(30, nextSampleTime)); |
||||||
|
// After rollover
|
||||||
|
QCOMPARE(progress.getBytesSent(), uint64_t(30)); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check that the reported file size matches what was given |
||||||
|
*/ |
||||||
|
void TestFileProgress::testFileSizePersistence() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(33, 1000); |
||||||
|
QCOMPARE(progress.getFileSize(), uint64_t(33)); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that we have sane stats when no samples have been added |
||||||
|
*/ |
||||||
|
void TestFileProgress::testNoSamples() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 1000); |
||||||
|
QCOMPARE(progress.getSpeed(), 0.0); |
||||||
|
QVERIFY(progress.getTimeLeftSeconds() == std::numeric_limits<double>::infinity()); |
||||||
|
QCOMPARE(progress.getProgress(), 0.0); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that statistics are being average over the entire range of time |
||||||
|
* no matter the sample frequency |
||||||
|
*/ |
||||||
|
void TestFileProgress::testSpeedUnevenIntervals() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 4000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(20, nextSampleTime)); |
||||||
|
nextSampleTime = nextSampleTime.addMSecs(3000); |
||||||
|
QVERIFY(progress.addSample(50, nextSampleTime)); |
||||||
|
|
||||||
|
// 10->50 over 4 seconds
|
||||||
|
QCOMPARE(progress.getSpeed(), 10.0); |
||||||
|
} |
||||||
|
|
||||||
|
void TestFileProgress::testDefaultTimeLessThanNow() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 1000); |
||||||
|
QVERIFY(progress.lastSampleTime() < QTime::currentTime()); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that changing the time resets the speed count. Note that it would |
||||||
|
* be better to use the monotonic clock, but it's not trivial to get the |
||||||
|
* monotonic clock from Qt's time API |
||||||
|
*/ |
||||||
|
void TestFileProgress::testTimeChange() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 1000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
|
||||||
|
nextSampleTime = QTime(0, 0, 0); |
||||||
|
QVERIFY(progress.addSample(20, nextSampleTime)); |
||||||
|
|
||||||
|
QCOMPARE(progress.getSpeed(), 0.0); |
||||||
|
QCOMPARE(progress.getProgress(), 0.2); |
||||||
|
|
||||||
|
nextSampleTime = QTime(0, 0, 1); |
||||||
|
QVERIFY(progress.addSample(30, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getSpeed(), 10.0); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that when a file is complete it's speed is set to 0 |
||||||
|
*/ |
||||||
|
|
||||||
|
void TestFileProgress::testFinishedSpeed() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, 1000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
|
||||||
|
nextSampleTime = nextSampleTime.addMSecs(1000); |
||||||
|
QVERIFY(progress.addSample(100, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getSpeed(), 0.0); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test that we are averaged over the past period * samples time, and |
||||||
|
* when we roll we lose one sample period of data |
||||||
|
*/ |
||||||
|
void TestFileProgress::testSamplePeriod() |
||||||
|
{ |
||||||
|
// No matter the number of samples, we should always be averaging over 2s
|
||||||
|
auto progress = ToxFileProgress(100, 2000); |
||||||
|
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(0, nextSampleTime)); |
||||||
|
|
||||||
|
nextSampleTime = QTime(1, 0, 0, 500); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
|
||||||
|
// Even with less than a sample period our speed and size should be updated
|
||||||
|
QCOMPARE(progress.getSpeed(), 20.0); |
||||||
|
QCOMPARE(progress.getBytesSent(), uint64_t(10)); |
||||||
|
|
||||||
|
// Add a new sample at 1s, this should replace the previous sample
|
||||||
|
nextSampleTime = QTime(1, 0, 1); |
||||||
|
QVERIFY(progress.addSample(30, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getSpeed(), 30.0); |
||||||
|
QCOMPARE(progress.getBytesSent(), uint64_t(30)); |
||||||
|
|
||||||
|
// Add a new sample at 2s, our time should still be relative to 0
|
||||||
|
nextSampleTime = QTime(1, 0, 2); |
||||||
|
QVERIFY(progress.addSample(50, nextSampleTime)); |
||||||
|
// 50 - 0 over 2s
|
||||||
|
QCOMPARE(progress.getSpeed(), 25.0); |
||||||
|
QCOMPARE(progress.getBytesSent(), uint64_t(50)); |
||||||
|
} |
||||||
|
|
||||||
|
void TestFileProgress::testInvalidSamplePeriod() |
||||||
|
{ |
||||||
|
auto progress = ToxFileProgress(100, -1); |
||||||
|
|
||||||
|
// Sample period should be healed to 1000
|
||||||
|
auto nextSampleTime = QTime(1, 0, 0); |
||||||
|
QVERIFY(progress.addSample(0, nextSampleTime)); |
||||||
|
|
||||||
|
nextSampleTime = QTime(1, 0, 0, 500); |
||||||
|
QVERIFY(progress.addSample(10, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getSpeed(), 20.0); |
||||||
|
|
||||||
|
// Second sample should be removed and we should average over the full
|
||||||
|
// second
|
||||||
|
nextSampleTime = QTime(1, 0, 1); |
||||||
|
QVERIFY(progress.addSample(30, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getSpeed(), 30.0); |
||||||
|
|
||||||
|
// First sample should be evicted and we should have an updated speed
|
||||||
|
nextSampleTime = QTime(1, 0, 2); |
||||||
|
QVERIFY(progress.addSample(90, nextSampleTime)); |
||||||
|
QCOMPARE(progress.getSpeed(), 60.0); |
||||||
|
} |
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(TestFileProgress) |
||||||
|
#include "fileprogress_test.moc" |
||||||
Loading…
Reference in new issue