140 lines
5.1 KiB
C++
140 lines
5.1 KiB
C++
#include "testenv.h"
|
|
#include "fixtures.h"
|
|
#include "nettest.h"
|
|
|
|
#include "localization.h"
|
|
#include "seasonalpackdownloader.h"
|
|
|
|
#include <QSignalSpy>
|
|
|
|
namespace {
|
|
const QString kPack = QStringLiteral("https://launcher-builds.galeonworx.com/packs/season-5-r3.zip");
|
|
}
|
|
|
|
class TestSeasonalPackDownloader : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
FakeInternet m_net;
|
|
QString m_dir;
|
|
|
|
struct Run
|
|
{
|
|
explicit Run(SeasonalPackDownloader &d)
|
|
: started(&d, &SeasonalPackDownloader::started)
|
|
, finished(&d, &SeasonalPackDownloader::finished)
|
|
, failed(&d, &SeasonalPackDownloader::failed)
|
|
, canceled(&d, &SeasonalPackDownloader::canceled)
|
|
{}
|
|
bool waitEnd()
|
|
{
|
|
return QTest::qWaitFor([&] { return finished.count() + failed.count() + canceled.count() > 0; }, 20000);
|
|
}
|
|
QSignalSpy started, finished, failed, canceled;
|
|
};
|
|
|
|
private slots:
|
|
void initTestCase() { BILAUNCHER_START_FAKE_INTERNET(m_net); }
|
|
|
|
void init()
|
|
{
|
|
m_net.reset();
|
|
m_dir = TestEnv::freshDir(QStringLiteral("packs"));
|
|
}
|
|
|
|
void downloadsAndVerifies()
|
|
{
|
|
const QByteArray data(300 * 1024, 'p');
|
|
m_net.route(kPack, FakeResponse::bytes(data));
|
|
SeasonalPackDownloader downloader;
|
|
Run run(downloader);
|
|
const QString target = m_dir + "/sub/season-5.zip";
|
|
downloader.download(QUrl(kPack), target, Fixtures::sha256(data).toUpper(), data.size(), "Season 5");
|
|
QVERIFY(downloader.isRunning());
|
|
QCOMPARE(downloader.label(), QStringLiteral("Season 5"));
|
|
QCOMPARE(downloader.currentFile(), QStringLiteral("season-5.zip"));
|
|
QCOMPARE(downloader.bytesTotal(), qint64(data.size()));
|
|
QCOMPARE(run.started.count(), 1);
|
|
QVERIFY(run.waitEnd());
|
|
QCOMPARE(run.finished.count(), 1);
|
|
QCOMPARE(run.finished.constFirst().constFirst().toString(), target);
|
|
QCOMPARE(Fixtures::readFile(target), data);
|
|
QVERIFY(!downloader.isRunning());
|
|
QCOMPARE(downloader.fraction(), -1.0);
|
|
}
|
|
|
|
void checksumMismatchLeavesNoFile()
|
|
{
|
|
m_net.route(kPack, FakeResponse::bytes("tampered"));
|
|
SeasonalPackDownloader downloader;
|
|
Run run(downloader);
|
|
const QString target = m_dir + "/season.zip";
|
|
downloader.download(QUrl(kPack), target, QString(64, u'a'), 8, "S");
|
|
QVERIFY(run.waitEnd());
|
|
QCOMPARE(run.failed.count(), 1);
|
|
QCOMPARE(run.failed.constFirst().at(0).toString(), QStringLiteral("S"));
|
|
QCOMPARE(run.failed.constFirst().at(1).toString(), Loc::text("seasonal.error.checksumMismatch"));
|
|
QVERIFY(!QFile::exists(target));
|
|
}
|
|
|
|
void httpErrorAndTruncation()
|
|
{
|
|
SeasonalPackDownloader downloader;
|
|
{
|
|
m_net.route(kPack, FakeResponse::error(404));
|
|
Run run(downloader);
|
|
downloader.download(QUrl(kPack), m_dir + "/a.zip", QString(64, u'a'), 0, "A");
|
|
QVERIFY(run.waitEnd());
|
|
QVERIFY(run.failed.constFirst().at(1).toString().startsWith(
|
|
Loc::text("seasonal.error.downloadFailed").section(u'%', 0, 0)));
|
|
}
|
|
{
|
|
FakeResponse cut = FakeResponse::bytes(QByteArray(4096, 'x'));
|
|
cut.truncateTo = 100;
|
|
m_net.route(kPack, cut);
|
|
Run run(downloader);
|
|
downloader.download(QUrl(kPack), m_dir + "/b.zip", Fixtures::sha256(QByteArray(4096, 'x')), 4096, "B");
|
|
QVERIFY(run.waitEnd());
|
|
QCOMPARE(run.failed.count(), 1);
|
|
QVERIFY(!QFile::exists(m_dir + "/b.zip"));
|
|
}
|
|
}
|
|
|
|
void cancelInFlight()
|
|
{
|
|
FakeResponse hang;
|
|
hang.hang = true;
|
|
m_net.route(kPack, hang);
|
|
SeasonalPackDownloader downloader;
|
|
Run run(downloader);
|
|
downloader.download(QUrl(kPack), m_dir + "/c.zip", QString(64, u'a'), 10, "C");
|
|
QTRY_COMPARE_WITH_TIMEOUT(m_net.hits(kPack), 1, 15000);
|
|
downloader.cancel();
|
|
QVERIFY(run.waitEnd());
|
|
QCOMPARE(run.canceled.count(), 1);
|
|
QCOMPARE(run.canceled.constFirst().constFirst().toString(), QStringLiteral("C"));
|
|
QVERIFY(!QFile::exists(m_dir + "/c.zip"));
|
|
QVERIFY(!downloader.isRunning());
|
|
downloader.cancel(); // повторная отмена без загрузки — ничего не делает
|
|
QCOMPARE(run.canceled.count(), 1);
|
|
}
|
|
|
|
void secondDownloadWhileBusyIsRejected()
|
|
{
|
|
FakeResponse slow = FakeResponse::bytes("x");
|
|
slow.delayMs = 500;
|
|
m_net.route(kPack, slow);
|
|
SeasonalPackDownloader downloader;
|
|
Run run(downloader);
|
|
downloader.download(QUrl(kPack), m_dir + "/d.zip", Fixtures::sha256("x"), 1, "D");
|
|
downloader.download(QUrl(kPack), m_dir + "/e.zip", Fixtures::sha256("x"), 1, "E");
|
|
QCOMPARE(run.failed.count(), 1);
|
|
QCOMPARE(run.failed.constFirst().at(0).toString(), QStringLiteral("E"));
|
|
QCOMPARE(run.failed.constFirst().at(1).toString(), Loc::text("seasonal.error.downloadInProgress"));
|
|
QTRY_COMPARE_WITH_TIMEOUT(run.finished.count(), 1, 15000);
|
|
}
|
|
};
|
|
|
|
BILAUNCHER_TEST_MAIN(TestSeasonalPackDownloader)
|
|
#include "tst_seasonalpackdownloader.moc"
|