Skip to content

Commit

Permalink
test_imap_pop3_compat: Improve synchronization in flaky test.
Browse files Browse the repository at this point in the history
Occasionally, test_imap_pop3_compat fails to run successfully
due to a race condition where the POP3 login will process
before the IMAP TESTLOCK command begins, resulting in the
opposite of the expected scenario (POP3 gaining an exclusive
lock and preventing IMAP access, rather than IMAP gaining a
a non-exclusive lock and preventing POP3's exclusive access).

This adds an untagged reply to the TESTLOCK command in net_imap
that the test suite can use to synchronize, to ensure the POP3
PASS command is not sent prior to the IMAP client acquiring
the mailbox lock.
  • Loading branch information
InterLinked1 committed Feb 29, 2024
1 parent 5517fc2 commit 663446a
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 2 deletions.
3 changes: 2 additions & 1 deletion nets/net_imap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ static void low_quota_alert(struct imap_session *imap)
{
unsigned long quotaleft = mailbox_quota_remaining(imap->mbox);
if (quotaleft < LOW_MAILBOX_SPACE_THRESHOLD) { /* Very little quota remaining */
imap_send(imap, "OK [ALERT] Mailbox is almost full (%lu KB quota remaining)\n", quotaleft / 1024);
imap_send(imap, "OK [ALERT] Mailbox is almost full (%lu KB quota remaining)", quotaleft / 1024);
}
}

Expand Down Expand Up @@ -4578,6 +4578,7 @@ static int imap_process(struct imap_session *imap, char *s)
/* Hold the mailbox lock for a moment. */
/*! \note This is only used for the test suite, it is not part of any IMAP standard or intended for clients. */
MAILBOX_TRYRDLOCK(imap);
imap_send(imap, "TESTLOCK in progress");
usleep(4000000); /* 500ms is sufficient normally, but under valgrind, we need more time. Even 2500ms is not enough. */
mailbox_unlock(imap->mbox);
imap_reply(imap, "OK Lock test succeeded");
Expand Down
2 changes: 1 addition & 1 deletion tests/test_imap_pop3_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ static int run(void)

/* Interleave these writes at the same time to ensure the lock is held when the POP server tries to authenticate */
SWRITE(client1, "a2 TESTLOCK" ENDL); /* When the INBOX is selected, that should temporarily grab the lock */
CLIENT_EXPECT(client1, "TESTLOCK in progress"); /* Wait for TESTLOCK command to start processing, so we know the lock's held */

SWRITE(client2, "PASS " TEST_PASS ENDL);

CLIENT_EXPECT(client2, "-ERR [IN-USE]"); /* Mailbox is busy */
close_if(client2); /* POP server will disconnect at this point. We'll need to reconnect. */

Expand Down

0 comments on commit 663446a

Please sign in to comment.