Skip to content

Commit 16ed527

Browse files
committed
Room/qmc-example: consider fake state event rejection as valid
This is an addition in matrix-org/synapse#5805 - Synapse no more tolerates fake state events (which actually obviates the need for this test but fake state events still go through on older Synapses). To allow checking for both cases Room behaviour has been slightly changed (without compat breakage) to make sure the pending event status is set to ReachedServer (and pendingEventChanged() is emitted, if necessary) before merging the pending event into the timeline.
1 parent c05ade8 commit 16ed527

File tree

2 files changed

+45
-20
lines changed

2 files changed

+45
-20
lines changed

examples/qmc-example.cpp

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -375,42 +375,64 @@ void QMCTest::checkFileSendingOutcome(const QString& txnId,
375375
void QMCTest::setTopic()
376376
{
377377
static const char* const stateTestName = "State setting test";
378-
static const char* const fakeStateTestName =
379-
"Fake state event immunity test";
380378
running.push_back(stateTestName);
381-
running.push_back(fakeStateTestName);
382379
auto initialTopic = targetRoom->topic();
383380

384-
const auto newTopic = c->generateTxnId();
381+
const auto newTopic = c->generateTxnId(); // Just a way to get a unique id
385382
targetRoom->setTopic(newTopic); // Sets the state by proper means
386383
const auto fakeTopic = c->generateTxnId();
387-
targetRoom->postJson(RoomTopicEvent::matrixTypeId(), // Fake state event
388-
RoomTopicEvent(fakeTopic).contentJson());
384+
const auto fakeTxnId =
385+
targetRoom->postJson(RoomTopicEvent::matrixTypeId(), // Fake state event
386+
RoomTopicEvent(fakeTopic).contentJson());
389387

390388
connectUntil(targetRoom, &Room::topicChanged, this,
391389
[this, newTopic, fakeTopic, initialTopic] {
392390
if (targetRoom->topic() == newTopic) {
393391
QMC_CHECK(stateTestName, true);
394-
// Don't reset the topic yet if the negative test still
395-
// runs
396-
if (!running.contains(fakeStateTestName))
397-
targetRoom->setTopic(initialTopic);
398-
399392
return true;
400393
}
401394
return false;
402395
});
403396

404-
connectUntil(targetRoom, &Room::pendingEventAboutToMerge, this,
405-
[this, fakeTopic, initialTopic](const RoomEvent* e, int) {
406-
if (e->contentJson().value("topic").toString() != fakeTopic)
407-
return false; // Wait on for the right event
397+
// Older Synapses allowed sending fake state events through, although
398+
// did not process them; // https://github.com/matrix-org/synapse/pull/5805
399+
// changed that and now Synapse 400's in response to fake state events.
400+
// The following two-step approach handles both cases, assuming that
401+
// Room::pendingEventChanged() with EventStatus::ReachedServer is guaranteed
402+
// to be emitted before Room::pendingEventAboutToMerge.
403+
connectUntil(
404+
targetRoom, &Room::pendingEventChanged, this,
405+
[this, fakeTopic, initialTopic, fakeTxnId](int pendingIdx) {
406+
const auto& pendingEvents = targetRoom->pendingEvents();
407+
Q_ASSERT(pendingIdx >= 0 && pendingIdx < int(pendingEvents.size()));
408+
const auto& evt = pendingEvents[pendingIdx];
409+
if (evt->transactionId() != fakeTxnId)
410+
return false;
408411

409-
QMC_CHECK(fakeStateTestName, !e->isStateEvent());
410-
if (!running.contains(fakeStateTestName))
411-
targetRoom->setTopic(initialTopic);
412-
return true;
413-
});
412+
if (evt.deliveryStatus() == EventStatus::SendingFailed) {
413+
QMC_CHECK("Fake state event immunity test", true);
414+
return true;
415+
}
416+
if (evt.deliveryStatus() != EventStatus::ReachedServer)
417+
return false;
418+
419+
// All before was just a preparation, this is where the test starts.
420+
// (If Synapse rejected the event the library immunity can't be
421+
// tested.)
422+
static const char* const fakeStateTestName =
423+
"Fake state event immunity test";
424+
running.push_back(fakeStateTestName);
425+
connectUntil(
426+
targetRoom, &Room::pendingEventAboutToMerge, this,
427+
[this, fakeTopic, initialTopic](const RoomEvent* e, int) {
428+
if (e->contentJson().value("topic").toString() != fakeTopic)
429+
return false; // Wait on for the right event
430+
431+
QMC_CHECK(fakeStateTestName, !e->isStateEvent());
432+
return true;
433+
});
434+
return true;
435+
});
414436
}
415437

416438
void QMCTest::addAndRemoveTag()

lib/room.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,7 @@ QString Room::retryMessage(const QString& txnId)
15201520
" events are likely to be in the timeline after retry";
15211521
}
15221522
it->resetStatus();
1523+
emit pendingEventChanged(int(it - d->unsyncedEvents.begin()));
15231524
return d->doSendEvent(it->event());
15241525
}
15251526

@@ -2189,6 +2190,8 @@ Room::Changes Room::Private::addNewMessageEvents(RoomEvents&& events)
21892190
auto* nextPendingEvt = nextPending->get();
21902191
const auto pendingEvtIdx =
21912192
int(nextPendingPair.second - unsyncedEvents.begin());
2193+
nextPendingPair.second->setReachedServer(nextPendingEvt->id());
2194+
emit q->pendingEventChanged(pendingEvtIdx);
21922195
emit q->pendingEventAboutToMerge(nextPendingEvt, pendingEvtIdx);
21932196
qDebug(EVENTS) << "Merging pending event from transaction"
21942197
<< nextPendingEvt->transactionId() << "into"

0 commit comments

Comments
 (0)