mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
342 lines
10 KiB
C++
342 lines
10 KiB
C++
|
/*
|
||
|
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"
|