Skip to content

Commit

Permalink
Make autotests even more robust against timeouts
Browse files Browse the repository at this point in the history
These now use the information about job back-off strategies to calculate
precisely how long they should wait for a job to complete.
  • Loading branch information
KitsuneRal committed Nov 27, 2024
1 parent 104b05f commit 7bc517e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 25 deletions.
46 changes: 24 additions & 22 deletions autotests/testolmaccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void TestOlmAccount::uploadOneTimeKeys()
QCOMPARE(oneTimeKeyCounts.value(Curve25519Key), 5);
},
[] { QFAIL("upload failed"); });
QVERIFY(waitForFuture(uploadFuture));
QVERIFY(waitForJob(uploadFuture));
}

void TestOlmAccount::uploadSignedOneTimeKeys()
Expand All @@ -233,7 +233,7 @@ void TestOlmAccount::uploadSignedOneTimeKeys()
QCOMPARE(oneTimeKeyCounts.value(SignedCurve25519Key), nKeys);
},
[] { QFAIL("upload failed"); });
QVERIFY(waitForFuture(uploadFuture));
QVERIFY(waitForJob(uploadFuture));
}

void TestOlmAccount::uploadKeys()
Expand All @@ -249,7 +249,7 @@ void TestOlmAccount::uploadKeys()
QCOMPARE(oneTimeKeyCounts.value(SignedCurve25519Key), 1);
},
[] { QFAIL("upload failed"); });
QVERIFY(waitForFuture(request));
QVERIFY(waitForJob(request));
}

void TestOlmAccount::queryTest()
Expand All @@ -265,7 +265,7 @@ void TestOlmAccount::queryTest()
.then([](const QHash<QString, int>& aliceOneTimeKeyCounts) {
QCOMPARE(aliceOneTimeKeyCounts.value(SignedCurve25519Key), 1);
});
QVERIFY(waitForFuture(aliceUploadKeysRequest));
QVERIFY(waitForJob(aliceUploadKeysRequest));

auto bobOlm = bob->olmAccount();
bobOlm->generateOneTimeKeys(1);
Expand All @@ -274,7 +274,7 @@ void TestOlmAccount::queryTest()
.then([](const QHash<QString, int>& bobOneTimeKeyCounts) {
QCOMPARE(bobOneTimeKeyCounts.value(SignedCurve25519Key), 1);
});
QVERIFY(waitForFuture(bobUploadKeysRequest));
QVERIFY(waitForJob(bobUploadKeysRequest));

// Each user is requests each other's keys.
const QHash<QString, QStringList> deviceKeysForBob{ { bob->userId(), {} } };
Expand All @@ -292,7 +292,7 @@ void TestOlmAccount::queryTest()
QCOMPARE(aliceDevKeys.keys, bobOlm->deviceKeys().keys);
QCOMPARE(aliceDevKeys.signatures, bobOlm->deviceKeys().signatures);
});
QVERIFY(waitForFuture(queryBobKeysResult));
QVERIFY(waitForJob(queryBobKeysResult));

const QHash<QString, QStringList> deviceKeysForAlice{ { alice->userId(), {} } };
const auto queryAliceKeysResult =
Expand All @@ -309,7 +309,7 @@ void TestOlmAccount::queryTest()
QCOMPARE(devKeys.keys, aliceOlm->deviceKeys().keys);
QCOMPARE(devKeys.signatures, aliceOlm->deviceKeys().signatures);
});
QVERIFY(waitForFuture(queryAliceKeysResult));
QVERIFY(waitForJob(queryAliceKeysResult));
}

void TestOlmAccount::claimKeys()
Expand All @@ -324,7 +324,7 @@ void TestOlmAccount::claimKeys()
.then([bob](const QHash<QString, int>& oneTimeKeyCounts) {
QCOMPARE(oneTimeKeyCounts.value(SignedCurve25519Key), 1);
});
QVERIFY(waitForFuture(request));
QVERIFY(waitForJob(request));

// Alice retrieves bob's keys & claims one signed one-time key.
const QHash<QString, QStringList> deviceKeysToQuery{ { bob->userId(), {} } };
Expand All @@ -336,7 +336,7 @@ void TestOlmAccount::claimKeys()
QVERIFY(verifyIdentitySignature(bobDevices.value(bob->deviceId()), bob->deviceId(),
bob->userId()));
});
QVERIFY(waitForFuture(queryKeysJob));
QVERIFY(waitForJob(queryKeysJob));

