-
Notifications
You must be signed in to change notification settings - Fork 560
Update HomeserverTestCase.get_success(...) and friends to drive async Rust (Tokio runtime/thread pool)
#19871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 12 commits
520a4bc
65a1c59
fdeed9a
5ca9050
6e9b2a2
c45774c
ae7e367
f54d0c0
997a160
b501ad1
9cfd0f9
66a515b
a1092da
09c91d3
4357aa4
edce488
5cc4590
5b27102
44253df
47297af
cc2c27b
26dc512
2bce6e7
3425d15
ecce873
2c51142
999d22d
41642be
350b15f
60ddfc6
167ad62
ad0bbb6
f0e968a
85edec1
919a94c
2c8ea3a
2300a19
a1170c6
efcd574
749ea8b
77ddfcf
92346f2
ce1758c
0add7cd
a871de0
74060df
28586c6
cb91056
a975f83
34f015f
e7b09b3
f11be8b
453a296
2bff819
a12a9e0
d034373
77184c8
5be3534
77ce7a5
bc54b65
3cb3c66
c37b6ce
6e86cf3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Update `HomeserverTestCase.get_success(...)` and friends to drive async Rust (Tokio runtime/thread pool). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -357,7 +357,6 @@ def create_invite() -> EventBase: | |
| event.room_version, | ||
| ), | ||
| exc=LimitExceededError, | ||
| by=0.5, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In a lot of cases, the |
||
| ) | ||
|
|
||
| def _build_and_send_join_event( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,7 @@ | |
| get_verify_key, | ||
| ) | ||
|
|
||
| from twisted.internet.defer import ensureDeferred | ||
| from twisted.internet.testing import MemoryReactor | ||
|
|
||
| from synapse.api.constants import EventTypes, Membership, PresenceState | ||
|
|
@@ -58,6 +59,7 @@ | |
| from synapse.storage.keys import FetchKeyResult | ||
| from synapse.types import JsonDict, UserID, get_domain_from_id | ||
| from synapse.util.clock import Clock | ||
| from synapse.util.duration import Duration | ||
|
|
||
| from tests import unittest | ||
| from tests.replication._base import BaseMultiWorkerStreamTestCase | ||
|
|
@@ -948,12 +950,17 @@ def test_external_process_timeout(self) -> None: | |
| ) | ||
| worker_presence_handler = worker_to_sync_against.get_presence_handler() | ||
|
|
||
| self.get_success( | ||
| sync_d = ensureDeferred( | ||
| worker_presence_handler.user_syncing( | ||
| self.user_id, self.device_id, True, PresenceState.ONLINE | ||
| ), | ||
| by=0.1, | ||
| ) | ||
| ) | ||
| # `user_syncing` proxies the presence write to the main process over an HTTP | ||
| # replication request. The request body is streamed by a `Cooperator` that uses | ||
| # the clock to schedule each chunk at a tiny *non-zero* delay (`_EPSILON`), so | ||
| # we need to actually advance the clock for it to fire. | ||
| self.reactor.advance(Duration(microseconds=1).as_secs()) | ||
|
erikjohnston marked this conversation as resolved.
Outdated
|
||
| self.get_success(sync_d) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the main pattern I'm recommending if you need to advance time by an non-zero increment.
The difference between |
||
|
|
||
| # Check that if we wait a while without telling the handler the user has | ||
| # stopped syncing that their presence state doesn't get timed out. | ||
|
|
@@ -1264,30 +1271,40 @@ def test_set_presence_from_syncing_multi_device( | |
| worker_presence_handler = worker_to_sync_against.get_presence_handler() | ||
|
|
||
| # 1. Sync with the first device. | ||
| self.get_success( | ||
| sync_d = ensureDeferred( | ||
| worker_presence_handler.user_syncing( | ||
| user_id, | ||
| "dev-1", | ||
| affect_presence=dev_1_state != PresenceState.OFFLINE, | ||
| presence_state=dev_1_state, | ||
| ), | ||
| by=0.01, | ||
| ) | ||
| ) | ||
| # `user_syncing` proxies the presence write to the main process over an HTTP | ||
| # replication request. The request body is streamed by a `Cooperator` that uses | ||
| # the clock to schedule each chunk at a tiny *non-zero* delay (`_EPSILON`), so | ||
| # we need to actually advance the clock for it to fire. | ||
| self.reactor.advance(Duration(microseconds=1).as_secs()) | ||
| self.get_success(sync_d) | ||
|
|
||
| # 2. Wait half the idle timer. | ||
| self.reactor.advance(IDLE_TIMER / 1000 / 2) | ||
| self.reactor.pump([0.1]) | ||
|
|
||
| # 3. Sync with the second device. | ||
| self.get_success( | ||
| sync_d = ensureDeferred( | ||
| worker_presence_handler.user_syncing( | ||
| user_id, | ||
| "dev-2", | ||
| affect_presence=dev_2_state != PresenceState.OFFLINE, | ||
| presence_state=dev_2_state, | ||
| ), | ||
| by=0.01, | ||
| ) | ||
| ) | ||
| # `user_syncing` proxies the presence write to the main process over an HTTP | ||
| # replication request. The request body is streamed by a `Cooperator` that uses | ||
| # the clock to schedule each chunk at a tiny *non-zero* delay (`_EPSILON`), so | ||
| # we need to actually advance the clock for it to fire. | ||
| self.reactor.advance(Duration(microseconds=1).as_secs()) | ||
| self.get_success(sync_d) | ||
|
|
||
| # 4. Assert the expected presence state. | ||
| state = self.get_success( | ||
|
|
@@ -1305,15 +1322,21 @@ def test_set_presence_from_syncing_multi_device( | |
| # | ||
| # This is due to EXTERNAL_PROCESS_EXPIRY being equivalent to IDLE_TIMER. | ||
| if test_with_workers: | ||
| with self.get_success( | ||
| sync_d = ensureDeferred( | ||
| worker_presence_handler.user_syncing( | ||
| f"@other-user:{self.hs.config.server.server_name}", | ||
| "dev-3", | ||
| affect_presence=True, | ||
| presence_state=PresenceState.ONLINE, | ||
| ), | ||
| by=0.01, | ||
| ): | ||
| ) | ||
| ) | ||
| # `user_syncing` proxies the presence write to the main process over an HTTP | ||
| # replication request. The request body is streamed by a `Cooperator` that uses | ||
| # the clock to schedule each chunk at a tiny *non-zero* delay (`_EPSILON`), so | ||
| # we need to actually advance the clock for it to fire. | ||
| self.reactor.advance(Duration(microseconds=1).as_secs()) | ||
|
|
||
| with self.get_success(sync_d): | ||
| pass | ||
|
|
||
| # 5. Advance such that the first device should be discarded (the idle timer), | ||
|
|
@@ -1501,26 +1524,36 @@ def test_set_presence_from_non_syncing_multi_device( | |
| worker_presence_handler = worker_to_sync_against.get_presence_handler() | ||
|
|
||
| # 1. Sync with the first device. | ||
| sync_1 = self.get_success( | ||
| sync_d = ensureDeferred( | ||
| worker_presence_handler.user_syncing( | ||
| user_id, | ||
| "dev-1", | ||
| affect_presence=dev_1_state != PresenceState.OFFLINE, | ||
| presence_state=dev_1_state, | ||
| ), | ||
| by=0.1, | ||
| ) | ||
| ) | ||
| # `user_syncing` proxies the presence write to the main process over an HTTP | ||
| # replication request. The request body is streamed by a `Cooperator` that uses | ||
| # the clock to schedule each chunk at a tiny *non-zero* delay (`_EPSILON`), so | ||
| # we need to actually advance the clock for it to fire. | ||
| self.reactor.advance(Duration(microseconds=1).as_secs()) | ||
| sync_1 = self.get_success(sync_d) | ||
|
|
||
| # 2. Sync with the second device. | ||
| sync_2 = self.get_success( | ||
| sync_d = ensureDeferred( | ||
| worker_presence_handler.user_syncing( | ||
| user_id, | ||
| "dev-2", | ||
| affect_presence=dev_2_state != PresenceState.OFFLINE, | ||
| presence_state=dev_2_state, | ||
| ), | ||
| by=0.1, | ||
| ) | ||
| ) | ||
| # `user_syncing` proxies the presence write to the main process over an HTTP | ||
| # replication request. The request body is streamed by a `Cooperator` that uses | ||
| # the clock to schedule each chunk at a tiny *non-zero* delay (`_EPSILON`), so | ||
| # we need to actually advance the clock for it to fire. | ||
| self.reactor.advance(Duration(microseconds=1).as_secs()) | ||
| sync_2 = self.get_success(sync_d) | ||
|
|
||
| # 3. Assert the expected presence state. | ||
| state = self.get_success( | ||
|
|
@@ -1622,12 +1655,17 @@ def test_set_presence_from_syncing_keeps_busy( | |
| # Perform a sync with a presence state other than busy. This should NOT change | ||
| # our presence status; we only change from busy if we explicitly set it via | ||
| # /presence/*. | ||
| self.get_success( | ||
| sync_d = ensureDeferred( | ||
| worker_to_sync_against.get_presence_handler().user_syncing( | ||
| self.user_id, self.device_id, True, PresenceState.ONLINE | ||
| ), | ||
| by=0.1, | ||
| ) | ||
| ) | ||
| # `user_syncing` proxies the presence write to the main process over an HTTP | ||
| # replication request. The request body is streamed by a `Cooperator` that uses | ||
| # the clock to schedule each chunk at a tiny *non-zero* delay (`_EPSILON`), so | ||
| # we need to actually advance the clock for it to fire. | ||
| self.reactor.advance(Duration(microseconds=1).as_secs()) | ||
| self.get_success(sync_d) | ||
|
|
||
| # Check against the main process that the user's presence did not change. | ||
| state = self.get_success(self.presence_handler.get_state(self.user_id_obj)) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The explanation here is slightly hand-wavey.
The other comment explanations are more concrete at-least in the fact that I've traced some scheduled reactor callback.