|
28 | 28 | make_deferred_yieldable,
|
29 | 29 | )
|
30 | 30 | from synapse.util.async_helpers import (
|
| 31 | + AwakenableSleeper, |
31 | 32 | ObservableDeferred,
|
32 | 33 | concurrently_execute,
|
33 | 34 | delay_cancellation,
|
34 | 35 | stop_cancellation,
|
35 | 36 | timeout_deferred,
|
36 | 37 | )
|
37 | 38 |
|
| 39 | +from tests.server import get_clock |
38 | 40 | from tests.unittest import TestCase
|
39 | 41 |
|
40 | 42 |
|
@@ -496,3 +498,81 @@ async def outer():
|
496 | 498 | # logging context.
|
497 | 499 | blocking_d.callback(None)
|
498 | 500 | self.successResultOf(d)
|
| 501 | + |
| 502 | + |
| 503 | +class AwakenableSleeperTests(TestCase): |
| 504 | + "Tests AwakenableSleeper" |
| 505 | + |
| 506 | + def test_sleep(self): |
| 507 | + reactor, _ = get_clock() |
| 508 | + sleeper = AwakenableSleeper(reactor) |
| 509 | + |
| 510 | + d = defer.ensureDeferred(sleeper.sleep("name", 1000)) |
| 511 | + |
| 512 | + reactor.pump([0.0]) |
| 513 | + self.assertFalse(d.called) |
| 514 | + |
| 515 | + reactor.advance(0.5) |
| 516 | + self.assertFalse(d.called) |
| 517 | + |
| 518 | + reactor.advance(0.6) |
| 519 | + self.assertTrue(d.called) |
| 520 | + |
| 521 | + def test_explicit_wake(self): |
| 522 | + reactor, _ = get_clock() |
| 523 | + sleeper = AwakenableSleeper(reactor) |
| 524 | + |
| 525 | + d = defer.ensureDeferred(sleeper.sleep("name", 1000)) |
| 526 | + |
| 527 | + reactor.pump([0.0]) |
| 528 | + self.assertFalse(d.called) |
| 529 | + |
| 530 | + reactor.advance(0.5) |
| 531 | + self.assertFalse(d.called) |
| 532 | + |
| 533 | + sleeper.wake("name") |
| 534 | + self.assertTrue(d.called) |
| 535 | + |
| 536 | + reactor.advance(0.6) |
| 537 | + |
| 538 | + def test_multiple_sleepers_timeout(self): |
| 539 | + reactor, _ = get_clock() |
| 540 | + sleeper = AwakenableSleeper(reactor) |
| 541 | + |
| 542 | + d1 = defer.ensureDeferred(sleeper.sleep("name", 1000)) |
| 543 | + |
| 544 | + reactor.advance(0.6) |
| 545 | + self.assertFalse(d1.called) |
| 546 | + |
| 547 | + # Add another sleeper |
| 548 | + d2 = defer.ensureDeferred(sleeper.sleep("name", 1000)) |
| 549 | + |
| 550 | + # Only the first sleep should time out now. |
| 551 | + reactor.advance(0.6) |
| 552 | + self.assertTrue(d1.called) |
| 553 | + self.assertFalse(d2.called) |
| 554 | + |
| 555 | + reactor.advance(0.6) |
| 556 | + self.assertTrue(d2.called) |
| 557 | + |
| 558 | + def test_multiple_sleepers_wake(self): |
| 559 | + reactor, _ = get_clock() |
| 560 | + sleeper = AwakenableSleeper(reactor) |
| 561 | + |
| 562 | + d1 = defer.ensureDeferred(sleeper.sleep("name", 1000)) |
| 563 | + |
| 564 | + reactor.advance(0.5) |
| 565 | + self.assertFalse(d1.called) |
| 566 | + |
| 567 | + # Add another sleeper |
| 568 | + d2 = defer.ensureDeferred(sleeper.sleep("name", 1000)) |
| 569 | + |
| 570 | + # Neither should fire yet |
| 571 | + reactor.advance(0.3) |
| 572 | + self.assertFalse(d1.called) |
| 573 | + self.assertFalse(d2.called) |
| 574 | + |
| 575 | + # Explicitly waking both up works |
| 576 | + sleeper.wake("name") |
| 577 | + self.assertTrue(d1.called) |
| 578 | + self.assertTrue(d2.called) |
0 commit comments