// Retrieve the identity key for the current device to check after claiming
// const auto& bobEd25519 =
Expand All @@ -363,7 +363,7 @@ void TestOlmAccount::claimKeys()
}
},
[] { QFAIL("Claim job failed"); });
QVERIFY(waitForFuture(claimKeysJob));
QVERIFY(waitForJob(claimKeysJob));
}

void TestOlmAccount::claimMultipleKeys()
Expand All @@ -380,7 +380,7 @@ void TestOlmAccount::claimMultipleKeys()
.then([](const QHash<QString, int>& oneTimeKeyCounts) {
QCOMPARE(oneTimeKeyCounts.value(SignedCurve25519Key), 10);
});
QVERIFY(waitForFuture(aliceUploadKeyRequest));
QVERIFY(waitForJob(aliceUploadKeyRequest));

auto olm1 = alice1->olmAccount();
olm1->generateOneTimeKeys(10);
Expand All @@ -389,7 +389,7 @@ void TestOlmAccount::claimMultipleKeys()
.then([](const QHash<QString, int>& oneTimeKeyCounts) {
QCOMPARE(oneTimeKeyCounts.value(SignedCurve25519Key), 10);
});
QVERIFY(waitForFuture(alice1UploadKeyRequest));
QVERIFY(waitForJob(alice1UploadKeyRequest));

auto olm2 = alice2->olmAccount();
olm2->generateOneTimeKeys(10);
Expand All @@ -398,7 +398,7 @@ void TestOlmAccount::claimMultipleKeys()
.then([](const QHash<QString, int>& oneTimeKeyCounts) {
QCOMPARE(oneTimeKeyCounts.value(SignedCurve25519Key), 10);
});
QVERIFY(waitForFuture(alice2UploadKeyRequest));
QVERIFY(waitForJob(alice2UploadKeyRequest));

// Bob will claim keys from all Alice's devices
CREATE_CONNECTION(bob, "bob3"_L1, "secret"_L1, "BobPhone"_L1)
Expand All @@ -412,22 +412,24 @@ void TestOlmAccount::claimMultipleKeys()
bob->callApi<ClaimKeysJob>(oneTimeKeys).then([alice](const ClaimKeysJob::Response& r) {
QCOMPARE(r.oneTimeKeys.value(alice->userId()).size(), 3);
});
QVERIFY(waitForFuture(claimResult));
QVERIFY(waitForJob(claimResult));
}

void TestOlmAccount::enableEncryption()
{
CREATE_CONNECTION(alice, "alice9"_L1, "secret"_L1, "AlicePhone"_L1)

const auto futureRoom = alice->createRoom(Connection::PublishRoom, {}, {}, {}, {})
.then([alice](const QString& roomId) {
auto room = alice->room(roomId);
room->activateEncryption();
return room;
});
QVERIFY(waitForFuture(futureRoom));
auto createRoomJob = alice->createRoom(Connection::PublishRoom, {}, {}, {}, {});
auto futureEncryptedRoom = createRoomJob.then([alice](const QString& roomId) {
auto room = alice->room(roomId);
room->activateEncryption();
return room;
});
QVERIFY(waitForJob(createRoomJob));
alice->syncLoop();
QVERIFY(QTest::qWaitFor([room = futureRoom.result()] { return room->usesEncryption(); }, 40000));
// Give extra 5 seconds for the network roundtrip
QVERIFY(QTest::qWaitFor(std::bind_front(&Room::usesEncryption, futureEncryptedRoom.result()),
SyncJob::defaultTimeoutMillis * 2 + 5000));
}

QTEST_GUILESS_MAIN(TestOlmAccount)
13 changes: 10 additions & 3 deletions autotests/testutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
namespace Quotient {

class Connection;
template <class JobT>
class JobHandle;

std::shared_ptr<Connection> createTestConnection(QLatin1StringView localUserName,
QLatin1StringView secret,
Expand All @@ -22,8 +24,13 @@ std::shared_ptr<Connection> createTestConnection(QLatin1StringView localUserName
if (!VAR) \
QFAIL("Could not set up test connection");

inline bool waitForFuture(const auto& ft)
requires requires { ft.isFinished(); }
template <typename JobT>
inline bool waitForJob(const Quotient::JobHandle<JobT>& job)
{
return QTest::qWaitFor([ft] { return ft.isFinished(); }, 40000);
const auto& [timeouts, retryIntervals, _] = job->currentBackoffStrategy();
return QTest::qWaitFor([job] { return job.isFinished(); },
std::chrono::milliseconds(
std::reduce(timeouts.cbegin(), timeouts.cend())
+ std::reduce(retryIntervals.cbegin(), retryIntervals.cend()))
.count());
}

0 comments on commit 7bc517e

Please sign in to comment.