|
14 | 14 | NotImplementedByController,
|
15 | 15 | )
|
16 | 16 | from irctest.cases import BaseServerTestCase
|
| 17 | +from irctest.client_mock import ClientMock |
17 | 18 | from irctest.exceptions import NoMessageException
|
18 | 19 | from irctest.patma import ANYSTR
|
19 | 20 |
|
@@ -554,6 +555,42 @@ class SableServicesController(BaseServicesController):
|
554 | 555 |
|
555 | 556 | faketime_cmd: Sequence[str]
|
556 | 557 |
|
| 558 | + def wait_for_services(self) -> None: |
| 559 | + """Overrides the default implementation, as it relies on |
| 560 | + ``PRIVMSG NickServ: HELP``, which always succeeds on Sable. |
| 561 | +
|
| 562 | + Instead, this relies on SASL PLAIN availability.""" |
| 563 | + if self.services_up: |
| 564 | + # Don't check again if they are already available |
| 565 | + return |
| 566 | + self.server_controller.wait_for_port() |
| 567 | + |
| 568 | + c = ClientMock(name="chkSASL", show_io=True) |
| 569 | + c.connect(self.server_controller.hostname, self.server_controller.port) |
| 570 | + |
| 571 | + def wait() -> None: |
| 572 | + while True: |
| 573 | + c.sendLine("CAP LS 302") |
| 574 | + for msg in c.getMessages(synchronize=False): |
| 575 | + if msg.command == "CAP": |
| 576 | + assert msg.params[-2] == "LS", msg |
| 577 | + for cap in msg.params[-1].split(): |
| 578 | + if cap.startswith("sasl="): |
| 579 | + mechanisms = cap.split("=", 1)[1].split(",") |
| 580 | + if "PLAIN" in mechanisms: |
| 581 | + return |
| 582 | + else: |
| 583 | + if msg.params[0] == "*": |
| 584 | + # End of CAP LS |
| 585 | + time.sleep(self.server_controller.sync_sleep_time) |
| 586 | + |
| 587 | + wait() |
| 588 | + |
| 589 | + c.sendLine("QUIT") |
| 590 | + c.getMessages() |
| 591 | + c.disconnect() |
| 592 | + self.services_up = True |
| 593 | + |
557 | 594 | def run(self, protocol: str, server_hostname: str, server_port: int) -> None:
|
558 | 595 | assert protocol == "sable"
|
559 | 596 | assert self.server_controller.directory is not None
|
|
0 commit comments