-
Notifications
You must be signed in to change notification settings - Fork 1
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
Fallback key test #67
base: main
Are you sure you want to change the base?
Changes from 12 commits
1094d35
38c9df4
7456376
c232675
cac449f
a6d8189
9df7e65
8c404ee
5807aa9
0c577e3
f693de8
5ee4e85
0235849
009f5ef
fa2d038
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 |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import asyncio | ||
import logging | ||
from typing import Any, Dict, Optional, Union | ||
from typing import Any, Dict, Optional, Union, cast | ||
|
||
from trafficlight.homerunner import HomeServer | ||
|
||
|
@@ -174,10 +174,11 @@ async def accept_crosssign(self) -> None: | |
async def verify_crosssign(self) -> None: | ||
await self._perform_action({"action": "verify_crosssign_emoji", "data": {}}) | ||
|
||
async def create_room(self, room_name: str) -> None: | ||
await self._perform_action( | ||
async def create_room(self, room_name: str) -> str: | ||
response = await self._perform_action( | ||
{"action": "create_room", "data": {"name": room_name}} | ||
) | ||
return cast(str, response["response"]) | ||
|
||
async def create_dm(self, user_id: str) -> None: | ||
await self._perform_action({"action": "create_dm", "data": {"userId": user_id}}) | ||
|
@@ -255,3 +256,6 @@ async def advance_clock(self, duration: int) -> None: | |
await self._perform_action( | ||
{"action": "advance_clock", "data": {"milliseconds": duration}} | ||
) | ||
|
||
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. I can't see where go_offline is being used - do we need this still - is the test OK with using the network_proxy to make the client be offline? 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 selected the wrong bit of code; the code in question is just below this line; sorry) |
||
async def go_offline(self) -> None: | ||
await self._perform_action({"action": "go_offline", "data": {}}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import asyncio | ||
import logging | ||
|
||
from nio import AsyncClient, AsyncClientConfig, SyncResponse, store | ||
|
||
from trafficlight.client_types import ElementWebStable | ||
from trafficlight.homerunner import HomeServer | ||
from trafficlight.internals.client import MatrixClient, NetworkProxyClient | ||
from trafficlight.internals.test import Test | ||
from trafficlight.server_types import SynapseDevelop | ||
|
||
|
||
# CLIENT_COUNT=2 REQUIRES_PROXY=true CYPRESS_BASE_URL="https://app.element.io" ./trafficlight/scripts-dev/run-localdev-setup.sh && tmux kill-server | ||
# Passing Test | ||
class FallbackKeyTest(Test): | ||
def __init__(self) -> None: | ||
super().__init__() | ||
self._client_under_test([ElementWebStable()], "alice") | ||
self._client_under_test([ElementWebStable()], "bob") | ||
self._network_proxy("alice_proxy") | ||
self._server_under_test(SynapseDevelop(), ["server"]) | ||
|
||
async def run( | ||
self, | ||
alice: MatrixClient, | ||
bob: MatrixClient, | ||
server: HomeServer, | ||
alice_proxy: NetworkProxyClient, | ||
) -> None: | ||
await alice_proxy.proxy_to(server) | ||
await asyncio.gather(alice.register(alice_proxy), bob.register(server)) | ||
room_id = await alice.create_room("fallback test room") | ||
logging.info(f"Got room-id as {room_id}") | ||
await alice.invite_user(f"{bob.localpart}:{server.server_name}") | ||
await bob.accept_invite() | ||
# disable sync for alice, so she can't upload more device keys | ||
await alice_proxy.disable_endpoint("/_matrix/client/r0/sync") | ||
for i in range(60): | ||
await login_and_send_message_in_room( | ||
server, bob, room_id, f"Hello world {i + 1}!" | ||
) | ||
await alice_proxy.enable_endpoint("/_matrix/client/r0/sync") | ||
# last message would have exhausted the OTKs, | ||
# so we should have fallen back to the fallback key | ||
await alice.verify_message_in_timeline("Hello world 60!") | ||
|
||
|
||
async def login_and_send_message_in_room( | ||
server: HomeServer, user: MatrixClient, room_id: str, message: str | ||
) -> None: | ||
# need to install python-olm and pip install "matrix-nio[e2e] | ||
logging.info( | ||
f"trying to login as @{user.localpart}:{server.server_name} with password ${user.password} and send a message in #{room_id}..." | ||
) | ||
user_id = f"@{user.localpart}:{server.server_name}" | ||
client = AsyncClient( | ||
server.cs_api, | ||
user_id, | ||
config=AsyncClientConfig( | ||
encryption_enabled=True, store=store.SqliteMemoryStore | ||
), | ||
) | ||
|
||
# This method will be called after each sync | ||
async def handle_sync(_: None) -> None: | ||
# Send the message after initial sync | ||
await client.room_send( | ||
room_id, | ||
message_type="m.room.message", | ||
content={"msgtype": "m.text", "body": message}, | ||
ignore_unverified_devices=True, | ||
) | ||
# Stop syncing | ||
task.cancel() | ||
|
||
try: | ||
client.add_response_callback(handle_sync, SyncResponse) | ||
await client.login(user.password) | ||
# sync_forever must be used for encryption to work | ||
task = asyncio.create_task(client.sync_forever(timeout=30000)) | ||
await task | ||
except Exception as e: | ||
logging.exception(str(e)) | ||
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. What exception are we catching, logging and dropping here? If we do it like this, the exception handling of the test suite as a whole won't mark the test as failed - are we using this to hide an exception that isn't fatal to the test? A short note on what we're catching/why would be good if we do need to hide exceptions that aren't failures. |
||
finally: | ||
await client.close() |
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.
I made a comment on the related PR in the adapter; i think we should have a little structure here to allow us to extend later (rather than only returning a string). If we change it in the adapter we'll need to change it here.