Skip to content

Commit ccd647e

Browse files
committed
sable: Actually check services are up in tests that rely on them
This should fix some flakiness.
1 parent 9de6415 commit ccd647e

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

irctest/controllers/sable.py

+48
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
NotImplementedByController,
1515
)
1616
from irctest.cases import BaseServerTestCase
17+
from irctest.client_mock import ClientMock
1718
from irctest.exceptions import NoMessageException
1819
from irctest.patma import ANYSTR
1920

@@ -496,6 +497,53 @@ def kill_proc(self) -> None:
496497
os.killpg(self.pgroup_id, signal.SIGKILL)
497498
super().kill_proc()
498499

500+
def wait_for_services(self) -> None:
501+
# by default, wait_for_services() connects a user that sends a HELP command
502+
# to NickServ and assumes services are up when it receives a non-ERR_NOSUCHNICK
503+
# reply.
504+
# However, with Sable, NickServ is always up, even when services are not linked,
505+
# so we need to check a different way. We check presence of a non-EXTERNAL
506+
# value to the sasl capability, but LINKS would
507+
if self.services_up:
508+
# Don't check again if they are already available
509+
return
510+
self.server_controller.wait_for_port()
511+
512+
c = ClientMock(name="chkSvs", show_io=True)
513+
c.connect(self.server_controller.hostname, self.server_controller.port)
514+
c.sendLine("NICK chkSvs")
515+
c.sendLine("USER chk chk chk chk")
516+
time.sleep(self.server_controller.sync_sleep_time)
517+
got_end_of_motd = False
518+
while not got_end_of_motd:
519+
for msg in c.getMessages(synchronize=False):
520+
if msg.command == "PING":
521+
# Hi Unreal
522+
c.sendLine("PONG :" + msg.params[0])
523+
if msg.command in ("376", "422"): # RPL_ENDOFMOTD / ERR_NOMOTD
524+
got_end_of_motd = True
525+
526+
timeout = time.time() + 10
527+
while not self.services_up:
528+
if time.time() > timeout:
529+
raise Exception("Timeout while waiting for services")
530+
c.sendLine("CAP LS 302")
531+
532+
msgs = self.getNickServResponse(c, timeout=1)
533+
for msg in msgs:
534+
if msg.command == "CAP":
535+
pass
536+
for token in msg.params[-1].split():
537+
if token.startswith("sasl="):
538+
if "PLAIN" in token.removeprefix("sasl=").split(","):
539+
# SASL PLAIN is available, so services are linked.
540+
self.services_up = True
541+
break
542+
543+
c.sendLine("QUIT")
544+
c.getMessages()
545+
c.disconnect()
546+
499547

500548
def get_irctest_controller_class() -> Type[SableController]:
501549
return SableController

mypy.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[mypy]
2-
python_version = 3.8
2+
python_version = 3.9
33
warn_return_any = True
44
warn_unused_configs = True
55

0 commit comments

Comments
 (0)